mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-01-22 19:04:38 +00:00
Compare commits
70 Commits
fix-6400
...
eventcatch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4dcf9a338 | ||
|
|
a893791f97 | ||
|
|
aaf1aa3821 | ||
|
|
8114d5475b | ||
|
|
29599baa3b | ||
|
|
b196cf77e8 | ||
|
|
4d3ebf4bf0 | ||
|
|
b3268546ef | ||
|
|
615d8da64f | ||
|
|
45a1478bc9 | ||
|
|
a071881562 | ||
|
|
2c38c8351b | ||
|
|
a51191d334 | ||
|
|
4054566493 | ||
|
|
5f994f7d46 | ||
|
|
7a7472833f | ||
|
|
9777aa9d13 | ||
|
|
d0b5b2124a | ||
|
|
95bd694a65 | ||
|
|
49de500b5e | ||
|
|
4cf3df0f86 | ||
|
|
1ae1ff3da2 | ||
|
|
4f42df8bef | ||
|
|
36b162a377 | ||
|
|
82c8fe7fa8 | ||
|
|
5378b45c40 | ||
|
|
ab3109d84b | ||
|
|
a4ab42da8a | ||
|
|
af87727ffc | ||
|
|
6b4e5c74ad | ||
|
|
94ab1e998d | ||
|
|
8af99878cc | ||
|
|
d6d2bc455c | ||
|
|
d5ff723d4c | ||
|
|
1d0af90ba2 | ||
|
|
b12d6c0758 | ||
|
|
a89677ea40 | ||
|
|
59572cd75d | ||
|
|
1d16206188 | ||
|
|
37a6ff8521 | ||
|
|
d3ea98fcef | ||
|
|
5022516c61 | ||
|
|
965d8ee014 | ||
|
|
8e50ad1243 | ||
|
|
33f40c47c6 | ||
|
|
1b3c2557b8 | ||
|
|
6b31d7cae3 | ||
|
|
1a4766c5a1 | ||
|
|
3e62e8406b | ||
|
|
e49dda3b48 | ||
|
|
bd447f0716 | ||
|
|
13faeaa0bd | ||
|
|
7f0fb2b610 | ||
|
|
7d2994388b | ||
|
|
edb5dc3fdc | ||
|
|
df1b1316c8 | ||
|
|
1a0c831216 | ||
|
|
f4365e4bb4 | ||
|
|
75d10a2dc3 | ||
|
|
da7cf7a4f3 | ||
|
|
6452eb56a9 | ||
|
|
9fce8153df | ||
|
|
4cdfa4e3f9 | ||
|
|
d6384df6fc | ||
|
|
f0bd06b38d | ||
|
|
d823856082 | ||
|
|
b02a82ba0f | ||
|
|
c43b013539 | ||
|
|
5548186c93 | ||
|
|
def9b553a8 |
@@ -1,15 +1,8 @@
|
||||
# Known minified files
|
||||
# Ignore "third party" code whose style we will not change.
|
||||
/boot/sjcl.js
|
||||
/core/modules/utils/base64-utf8/base64-utf8.module.js
|
||||
/core/modules/utils/base64-utf8/base64-utf8.module.min.js
|
||||
/core/modules/utils/diff-match-patch/diff_match_patch.js
|
||||
/plugins/tiddlywiki/async/files/async.min.v1.5.0.js
|
||||
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/anyword-hint.js
|
||||
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/css-hint.js
|
||||
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/html-hint.js
|
||||
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/javascript-hint.js
|
||||
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/show-hint.js
|
||||
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/xml-hint.js
|
||||
/plugins/tiddlywiki/codemirror-closebrackets/files/addon/edit/closebrackets.js
|
||||
/plugins/tiddlywiki/codemirror-closebrackets/files/addon/edit/matchbrackets.js
|
||||
/plugins/tiddlywiki/codemirror-closetag/files/addon/edit/closetag.js
|
||||
/plugins/tiddlywiki/codemirror-closetag/files/addon/fold/xml-fold.js
|
||||
/core/modules/utils/diff-match-patch/diff_match_patch_uncompressed.js
|
||||
/core/modules/utils/dom/csscolorparser.js
|
||||
/plugins/tiddlywiki/*/files/
|
||||
|
||||
@@ -64,7 +64,23 @@ rules:
|
||||
init-declarations: 'off'
|
||||
jsx-quotes: error
|
||||
key-spacing: 'off'
|
||||
keyword-spacing: 'off'
|
||||
keyword-spacing:
|
||||
- error
|
||||
- before: true
|
||||
after: false
|
||||
overrides:
|
||||
'case':
|
||||
after: true
|
||||
'do':
|
||||
'after': true
|
||||
'else':
|
||||
after: true
|
||||
'return':
|
||||
after: true
|
||||
'throw':
|
||||
after: true
|
||||
'try':
|
||||
after: true
|
||||
line-comment-position: 'off'
|
||||
linebreak-style: 'off'
|
||||
lines-around-comment: 'off'
|
||||
|
||||
28
boot/boot.js
28
boot/boot.js
@@ -68,6 +68,26 @@ $tw.utils.isArrayEqual = function(array1,array2) {
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
Add an entry to a sorted array if it doesn't already exist, while maintaining the sort order
|
||||
*/
|
||||
$tw.utils.insertSortedArray = function(array,value) {
|
||||
var low = 0, high = array.length - 1, mid, cmp;
|
||||
while(low <= high) {
|
||||
mid = (low + high) >> 1;
|
||||
cmp = value.localeCompare(array[mid]);
|
||||
if(cmp > 0) {
|
||||
low = mid + 1;
|
||||
} else if(cmp < 0) {
|
||||
high = mid - 1;
|
||||
} else {
|
||||
return array;
|
||||
}
|
||||
}
|
||||
array.splice(low,0,value);
|
||||
return array;
|
||||
};
|
||||
|
||||
/*
|
||||
Push entries onto an array, removing them first if they already exist in the array
|
||||
array: array to modify (assumed to be free of duplicates)
|
||||
@@ -1094,7 +1114,7 @@ $tw.Wiki = function(options) {
|
||||
tiddlerTitles = null, // Array of tiddler titles
|
||||
getTiddlerTitles = function() {
|
||||
if(!tiddlerTitles) {
|
||||
tiddlerTitles = Object.keys(tiddlers);
|
||||
tiddlerTitles = Object.keys(tiddlers).sort(function(a,b) {return a.localeCompare(b);});
|
||||
}
|
||||
return tiddlerTitles;
|
||||
},
|
||||
@@ -1147,10 +1167,8 @@ $tw.Wiki = function(options) {
|
||||
}
|
||||
// Save the new tiddler
|
||||
tiddlers[title] = tiddler;
|
||||
// Check we've got it's title
|
||||
if(tiddlerTitles && tiddlerTitles.indexOf(title) === -1) {
|
||||
tiddlerTitles.push(title);
|
||||
}
|
||||
// Check we've got the title
|
||||
tiddlerTitles = $tw.utils.insertSortedArray(tiddlerTitles || [],title);
|
||||
// Record the new tiddler state
|
||||
updateDescriptor["new"] = {
|
||||
tiddler: tiddler,
|
||||
|
||||
@@ -14,7 +14,7 @@ ConfirmAction: Do you wish to proceed?
|
||||
Count: count
|
||||
DefaultNewTiddlerTitle: New Tiddler
|
||||
Diffs/CountMessage: <<diff-count>> differences
|
||||
DropMessage: Drop here (or use the 'Escape' key to cancel)
|
||||
DropMessage: Drop now (or use the 'Escape' key to cancel)
|
||||
Encryption/Cancel: Cancel
|
||||
Encryption/ConfirmClearPassword: Do you wish to clear the password? This will remove the encryption applied when saving this wiki
|
||||
Encryption/PromptSetPassword: Set a new password for this TiddlyWiki
|
||||
|
||||
@@ -13,8 +13,8 @@ Text editor operation to wrap the selected lines with a prefix and suffix
|
||||
"use strict";
|
||||
|
||||
exports["wrap-lines"] = function(event,operation) {
|
||||
var prefix = operation.paramObject.prefix || "",
|
||||
suffix = operation.paramObject.suffix || "";
|
||||
var prefix = event.paramObject.prefix || "",
|
||||
suffix = event.paramObject.suffix || "";
|
||||
// Cut just past the preceding line break, or the start of the text
|
||||
operation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);
|
||||
// Cut to just past the following line break, or to the end of the text
|
||||
|
||||
@@ -95,10 +95,12 @@ function parseFilterOperation(operators,filterString,p) {
|
||||
if(nextBracketPos === -1) {
|
||||
throw "Missing closing bracket in filter expression";
|
||||
}
|
||||
if(!operator.regexp) {
|
||||
if(operator.regexp) {
|
||||
operand.text = "";
|
||||
} else {
|
||||
operand.text = filterString.substring(p,nextBracketPos);
|
||||
operator.operands.push(operand);
|
||||
}
|
||||
operator.operands.push(operand);
|
||||
p = nextBracketPos + 1;
|
||||
}
|
||||
|
||||
|
||||
27
core/modules/filters/crypto.js
Normal file
27
core/modules/filters/crypto.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/crypto.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operators for cryptography, using the Stanford JavaScript library
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.sha256 = function(source,operator,options) {
|
||||
var results = [],
|
||||
length = parseInt(operator.operand,10) || 20,
|
||||
sha256 = function(text) {
|
||||
return sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(text)).substr(0,length);
|
||||
};
|
||||
source(function(tiddler,title) {
|
||||
results.push(sha256(title));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -20,7 +20,7 @@ exports.insertbefore = function(source,operator,options) {
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
});
|
||||
var target = options.widget && options.widget.getVariable(operator.suffix || "currentTiddler");
|
||||
var target = operator.operands[1] || (options.widget && options.widget.getVariable(operator.suffix || "currentTiddler"));
|
||||
if(target !== operator.operand) {
|
||||
// Remove the entry from the list if it is present
|
||||
var pos = results.indexOf(operator.operand);
|
||||
|
||||
@@ -19,13 +19,13 @@ exports.draft = function(source,prefix,options) {
|
||||
var results = [];
|
||||
if(prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(!tiddler || !$tw.utils.hop(tiddler.fields,"draft.of")) {
|
||||
if(!tiddler || !tiddler.isDraft()) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler && $tw.utils.hop(tiddler.fields,"draft.of") && (tiddler.fields["draft.of"].length !== 0)) {
|
||||
if(tiddler && tiddler.isDraft()) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -87,7 +87,8 @@ exports.butlast = function(source,operator,options) {
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
});
|
||||
return results.slice(0,-count);
|
||||
var index = count === 0 ? results.length : -count;
|
||||
return results.slice(0,index);
|
||||
};
|
||||
exports.bl = exports.butlast;
|
||||
|
||||
|
||||
@@ -5,9 +5,11 @@ module-type: filteroperator
|
||||
|
||||
Filter operator that looks up values via a title prefix
|
||||
|
||||
[lookup:<field>[<prefix>]]
|
||||
[lookup:<defaultvalue>:<field OR index>[<prefix>],[<field-name OR index-name>]]
|
||||
|
||||
Prepends the prefix to the selected items and returns the specified field value
|
||||
Prepends the prefix to the selected items and returns the specified
|
||||
field or index value. If the 2nd suffix does not exist, it defaults to field.
|
||||
If the second operand is missing it defaults to "text" for fields, and "0" for indexes
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
@@ -20,10 +22,31 @@ Prepends the prefix to the selected items and returns the specified field value
|
||||
Export our filter function
|
||||
*/
|
||||
exports.lookup = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(options.wiki.getTiddlerText(operator.operand + title) || operator.suffix || '');
|
||||
});
|
||||
var results = [],
|
||||
suffixes = operator.suffixes || [],
|
||||
defaultSuffix = suffixes[0] ? (suffixes[0][0] || "") : "",
|
||||
indexSuffix = (suffixes[1] && suffixes[1][0] === "index") ? true : false,
|
||||
target;
|
||||
if(operator.operands.length == 2) {
|
||||
target = operator.operands[1]
|
||||
} else {
|
||||
target = indexSuffix ? "0": "text";
|
||||
}
|
||||
if(indexSuffix) {
|
||||
source(function(tiddler,title) {
|
||||
var data = options.wiki.extractTiddlerDataItem(operator.operands[0]+title,target,defaultSuffix);
|
||||
results.push(data);
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
var value = defaultSuffix;
|
||||
var targetTiddler = options.wiki.getTiddler(operator.operands[0]+title);
|
||||
if(targetTiddler && targetTiddler.getFieldString(target)) {
|
||||
value = targetTiddler.getFieldString(target);
|
||||
}
|
||||
results.push(value);
|
||||
});
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
|
||||
@@ -16,19 +16,37 @@ Filter operator for checking if a title starts with a prefix
|
||||
Export our filter function
|
||||
*/
|
||||
exports.prefix = function(source,operator,options) {
|
||||
var results = [];
|
||||
if(operator.prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(0,operator.operand.length) !== operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
var results = [],
|
||||
suffixes = (operator.suffixes || [])[0] || [];
|
||||
if(suffixes.indexOf("caseinsensitive") !== -1) {
|
||||
var operand = operator.operand.toLowerCase();
|
||||
if(operator.prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(title.toLowerCase().substr(0,operand.length) !== operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.toLowerCase().substr(0,operand.length) === operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(0,operator.operand.length) === operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
if(operator.prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(0,operator.operand.length) !== operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(0,operator.operand.length) === operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
@@ -16,12 +16,22 @@ Filter operator for removing a prefix from each title in the list. Titles that d
|
||||
Export our filter function
|
||||
*/
|
||||
exports.removeprefix = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(0,operator.operand.length) === operator.operand) {
|
||||
results.push(title.substr(operator.operand.length));
|
||||
}
|
||||
});
|
||||
var results = [],
|
||||
suffixes = (operator.suffixes || [])[0] || [];
|
||||
if(suffixes.indexOf("caseinsensitive") !== -1) {
|
||||
var operand = operator.operand.toLowerCase();
|
||||
source(function(tiddler,title) {
|
||||
if(title.toLowerCase().substr(0,operand.length) === operand) {
|
||||
results.push(title.substr(operand.length));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(0,operator.operand.length) === operator.operand) {
|
||||
results.push(title.substr(operator.operand.length));
|
||||
}
|
||||
});
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
|
||||
@@ -16,12 +16,26 @@ Filter operator for removing a suffix from each title in the list. Titles that d
|
||||
Export our filter function
|
||||
*/
|
||||
exports.removesuffix = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
if(title && title.substr(-operator.operand.length) === operator.operand) {
|
||||
results.push(title.substr(0,title.length - operator.operand.length));
|
||||
}
|
||||
});
|
||||
var results = [],
|
||||
suffixes = (operator.suffixes || [])[0] || [];
|
||||
if (!operator.operand) {
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
});
|
||||
} else if(suffixes.indexOf("caseinsensitive") !== -1) {
|
||||
var operand = operator.operand.toLowerCase();
|
||||
source(function(tiddler,title) {
|
||||
if(title && title.toLowerCase().substr(-operand.length) === operand) {
|
||||
results.push(title.substr(0,title.length - operand.length));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title && title.substr(-operator.operand.length) === operator.operand) {
|
||||
results.push(title.substr(0,title.length - operator.operand.length));
|
||||
}
|
||||
});
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ exports.search = function(source,operator,options) {
|
||||
invert: invert,
|
||||
field: fields,
|
||||
excludeField: excludeFields,
|
||||
some: hasFlag("some"),
|
||||
caseSensitive: hasFlag("casesensitive"),
|
||||
literal: hasFlag("literal"),
|
||||
whitespace: hasFlag("whitespace"),
|
||||
|
||||
@@ -16,19 +16,41 @@ Filter operator for checking if a title ends with a suffix
|
||||
Export our filter function
|
||||
*/
|
||||
exports.suffix = function(source,operator,options) {
|
||||
var results = [];
|
||||
if(operator.prefix === "!") {
|
||||
var results = [],
|
||||
suffixes = (operator.suffixes || [])[0] || [];
|
||||
if (!operator.operand) {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(-operator.operand.length) !== operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
results.push(title);
|
||||
});
|
||||
} else if(suffixes.indexOf("caseinsensitive") !== -1) {
|
||||
var operand = operator.operand.toLowerCase();
|
||||
if(operator.prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(title.toLowerCase().substr(-operand.length) !== operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.toLowerCase().substr(-operand.length) === operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(-operator.operand.length) === operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
if(operator.prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(-operator.operand.length) !== operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(-operator.operand.length) === operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ exports.untagged = function(source,operator,options) {
|
||||
var results = [],
|
||||
expected = (operator.prefix === "!");
|
||||
source(function(tiddler,title) {
|
||||
if((tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) === expected) {
|
||||
if(((tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) === expected) || (!tiddler && !expected)) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -239,7 +239,7 @@ exports.parseFilterVariable = function(source) {
|
||||
};
|
||||
|
||||
/*
|
||||
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, valueType: "string|indirect|macro", value:, start:, end:,}
|
||||
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}
|
||||
*/
|
||||
exports.parseAttribute = function(source,pos) {
|
||||
var node = {
|
||||
@@ -248,7 +248,7 @@ exports.parseAttribute = function(source,pos) {
|
||||
// Define our regexps
|
||||
var reAttributeName = /([^\/\s>"'=]+)/g,
|
||||
reUnquotedAttribute = /([^\/\s<>"'=]+)/g,
|
||||
reFilteredValue = /\{\{\{(.+?)\}\}\}/g,
|
||||
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/g,
|
||||
reIndirectValue = /\{\{([^\}]+)\}\}/g;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
|
||||
@@ -34,7 +34,6 @@ function Server(options) {
|
||||
this.authenticators = options.authenticators || [];
|
||||
this.wiki = options.wiki;
|
||||
this.boot = options.boot || $tw.boot;
|
||||
this.servername = $tw.utils.transliterateToSafeASCII(this.wiki.getTiddlerText("$:/SiteTitle") || "TiddlyWiki5");
|
||||
// Initialise the variables
|
||||
this.variables = $tw.utils.extend({},this.defaultVariables);
|
||||
if(options.variables) {
|
||||
@@ -44,7 +43,8 @@ function Server(options) {
|
||||
}
|
||||
}
|
||||
}
|
||||
$tw.utils.extend({},this.defaultVariables,options.variables);
|
||||
// Setup the default required plugins
|
||||
this.requiredPlugins = this.get("required-plugins").split(',');
|
||||
// Initialise CSRF
|
||||
this.csrfDisable = this.get("csrf-disable") === "yes";
|
||||
// Initialize Gzip compression
|
||||
@@ -52,14 +52,24 @@ function Server(options) {
|
||||
// Initialize browser-caching
|
||||
this.enableBrowserCache = this.get("use-browser-cache") === "yes";
|
||||
// Initialise authorization
|
||||
var authorizedUserName = (this.get("username") && this.get("password")) ? this.get("username") : "(anon)";
|
||||
var authorizedUserName;
|
||||
if(this.get("username") && this.get("password")) {
|
||||
authorizedUserName = this.get("username");
|
||||
} else if(this.get("credentials")) {
|
||||
authorizedUserName = "(authenticated)";
|
||||
} else {
|
||||
authorizedUserName = "(anon)";
|
||||
}
|
||||
this.authorizationPrincipals = {
|
||||
readers: (this.get("readers") || authorizedUserName).split(",").map($tw.utils.trim),
|
||||
writers: (this.get("writers") || authorizedUserName).split(",").map($tw.utils.trim)
|
||||
}
|
||||
if(this.get("admin") || authorizedUserName !== "(anon)") {
|
||||
this.authorizationPrincipals["admin"] = (this.get("admin") || authorizedUserName).split(',').map($tw.utils.trim)
|
||||
}
|
||||
// Load and initialise authenticators
|
||||
$tw.modules.forEachModuleOfType("authenticator", function(title,authenticatorDefinition) {
|
||||
// console.log("Loading server route " + title);
|
||||
// console.log("Loading authenticator " + title);
|
||||
self.addAuthenticator(authenticatorDefinition.AuthenticatorClass);
|
||||
});
|
||||
// Load route handlers
|
||||
@@ -71,15 +81,21 @@ function Server(options) {
|
||||
this.listenOptions = null;
|
||||
this.protocol = "http";
|
||||
var tlsKeyFilepath = this.get("tls-key"),
|
||||
tlsCertFilepath = this.get("tls-cert");
|
||||
tlsCertFilepath = this.get("tls-cert"),
|
||||
tlsPassphrase = this.get("tls-passphrase");
|
||||
if(tlsCertFilepath && tlsKeyFilepath) {
|
||||
this.listenOptions = {
|
||||
key: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsKeyFilepath),"utf8"),
|
||||
cert: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsCertFilepath),"utf8")
|
||||
cert: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsCertFilepath),"utf8"),
|
||||
passphrase: tlsPassphrase || ''
|
||||
};
|
||||
this.protocol = "https";
|
||||
}
|
||||
this.transport = require(this.protocol);
|
||||
// Name the server and init the boot state
|
||||
this.servername = $tw.utils.transliterateToSafeASCII(this.get("server-name") || this.wiki.getTiddlerText("$:/SiteTitle") || "TiddlyWiki5");
|
||||
this.boot.origin = this.get("origin")? this.get("origin"): this.protocol+"://"+this.get("host")+":"+this.get("port");
|
||||
this.boot.pathPrefix = this.get("path-prefix") || "";
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -150,6 +166,7 @@ function sendResponse(request,response,statusCode,headers,data,encoding) {
|
||||
Server.prototype.defaultVariables = {
|
||||
port: "8080",
|
||||
host: "127.0.0.1",
|
||||
"required-plugins": "$:/plugins/tiddlywiki/filesystem,$:/plugins/tiddlywiki/tiddlyweb",
|
||||
"root-tiddler": "$:/core/save/all",
|
||||
"root-render-type": "text/plain",
|
||||
"root-serve-type": "text/html",
|
||||
@@ -239,15 +256,15 @@ Server.prototype.requestHandler = function(request,response,options) {
|
||||
state.pathPrefix = options.pathPrefix || this.get("path-prefix") || "";
|
||||
state.sendResponse = sendResponse.bind(self,request,response);
|
||||
// Get the principals authorized to access this resource
|
||||
var authorizationType = this.methodMappings[request.method] || "readers";
|
||||
state.authorizationType = options.authorizationType || this.methodMappings[request.method] || "readers";
|
||||
// Check for the CSRF header if this is a write
|
||||
if(!this.csrfDisable && authorizationType === "writers" && request.headers["x-requested-with"] !== "TiddlyWiki") {
|
||||
if(!this.csrfDisable && state.authorizationType === "writers" && request.headers["x-requested-with"] !== "TiddlyWiki") {
|
||||
response.writeHead(403,"'X-Requested-With' header required to login to '" + this.servername + "'");
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
// Check whether anonymous access is granted
|
||||
state.allowAnon = this.isAuthorized(authorizationType,null);
|
||||
state.allowAnon = this.isAuthorized(state.authorizationType,null);
|
||||
// Authenticate with the first active authenticator
|
||||
if(this.authenticators.length > 0) {
|
||||
if(!this.authenticators[0].authenticateRequest(request,response,state)) {
|
||||
@@ -256,7 +273,7 @@ Server.prototype.requestHandler = function(request,response,options) {
|
||||
}
|
||||
}
|
||||
// Authorize with the authenticated username
|
||||
if(!this.isAuthorized(authorizationType,state.authenticatedUsername)) {
|
||||
if(!this.isAuthorized(state.authorizationType,state.authenticatedUsername)) {
|
||||
response.writeHead(401,"'" + state.authenticatedUsername + "' is not authorized to access '" + this.servername + "'");
|
||||
response.end();
|
||||
return;
|
||||
@@ -322,8 +339,16 @@ Server.prototype.listen = function(port,host,prefix) {
|
||||
port = process.env[port] || 8080;
|
||||
}
|
||||
// Warn if required plugins are missing
|
||||
if(!this.wiki.getTiddler("$:/plugins/tiddlywiki/tiddlyweb") || !this.wiki.getTiddler("$:/plugins/tiddlywiki/filesystem")) {
|
||||
$tw.utils.warning("Warning: Plugins required for client-server operation (\"tiddlywiki/filesystem\" and \"tiddlywiki/tiddlyweb\") are missing from tiddlywiki.info file");
|
||||
var missing = [];
|
||||
for (var index=0; index<this.requiredPlugins.length; index++) {
|
||||
if (!this.wiki.getTiddler(this.requiredPlugins[index])) {
|
||||
missing.push(this.requiredPlugins[index]);
|
||||
}
|
||||
}
|
||||
if(missing.length > 0) {
|
||||
var error = "Warning: Plugin(s) required for client-server operation are missing.\n"+
|
||||
"\""+ missing.join("\", \"")+"\"";
|
||||
$tw.utils.warning(error);
|
||||
}
|
||||
// Create the server
|
||||
var server;
|
||||
|
||||
@@ -51,6 +51,20 @@ exports.startup = function() {
|
||||
element.focus(event.paramObject);
|
||||
}
|
||||
});
|
||||
// Install the tm-rename-tiddler and tm-relink-tiddler messages
|
||||
var makeRenameHandler = function(method) {
|
||||
return function(event) {
|
||||
var options = {},
|
||||
paramObject = event.paramObject || {},
|
||||
from = paramObject.from || event.tiddlerTitle,
|
||||
to = paramObject.to;
|
||||
options.dontRenameInTags = (paramObject.renameInTags === "false" || paramObject.renameInTags === "no") ? true : false;
|
||||
options.dontRenameInLists = (paramObject.renameInLists === "false" || paramObject.renameInLists === "no") ? true : false;
|
||||
$tw.wiki[method](from,to,options);
|
||||
};
|
||||
};
|
||||
$tw.rootWidget.addEventListener("tm-rename-tiddler",makeRenameHandler("renameTiddler"));
|
||||
$tw.rootWidget.addEventListener("tm-relink-tiddler",makeRenameHandler("relinkTiddler"));
|
||||
// Install the scroller
|
||||
$tw.pageScroller = new $tw.utils.PageScroller();
|
||||
$tw.rootWidget.addEventListener("tm-scroll",function(event) {
|
||||
|
||||
@@ -20,6 +20,8 @@ exports.synchronous = true;
|
||||
|
||||
// Global to keep track of open windows (hashmap by title)
|
||||
$tw.windows = {};
|
||||
// Default template to use for new windows
|
||||
var DEFAULT_WINDOW_TEMPLATE = "$:/core/templates/single.tiddler.window";
|
||||
|
||||
exports.startup = function() {
|
||||
// Handle open window message
|
||||
@@ -29,22 +31,25 @@ exports.startup = function() {
|
||||
title = event.param || event.tiddlerTitle,
|
||||
paramObject = event.paramObject || {},
|
||||
windowTitle = paramObject.windowTitle || title,
|
||||
template = paramObject.template || "$:/core/templates/single.tiddler.window",
|
||||
windowID = paramObject.windowID || title,
|
||||
template = paramObject.template || DEFAULT_WINDOW_TEMPLATE,
|
||||
width = paramObject.width || "700",
|
||||
height = paramObject.height || "600",
|
||||
variables = $tw.utils.extend({},paramObject,{currentTiddler: title});
|
||||
top = paramObject.top,
|
||||
left = paramObject.left,
|
||||
variables = $tw.utils.extend({},paramObject,{currentTiddler: title, "tv-window-id": windowID});
|
||||
// Open the window
|
||||
var srcWindow,
|
||||
srcDocument;
|
||||
// In case that popup blockers deny opening a new window
|
||||
try {
|
||||
srcWindow = window.open("","external-" + title,"scrollbars,width=" + width + ",height=" + height),
|
||||
srcWindow = window.open("","external-" + windowID,"scrollbars,width=" + width + ",height=" + height + (top ? ",top=" + top : "" ) + (left ? ",left=" + left : "" )),
|
||||
srcDocument = srcWindow.document;
|
||||
}
|
||||
catch(e) {
|
||||
return;
|
||||
}
|
||||
$tw.windows[title] = srcWindow;
|
||||
$tw.windows[windowID] = srcWindow;
|
||||
// Check for reopening the same window
|
||||
if(srcWindow.haveInitialisedWindow) {
|
||||
return;
|
||||
@@ -54,7 +59,7 @@ exports.startup = function() {
|
||||
srcDocument.close();
|
||||
srcDocument.title = windowTitle;
|
||||
srcWindow.addEventListener("beforeunload",function(event) {
|
||||
delete $tw.windows[title];
|
||||
delete $tw.windows[windowID];
|
||||
$tw.wiki.removeEventListener("change",refreshHandler);
|
||||
},false);
|
||||
// Set up the styles
|
||||
@@ -88,13 +93,21 @@ exports.startup = function() {
|
||||
srcWindow.document.documentElement.addEventListener("click",$tw.popup,true);
|
||||
srcWindow.haveInitialisedWindow = true;
|
||||
});
|
||||
// Close open windows when unloading main window
|
||||
$tw.addUnloadTask(function() {
|
||||
$tw.rootWidget.addEventListener("tm-close-window",function(event) {
|
||||
var windowID = event.param,
|
||||
win = $tw.windows[windowID];
|
||||
if(win) {
|
||||
win.close();
|
||||
}
|
||||
});
|
||||
var closeAllWindows = function() {
|
||||
$tw.utils.each($tw.windows,function(win) {
|
||||
win.close();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
$tw.rootWidget.addEventListener("tm-close-all-windows",closeAllWindows);
|
||||
// Close open windows when unloading main window
|
||||
$tw.addUnloadTask(closeAllWindows);
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -16,21 +16,23 @@ Browser data transfer utilities, used with the clipboard and drag and drop
|
||||
Options:
|
||||
|
||||
domNode: dom node to make draggable
|
||||
selector: CSS selector to identify element within domNode to be used as drag handle (optional)
|
||||
dragImageType: "pill", "blank" or "dom" (the default)
|
||||
dragTiddlerFn: optional function to retrieve the title of tiddler to drag
|
||||
dragFilterFn: optional function to retreive the filter defining a list of tiddlers to drag
|
||||
widget: widget to use as the contect for the filter
|
||||
widget: widget to use as the context for the filter
|
||||
*/
|
||||
exports.makeDraggable = function(options) {
|
||||
var dragImageType = options.dragImageType || "dom",
|
||||
dragImage,
|
||||
domNode = options.domNode;
|
||||
domNode = options.domNode,
|
||||
dragHandle = options.selector && domNode.querySelector(options.selector) || domNode;
|
||||
// Make the dom node draggable (not necessary for anchor tags)
|
||||
if((domNode.tagName || "").toLowerCase() !== "a") {
|
||||
domNode.setAttribute("draggable","true");
|
||||
dragHandle.setAttribute("draggable","true");
|
||||
}
|
||||
// Add event handlers
|
||||
$tw.utils.addEventListeners(domNode,[
|
||||
$tw.utils.addEventListeners(dragHandle,[
|
||||
{name: "dragstart", handlerFunction: function(event) {
|
||||
if(event.dataTransfer === undefined) {
|
||||
return false;
|
||||
@@ -45,7 +47,7 @@ exports.makeDraggable = function(options) {
|
||||
}
|
||||
var titleString = $tw.utils.stringifyList(titles);
|
||||
// Check that we've something to drag
|
||||
if(titles.length > 0 && event.target === domNode) {
|
||||
if(titles.length > 0 && event.target === dragHandle) {
|
||||
// Mark the drag in progress
|
||||
$tw.dragInProgress = domNode;
|
||||
// Set the dragging class on the element being dragged
|
||||
|
||||
@@ -49,10 +49,14 @@ Handle an event
|
||||
*/
|
||||
PageScroller.prototype.handleEvent = function(event) {
|
||||
if(event.type === "tm-scroll") {
|
||||
var options = {};
|
||||
if($tw.utils.hop(event.paramObject,"animationDuration")) {
|
||||
options.animationDuration = event.paramObject.animationDuration;
|
||||
}
|
||||
if(event.paramObject && event.paramObject.selector) {
|
||||
this.scrollSelectorIntoView(null,event.paramObject.selector);
|
||||
this.scrollSelectorIntoView(null,event.paramObject.selector,null,options);
|
||||
} else {
|
||||
this.scrollIntoView(event.target);
|
||||
this.scrollIntoView(event.target,null,options);
|
||||
}
|
||||
return false; // Event was handled
|
||||
}
|
||||
@@ -62,10 +66,10 @@ PageScroller.prototype.handleEvent = function(event) {
|
||||
/*
|
||||
Handle a scroll event hitting the page document
|
||||
*/
|
||||
PageScroller.prototype.scrollIntoView = function(element,callback) {
|
||||
PageScroller.prototype.scrollIntoView = function(element,callback,options) {
|
||||
var self = this,
|
||||
duration = $tw.utils.getAnimationDuration(),
|
||||
srcWindow = element ? element.ownerDocument.defaultView : window;
|
||||
duration = $tw.utils.hop(options,"animationDuration") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(),
|
||||
srcWindow = element ? element.ownerDocument.defaultView : window;
|
||||
// Now get ready to scroll the body
|
||||
this.cancelScroll(srcWindow);
|
||||
this.startTime = Date.now();
|
||||
@@ -122,11 +126,11 @@ PageScroller.prototype.scrollIntoView = function(element,callback) {
|
||||
drawFrame();
|
||||
};
|
||||
|
||||
PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) {
|
||||
PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {
|
||||
baseElement = baseElement || document.body;
|
||||
var element = baseElement.querySelector(selector);
|
||||
if(element) {
|
||||
this.scrollIntoView(element,callback);
|
||||
this.scrollIntoView(element,callback,options);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -27,7 +27,10 @@ DraggableWidget.prototype = new Widget();
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
DraggableWidget.prototype.render = function(parent,nextSibling) {
|
||||
var self = this;
|
||||
var self = this,
|
||||
tag,
|
||||
domNode,
|
||||
classes = [];
|
||||
// Save the parent dom node
|
||||
this.parentDomNode = parent;
|
||||
// Compute our attributes
|
||||
@@ -35,18 +38,23 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
|
||||
// Execute our logic
|
||||
this.execute();
|
||||
// Sanitise the specified tag
|
||||
var tag = this.draggableTag;
|
||||
tag = this.draggableTag;
|
||||
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
|
||||
tag = "div";
|
||||
}
|
||||
// Create our element
|
||||
var domNode = this.document.createElement(tag);
|
||||
domNode = this.document.createElement(tag);
|
||||
// Assign classes
|
||||
var classes = ["tc-draggable"];
|
||||
if(this.draggableClasses) {
|
||||
classes.push(this.draggableClasses);
|
||||
}
|
||||
if(!this.dragHandleSelector) {
|
||||
classes.push("tc-draggable");
|
||||
}
|
||||
domNode.setAttribute("class",classes.join(" "));
|
||||
// Insert the node into the DOM and render any children
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(domNode,null);
|
||||
// Add event handlers
|
||||
$tw.utils.makeDraggable({
|
||||
domNode: domNode,
|
||||
@@ -55,11 +63,9 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
|
||||
startActions: self.startActions,
|
||||
endActions: self.endActions,
|
||||
dragImageType: self.dragImageType,
|
||||
widget: this
|
||||
widget: this,
|
||||
selector: self.dragHandleSelector
|
||||
});
|
||||
// Insert the link into the DOM and render any children
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(domNode,null);
|
||||
this.domNodes.push(domNode);
|
||||
};
|
||||
|
||||
@@ -72,7 +78,8 @@ DraggableWidget.prototype.execute = function() {
|
||||
this.draggableClasses = this.getAttribute("class");
|
||||
this.startActions = this.getAttribute("startactions");
|
||||
this.endActions = this.getAttribute("endactions");
|
||||
this.dragImageType = this.getAttribute("dragimagetype");
|
||||
this.dragImageType = this.getAttribute("dragimagetype");
|
||||
this.dragHandleSelector = this.getAttribute("selector");
|
||||
// Make the child widgets
|
||||
this.makeChildWidgets();
|
||||
};
|
||||
|
||||
@@ -46,6 +46,7 @@ EventWidget.prototype.render = function(parent,nextSibling) {
|
||||
$tw.utils.each(this.types,function(type) {
|
||||
domNode.addEventListener(type,function(event) {
|
||||
var selector = self.getAttribute("selector"),
|
||||
matchSelector = self.getAttribute("matchSelector"),
|
||||
actions = self.getAttribute("$"+type) || self.getAttribute("actions-"+type),
|
||||
stopPropagation = self.getAttribute("stopPropagation","onaction"),
|
||||
selectedNode = event.target,
|
||||
@@ -56,46 +57,49 @@ EventWidget.prototype.render = function(parent,nextSibling) {
|
||||
if(selectedNode.nodeType === 3) {
|
||||
selectedNode = selectedNode.parentNode;
|
||||
}
|
||||
// Check that the selected node matches any matchSelector
|
||||
if(matchSelector && !$tw.utils.domMatchesSelector(selectedNode,matchSelector)) {
|
||||
return false;
|
||||
}
|
||||
if(selector) {
|
||||
// Search ancestors for a node that matches the selector
|
||||
while(!$tw.utils.domMatchesSelector(selectedNode,selector) && selectedNode !== domNode) {
|
||||
selectedNode = selectedNode.parentNode;
|
||||
}
|
||||
// If we found one, copy the attributes as variables, otherwise exit
|
||||
if($tw.utils.domMatchesSelector(selectedNode,selector)) {
|
||||
// Only set up variables if we have actions to invoke
|
||||
if(actions) {
|
||||
$tw.utils.each(selectedNode.attributes,function(attribute) {
|
||||
variables["dom-" + attribute.name] = attribute.value.toString();
|
||||
});
|
||||
//Add a variable with a popup coordinate string for the selected node
|
||||
variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")";
|
||||
|
||||
//Add variables for offset of selected node
|
||||
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();
|
||||
variables["tv-selectednode-posy"] = selectedNode.offsetTop.toString();
|
||||
variables["tv-selectednode-width"] = selectedNode.offsetWidth.toString();
|
||||
variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString();
|
||||
|
||||
if(event.clientX && event.clientY) {
|
||||
//Add variables for event X and Y position relative to selected node
|
||||
selectedNodeRect = selectedNode.getBoundingClientRect();
|
||||
variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString();
|
||||
variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString();
|
||||
|
||||
//Add variables for event X and Y position relative to event catcher node
|
||||
catcherNodeRect = self.domNode.getBoundingClientRect();
|
||||
variables["event-fromcatcher-posx"] = (event.clientX - catcherNodeRect.left).toString();
|
||||
variables["event-fromcatcher-posy"] = (event.clientY - catcherNodeRect.top).toString();
|
||||
|
||||
//Add variables for event X and Y position relative to the viewport
|
||||
variables["event-fromviewport-posx"] = event.clientX.toString();
|
||||
variables["event-fromviewport-posy"] = event.clientY.toString();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Exit if we didn't find one
|
||||
if(selectedNode === domNode) {
|
||||
return false;
|
||||
}
|
||||
// Only set up variables if we have actions to invoke
|
||||
if(actions) {
|
||||
$tw.utils.each(selectedNode.attributes,function(attribute) {
|
||||
variables["dom-" + attribute.name] = attribute.value.toString();
|
||||
});
|
||||
//Add a variable with a popup coordinate string for the selected node
|
||||
variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")";
|
||||
|
||||
//Add variables for offset of selected node
|
||||
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();
|
||||
variables["tv-selectednode-posy"] = selectedNode.offsetTop.toString();
|
||||
variables["tv-selectednode-width"] = selectedNode.offsetWidth.toString();
|
||||
variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString();
|
||||
|
||||
if(event.clientX && event.clientY) {
|
||||
//Add variables for event X and Y position relative to selected node
|
||||
selectedNodeRect = selectedNode.getBoundingClientRect();
|
||||
variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString();
|
||||
variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString();
|
||||
|
||||
//Add variables for event X and Y position relative to event catcher node
|
||||
catcherNodeRect = self.domNode.getBoundingClientRect();
|
||||
variables["event-fromcatcher-posx"] = (event.clientX - catcherNodeRect.left).toString();
|
||||
variables["event-fromcatcher-posy"] = (event.clientY - catcherNodeRect.top).toString();
|
||||
|
||||
//Add variables for event X and Y position relative to the viewport
|
||||
variables["event-fromviewport-posx"] = event.clientX.toString();
|
||||
variables["event-fromviewport-posy"] = event.clientY.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Execute our actions with the variables
|
||||
if(actions) {
|
||||
|
||||
@@ -46,7 +46,7 @@ ImportVariablesWidget.prototype.execute = function(tiddlerList) {
|
||||
this.tiddlerList = tiddlerList || this.wiki.filterTiddlers(this.filter,this);
|
||||
// Accumulate the <$set> widgets from each tiddler
|
||||
$tw.utils.each(this.tiddlerList,function(title) {
|
||||
var parser = widgetPointer.wiki.parseTiddler(title);
|
||||
var parser = widgetPointer.wiki.parseTiddler(title,{parseAsInline:true});
|
||||
if(parser) {
|
||||
var parseTreeNode = parser.tree[0];
|
||||
while(parseTreeNode && parseTreeNode.type === "set") {
|
||||
|
||||
@@ -51,6 +51,9 @@ ListWidget.prototype.render = function(parent,nextSibling) {
|
||||
} else {
|
||||
this.storyview = null;
|
||||
}
|
||||
if(this.storyview && this.storyview.renderEnd) {
|
||||
this.storyview.renderEnd();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -44,8 +44,7 @@ NavigatorWidget.prototype.render = function(parent,nextSibling) {
|
||||
{type: "tm-fold-tiddler", handler: "handleFoldTiddlerEvent"},
|
||||
{type: "tm-fold-other-tiddlers", handler: "handleFoldOtherTiddlersEvent"},
|
||||
{type: "tm-fold-all-tiddlers", handler: "handleFoldAllTiddlersEvent"},
|
||||
{type: "tm-unfold-all-tiddlers", handler: "handleUnfoldAllTiddlersEvent"},
|
||||
{type: "tm-rename-tiddler", handler: "handleRenameTiddlerEvent"}
|
||||
{type: "tm-unfold-all-tiddlers", handler: "handleUnfoldAllTiddlersEvent"}
|
||||
]);
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
@@ -632,16 +631,6 @@ NavigatorWidget.prototype.handleUnfoldAllTiddlersEvent = function(event) {
|
||||
});
|
||||
};
|
||||
|
||||
NavigatorWidget.prototype.handleRenameTiddlerEvent = function(event) {
|
||||
var options = {},
|
||||
paramObject = event.paramObject || {},
|
||||
from = paramObject.from || event.tiddlerTitle,
|
||||
to = paramObject.to;
|
||||
options.dontRenameInTags = (paramObject.renameInTags === "false" || paramObject.renameInTags === "no") ? true : false;
|
||||
options.dontRenameInLists = (paramObject.renameInLists === "false" || paramObject.renameInLists === "no") ? true : false;
|
||||
this.wiki.renameTiddler(from,to,options);
|
||||
};
|
||||
|
||||
exports.navigator = NavigatorWidget;
|
||||
|
||||
})();
|
||||
|
||||
@@ -38,10 +38,14 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) {
|
||||
if(this.outerDomNode.scrollWidth <= this.outerDomNode.offsetWidth && this.outerDomNode.scrollHeight <= this.outerDomNode.offsetHeight && this.fallthrough === "yes") {
|
||||
return true;
|
||||
}
|
||||
var options = {};
|
||||
if($tw.utils.hop(event.paramObject,"animationDuration")) {
|
||||
options.animationDuration = event.paramObject.animationDuration;
|
||||
}
|
||||
if(event.paramObject && event.paramObject.selector) {
|
||||
this.scrollSelectorIntoView(null,event.paramObject.selector);
|
||||
this.scrollSelectorIntoView(null,event.paramObject.selector,null,options);
|
||||
} else {
|
||||
this.scrollIntoView(event.target);
|
||||
this.scrollIntoView(event.target,null,options);
|
||||
}
|
||||
return false; // Handled event
|
||||
};
|
||||
@@ -49,9 +53,9 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) {
|
||||
/*
|
||||
Scroll an element into view
|
||||
*/
|
||||
ScrollableWidget.prototype.scrollIntoView = function(element) {
|
||||
var duration = $tw.utils.getAnimationDuration(),
|
||||
srcWindow = element ? element.ownerDocument.defaultView : window;
|
||||
ScrollableWidget.prototype.scrollIntoView = function(element,callback,options) {
|
||||
var duration = $tw.utils.hop(options,"animationDuration") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(),
|
||||
srcWindow = element ? element.ownerDocument.defaultView : window;
|
||||
this.cancelScroll();
|
||||
this.startTime = Date.now();
|
||||
var scrollPosition = {
|
||||
@@ -114,11 +118,11 @@ ScrollableWidget.prototype.scrollIntoView = function(element) {
|
||||
}
|
||||
};
|
||||
|
||||
ScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) {
|
||||
ScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {
|
||||
baseElement = baseElement || document.body;
|
||||
var element = baseElement.querySelector(selector);
|
||||
if(element) {
|
||||
this.scrollIntoView(element,callback);
|
||||
this.scrollIntoView(element,callback,options);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -155,8 +159,6 @@ ScrollableWidget.prototype.render = function(parent,nextSibling) {
|
||||
// Create elements
|
||||
this.outerDomNode = this.document.createElement("div");
|
||||
$tw.utils.setStyle(this.outerDomNode,[
|
||||
{overflowY: "auto"},
|
||||
{overflowX: "auto"},
|
||||
{webkitOverflowScrolling: "touch"}
|
||||
]);
|
||||
this.innerDomNode = this.document.createElement("div");
|
||||
|
||||
@@ -314,24 +314,40 @@ excludeEventAttributes: ignores attributes whose name begins with "on"
|
||||
Widget.prototype.assignAttributes = function(domNode,options) {
|
||||
options = options || {};
|
||||
var self = this;
|
||||
$tw.utils.each(this.attributes,function(v,a) {
|
||||
// Check exclusions
|
||||
if(options.excludeEventAttributes && a.substr(0,2) === "on") {
|
||||
v = undefined;
|
||||
var assignAttribute = function(name,value) {
|
||||
// Check for excluded attribute names
|
||||
if(options.excludeEventAttributes && name.substr(0,2) === "on") {
|
||||
value = undefined;
|
||||
}
|
||||
if(v !== undefined) {
|
||||
var b = a.split(":");
|
||||
// Setting certain attributes can cause a DOM error (eg xmlns on the svg element)
|
||||
try {
|
||||
if (b.length == 2 && b[0] == "xlink"){
|
||||
domNode.setAttributeNS("http://www.w3.org/1999/xlink",b[1],v);
|
||||
} else {
|
||||
domNode.setAttributeNS(null,a,v);
|
||||
if(value !== undefined) {
|
||||
// Handle the xlink: namespace
|
||||
var namespace = null;
|
||||
if(name.substr(0,6) === "xlink:" && name.length > 6) {
|
||||
namespace = "http://www.w3.org/1999/xlink";
|
||||
name = name.substr(6);
|
||||
}
|
||||
// Handle styles
|
||||
if(name.substr(0,6) === "style." && name.length > 6) {
|
||||
domNode.style[$tw.utils.unHyphenateCss(name.substr(6))] = value;
|
||||
} else {
|
||||
// Setting certain attributes can cause a DOM error (eg xmlns on the svg element)
|
||||
try {
|
||||
domNode.setAttributeNS(namespace,name,value);
|
||||
} catch(e) {
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// Not all parse tree nodes have the orderedAttributes property
|
||||
if(this.parseTreeNode.orderedAttributes) {
|
||||
$tw.utils.each(this.parseTreeNode.orderedAttributes,function(attribute,index) {
|
||||
assignAttribute(attribute.name,self.attributes[attribute.name]);
|
||||
});
|
||||
} else {
|
||||
$tw.utils.each(Object.keys(self.attributes).sort(),function(name) {
|
||||
assignAttribute(name,self.attributes[name]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -639,14 +639,25 @@ Lookup a given tiddler and return a list of all the tiddlers that include it in
|
||||
*/
|
||||
exports.findListingsOfTiddler = function(targetTitle,fieldName) {
|
||||
fieldName = fieldName || "list";
|
||||
var titles = [];
|
||||
this.each(function(tiddler,title) {
|
||||
var list = $tw.utils.parseStringArray(tiddler.fields[fieldName]);
|
||||
if(list && list.indexOf(targetTitle) !== -1) {
|
||||
titles.push(title);
|
||||
}
|
||||
var wiki = this;
|
||||
var listings = this.getGlobalCache("listings-" + fieldName,function() {
|
||||
var listings = Object.create(null);
|
||||
wiki.each(function(tiddler,title) {
|
||||
var list = $tw.utils.parseStringArray(tiddler.fields[fieldName]);
|
||||
if(list) {
|
||||
for(var i = 0; i < list.length; i++) {
|
||||
var listItem = list[i],
|
||||
listing = listings[listItem] || [];
|
||||
if (listing.indexOf(title) === -1) {
|
||||
listing.push(title);
|
||||
}
|
||||
listings[listItem] = listing;
|
||||
}
|
||||
}
|
||||
});
|
||||
return listings;
|
||||
});
|
||||
return titles;
|
||||
return listings[targetTitle] || [];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1196,23 +1207,28 @@ Return an array of tiddler titles that match a search string
|
||||
text: The text string to search for
|
||||
options: see below
|
||||
Options available:
|
||||
source: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)
|
||||
source: an iterator function for the source tiddlers, called source(iterator),
|
||||
where iterator is called as iterator(tiddler,title)
|
||||
exclude: An array of tiddler titles to exclude from the search
|
||||
invert: If true returns tiddlers that do not contain the specified string
|
||||
caseSensitive: If true forces a case sensitive search
|
||||
field: If specified, restricts the search to the specified field, or an array of field names
|
||||
anchored: If true, forces all but regexp searches to be anchored to the start of text
|
||||
excludeField: If true, the field options are inverted to specify the fields that are not to be searched
|
||||
|
||||
The search mode is determined by the first of these boolean flags to be true
|
||||
literal: searches for literal string
|
||||
whitespace: same as literal except runs of whitespace are treated as a single space
|
||||
regexp: treats the search term as a regular expression
|
||||
words: (default) treats search string as a list of tokens, and matches if all tokens are found, regardless of adjacency or ordering
|
||||
words: (default) treats search string as a list of tokens, and matches if all tokens are found,
|
||||
regardless of adjacency or ordering
|
||||
some: treats search string as a list of tokens, and matches if at least ONE token is found
|
||||
*/
|
||||
exports.search = function(text,options) {
|
||||
options = options || {};
|
||||
var self = this,
|
||||
t,
|
||||
regExpStr="",
|
||||
invert = !!options.invert;
|
||||
// Convert the search string into a regexp for each term
|
||||
var terms, searchTermsRegExps,
|
||||
@@ -1239,7 +1255,18 @@ exports.search = function(text,options) {
|
||||
searchTermsRegExps = null;
|
||||
console.log("Regexp error parsing /(" + text + ")/" + flags + ": ",e);
|
||||
}
|
||||
} else {
|
||||
} else if(options.some) {
|
||||
terms = text.trim().split(/ +/);
|
||||
if(terms.length === 1 && terms[0] === "") {
|
||||
searchTermsRegExps = null;
|
||||
} else {
|
||||
searchTermsRegExps = [];
|
||||
for(t=0; t<terms.length; t++) {
|
||||
regExpStr += (t===0) ? anchor + $tw.utils.escapeRegExp(terms[t]) : "|" + anchor + $tw.utils.escapeRegExp(terms[t]);
|
||||
}
|
||||
searchTermsRegExps.push(new RegExp("(" + regExpStr + ")",flags));
|
||||
}
|
||||
} else { // default: words
|
||||
terms = text.split(/ +/);
|
||||
if(terms.length === 1 && terms[0] === "") {
|
||||
searchTermsRegExps = null;
|
||||
@@ -1250,7 +1277,7 @@ exports.search = function(text,options) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Accumulate the array of fields to be searched or excluded from the search
|
||||
// Accumulate the array of fields to be searched or excluded from the search
|
||||
var fields = [];
|
||||
if(options.field) {
|
||||
if($tw.utils.isArray(options.field)) {
|
||||
|
||||
@@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/Plugins/Languages
|
||||
tags: $:/tags/MoreSideBar/Plugins
|
||||
caption: {{$:/language/ControlPanel/Plugins/Languages/Caption}}
|
||||
|
||||
<$list filter="[!has[draft.of]plugin-type[language]sort[description]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>
|
||||
<$list filter="[!has[draft.of]plugin-type[language]sort[name]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>
|
||||
|
||||
@@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/Plugins/Plugins
|
||||
tags: $:/tags/MoreSideBar/Plugins
|
||||
caption: {{$:/language/ControlPanel/Plugins/Plugins/Caption}}
|
||||
|
||||
<$list filter="[!has[draft.of]plugin-type[plugin]sort[description]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}>>/>
|
||||
<$list filter="[!has[draft.of]plugin-type[plugin]sort[name]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}>>/>
|
||||
|
||||
@@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/Plugins/Theme
|
||||
tags: $:/tags/MoreSideBar/Plugins
|
||||
caption: {{$:/language/ControlPanel/Plugins/Themes/Caption}}
|
||||
|
||||
<$list filter="[!has[draft.of]plugin-type[theme]sort[description]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>
|
||||
<$list filter="[!has[draft.of]plugin-type[theme]sort[name]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>
|
||||
|
||||
@@ -6,7 +6,7 @@ caption: {{$:/language/SideBar/Open/Caption}}
|
||||
\define lingo-base() $:/language/CloseAll/
|
||||
|
||||
\define drop-actions()
|
||||
<$action-listops $tiddler=<<tv-story-list>> $subfilter="+[insertbefore:currentTiddler<actionTiddler>]"/>
|
||||
<$action-listops $tiddler=<<tv-story-list>> $subfilter="+[insertbefore<actionTiddler>,<currentTiddler>]"/>
|
||||
\end
|
||||
|
||||
\define placeholder()
|
||||
|
||||
@@ -17,7 +17,7 @@ tags: $:/tags/Macro
|
||||
\end
|
||||
|
||||
\define list-links-draggable-drop-actions()
|
||||
<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter="+[insertbefore:currentTiddler<actionTiddler>]"/>
|
||||
<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter="+[insertbefore<actionTiddler>,<currentTiddler>]"/>
|
||||
\end
|
||||
|
||||
\define list-links-draggable(tiddler,field:"list",type:"ul",subtype:"li",class:"",itemTemplate)
|
||||
@@ -61,7 +61,7 @@ tags: $:/tags/Macro
|
||||
<$action-deletefield $field="list-after"/>
|
||||
</$list>
|
||||
<!-- Save the new order to the Tag Tiddler -->
|
||||
<$action-listops $tiddler=<<__tag__>> $field="list" $filter="+[enlist<order>] +[insertbefore:currentTiddler<actionTiddler>]"/>
|
||||
<$action-listops $tiddler=<<__tag__>> $field="list" $filter="+[enlist<order>] +[insertbefore<actionTiddler>,<currentTiddler>]"/>
|
||||
<!-- Make sure the newly added item has the right tag -->
|
||||
<!-- Removing this line makes dragging tags within the dropdown work as intended -->
|
||||
<!--<$action-listops $tiddler=<<actionTiddler>> $tags=<<__tag__>>/>-->
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
chapter.of: Extended Persistence
|
||||
created: 20140708084850294
|
||||
modified: 20140717181245449
|
||||
modified: 20210720193245000
|
||||
sub.num: 3
|
||||
tags: doc
|
||||
title: Syncadaptor
|
||||
|
||||
A module with ``module-type: syncadaptor`` provides functionality to get a list of tiddlers (this list is provided as ~SkinnyTiddlers, which are normal tiddlers without the text field) and to load, save and delete single tiddlers. A syncadaptor can also provide functions to login and logout so that syncadaptor modules can be used to synchronize tiddlers with a remote server.
|
||||
|
||||
The syncer module only uses one syncadaptor and honours a special [[system tiddler|System Tiddlers]] [[$:/config/SyncFilter]] containing a [[filter string|Tags and Filter Mechanism]]. Tiddlers matching this filter string are not saved to the server with a syncadapter. It uses the [[WebServer API|https://tiddlywiki.com/#WebServer%20API%3A%20Get%20All%20Tiddlers]] to load modified tiddlers from the server, which returns only non-system tiddlers.
|
||||
The syncer module only uses one syncadaptor and honours a special [[system tiddler|System Tiddlers]] [[$:/config/SyncFilter]] containing a [[filter string|Tags and Filter Mechanism]]. Tiddlers matching this filter string are saved to the server with a syncadapter. It uses the [[WebServer API|https://tiddlywiki.com/#WebServer%20API%3A%20Get%20All%20Tiddlers]] to load modified tiddlers from the server, which returns only non-system tiddlers.
|
||||
|
||||
@@ -5,7 +5,7 @@ caption: {{$:/language/SideBar/Open/Caption}}
|
||||
\define lingo-base() $:/language/CloseAll/
|
||||
|
||||
\define drop-actions()
|
||||
<$action-listops $tiddler="$:/StoryList" $subfilter="+[insertbefore:currentTiddler<actionTiddler>]"/>
|
||||
<$action-listops $tiddler="$:/StoryList" $subfilter="+[insertbefore<actionTiddler>,<currentTiddler>]"/>
|
||||
\end
|
||||
|
||||
<$list filter="[list[$:/StoryList]]" history="$:/HistoryList" storyview="pop">
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
created: 20220219141117559
|
||||
list-before: $:/config/ViewTemplateTitleFilters/default
|
||||
modified: 20220220192507247
|
||||
tags: $:/tags/ViewTemplateTitleFilter
|
||||
title: $:/config/ViewTemplateTitleFilters/fr-default
|
||||
|
||||
[has[fr-title]then[$:/core/ui/ViewTemplate/title/fr-default]]
|
||||
@@ -0,0 +1,8 @@
|
||||
created: 20220219134855444
|
||||
modified: 20220220192530872
|
||||
title: $:/core/ui/ViewTemplate/title/fr-default
|
||||
|
||||
\whitespace trim
|
||||
<h2 class="tc-title">
|
||||
<$view field="fr-title"/>
|
||||
</h2>
|
||||
174
editions/fr-FR/tiddlers/$ _editions_tw5.com_doc-macros.tid
Normal file
174
editions/fr-FR/tiddlers/$ _editions_tw5.com_doc-macros.tid
Normal file
@@ -0,0 +1,174 @@
|
||||
created: 20150117152607000
|
||||
modified: 20220220000852855
|
||||
tags: $:/tags/Macro
|
||||
title: $:/editions/tw5.com/doc-macros
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
\define .concat(1,2,3,4,5) $1$$2$$3$$4$$5$
|
||||
|
||||
\define .def(_) <dfn class="doc-def">$_$</dfn>
|
||||
\define .em(_) <em class="doc-em">$_$</em>
|
||||
\define .strong(_) <strong class="doc-strong">$_$</strong>
|
||||
\define .place(_) <code class="doc-place">$_$</code>
|
||||
\define .word(_) "$_$"
|
||||
|
||||
\define .preamble(_) :.doc-preamble $_$
|
||||
\define .note(_)
|
||||
@@.doc-note
|
||||
;Note
|
||||
: $_$
|
||||
@@
|
||||
\end
|
||||
|
||||
\define .tid(_) <code class="doc-tiddler">$_$</code>
|
||||
\define .tag(_) <code class="doc-tag">$_$</code>
|
||||
\define .field(_) <code class="doc-field">$_$</code>
|
||||
\define .value(_) <code class="doc-value">$_$</code>
|
||||
\define .op(_) <code class="doc-operator">$_$</code>
|
||||
\define .var(_) <code class="doc-var">$_$</code>
|
||||
\define .wid(_) <code class="doc-widget">$$_$</code>
|
||||
\define .attr(_) <code class="doc-attr">$_$</code>
|
||||
\define .param(_) <code class="doc-param">$_$</code>
|
||||
|
||||
\define .mtitle(_) $_$ Macro
|
||||
\define .otitle(_) $_$ Operator
|
||||
\define .vtitle(_) $_$ Variable
|
||||
|
||||
\define .link(_,to) <$link to="$to$">$_$</$link>
|
||||
\define .clink(_,to) <span class="doc-clink"><<.link """$_$""" "$to$">></span>
|
||||
\define .dlink(_,to) <$macrocall $name=".link" _=<<.def "$_$">> to="$to$">/>
|
||||
\define .dlink-ex(_,to) <a href="$to$" class="tc-tiddlylink-external" target="_blank" rel="noopener noreferrer"><<.def "$_$">></a>
|
||||
\define .flink(to) <$macrocall $name=".link" _=<<.field {{$to$!!caption}}>> to="$to$"/>
|
||||
\define .mlink(_,to) <$macrocall $name=".link" _=<<.var "$_$">> to=<<.mtitle "$_$">>/>
|
||||
\define .mlink2(_,to) <$macrocall $name=".link" _=<<.var "$_$">> to="$to$"/>
|
||||
\define .olink(_) <$macrocall $name=".link" _=<<.op "$_$">> to=<<.otitle "$_$">>/>
|
||||
\define .olink2(_,to) <$macrocall $name=".link" _=<<.op "$_$">> to=<<.otitle "$to$">>/>
|
||||
\define .vlink(_,to) <$macrocall $name=".link" _=<<.var "$_$">> to=<<.vtitle "$_$">>/>
|
||||
\define .vlink2(_,to) <$macrocall $name=".link" _=<<.var "$_$">> to="$to$"/>
|
||||
\define .wlink(to) <$macrocall $name=".link" _=<<.wid {{$to$!!caption}}>> to="$to$"/>
|
||||
\define .wlink2(_,to) <$macrocall $name=".link" _="$_$" to="$to$"/>
|
||||
|
||||
\define .key(_) <span class="doc-key">$_$</span>
|
||||
\define .combokey(_) <$macrocall $name=".if" cond="$_$" then=<<.key '$_$'>>/>
|
||||
\define .keycombo(1,2,3,4) <<.combokey "$1$">><<.if "$2$" +>><<.combokey "$2$">><<.if "$3$" +>><<.combokey "$3$">><<.if "$4$" +>><<.combokey "$4$">>
|
||||
|
||||
\define .tab(_) <span class="doc-tab">{{$_$!!caption}}</span>
|
||||
\define .sidebar-tab(_) <<.tab "$:/core/ui/SideBar/$_$">>
|
||||
\define .more-tab(_) <<.tab "$:/core/ui/MoreSideBar/$_$">>
|
||||
\define .info-tab(_) <<.tab "$:/core/ui/TiddlerInfo/$_$">>
|
||||
\define .controlpanel-tab(_) <<.tab "$:/core/ui/ControlPanel/$_$">>
|
||||
\define .advancedsearch-tab(_) <<.tab "$:/core/ui/AdvancedSearch/$_$">>
|
||||
\define .toc-tab() <<.tab "TableOfContents">>
|
||||
\define .example-tab(_) <span class="doc-tab">$_$</span>
|
||||
|
||||
\define .button(_) <span class="doc-button">{{$:/core/ui/Buttons/$_$!!caption}}</span>
|
||||
|
||||
\define .icon(_) <span class="doc-icon">{{$_$}}</span>
|
||||
|
||||
\define .tip(_) <div class="doc-icon-block"><div class="doc-block-icon">{{$:/core/images/tip}}</div> $_$</div>
|
||||
\define .warning(_) <div class="doc-icon-block"><div class="doc-block-icon">{{$:/core/images/warning}}</div> $_$</div>
|
||||
|
||||
\define .state-prefix() $:/state/editions/tw5.com/
|
||||
|
||||
\define .lorem()
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
\end
|
||||
|
||||
\define .toc-lorem()
|
||||
C'est un exemple de tiddler. Voir [[Macros Table des matières (Exemples)|Table-of-Contents Macros (Examples)]].
|
||||
|
||||
<<.lorem>>
|
||||
\end
|
||||
|
||||
\define .example(n,eg,egvar:NO-SUCH-VAR)
|
||||
<div class="doc-example">
|
||||
<$reveal default="$egvar$" type="match" text="NO-SUCH-VAR">
|
||||
<$macrocall $name="copy-to-clipboard-above-right" src="""$eg$"""/>
|
||||
<$codeblock code="""$eg$"""/>
|
||||
</$reveal>
|
||||
<$reveal default="$egvar$" type="nomatch" text="NO-SUCH-VAR">
|
||||
<!-- allow an example to contain """ -->
|
||||
<$macrocall $name="copy-to-clipboard-above-right" src=<<$egvar$>>/>
|
||||
<$codeblock code=<<$egvar$>>/>
|
||||
</$reveal>
|
||||
<$list filter="[title<.state-prefix>addsuffix{!!title}addsuffix[/]addsuffix[$n$]]" variable=".state">
|
||||
<$reveal state=<<.state>> type="nomatch" text="show">
|
||||
<dl>
|
||||
<dd><$button set=<<.state>> setTo="show">Essayez</$button></dd>
|
||||
</dl>
|
||||
</$reveal>
|
||||
<$reveal state=<<.state>> type="match" text="show">
|
||||
<dl>
|
||||
<dd><$button set=<<.state>> setTo="">Cachez</$button></dd>
|
||||
</dl>
|
||||
<blockquote class="doc-example-result">
|
||||
<$reveal default="$egvar$" type="match" text="NO-SUCH-VAR">
|
||||
$eg$
|
||||
</$reveal>
|
||||
<$reveal default="$egvar$" type="nomatch" text="NO-SUCH-VAR">
|
||||
<<$egvar$>>
|
||||
</$reveal>
|
||||
</blockquote>
|
||||
</$reveal>
|
||||
</$list>
|
||||
\end
|
||||
|
||||
\define .bad-example(eg)
|
||||
<table class="doc-bad-example">
|
||||
<tbody>
|
||||
<tr class="evenRow">
|
||||
<td><span class="tc-inline-style" style="font-size:1.5em;">⚠</span> Warning:<br> Don't do it this way!</td>
|
||||
<td>
|
||||
|
||||
$eg$
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
\end
|
||||
|
||||
\define .link-badge(text,link,colour)
|
||||
<a href=<<__link__>> class="doc-link-badge" style="background-color:$colour$;" target="_blank" rel="noopener noreferrer"><$text text=<<__text__>>/></a>
|
||||
\end
|
||||
|
||||
|
||||
\define .link-badge-added(link,colour:#ffe246) <<.link-badge "added" """$link$""" """$colour$""">>
|
||||
\define .link-badge-addendum(link,colour:#fcc84a) <<.link-badge "addendum" """$link$""" """$colour$""">>
|
||||
\define .link-badge-extended(link,colour:#f9a344) <<.link-badge "extended" """$link$""" """$colour$""">>
|
||||
\define .link-badge-fixed(link,colour:#ffa86d) <<.link-badge "fixed" """$link$""" """$colour$""">>
|
||||
\define .link-badge-here(link,colour:#d88e63) <<.link-badge "here" """$link$""" """$colour$""">>
|
||||
\define .link-badge-hide(link,colour:#9d959f) <<.link-badge "hide" """$link$""" """$colour$""">>
|
||||
\define .link-badge-improved(link,colour:#7593c7) <<.link-badge "improved" """$link$""" """$colour$""">>
|
||||
\define .link-badge-modified(link,colour:#7f99c9) <<.link-badge "modified" """$link$""" """$colour$""">>
|
||||
\define .link-badge-removed(link,colour:#a9aabc) <<.link-badge "removed" """$link$""" """$colour$""">>
|
||||
\define .link-badge-renamed(link,colour:#b4b995) <<.link-badge "renamed" """$link$""" """$colour$""">>
|
||||
\define .link-badge-updated(link,colour:#91ba66) <<.link-badge "updated" """$link$""" """$colour$""">>
|
||||
|
||||
\define .tiddler-fields(tiddler)
|
||||
<$tiddler tiddler=<<__tiddler__>>>
|
||||
<div class="doc-tiddler-fields">
|
||||
<h2>
|
||||
<$link>
|
||||
<span class="tc-tiddler-title-icon">{{||$:/core/ui/TiddlerIcon}}</span><$text text=<<currentTiddler>>/>
|
||||
</$link>
|
||||
</h2>
|
||||
<table class="tc-view-field-table">
|
||||
<tbody>
|
||||
<$list filter="[all[current]fields[]sort[title]] -title" template="$:/core/ui/TiddlerFieldTemplate" variable="listItem"/>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</$tiddler>
|
||||
\end
|
||||
|
||||
\define .banner-credits(credit,url)
|
||||
<img src=<<__url__>> width="140" style="float:left;margin-right:0.5em;"/>
|
||||
|
||||
$credit$
|
||||
|
||||
<div style="clear:both;">
|
||||
|
||||
</div>
|
||||
\end
|
||||
|
||||
<pre><$view field="text"/></pre>
|
||||
@@ -1,46 +0,0 @@
|
||||
created: 20141119191707140
|
||||
modified: 20141128165607841
|
||||
tags: $:/tags/ViewTemplate
|
||||
title: $:/core/ui/ViewTemplate/title
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
\define title-styles()
|
||||
fill:$(foregroundColor)$;
|
||||
\end
|
||||
\define config-title()
|
||||
$:/config/ViewToolbarButtons/Visibility/$(listItem)$
|
||||
\end
|
||||
<div class="tc-tiddler-title">
|
||||
<div class="tc-titlebar">
|
||||
<span class="tc-tiddler-controls">
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]" variable="listItem"><$reveal type="nomatch" state=<<config-title>> text="hide"><$transclude tiddler=<<listItem>>/></$reveal></$list>
|
||||
</span>
|
||||
<$set name="tv-wikilinks" value={{$:/config/Tiddlers/TitleLinks}}>
|
||||
<$link>
|
||||
<$set name="foregroundColor" value={{!!color}}>
|
||||
<span class="tc-tiddler-title-icon" style=<<title-styles>>>
|
||||
<$transclude tiddler={{!!icon}}/>
|
||||
</span>
|
||||
</$set>
|
||||
<$list filter="[all[current]removeprefix[$:/]]">
|
||||
<h2 class="tc-title" title={{$:/language/SystemTiddler/Tooltip}}>
|
||||
<span class="tc-system-title-prefix">$:/</span><$text text=<<currentTiddler>>/>
|
||||
</h2>
|
||||
</$list>
|
||||
<$list filter="[all[current]!prefix[$:/]]">
|
||||
<h2 class="tc-title">
|
||||
<$view field="fr-title">
|
||||
<$view field="title"/>
|
||||
</$view>
|
||||
</h2>
|
||||
</$list>
|
||||
</$link>
|
||||
</$set>
|
||||
</div>
|
||||
|
||||
<$reveal type="nomatch" text="" default="" state=<<tiddlerInfoState>> class="tc-tiddler-info tc-popup-handle" animate="yes" retain="yes">
|
||||
|
||||
<$transclude tiddler="$:/core/ui/TiddlerInfo"/>
|
||||
|
||||
</$reveal>
|
||||
</div>
|
||||
@@ -36,3 +36,4 @@ type: text/vnd.tiddlywiki
|
||||
<!-- NO-BREAK SPACE Unicode: U+00A0, UTF-8: C2 A0, ISO-8859-1: A0 -->
|
||||
« $text$ »
|
||||
\end
|
||||
\define fr(cible) <$link to="$cible$"><$view tiddler="$cible$" field="fr-title">{{$cible$!!title}}</$view></$link>
|
||||
|
||||
11
editions/fr-FR/tiddlers/Community Links Aggregator.tid
Normal file
11
editions/fr-FR/tiddlers/Community Links Aggregator.tid
Normal file
@@ -0,0 +1,11 @@
|
||||
created: 20210322151848025
|
||||
fr-title: Agrégateur de liens communautaire
|
||||
modified: 20220217174626896
|
||||
tags: Community
|
||||
title: Community Links Aggregator
|
||||
|
||||
L'Agrégateur de liens communautaire est une collection fréquemment mise à jour de liens vers des ressources utiles et intéressantes sur <<tw>>, dénichés par notre équipe d'éditeurs communautaires. Le site agrège les liens soigneusement sélectionnés par les membres de la communauté <<tw>>. Il permet de visualiser les liens les plus récents, et de les explorer par catégorie et chronologiquement.
|
||||
|
||||
https://links.tiddlywiki.com/
|
||||
|
||||
Plus les contributeurs sont nombreux, et mieux le site fonctionne<<!>> Comme chacun n'est pas tenu de recenser chaque lien qui passe, la pression individuelle sur les contributeurs est réduite. L'agrégation des liens réduit aussi l'impact d'une erreur, par exemple d'une erreur de catégorisation<<:>> si un contributeur catégorise un lien dans la mauvaise rubrique, le site permet de voir qu'une seule personne a utilisé cette rubrique, alors que la majorité utilise la catégorie appropriée. Ainsi, nous espérons qu'une sorte de //intelligence collective// émergera, avec un consensus sur la manière la plus utile de décrire et de catégoriser les liens.
|
||||
@@ -1,10 +1,12 @@
|
||||
fr-title: Communauté
|
||||
created: 20130909151600000
|
||||
modified: 20141019103047540
|
||||
fr-title: Communauté
|
||||
modified: 20220217155910582
|
||||
tags: TableOfContents
|
||||
title: Community
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
C'est ici que nous rassemblons les dernières productions les plus utiles en provenance de la communauté <<tw>>.
|
||||
<<.tip "Les liens les plus utiles et les plus récents sont maintenant regroupés dans [[l’Agrégateur de liens communautaire|Community Links Aggregator]].">>
|
||||
|
||||
<<tabs "Forums Latest Tutorials Resources Examples Articles Meetups" "Latest">>
|
||||
Lorsque tous les liens pertinents auront été transférés, ces entrées seront retirées du site tiddlywiki.com.
|
||||
|
||||
<<tabs "Forums Latest Tutorials [[Community Editions]] [[Community Plugins]] [[Community Themes]] [[Community Palettes]] [[Other Resources]] Examples Articles Meetups" "Latest">>
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
created: 20150412191004348
|
||||
fr-title: Développeurs
|
||||
modified: 20150621192259510
|
||||
modified: 20220217174800697
|
||||
tags: Community
|
||||
title: Developers
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
Les développeurs disposent de plusieurs ressources pour discuter et contribuer au développement de TiddlyWiki.
|
||||
Plusieurs ressources permettent aux développeurs d'en apprendre plus sur <<tw>>, de collaborer et de discuter de son développement.
|
||||
|
||||
* [[tiddlywiki.com/dev|https://tiddlywiki.com/dev]] la documentation officielle de développement
|
||||
* [[TiddlyWikiDev group|http://groups.google.com/group/TiddlyWikiDev]] pour les discussions au sujet du développement de TiddlyWiki
|
||||
* https://github.com/Jermolene/TiddlyWiki5 pour le code source et l'activité de développement
|
||||
* [[tiddlywiki.com/dev|https://tiddlywiki.com/dev]] est la documentation officielle des développeurs
|
||||
* Vous pouvez vous impliquer dans le développement de <<tw>> sur [[GitHub|https://github.com/Jermolene/TiddlyWiki5]]
|
||||
** Les [[discussions|https://github.com/Jermolene/TiddlyWiki5/discussions]] sont disponibles pour les questions ouvertes et les questions/réponses.
|
||||
** Les [[problèmes|https://github.com/Jermolene/TiddlyWiki5/issues]] permettent de signaler les bogues et de proposer de nouvelles idées spécifiques, réalistes et raisonnables
|
||||
* L'ancien groupe ~TiddlyWikiDev sur Google Group est maintenant fermé, et remplacé par les [[discussions GitHub|https://github.com/Jermolene/TiddlyWiki5/discussions]], mais une archive reste disponible<<:>> https://groups.google.com/group/TiddlyWikiDev
|
||||
** Une fonctionnalité de recherche étendue du groupe est disponible sur [[mail-archive.com|https://www.mail-archive.com/tiddlywikidev@googlegroups.com/]]
|
||||
* Pour les dernières nouvelles, suivez [[@TiddlyWiki sur Twitter|http://twitter.com/#!/TiddlyWiki]]
|
||||
* Tchatchez sur https://gitter.im/TiddlyWiki/public (une salle dédiée au développement arrive bientôt)
|
||||
|
||||
11
editions/fr-FR/tiddlers/Federatial.tid
Normal file
11
editions/fr-FR/tiddlers/Federatial.tid
Normal file
@@ -0,0 +1,11 @@
|
||||
created: 20130825154900000
|
||||
modified: 20220219164816011
|
||||
tags: Definitions
|
||||
title: Federatial
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
Federatial Limited est une entreprise de consultants en logiciel fondée par JeremyRuston, le créateur de <<tw>>.
|
||||
|
||||
Federatial aide les organisations à explorer de nouveaux concepts d'interaction utilisateur grâce au prototypage rapide d'outils sophistiqués basés sur le web.
|
||||
|
||||
Pour plus d'informations, visitez [[https://federatial.com/]] et [[https://twitter.com/federatial]].
|
||||
@@ -1,25 +1,39 @@
|
||||
caption: Forum
|
||||
created: 20140721121924384
|
||||
fr-title: Forum
|
||||
modified: 20150614155153966
|
||||
modified: 20220217174719926
|
||||
tags: Community
|
||||
title: Forums
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
! Utilisateurs
|
||||
! Forum en français
|
||||
|
||||
Les groupes de discussion ~TiddlyWiki sont des listes de publipostage pour discuter de ~TiddlyWiki<<:>> demandes d'aide, annonces de nouvelles version et plugins, échanges sur les nouvelles fonctionnalités, ou simples partages d'expériences. Vous pouvez participer via le site web associé, ou souscrire par email.
|
||||
La communauté francophone sur <<tw>> a son forum, venez contribuer<<!>>
|
||||
|
||||
* Le groupe principal de ~TiddlyWiki<<:>> http://groups.google.com/group/TiddlyWiki
|
||||
*> Notez qu'il n'est nul besoin d'avoir un compte Google pour vous joindre aux groupes de discussion. Souscrire par l'envoi d'un email à mailto:tiddlywiki+subscribe@googlegroups.com ou mailto:tiddlywikidev+subscribe@googlegroups.com.
|
||||
* Visualiser les enregistrements de nos réguliers [[TiddlyWiki Hangouts]]
|
||||
* Suivre [[@TiddlyWiki sur Twitter|http://twitter.com/TiddlyWiki]] pour les dernières nouvelles.
|
||||
https://forum.tiddlywiki.fr/
|
||||
|
||||
! Développeurs
|
||||
! Forums officiels
|
||||
|
||||
* Le groupe TiddlyWikiDev pour les dévelopeurs<<:>> http://groups.google.com/group/TiddlyWikiDev
|
||||
*> Notez qu'il n'est nul besoin d'avoir un compte Google pour vous joindre aux groupes de discussion. Souscrire par l'envoi d'un email à mailto:tiddlywiki+subscribe@googlegroups.com ou mailto:tiddlywikidev+subscribe@googlegroups.com.
|
||||
* Suivre [[@TiddlyWiki sur Twitter|http://twitter.com/TiddlyWiki]] pour les dernières nouvelles.
|
||||
* Impliquez-vous dans le [[développement sur GitHub|https://github.com/Jermolene/TiddlyWiki5]]
|
||||
Le nouveau forum officiel pour discuter de <<tw>><<:>> demandes d'aide, annonces de nouvelles version et plugins, échanges sur les nouvelles fonctionnalités, ou simples partages d'expériences. Vous pouvez participer via le site web associé, ou souscrire par email.
|
||||
|
||||
Les nouvelles versions de TiddlyWiki, TiddlyDesktop et TiddlyFox sont annoncés par les groupes de discussion et [[Twitter|https://twitter.com/TiddlyWiki]] (vous pouvez aussi souscrire au flux Atom/RSS des [[versions de TiddlyWiki sur GitHub|https://github.com/jermolene/tiddlywiki5/releases.atom]])
|
||||
https://talk.tiddlywiki.org/
|
||||
|
||||
Notez que talk.tiddlywiki.org est un service communautaire que nous hébergeons et maintenons nous-mêmes. Les modestes frais de mise à disposition du site sont couverts par les contributions de la communauté.
|
||||
|
||||
Pour le confort de la communauté, l'ancien groupe <<tw>>, hébergé sur Google Groups depuis 2005, reste fonctionnel.
|
||||
|
||||
https://groups.google.com/group/TiddlyWiki
|
||||
|
||||
! Forums des développeurs
|
||||
|
||||
{{Developers}}
|
||||
|
||||
! Autres forums
|
||||
|
||||
* [[TiddlyWiki Subreddit|https://www.reddit.com/r/TiddlyWiki5/]]
|
||||
* Tchatchez avec Gitter sur https://gitter.im/TiddlyWiki/public<<!>>
|
||||
* Tchatchez avec Discord sur https://discord.gg/HFFZVQ8
|
||||
|
||||
!! Documentation
|
||||
|
||||
Il existe un groupe de discussion spécialement dédié aux initiatives d'amélioration de la documentation<<:>> https://groups.google.com/group/tiddlywikidocs
|
||||
|
||||
@@ -2,12 +2,12 @@ caption: Bienvenue !
|
||||
created: 20130822170200000
|
||||
fr-title: Bienvenue !
|
||||
list: [[Discover TiddlyWiki]] [[Some of the things you can do with TiddlyWiki]] [[Ten reasons to switch to TiddlyWiki]] Examples [[History of TiddlyWiki]] [[What happened to the original TiddlyWiki?]]
|
||||
modified: 20160603043549286
|
||||
modified: 20220217174842374
|
||||
tags: TableOfContents
|
||||
title: HelloThere
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
''N'avez-vous jamais eu la sensation que votre tête était trop petite pour contenir tout ce dont vous avez besoin de mémoriser ?''
|
||||
''N'avez-vous jamais eu la sensation que votre tête était trop petite pour contenir tout ce que vous avez besoin de mémoriser<<?>>''
|
||||
|
||||
Bienvenue sur TiddlyWiki, un carnet de notes web [[non-linéaire|Philosophy of Tiddlers]] pour [[saisir|Creating and editing tiddlers]], [[organiser|Structuring TiddlyWiki]] et [[partager|Sharing your tiddlers with others]] des informations simples ou complexes.
|
||||
|
||||
@@ -17,19 +17,22 @@ Utilisez-le pour gérer votre [[liste de tâches|TaskManagementExample]], faire
|
||||
<<list-thumbnails filter:"[tag[HelloThumbnail]]" width:"168" height:"95">>
|
||||
</div>
|
||||
|
||||
Contrairement aux services en ligne classiques, TiddlyWiki vous permet de choisir où conserver vos informations , et garantit que, dans les décennies à venir, vous pourrez toujours utiliser les notes que vous prenez aujourd'hui.
|
||||
Contrairement aux services en ligne classiques, TiddlyWiki vous permet de choisir où conserver vos informations, et garantit que, dans les décennies à venir, vous pourrez toujours utiliser les notes que vous prenez aujourd'hui.
|
||||
|
||||
<div style="font-size:0.7em;text-align:center;margin-top:3em;margin-bottom:3em;">
|
||||
<a href="http://groups.google.com/group/TiddlyWiki" class="tc-btn-big-green" style="background-color:#FF8C19;" target="_blank" rel="noopener noreferrer">
|
||||
{{$:/core/images/mail}} ~TiddlyWiki Mailing List
|
||||
<div style="font-size:0.7em;text-align:center;margin:3em auto;">
|
||||
<a href="https://talk.tiddlywiki.org/" class="tc-btn-big-green" style="border-radius:4px;background-color:#FF8C19;" target="_blank" rel="noopener noreferrer">
|
||||
{{$:/core/images/help}} ~TalkTW
|
||||
</a>
|
||||
<a href="https://www.youtube.com/c/JeremyRuston" class="tc-btn-big-green" style="background-color:#e52d27;" target="_blank" rel="noopener noreferrer">
|
||||
{{$:/core/images/video}} ~TiddlyWiki sur ~YouTube
|
||||
<a href="https://www.youtube.com/c/JeremyRuston" class="tc-btn-big-green" style="border-radius:4px;background-color:#e52d27;" target="_blank" rel="noopener noreferrer">
|
||||
{{$:/core/images/video}} ~YouTube
|
||||
</a>
|
||||
<a href="https://twitter.com/TiddlyWiki" class="tc-btn-big-green" style="background-color:#5E9FCA;" target="_blank" rel="noopener noreferrer">
|
||||
{{$:/core/images/twitter}} @~TiddlyWiki sur Twitter
|
||||
<a href="https://twitter.com/TiddlyWiki" class="tc-btn-big-green" style="border-radius:4px;background-color:#5E9FCA;" target="_blank" rel="noopener noreferrer">
|
||||
{{$:/core/images/twitter}} Twitter
|
||||
</a>
|
||||
<a href="https://github.com/Jermolene/TiddlyWiki5" class="tc-btn-big-green" style="background-color:#444;" target="_blank" rel="noopener noreferrer">
|
||||
{{$:/core/images/github}} ~TiddlyWiki sur ~GitHub
|
||||
<a href="https://github.com/Jermolene/TiddlyWiki5" class="tc-btn-big-green" style="border-radius:4px;background-color:#444;" target="_blank" rel="noopener noreferrer">
|
||||
{{$:/core/images/github}} ~GitHub
|
||||
</a>
|
||||
<a href="https://gitter.im/TiddlyWiki/public" class="tc-btn-big-green" style="border-radius:4px;background-color:#753a88;background-image:linear-gradient(to left,#cc2b5e,#753a88);" target="_blank" rel="noopener noreferrer">
|
||||
{{$:/core/images/gitter}} Gitter
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
caption: Jeremy Ruston
|
||||
created: 20130825162500000
|
||||
modified: 20150623064203685
|
||||
modified: 20220219163924300
|
||||
tags: Definitions
|
||||
title: JeremyRuston
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
Je suis l'inventeur original de TiddlyWiki. Vous pouvez me retrouver sur ces services<<:>>
|
||||
Je suis l'inventeur original de TiddlyWiki. Vous pouvez m'engager sur [[Federatial]], et me retrouver sur ces services<<:>>
|
||||
|
||||
* jeremy (at) jermolene (dot) com
|
||||
* [[Jermolene on GitHub|https://github.com/Jermolene]]
|
||||
* [[Jermolene on GitTip|https://www.gittip.com/Jermolene/]], micropaiements
|
||||
* [[@Jermolene on Twitter|http://twitter.com/#!/jermolene]]
|
||||
* [[Jermy on LinkedIn|http://www.linkedin.com/in/jermy]]
|
||||
* [[Jermy on Flickr|http://www.flickr.com/photos/jermy/]]
|
||||
* [[Jermolene sur GitHub|https://github.com/Jermolene]]
|
||||
* [[Jermolene sur GitTip|https://www.gittip.com/Jermolene/]], un service de micropaiements
|
||||
* [[@Jermolene sur Twitter|http://twitter.com/#!/jermolene]]
|
||||
* [[Jermy sur LinkedIn|http://www.linkedin.com/in/jermy]]
|
||||
* [[Jermy sur Flickr|http://www.flickr.com/photos/jermy/]]
|
||||
|
||||
Encore plus d'infos<<:>>
|
||||
Informations supplémentaires<<:>>
|
||||
|
||||
* Une [[interview de moi sur The Inquirer|http://www.theinquirer.net/inquirer/feature/2105529/bt-software-engineer-tells-telco-source]] par Wendy Grossman
|
||||
* Une [[interview hilarante avec moi|https://www.youtube.com/watch?v=auyIhw8MTmQ]] de la télévision britanique en 1983
|
||||
* Ici, un vidéo de présentation que j'ai réalisée en 2007 appelée [["How to Start an Open Source Project"|http://vimeo.com/856110]].
|
||||
* Ici, une vidéo de présentation que j'ai réalisée en 2007 intitulée [["How to Start an Open Source Project"|http://vimeo.com/856110]].
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
caption: list
|
||||
created: 20130830092500000
|
||||
fr-title: Champ liste
|
||||
modified: 20150614082620572
|
||||
modified: 20220219194303634
|
||||
tags: Fields
|
||||
title: ListField
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
[[Champ de tiddler|TiddlerFields]], `list` peut aider à structurer son contenu. Sa valeur est une [[liste de titres|Title List]], et peut être maniée de différentes façons<<:>>
|
||||
Le [[champ de tiddler|TiddlerFields]] `list` est une fonctionnalité optionnelle qui peut vous aider à structurer votre contenu. Sa valeur est une [[liste de titres|Title List]], qui peut être utilisée de différentes façons<<:>>
|
||||
|
||||
* Le champ `list` d'un tiddler utilisé comme étiquette détermine l'ordre des tiddlers portant ce tag - voir [[ Étiqueter |Tagging]] pour plus de détails
|
||||
* Le [[filtre|Filters]] `list` sélectionne les entrées d'une liste
|
||||
* Le [[filtre|Filters]] `listed` sélectionne les tiddlers listant le(s) tiddler(s) sélectionné(s)
|
||||
* Le NavigatorWidget manipule un tiddler $:/StoryList contenant un champ `list` des tiddlers affichés dans la colonne principale ''Récents''
|
||||
* Le champ `list` d'un tiddler utilisé comme tag détermine l'ordre des tiddlers portant ce tag -- voir [[Étiqueter|Tagging]] pour plus de détails
|
||||
* Le [[filtre|Filters]] `list` sélectionne les entrées d'une liste -- voir <<fr "list Operator">>
|
||||
* Le [[filtre|Filters]] `listed` sélectionne les tiddlers listant le(s) tiddler(s) sélectionné(s) -- voir <<fr "listed Operator">>
|
||||
* Le widget <<.wlink NavigatorWidget>> manipule un tiddler $:/StoryList dont le champ `list` contient les tiddlers affichés dans la vue principale
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
caption: Macros
|
||||
created: 20131205160746466
|
||||
fr-title: Macros dans WikiText
|
||||
modified: 20150621152601026
|
||||
fr-title: Macros en WikiTexte
|
||||
modified: 20220219191257167
|
||||
tags: WikiText
|
||||
title: Macros in WikiText
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
L'utilisation des [[macros|Macros]] dans [[WikiTexte|WikiText]] a deux aspects distincts<<:>>
|
||||
L'utilisation des [[macros|Macros]] en [[WikiTexte|WikiText]] recouvre deux aspects distincts<<:>>
|
||||
|
||||
* [[Définition des macros|Macro Definitions in WikiText]]
|
||||
* [[Appel des macros|Macro Calls in WikiText]]
|
||||
* [[La définition des macros|Macro Definitions in WikiText]]
|
||||
* [[L'appel des macros|Macro Calls in WikiText]]
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
caption: Macros
|
||||
created: 20140211171341271
|
||||
modified: 20150622110720298
|
||||
modified: 20220219192959452
|
||||
tags: Concepts Reference
|
||||
title: Macros
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
Les macros sont des bouts de texte qui peuvent être insérés à l'aide d'un raccourci concis<<dp>>
|
||||
Une <<.def macro>> est un //bout de texte// auquel on donne un nom. Le <<fr WikiText>> utilise ce nom comme raccourci pour [[transclure|Transclusion]] le //bout de texte//. Ces [[transclusions|Transclusion]] particulières s'appellent des <<.def "appels de macro">>, et chaque appel peut transmettre un ensemble différent d'arguments, qui se substituent à leur emplacement dans le //bout de texte//.
|
||||
|
||||
```
|
||||
<<maMacro>>
|
||||
```
|
||||
Pour une description de la syntaxe, voir <<fr "Macros in WikiText">>.
|
||||
|
||||
Vous pouvez écrire vos propres [[macros en WikiText|Macros in WikiText]] ou pour plus de souplesse, vous pouvez écrire des [[macros en Javascript|JavaScript Macros]].
|
||||
La plupart des macros sont en fait des [[variables|Variables]] paramétrées.
|
||||
|
||||
Les macros suivantes sont fournies avec <<tw>><<dp>>
|
||||
Elles sont définies en utilisant le [[pragma|Pragma]] `\define`. (En coulisses, cette syntaxe est transformé en <<fr SetWidget>>, donc les macros et les variables sont bien les deux faces de la même pièce.)
|
||||
|
||||
<<list-links "[tag[Macros]]">>
|
||||
Le //bout de texte// et ses arguments sont traités comme de simple chaînes de caractères, sans interprétation du <<fr WikiText>>, au moins jusqu'à ce que le dernier emplacement ait été rempli et que l'appel de macro soit terminé. Cela signifie qu'une macro peut assembler et renvoyer la syntaxe complète d'un composant <<fr WikiText>>, comme un [[lien|Linking in WikiText]] par exemple. (Voir <<fr "Transclusion and Substitution">> pour une discussion plus approfondie sur ce sujet.)
|
||||
|
||||
A l'intérieur d'un //bout de texte// lui-même, le seul balisage détecté est `$nom$` (un emplacement pour le paramètre `nom` qui sera substitué par l'argument correspondant reçu au moment d'un appel de macro) et `$(nom)$` (un emplacement pour une [[variable|Variables]]).
|
||||
|
||||
La macro <<.mlink dumpvariables>> liste toutes les variables (y-compris les macros) qui sont disponibles à cet endroit de l'arborescence des widgets.
|
||||
|
||||
Un widget <<.wlink ImportVariablesWidget>> peut être utilisé pour copier une définition de macro vers une autre branche de [[l'arbre des widgets|Widgets]]. <<tw>> utilise cette technique en interne pour implémenter des macros globales -- c'est-à-dire des macros définies dans des tiddlers étiquetés <<.tag $:/tags/Macro>>. (Le tag <<.tag $:/tags/Macro/View>> est quant à lui utilisé pour définir des macros qui ne doivent être disponibles que dans le modèle de vue principal et le panneau de prévisualisation.)
|
||||
|
||||
Pour un maximum de flexibilité, les macros peuvent aussi être <<.js-macro-link "écrites en tant que modules JavaScript">>.
|
||||
|
||||
Un effet similaire à l'utilisation de macros paramétrées peut être obtenu en encadrant une [[transclusion|Transclusion]] par une définition de [[variables|Variables]].
|
||||
|
||||
<<tw>> intègre [[plusieurs macros|Core Macros]] dans son cœur.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
created: 20131128075743966
|
||||
fr-title: Philosophie des tiddlers
|
||||
modified: 20141203144108401
|
||||
modified: 20220220004339779
|
||||
tags: Learning
|
||||
title: Philosophy of Tiddlers
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -9,4 +9,4 @@ Lorsqu'on enregistre et organise des informations, on se donne pour objectif de
|
||||
|
||||
La philosophie des [[tiddlers|Tiddlers]] consiste à maximiser les possibilités de réutilisation en découpant l'information en unités sémantiques aussi petites que possible, grâce à une [[modélisation riche des relations entre elles|Structuring TiddlyWiki]]. On utilise ensuite l'agrégation et la composition pour tisser les fragments entre eux afin de construire des déroulés cohérents.
|
||||
|
||||
TiddlyWiki a pour ambition de proposer une algèbre pour les tiddlers<<dp>> une manière concise d'exprimer et d'explorer les relations entre les diverses pièces d'information.
|
||||
<<tw>> a pour ambition de proposer une algèbre pour les tiddlers<<dp>> une manière concise d'exprimer et d'explorer les relations entre les diverses bribes d'information.
|
||||
|
||||
@@ -1,10 +1,69 @@
|
||||
fr-title: Sauvegarder les modifications
|
||||
created: 20140912140651119
|
||||
modified: 20141116123050408
|
||||
fr-title: Sauvegarder les modifications
|
||||
list:
|
||||
modified: 20220217174230426
|
||||
saving-browser: Firefox Chrome Edge [[Internet Explorer]] Safari Opera
|
||||
saving-os: Windows Mac Linux Android iOS
|
||||
tags: [[Working with TiddlyWiki]]
|
||||
title: Saving
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
Voici les méthodes disponibles pour sauvegarder vos modifications avec TiddlyWiki<<dp>>
|
||||
\define alltagsfilter()
|
||||
<$vars tag1="tag[" tag2="]" lb="[" rb="tag[Saving]sort[delivery]]">
|
||||
<$set filter="[list[]addprefix<tag1>addsuffix<tag2>]+[join[]addprefix<lb>addsuffix<rb>]" name="alltags" select=0>
|
||||
<$text text=<<alltags>>/>
|
||||
</$set>
|
||||
</$vars>
|
||||
\end
|
||||
|
||||
<<list-links "[tag[Saving]]">>
|
||||
\define saverssidebaritem(item:"Linux")
|
||||
<$checkbox tiddler=<<qualify $:/temp/$item$>> field="status" checked="selected" checkactions=<<checkactions "$item$">> uncheckactions=<<uncheckactions "$item$">> default="closed"> $item$</$checkbox><br/>
|
||||
\end
|
||||
|
||||
\define saverssidebaritemlist(fieldname:"os")
|
||||
<$list filter="[enlist{!!$fieldname$}]" variable="currentItem">
|
||||
<$macrocall $name="saverssidebaritem" item=<<currentItem>>/>
|
||||
</$list>
|
||||
\end
|
||||
|
||||
\define uncheckactions(item:"Linux")
|
||||
<$action-listops $subfilter="-[[$item$]]"/>
|
||||
\end
|
||||
|
||||
\define checkactions(item:"Linux")
|
||||
<$action-listops $subfilter="[[$item$]]"/>
|
||||
\end
|
||||
|
||||
\define uncheckactions(item:"Linux")
|
||||
<$action-listops $subfilter="-[[$item$]]"/>
|
||||
\end
|
||||
|
||||
Méthodes disponibles pour enregistrer les modifications avec <<tw>><<:>>
|
||||
|
||||
<div class="tc-wrapper-flex">
|
||||
<div class="tc-saving-sidebar">
|
||||
<div class="tc-saving-sidebar-category">
|
||||
<div class="tc-saving-sidebar-category-title">Plateforme</div>
|
||||
<div class="tc-saving-sidebar-category-item">
|
||||
<<saverssidebaritemlist "saving-os">>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tc-saving-sidebar-category">
|
||||
<div class="tc-saving-sidebar-category-title">Navigateur internet</div>
|
||||
<div class="tc-saving-sidebar-category-item">
|
||||
<<saverssidebaritemlist "saving-browser">>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Page content -->
|
||||
<div class="content">
|
||||
<$wikify text=<<alltagsfilter>> name="alltagsfilterwikified">
|
||||
<$list filter=<<alltagsfilterwikified>>>
|
||||
{{||$:/_tw5.com-card-template}}
|
||||
</$list>
|
||||
</$wikify>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
created: 20131128090536894
|
||||
fr-title: Structurer TiddlyWiki
|
||||
modified: 20150620093923918
|
||||
modified: 20220220003638545
|
||||
tags: [[Working with TiddlyWiki]]
|
||||
title: Structuring TiddlyWiki
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
TiddlyWiki5 fournit plusieurs fonctionnalités qui vous aideront à structurer les informations sous forme de [[tiddlers|Tiddlers]], et à modéliser les relations entre eux<<dp>>
|
||||
TiddlyWiki5 fournit plusieurs fonctionnalités qui vous aideront à structurer les informations sous forme de [[tiddlers|Tiddlers]], et à modéliser les relations entre eux<<:>>
|
||||
|
||||
* [[Liens dans un tiddler|TiddlerLinks]]
|
||||
* [[Étiqueter par tag|Tagging]]
|
||||
* [[Tiddler de listes|ListWidget]]
|
||||
* [[Tiddlers de données|DataTiddlers]]
|
||||
* <<fr TiddlerLinks>>
|
||||
* <<fr Tagging>>
|
||||
* <<fr "Title List">>
|
||||
* <<fr DataTiddlers>>
|
||||
|
||||
@@ -1,35 +1,41 @@
|
||||
created: 20140904075400000
|
||||
fr-title: Étiqueter par tag
|
||||
modified: 20150624092812640
|
||||
modified: 20220220002448916
|
||||
tags: [[Working with TiddlyWiki]] Concepts
|
||||
title: Tagging
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
Étiqueter un tiddler consiste à assigner par un tag à un tiddler une catégorie de votre choix (voir [[Créer et éditer des tiddlers|Creating and editing tiddlers]] pour des instructions sur la manière de taguer). Par exemple, les tiddlers représentant des individus pourraient être étiquetés par les tags ''ami'', ''famille'', ''collègue'', etc. pour indiquer leur relation avec l'auteur. Plusieurs tags peuvent être appliqués au même tiddler.
|
||||
L'étiquetage des tiddlers permet de les organiser en catégories. Par exemple, les tiddlers représentant des individus pourraient être étiquetés avec les tags ''ami'', ''famille'', ''collègue'', etc. pour indiquer leur relation avec l'auteur.
|
||||
|
||||
Un tag est en fait un simple tiddler (ou un tiddler potentiel), qui peut lui-même avoir ses propres tags. Plusieurs tags peuvent être appliqués au même tiddler.
|
||||
|
||||
Voir <<fr "Creating and editing tiddlers">> pour des instructions sur la façon d'étiqueter les tiddlers.
|
||||
|
||||
Le fait d'étiqueter les tiddlers vous procure de nombreux moyens supplémentaires de visualiser, parcourir, et organiser vos informations<<:>>
|
||||
|
||||
* Les pastilles colorées pour chaque tag d'un tiddler vous donnent accès à tous les autres tiddlers de même tag, ainsi qu'au tiddler correspondant au tag lui-même.
|
||||
* L'onglet //Étiqueté// dans le panneau d'informations du tiddler (accessible en cliquant sur le bouton {{$:/core/images/info-button}}) vous donne les liens vers tous les tiddlers tagués avec le titre du tiddler courant.
|
||||
* Vous pouvez utiliser l'onglet Tags dans l'onglet Plus de la barre latérale pour visualiser tous vos tags et accéder à vos tiddlers étiquetés.
|
||||
* Vous pouvez utiliser des [[filtres|Filters]] pour créer des listes de tiddlers selon leurs tags, puis afficher toute combinaison de champs souhaitée. Par exemple, vous pouvez créer une liste qui montre à la fois le titre et le texte de tous les tiddlers étiquetés //Glossaire//. Ces listes peuvent être formatées à votre goût<<:>> avec des puces, des nombres, ou séparées par des virgules, etc.
|
||||
* Les tags <<gf système>> peuvent servir à personnaliser la mise en forme des tiddlers et de la page ~TiddlyWiki dans son ensemble. Voir les instructions correspondantes dans [[Personnalisation de la mise en forme de la page et des tiddlers|Page and tiddler layout customisation]].
|
||||
* Les pastilles colorées pour chaque tag d'un tiddler vous donnent accès à tous les autres tiddlers portant le même tag, ainsi qu'au tiddler correspondant au tag lui-même.
|
||||
|
||||
* Lorsqu'un tiddler est utilisé pour étiqueter d'autres tiddlers, l'onglet ''Étiquetage'' dans son [[panneau d'informations|InfoPanel]] liste tous les tiddlers tagués avec le titre du tiddler courant.
|
||||
|
||||
* L'onglet ''Plus'' de la barre latérale contient un onglet ''Tags'' qui permet de visualiser tous vos tags et d'accéder à vos tiddlers étiquetés.
|
||||
|
||||
* Vous pouvez utiliser des [[filtres|Filters]] pour créer des listes de tiddlers selon leurs tags, puis afficher toute combinaison de [[champs|TiddlerFields]] souhaitée. Par exemple, vous pouvez créer un glossaire en listant le titre et le texte de tous les tiddlers étiquetés //Glossaire//. De telles listes peuvent être formatées à votre goût<<:>> avec des puces, des nombres, ou séparées par des virgules, etc.
|
||||
|
||||
* Les <<gf "tags système">> contrôlent la mise en forme des tiddlers et de la page <<tw>> dans son ensemble. Voir les instructions correspondantes dans <<fr "Page and tiddler layout customisation">>.
|
||||
|
||||
Encore deux choses que les tags permettent de faire<<:>>
|
||||
|
||||
! Affecter des couleurs et des icones à un tag
|
||||
! Affecter des couleurs et des icônes à un tag
|
||||
|
||||
Vous pouvez utiliser le [[gestionnaire de tags|$:/TagManager]], présent dans l'onglet Tags de l'onglet Plus de la barre latérale, pour affecter une couleur de fond et/ou une icone à un tag.
|
||||
Vous pouvez utiliser le <<.icon $:/core/images/tag-button>> [[gestionnaire de tags|$:/TagManager]], présent dans l'onglet ''Tags'' de l'onglet ''Plus'' de la barre latérale, pour affecter une couleur de fond et/ou une icône à un tag.
|
||||
|
||||
* Les couleurs peuvent être affectées à un tag soit en spécifiant la valeur CSS de la couleur dans la fenêtre supérieure dans la colonne des couleurs, soit en choisissant une couleur à partir du menu déroulant proposé.
|
||||
* Les icones peuvent être affectées à un tag en cliquant sur le bouton {{$:/core/images/down-arrow}} dans la colonne des icones et en choisissant une des icones proposées.
|
||||
* Les couleurs peuvent être affectées à un tag en cliquant sur le bouton de la colonne des couleurs et en sélectionnant une proposition. Sinon, spécifiez la valeur [[CSS]] de la couleur dans la zone de saisie accessible en cliquant sur le bouton <<.icon $:/core/images/info-button>>.
|
||||
* Les icônes peuvent être affectées à un tag en cliquant sur le bouton <<.icon $:/core/images/down-arrow>> dans la colonne des icônes et en choisissant une des icônes proposées.
|
||||
|
||||
! Utiliser des champs `list` pour ajuster l'ordre des listes par tag
|
||||
! Changer l'ordre dans lequel les tiddlers sont listés
|
||||
|
||||
Si vous voulez créer une liste de tiddlers à l'aide d'un [[filtre|Filters]] à partir d'un tag qu'ils ont en commun, en les triant selon un ordre particulier plutôt que selon l'ordre alphabétique par défaut, vous pouvez créer un champ appelé 'list' dans le tiddler du tag lui-même, et y ajouter les titres des tiddlers à ordonner dans l'ordre désiré. ~TiddlyWiki triera les listes de tiddlers tagués dans l'ordre de priorité suivant<<:>>
|
||||
Par défaut, les tiddlers tagués sont listés dans l'ordre alphabétique.
|
||||
|
||||
* Premièrement, les tiddlers placés dans le [[champ list|ListField]] du tiddler de tag seront placés dans une nouvelle liste dans le même ordre
|
||||
* Deuxièmement, tout tiddler sans place fixe mais disposant d'un champ ''list-before'' sera placé avant le tiddler indiqué dans le champ
|
||||
** (si le champ ''list-before'' est vide, alors le tiddler sans place prédéfinie sera placé au début de la liste)
|
||||
* Troisièmement, tout tiddler sans place prédéfinie disposant d'un champ ''list-after'' sera placé juste après le tiddler indiqué dans le champ
|
||||
* Enfin, tout tiddler n'ayant toujours pas de place prédéfinie sera placé à la fin de la liste
|
||||
Si vous voulez un ordre différent, ajoutez un champ `list` au tiddler du tag, et affectez lui comme valeur la [[liste de ses tiddlers|Title List]] dans l'ordre choisi.
|
||||
|
||||
Le champ `list` n'a pas besoin de contenir tous les tiddlers. <<tw>> utilise des [[règles précises|Order of Tagged Tiddlers]] pour trier les tiddlers tagués.
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
created: 20130825202900000
|
||||
fr-title: Liens dans un Tiddler
|
||||
modified: 20150624092911695
|
||||
modified: 20220219170847313
|
||||
tags: Concepts
|
||||
title: TiddlerLinks
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
Les liens sont des éléments d'un tiddler où cliquer engendre la navigation vers un tiddler différent. Le comportement d'une navigation est déterminé par le StoryView (la vue) en cours<<;>> par défaut, la vue classique de TiddlyWiki montre son déroulé comme une suite linéaire de tiddlers.
|
||||
Les liens sont des éléments d'un tiddler où cliquer engendre la navigation vers un tiddler différent. Le comportement d'une navigation est déterminé par le StoryView (la vue) en cours<<:>> par défaut, la vue classique de TiddlyWiki montre son déroulé comme une suite linéaire de tiddlers.
|
||||
|
||||
Presser la touche ''control'' ou ''command'' en cliquant sur le lien d'un link ouvre le tiddler cible sans s'y déplacer. Cela peut-être un moyen pratique de dresser une suite de tiddlers à lire plus tard.
|
||||
|
||||
@@ -13,12 +13,12 @@ Les liens sont utiles pour modéliser des relations organiques entre tiddlers, e
|
||||
|
||||
Le [[panneau d'information|InfoPanel]] liste la provenance des liens vers un tiddler dans l'onglet ''References''.
|
||||
|
||||
Les [[filtres|Filters]] peuvent inclure les opérateur de filtrage suivant qui fonctionnent avec les liens<<:>>
|
||||
Les [[filtres|Filters]] peuvent inclure les opérateur de filtrage suivant qui fonctionnent avec les liens<<:>>
|
||||
|
||||
* `[links[]]` - renvoie les titres des tiddlers dont les liens proviennent de la sélection des tiddler(s) en cours
|
||||
* `[backlinks[]]` - renvoie les titres des tiddlers destination des liens des tiddler(s) en cours sélectionnés
|
||||
|
||||
TiddlyWiki5 modifie l'apparence des liens des tiddlers pour donner plus d'informations sur la cible du lien<<:>>
|
||||
TiddlyWiki5 modifie l'apparence des liens des tiddlers pour donner plus d'informations sur la cible du lien<<:>>
|
||||
|
||||
|!Description lien |!Affichage lien |
|
||||
|Vers tiddler existant |[[Ainsi|TiddlerLinks]] |
|
||||
@@ -26,4 +26,4 @@ TiddlyWiki5 modifie l'apparence des liens des tiddlers pour donner plus d'inform
|
||||
|Vers tiddler shadow non remplacé |[[Ainsi|$:/core/copyright.txt]] |
|
||||
|Vers tiddler shadow remplacé par un tiddler ordinaire|[[Ainsi|$:/SiteTitle]] |
|
||||
|
||||
Les liens externes sont affichés comme ceci<<:>> https://tiddlywiki.com/ ou [[comme ça|https://tiddlywiki.com/]].
|
||||
Les liens externes sont affichés comme ceci<<:>> https://tiddlywiki.com/ ou [[comme ça|https://tiddlywiki.com/]].
|
||||
|
||||
46
editions/fr-FR/tiddlers/TiddlyFox Apocalypse.tid
Normal file
46
editions/fr-FR/tiddlers/TiddlyFox Apocalypse.tid
Normal file
@@ -0,0 +1,46 @@
|
||||
created: 20171109170823847
|
||||
fr-title: L'apocalypse de TiddlyFox
|
||||
modified: 20220217174448054
|
||||
tags: TiddlyFox
|
||||
title: TiddlyFox Apocalypse
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
! Résumé
|
||||
|
||||
Le 14 novembre 2017 Mozilla [[a publié Firefox 57|https://blog.mozilla.org/blog/2017/09/26/firefox-quantum-beta-developer-edition/]], une nouvelle version majeure comprenant de nombreuses améliorations et correctifs de sécurité. Toutefois, ces améliorations comportaient ''des changements fondamentaux du modèle de sécurité qui ont eu comme effet indésirable d'empêcher ~TiddlyFox de fonctionner''.
|
||||
|
||||
TiddlyFox restera disponible pour les [[utilisateurs d'anciennes versions de Firefox|https://groups.google.com/d/topic/tiddlywiki/OJQ0yRq4zog/discussion]], mais ceux qui passeront à une version plus récente devront choisir une autre façon de gérer la sauvegarde des modifications avec TiddlyWiki.
|
||||
|
||||
Heureusement, il existe de nouvelles façons de travailler avec TiddlyWiki et les utilisateurs ont de nombreux choix alternatifs (voir les détails dans <<fr GettingStarted>>). La disparition de TiddlyFox a provoqué plusieurs de ces développements récents et pourrait finalement être bénéfique pour la communauté.
|
||||
|
||||
Ces développements font l'objet d'une [[discussion|https://groups.google.com/d/topic/tiddlywiki/LcldXzPlTK0/discussion]] sur les forums TiddlyWiki.
|
||||
|
||||
! Contexte
|
||||
|
||||
Firefox a été initialement publié en novembre 2004, quelques mois après la première version de TiddlyWiki. C'était très comparable au Faucon Millénium pour l'Étoile de la Mort de Microsoft (incarnée par Internet Explorer). IE écrasait depuis 5 ans le marché des navigateurs, provoquant la frustration de nombreux développeurs web face aux extensions au HTML de Microsoft qui étaient devenus des standards //de facto// au détriment d'une innovation qui aurait pu bénéficier à l'ensemble de la communauté web.
|
||||
|
||||
Firefox a vite eu du succès car il réussissait à afficher les pages web avec un rendu assez proche d'Internet Explorer tout en offrant une meilleure expérience utilisateur. Ses avantages résidaient en grande partie dans la possibilité offerte à l'utilisateur de modifier chaque aspect du navigateur. Deux innovations étaient à l'origine de cette capacité<<:>>
|
||||
|
||||
* L'intégralité de l'interface utilisateur du navigateur était écrite en [[XUL|https://en.wikipedia.org/wiki/XUL]], une extension au HTML qui lui permettait d'afficher des interface utilisateur conventionnelles (à l'époque, le HTML était limité à un simple rendu de documents structurés). Ajuster quelques lignes de code en XUL pouvait radicalement transformer l'interface du navigateur.
|
||||
* L'architecture d'extensions de Mozilla donnait les pleins pouvoirs aux extensions, leur permettant d'observer et d'interagir profondément avec le moteur du navigateur lui-même, ainsi qu'avec le système de fichiers de l'ordinateur sur lequel il s'exécutait.
|
||||
|
||||
Ces deux conditions permirent l'épanouissement d'un large écosystème d'extensions autour de Firefox, pour certaines extrêmement populaires. Dans de nombreux cas, les innovations apportées par des extensions furent ensuite intégrées dans le navigateur, en particulier le débogueur [[Firebug|https://en.wikipedia.org/wiki/Firebug_(software)]] qui fut par la suite cloné par tous les éditeurs de navigateurs.
|
||||
|
||||
Firefox resta très populaire jusqu'à ce que Google rejoigne le développement du moteur rival ~WebKit pour développer Chome. Google choisit une approche très différente des compromis au cœur d'un navigateur, se concentrant sur l'amélioration de la sécurité au détriment de toute autre considération. Ils innovèrent avec l'isolation de chaque onglet dans un processus dédié, qui fut rapidement repris par les principaux navigateurs concurrents.
|
||||
|
||||
L'orientation de Google les empêcha d'adopter l'approche libertaire de Mozilla pour les extensions. Au lieu d'avoir accès à tout l'environnement du navigateur et au système, les extensions de Chrome ne voient qu'une petite partie de ce qui se passe dans le navigateur, et n'ont qu'un accès minimal aux ressources de l'hôte.
|
||||
|
||||
Le ralliement de Mozilla à l'approche de la [[sécurité des extensions de navigateurs|https://support.mozilla.org/en-US/kb/firefox-add-technology-modernizing]] de Google était inévitable. A ce point, Mozilla aurait été irresponsable de publier un navigateur construit sur un modèle de sécurité notoirement inférieur à celui du leader du marché.
|
||||
|
||||
! Leçons
|
||||
|
||||
Une partie de la fécondité de l'écosystème autour de TiddlyWiki provient de l'adoption des deux principes de Firefox cités précédemment<<:>>
|
||||
|
||||
* Construire l'interface utilisateur de l'application avec les mêmes primitives que son contenu
|
||||
* Permettre aux extensions d'accéder et interagir librement avec la logique interne de l'application.
|
||||
|
||||
Ces deux caractéristiques confrontent TiddlyWiki aux mêmes défis de sécurité que Firefox en son temps. Un TiddlyWiki orienté principalement vers la sécurité serait contraint de réduire ces possibilités.
|
||||
|
||||
! Le futur
|
||||
|
||||
Dans le domaine des interfaces basées sur les navigateurs et des interactions utilisateur, l'innovation a maintenant quitté les extensions pour migrer vers une nouvelle génération d'environnements qui simplifient la créations de navigateurs sur-mesure basés sur des moteurs de rendu HTML libres sur étagère. Ainsi, TiddlyDesktop utilise [[nwjs|https://nwjs.io]], et [[Beaker Browser]] utilise une alternative nommée [[Electron|https://electron.atom.io/]].
|
||||
@@ -1,17 +1,20 @@
|
||||
created: 20130825161100000
|
||||
modified: 20160602060511458
|
||||
modified: 20220217174534558
|
||||
tags: Definitions
|
||||
title: TiddlyFox
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
//~TiddlyFox// est une extension pour Firefox qui permet aux fichiers <<tw>> autonomes d'enregistrer leurs modifications directement sur le système de fichiers. //~TiddlyFox// fonctionne aussi bien sur les versions station de travail que mobile de [[Firefox]]. Voir [[Enregistrer avec TiddlyFox|Saving with TiddlyFox]] ou [[Enregistrer avec TiddlyFox pour Android|Saving with TiddlyFox on Android]] pour des instructions détaillées.
|
||||
|
||||
//~TiddlyFox// peut être téléchargé depuis le site //Mozilla Addons//<<dp>>
|
||||
~TiddlyFox est maintenant obsolète car il n'est plus compatible avec les dernières versions de Firefox (voir <<fr "TiddlyFox Apocalypse">>). Il existe de nombreuses alternatives à ~TiddlyFox, mais aucune ne fonctionne exactement de la même façon. Voir <<fr GettingStarted>> pour plus d'informations.
|
||||
|
||||
|
||||
//~TiddlyFox// peut être téléchargé depuis le site //Mozilla Addons//<<:>>
|
||||
|
||||
https://addons.mozilla.org/fr/firefox/addon/tiddlyfox/
|
||||
|
||||
<<<
|
||||
Vous pouvez également installer la dernière version de développement de ~TiddlyFox directement depuis GitHub<<dp>>
|
||||
Vous pouvez également installer la dernière version de développement de ~TiddlyFox directement depuis GitHub<<:>>
|
||||
|
||||
https://github.com/TiddlyWiki/TiddlyFox/raw/master/tiddlyfox.xpi
|
||||
<<<
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
caption: TiddlyWiki
|
||||
created: 20130822170700000
|
||||
modified: 20150622113210434
|
||||
modified: 20220219162827424
|
||||
tags: Concepts
|
||||
title: TiddlyWiki
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
~TiddlyWiki est un outil riche et interactif, capable de manipuler des données structurées complexes. Il est assez éloigné des outils conventionnels comme les traitements de texte ou les feuilles de calcul.
|
||||
<<tw>> est un outil riche et interactif, capable de manipuler des données complexes dont la structure n'est pas adaptée aux outils conventionnels comme les traitements de texte ou les feuilles de calcul.
|
||||
|
||||
~TiddlyWiki est conçu pour s'adapter à votre cerveau, en vous aidant à gérer ce qui s'adapte mal. L'[[idée fondamentale|Philosophy of Tiddlers]] est que les informations sont plus utiles et plus facilement réutilisables quand on les découpe en morceaux sémantiques aussi petits que possible -- [[les tiddlers|Tiddlers]] -- en leur donnant des titres à partir desquels le wiki pourra se [[structurer|Structuring TiddlyWiki]] à l'aide de [[liens|TiddlerLinks]], d'[[étiquettes|Tagging]], de [[listes|ListField]] et de [[macros|Macros]]. Les tiddlers utilisent une notation [[WikiTexte|WikiText]] qui permet de représenter de façon concise une grande panoplie de fonctions hypertexte et de formatage. Le but de ~TiddlyWiki est de fournir une interface de travail fluide, à même de faciliter l'agrégation des tiddlers et leur recomposition en textes plus long.
|
||||
<<tw>> est conçu pour s'adapter à votre cerveau, en vous aidant à gérer ce qui s'adapte mal. L'[[idée fondamentale|Philosophy of Tiddlers]] est que les informations sont plus utiles et plus facilement réutilisables quand on les découpe en morceaux sémantiques aussi petits que possible -- [[les tiddlers|Tiddlers]] -- en leur donnant des titres à partir desquels le wiki pourra se [[structurer|Structuring TiddlyWiki]] à l'aide de [[liens|TiddlerLinks]], d'[[étiquettes|Tagging]], de [[listes|ListField]] et de [[macros|Macros]]. Les tiddlers utilisent une notation [[WikiTexte|WikiText]] qui permet de représenter de façon concise une grande panoplie de fonctions hypertexte et de formatage. Le but de <<tw>> est de fournir une interface de travail fluide, à même de faciliter l'agrégation des tiddlers et leur recomposition en textes plus long.
|
||||
|
||||
Les gens [[adorent utiliser|Raves]] ~TiddlyWiki. Parce qu'on peut l'utiliser en l'absence d'infrastructure de serveurs compliquée, et parce qu'il est [[open source|OpenSource]], il a apporté une liberté inédite à ceux qui veulent garder le contrôle de leurs précieuses informations. ~TiddlyWiki a été créé initialement par JeremyRuston et est maintenant devenu un projet //open source// qui s'épanouit grâce à une [[communauté|Community]] active de développeurs indépendants.
|
||||
Les gens adorent utiliser <<tw>>. Comme on peut l'utiliser en l'absence d'infrastructure de serveurs compliquée, et qu'il est [[open source|OpenSource]], il a apporté une liberté inédite à ceux qui veulent garder le contrôle de leurs précieuses informations.
|
||||
|
||||
<<tw>> a été créé initialement par JeremyRuston et est maintenant devenu un projet //open source// qui s'épanouit grâce à une [[communauté|Community]] active de développeurs indépendants.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
caption: 5.2.2
|
||||
created: 20211208115905247
|
||||
modified: 20211208115905247
|
||||
created: 20220208152620527
|
||||
modified: 20220208152620527
|
||||
tags: ReleaseNotes
|
||||
title: Release 5.2.2
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -13,46 +13,122 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
! Highlights
|
||||
|
||||
*
|
||||
!! <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6421">> support for line breaks within filtered transcluded attributes
|
||||
|
||||
! Bug Fixes
|
||||
To improve readability, it is now possible to use newlines as whitespace within filtered transcluded attributes of HTML elements and widgets. For example:
|
||||
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/60187dc59e6546d9ca8e6a35418f782a9627cda0">> importing/upgrading encrypted single file wikis
|
||||
```
|
||||
<span class={{{
|
||||
[<currentTiddler>addsuffix[-primaryList]]
|
||||
:except[<searchListState>get[text]]
|
||||
:and[then[]else[tc-list-item-selected]]
|
||||
}}}>
|
||||
```
|
||||
|
||||
! Usability Improvements
|
||||
!! <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6383">> inconsistent ordering of tagged tiddlers
|
||||
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/853a899c77766e47eade1dfa5822640ef9915637">> wrapping and wikification of field names in field viewer
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/0186c6490fbd1d8fd4de7c3fa99ccf4d129fbd80">> missing whitespace between description and MIME type in edit template dropdown for the ''type'' field
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/c7e8c87f85b54f60302ff8e396a7569d996e3f67">> incorrect usage of code view for certain system tiddlers
|
||||
This was a long standing bug that manifested itself in several ways.
|
||||
|
||||
! Widget Improvements
|
||||
The root cause was that the order in which tiddlers were enumerated depended upon the order in which they had been added to the store.
|
||||
|
||||
*
|
||||
The effect was that lists based on enumerating tiddlers would show different results depending upon whether new tiddlers were added since the wiki was reloaded.
|
||||
|
||||
! Filter improvements
|
||||
For example, adding a new tiddler with a given tag previously caused the new tiddler to appear at the bottom of the tag pill listing for that tag. Saving and reloading the wiki would reorder the list to put the new tiddler in the correct position.
|
||||
|
||||
*
|
||||
The fix ensures that the enumeration order remains consistent.
|
||||
|
||||
! Hackability Improvements
|
||||
!! <<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/pull/6427">> [[Highlight Plugin]] to use highlight.js v11.4.0
|
||||
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/54cfda76ee353190f1cf0210b9071894fb1a5690">> support for ''code-body'' field set to ''yes'' to trigger display of a tiddler in the code view
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/66ae1d6930796a9eb062fdb64a755adab8f39294">> classes to the ImageWidget to indicate whether it is loading, loaded or has encountered an error
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6381">> sourceURL tags to $:/boot/boot.js and $:/boot/bootprefix.js, enabling them to be accessed in the browser debugger more easily
|
||||
This is a major upgrade to the latest version of highlight.js. The new version has many improvements, including better support for Fortran.
|
||||
|
||||
! Developer Improvements
|
||||
<<.warning """The new version of the [[Highlight Plugin]] requires a modern browser that fully supports JavaScript ES6 (released in 2015). The older version is still available as the ''highlight-legacy'' plugin for users who need to use an older browser.""">>
|
||||
|
||||
*
|
||||
! Plugin Improvements
|
||||
|
||||
! Node.js Improvements
|
||||
|
||||
*
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6428">> issue with ~LaTeX content within Markdown tiddlers
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6457">> incorrect handling of dropdown classes in the menu bar plugin
|
||||
|
||||
! Translation improvements
|
||||
|
||||
* Polish
|
||||
* Chinese
|
||||
* French
|
||||
|
||||
! Usability Improvements
|
||||
|
||||
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/6435">> wording of drag and drop banner (from "drop here" to "drop now")
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/853a899c77766e47eade1dfa5822640ef9915637">> wrapping and wikification of field names in field viewer
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/0186c6490fbd1d8fd4de7c3fa99ccf4d129fbd80">> missing whitespace between description and MIME type in edit template dropdown for the ''type'' field
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/c7e8c87f85b54f60302ff8e396a7569d996e3f67">> incorrect usage of code view for certain system tiddlers
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6501">> sidebar plugin listing to be sorted by name rather than description
|
||||
|
||||
! Widget Improvements
|
||||
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/66ae1d6930796a9eb062fdb64a755adab8f39294">> classes to the ImageWidget to indicate whether it is loading, loaded or has encountered an error
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6389">> RadioWidget not using default value if the field or index is missing
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6426">> issue with ImportVariablesWidget when importing block mode widgets
|
||||
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/6480">> DraggableWidget to support an optional drag handle
|
||||
|
||||
! Filter improvements
|
||||
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6468">> support for case insensitive matching for the [[prefix Operator]] and [[suffix Operator]]
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/1a0c831216c397c6fef8e5685e47857193411a1b">> [[sha256 Operator]]
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6438">> crash when using deprecated regexp operands for filter operators
|
||||
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/5742">> [[lookup Operator]] to support indexes as well as fields
|
||||
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/6293">> [[search Operator]] with new 'some' flag
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6478">> [[untagged Operator]] to consider non-existent tiddlers to be untagged
|
||||
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/6477">> [[insertbefore Operator]] to accept the position title as a parameter, instead of as a variable name in the suffix
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6483">> [[butlast Operator]] to be consistent with the [[rest Operator]]
|
||||
|
||||
! Hackability Improvements
|
||||
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6388">> support for directly specifying style properties on [[HTML elements|HTML in WikiText]] (for example, `<div style.color={{!!color}}>`)
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/54cfda76ee353190f1cf0210b9071894fb1a5690">> support for ''code-body'' field set to ''yes'' to trigger display of a tiddler in the code view
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6410">> support to [[WidgetMessage: tm-scroll]] for scrolling without animating
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/1d16206188ebd5ca7481a7f565bf5fc4c08239fd">> support for [[WidgetMessage: tm-relink-tiddler]]
|
||||
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/6470">> [[WidgetMessage: tm-open-window]] to support 'top' and 'left' parameters
|
||||
|
||||
! Developer Improvements
|
||||
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6409">> support for ''renderEnd()'' method for storyviews
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6381">> sourceURL tags to $:/boot/boot.js and $:/boot/bootprefix.js, enabling them to be accessed in the browser debugger more easily
|
||||
|
||||
! Node.js Improvements
|
||||
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5899">> several new web server options: [[admin|WebServer Parameter: admin]], [[required-plugins|WebServer Parameter: required-plugins]] and [[tls-passphrase|WebServer Parameter: tls-passphrase]]
|
||||
|
||||
! Performance Improvements
|
||||
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6327">> support for caching the [[listed Operator]]
|
||||
|
||||
! Bug Fixes
|
||||
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/60187dc59e6546d9ca8e6a35418f782a9627cda0">> importing/upgrading encrypted single file wikis
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6376">> [[WidgetMessage: tm-edit-text-operation]] crash with ''wrap-lines'' operation if prefix or suffix is missing
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6395">> processing of $:/tags/RawMarkupWikified/TopHead tiddlers
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6398">> issue whereby renaming tags could result in duplicate tags
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6440">> search results obscured on narrow screens
|
||||
|
||||
! Acknowledgements
|
||||
|
||||
[[@Jermolene|https://github.com/Jermolene]] would like to thank the contributors to this release who have generously given their time to help improve TiddlyWiki:
|
||||
|
||||
* <<contributor Jermolene>>
|
||||
* <<contributor benwebber>>
|
||||
* <<contributor BramChen>>
|
||||
* <<contributor btheado>>
|
||||
* <<contributor cdruan>>
|
||||
* <<contributor davout1806>>
|
||||
* <<contributor EvidentlyCube>>
|
||||
* <<contributor flibbles>>
|
||||
* <<contributor ibnishak>>
|
||||
* <<contributor jc-ose>>
|
||||
* <<contributor joshuafontany>>
|
||||
* <<contributor linonetwo>>
|
||||
* <<contributor Marxsal>>
|
||||
* <<contributor nilslindemann>>
|
||||
* <<contributor pmario>>
|
||||
* <<contributor rryan>>
|
||||
* <<contributor saqimtiaz>>
|
||||
* <<contributor slaymaker1907>>
|
||||
* <<contributor tw-FRed>>
|
||||
* <<contributor twMat>>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
title: $:/editions/tw5.com/download-empty
|
||||
code-body: yes
|
||||
|
||||
\define saveTiddlerFilter()
|
||||
[[$:/core]] [[$:/isEncrypted]] [[$:/themes/tiddlywiki/snowwhite]] [[$:/themes/tiddlywiki/vanilla]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] [[$:/config/OfficialPluginLibrary]] +[sort[title]]
|
||||
|
||||
@@ -57,8 +57,19 @@ Tests the filtering mechanism.
|
||||
);
|
||||
});
|
||||
|
||||
describe("With tiddlers in the store unsorted",function() {
|
||||
testWithAndWithoutIndexers();
|
||||
});
|
||||
describe("With tiddlers in the store sorted ascending",function() {
|
||||
testWithAndWithoutIndexers({sort: "ascending"});
|
||||
});
|
||||
describe("With tiddlers in the store sorted descending",function() {
|
||||
testWithAndWithoutIndexers({sort: "descending"});
|
||||
});
|
||||
|
||||
function testWithAndWithoutIndexers(options) {
|
||||
describe("With no indexers", function() {
|
||||
var wiki = setupWiki({enableIndexers: []});
|
||||
var wiki = setupWiki(Object.assign({},options,{enableIndexers: []}));
|
||||
it("should not create indexes when requested not to",function() {
|
||||
expect(wiki.getIndexer("FieldIndexer")).toBe(null);
|
||||
});
|
||||
@@ -66,14 +77,16 @@ Tests the filtering mechanism.
|
||||
});
|
||||
|
||||
describe("With all indexers", function() {
|
||||
var wiki = setupWiki();
|
||||
var wiki = setupWiki(options);
|
||||
if(wiki.getIndexer("FieldIndexer")) {
|
||||
wiki.getIndexer("FieldIndexer").setMaxIndexedValueLength(8); // Note that JoeBloggs is 9, and John is 5
|
||||
}
|
||||
runTests(wiki);
|
||||
});
|
||||
}
|
||||
|
||||
function setupWiki(wikiOptions) {
|
||||
wikiOptions = wikiOptions || {};
|
||||
// Create a wiki
|
||||
var wiki = new $tw.Wiki(wikiOptions);
|
||||
// Add a plugin containing some shadow tiddlers
|
||||
@@ -104,13 +117,12 @@ Tests the filtering mechanism.
|
||||
}
|
||||
}
|
||||
};
|
||||
wiki.addTiddler({
|
||||
var tiddlers = [{
|
||||
title: "$:/ShadowPlugin",
|
||||
text: JSON.stringify(shadowTiddlers),
|
||||
"plugin-type": "plugin",
|
||||
type: "application/json"});
|
||||
// Add a few tiddlers
|
||||
wiki.addTiddler({
|
||||
type: "application/json"
|
||||
},{
|
||||
title: "TiddlerOne",
|
||||
text: "The quick brown fox in $:/TiddlerTwo",
|
||||
tags: ["one"],
|
||||
@@ -119,8 +131,8 @@ Tests the filtering mechanism.
|
||||
slug: "tiddler-one",
|
||||
authors: "Joe Bloggs",
|
||||
modifier: "JoeBloggs",
|
||||
modified: "201304152222"});
|
||||
wiki.addTiddler({
|
||||
modified: "201304152222"
|
||||
},{
|
||||
title: "$:/TiddlerTwo",
|
||||
text: "The rain in Spain\nfalls mainly on the plain and [[a fourth tiddler]]",
|
||||
tags: ["two"],
|
||||
@@ -129,44 +141,75 @@ Tests the filtering mechanism.
|
||||
slug: "tiddler-two",
|
||||
authors: "[[John Doe]]",
|
||||
modifier: "John",
|
||||
modified: "201304152211"});
|
||||
wiki.addTiddler({
|
||||
modified: "201304152211"
|
||||
},{
|
||||
title: "Tiddler Three",
|
||||
text: "The speed of sound in light\n\nThere is no TiddlerZero but TiddlerSix",
|
||||
tags: ["one","two"],
|
||||
cost: "56",
|
||||
value: "80",
|
||||
modifier: "John",
|
||||
modified: "201304162202"});
|
||||
wiki.addTiddler({
|
||||
modified: "201304162202"
|
||||
},{
|
||||
title: "a fourth tiddler",
|
||||
text: "The quality of mercy is not drained by [[Tiddler Three]]",
|
||||
tags: [],
|
||||
cost: "82",
|
||||
value: "72",
|
||||
empty: "not",
|
||||
modifier: "John"});
|
||||
wiki.addTiddler({
|
||||
modifier: "John"
|
||||
},{
|
||||
title: "one",
|
||||
text: "This is the text of tiddler [[one]]",
|
||||
list: "[[Tiddler Three]] [[TiddlerOne]]",
|
||||
empty: "",
|
||||
modifier: "John"});
|
||||
wiki.addTiddler({
|
||||
modifier: "John"
|
||||
},{
|
||||
title: "hasList",
|
||||
text: "This is the text of tiddler [[hasList]]",
|
||||
list: "[[Tiddler Three]] [[TiddlerOne]]",
|
||||
modifier: "PMario"});
|
||||
wiki.addTiddler({
|
||||
modifier: "PMario"
|
||||
},{
|
||||
title: "has filter",
|
||||
text: "This is the text of tiddler [[has filter]]",
|
||||
filter: "[[Tiddler Three]] [[TiddlerOne]] [subfilter{hasList!!list}]",
|
||||
modifier: "PMario"});
|
||||
wiki.addTiddler({
|
||||
modifier: "PMario"
|
||||
},{
|
||||
title: "filter regexp test",
|
||||
text: "Those strings have been used to create the `regexp = /[+|\-|~]?([[](?:[^\]])*\]+)|([+|-|~|\S]\S*)/;`",
|
||||
filter: "+aaa -bbb ~ccc aaaaaabbbbbbbbaa \"bb'b\" 'cc\"c' [[abc]] [[tiddler with spaces]] [is[test]] [is[te st]] a s df [enlist<hugo>] +[enlist:raw{test with spaces}] [enlist:raw{test with spaces}] [[a a]] [[ ] [ ]] [[ [hugo]] [subfilter{Story/Tower of Hanoi/A-C Sequence}]",
|
||||
modifier: "PMario"});
|
||||
modifier: "PMario"
|
||||
}];
|
||||
// Load the tiddlers in the required order
|
||||
var fnCompare;
|
||||
switch(wikiOptions.sort) {
|
||||
case "ascending":
|
||||
fnCompare = function(a,b) {
|
||||
if(a.title < b.title) {
|
||||
return -1;
|
||||
} else if(a.title > b.title) {
|
||||
return +1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
break;
|
||||
case "descending":
|
||||
fnCompare = function(a,b) {
|
||||
if(a.title < b.title) {
|
||||
return +1;
|
||||
} else if(a.title > b.title) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
if(fnCompare) {
|
||||
tiddlers.sort(fnCompare);
|
||||
}
|
||||
wiki.addTiddlers(tiddlers);
|
||||
// Unpack plugin tiddlers
|
||||
wiki.readPluginInfo();
|
||||
wiki.registerPluginTiddlers("plugin");
|
||||
@@ -197,7 +240,7 @@ Tests the filtering mechanism.
|
||||
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]then[Susi]]").join(",")).toBe("Susi,Susi,Susi,Susi,Susi,Susi,Susi,Susi");
|
||||
expect(wiki.filterTiddlers("[modifier[DaveBloggs]then[Susi]]").join(",")).toBe("");
|
||||
expect(wiki.filterTiddlers("[modifier[JoeBloggs]else[Susi]]").join(",")).toBe("TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]else[Susi]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]else[Susi]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[modifier[DaveBloggs]else[Susi]]").join(",")).toBe("Susi");
|
||||
});
|
||||
|
||||
@@ -211,6 +254,8 @@ Tests the filtering mechanism.
|
||||
it("should handle the lookup operator", function() {
|
||||
expect(wiki.filterTiddlers("Six Seventh 8 +[lookup[Tiddler]]").join(",")).toBe("Missing inaction from TiddlerOne,,Tidd");
|
||||
expect(wiki.filterTiddlers("Six Seventh 8 +[lookup:8[Tiddler]]").join(",")).toBe("Missing inaction from TiddlerOne,8,Tidd");
|
||||
expect(wiki.filterTiddlers("Six Seventh 8 +[lookup:8[Tiddler],[text]]").join(",")).toBe("Missing inaction from TiddlerOne,8,Tidd");
|
||||
expect(wiki.filterTiddlers("Six Seventh 8 +[lookup[Tiddler],[tags]]").join(",")).toBe(",one,one");
|
||||
});
|
||||
|
||||
it("should retrieve shadow tiddlers", function() {
|
||||
@@ -219,31 +264,31 @@ Tests the filtering mechanism.
|
||||
|
||||
it("should handle the title operator", function() {
|
||||
expect(wiki.filterTiddlers("TiddlerOne [title[$:/TiddlerTwo]] [[Tiddler Three]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[!title[Tiddler Three]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,a fourth tiddler,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!title[Tiddler Three]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("TiddlerOne [title[$:/TiddlerTwo]] [[Tiddler Three]] [[A Missing Tiddler]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,A Missing Tiddler");
|
||||
});
|
||||
|
||||
it("should handle the field operator", function() {
|
||||
expect(wiki.filterTiddlers("[modifier[JoeBloggs]]").join(",")).toBe("TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!is[system]!modifier[JoeBloggs]]").join(",")).toBe("Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[!is[system]!modifier[JoeBloggs]]").join(",")).toBe("a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[field:modifier[JoeBloggs]]").join(",")).toBe("TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[!field:modifier[JoeBloggs]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!is[system]!field:modifier[JoeBloggs]]").join(",")).toBe("Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[modifier[John]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one");
|
||||
expect(wiki.filterTiddlers("[!modifier[John]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!is[system]!modifier[John]]").join(",")).toBe("TiddlerOne,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[field:modifier[John]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one");
|
||||
expect(wiki.filterTiddlers("[!field:modifier[John]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!is[system]!field:modifier[John]]").join(",")).toBe("TiddlerOne,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!field:modifier[JoeBloggs]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[!is[system]!field:modifier[JoeBloggs]]").join(",")).toBe("a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[modifier[John]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,one,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[!modifier[John]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,has filter,hasList,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[!is[system]!modifier[John]]").join(",")).toBe("filter regexp test,has filter,hasList,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[field:modifier[John]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,one,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[!field:modifier[John]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,has filter,hasList,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[!is[system]!field:modifier[John]]").join(",")).toBe("filter regexp test,has filter,hasList,TiddlerOne");
|
||||
});
|
||||
|
||||
it("should handle the regexp operator", function() {
|
||||
expect(wiki.filterTiddlers("[regexp[id]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler");
|
||||
expect(wiki.filterTiddlers("[!regexp[id]]").join(",")).toBe("$:/ShadowPlugin,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[regexp[Tid]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[regexp[(?i)Tid]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler");
|
||||
expect(wiki.filterTiddlers("[!regexp[Tid(?i)]]").join(",")).toBe("$:/ShadowPlugin,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[regexp[id]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[!regexp[id]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,has filter,hasList,one");
|
||||
expect(wiki.filterTiddlers("[regexp[Tid]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[regexp[(?i)Tid]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[!regexp[Tid(?i)]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,has filter,hasList,one");
|
||||
});
|
||||
|
||||
// The following 2 tests should write a log -> WARNING: Filter modifier has a deprecated regexp operand XXXX
|
||||
@@ -253,20 +298,55 @@ Tests the filtering mechanism.
|
||||
expect(wiki.filterTiddlers("[modifier/JoeBloggs/]").join(",")).toBe("TiddlerOne");
|
||||
expect(console.log).toHaveBeenCalledWith("WARNING: Filter", "modifier", "has a deprecated regexp operand", /JoeBloggs/);
|
||||
console.log.calls.reset();
|
||||
expect(wiki.filterTiddlers("[modifier/Jo/]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one");
|
||||
expect(wiki.filterTiddlers("[modifier/Jo/]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,one,Tiddler Three,TiddlerOne");
|
||||
expect(console.log).toHaveBeenCalledWith("WARNING: Filter", "modifier", "has a deprecated regexp operand", /Jo/);
|
||||
});
|
||||
|
||||
it("should handle regular expression operands without crashing", function() {
|
||||
spyOn(console, 'log');
|
||||
// We don't really care about the results. Just don't get RSoD.
|
||||
expect(() => wiki.filterTiddlers("[all/current/]")).not.toThrow();
|
||||
expect(() => wiki.filterTiddlers("[prefix/anything/]")).not.toThrow();
|
||||
expect(() => wiki.filterTiddlers("[title/anything/]")).not.toThrow();
|
||||
expect(() => wiki.filterTiddlers("[/anything/]")).not.toThrow();
|
||||
expect(() => wiki.filterTiddlers("[//]")).not.toThrow();
|
||||
});
|
||||
|
||||
it("should handle the prefix operator", function() {
|
||||
expect(wiki.filterTiddlers("[prefix[Tiddler]]").join(",")).toBe("TiddlerOne,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[prefix[Tiddler]]").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[prefix:casesensitive[tiddler]]").join(",")).toBe("");
|
||||
expect(wiki.filterTiddlers("[prefix:caseinsensitive[tiddler]]").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[prefix[nothing]]").join(",")).toBe("");
|
||||
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]prefix[]]").join(",")).toBe("ABCDE,abcde");
|
||||
});
|
||||
|
||||
it("should handle the suffix operator", function() {
|
||||
expect(wiki.filterTiddlers("[suffix[One]]").join(",")).toBe("TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[suffix:casesensitive[one]]").join(",")).toBe("one");
|
||||
expect(wiki.filterTiddlers("[suffix:caseinsensitive[one]]").join(",")).toBe("one,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[suffix[nothing]]").join(",")).toBe("");
|
||||
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]suffix[]]").join(",")).toBe("ABCDE,abcde");
|
||||
});
|
||||
|
||||
it("should handle the removeprefix operator", function() {
|
||||
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removeprefix[ABC]]").join(",")).toBe("DE");
|
||||
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removeprefix:casesensitive[ABC]]").join(",")).toBe("DE");
|
||||
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removeprefix:caseinsensitive[abc]]").join(",")).toBe("DE,de");
|
||||
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removeprefix[]]").join(",")).toBe("ABCDE,abcde");
|
||||
});
|
||||
|
||||
it("should handle the removesuffix operator", function() {
|
||||
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removesuffix[DE]]").join(",")).toBe("ABC");
|
||||
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removesuffix:casesensitive[DE]]").join(",")).toBe("ABC");
|
||||
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removesuffix:caseinsensitive[de]]").join(",")).toBe("ABC,abc")
|
||||
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removesuffix[]]").join(",")).toBe("ABCDE,abcde");
|
||||
});
|
||||
|
||||
it("should handle the sort and sortcs operators", function() {
|
||||
expect(wiki.filterTiddlers("[sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[!sort[title]]").join(",")).toBe("TiddlerOne,Tiddler Three,one,hasList,has filter,filter regexp test,a fourth tiddler,$:/TiddlerTwo,$:/ShadowPlugin");
|
||||
expect(wiki.filterTiddlers("[sort[modified]]").join(",")).toBe("$:/ShadowPlugin,a fourth tiddler,one,hasList,has filter,filter regexp test,$:/TiddlerTwo,TiddlerOne,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[!sort[modified]]").join(",")).toBe("Tiddler Three,TiddlerOne,$:/TiddlerTwo,$:/ShadowPlugin,a fourth tiddler,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[sort[modified]]").join(",")).toBe("$:/ShadowPlugin,a fourth tiddler,filter regexp test,has filter,hasList,one,$:/TiddlerTwo,TiddlerOne,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[!sort[modified]]").join(",")).toBe("Tiddler Three,TiddlerOne,$:/TiddlerTwo,$:/ShadowPlugin,a fourth tiddler,filter regexp test,has filter,hasList,one");
|
||||
// Temporarily commenting out the following two lines because of platform differences for localeCompare between the browser and Node.js
|
||||
// expect(wiki.filterTiddlers("[sortcs[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne,a fourth tiddler,one");
|
||||
// expect(wiki.filterTiddlers("[!sortcs[title]]").join(",")).toBe("one,a fourth tiddler,TiddlerOne,Tiddler Three,$:/TiddlerTwo");
|
||||
@@ -291,6 +371,7 @@ Tests the filtering mechanism.
|
||||
expect(wiki.filterTiddlers("[sort[title]reverse[]]").join(",")).toBe("TiddlerOne,Tiddler Three,one,hasList,has filter,filter regexp test,a fourth tiddler,$:/TiddlerTwo,$:/ShadowPlugin");
|
||||
expect(wiki.filterTiddlers("[sort[title]reverse[x]]").join(",")).toBe("TiddlerOne,Tiddler Three,one,hasList,has filter,filter regexp test,a fourth tiddler,$:/TiddlerTwo,$:/ShadowPlugin");
|
||||
expect(wiki.filterTiddlers("[sort[title]butlast[]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[sort[title]butlast[0]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[sort[title]butlast[2]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one");
|
||||
expect(wiki.filterTiddlers("[sort[title]butlast[11]]").join(",")).toBe("");
|
||||
expect(wiki.filterTiddlers("[sort[title]butlast[x]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
|
||||
@@ -316,10 +397,10 @@ Tests the filtering mechanism.
|
||||
expect(wiki.filterTiddlers("[all[shadows]tag[two]]").join(",")).toBe("$:/TiddlerFive");
|
||||
expect(wiki.filterTiddlers("[all[shadows+tiddlers]tag[two]]").join(",")).toBe("$:/TiddlerFive,$:/TiddlerTwo,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[all[tiddlers+shadows]tag[two]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,$:/TiddlerFive");
|
||||
expect(wiki.filterTiddlers("[all[shadows+tiddlers]]").join(",")).toBe("$:/TiddlerFive,TiddlerSix,TiddlerSeventh,Tiddler8,$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[all[tiddlers+shadows]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test,$:/TiddlerFive,TiddlerSix,TiddlerSeventh,Tiddler8");
|
||||
expect(wiki.filterTiddlers("[all[shadows+tiddlers]]").join(",")).toBe("$:/TiddlerFive,TiddlerSix,TiddlerSeventh,Tiddler8,$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[all[tiddlers+shadows]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne,$:/TiddlerFive,TiddlerSix,TiddlerSeventh,Tiddler8");
|
||||
expect(wiki.filterTiddlers("[all[tiddlers]tag[two]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[all[orphans+tiddlers+tags]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,hasList,has filter,filter regexp test,two,one");
|
||||
expect(wiki.filterTiddlers("[all[orphans+tiddlers+tags]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,Tiddler Three,TiddlerOne,two,one");
|
||||
});
|
||||
|
||||
it("should handle the tags operator", function() {
|
||||
@@ -330,11 +411,11 @@ Tests the filtering mechanism.
|
||||
it("should handle the match operator", function() {
|
||||
expect(wiki.filterTiddlers("[match[TiddlerOne]]").join(",")).toBe("TiddlerOne");
|
||||
expect(wiki.filterTiddlers("TiddlerOne TiddlerOne =[match[TiddlerOne]]").join(",")).toBe("TiddlerOne,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[!match[TiddlerOne]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!match[TiddlerOne]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[match:casesensitive[tiddlerone]]").join(",")).toBe("");
|
||||
expect(wiki.filterTiddlers("[!match:casesensitive[tiddlerone]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!match:casesensitive[tiddlerone]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[match:caseinsensitive[tiddlerone]]").join(",")).toBe("TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[!match:caseinsensitive[tiddlerone]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!match:caseinsensitive[tiddlerone]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
|
||||
});
|
||||
|
||||
it("should handle the tagging operator", function() {
|
||||
@@ -348,6 +429,9 @@ Tests the filtering mechanism.
|
||||
it("should handle the untagged operator", function() {
|
||||
expect(wiki.filterTiddlers("[untagged[]sort[title]]").join(",")).toBe("$:/ShadowPlugin,a fourth tiddler,filter regexp test,has filter,hasList,one");
|
||||
expect(wiki.filterTiddlers("[!untagged[]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne");
|
||||
// Should consider non-existent tiddlers untagged.
|
||||
expect(wiki.filterTiddlers("[enlist[a b c]untagged[]]").join(",")).toBe("a,b,c");
|
||||
expect(wiki.filterTiddlers("[enlist[a b c]!untagged[]]").join(",")).toBe("");
|
||||
});
|
||||
|
||||
it("should handle the links operator", function() {
|
||||
@@ -383,6 +467,11 @@ Tests the filtering mechanism.
|
||||
expect(wiki.filterTiddlers("[list[TiddlerSeventh]sort[title]]").join(",")).toBe("a fourth tiddler,MissingTiddler,Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[tag[one]list[TiddlerSeventh]sort[title]]").join(",")).toBe("a fourth tiddler,MissingTiddler,Tiddler Three,TiddlerOne");
|
||||
});
|
||||
|
||||
it("should handle the listed operator", function() {
|
||||
expect(wiki.filterTiddlers("TiddlerOne MissingTiddler +[listed[]]").join(",")).toBe('hasList,one');
|
||||
expect(wiki.filterTiddlers("one two +[listed[tags]]").join(",")).toBe('TiddlerOne,$:/TiddlerTwo,Tiddler Three');
|
||||
});
|
||||
|
||||
it("should handle the next operator", function() {
|
||||
expect(wiki.filterTiddlers("[[Tiddler Three]next[TiddlerSeventh]]").join(",")).toBe("a fourth tiddler");
|
||||
@@ -404,21 +493,54 @@ Tests the filtering mechanism.
|
||||
expect(wiki.filterTiddlers("[search:modifier:regexp[(d|bl)o(ggs|e)]sort[title]]").join(",")).toBe("TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[search:-modifier,authors:[g]sort[title]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[search:*:[g]sort[title]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[search:text:anchored[the]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler");
|
||||
expect(wiki.filterTiddlers("[search:text:anchored[the]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
|
||||
});
|
||||
|
||||
|
||||
it("should yield search results where 'default' search finds at least 1 token", function() {
|
||||
expect(wiki.filterTiddlers("[search::some[one two]sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,one,Tiddler Three,TiddlerOne");
|
||||
});
|
||||
|
||||
it("should yield search results where 'title' finds at least one token", function() {
|
||||
expect(wiki.filterTiddlers("[search:title:some[tiddler]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[search:title:some[tiddler one]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,one,Tiddler Three,TiddlerOne");
|
||||
});
|
||||
|
||||
it("should yield search results where 'tags' finds at least one token", function() {
|
||||
expect(wiki.filterTiddlers("[search:tags:some[one]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[search:tags:some[two]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[search:tags:some[two one]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne");
|
||||
});
|
||||
|
||||
it("should yield search results where 'tags' finds at least one token / casesensitive", function() {
|
||||
expect(wiki.filterTiddlers("[search:tags:some[ONE]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[search:tags:some,casesensitive[two ONE]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
|
||||
});
|
||||
|
||||
it("should yield search results where 'tags' finds at least one token / anchored", function() {
|
||||
expect(wiki.filterTiddlers("[search:tags:some,anchored[one]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[search:tags:some,anchored[two]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
|
||||
// search:title
|
||||
expect(wiki.filterTiddlers("[search:title:some,anchored[tiddler]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[search:title:some,anchored[tiddler one]sort[title]]").join(",")).toBe("one,Tiddler Three,TiddlerOne");
|
||||
});
|
||||
|
||||
it("should yield search results where 'tags' finds at least one token / anchored & casesensitive", function() {
|
||||
expect(wiki.filterTiddlers("[search:title:some,anchored,casesensitive[Tiddler one]sort[title]]").join(",")).toBe("one,Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[search:title:some,anchored,casesensitive[Tiddler ONE]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||
});
|
||||
|
||||
it("should yield search results that have search tokens spread across different fields", function() {
|
||||
expect(wiki.filterTiddlers("[search[fox one]sort[title]]").join(",")).toBe("TiddlerOne");
|
||||
});
|
||||
|
||||
|
||||
it("should handle the each operator", function() {
|
||||
expect(wiki.filterTiddlers("[each[modifier]sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,hasList,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[each[modifier]sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,filter regexp test,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[each:list-item[tags]sort[title]]").join(",")).toBe("one,two");
|
||||
expect(wiki.filterTiddlers("[each:list-item[authors]sort[title]]").join(",")).toBe("Bloggs,Joe,John Doe");
|
||||
});
|
||||
|
||||
it("should handle the eachday operator", function() {
|
||||
expect(wiki.filterTiddlers("[eachday[modified]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[eachday[modified]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
|
||||
});
|
||||
|
||||
it("should handle the sameday operator", function() {
|
||||
@@ -446,7 +568,7 @@ Tests the filtering mechanism.
|
||||
});
|
||||
|
||||
it("should handle the '[is[missing]]' operator", function() {
|
||||
expect(wiki.filterTiddlers("[all[]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[all[]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[all[missing]]").join(",")).toBe("TiddlerZero");
|
||||
expect(wiki.filterTiddlers("[!is[missing]sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[[TiddlerOne]is[missing]]").join(",")).toBe("");
|
||||
@@ -457,11 +579,39 @@ Tests the filtering mechanism.
|
||||
|
||||
it("should handle the '[is[orphan]]' operator", function() {
|
||||
expect(wiki.filterTiddlers("[is[orphan]sort[title]]").join(",")).toBe("a fourth tiddler,filter regexp test,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[!is[orphan]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,one,hasList,has filter");
|
||||
expect(wiki.filterTiddlers("[!is[orphan]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,has filter,hasList,one,Tiddler Three");
|
||||
expect(wiki.filterTiddlers("[[TiddlerOne]is[orphan]]").join(",")).toBe("TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[[TiddlerOne]!is[orphan]]").join(",")).toBe("");
|
||||
expect(wiki.filterTiddlers("[!title[Tiddler Three]is[orphan]sort[title]]").join(",")).toBe("a fourth tiddler,filter regexp test,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[!title[Tiddler Three]!is[orphan]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,one,hasList,has filter");
|
||||
expect(wiki.filterTiddlers("[!title[Tiddler Three]!is[orphan]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,has filter,hasList,one");
|
||||
});
|
||||
|
||||
it("should handle the '[is[draft]]' operator", function() {
|
||||
var wiki = new $tw.Wiki();
|
||||
wiki.addTiddlers([
|
||||
{title: "A"},
|
||||
{title: "Draft of 'A'", "draft.of": "A", "draft.title": "A"},
|
||||
{title: "B"},
|
||||
{title: "Draft of 'B'", "draft.of": "B"},
|
||||
{title: "C"},
|
||||
// Not a true draft. Doesn't have draft.of
|
||||
{title: "Draft of 'C'", "draft.title": "C"},
|
||||
{title: "E"},
|
||||
// Broken. Has draft.of, but it's empty. Still a draft
|
||||
{title: "Draft of 'E'", "draft.of": "", "draft.title": ""}
|
||||
// Not a draft. It doesn't exist.
|
||||
//{title: "F"} // This one is deliberately missing
|
||||
]);
|
||||
// is analagous to [has[draft.of]],
|
||||
// except they handle empty draft.of differently
|
||||
expect(wiki.filterTiddlers("[all[]] F +[is[draft]]").join(",")).toEqual("Draft of 'A',Draft of 'B',Draft of 'E'");
|
||||
expect(wiki.filterTiddlers("[all[]] F +[!is[draft]]").join(",")).toEqual("A,B,C,Draft of 'C',E,F");
|
||||
// [is[draft]] and [!is[draft]] are proper complements
|
||||
var included = wiki.filterTiddlers("[all[]] F +[is[draft]]")
|
||||
var excluded = wiki.filterTiddlers("[all[]] F +[!is[draft]]")
|
||||
var all = [].concat(included, excluded).sort();
|
||||
// combined, they should have exactly one of everything.
|
||||
expect(wiki.filterTiddlers("[all[]] F +[sort[]]")).toEqual(all);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -606,16 +756,27 @@ Tests the filtering mechanism.
|
||||
rootWidget.setVariable("tidTitle","e");
|
||||
rootWidget.setVariable("tidList","one tid with spaces");
|
||||
|
||||
// Position title specified as suffix.
|
||||
expect(wiki.filterTiddlers("a b c d e f +[insertbefore:myVar[f]]",anchorWidget).join(",")).toBe("a,b,f,c,d,e");
|
||||
expect(wiki.filterTiddlers("a b c d e f +[insertbefore:myVar<tidTitle>]",anchorWidget).join(",")).toBe("a,b,e,c,d,f");
|
||||
expect(wiki.filterTiddlers("a b c d e f +[insertbefore:myVar[gg gg]]",anchorWidget).join(",")).toBe("a,b,gg gg,c,d,e,f");
|
||||
|
||||
expect(wiki.filterTiddlers("a b c d e +[insertbefore:myVar<tidList>]",anchorWidget).join(",")).toBe("a,b,one tid with spaces,c,d,e");
|
||||
expect(wiki.filterTiddlers("a b c d e f +[insertbefore:tidTitle{TiddlerOne!!tags}]",anchorWidget).join(",")).toBe("a,b,c,d,one,e,f");
|
||||
|
||||
// Position title specified as parameter.
|
||||
expect(wiki.filterTiddlers("a b c d e +[insertbefore[f],[a]]",anchorWidget).join(",")).toBe("f,a,b,c,d,e");
|
||||
expect(wiki.filterTiddlers("a b c d e +[insertbefore[f],<myVar>]",anchorWidget).join(",")).toBe("a,b,f,c,d,e");
|
||||
|
||||
// Parameter takes precedence over suffix.
|
||||
expect(wiki.filterTiddlers("a b c d e +[insertbefore:myVar[f],[a]]",anchorWidget).join(",")).toBe("f,a,b,c,d,e");
|
||||
|
||||
// Next 2 tests do weired things, but will pass - there for compatibility reasons
|
||||
// No position title.
|
||||
expect(wiki.filterTiddlers("a b c [[with space]] +[insertbefore[b]]").join(",")).toBe("a,c,with space,b");
|
||||
expect(wiki.filterTiddlers("a b c d e +[insertbefore:2[b]]").join(",")).toBe("a,c,d,e,b");
|
||||
|
||||
// Position title does not exist.
|
||||
expect(wiki.filterTiddlers("a b c d e +[insertbefore:foo[b]]").join(",")).toBe("a,c,d,e,b");
|
||||
expect(wiki.filterTiddlers("a b c d e +[insertbefore[b],[foo]]").join(",")).toBe("a,c,d,e,b");
|
||||
expect(wiki.filterTiddlers("a b c d e +[insertbefore[b],<foo>]").join(",")).toBe("a,c,d,e,b");
|
||||
});
|
||||
|
||||
it("should handle the move operator", function() {
|
||||
@@ -775,10 +936,10 @@ Tests the filtering mechanism.
|
||||
rootWidget.setVariable("sort2","[get[text]else[]length[]]");
|
||||
rootWidget.setVariable("sort3","[{!!value}divide{!!cost}]");
|
||||
rootWidget.setVariable("sort4","[{!!title}]");
|
||||
expect(wiki.filterTiddlers("[sortsub:number<sort1>]",anchorWidget).join(",")).toBe("one,hasList,TiddlerOne,has filter,$:/TiddlerTwo,Tiddler Three,$:/ShadowPlugin,a fourth tiddler,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!sortsub:number<sort1>]",anchorWidget).join(",")).toBe("filter regexp test,a fourth tiddler,$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,TiddlerOne,has filter,hasList,one");
|
||||
expect(wiki.filterTiddlers("[sortsub:string<sort1>]",anchorWidget).join(",")).toBe("TiddlerOne,has filter,$:/TiddlerTwo,Tiddler Three,$:/ShadowPlugin,a fourth tiddler,filter regexp test,one,hasList");
|
||||
expect(wiki.filterTiddlers("[!sortsub:string<sort1>]",anchorWidget).join(",")).toBe("hasList,one,filter regexp test,a fourth tiddler,$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,TiddlerOne,has filter");
|
||||
expect(wiki.filterTiddlers("[sortsub:number<sort1>]",anchorWidget).join(",")).toBe("one,hasList,has filter,TiddlerOne,$:/TiddlerTwo,Tiddler Three,$:/ShadowPlugin,a fourth tiddler,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!sortsub:number<sort1>]",anchorWidget).join(",")).toBe("filter regexp test,a fourth tiddler,$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,has filter,TiddlerOne,hasList,one");
|
||||
expect(wiki.filterTiddlers("[sortsub:string<sort1>]",anchorWidget).join(",")).toBe("has filter,TiddlerOne,$:/TiddlerTwo,Tiddler Three,$:/ShadowPlugin,a fourth tiddler,filter regexp test,one,hasList");
|
||||
expect(wiki.filterTiddlers("[!sortsub:string<sort1>]",anchorWidget).join(",")).toBe("hasList,one,filter regexp test,a fourth tiddler,$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,has filter,TiddlerOne");
|
||||
expect(wiki.filterTiddlers("[sortsub:number<sort2>]",anchorWidget).join(",")).toBe("one,TiddlerOne,hasList,has filter,a fourth tiddler,Tiddler Three,$:/TiddlerTwo,filter regexp test,$:/ShadowPlugin");
|
||||
expect(wiki.filterTiddlers("[!sortsub:number<sort2>]",anchorWidget).join(",")).toBe("$:/ShadowPlugin,filter regexp test,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,has filter,hasList,TiddlerOne,one");
|
||||
expect(wiki.filterTiddlers("[sortsub:string<sort2>]",anchorWidget).join(",")).toBe("one,TiddlerOne,hasList,has filter,$:/ShadowPlugin,a fourth tiddler,Tiddler Three,$:/TiddlerTwo,filter regexp test");
|
||||
@@ -899,4 +1060,4 @@ Tests the filtering mechanism.
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
||||
@@ -128,6 +128,21 @@ describe("HTML tag new parser tests", function() {
|
||||
expect($tw.utils.parseAttribute("p=\"blah\" ",0)).toEqual(
|
||||
{ type : 'string', start : 0, name : 'p', value : 'blah', end : 8 }
|
||||
);
|
||||
expect($tw.utils.parseAttribute("p=\"bl\nah\" ",0)).toEqual(
|
||||
{ type : 'string', start : 0, name : 'p', value : 'bl\nah', end : 9 }
|
||||
);
|
||||
expect($tw.utils.parseAttribute("p={{{blah}}} ",0)).toEqual(
|
||||
{ type : 'filtered', start : 0, name : 'p', filter : 'blah', end : 12 }
|
||||
);
|
||||
expect($tw.utils.parseAttribute("p={{{bl\nah}}} ",0)).toEqual(
|
||||
{ type : 'filtered', start : 0, name : 'p', filter : 'bl\nah', end : 13 }
|
||||
);
|
||||
expect($tw.utils.parseAttribute("p={{{ [{$:/layout}] }}} ",0)).toEqual(
|
||||
{ type : 'filtered', start : 0, name : 'p', filter : ' [{$:/layout}] ', end : 23 }
|
||||
);
|
||||
expect($tw.utils.parseAttribute("p={{blah}} ",0)).toEqual(
|
||||
{ type : 'indirect', start : 0, name : 'p', textReference : 'blah', end : 10 }
|
||||
);
|
||||
expect($tw.utils.parseAttribute("p=blah ",0)).toEqual(
|
||||
{ type : 'string', start : 0, name : 'p', value : 'blah', end : 6 }
|
||||
);
|
||||
|
||||
@@ -392,10 +392,10 @@ describe("'reduce' and 'intersection' filter prefix tests", function() {
|
||||
rootWidget.setVariable("larger-than-18","[get[text]length[]compare:integer:gteq[18]]");
|
||||
rootWidget.setVariable("nr","18");
|
||||
rootWidget.setVariable("larger-than-18-with-var","[get[text]length[]compare:integer:gteq<nr>]");
|
||||
expect(wiki.filterTiddlers("[tag[textexample]] :filter[get[text]length[]compare:integer:gteq[18]]",anchorWidget).join(",")).toBe("Red wine,Cheesecake,Chocolate Cake");
|
||||
expect(wiki.filterTiddlers("[tag[textexample]]",anchorWidget).join(",")).toBe("Sparkling water,Red wine,Cheesecake,Chocolate Cake");
|
||||
expect(wiki.filterTiddlers("[tag[textexample]filter<larger-than-18>]",anchorWidget).join(",")).toBe("Red wine,Cheesecake,Chocolate Cake");
|
||||
expect(wiki.filterTiddlers("[tag[textexample]filter<larger-than-18-with-var>]",anchorWidget).join(",")).toBe("Red wine,Cheesecake,Chocolate Cake");
|
||||
expect(wiki.filterTiddlers("[tag[textexample]] :filter[get[text]length[]compare:integer:gteq[18]]",anchorWidget).join(",")).toBe("Cheesecake,Chocolate Cake,Red wine");
|
||||
expect(wiki.filterTiddlers("[tag[textexample]]",anchorWidget).join(",")).toBe("Cheesecake,Chocolate Cake,Red wine,Sparkling water");
|
||||
expect(wiki.filterTiddlers("[tag[textexample]filter<larger-than-18>]",anchorWidget).join(",")).toBe("Cheesecake,Chocolate Cake,Red wine");
|
||||
expect(wiki.filterTiddlers("[tag[textexample]filter<larger-than-18-with-var>]",anchorWidget).join(",")).toBe("Cheesecake,Chocolate Cake,Red wine");
|
||||
});
|
||||
|
||||
it("should handle the :sort prefix", function() {
|
||||
@@ -405,7 +405,7 @@ describe("'reduce' and 'intersection' filter prefix tests", function() {
|
||||
expect(wiki.filterTiddlers("[tag[textexample]] :sort:number:[get[text]length[]]").join(",")).toBe("Sparkling water,Chocolate Cake,Red wine,Cheesecake");
|
||||
expect(wiki.filterTiddlers("[tag[textexample]] :sort:number:reverse[get[text]length[]]").join(",")).toBe("Cheesecake,Red wine,Chocolate Cake,Sparkling water");
|
||||
expect(wiki.filterTiddlers("[tag[notatag]] :sort:number[get[price]]").join(",")).toBe("");
|
||||
expect(wiki.filterTiddlers("[tag[cakes]] :sort:string[{!!title}]").join(",")).toBe("Cheesecake,cheesecake,Chocolate Cake,chocolate cake,Persian love cake,Pound cake");
|
||||
expect(wiki.filterTiddlers("[tag[cakes]] :sort:string[{!!title}]").join(",")).toBe("cheesecake,Cheesecake,chocolate cake,Chocolate Cake,Persian love cake,Pound cake");
|
||||
expect(wiki.filterTiddlers("[tag[cakes]] :sort:string:casesensitive[{!!title}]").join(",")).toBe("Cheesecake,Chocolate Cake,Persian love cake,Pound cake,cheesecake,chocolate cake");
|
||||
expect(wiki.filterTiddlers("[tag[cakes]] :sort:string:casesensitive,reverse[{!!title}]").join(",")).toBe("chocolate cake,cheesecake,Pound cake,Persian love cake,Chocolate Cake,Cheesecake");
|
||||
});
|
||||
|
||||
@@ -102,6 +102,25 @@ function runTests(wiki,wikiOptions) {
|
||||
expect(wiki.filterTiddlers("[tag[TiddlerSeventh]]").join(",")).toBe("Tiddler10,TiddlerOne,Tiddler Three,Tiddler11,Tiddler9,a fourth tiddler");
|
||||
});
|
||||
|
||||
it("should apply identical tag ordering irrespective of tag creation order", function () {
|
||||
var wiki;
|
||||
wiki = new $tw.Wiki(wikiOptions);
|
||||
wiki.addTiddler({ title: "A", text: "", tags: "sortTag"});
|
||||
wiki.addTiddler({ title: "B", text: "", tags: "sortTag"});
|
||||
wiki.addTiddler({ title: "C", text: "", tags: "sortTag"});
|
||||
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("A,B,C");
|
||||
wiki = new $tw.Wiki(wikiOptions);
|
||||
wiki.addTiddler({ title: "A", text: "", tags: "sortTag"});
|
||||
wiki.addTiddler({ title: "C", text: "", tags: "sortTag"});
|
||||
wiki.addTiddler({ title: "B", text: "", tags: "sortTag"});
|
||||
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("A,B,C");
|
||||
wiki = new $tw.Wiki(wikiOptions);
|
||||
wiki.addTiddler({ title: "C", text: "", tags: "sortTag"});
|
||||
wiki.addTiddler({ title: "B", text: "", tags: "sortTag"});
|
||||
wiki.addTiddler({ title: "A", text: "", tags: "sortTag"});
|
||||
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("A,B,C");
|
||||
});
|
||||
|
||||
// Tests for issue (#3296)
|
||||
it("should apply tag ordering in order of dependency", function () {
|
||||
var wiki = new $tw.Wiki(wikiOptions);
|
||||
|
||||
@@ -169,6 +169,16 @@ describe("Utility tests", function() {
|
||||
expect(cv("1.1.1","1.1.2")).toEqual(-1);
|
||||
});
|
||||
|
||||
it("should insert strings into sorted arrays", function() {
|
||||
expect($tw.utils.insertSortedArray([],"a").join(",")).toEqual("a");
|
||||
expect($tw.utils.insertSortedArray(["b","c","d"],"a").join(",")).toEqual("a,b,c,d");
|
||||
expect($tw.utils.insertSortedArray(["b","c","d"],"d").join(",")).toEqual("b,c,d");
|
||||
expect($tw.utils.insertSortedArray(["b","c","d"],"f").join(",")).toEqual("b,c,d,f");
|
||||
expect($tw.utils.insertSortedArray(["b","c","d","e"],"f").join(",")).toEqual("b,c,d,e,f");
|
||||
expect($tw.utils.insertSortedArray(["b","c","g"],"f").join(",")).toEqual("b,c,f,g");
|
||||
expect($tw.utils.insertSortedArray(["b","c","d"],"ccc").join(",")).toEqual("b,c,ccc,d");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
@@ -119,7 +119,7 @@ describe("WikiText parser tests", function() {
|
||||
);
|
||||
});
|
||||
|
||||
it("should parse comment in pragma area. Comment will be INVISIBLE", function() {
|
||||
it("should parse comment in pragma area. Comment will be invisible", function() {
|
||||
expect(parse("<!-- comment in pragma area -->\n\\define aMacro()\nnothing\n\\end\n")).toEqual(
|
||||
|
||||
[ { type : 'set', attributes : { name : { type : 'string', value : 'aMacro' }, value : { type : 'string', value : 'nothing' } }, children : [ ], params : [ ], isMacroDefinition : true } ]
|
||||
@@ -127,6 +127,19 @@ describe("WikiText parser tests", function() {
|
||||
);
|
||||
});
|
||||
|
||||
it("should block mode filtered transclusions", function() {
|
||||
expect(parse("{{{ filter }}}")).toEqual(
|
||||
|
||||
[ { type: 'list', attributes: { filter: { type: 'string', value: ' filter ' } }, isBlock: true } ]
|
||||
|
||||
);
|
||||
expect(parse("{{{ fil\nter }}}")).toEqual(
|
||||
|
||||
[ { type: 'list', attributes: { filter: { type: 'string', value: ' fil\nter ' } }, isBlock: true } ]
|
||||
|
||||
);
|
||||
});
|
||||
|
||||
it("should parse inline macro calls", function() {
|
||||
expect(parse("<<john>><<paul>><<george>><<ringo>>")).toEqual(
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
created: 20150630205511173
|
||||
modified: 20150630205632460
|
||||
modified: 20220226175543038
|
||||
tags:
|
||||
title: Contributor License Agreement
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
Like other OpenSource projects, TiddlyWiki5 needs a signed contributor license agreement from individual contributors. This is a legal agreement that allows contributors to assert that they own the copyright of their contribution, and that they agree to license it to the UnaMesa Association (the legal entity that owns TiddlyWiki on behalf of the community).
|
||||
|
||||
* For individuals use: [[licenses/CLA-individual|https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-individual.md]]
|
||||
* For entities use: [[licenses/CLA-entity|https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-entity.md]]
|
||||
* For individuals use: [[licenses/CLA-individual|https://github.com/Jermolene/TiddlyWiki5/tree/tiddlywiki-com/licenses/cla-individual.md]]
|
||||
* For entities use: [[licenses/CLA-entity|https://github.com/Jermolene/TiddlyWiki5/tree/tiddlywiki-com/licenses/cla-entity.md]]
|
||||
|
||||
@@ -1,28 +1,31 @@
|
||||
created: 20140721121924384
|
||||
modified: 20201222114755959
|
||||
modified: 20220131165124489
|
||||
tags: Community
|
||||
title: Forums
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
! Users
|
||||
! Official Forums
|
||||
|
||||
The ~TiddlyWiki discussion groups are mailing lists for talking about ~TiddlyWiki: requests for help, announcements of new releases and plugins, debating new features, or just sharing experiences. You can participate via the associated website, or subscribe via email.
|
||||
The new official forum for talking about ~TiddlyWiki: requests for help, announcements of new releases and plugins, debating new features, or just sharing experiences. You can participate via the associated website, or subscribe via email.
|
||||
|
||||
* The main ~TiddlyWiki group: https://groups.google.com/group/TiddlyWiki
|
||||
*> Note that you do not need a Google Account to join the discussion groups. Subscribe by sending an email to mailto:tiddlywiki+subscribe@googlegroups.com.
|
||||
** An enhanced group search facility is available on [[mail-archive.com|https://www.mail-archive.com/tiddlywiki@googlegroups.com/]]
|
||||
* Watch recordings of our regular [[TiddlyWiki Hangouts]]
|
||||
* Follow [[@TiddlyWiki on Twitter|http://twitter.com/TiddlyWiki]] for the latest news
|
||||
* New: Join us on our live chat at https://gitter.im/TiddlyWiki/public !
|
||||
* There is also a discord available at https://discord.gg/HFFZVQ8
|
||||
https://talk.tiddlywiki.org/
|
||||
|
||||
Note that talk.tiddlywiki.org is a community run service that we host and maintain ourselves. The modest running costs are covered by community contributions.
|
||||
|
||||
! Developers
|
||||
For the convenience of existing users, we also continue to operate the original ~TiddlyWiki group (hosted on Google Groups since 2005):
|
||||
|
||||
https://groups.google.com/group/TiddlyWiki
|
||||
|
||||
! Developer Forums
|
||||
|
||||
{{Developers}}
|
||||
|
||||
New releases of TiddlyWiki, TiddlyDesktop and TiddlyFox are announced via the discussion groups and [[Twitter|https://twitter.com/TiddlyWiki]] (you can also subscribe to an Atom/RSS feed of [[TiddlyWiki releases from GitHub|https://github.com/jermolene/tiddlywiki5/releases.atom]])
|
||||
! Other Forums
|
||||
|
||||
! Documentation
|
||||
* [[TiddlyWiki Subreddit|https://www.reddit.com/r/TiddlyWiki5/]]
|
||||
* Chat with Gitter at https://gitter.im/TiddlyWiki/public !
|
||||
* Chat on Discord at https://discord.gg/HFFZVQ8
|
||||
|
||||
!! Documentation
|
||||
|
||||
There is also a discussion group specifically for discussing TiddlyWiki documentation improvement initiatives: https://groups.google.com/group/tiddlywikidocs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20150630205653005
|
||||
modified: 20190115165616599
|
||||
modified: 20220226175503241
|
||||
tags:
|
||||
title: Signing the Contributor License Agreement
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -8,7 +8,7 @@ Create a GitHub pull request to add your name to `cla-individual.md` or `cla-ent
|
||||
|
||||
''step by step''
|
||||
|
||||
# Navigate to [[licenses/CLA-individual|https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-individual.md]] or [[licenses/CLA-entity|https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-entity.md]] according to whether you are signing as an individual or representative of an organisation
|
||||
# Navigate to [[licenses/CLA-individual|https://github.com/Jermolene/TiddlyWiki5/tree/tiddlywiki-com/licenses/cla-individual.md]] or [[licenses/CLA-entity|https://github.com/Jermolene/TiddlyWiki5/tree/tiddlywiki-com/licenses/cla-entity.md]] according to whether you are signing as an individual or representative of an organisation
|
||||
# Ensure that the "branch" dropdown at the top left is set to `tiddlywiki-com`
|
||||
# Click the "edit" button at the top-right corner (clicking this button will fork the project so you can edit the file)
|
||||
# Add your name at the bottom
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20140211171341271
|
||||
modified: 20200103092706002
|
||||
modified: 20220128112317724
|
||||
tags: Concepts Reference
|
||||
title: Macros
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -14,8 +14,6 @@ They are created using the `\define` [[pragma|Pragma]]. (Behind the scenes, this
|
||||
|
||||
The snippet and its incoming parameter values are treated as simple strings of characters with no WikiText meaning, at least until the placeholders have been filled in and the macro call has returned. This means that a macro can assemble and return the complete syntax of a ~WikiText component, such as a [[link|Linking in WikiText]]. (See [[Transclusion and Substitution]] for further discussion of this.)
|
||||
|
||||
The string returned by a macro call is parsed separately from any surrounding ~WikiText components. So a safe way to insert a special character sequence (such as `[[` or `<`) without triggering its normal ~WikiText meaning is to wrap it in a macro.
|
||||
|
||||
Within a snippet itself, the only markup detected is `$name$` (a placeholder for a macro parameter) and `$(name)$` (a placeholder for a [[variable|Variables]]).
|
||||
|
||||
The <<.mlink dumpvariables>> macro lists all variables (including macros) that are available at that position in the widget tree.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
created: 20150219175930000
|
||||
modified: 20180928145730028
|
||||
tags: Concepts
|
||||
modified: 20220122182842041
|
||||
tags: Concepts [[WikiText Parser Modes]]
|
||||
title: Pragma
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
title: $:/_tw5.com/CustomStoryTiddlerTemplateDemo/Styles
|
||||
tags: $:/tags/Stylesheet
|
||||
code-body: yes
|
||||
|
||||
.tc-custom-tiddler-template {
|
||||
border: 3px solid <<colour muted-foreground>>;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
title: $:/_tw5.com/CustomStoryTiddlerTemplateDemo/Template
|
||||
code-body: yes
|
||||
|
||||
\define list-item-styles()
|
||||
transform: translate($(left)$%,$(top)$%) scale(0.3) rotate($(angle)$deg);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
title: $:/_tw5.com/CustomStoryTiddlerTemplateDemo/Filter
|
||||
tags: $:/tags/StoryTiddlerTemplateFilter
|
||||
list-before: $:/config/StoryTiddlerTemplateFilters/default
|
||||
code-body: yes
|
||||
|
||||
[tag[$:/tags/TiddlerList]then[$:/_tw5.com/CustomStoryTiddlerTemplateDemo/Template]]
|
||||
|
||||
@@ -22,5 +22,5 @@ Most files are imported as individual tiddlers. The exceptions are:
|
||||
|
||||
!! Importing content from other ~TiddlyWiki browser windows
|
||||
|
||||
Tiddlers can be imported from other ~TiddlyWiki browser windows via [[Drag and Drop]]. Drag a tiddler link or tag from one ~TiddlyWiki browser window to another. Dragging a link will import a single tiddler while dragging a tag pill will import all of the tiddlers that carry that tag.
|
||||
Tiddlers can be imported from other ~TiddlyWiki browser windows via [[Drag and Drop]]. Drag a TiddlyWiki internal link or a tag from one ~TiddlyWiki browser window to another. Dragging an internal link will import a single tiddler while dragging a tag pill will import all of the tiddlers that carry that tag.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20140410103123179
|
||||
modified: 20150203191930000
|
||||
modified: 20220226043344258
|
||||
tags: [[Filter Operators]] [[Order Operators]]
|
||||
title: butlast Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -10,4 +10,6 @@ op-parameter: an integer, defaulting to 1
|
||||
op-parameter-name: N
|
||||
op-output: all but the last <<.place N>> input titles
|
||||
|
||||
<<.from-version "5.2.2">> The <<.op butlast>> operator returns the input list unchanged if <<.place N>> is 0. This is consistent with the behaviour of the [[rest Operator]].
|
||||
|
||||
<<.operator-examples "butlast">>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20150118134611000
|
||||
modified: 20150118183143000
|
||||
modified: 20220226043344258
|
||||
tags: [[butlast Operator]] [[Operator Examples]]
|
||||
title: butlast Operator (Examples)
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -7,5 +7,6 @@ type: text/vnd.tiddlywiki
|
||||
<<.using-days-of-week>>
|
||||
|
||||
<<.operator-example 1 "[list[Days of the Week]butlast[]]">>
|
||||
<<.operator-example 2 "[list[Days of the Week]butlast[2]]">>
|
||||
<<.operator-example 3 "A B C D E F G H I J K L M +[butlast[7]]">>
|
||||
<<.operator-example 2 "[list[Days of the Week]butlast[0]]">>
|
||||
<<.operator-example 3 "[list[Days of the Week]butlast[2]]">>
|
||||
<<.operator-example 4 "A B C D E F G H I J K L M +[butlast[7]]">>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
created: 20220223004441865
|
||||
modified: 20220223004441865
|
||||
tags: [[Operator Examples]] [[insertbefore Operator]]
|
||||
title: insertbefore Operator (Examples)
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
\define before-title() Friday
|
||||
\define missing-title() Yesterday
|
||||
\define display-variable(name)
|
||||
''<$text text=<<__name__>>/>'': <code><$text text={{{ [<__name__>getvariable[]] }}}/></code>
|
||||
\end
|
||||
|
||||
These examples use the following predefined variables:
|
||||
|
||||
* <<display-variable before-title>>
|
||||
* <<display-variable missing-title>>
|
||||
|
||||
<<.operator-example 1 """[list[Days of the Week]insertbefore[Today]]""">>
|
||||
|
||||
<<.operator-example 2 """[list[Days of the Week]insertbefore[Today],[Tuesday]]""">>
|
||||
|
||||
<<.operator-example 3 """[list[Days of the Week]insertbefore[Today],<before-title>]""">>
|
||||
|
||||
<<.operator-example 4 """[list[Days of the Week]insertbefore:before-title[Today]]""">>
|
||||
|
||||
<<.operator-example 5 """[list[Days of the Week]insertbefore[Today],<missing-title>]""">>
|
||||
|
||||
<<.operator-example 6 """[list[Days of the Week]insertbefore:missing-title[Today]]""">>
|
||||
@@ -6,3 +6,8 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
<<.operator-example 1 "[all[shadows+tiddlers]tag[$:/tags/PageControls]lookup[$:/config/PageControlButtons/Visibility/]]" "Retrieve the visibility status of each page control button">>
|
||||
<<.operator-example 2 "[all[shadows+tiddlers]tag[$:/tags/PageControls]lookup:show[$:/config/PageControlButtons/Visibility/]]" "Retrieve the visibility status of each page control button, this time with a default value">>
|
||||
<<.operator-example 3 "[all[tiddlers]has[plugin-type]removeprefix[$:/plugins/tiddlywiki/]lookup:missing-description:field[$:/plugins/tiddlywiki/],[description]]" "Retrieve the description of all plugin-tiddlers that are in the `$:/plugins/tiddlywiki/` namespace.">>
|
||||
<<.operator-example 4 "OriginalTiddlerPaths +[lookup:missing-index:index[$:/config/],[HelloThere]]" "Lookup the original tiddler path on disk for the [[Hello There]] tiddler.">>
|
||||
<<.operator-example 5 "OriginalTiddlerPaths +[lookup:missing-index:index[$:/config/],[MissingTiddler]]" "Lookup the original tiddler path on disk for the [[MissingTiddler]] tiddler.">>
|
||||
<<.operator-example 6 "HistoryList MissingHistoryList +[lookup:missing-0:index[$:/]]" "Retrieve index `0` from the `$:/HistoryList` and `$:/MissingHistoryList`.">>
|
||||
<<.operator-example 7 "OriginalTiddlerPaths MissingTiddlerPaths +[lookup:missing-tiddler:index[$:/config/],[$:/key-test]]" "Retrieve index `$:/key-test` from `$:/config/OriginalTiddlerPaths` and `$:/config/MissingTiddlerPaths`.">>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
created: 20150123223129000
|
||||
modified: 20150123223321000
|
||||
modified: 20220218023400000
|
||||
tags: [[prefix Operator]] [[Operator Examples]]
|
||||
title: prefix Operator (Examples)
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.operator-example 1 "[tag[task]!prefix[Go]]">>
|
||||
<<.operator-example 2 "[prefix[$:/languages/]]">>
|
||||
<<.operator-example 3 "[prefix[$:/]]" "same as `[is[system]]`">>
|
||||
<<.operator-example 2 "[tag[task]!prefix:caseinsensitive[go]]">>
|
||||
<<.operator-example 3 "[prefix[$:/languages/]]">>
|
||||
<<.operator-example 4 "[prefix[$:/]]" "same as `[is[system]]`">>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
created: 20150118132851000
|
||||
modified: 20150123210429000
|
||||
modified: 20220218023400000
|
||||
tags: [[removeprefix Operator]] [[Operator Examples]]
|
||||
title: removeprefix Operator (Examples)
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.operator-example 1 "[[My Cat]] [[Your Garden]] [[My Favourite Armchair]] +[removeprefix[My ]]">>
|
||||
<<.operator-example 2 "[[My Cat]] [[Your Garden]] [[My Favourite Armchair]] +[removeprefix:caseinsensitive[my ]]">>
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
created: 20150118132851000
|
||||
modified: 20150123211000000
|
||||
modified: 20220218023400000
|
||||
tags: [[removesuffix Operator]] [[Operator Examples]]
|
||||
title: removesuffix Operator (Examples)
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.operator-example 1 "SIMPLEX Googolplex Complex +[removesuffix[plex]]">>
|
||||
|
||||
|
||||
<<.operator-example 2 "SIMPLEX Googolplex Complex +[removesuffix:caseinsensitive[plex]]">>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20150118134611000
|
||||
modified: 20150123211722000
|
||||
modified: 20220226043344258
|
||||
tags: [[rest Operator]] [[Operator Examples]]
|
||||
title: rest Operator (Examples)
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -7,5 +7,6 @@ type: text/vnd.tiddlywiki
|
||||
<<.using-days-of-week>>
|
||||
|
||||
<<.operator-example 1 "[list[Days of the Week]rest[]]">>
|
||||
<<.operator-example 2 "[list[Days of the Week]rest[3]]">>
|
||||
<<.operator-example 3 "Z Y X W V U T S R Q P O +[rest[5]]">>
|
||||
<<.operator-example 2 "[list[Days of the Week]rest[0]]">>
|
||||
<<.operator-example 3 "[list[Days of the Week]rest[3]]">>
|
||||
<<.operator-example 4 "Z Y X W V U T S R Q P O +[rest[5]]">>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20150124104508000
|
||||
modified: 20181025082022690
|
||||
modified: 20211129122755444
|
||||
tags: [[search Operator]] [[Operator Examples]]
|
||||
title: search Operator (Examples)
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -13,3 +13,8 @@ type: text/vnd.tiddlywiki
|
||||
<$macrocall $name=".operator-example" n="7" eg="[!is[system]search::literal[the first]]" ie="non-system tiddlers containing a case-insensitive match for the literal phrase <<.word 'the first'>>"/>
|
||||
<$macrocall $name=".operator-example" n="8" eg="[!is[system]search::literal,casesensitive[The first]]" ie="non-system tiddlers containing a case-sensitive match for the literal phrase <<.word 'The first'>>"/>
|
||||
<$macrocall $name=".operator-example" n="9" eg="[search:caption,description:casesensitive,words[arch]]" ie="any tiddlers containing a case-sensitive match for the word `arch` in their <<.field caption>> or <<.field description>> fields"/>
|
||||
<$macrocall $name=".operator-example" n="10" eg="[search:tags:some[how test]]" ie="any tiddlers containing at least 1 of the search terms in the field: <<.field tags>>"/>
|
||||
<$macrocall $name=".operator-example" n="11" eg="[search:tags:some,casesensitive[how test]]" ie="any tiddlers containing at least 1 of the case-sensitive search terms in the field: <<.field tags>>"/>
|
||||
<$macrocall $name=".operator-example" n="12" eg="[search:tags,title:some,anchored[how test]]" ie="any tiddlers containing at least 1 of anchored search terms in the fields: <<.field tags>> and <<.field title>>"/>
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
created: 20150124113652000
|
||||
modified: 20150124113925000
|
||||
modified: 20220218023400000
|
||||
tags: [[suffix Operator]] [[Operator Examples]]
|
||||
title: suffix Operator (Examples)
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.operator-example 1 "[suffix[.jpg]]">>
|
||||
<<.operator-example 2 "[tag[task]!suffix[ing]]">>
|
||||
<<.operator-example 2 "[suffix:caseinsensitive[.JPG]]">>
|
||||
<<.operator-example 3 "[tag[task]!suffix[ing]]">>
|
||||
|
||||
@@ -1,15 +1,31 @@
|
||||
caption: insertbefore
|
||||
created: 20170406090122441
|
||||
modified: 20170406091248994
|
||||
modified: 20220223004441865
|
||||
op-input: a [[selection of titles|Title Selection]]
|
||||
op-output: the input tiddler list with the new entry inserted
|
||||
op-parameter: the title of the tiddler to insert
|
||||
op-parameter-name: T
|
||||
op-parameter: <<.from-version "5.2.2">> the <<.op insertbefore>> operator accepts 1 or 2 parameters, see below for details
|
||||
op-purpose: insert an item <<.place T>> into a list immediately before an item <<.place B>>
|
||||
op-suffix: the name of a variable containing the title of the tiddler before which this one should be inserted
|
||||
op-suffix-name: B
|
||||
op-suffix: (optional) the name of a variable containing the title of the tiddler before which this one should be inserted
|
||||
tags: [[Filter Operators]] [[Order Operators]] [[Listops Operators]]
|
||||
title: insertbefore Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.from-version "5.2.2">>
|
||||
|
||||
The <<.op insertbefore>> operator requires at least one parameter which specifies the title to insert into the input list. A second parameter can be used to specify the title before which the new title should be inserted.
|
||||
|
||||
```
|
||||
insertbefore:<before-title-variable>[<title>],[<before-title>]
|
||||
```
|
||||
|
||||
* ''title'' : a title <<.place T>> to insert in the input list.
|
||||
* ''before-title'' : (optional). Insert <<.place T>> before this title <<.place B>> in the input list.
|
||||
* ''before-title-variable'' : (optional). The name of a variable specifying <<.place B>> instead of the `before-title` parameter.
|
||||
|
||||
If the item <<.place B>> isn't present in the input list then the new item is inserted at the end of the list.
|
||||
|
||||
<<.tip "Either [[parameter|Filter Parameter]] can be a string, a text reference or a variable">>
|
||||
|
||||
<<.tip "If <<.place B>> is specified as both a suffix and a parameter, the parameter takes precedence">>
|
||||
|
||||
<<.operator-examples "insertbefore">>
|
||||
|
||||
@@ -1,24 +1,42 @@
|
||||
caption: lookup
|
||||
created: 20170907103639431
|
||||
modified: 20170907144703051
|
||||
modified: 20210116081305739
|
||||
op-input: a [[selection of titles|Title Selection]]
|
||||
op-output: the lookup values corresponding to each input title
|
||||
op-parameter: prefix applied to input titles to yield title of lookup tiddler from which value is retrieved
|
||||
op-parameter-name: P
|
||||
op-purpose: applies a prefix to each input title to yield the title of a tiddler from which the final value is retrieved
|
||||
op-suffix: the default value to be used for missing lookups
|
||||
op-suffix-name: D
|
||||
op-output: the lookup values corresponding to each lookup tiddler
|
||||
op-parameter: prefix applied to input titles to yield title of lookup tiddler from which value is retrieved. Now accepts 1 or 2 parameters, see below for details
|
||||
op-parameter-name: P, T
|
||||
op-purpose: applies a prefix to each input title to yield the title of a tiddler from which the final value is retrieved. With a single parameter, the default field is "text" and the default index is "0". If a second parameter is provided, that becomes the target field or index.
|
||||
op-suffix: the default value to be used for missing lookups. This operator can now accept a second suffix of `:index`, see below for details
|
||||
op-suffix-name: D, I
|
||||
tags: [[Filter Operators]]
|
||||
title: lookup Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.from-version "5.1.15">>
|
||||
|
||||
The action of this operator is as follows:
|
||||
The action of this operator is as follows with 1 parameter:
|
||||
|
||||
* Apply the specified prefix to each input tiddler title, yielding a new list of tiddler titles
|
||||
* Transclude the value of each of those tiddlers
|
||||
** Substitute the default value for missing or empty tiddlers
|
||||
* Transclude the value of the `text` field each of those tiddlers
|
||||
** Substitute the default value for missing or empty values
|
||||
* Return the list of values
|
||||
|
||||
<<.from-version "5.2.2">>
|
||||
|
||||
The use of the `:index` second suffix changes the default lookup location from field: `text` to index: `0`. This is used if no 2nd parameter is provided.
|
||||
|
||||
The action of this operator is as follows with 2 parameters:
|
||||
|
||||
If there are two parameters provided, use the second parameter as the target field or index.
|
||||
|
||||
<<.note """If there is only one parameter given, the filter checks for a second suffix equal to "index". If this suffix is found, the default target index is "0".
|
||||
In all other cases, the default target field is "text".""">>
|
||||
|
||||
Then:
|
||||
|
||||
* Apply the specified prefix to each input tiddler title, yielding a new list of tiddler titles
|
||||
* Transclude the value of the target field or index
|
||||
** Substitute the default value for missing or empty values
|
||||
* Return the list of values
|
||||
|
||||
<<.operator-examples "lookup">>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20140410103123179
|
||||
modified: 20150203192735000
|
||||
modified: 20220218023400000
|
||||
tags: [[Filter Operators]] [[String Operators]] [[Negatable Operators]]
|
||||
title: prefix Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -10,7 +10,22 @@ op-parameter: a string of characters
|
||||
op-parameter-name: S
|
||||
op-output: those input titles that start with <<.place S>>
|
||||
op-neg-output: those input tiddlers that do <<.em not>> start with <<.place S>>
|
||||
op-suffix: the <<.op prefix>> operator uses a rich suffix, see below for details
|
||||
|
||||
<<.s-matching-is-case-sensitive>>
|
||||
<<.from-version "5.2.2">>
|
||||
|
||||
The <<.op prefix>> operator uses an extended syntax that permits multiple flags to be passed:
|
||||
|
||||
```
|
||||
[prefix:<flag list>[<operand>]]
|
||||
```
|
||||
|
||||
* ''flag list'': a comma delimited list of flags
|
||||
* ''operand'': filter operand
|
||||
|
||||
The available flags are:
|
||||
|
||||
* ''casesensitive'': (default), this flag forces a case-sensitive match, where upper and lower case letters are considered different
|
||||
* ''caseinsensitive'': overrides the default so that upper and lower case letters are considered identical for matching purposes
|
||||
|
||||
<<.operator-examples "prefix">>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20140410103123179
|
||||
modified: 20150203190709000
|
||||
modified: 20220218023400000
|
||||
tags: [[Filter Operators]] [[String Operators]]
|
||||
title: removeprefix Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -9,9 +9,24 @@ op-input: a [[selection of titles|Title Selection]]
|
||||
op-parameter: a string of characters
|
||||
op-parameter-name: S
|
||||
op-output: those input titles that start with <<.place S>>, but with those characters discarded
|
||||
|
||||
<<.s-matching-is-case-sensitive>>
|
||||
op-suffix: the <<.op removeprefix>> operator uses a rich suffix, see below for details
|
||||
|
||||
<<.tip " This filters out input titles that do not start with S. For removing S without filtering out input titles that don't start with S, see [[trim|trim Operator]].">>
|
||||
|
||||
<<.from-version "5.2.2">>
|
||||
|
||||
The <<.op removeprefix>> operator uses an extended syntax that permits multiple flags to be passed:
|
||||
|
||||
```
|
||||
[removeprefix:<flag list>[<operand>]]
|
||||
```
|
||||
|
||||
* ''flag list'': a comma delimited list of flags
|
||||
* ''operand'': filter operand
|
||||
|
||||
The available flags are:
|
||||
|
||||
* ''casesensitive'': (default), this flag forces a case-sensitive match, where upper and lower case letters are considered different
|
||||
* ''caseinsensitive'': overrides the default so that upper and lower case letters are considered identical for matching purposes
|
||||
|
||||
<<.operator-examples "removeprefix">>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20140828133830424
|
||||
modified: 20150203190744000
|
||||
modified: 20220218023400000
|
||||
tags: [[Filter Operators]] [[String Operators]]
|
||||
title: removesuffix Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -9,9 +9,24 @@ op-input: a [[selection of titles|Title Selection]]
|
||||
op-parameter: a string of characters
|
||||
op-parameter-name: S
|
||||
op-output: those input titles that end with <<.place S>>, but with those characters discarded
|
||||
|
||||
<<.s-matching-is-case-sensitive>>
|
||||
op-suffix: the <<.op removesuffix>> operator uses a rich suffix, see below for details
|
||||
|
||||
<<.tip " This filters out input titles that do not end with S. For removing S without filtering out input titles that don't end with S, see [[trim|trim Operator]].">>
|
||||
|
||||
<<.from-version "5.2.2">>
|
||||
|
||||
The <<.op removesuffix>> operator uses an extended syntax that permits multiple flags to be passed:
|
||||
|
||||
```
|
||||
[removesuffix:<flag list>[<operand>]]
|
||||
```
|
||||
|
||||
* ''flag list'': a comma delimited list of flags
|
||||
* ''operand'': filter operand
|
||||
|
||||
The available flags are:
|
||||
|
||||
* ''casesensitive'': (default), this flag forces a case-sensitive match, where upper and lower case letters are considered different
|
||||
* ''caseinsensitive'': overrides the default so that upper and lower case letters are considered identical for matching purposes
|
||||
|
||||
<<.operator-examples "removesuffix">>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
caption: search
|
||||
created: 20140410103123179
|
||||
modified: 20190731212738712
|
||||
modified: 20211129120739275
|
||||
op-input: a [[selection of titles|Title Selection]]
|
||||
op-neg-output: those input tiddlers in which <<.em not>> all of the search terms can be found
|
||||
op-output: those input tiddlers in which <<.em all>> of the search terms can be found in the value of field <<.place F>>
|
||||
op-parameter: one or more search terms, separated by spaces, or a literal search string
|
||||
op-purpose: filter the input by searching tiddler content
|
||||
op-suffix: the <<.op search>> operator uses a rich suffix, see below for details
|
||||
tags: [[Filter Operators]] [[Common Operators]] [[Field Operators]] [[Negatable Operators]]
|
||||
title: search Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
caption: search
|
||||
op-purpose: filter the input by searching tiddler content
|
||||
op-input: a [[selection of titles|Title Selection]]
|
||||
op-suffix: the <<.op search>> operator uses a rich suffix, see below for details
|
||||
op-parameter: one or more search terms, separated by spaces, or a literal search string
|
||||
op-output: those input tiddlers in which <<.em all>> of the search terms can be found in the value of field <<.place F>>
|
||||
op-neg-output: those input tiddlers in which <<.em not>> all of the search terms can be found
|
||||
|
||||
<<.from-version "5.1.18">> The search filter operator was significantly enhanced in 5.1.18. Earlier versions do not support the extended syntax and therefore do not permit searching multiple fields, or the ''literal'' or ''casesensitive'' options.
|
||||
|
||||
@@ -38,7 +38,8 @@ The available flags are:
|
||||
** ''literal'': considers the search string to be a literal string, and requires an exact match
|
||||
** ''whitespace'': considers the search string to be a literal string, but will consider all runs of whitespace to be equivalent to a single space. Thus `A B` matches `A B`
|
||||
** ''regexp'': treats the search string as a regular expression. Note that the ''regexp'' option obviates the need for the older <<.olink regexp>> operator.
|
||||
** ''words'': (the default) treats the search string as a list of tokens separated by whitespace, and matches if all of the tokens appear in the string (regardless of ordering and whether there is other text in between)
|
||||
** ''words'': (the default) treats the search string as a list of tokens separated by whitespace, and matches if ''all of the tokens'' appear in the string (regardless of ordering and whether there is other text in between)
|
||||
** ''some'': <<.from-version "5.2.2">> treats the search string as a list of tokens separated by whitespace, and matches if ''at least one'' of the tokens appear in the string
|
||||
* ''casesensitive'': if present, this flag forces a case-sensitive match, where upper and lower case letters are considered different. By default, upper and lower case letters are considered identical for matching purposes.
|
||||
* ''anchored'': <<.from-version "5.1.20">> anchors the search to the start of the string (applies to ''whitespace'', ''literal'' and ''words'' modes)
|
||||
|
||||
|
||||
18
editions/tw5.com/tiddlers/filters/sha256 Operator.tid
Normal file
18
editions/tw5.com/tiddlers/filters/sha256 Operator.tid
Normal file
@@ -0,0 +1,18 @@
|
||||
caption: sha256
|
||||
created: 20220129105504961
|
||||
modified: 20220129105504961
|
||||
op-input: a [[selection of titles|Title Selection]]
|
||||
op-output: the base64 encoded sha256 of the input, truncated to the specified length
|
||||
op-parameter: the number of characters to return, up to a maximum of 64
|
||||
op-parameter-name: L
|
||||
op-purpose: apply sha256 hash to a string
|
||||
tags: [[Filter Operators]] [[String Operators]]
|
||||
title: sha256 Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
from-version: 5.1.14
|
||||
|
||||
Hashes are a way of turning strings of arbitrary length into obfuscated strings of fixed length. They are often used in situations where items need to be stored by name but it is inconvenient to allow arbitrary length strings.
|
||||
|
||||
See Wikipedia for details of the [[sha256|https://en.wikipedia.org/wiki/SHA-2]] operation.
|
||||
|
||||
<<.operator-examples "sha256">>
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20140828133830424
|
||||
modified: 20150203192738000
|
||||
modified: 20220218023400000
|
||||
tags: [[Filter Operators]] [[String Operators]] [[Negatable Operators]]
|
||||
title: suffix Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -10,7 +10,22 @@ op-parameter: a string of characters
|
||||
op-parameter-name: S
|
||||
op-output: those input titles that end with <<.place S>>
|
||||
op-neg-output: those input tiddlers that do <<.em not>> end with <<.place S>>
|
||||
op-suffix: the <<.op suffix>> operator uses a rich suffix, see below for details
|
||||
|
||||
<<.s-matching-is-case-sensitive>>
|
||||
<<.from-version "5.2.2">>
|
||||
|
||||
The <<.op suffix>> operator uses an extended syntax that permits multiple flags to be passed:
|
||||
|
||||
```
|
||||
[suffix:<flag list>[<operand>]]
|
||||
```
|
||||
|
||||
* ''flag list'': a comma delimited list of flags
|
||||
* ''operand'': filter operand
|
||||
|
||||
The available flags are:
|
||||
|
||||
* ''casesensitive'': (default), this flag forces a case-sensitive match, where upper and lower case letters are considered different
|
||||
* ''caseinsensitive'': overrides the default so that upper and lower case letters are considered identical for matching purposes
|
||||
|
||||
<<.operator-examples "suffix">>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
created: 20130822170200000
|
||||
list: [[A Gentle Guide to TiddlyWiki]] [[Discover TiddlyWiki]] [[Some of the things you can do with TiddlyWiki]] [[Ten reasons to switch to TiddlyWiki]] Examples [[What happened to the original TiddlyWiki?]] [[HelloThumbnail - TWEUM2017]]
|
||||
modified: 20211208115833846
|
||||
modified: 20220131164555580
|
||||
tags: TableOfContents
|
||||
title: HelloThere
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -18,8 +18,8 @@ Use it to keep your [[to-do list|TaskManagementExample]], to plan an [[essay or
|
||||
Unlike conventional online services, TiddlyWiki lets you choose where to keep your data, guaranteeing that in the decades to come you will [[still be able to use|Future Proof]] the notes you take today.
|
||||
|
||||
<div style="font-size:0.7em;text-align:center;margin:3em auto;">
|
||||
<a href="https://groups.google.com/group/TiddlyWiki" class="tc-btn-big-green" style="border-radius:4px;background-color:#FF8C19;" target="_blank" rel="noopener noreferrer">
|
||||
{{$:/core/images/help}} Forum
|
||||
<a href="https://talk.tiddlywiki.org/" class="tc-btn-big-green" style="border-radius:4px;background-color:#FF8C19;" target="_blank" rel="noopener noreferrer">
|
||||
{{$:/core/images/help}} ~TalkTW
|
||||
</a>
|
||||
<a href="https://www.youtube.com/c/JeremyRuston" class="tc-btn-big-green" style="border-radius:4px;background-color:#e52d27;" target="_blank" rel="noopener noreferrer">
|
||||
{{$:/core/images/video}} ~YouTube
|
||||
|
||||
@@ -7,8 +7,6 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
The <<.def list-links-draggable>> [[macro|Macros]] renders the ListField of a tiddler as a list of links that can be reordered via [[drag and drop|Drag and Drop]].
|
||||
|
||||
Note: The list must be contained in a different tiddler. I.e. If the list is populated in the list field of the current tiddler, the drag and drop action will have no effect.
|
||||
|
||||
!! Parameters
|
||||
|
||||
;tiddler
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
created: 20220301162305764
|
||||
modified: 20220301180818011
|
||||
tags: Messages
|
||||
title: WidgetMessage: tm-close-all-windows
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.from-version 5.2.2>>
|
||||
The `tm-close-all-windows` [[message|Messages]] closes all additional //browser// window that were opened with [[tm-open-window|WidgetMessage: tm-open-window]].
|
||||
|
||||
The `tm-close-window` message is best generated with the ActionSendMessageWidget, which in turn is triggered by a widget such as the ButtonWidget. It is handled by the core itself.
|
||||
|
||||
<$macrocall $name='wikitext-example-without-html'
|
||||
src="""
|
||||
<$button>Close All Windows
|
||||
<$action-sendmessage
|
||||
$message="tm-close-all-windows"
|
||||
/>
|
||||
</$button>
|
||||
""" />
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
caption: tm-open-window
|
||||
created: 20220228140417116
|
||||
modified: 20220301180905777
|
||||
tags: Messages
|
||||
title: WidgetMessage: tm-close-window
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.from-version 5.2.2>>
|
||||
The `tm-close-window` [[message|Messages]] closes an additional //browser// window that was opened with [[tm-open-window|WidgetMessage: tm-open-window]]. Specify which window to close by setting the value of <<.param param>> to the string used as <<.param windowID>> when opening the window.
|
||||
|
||||
|!Name |!Description |
|
||||
|param //{default param}// |String used as <<.param windowID>> when opening the window |
|
||||
|
||||
The `tm-close-window` message is best generated with the ActionSendMessageWidget, which in turn is triggered by a widget such as the ButtonWidget. It is handled by the core itself.
|
||||
|
||||
<<.tip """When used with the ActionSendMessageWidget, <<.param 'param'>> becomes <<.param '$param'>> """>>
|
||||
<<.tip """To close all additional browser windows that were opened with [[tm-open-window|WidgetMessage: tm-open-window]] use [[WidgetMessage: tm-close-all-windows]]""">>
|
||||
|
||||
<$macrocall $name='wikitext-example-without-html'
|
||||
src="""
|
||||
<$button>Open Window
|
||||
<$action-sendmessage
|
||||
$message="tm-open-window"
|
||||
$param="$:/temp/openme"
|
||||
template="SampleWindowTemplate"
|
||||
windowTitle="My Window Title"
|
||||
width="400"
|
||||
height="500"
|
||||
windowID="window1"
|
||||
something="I just in over in a variable, and boy is my Hashmap tired." />
|
||||
</$button>
|
||||
<$button>Close Window
|
||||
<$action-sendmessage
|
||||
$message="tm-close-window"
|
||||
$param="window1"
|
||||
/>
|
||||
</$button>
|
||||
""" />
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user