mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-02-13 13:39:50 +00:00
Compare commits
76 Commits
core-icons
...
camelcase-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45551d3b0c | ||
|
|
2f3a461bab | ||
|
|
9ad19f872f | ||
|
|
e21c39d471 | ||
|
|
ea831d25fd | ||
|
|
48b22abdaa | ||
|
|
a371ea0555 | ||
|
|
68a7655396 | ||
|
|
f19e74900e | ||
|
|
df323fe3c9 | ||
|
|
4e7a6ffc22 | ||
|
|
bc3a7d9826 | ||
|
|
90f0ff8067 | ||
|
|
74e0619782 | ||
|
|
86e5fbce5d | ||
|
|
fb79bebef4 | ||
|
|
5d0043012a | ||
|
|
fec7e8791d | ||
|
|
f2c458a722 | ||
|
|
86524aafbd | ||
|
|
442e3f1e97 | ||
|
|
a9380655a0 | ||
|
|
9b59dff275 | ||
|
|
3f763775d6 | ||
|
|
9b78e871aa | ||
|
|
d4846bae6c | ||
|
|
6941d079b8 | ||
|
|
e62f86a4c7 | ||
|
|
8e132948b6 | ||
|
|
6a12b15fac | ||
|
|
990909c310 | ||
|
|
8ad08b0cd4 | ||
|
|
a4da53ef6c | ||
|
|
2e377b1f48 | ||
|
|
70ee30fdf3 | ||
|
|
d5a7425458 | ||
|
|
fb10b1ee91 | ||
|
|
576d476a21 | ||
|
|
8aa0db59a3 | ||
|
|
9d6784f262 | ||
|
|
61e2ad4286 | ||
|
|
db6b4f17e8 | ||
|
|
2ab28cc2b8 | ||
|
|
1af4324370 | ||
|
|
3da0a9431c | ||
|
|
1f35b945a5 | ||
|
|
5124cbc776 | ||
|
|
9f1eab175d | ||
|
|
8f4b22110c | ||
|
|
8ad35a9411 | ||
|
|
18d7d3d8c0 | ||
|
|
3518e257c0 | ||
|
|
fe716dd58f | ||
|
|
e2fe681b50 | ||
|
|
36ac142110 | ||
|
|
e66e791944 | ||
|
|
474b73bdbe | ||
|
|
2b95daf59b | ||
|
|
2bfefe3880 | ||
|
|
96f97f237a | ||
|
|
9cdb38d800 | ||
|
|
4e96a012f6 | ||
|
|
e92e125697 | ||
|
|
6820d45bf0 | ||
|
|
d6533b9ee1 | ||
|
|
3ee5f10362 | ||
|
|
a6ced74a13 | ||
|
|
b61aef27d7 | ||
|
|
a1b706a945 | ||
|
|
2340d48844 | ||
|
|
4e641f4fc0 | ||
|
|
17f18daa89 | ||
|
|
b2aeea0393 | ||
|
|
48b7b5d294 | ||
|
|
1cac177211 | ||
|
|
6da74c6104 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
.DS_Store
|
||||
.c9/
|
||||
.vs/
|
||||
.vscode/
|
||||
tmp/
|
||||
output/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# Default to the current version number for building the plugin library
|
||||
|
||||
if [ -z "$TW5_BUILD_VERSION" ]; then
|
||||
TW5_BUILD_VERSION=v5.2.8
|
||||
TW5_BUILD_VERSION=v5.3.0
|
||||
fi
|
||||
|
||||
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
||||
|
||||
66
boot/boot.js
66
boot/boot.js
@@ -569,10 +569,23 @@ $tw.utils.getTypeEncoding = function(ext) {
|
||||
return typeInfo ? typeInfo.encoding : "utf8";
|
||||
};
|
||||
|
||||
var globalCheck =[
|
||||
" Object.defineProperty(Object.prototype, '__temp__', {",
|
||||
" get: function () { return this; },",
|
||||
" configurable: true",
|
||||
" });",
|
||||
" if(Object.keys(__temp__).length){",
|
||||
" console.log(Object.keys(__temp__));",
|
||||
" delete Object.prototype.__temp__;",
|
||||
" throw \"Global assignment is not allowed within modules on node.\";",
|
||||
" }",
|
||||
" delete Object.prototype.__temp__;",
|
||||
].join('\n');
|
||||
|
||||
/*
|
||||
Run code globally with specified context variables in scope
|
||||
*/
|
||||
$tw.utils.evalGlobal = function(code,context,filename) {
|
||||
$tw.utils.evalGlobal = function(code,context,filename,sandbox,allowGlobals) {
|
||||
var contextCopy = $tw.utils.extend(Object.create(null),context);
|
||||
// Get the context variables as a pair of arrays of names and values
|
||||
var contextNames = [], contextValues = [];
|
||||
@@ -581,25 +594,38 @@ $tw.utils.evalGlobal = function(code,context,filename) {
|
||||
contextValues.push(value);
|
||||
});
|
||||
// Add the code prologue and epilogue
|
||||
code = "(function(" + contextNames.join(",") + ") {(function(){\n" + code + "\n;})();\nreturn exports;\n})\n";
|
||||
code = [
|
||||
"(function(" + contextNames.join(",") + ") {",
|
||||
" (function(){\n" + code + "\n;})();",
|
||||
(!$tw.browser && sandbox && !allowGlobals) ? globalCheck : "",
|
||||
" return exports;\n",
|
||||
"})"
|
||||
].join("\n");
|
||||
|
||||
// Compile the code into a function
|
||||
var fn;
|
||||
if($tw.browser) {
|
||||
fn = window["eval"](code + "\n\n//# sourceURL=" + filename);
|
||||
} else {
|
||||
fn = vm.runInThisContext(code,filename);
|
||||
if(sandbox){
|
||||
fn = vm.runInContext(code,sandbox,filename)
|
||||
} else {
|
||||
fn = vm.runInThisContext(code,filename);
|
||||
}
|
||||
}
|
||||
// Call the function and return the exports
|
||||
return fn.apply(null,contextValues);
|
||||
};
|
||||
|
||||
$tw.utils.sandbox = !$tw.browser ? vm.createContext({}) : undefined;
|
||||
/*
|
||||
Run code in a sandbox with only the specified context variables in scope
|
||||
*/
|
||||
$tw.utils.evalSandboxed = $tw.browser ? $tw.utils.evalGlobal : function(code,context,filename) {
|
||||
var sandbox = $tw.utils.extend(Object.create(null),context);
|
||||
vm.runInNewContext(code,sandbox,filename);
|
||||
return sandbox.exports;
|
||||
$tw.utils.evalSandboxed = $tw.browser ? $tw.utils.evalGlobal : function(code,context,filename,allowGlobals) {
|
||||
return $tw.utils.evalGlobal(
|
||||
code,context,filename,
|
||||
allowGlobals ? vm.createContext({}) : $tw.utils.sandbox,
|
||||
allowGlobals
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1920,7 +1946,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
||||
// Read the specification
|
||||
var filesInfo = $tw.utils.parseJSONSafe(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"));
|
||||
// Helper to process a file
|
||||
var processFile = function(filename,isTiddlerFile,fields,isEditableFile) {
|
||||
var processFile = function(filename,isTiddlerFile,fields,isEditableFile,rootPath) {
|
||||
var extInfo = $tw.config.fileExtensionInfo[path.extname(filename)],
|
||||
type = (extInfo || {}).type || fields.type || "text/plain",
|
||||
typeInfo = $tw.config.contentTypeInfo[type] || {},
|
||||
@@ -1941,6 +1967,12 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
||||
} else {
|
||||
var value = tiddler[name];
|
||||
switch(fieldInfo.source) {
|
||||
case "subdirectories":
|
||||
value = path.relative(rootPath, filename).split('/').slice(0, -1);
|
||||
break;
|
||||
case "filepath":
|
||||
value = path.relative(rootPath, filename);
|
||||
break;
|
||||
case "filename":
|
||||
value = path.basename(filename);
|
||||
break;
|
||||
@@ -2023,7 +2055,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
||||
var thisPath = path.relative(filepath, files[t]),
|
||||
filename = path.basename(thisPath);
|
||||
if(filename !== "tiddlywiki.files" && !metaRegExp.test(filename) && fileRegExp.test(filename)) {
|
||||
processFile(thisPath,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile);
|
||||
processFile(thisPath,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile,dirSpec.path);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -2048,7 +2080,11 @@ $tw.loadPluginFolder = function(filepath,excludeRegExp) {
|
||||
console.log("Warning: missing plugin.info file in " + filepath);
|
||||
return null;
|
||||
}
|
||||
var pluginInfo = $tw.utils.parseJSONSafe(fs.readFileSync(infoPath,"utf8"));
|
||||
var pluginInfo = $tw.utils.parseJSONSafe(fs.readFileSync(infoPath,"utf8"),function() {return null;});
|
||||
if(!pluginInfo) {
|
||||
console.log("warning: invalid JSON in plugin.info file at " + infoPath);
|
||||
pluginInfo = {};
|
||||
}
|
||||
// Read the plugin files
|
||||
var pluginFiles = $tw.loadTiddlersFromPath(filepath,excludeRegExp);
|
||||
// Save the plugin tiddlers into the plugin info
|
||||
@@ -2165,7 +2201,11 @@ $tw.loadWikiTiddlers = function(wikiPath,options) {
|
||||
pluginFields;
|
||||
// Bail if we don't have a wiki info file
|
||||
if(fs.existsSync(wikiInfoPath)) {
|
||||
wikiInfo = $tw.utils.parseJSONSafe(fs.readFileSync(wikiInfoPath,"utf8"));
|
||||
wikiInfo = $tw.utils.parseJSONSafe(fs.readFileSync(wikiInfoPath,"utf8"),function() {return null;});
|
||||
if(!wikiInfo) {
|
||||
console.log("warning: invalid JSON in tiddlywiki.info file at " + wikiInfoPath);
|
||||
wikiInfo = {};
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -2408,7 +2448,7 @@ $tw.boot.initStartup = function(options) {
|
||||
$tw.utils.registerFileType("video/webm","base64",".webm");
|
||||
$tw.utils.registerFileType("video/mp4","base64",".mp4");
|
||||
$tw.utils.registerFileType("audio/mp3","base64",".mp3");
|
||||
$tw.utils.registerFileType("audio/mpeg","base64");
|
||||
$tw.utils.registerFileType("audio/mpeg","base64",[".mp3",".m2a",".mp2",".mpa",".mpg",".mpga"]);
|
||||
$tw.utils.registerFileType("text/markdown","utf8",[".md",".markdown"],{deserializerType:"text/x-markdown"});
|
||||
$tw.utils.registerFileType("text/x-markdown","utf8",[".md",".markdown"]);
|
||||
$tw.utils.registerFileType("application/enex+xml","utf8",".enex");
|
||||
|
||||
@@ -18,7 +18,7 @@ All parameters are optional with safe defaults, and can be specified in any orde
|
||||
* ''anon-username'' - the username for signing edits for anonymous users
|
||||
* ''username'' - optional username for basic authentication
|
||||
* ''password'' - optional password for basic authentication
|
||||
* ''authenticated-user-header'' - optional name of header to be used for trusted authentication
|
||||
* ''authenticated-user-header'' - optional name of request header to be used for trusted authentication.
|
||||
* ''readers'' - comma-separated list of principals allowed to read from this wiki
|
||||
* ''writers'' - comma-separated list of principals allowed to write to this wiki
|
||||
* ''csrf-disable'' - set to "yes" to disable CSRF checks (defaults to "no")
|
||||
|
||||
@@ -118,6 +118,8 @@ FramedEngine.prototype.copyStyles = function() {
|
||||
this.domNode.style.margin = "0";
|
||||
// In Chrome setting -webkit-text-fill-color overrides the placeholder text colour
|
||||
this.domNode.style["-webkit-text-fill-color"] = "currentcolor";
|
||||
// Ensure we don't force text direction to LTR
|
||||
this.domNode.style.removeProperty("direction");
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
25
core/modules/filters/format/timestamp.js
Normal file
25
core/modules/filters/format/timestamp.js
Normal file
@@ -0,0 +1,25 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/format/timestamp.js
|
||||
type: application/javascript
|
||||
module-type: formatfilteroperator
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.timestamp = function(source,operand,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
if (title.match(/^-?\d+$/)) {
|
||||
var value = new Date(Number(title));
|
||||
results.push($tw.utils.formatDateString(value,operand || "[UTC]YYYY0MM0DD0hh0mm0ss0XXX"));
|
||||
}
|
||||
});
|
||||
return results;
|
||||
};
|
||||
})();
|
||||
@@ -21,7 +21,7 @@ Export our filter function
|
||||
*/
|
||||
exports["[unknown]"] = function(source,operator,options) {
|
||||
// Check for a user defined filter operator
|
||||
if(operator.operator.charAt(0) === ".") {
|
||||
if(operator.operator.indexOf(".") !== -1) {
|
||||
var variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(operator.operator);
|
||||
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
|
||||
var list = options.widget.evaluateVariable(operator.operator,{params: operator.operands, source: source});
|
||||
|
||||
@@ -78,7 +78,7 @@ exports.parseTag = function(source,pos,options) {
|
||||
orderedAttributes: []
|
||||
};
|
||||
// Define our regexps
|
||||
var reTagName = /([a-zA-Z0-9\-\$]+)/g;
|
||||
var reTagName = /([a-zA-Z0-9\-\$\.]+)/g;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for a less than sign
|
||||
@@ -138,7 +138,7 @@ exports.parseTag = function(source,pos,options) {
|
||||
|
||||
exports.findNextTag = function(source,pos,options) {
|
||||
// A regexp for finding candidate HTML tags
|
||||
var reLookahead = /<([a-zA-Z\-\$]+)/g;
|
||||
var reLookahead = /<([a-zA-Z\-\$\.]+)/g;
|
||||
// Find the next candidate
|
||||
reLookahead.lastIndex = pos;
|
||||
var match = reLookahead.exec(source);
|
||||
|
||||
@@ -26,7 +26,7 @@ Instantiate parse rule
|
||||
exports.init = function(parser) {
|
||||
this.parser = parser;
|
||||
// Regexp to match
|
||||
this.matchRegExp = /^\\parameters\s*\(([^)]*)\)\s*\r?\n/mg;
|
||||
this.matchRegExp = /^\\parameters\s*\(([^)]*)\)(\s*\r?\n)?/mg;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
40
core/modules/parsers/wikiparser/rules/wikilinkprefix.js
Normal file
40
core/modules/parsers/wikiparser/rules/wikilinkprefix.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/*\
|
||||
title: $:/core/modules/parsers/wikiparser/rules/wikilinkprefix.js
|
||||
type: application/javascript
|
||||
module-type: wikirule
|
||||
|
||||
Wiki text inline rule for suppressed wiki links. For example:
|
||||
|
||||
```
|
||||
~SuppressedLink
|
||||
```
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.name = "wikilinkprefix";
|
||||
exports.types = {inline: true};
|
||||
|
||||
exports.init = function(parser) {
|
||||
this.parser = parser;
|
||||
// Regexp to match
|
||||
this.matchRegExp = new RegExp($tw.config.textPrimitives.unWikiLink + $tw.config.textPrimitives.wikiLink,"mg");
|
||||
};
|
||||
|
||||
/*
|
||||
Parse the most recent match
|
||||
*/
|
||||
exports.parse = function() {
|
||||
// Get the details of the match
|
||||
var linkText = this.match[0];
|
||||
// Move past the wikilink
|
||||
this.parser.pos = this.matchRegExp.lastIndex;
|
||||
// Return the link without unwikilink character as plain text
|
||||
return [{type: "text", text: linkText.substr(1)}];
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -37,7 +37,7 @@ HeaderAuthenticator.prototype.authenticateRequest = function(request,response,st
|
||||
return false;
|
||||
} else {
|
||||
// authenticatedUsername will be undefined for anonymous users
|
||||
state.authenticatedUsername = username;
|
||||
state.authenticatedUsername = $tw.utils.decodeURIComponentSafe(username);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -41,12 +41,8 @@ exports.startup = function() {
|
||||
$tw.rootWidget.addEventListener("tm-focus-selector",function(event) {
|
||||
var selector = event.param || "",
|
||||
element,
|
||||
doc = event.event && event.event.target ? event.event.target.ownerDocument : document;
|
||||
try {
|
||||
element = doc.querySelector(selector);
|
||||
} catch(e) {
|
||||
console.log("Error in selector: ",selector)
|
||||
}
|
||||
baseElement = event.event && event.event.target ? event.event.target.ownerDocument : document;
|
||||
element = $tw.utils.querySelectorSafe(selector,baseElement);
|
||||
if(element && element.focus) {
|
||||
element.focus(event.paramObject);
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ function findTitleDomNode(widget,targetClass) {
|
||||
targetClass = targetClass || "tc-title";
|
||||
var domNode = widget.findFirstDomNode();
|
||||
if(domNode && domNode.querySelector) {
|
||||
return domNode.querySelector("." + targetClass);
|
||||
return $tw.utils.querySelectorSafe("." + targetClass,domNode);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -365,5 +365,25 @@ exports.collectDOMVariables = function(selectedNode,domNode,event) {
|
||||
return variables;
|
||||
};
|
||||
|
||||
/*
|
||||
Make sure the CSS selector is not invalid
|
||||
*/
|
||||
exports.querySelectorSafe = function(selector,baseElement) {
|
||||
baseElement = baseElement || document;
|
||||
try {
|
||||
return baseElement.querySelector(selector);
|
||||
} catch(e) {
|
||||
console.log("Invalid selector: ",selector);
|
||||
}
|
||||
};
|
||||
|
||||
exports.querySelectorAllSafe = function(selector,baseElement) {
|
||||
baseElement = baseElement || document;
|
||||
try {
|
||||
return baseElement.querySelectorAll(selector);
|
||||
} catch(e) {
|
||||
console.log("Invalid selector: ",selector);
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -159,7 +159,7 @@ exports.importDataTransfer = function(dataTransfer,fallbackTitle,callback) {
|
||||
if(!$tw.browser.isIE || importDataTypes[t].IECompatible) {
|
||||
// Get the data
|
||||
var dataType = importDataTypes[t];
|
||||
var data = dataTransfer.getData(dataType.type);
|
||||
var data = dataTransfer.getData(dataType.type);
|
||||
// Import the tiddlers in the data
|
||||
if(data !== "" && data !== null) {
|
||||
if($tw.log.IMPORT) {
|
||||
@@ -173,6 +173,36 @@ exports.importDataTransfer = function(dataTransfer,fallbackTitle,callback) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.importPaste = function(item,fallbackTitle,callback) {
|
||||
// Try each provided data type in turn
|
||||
for(var t=0; t<importDataTypes.length; t++) {
|
||||
if(item.type === importDataTypes[t].type) {
|
||||
// Get the data
|
||||
var dataType = importDataTypes[t];
|
||||
|
||||
item.getAsString(function(data){
|
||||
if($tw.log.IMPORT) {
|
||||
console.log("Importing data type '" + dataType.type + "', data: '" + data + "'")
|
||||
}
|
||||
var tiddlerFields = dataType.toTiddlerFieldsArray(data,fallbackTitle);
|
||||
callback(tiddlerFields);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.itemHasValidDataType = function(item) {
|
||||
for(var t=0; t<importDataTypes.length; t++) {
|
||||
if(!$tw.browser.isIE || importDataTypes[t].IECompatible) {
|
||||
if(item.type === importDataTypes[t].type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var importDataTypes = [
|
||||
{type: "text/vnd.tiddler", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
return parseJSONTiddlers(data,fallbackTitle);
|
||||
@@ -205,7 +235,13 @@ var importDataTypes = [
|
||||
return [{title: fallbackTitle, text: data}];
|
||||
}},
|
||||
{type: "text/uri-list", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
return [{title: fallbackTitle, text: data}];
|
||||
// Check for tiddler data URI
|
||||
var match = $tw.utils.decodeURIComponentSafe(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
|
||||
if(match) {
|
||||
return parseJSONTiddlers(match[1],fallbackTitle);
|
||||
} else {
|
||||
return [{title: fallbackTitle, text: data}]; // As URL string
|
||||
}
|
||||
}}
|
||||
];
|
||||
|
||||
|
||||
@@ -127,8 +127,8 @@ PageScroller.prototype.scrollIntoView = function(element,callback,options) {
|
||||
};
|
||||
|
||||
PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {
|
||||
baseElement = baseElement || document.body;
|
||||
var element = baseElement.querySelector(selector);
|
||||
baseElement = baseElement || document;
|
||||
var element = $tw.utils.querySelectorSafe(selector,baseElement);
|
||||
if(element) {
|
||||
this.scrollIntoView(element,callback,options);
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ CheckboxWidget.prototype.getValue = function() {
|
||||
var list;
|
||||
if(this.checkboxListField) {
|
||||
if($tw.utils.hop(tiddler.fields,this.checkboxListField)) {
|
||||
list = tiddler.getFieldList(this.checkboxListField);
|
||||
list = tiddler.getFieldList(this.checkboxListField) || [];
|
||||
} else {
|
||||
list = $tw.utils.parseStringArray(this.checkboxDefault || "") || [];
|
||||
}
|
||||
@@ -208,16 +208,20 @@ CheckboxWidget.prototype.handleChangeEvent = function(event) {
|
||||
if(this.checkboxListField || this.checkboxListIndex) {
|
||||
var fieldContents, listContents, oldPos, newPos;
|
||||
if(this.checkboxListField) {
|
||||
fieldContents = tiddler ? tiddler.fields[this.checkboxListField] : undefined;
|
||||
fieldContents = (tiddler ? tiddler.fields[this.checkboxListField] : undefined) || [];
|
||||
} else {
|
||||
fieldContents = this.wiki.extractTiddlerDataItem(this.checkboxTitle,this.checkboxListIndex);
|
||||
}
|
||||
if($tw.utils.isArray(fieldContents)) {
|
||||
// Make a copy so we can modify it without changing original that's refrenced elsewhere
|
||||
listContents = fieldContents.slice(0);
|
||||
} else {
|
||||
listContents = $tw.utils.parseStringArray(fieldContents) || [];
|
||||
} else if(typeof fieldContents === "string") {
|
||||
listContents = $tw.utils.parseStringArray(fieldContents);
|
||||
// No need to copy since parseStringArray returns a fresh array, not refrenced elsewhere
|
||||
} else {
|
||||
// Field was neither an array nor a string; it's probably something that shouldn't become
|
||||
// an array (such as a date field), so bail out *without* triggering actions
|
||||
return;
|
||||
}
|
||||
oldPos = notValue ? listContents.indexOf(notValue) : -1;
|
||||
newPos = value ? listContents.indexOf(value) : -1;
|
||||
|
||||
@@ -39,7 +39,7 @@ DiffTextWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.execute();
|
||||
// Create the diff
|
||||
var dmpObject = new dmp.diff_match_patch(),
|
||||
diffs = dmpObject.diff_main(this.getAttribute("source"),this.getAttribute("dest"));
|
||||
diffs = dmpObject.diff_main(this.getAttribute("source",""),this.getAttribute("dest",""));
|
||||
// Apply required cleanup
|
||||
switch(this.getAttribute("cleanup","semantic")) {
|
||||
case "none":
|
||||
|
||||
@@ -271,6 +271,20 @@ DropZoneWidget.prototype.handlePasteEvent = function(event) {
|
||||
callback: readFileCallback,
|
||||
deserializer: this.dropzoneDeserializer
|
||||
});
|
||||
} else if(item.kind === "string" && !["text/html", "text/plain", "Text"].includes(item.type) && $tw.utils.itemHasValidDataType(item)) {
|
||||
// Try to import the various data types we understand
|
||||
var fallbackTitle = self.wiki.generateNewTitle("Untitled");
|
||||
//Use the deserializer specified if any
|
||||
if(this.dropzoneDeserializer) {
|
||||
item.getAsString(function(str){
|
||||
var tiddlerFields = self.wiki.deserializeTiddlers(null,str,{title: fallbackTitle},{deserializer:self.dropzoneDeserializer});
|
||||
if(tiddlerFields && tiddlerFields.length) {
|
||||
readFileCallback(tiddlerFields);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$tw.utils.importPaste(item,fallbackTitle,readFileCallback);
|
||||
}
|
||||
} else if(item.kind === "string") {
|
||||
// Create tiddlers from string items
|
||||
var tiddlerFields;
|
||||
|
||||
@@ -92,12 +92,9 @@ LinkCatcherWidget.prototype.handleNavigateEvent = function(event) {
|
||||
this.executingActions = false;
|
||||
}
|
||||
} else {
|
||||
// This is a navigate event generated by the actions of this linkcatcher, so we don't trap it again, but just pass it to the parent
|
||||
this.parentWidget.dispatchEvent({
|
||||
type: "tm-navigate",
|
||||
param: event.navigateTo,
|
||||
navigateTo: event.navigateTo
|
||||
});
|
||||
// This is a navigate event generated by the actions of this linkcatcher,
|
||||
// so we don't trap it again, but just pass it to the parent
|
||||
this.parentWidget.dispatchEvent(event);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -51,7 +51,8 @@ MacroCallWidget.prototype.execute = function() {
|
||||
var positionalName = 0,
|
||||
parseTreeNodes = [{
|
||||
type: "transclude",
|
||||
isBlock: this.parseTreeNode.isBlock
|
||||
isBlock: this.parseTreeNode.isBlock,
|
||||
children: this.parseTreeNode.children
|
||||
}];
|
||||
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$variable",this.macroName);
|
||||
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$type",this.parseType);
|
||||
|
||||
@@ -119,8 +119,8 @@ ScrollableWidget.prototype.scrollIntoView = function(element,callback,options) {
|
||||
};
|
||||
|
||||
ScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {
|
||||
baseElement = baseElement || document.body;
|
||||
var element = baseElement.querySelector(selector);
|
||||
baseElement = baseElement || document;
|
||||
var element = $tw.utils.querySelectorSafe(selector,baseElement);
|
||||
if(element) {
|
||||
this.scrollIntoView(element,callback,options);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ SlotWidget.prototype.execute = function() {
|
||||
var pointer = this.parentWidget,
|
||||
depth = this.slotDepth;
|
||||
while(pointer) {
|
||||
if(pointer instanceof TranscludeWidget) {
|
||||
if(pointer instanceof TranscludeWidget && pointer.hasVisibleSlots()) {
|
||||
depth--;
|
||||
if(depth <= 0) {
|
||||
break;
|
||||
|
||||
@@ -45,7 +45,7 @@ TranscludeWidget.prototype.execute = function() {
|
||||
var target = this.getTransclusionTarget(),
|
||||
parseTreeNodes = target.parseTreeNodes;
|
||||
this.sourceText = target.text;
|
||||
this.sourceType = target.type;
|
||||
this.parserType = target.type;
|
||||
this.parseAsInline = target.parseAsInline;
|
||||
// Process the transclusion according to the output type
|
||||
switch(this.transcludeOutput || "text/html") {
|
||||
@@ -58,7 +58,7 @@ TranscludeWidget.prototype.execute = function() {
|
||||
break;
|
||||
default:
|
||||
// text/plain
|
||||
var plainText = this.wiki.renderText("text/plain",this.sourceType,this.sourceText,{parentWidget: this});
|
||||
var plainText = this.wiki.renderText("text/plain",this.parserType,this.sourceText,{parentWidget: this});
|
||||
parseTreeNodes = [{type: "text", text: plainText}];
|
||||
break;
|
||||
}
|
||||
@@ -171,99 +171,101 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
|
||||
}
|
||||
var parser;
|
||||
// Get the parse tree
|
||||
if(this.transcludeVariable) {
|
||||
// Transcluding a variable
|
||||
var variableInfo = this.getVariableInfo(this.transcludeVariable,{params: this.getOrderedTransclusionParameters()}),
|
||||
srcVariable = variableInfo && variableInfo.srcVariable;
|
||||
if(srcVariable) {
|
||||
if(srcVariable.isFunctionDefinition) {
|
||||
// Function to return parameters by name or position
|
||||
var fnGetParam = function(name,index) {
|
||||
// Parameter names starting with dollar must be escaped to double dollars
|
||||
if(name.charAt(0) === "$") {
|
||||
name = "$" + name;
|
||||
}
|
||||
// Look for the parameter by name
|
||||
if(self.hasAttribute(name)) {
|
||||
return self.getAttribute(name);
|
||||
// Look for the parameter by index
|
||||
} else if(self.hasAttribute(index + "")) {
|
||||
return self.getAttribute(index + "");
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
result = this.evaluateVariable(this.transcludeVariable,{params: fnGetParam})[0] || "";
|
||||
parser = {
|
||||
tree: [{
|
||||
type: "text",
|
||||
text: result
|
||||
}],
|
||||
source: result,
|
||||
type: "text/vnd.tiddlywiki"
|
||||
};
|
||||
if(parseAsInline) {
|
||||
parser.tree[0] = {
|
||||
type: "text",
|
||||
text: result
|
||||
};
|
||||
} else {
|
||||
parser.tree[0] = {
|
||||
type: "element",
|
||||
tag: "p",
|
||||
children: [{
|
||||
if(this.hasAttribute("$variable")) {
|
||||
if(this.transcludeVariable) {
|
||||
// Transcluding a variable
|
||||
var variableInfo = this.getVariableInfo(this.transcludeVariable,{params: this.getOrderedTransclusionParameters()}),
|
||||
srcVariable = variableInfo && variableInfo.srcVariable;
|
||||
if(variableInfo.text) {
|
||||
if(srcVariable.isFunctionDefinition) {
|
||||
// Function to return parameters by name or position
|
||||
var fnGetParam = function(name,index) {
|
||||
// Parameter names starting with dollar must be escaped to double dollars
|
||||
if(name.charAt(0) === "$") {
|
||||
name = "$" + name;
|
||||
}
|
||||
// Look for the parameter by name
|
||||
if(self.hasAttribute(name)) {
|
||||
return self.getAttribute(name);
|
||||
// Look for the parameter by index
|
||||
} else if(self.hasAttribute(index + "")) {
|
||||
return self.getAttribute(index + "");
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
result = this.evaluateVariable(this.transcludeVariable,{params: fnGetParam})[0] || "";
|
||||
parser = {
|
||||
tree: [{
|
||||
type: "text",
|
||||
text: result
|
||||
}]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var cacheKey = (parseAsInline ? "inlineParser" : "blockParser") + (this.transcludeType || "");
|
||||
if(variableInfo.isCacheable && srcVariable[cacheKey]) {
|
||||
parser = srcVariable[cacheKey];
|
||||
} else {
|
||||
parser = this.wiki.parseText(this.transcludeType,variableInfo.text || "",{parseAsInline: parseAsInline, configTrimWhiteSpace: srcVariable.configTrimWhiteSpace});
|
||||
if(variableInfo.isCacheable) {
|
||||
srcVariable[cacheKey] = parser;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(parser) {
|
||||
// Add parameters widget for procedures and custom widgets
|
||||
if(srcVariable.isProcedureDefinition || srcVariable.isWidgetDefinition) {
|
||||
parser = {
|
||||
tree: [
|
||||
{
|
||||
type: "parameters",
|
||||
children: parser.tree
|
||||
}
|
||||
],
|
||||
source: parser.source,
|
||||
type: parser.type
|
||||
}
|
||||
$tw.utils.each(srcVariable.params,function(param) {
|
||||
var name = param.name;
|
||||
// Parameter names starting with dollar must be escaped to double dollars
|
||||
if(name.charAt(0) === "$") {
|
||||
name = "$" + name;
|
||||
}],
|
||||
source: result,
|
||||
type: "text/vnd.tiddlywiki"
|
||||
};
|
||||
if(parseAsInline) {
|
||||
parser.tree[0] = {
|
||||
type: "text",
|
||||
text: result
|
||||
};
|
||||
} else {
|
||||
parser.tree[0] = {
|
||||
type: "element",
|
||||
tag: "p",
|
||||
children: [{
|
||||
type: "text",
|
||||
text: result
|
||||
}]
|
||||
}
|
||||
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],name,param["default"])
|
||||
});
|
||||
} else {
|
||||
// For macros and ordinary variables, wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
|
||||
parser = {
|
||||
tree: [
|
||||
{
|
||||
type: "vars",
|
||||
children: parser.tree
|
||||
}
|
||||
],
|
||||
source: parser.source,
|
||||
type: parser.type
|
||||
}
|
||||
$tw.utils.each(variableInfo.params,function(param) {
|
||||
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],"__" + param.name + "__",param.value)
|
||||
});
|
||||
} else {
|
||||
var cacheKey = (parseAsInline ? "inlineParser" : "blockParser") + (this.transcludeType || "");
|
||||
if(variableInfo.isCacheable && srcVariable[cacheKey]) {
|
||||
parser = srcVariable[cacheKey];
|
||||
} else {
|
||||
parser = this.wiki.parseText(this.transcludeType,variableInfo.text || "",{parseAsInline: parseAsInline, configTrimWhiteSpace: srcVariable.configTrimWhiteSpace});
|
||||
if(variableInfo.isCacheable) {
|
||||
srcVariable[cacheKey] = parser;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(parser) {
|
||||
// Add parameters widget for procedures and custom widgets
|
||||
if(srcVariable.isProcedureDefinition || srcVariable.isWidgetDefinition) {
|
||||
parser = {
|
||||
tree: [
|
||||
{
|
||||
type: "parameters",
|
||||
children: parser.tree
|
||||
}
|
||||
],
|
||||
source: parser.source,
|
||||
type: parser.type
|
||||
}
|
||||
$tw.utils.each(srcVariable.params,function(param) {
|
||||
var name = param.name;
|
||||
// Parameter names starting with dollar must be escaped to double dollars
|
||||
if(name.charAt(0) === "$") {
|
||||
name = "$" + name;
|
||||
}
|
||||
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],name,param["default"])
|
||||
});
|
||||
} else {
|
||||
// For macros and ordinary variables, wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
|
||||
parser = {
|
||||
tree: [
|
||||
{
|
||||
type: "vars",
|
||||
children: parser.tree
|
||||
}
|
||||
],
|
||||
source: parser.source,
|
||||
type: parser.type
|
||||
}
|
||||
$tw.utils.each(variableInfo.params,function(param) {
|
||||
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],"__" + param.name + "__",param.value)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,6 +281,8 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
|
||||
defaultType: this.transcludeType
|
||||
});
|
||||
}
|
||||
// Set 'thisTiddler'
|
||||
this.setVariable("thisTiddler",this.transcludeTitle);
|
||||
// Return the parse tree
|
||||
if(parser) {
|
||||
return {
|
||||
@@ -380,6 +384,13 @@ TranscludeWidget.prototype.getTransclusionSlotFill = function(name,defaultParseT
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Return whether this transclusion should be visible to the slot widget
|
||||
*/
|
||||
TranscludeWidget.prototype.hasVisibleSlots = function() {
|
||||
return this.getAttribute("$fillignore","no") === "no";
|
||||
}
|
||||
|
||||
/*
|
||||
Compose a string comprising the title, field and/or index to identify this transclusion for recursion detection
|
||||
*/
|
||||
|
||||
@@ -324,7 +324,7 @@ Widget.prototype.makeFakeWidgetWithVariables = function(variables) {
|
||||
};
|
||||
|
||||
/*
|
||||
Evaluate a variable and associated actual parameters and result the resulting array.
|
||||
Evaluate a variable and associated actual parameters and return the resulting array.
|
||||
The way that the variable is evaluated depends upon its type:
|
||||
* Functions are evaluated as parameterised filter strings
|
||||
* Macros are returned as plain text with substitution of parameters
|
||||
@@ -403,7 +403,7 @@ Widget.prototype.computeAttribute = function(attribute) {
|
||||
if(attribute.type === "filtered") {
|
||||
value = this.wiki.filterTiddlers(attribute.filter,this)[0] || "";
|
||||
} else if(attribute.type === "indirect") {
|
||||
value = this.wiki.getTextReference(attribute.textReference,"",this.getVariable("currentTiddler"));
|
||||
value = this.wiki.getTextReference(attribute.textReference,"",this.getVariable("currentTiddler")) || "";
|
||||
} else if(attribute.type === "macro") {
|
||||
var variableInfo = this.getVariableInfo(attribute.value.name,{params: attribute.value.params});
|
||||
if(variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
|
||||
@@ -546,8 +546,8 @@ Widget.prototype.makeChildWidget = function(parseTreeNode,options) {
|
||||
var variableDefinitionName = "$" + parseTreeNode.type;
|
||||
if(this.variables[variableDefinitionName]) {
|
||||
var isOverrideable = function() {
|
||||
// Widget is overrideable if it has a double dollar user defined name, or if it is an existing JS widget and we're not in safe mode
|
||||
return parseTreeNode.type.charAt(0) === "$" || (!!self.widgetClasses[parseTreeNode.type] && !$tw.safeMode);
|
||||
// Widget is overrideable if its name contains a period, or if it is an existing JS widget and we're not in safe mode
|
||||
return parseTreeNode.type.indexOf(".") !== -1 || (!!self.widgetClasses[parseTreeNode.type] && !$tw.safeMode);
|
||||
};
|
||||
if(!parseTreeNode.isNotRemappable && isOverrideable()) {
|
||||
var variableInfo = this.getVariableInfo(variableDefinitionName,{allowSelfAssigned: true});
|
||||
|
||||
@@ -1149,7 +1149,7 @@ exports.makeTranscludeWidget = function(title,options) {
|
||||
if(options.importVariables) {
|
||||
parseTreeImportVariables.attributes.filter.value = options.importVariables;
|
||||
} else if(options.importPageMacros) {
|
||||
parseTreeImportVariables.attributes.filter.value = "[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]";
|
||||
parseTreeImportVariables.attributes.filter.value = this.getTiddlerText("$:/core/config/GlobalImportFilter");
|
||||
}
|
||||
parseTreeDiv.tree[0].children.push(parseTreeImportVariables);
|
||||
parseTreeImportVariables.children.push(parseTreeTransclude);
|
||||
|
||||
@@ -3,5 +3,5 @@ title: $:/core/templates/exporters/StaticRiver/Content
|
||||
\define renderContent()
|
||||
{{{ $(exportFilter)$ ||$:/core/templates/static-tiddler}}}
|
||||
\end
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
<<renderContent>>
|
||||
|
||||
@@ -7,5 +7,5 @@ condition: [<count>compare:lte[1]]
|
||||
\define renderContent()
|
||||
{{{ $(exportFilter)$ +[limit[1]] ||$:/core/templates/tid-tiddler}}}
|
||||
\end
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
<<renderContent>>
|
||||
@@ -1,11 +1,14 @@
|
||||
title: $:/core/save/all-external-js
|
||||
|
||||
\whitespace trim
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
\define saveTiddlerFilter()
|
||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
||||
\end
|
||||
|
||||
<!-- Important: core library is provided by serving URI encoded $:/core/templates/tiddlywiki5.js -->
|
||||
\define defaultCoreURL() %24%3A%2Fcore%2Ftemplates%2Ftiddlywiki5.js
|
||||
|
||||
<$let coreURL={{{ [[coreURL]is[variable]then<coreURL>else<defaultCoreURL>] }}}>
|
||||
{{$:/core/templates/tiddlywiki5-external-js.html}}
|
||||
</$let>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
title: $:/core/save/offline-external-js
|
||||
|
||||
\whitespace trim
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
\define saveTiddlerFilter()
|
||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
||||
\end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
title: $:/core/save/all
|
||||
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
\define saveTiddlerFilter()
|
||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
||||
\end
|
||||
|
||||
@@ -2,7 +2,7 @@ title: $:/core/templates/server/static.tiddler.html
|
||||
|
||||
\whitespace trim
|
||||
\define tv-wikilink-template() $uri_encoded$
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
|
||||
@@ -4,7 +4,7 @@ title: $:/core/templates/single.tiddler.window
|
||||
\define containerClasses()
|
||||
tc-page-container tc-page-view-$(storyviewTitle)$ tc-language-$(languageTitle)$
|
||||
\end
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
|
||||
<$vars
|
||||
tv-config-toolbar-icons={{$:/config/Toolbar/Icons}}
|
||||
|
||||
@@ -4,7 +4,7 @@ title: $:/core/templates/static.tiddler.html
|
||||
\define tv-config-toolbar-icons() no
|
||||
\define tv-config-toolbar-text() no
|
||||
\define tv-config-toolbar-class() tc-btn-invisible
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
`<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
@@ -30,15 +30,15 @@ Block transclusions are shown in red, and inline transclusions are shown in gree
|
||||
<!-- Look for a parameter starting with $ to determine if we are in legacy mode -->
|
||||
<$list filter="[<@params>jsonindexes[]] :filter[<currentTiddler>prefix[$]] +[limit[1]]" variable="ignore" emptyMessage="""
|
||||
<!-- Legacy mode: we render the transclusion without a dollar sign for recursionMarker and mode -->
|
||||
<$genesis $type="$transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" recursionMarker="no" mode=<<mode>>>
|
||||
<$genesis $type="$transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" recursionMarker="no" mode=<<mode>> $$fillignore="yes">
|
||||
<!-- Reach back up to the grandparent transclusion to get the correct slot value -->
|
||||
<$slot $name="ts-raw" $depth="2"/>
|
||||
<$slot $name="ts-raw"/>
|
||||
</$genesis>
|
||||
""">
|
||||
<!-- Non-legacy mode: we use dollar signs for the recursionMarker and mode -->
|
||||
<$genesis $type="$transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" $$recursionMarker="no" $$mode=<<mode>>>
|
||||
<$genesis $type="$transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" $$recursionMarker="no" $$mode=<<mode>> $$fillignore="yes">
|
||||
<!-- Reach back up to the grandparent transclusion to get the correct slot fill value -->
|
||||
<$slot $name="ts-raw" $depth="2"/>
|
||||
<$slot $name="ts-raw"/>
|
||||
</$genesis>
|
||||
</$list>
|
||||
</$genesis>
|
||||
|
||||
@@ -211,7 +211,7 @@ $:/state/add-plugin-info/$(connectionTiddler)$/$(assetInfo)$
|
||||
</div>
|
||||
\end
|
||||
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
\whitespace trim
|
||||
|
||||
<div>
|
||||
|
||||
@@ -2,7 +2,7 @@ title: $:/core/ui/EditTemplate/body/preview/output
|
||||
tags: $:/tags/EditPreview
|
||||
caption: {{$:/language/EditTemplate/Body/Preview/Type/Output}}
|
||||
|
||||
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]] [all[shadows+tiddlers]tag[$:/tags/Macro/View/Body]!has[draft.of]]
|
||||
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Macro/View/Body]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global/View]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global/View/Body]!is[draft]]
|
||||
<$set name="tv-tiddler-preview" value="yes">
|
||||
|
||||
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateBodyFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/body/default]] }}} />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
title: $:/core/ui/PageStylesheet
|
||||
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
\whitespace trim
|
||||
|
||||
<$set name="currentTiddler" value={{$:/language}}>
|
||||
|
||||
@@ -4,7 +4,7 @@ description: {{$:/language/PageTemplate/Description}}
|
||||
icon: $:/core/images/layout-button
|
||||
|
||||
\whitespace trim
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
|
||||
<$vars
|
||||
tv-config-toolbar-icons={{$:/config/Toolbar/Icons}}
|
||||
|
||||
@@ -26,7 +26,7 @@ $button$
|
||||
<div class="tc-sidebar-tab-open">
|
||||
<$list filter="[list<tv-story-list>]" history=<<tv-history-list>> storyview="pop">
|
||||
<div class="tc-sidebar-tab-open-item">
|
||||
<$macrocall $name="droppable-item" button="<$button message='tm-close-tiddler' tooltip={{$:/language/Buttons/Close/Hint}} aria-label={{$:/language/Buttons/Close/Caption}} class='tc-btn-invisible tc-btn-mini tc-small-gap-right'>{{$:/core/images/close-button}}</$button><$link to={{!!title}}><$view field='title'/></$link>"/>
|
||||
<$macrocall $name="droppable-item" button="<$button message='tm-close-tiddler' tooltip={{$:/language/Buttons/Close/Hint}} aria-label={{$:/language/Buttons/Close/Caption}} class='tc-btn-invisible tc-btn-mini tc-small-gap-right'>{{$:/core/images/close-button}}</$button><$link/>"/>
|
||||
</div>
|
||||
</$list>
|
||||
<$tiddler tiddler="">
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
title: $:/core/ui/StoryTiddlerTemplate
|
||||
|
||||
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/StoryTiddlerTemplateFilter]!is[draft]get[text]] :and[!is[blank]else{$:/config/ui/ViewTemplate}] }}} />
|
||||
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/StoryTiddlerTemplateFilter]!is[draft]get[text]] :and[has[title]else[$:/core/ui/ViewTemplate]] }}} />
|
||||
|
||||
@@ -5,10 +5,10 @@ title: $:/core/ui/ViewTemplate
|
||||
$:/state/folded/$(currentTiddler)$
|
||||
\end
|
||||
\define cancel-delete-tiddler-actions(message) <$action-sendmessage $message="tm-$message$-tiddler"/>
|
||||
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]]
|
||||
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global/View]!is[draft]]
|
||||
<$vars storyTiddler=<<currentTiddler>> tiddlerInfoState=<<qualify "$:/state/popup/tiddler-info">>>
|
||||
<div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ [all[shadows+tiddlers]tag[$:/tags/ClassFilters/TiddlerTemplate]!is[draft]] :map:flat[subfilter{!!text}] tc-tiddler-frame tc-tiddler-view-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[shadow]is[tiddler]then[tc-tiddler-overridden-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}} role="article">
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem">
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!is[draft]]" variable="listItem">
|
||||
<$transclude tiddler=<<listItem>>/>
|
||||
</$list>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
title: $:/core/ui/ViewTemplate/body
|
||||
tags: $:/tags/ViewTemplate
|
||||
|
||||
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View/Body]!has[draft.of]]
|
||||
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View/Body]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global/View/Body]!is[draft]]
|
||||
|
||||
<$reveal tag="div" class="tc-tiddler-body" type="nomatch" stateTitle=<<folded-state>> text="hide" retain="yes" animate="yes">
|
||||
|
||||
|
||||
2
core/wiki/config/GlobalImportFilter.tid
Normal file
2
core/wiki/config/GlobalImportFilter.tid
Normal file
@@ -0,0 +1,2 @@
|
||||
title: $:/core/config/GlobalImportFilter
|
||||
text: [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global]!is[draft]]
|
||||
@@ -1,3 +1,3 @@
|
||||
title: $:/config/WikiParserRules/Inline/wikilink
|
||||
|
||||
enable
|
||||
disable
|
||||
@@ -3,14 +3,26 @@ tags: $:/tags/Macro
|
||||
|
||||
\define translink(title,mode:"block")
|
||||
\whitespace trim
|
||||
<div style="border:1px solid #ccc; padding: 0.5em; background: black; foreground; white;">
|
||||
<$list filter="[<__mode__>match[block]]">
|
||||
<div class="tc-translink">
|
||||
<div>
|
||||
<$link to="""$title$""">
|
||||
<$text text="""$title$"""/>
|
||||
<h1><$text text="""$title$"""/></h1>
|
||||
</$link>
|
||||
<div style="border:1px solid #ccc; padding: 0.5em; background: white; foreground; black;">
|
||||
<$transclude tiddler="""$title$""" mode="$mode$">
|
||||
"<$text text="""$title$"""/>" is missing
|
||||
<$transclude tiddler="""$title$""" mode="block">
|
||||
<$set name="currentTiddler" value="""$title$"""><$transclude tiddler="$:/language/MissingTiddler/Hint"/></$set>
|
||||
</$transclude>
|
||||
</div>
|
||||
</div>
|
||||
</$list>
|
||||
<$list filter="[<__mode__>match[inline]]">
|
||||
<span class="tc-translink">
|
||||
<$link to="""$title$""">
|
||||
<$text text="""$title$"""/>
|
||||
</$link>
|
||||
 (<$transclude tiddler="""$title$""" mode="inline">
|
||||
<$set name="currentTiddler" value="""$title$"""><$transclude tiddler="$:/language/MissingTiddler/Hint"/></$set>
|
||||
</$transclude>)
|
||||
</span>
|
||||
</$list>
|
||||
\end
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
<div id="draggable" draggable="true">
|
||||
Drag me to a TiddlyWiki window
|
||||
</div>
|
||||
<button id="copy">
|
||||
Click to copy two tiddlers to the clipboard
|
||||
</button>
|
||||
|
||||
</body>
|
||||
<script>
|
||||
|
||||
@@ -30,6 +34,18 @@
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
document.getElementById("copy").addEventListener("click",function(event) {
|
||||
|
||||
function listener(event) {
|
||||
event.clipboardData.setData("URL","data:text/vnd.tiddler," + encodeURIComponent(JSON.stringify(tiddlerData)));
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
document.addEventListener("copy",listener);
|
||||
document.execCommand("copy");
|
||||
document.removeEventListener("copy",listener);
|
||||
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
title: $:/config/WikiParserRules/Inline/wikilink
|
||||
|
||||
enable
|
||||
@@ -5,7 +5,7 @@ title: $:/core/ui/ViewTemplate
|
||||
$:/state/folded/$(currentTiddler)$
|
||||
\end
|
||||
\define cancel-delete-tiddler-actions(message) <$action-sendmessage $message="tm-$message$-tiddler"/>
|
||||
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]]
|
||||
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global/View]!is[draft]]
|
||||
<$vars storyTiddler=<<currentTiddler>> tiddlerInfoState=<<qualify "$:/state/popup/tiddler-info">>>
|
||||
<div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ tc-tiddler-frame tc-tiddler-view-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[shadow]is[tiddler]then[tc-tiddler-overridden-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}>
|
||||
<$set name="state" value={{{ [[$:/state/viewtemplate/visibility/]addsuffix<currentTiddler>] }}}>
|
||||
|
||||
@@ -5,7 +5,7 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
\define tv-wikilink-template() https://tiddlywiki.com/static/$uri_doubleencoded$.html
|
||||
|
||||
<$importvariables filter="[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]">
|
||||
<$importvariables filter={{$:/core/config/GlobalImportFilter}}>
|
||||
|
||||
Bienvenue sur <<tw>>, un carnet de notes personnel web et non-linéaire que tout le monde peut utiliser et conserver, sans dépendre d'une quelconque entreprise.
|
||||
|
||||
|
||||
@@ -8,6 +8,6 @@ Tiddlers can contain formatted text:
|
||||
|
||||
Formatting is typed with special codes:
|
||||
|
||||
<$edit-text tiddler="FormattingDemoText" class="tc-edit-texteditor" minHeight="10px"/>
|
||||
<$edit-text tiddler="FormattingDemoText" class="tc-edit-texteditor" minHeight="100px"/>
|
||||
|
||||
TiddlyWiki is not just for text. [[Images]] are first class citizens, too.
|
||||
|
||||
@@ -49,14 +49,6 @@
|
||||
],
|
||||
"build": {
|
||||
"index": [
|
||||
"--rendertiddler","$:/core/save/all","index.html","text/plain"],
|
||||
"favicon": [
|
||||
"--savetiddler","$:/favicon.ico","favicon.ico",
|
||||
"--savetiddler","$:/green_favicon.ico","static/favicon.ico"],
|
||||
"static": [
|
||||
"--rendertiddler","$:/core/templates/static.template.html","static.html","text/plain",
|
||||
"--rendertiddler","$:/core/templates/alltiddlers.template.html","alltiddlers.html","text/plain",
|
||||
"--rendertiddlers","[!is[system]]","$:/core/templates/static.tiddler.html","static","text/plain",
|
||||
"--rendertiddler","$:/core/templates/static.template.css","static/static.css","text/plain"]
|
||||
"--rendertiddler","$:/core/save/all","index.html","text/plain"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
caption: 5.3.0
|
||||
created: 20230419103154368
|
||||
modified: 20230419103154368
|
||||
created: 20230506164543446
|
||||
modified: 20230506164543446
|
||||
tags: ReleaseNotes
|
||||
title: Release 5.3.0
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
//[[See GitHub for detailed change history of this release|https://github.com/Jermolene/TiddlyWiki5/compare/master...parameterised-transclusions]]//
|
||||
//[[See GitHub for detailed change history of this release|https://github.com/Jermolene/TiddlyWiki5/compare/v5.2.7...master]]//
|
||||
|
||||
! About v5.3.0
|
||||
! Overview of v5.3.0
|
||||
|
||||
This pre-release introduces a number of significant improvements and new features related to some of TiddlyWiki's most fundamental components: macros, widgets, operators and transclusion.
|
||||
This release introduces a number of significant improvements and new features related to some of TiddlyWiki's most fundamental components: macros, widgets, operators and transclusion. v5.3.0 also contains several other bug fixes and improvements.
|
||||
|
||||
! Introduction to v5.3.0
|
||||
! Introduction to Parameterised Transclusion, Procedures, Functions and Custom Widgets
|
||||
|
||||
The motivation of these changes is to fix one of ~TiddlyWiki 5's early design flaws: the reliance on macros using textual substitution as the primary way to modularise and reuse wikitext and filters.
|
||||
<<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6666">> The motivation of these changes is to fix one of ~TiddlyWiki 5's early design flaws: the reliance on macros using textual substitution as the primary way to modularise and reuse wikitext and filters.
|
||||
|
||||
Experience has shown that while macros are a good match for a small number of tasks, they are brittle and error prone for many common operations. See [[Macro Pitfalls]] for a discussion of the problems that accompany this approach. Over the years we have introduced mitigations for the worst problems but these have come at a cost of increased complexity.
|
||||
|
||||
@@ -30,9 +30,14 @@ These changes lay the groundwork for macros and related features to be deprecate
|
||||
|
||||
The new transclusion architecture is not by itself sufficient to enable us to fully deprecate macros yet. To handle the remaining use cases we propose a new backtick quoted attribute format that allows for the substitution of variable values. See https://github.com/Jermolene/TiddlyWiki5/issues/6663 for details.
|
||||
|
||||
! Defaulting to Disabling CamelCase Links
|
||||
|
||||
<<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/pull/7513">> CamelCase linking is now disabled by default. (Note that this wiki has CamelCase linking explicitly enabled)
|
||||
|
||||
! Plugin Improvements
|
||||
|
||||
*
|
||||
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/7260">> Dynannotate pugin to support three additional search modes
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7365">> problem with [[BrowserStorage Plugin]] unnecessarily saving shadow tiddlers
|
||||
|
||||
! Translation improvement
|
||||
|
||||
@@ -54,15 +59,24 @@ Improvements to the following translations:
|
||||
|
||||
! Filter improvements
|
||||
|
||||
*
|
||||
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/7292">> [[format Operator]] to support converting Unix timestamps to TiddlyWiki's native date format
|
||||
|
||||
! Hackability Improvements
|
||||
|
||||
*
|
||||
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/7413">> [[Core Icons]] to allow the size to be controlled with a parameter
|
||||
** <<.warning """This change can cause problems with non-standard usage of the core icons where the text is directly rendered instead of being transcluded""">>
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7182">> new [[thisTiddler Variable]] that refers to the tiddler currently being rendered
|
||||
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7332">> [[Story Tiddler Template Cascade]] handling to fall back to the default template if the output of the cascade is not valid
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7378">> missing file extensions for "audio/mpeg" files
|
||||
|
||||
! Bug Fixes
|
||||
|
||||
*
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7215">> importing tiddlers by pasting tiddler data
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7400">> unneeded 14px bottom border for textareas with autoheight enabled
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7380">> crashes when using an invalid CSS selector for [[WidgetMessage: tm-focus-selector]] and [[WidgetMessage: tm-scroll]]
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7401">> bug whereby scrolling occurs if the linkcatcher widget triggers an action-navigate and the $scroll attribute is set to "no"
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7409">> problem switching between LTR and RTL text
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7448">> bug when checkbox widget's listField attribute was given the name of a date field (like <<.field created>> or <<.field modified>>)
|
||||
|
||||
! Developer Improvements
|
||||
|
||||
@@ -70,14 +84,29 @@ Improvements to the following translations:
|
||||
|
||||
! Node.js Improvements
|
||||
|
||||
*
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7253">> support for `filepath` source attribute to [[tiddlywiki.files Files]]
|
||||
|
||||
! Performance Improvements
|
||||
|
||||
*
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/4624">> module execution to reuse the same sandbox, saving memory and improving performance
|
||||
|
||||
! 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:
|
||||
|
||||
<<.contributors """
|
||||
Arlen22
|
||||
btheado
|
||||
donmor
|
||||
flibbles
|
||||
GameDungeon
|
||||
kookma
|
||||
linonetwo
|
||||
Marxsal
|
||||
michsa
|
||||
muzimuzhi
|
||||
pmario
|
||||
rmunn
|
||||
saqimtiaz
|
||||
yaisog
|
||||
""">>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
title: $:/config/WikiParserRules/Inline/wikilink
|
||||
|
||||
enable
|
||||
@@ -0,0 +1,7 @@
|
||||
created: 20230314153132081
|
||||
modified: 20230314153243008
|
||||
title: $:/DefaultTiddlers
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
GettingStarted
|
||||
[[Using the external JavaScript template]]
|
||||
@@ -0,0 +1,4 @@
|
||||
title: $:/config/SaveWikiButton/Filename
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
external-<<version>>.html
|
||||
8
editions/server-external-js/tiddlers/external/tiddlywiki.files
vendored
Normal file
8
editions/server-external-js/tiddlers/external/tiddlywiki.files
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"tiddlers": [
|
||||
{
|
||||
"file": "../../../tw5.com/tiddlers/webserver/Using the external JavaScript template.tid",
|
||||
"isTiddlerFile": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2,8 +2,7 @@
|
||||
"description": "Client-server edition with external tiddlywiki.js",
|
||||
"plugins": [
|
||||
"tiddlywiki/tiddlyweb",
|
||||
"tiddlywiki/filesystem",
|
||||
"tiddlywiki/highlight"
|
||||
"tiddlywiki/filesystem"
|
||||
],
|
||||
"themes": [
|
||||
"tiddlywiki/vanilla",
|
||||
@@ -13,7 +12,7 @@
|
||||
"listen": [
|
||||
"--listen","root-tiddler=$:/core/save/all-external-js","use-browser-cache=yes"],
|
||||
"index": [
|
||||
"--render","$:/core/save/offline-external-js","index.html","text/plain",
|
||||
"--render","$:/core/save/offline-external-js","[[external-]addsuffix<version>addsuffix[.html]]","text/plain",
|
||||
"--render","$:/core/templates/tiddlywiki5.js","[[tiddlywikicore-]addsuffix<version>addsuffix[.js]]","text/plain"],
|
||||
"static": [
|
||||
"--render","$:/core/templates/static.template.html","static.html","text/plain",
|
||||
|
||||
29
editions/test/tiddlers/tests/data/this-tiddler/Simple.tid
Normal file
29
editions/test/tiddlers/tests/data/this-tiddler/Simple.tid
Normal file
@@ -0,0 +1,29 @@
|
||||
title: ThisTiddler/Simple
|
||||
description: Simple usage of thisTiddler variable
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
\import Macro
|
||||
\define print-this-tiddler()
|
||||
<$text text=<<thisTiddler>>/>
|
||||
\end
|
||||
|
||||
(<$text text=<<thisTiddler>>/>)
|
||||
|
||||
(<<print-this-tiddler>>)
|
||||
|
||||
(<<imported-print-this-tiddler>>)
|
||||
|
||||
+
|
||||
title: Macro
|
||||
|
||||
\define imported-print-this-tiddler()
|
||||
<$text text=<<thisTiddler>>/>
|
||||
\end
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>(Output)</p><p>(Output)</p><p>(Output)</p>
|
||||
@@ -12,15 +12,15 @@ title: Output
|
||||
title: Actions
|
||||
|
||||
\whitespace trim
|
||||
<!-- Define the <$$action-mywidget> widget by defining a transcludable variable with that name -->
|
||||
\widget $$action-mywidget(one:'Jaguar')
|
||||
<!-- Define the <$action.mywidget> widget by defining a transcludable variable with that name -->
|
||||
\widget $action.mywidget(one:'Jaguar')
|
||||
\whitespace trim
|
||||
<$action-setfield $tiddler="Result" $field="text" $value=<<one>>/>
|
||||
\end
|
||||
|
||||
<$$action-mywidget one="Dingo">
|
||||
<$action.mywidget one="Dingo">
|
||||
Crocodile
|
||||
</$$action-mywidget>
|
||||
</$action.mywidget>
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
|
||||
@@ -12,21 +12,21 @@ title: Output
|
||||
title: TiddlerOne
|
||||
|
||||
\whitespace trim
|
||||
<!-- Define the <$$mywidget> widget by defining a transcludable variable with that name -->
|
||||
\widget $$mywidget(one:'Jaguar')
|
||||
<!-- Define the <$my.widget> widget by defining a transcludable variable with that name -->
|
||||
\widget $my.widget(one:'Jaguar')
|
||||
\whitespace trim
|
||||
<$text text=<<one>>/>
|
||||
<$slot $name="ts-raw">
|
||||
Whale
|
||||
</$slot>
|
||||
\end
|
||||
<$$mywidget one="Dingo">
|
||||
<$my.widget one="Dingo">
|
||||
Crocodile
|
||||
</$$mywidget>
|
||||
<$$mywidget one="BumbleBee">
|
||||
</$my.widget>
|
||||
<$my.widget one="BumbleBee">
|
||||
Squirrel
|
||||
</$$mywidget>
|
||||
<$$mywidget/>
|
||||
</$my.widget>
|
||||
<$my.widget/>
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@ tags: [[$:/tags/wiki-test-spec]]
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
\widget $$mywidget()
|
||||
\widget $my.widget()
|
||||
<$slot $name=ts-raw>the body is empty</$slot>
|
||||
\end
|
||||
|
||||
#<$$mywidget/>
|
||||
#<$$mywidget></$$mywidget>
|
||||
#<$$mywidget>the body is not empty</$$mywidget>
|
||||
#<$my.widget/>
|
||||
#<$my.widget></$my.widget>
|
||||
#<$my.widget>the body is not empty</$my.widget>
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
@@ -6,21 +6,21 @@ tags: [[$:/tags/wiki-test-spec]]
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
\widget $$mywidget(one:'Jaguar')
|
||||
\widget $my.widget(one:'Jaguar')
|
||||
\whitespace trim
|
||||
<$text text=<<one>>/>
|
||||
<$slot $name="ts-stuff">
|
||||
Whale
|
||||
</$slot>
|
||||
\end
|
||||
<$$mywidget one="Dingo">
|
||||
<$my.widget one="Dingo">
|
||||
<$fill $name="ts-stuff">
|
||||
Crocodile
|
||||
</$fill>
|
||||
</$$mywidget>
|
||||
<$$mywidget one="BumbleBee">
|
||||
</$my.widget>
|
||||
<$my.widget one="BumbleBee">
|
||||
Squirrel
|
||||
</$$mywidget>
|
||||
</$my.widget>
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
|
||||
@@ -12,17 +12,17 @@ title: Output
|
||||
title: TiddlerOne
|
||||
|
||||
\whitespace trim
|
||||
<!-- Redefine the <$$mywidget> widget by defining a transcludable variable with that name -->
|
||||
\widget $$mywidget($variable:'Jaguar')
|
||||
<!-- Redefine the <$my.widget> widget by defining a transcludable variable with that name -->
|
||||
\widget $my.widget($variable:'Jaguar')
|
||||
\whitespace trim
|
||||
<$text text=<<$variable>>/>
|
||||
<$slot $name="ts-raw">
|
||||
Whale
|
||||
</$slot>
|
||||
\end
|
||||
<$$mywidget $variable="Dingo">
|
||||
<$my.widget $variable="Dingo">
|
||||
Crocodile
|
||||
</$$mywidget>
|
||||
</$my.widget>
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
title: Transclude/Macro/Missing
|
||||
description: Transcluding a missing or blank variable
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
<$macrocall $name="missingmacro">
|
||||
Fallback content
|
||||
</$macrocall>
|
||||
|
||||
<$transclude $variable="missingmacro">
|
||||
Fallback content
|
||||
</$transclude>
|
||||
|
||||
<$macrocall $name="">
|
||||
Fallback content
|
||||
</$macrocall>
|
||||
|
||||
<$transclude $variable="">
|
||||
Fallback content
|
||||
</$transclude>
|
||||
|
||||
<$let emptyVariable="">
|
||||
|
||||
<$macrocall $name="emptyVariable">
|
||||
Fallback content
|
||||
</$macrocall>
|
||||
|
||||
<$transclude $variable="emptyVariable">
|
||||
Fallback content
|
||||
</$transclude>
|
||||
|
||||
</$let>
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>Fallback content</p><p>Fallback content</p><p>Fallback content</p><p>Fallback content</p><p>Fallback content</p><p>Fallback content</p>
|
||||
@@ -56,7 +56,7 @@ Tests the checkbox widget thoroughly.
|
||||
* Test data for checkbox widget tests
|
||||
*/
|
||||
|
||||
const fieldModeTests = [
|
||||
var fieldModeTests = [
|
||||
{
|
||||
testName: "field mode checked",
|
||||
tiddlers: [{title: "TiddlerOne", text: "Jolly Old World", expand: "yes"}],
|
||||
@@ -95,16 +95,16 @@ Tests the checkbox widget thoroughly.
|
||||
},
|
||||
];
|
||||
|
||||
const indexModeTests = fieldModeTests.map(data => {
|
||||
const newData = {...data};
|
||||
const newName = data.testName.replace('field mode', 'index mode');
|
||||
const newTiddlers = data.tiddlers.map(tiddler => {
|
||||
var indexModeTests = fieldModeTests.map(data => {
|
||||
var newData = {...data};
|
||||
var newName = data.testName.replace('field mode', 'index mode');
|
||||
var newTiddlers = data.tiddlers.map(tiddler => {
|
||||
return {title: tiddler.title, type: "application/x-tiddler-dictionary", text: `one: a\nexpand: ${tiddler.expand}\ntwo: b`}
|
||||
});
|
||||
const newWidgetText = data.widgetText.replace("field='expand'", "index='expand'");
|
||||
const newChange = {};
|
||||
for (const key of Object.keys(data.expectedChange)) {
|
||||
const oldChange = data.expectedChange[key];
|
||||
var newWidgetText = data.widgetText.replace("field='expand'", "index='expand'");
|
||||
var newChange = {};
|
||||
for (var key of Object.keys(data.expectedChange)) {
|
||||
var oldChange = data.expectedChange[key];
|
||||
if (oldChange.expand) {
|
||||
newChange[key] = { text: `one: a\nexpand: ${oldChange.expand}\ntwo: b` }
|
||||
} else {
|
||||
@@ -119,7 +119,26 @@ Tests the checkbox widget thoroughly.
|
||||
return newData;
|
||||
});
|
||||
|
||||
const listModeTests = [
|
||||
var listModeTestsForDateFields = [
|
||||
{
|
||||
testName: "list mode created date field",
|
||||
tiddlers: [{title: "Colors", created: "201304152222", modified: "202301022222"}],
|
||||
widgetText: "<$checkbox tiddler='Colors' listField='created' checked='green' />",
|
||||
startsOutChecked: false,
|
||||
finalValue: false,
|
||||
expectedChange: { "Colors": { created: new Date("2013-04-15T22:22:00Z")}} // created field should *not* be touched by a listField checkbox
|
||||
},
|
||||
{
|
||||
testName: "list mode modified date field",
|
||||
tiddlers: [{title: "Colors", created: "201304152222", modified: "202301022222"}],
|
||||
widgetText: "<$checkbox tiddler='Colors' listField='modified' checked='green' />",
|
||||
startsOutChecked: false,
|
||||
finalValue: false,
|
||||
expectedChange: { "Colors": { modified: new Date("2023-01-02T22:22:00Z")}} // modified field should *not* be touched by a listField checkbox
|
||||
},
|
||||
]
|
||||
|
||||
var listModeTests = [
|
||||
{
|
||||
testName: "list mode add",
|
||||
tiddlers: [{title: "Colors", colors: "orange yellow"}],
|
||||
@@ -235,11 +254,11 @@ Tests the checkbox widget thoroughly.
|
||||
];
|
||||
|
||||
// https://github.com/Jermolene/TiddlyWiki5/issues/6871
|
||||
const listModeTestsWithListField = (
|
||||
var listModeTestsWithListField = (
|
||||
listModeTests
|
||||
.filter(data => data.widgetText.includes("listField='colors'"))
|
||||
.map(data => {
|
||||
const newData = {
|
||||
var newData = {
|
||||
...data,
|
||||
tiddlers: data.tiddlers.map(tiddler => ({...tiddler, list: tiddler.colors, colors: undefined})),
|
||||
widgetText: data.widgetText.replace("listField='colors'", "listField='list'"),
|
||||
@@ -250,11 +269,11 @@ Tests the checkbox widget thoroughly.
|
||||
return newData;
|
||||
})
|
||||
);
|
||||
const listModeTestsWithTagsField = (
|
||||
var listModeTestsWithTagsField = (
|
||||
listModeTests
|
||||
.filter(data => data.widgetText.includes("listField='colors'"))
|
||||
.map(data => {
|
||||
const newData = {
|
||||
var newData = {
|
||||
...data,
|
||||
tiddlers: data.tiddlers.map(tiddler => ({...tiddler, tags: tiddler.colors, colors: undefined})),
|
||||
widgetText: data.widgetText.replace("listField='colors'", "listField='tags'"),
|
||||
@@ -266,20 +285,20 @@ Tests the checkbox widget thoroughly.
|
||||
})
|
||||
);
|
||||
|
||||
const indexListModeTests = listModeTests.map(data => {
|
||||
const newData = {...data};
|
||||
const newName = data.testName.replace('list mode', 'index list mode');
|
||||
const newTiddlers = data.tiddlers.map(tiddler => {
|
||||
var indexListModeTests = listModeTests.map(data => {
|
||||
var newData = {...data};
|
||||
var newName = data.testName.replace('list mode', 'index list mode');
|
||||
var newTiddlers = data.tiddlers.map(tiddler => {
|
||||
if (tiddler.hasOwnProperty('colors')) {
|
||||
return {title: tiddler.title, type: "application/x-tiddler-dictionary", text: `one: a\ncolors: ${tiddler.colors}\ntwo: b`}
|
||||
} else if (tiddler.hasOwnProperty('someField')) {
|
||||
return {title: tiddler.title, type: "application/x-tiddler-dictionary", text: `one: a\nsomeField: ${tiddler.someField}\ntwo: b`}
|
||||
}
|
||||
});
|
||||
const newWidgetText = data.widgetText.replace("listField='colors'", "listIndex='colors'").replace(/\$field/g, '$index').replace("listField='someField'", "listIndex='someField'");
|
||||
const newChange = {};
|
||||
for (const key of Object.keys(data.expectedChange)) {
|
||||
const oldChange = data.expectedChange[key];
|
||||
var newWidgetText = data.widgetText.replace("listField='colors'", "listIndex='colors'").replace(/\$field/g, '$index').replace("listField='someField'", "listIndex='someField'");
|
||||
var newChange = {};
|
||||
for (var key of Object.keys(data.expectedChange)) {
|
||||
var oldChange = data.expectedChange[key];
|
||||
if (oldChange.colors) {
|
||||
newChange[key] = { text: `one: a\ncolors: ${oldChange.colors}\ntwo: b` }
|
||||
} else if (oldChange.someField !== undefined) {
|
||||
@@ -296,7 +315,7 @@ Tests the checkbox widget thoroughly.
|
||||
return newData;
|
||||
});
|
||||
|
||||
const filterModeTests = [
|
||||
var filterModeTests = [
|
||||
{
|
||||
testName: "filter mode false -> true",
|
||||
tiddlers: [{title: "Colors", colors: "red orange yellow"}],
|
||||
@@ -482,9 +501,10 @@ Tests the checkbox widget thoroughly.
|
||||
},
|
||||
];
|
||||
|
||||
const checkboxTestData = fieldModeTests.concat(
|
||||
var checkboxTestData = fieldModeTests.concat(
|
||||
indexModeTests,
|
||||
listModeTests,
|
||||
listModeTestsForDateFields,
|
||||
listModeTestsWithListField,
|
||||
listModeTestsWithTagsField,
|
||||
indexListModeTests,
|
||||
@@ -494,7 +514,7 @@ Tests the checkbox widget thoroughly.
|
||||
/*
|
||||
* Checkbox widget tests using the test data above
|
||||
*/
|
||||
for (const data of checkboxTestData) {
|
||||
for (var data of checkboxTestData) {
|
||||
it('checkbox widget test: ' + data.testName, function() {
|
||||
// Setup
|
||||
|
||||
@@ -505,7 +525,7 @@ Tests the checkbox widget thoroughly.
|
||||
|
||||
// Check initial state
|
||||
|
||||
const widget = findNodeOfType('checkbox', widgetNode);
|
||||
var widget = findNodeOfType('checkbox', widgetNode);
|
||||
// Verify that the widget is or is not checked as expected
|
||||
expect(widget.getValue()).toBe(data.startsOutChecked);
|
||||
|
||||
@@ -519,16 +539,16 @@ Tests the checkbox widget thoroughly.
|
||||
widget.handleChangeEvent(null);
|
||||
|
||||
// Check state again: in most tests, checkbox should be inverse of what it was
|
||||
const finalValue = data.hasOwnProperty('finalValue') ? data.finalValue : !data.startsOutChecked;
|
||||
var finalValue = data.hasOwnProperty('finalValue') ? data.finalValue : !data.startsOutChecked;
|
||||
expect(widget.getValue()).toBe(finalValue);
|
||||
|
||||
// Check that tiddler(s) has/have gone through expected change(s)
|
||||
for (const key of Object.keys(data.expectedChange)) {
|
||||
const tiddler = wiki.getTiddler(key);
|
||||
const change = data.expectedChange[key];
|
||||
for (const fieldName of Object.keys(change)) {
|
||||
const expectedValue = change[fieldName];
|
||||
const fieldValue = tiddler.fields[fieldName];
|
||||
for (var key of Object.keys(data.expectedChange)) {
|
||||
var tiddler = wiki.getTiddler(key);
|
||||
var change = data.expectedChange[key];
|
||||
for (var fieldName of Object.keys(change)) {
|
||||
var expectedValue = change[fieldName];
|
||||
var fieldValue = tiddler.fields[fieldName];
|
||||
expect(fieldValue).toEqual(expectedValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,14 +99,14 @@ Tests the filtering mechanism.
|
||||
},
|
||||
"TiddlerSix": {
|
||||
title: "TiddlerSix",
|
||||
text: "Missing inaction from TiddlerOne",
|
||||
text: "Missing inaction from [[TiddlerOne]]",
|
||||
filter: "[[one]] [[a a]] [subfilter{hasList!!list}]",
|
||||
tags: []
|
||||
},
|
||||
"TiddlerSeventh": {
|
||||
title: "TiddlerSeventh",
|
||||
text: "",
|
||||
list: "TiddlerOne [[Tiddler Three]] [[a fourth tiddler]] MissingTiddler",
|
||||
list: "[[TiddlerOne]] [[Tiddler Three]] [[a fourth tiddler]] [[MissingTiddler]]",
|
||||
tags: ["one"]
|
||||
},
|
||||
"Tiddler8": {
|
||||
@@ -144,7 +144,7 @@ Tests the filtering mechanism.
|
||||
modified: "201304152211"
|
||||
},{
|
||||
title: "Tiddler Three",
|
||||
text: "The speed of sound in light\n\nThere is no TiddlerZero but TiddlerSix",
|
||||
text: "The speed of sound in light\n\nThere is no [[TiddlerZero]] but [[TiddlerSix]]",
|
||||
tags: ["one","two"],
|
||||
cost: "56",
|
||||
value: "80",
|
||||
@@ -252,9 +252,9 @@ 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]]").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");
|
||||
});
|
||||
|
||||
@@ -990,10 +990,10 @@ Tests the filtering mechanism.
|
||||
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");
|
||||
expect(wiki.filterTiddlers("[!sortsub:string<sort2>]",anchorWidget).join(",")).toBe("filter regexp test,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,$:/ShadowPlugin,has filter,hasList,TiddlerOne,one");
|
||||
expect(wiki.filterTiddlers("[sortsub:number<sort2>]",anchorWidget).join(",")).toBe("one,TiddlerOne,hasList,has filter,a fourth tiddler,$:/TiddlerTwo,Tiddler Three,filter regexp test,$:/ShadowPlugin");
|
||||
expect(wiki.filterTiddlers("[!sortsub:number<sort2>]",anchorWidget).join(",")).toBe("$:/ShadowPlugin,filter regexp test,Tiddler Three,$:/TiddlerTwo,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,$:/TiddlerTwo,Tiddler Three,filter regexp test");
|
||||
expect(wiki.filterTiddlers("[!sortsub:string<sort2>]",anchorWidget).join(",")).toBe("filter regexp test,Tiddler Three,$:/TiddlerTwo,a fourth tiddler,$:/ShadowPlugin,has filter,hasList,TiddlerOne,one");
|
||||
expect(wiki.filterTiddlers("[[TiddlerOne]] [[$:/TiddlerTwo]] [[Tiddler Three]] [[a fourth tiddler]] +[!sortsub:number<sort3>]",anchorWidget).join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne,a fourth tiddler");
|
||||
expect(wiki.filterTiddlers("a1 a10 a2 a3 b10 b3 b1 c9 c11 c1 +[sortsub:alphanumeric<sort4>]",anchorWidget).join(",")).toBe("a1,a2,a3,a10,b1,b3,b10,c1,c9,c11");
|
||||
// #7155. The order of the output is the same as the input when an undefined variable is used in the subfitler
|
||||
@@ -1060,6 +1060,9 @@ Tests the filtering mechanism.
|
||||
expect(wiki.filterTiddlers("[[Hello There]] [[GettingStarted]] +[format:titlelist[]]").join(" ")).toBe("[[Hello There]] GettingStarted");
|
||||
expect(wiki.filterTiddlers("[title[Hello There]] +[format:titlelist[]]").join(" ")).toBe("[[Hello There]]");
|
||||
expect(wiki.filterTiddlers("[title[HelloThere]] +[format:titlelist[]]").join(" ")).toBe("HelloThere");
|
||||
expect(wiki.filterTiddlers("0 +[format:timestamp[]]").join(",")).toBe("19700101000000000");
|
||||
expect(wiki.filterTiddlers("1603188514443 +[format:timestamp[]]").join(",")).toBe("20201020100834443");
|
||||
expect(wiki.filterTiddlers("void +[format:timestamp[]]").join(",")).toBe("");
|
||||
});
|
||||
|
||||
it("should handle the deserializers operator", function() {
|
||||
|
||||
@@ -45,16 +45,6 @@ describe("WikiText tests", function() {
|
||||
it("should support attributes specified as macro invocations", function() {
|
||||
expect(wiki.renderTiddler("text/html","TiddlerFour")).toBe("<p><a class=\"tc-tiddlylink tc-tiddlylink-missing\" href=\"#This%20is%20my%20%27%27amazingly%27%27%20groovy%20macro%21\">This is a link</a></p>");
|
||||
});
|
||||
it("should identify wikiwords to automatically link", function() {
|
||||
expect(wiki.renderText("text/html","text/vnd-tiddlywiki","No wikilinks here").indexOf("<a") !== -1).toBe(false);
|
||||
expect(wiki.renderText("text/html","text/vnd-tiddlywiki","One WikiLink here").indexOf("<a") !== -1).toBe(true);
|
||||
expect(wiki.renderText("text/html","text/vnd-tiddlywiki","No Wiki-Link here").indexOf("<a") !== -1).toBe(false);
|
||||
expect(wiki.renderText("text/html","text/vnd-tiddlywiki","No Wiki×Link here").indexOf("<a") !== -1).toBe(false);
|
||||
expect(wiki.renderText("text/html","text/vnd-tiddlywiki","No Wiki÷Link here").indexOf("<a") !== -1).toBe(false);
|
||||
expect(wiki.renderText("text/html","text/vnd-tiddlywiki","No xWikiLink here").indexOf("<a") !== -1).toBe(false);
|
||||
expect(wiki.renderText("text/html","text/vnd-tiddlywiki","No -WikiLink here").indexOf("<a") !== -1).toBe(false);
|
||||
expect(wiki.renderText("text/html","text/vnd-tiddlywiki","No _WikiLink here").indexOf("<a") !== -1).toBe(false);
|
||||
});
|
||||
it("handles style wikitext notation", function() {
|
||||
expect(wiki.renderText("text/html","text/vnd-tiddlywiki","@@.myclass\n!header\n@@")).toBe("<h1 class=\"myclass\">header</h1>");
|
||||
expect(wiki.renderText("text/html","text/vnd-tiddlywiki","@@.myclass\n<div>\n\nContent</div>\n@@")).toBe("<div class=\"myclass\"><p>Content</p></div>");
|
||||
|
||||
@@ -6,6 +6,8 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
The edit template body cascade is a [[cascade|Cascades]] used by the default edit template to choose the template for displaying the tiddler body.
|
||||
|
||||
The core edit template body cascade can be found in $:/core/ui/EditTemplate/body
|
||||
|
||||
The default edit template body cascade consists of:
|
||||
|
||||
# If the tiddler has the field ''_canonical_uri'' then use the template $:/core/ui/EditTemplate/body/canonical-uri to display the remote URL
|
||||
@@ -13,4 +15,4 @@ The default edit template body cascade consists of:
|
||||
|
||||
You can see the current settings for the view template body cascade in $:/ControlPanel under the ''Info'' -> ''Advanced'' -> ''Cascades'' -> ''Edit Template Body'' tab.
|
||||
|
||||
<<list-links "[tag[Edit Template Body Cascade]]">>
|
||||
<<list-links "[tag[Edit Template Body Cascade]]">>
|
||||
|
||||
@@ -6,6 +6,8 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
The field editor cascade is a [[cascade|Cascades]] used to choose a template for rendering the field editor within the [[EditTemplate|$:/core/ui/EditTemplate/fields]].
|
||||
|
||||
The core field editor cascade can be found in $:/core/ui/EditTemplate/fields
|
||||
|
||||
The default field editor cascade only contains one element:
|
||||
|
||||
# Use the tiddler $:/core/ui/EditTemplate/fieldEditor/default to render the field
|
||||
@@ -14,4 +16,4 @@ See [[Customizing EditTemplate field rendering]] for more details.
|
||||
|
||||
You can see the current settings for the field editor cascade in $:/ControlPanel under the ''Info'' -> ''Advanced'' -> ''Cascades'' -> ''Field Editor'' tab.
|
||||
|
||||
<<list-links "[tag[Tiddler Field Editor Cascade]]">>
|
||||
<<list-links "[tag[Tiddler Field Editor Cascade]]">>
|
||||
|
||||
@@ -6,6 +6,8 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
"Story tiddler template" refers to the template used to display a tiddler within the story river.
|
||||
|
||||
The core story tiddler template can be found in $:/core/ui/StoryTiddlerTemplate
|
||||
|
||||
The [[Story Tiddler Template Cascade]] is used to choose the template to be used for a particular tiddler. By default, the edit template is used for tiddlers in draft mode, and the view template used otherwise.
|
||||
|
||||
See also:
|
||||
|
||||
@@ -6,6 +6,8 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
The tiddler colour cascade is a [[cascade|Cascades]] used to choose which colour should be used for a particular tiddler.
|
||||
|
||||
Core tiddler colour cascades can be found in $:/core/macros/tag, $:/core/ui/Components/tag-link, $:/core/ui/EditTemplate/tags, $:/core/ui/TagPickerTagTemplate, $:/core/ui/TagTemplate and $:/core/ui/ViewTemplate/title
|
||||
|
||||
The default tiddler colour cascade consists of:
|
||||
|
||||
# If the tiddler has a ''color'' field, use the value as the colour
|
||||
@@ -13,4 +15,4 @@ The default tiddler colour cascade consists of:
|
||||
|
||||
You can see the current settings for the tiddler colour cascade in $:/ControlPanel under the ''Info'' -> ''Advanced'' -> ''Cascades'' -> ''Tiddler Colour'' tab.
|
||||
|
||||
<<list-links "[tag[Tiddler Colour Cascade]]">>
|
||||
<<list-links "[tag[Tiddler Colour Cascade]]">>
|
||||
|
||||
@@ -6,6 +6,8 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
The tiddler icon cascade is a [[cascade|Cascades]] used to choose which icon should be used for a particular tiddler.
|
||||
|
||||
The core tiddler icon cascade can be found in $:/core/ui/TiddlerIcon
|
||||
|
||||
The default tiddler icon cascade consists of:
|
||||
|
||||
# If the tiddler has an ''icon'' field, use the value as the title of the icon tiddler
|
||||
@@ -13,4 +15,4 @@ The default tiddler icon cascade consists of:
|
||||
|
||||
You can see the current settings for the tiddler icon cascade in $:/ControlPanel under the ''Info'' -> ''Advanced'' -> ''Cascades'' -> ''Tiddler Icon'' tab.
|
||||
|
||||
<<list-links "[tag[Tiddler Icon Cascade]]">>
|
||||
<<list-links "[tag[Tiddler Icon Cascade]]">>
|
||||
|
||||
@@ -6,6 +6,8 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
The view template title cascade is a [[cascade|Cascades]] used by the default view template to choose the template for displaying the tiddler title.
|
||||
|
||||
The core view template title cascade can be found in $:/core/ui/ViewTemplate/title
|
||||
|
||||
The default view template title cascade consists of:
|
||||
|
||||
# If the tiddler title starts with `$:/` then use the template $:/core/ui/ViewTemplate/title/system which causes the `$:/` prefix to be displayed in pale text
|
||||
@@ -13,4 +15,4 @@ The default view template title cascade consists of:
|
||||
|
||||
You can see the current settings for the view template title cascade in $:/ControlPanel under the ''Info'' -> ''Advanced'' -> ''Cascades'' -> ''View Template Title'' tab.
|
||||
|
||||
<<list-links "[tag[View Template Title Cascade]]">>
|
||||
<<list-links "[tag[View Template Title Cascade]]">>
|
||||
|
||||
@@ -45,7 +45,7 @@ Special tags assign special behaviour or appearance to all of the tiddlers to wh
|
||||
|
||||
For example:
|
||||
|
||||
* $:/tags/Macro causes the macros defined in a tiddler to be available globally
|
||||
* $:/tags/Global causes the definitions in a tiddler to be available globally
|
||||
* $:/tags/Stylesheet causes the tiddler to be interpreted as a CSS stylesheet
|
||||
* $:/tags/SideBar causes the tiddler to be displayed as a sidebar tab
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ modified: 20230410105035569
|
||||
|
||||
<span style="float:right;">[img width=340 [Xememex Logo]]</span>
|
||||
|
||||
Xememex is a multiuser TiddlyWiki from [[Federatial]]. It allows large groups of people to work together on intertwingled wikis that can share content.
|
||||
Xememex is a multiuser TiddlyWiki from [[Federatial]]. It allows large groups of people to work together on intertwingled wikis that can share content. It is implemented as a serverless application on Amazon Web Services.
|
||||
|
||||
The largest customer implementation has hundreds of online wikis with thousands of users. See https://manuals.annafreud.org/
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ The initial startup actions are useful for customising TiddlyWiki according to e
|
||||
Note that global macros are not available within initial startup action tiddlers by default. If you need to access them then you'll need to explicitly include them with an [[Pragma: \import]] at the top of the tiddler:
|
||||
|
||||
```
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
```
|
||||
|
||||
!! Post-Render Startup Actions
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20201020102735123
|
||||
modified: 20220611104737314
|
||||
modified: 20230226135641976
|
||||
tags: [[Operator Examples]] [[format Operator]]
|
||||
title: format Operator (Examples)
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -15,20 +15,23 @@ Created date with a format string supplied as operator parameter:
|
||||
Modified date shown as a relative date:
|
||||
<<.operator-example 3 "[[HelloThere]get[modified]format:relativedate[]]">>
|
||||
|
||||
Get the date and time exactly 24 hours (86,400,000 milliseconds) from now:
|
||||
<<.operator-example 4 "[<now [UTC]YYYY0MM0DD0hh0mm0ss0XXX>format:date[TIMESTAMP]add[86400000]format:timestamp[DDth mmm YYYY 0hh:0mm:0ss]]">>
|
||||
|
||||
A tiddler title with spaces formatted as a title list:
|
||||
<<.operator-example 4 """[[Hello There]format:titlelist[]]""">>
|
||||
<<.operator-example 5 """[[Hello There]format:titlelist[]]""">>
|
||||
|
||||
All tiddler titles tagged with <<tag TableOfContents>> formatted as a title list:
|
||||
<<.operator-example 5 """[tag[TableOfContents]format:titlelist[]]""">>
|
||||
<<.operator-example 6 """[tag[TableOfContents]format:titlelist[]]""">>
|
||||
|
||||
A JSON string formatted as JSON – note how the JSON string is normalised to remove the duplicated properties:
|
||||
<<.operator-example 6 """[[{"one":"first","one":"another","two":"second"}]format:json[]]""">>
|
||||
<<.operator-example 7 """[[{"one":"first","one":"another","two":"second"}]format:json[]]""">>
|
||||
|
||||
<<.tip "To create a string to save a [[title list|Title List]] into a list field, use `format:titlelist[]` with the [[join operator|join Operator]]">>
|
||||
<<.operator-example 6 """[tag[TableOfContents]format:titlelist[]join[ ]]""">>
|
||||
<<.operator-example 8 """[tag[TableOfContents]format:titlelist[]join[ ]]""">>
|
||||
For example, to save titles tagged `TableOfContents` to the titles field of the tiddler [[format titlelist test]]:
|
||||
|
||||
<$macrocall $name='wikitext-example-without-html'
|
||||
src='<$button> test
|
||||
src='<$button>Try it
|
||||
<$action-setfield $tiddler="format titlelist test" titles={{{ [tag[TableOfContents]format:titlelist[]join[ ]] }}}/>
|
||||
</$button>'/>
|
||||
|
||||
@@ -20,8 +20,11 @@ The suffix <<.place B>> is one of the following supported string formats:
|
||||
|^`date` |The input string is interpreted as a UTC date and displayed according to the DateFormat specified in the optional operator operand. (Defaults to "YYYY MM DD 0hh:0mm") |
|
||||
|^`json` |<<.from-version "5.2.4">> The input string is interpreted as JSON and displayed with standard formatting. The optional operator operand specifies the number of spaces to use for indenting, or a string to use for indenting. Nothing is returned if the input string is not valid JSON |
|
||||
|^`relativedate` |The input string is interpreted as a UTC date and displayed as the interval from the present instant. Any operator parameters are ignored |
|
||||
|^`timestamp` |<<.from-version "5.3.0">> The input string is interpreted as number of milliseconds since the [[ECMAScript epoch|https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#the_ecmascript_epoch_and_timestamps]], 1 January 1970, and displayed according to the DateFormat specified in the optional operator operand. (Defaults to "[UTC]YYYY0MM0DD0hh0mm0ss0XXX") |
|
||||
|^`titlelist` |<<.from-version "5.2.0">> The input string wrapped in double square brackets if it contains a space. Appropriate for use in a [[title list|Title List]]. |
|
||||
|
||||
Invalid input strings are dropped by the <<.op format>> operator.
|
||||
|
||||
<<.warning """The [[Title List]] format cannot reliably represent items that contain certain specific character sequences such as `]] `. Thus it should not be used where there is a possibility of such sequences occurring.""">>
|
||||
|
||||
<<.operator-examples "format">>
|
||||
|
||||
@@ -21,7 +21,7 @@ Functions can be invoked in several ways:
|
||||
* Directly transclude functions with the syntax `<<myfn param:"value">>`
|
||||
* Assign functions to widget attributes with the syntax `<div class=<<myfn param:"value">>>`
|
||||
* Invoke functions via the [[function Operator]] with the syntax `[function[myfn],[value],...]`
|
||||
* Directly invoke functions whose names start with a period as custom filter operators with the syntax `[.myfn[value]]`
|
||||
* Directly invoke functions whose names contain a period as custom filter operators with the syntax `[my.fn[value]]` or `[.myfn[value]]`
|
||||
|
||||
!! How Functions Work
|
||||
|
||||
|
||||
@@ -77,11 +77,11 @@ In the [[Keyboard Shortcuts Tab|$:/core/ui/ControlPanel/KeyboardShortcuts]] the
|
||||
> If the tiddler has the tag <<tag $:/tags/KeyboardShortcut>>, the field ''key'' with the [[Keyboard Shortcut Descriptor]] as its value and some actions in its text field, the actions will be triggered when the mechanism detects the configured key-combination
|
||||
|
||||
<br>
|
||||
<$macrocall $name=".tip" _="""''Macros'' defined ''outside'' a global keyboard-shortcut (through a tiddler tagged `$:/tags/Macro`) need to be ''imported'' in order to be accessible.
|
||||
<$macrocall $name=".tip" _="""''Macros'' defined ''outside'' a global keyboard-shortcut (through a tiddler tagged `$:/tags/Global`) need to be ''imported'' in order to be accessible.
|
||||
The [[import pragma|Pragma]] can be used for that"""/>
|
||||
|
||||
<pre>
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
</pre>
|
||||
|
||||
If the tiddler that contains the macro definition is known and - for example - titled `my-macro-tiddler`
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
created: 20160810122928198
|
||||
modified: 20160810122934291
|
||||
modified: 20230505104214168
|
||||
tags: [[Editor toolbar]]
|
||||
title: Using Excise
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
|
||||
! Excise text
|
||||
From the EditorToolbar you can export selected text to a new tiddler and insert a [[link|Linking in WikiText]] [[Transclusion]] or [[macro|Macros]] in its place. Click ''Excise text'' (<<.icon $:/core/images/excise>>), input name of the new tiddler, and choose excise method.
|
||||
|
||||
!! How to excise text
|
||||
# Highlight the relevant piece of text
|
||||
#Click ''Excise text'' (<<.icon $:/core/images/excise>>)
|
||||
# Click ''Excise text'' (<<.icon $:/core/images/excise>>)
|
||||
# Give the new tiddler a title.
|
||||
# Chosse if the new tiddler will be tagged with the title of the current tiddler''*''.
|
||||
# Choose replacing method. [[link|Linking in WikiText]] [[Transclusion]] or [[macro|Macros]].
|
||||
|
||||
# Chosse if the new tiddler will be tagged with the title of the current tiddler (see note below).
|
||||
# Choose replacing method: [[link|Linking in WikiText]], [[transclusion|Transclusion]], or [[macro|Macros]].
|
||||
# Click the ''{{$:/language/Buttons/Excise/Caption/Excise}}'' button
|
||||
|
||||
|
||||
|
||||
''*NOTE:'' If you choose tic the option to `Tag new tiddler with the title of this tiddler`. The tag will be the'' draft title''. If you create a new tiddler (or clone an existing one), the draft title and the tag, will be `New Tiddler`. __You have to save the tiddler and re-edit it to get the new title as tag.__
|
||||
<<.strong Note!>> If you choose the option to `Tag new tiddler with the title of this tiddler`, the new tiddler will be tagged with the name of the current tiddler before it has been edited. If you have changed the title of the current tiddler, save it first and edit it again to perform excision with this option.
|
||||
|
||||
21
editions/tw5.com/tiddlers/macros/TranslinkMacro.tid
Normal file
21
editions/tw5.com/tiddlers/macros/TranslinkMacro.tid
Normal file
@@ -0,0 +1,21 @@
|
||||
created: 20230505090333510
|
||||
modified: 20230505090333510
|
||||
tags: Macros [[Core Macros]]
|
||||
title: translink Macro
|
||||
type: text/vnd.tiddlywiki
|
||||
caption: translink
|
||||
|
||||
The <<.def translink>> [[macro|Macros]] returns a frame with the title and [[transcluded|Transclusion]] text of a chosen tiddler. The title links to the transcluded tiddler.
|
||||
|
||||
If the chosen tiddler is missing, an appropriate message will be shown instead of the transcluded text.
|
||||
|
||||
This is the default macro used when [[excising|Using Excise]] text and replacing it with a macro.
|
||||
|
||||
!! Parameters
|
||||
|
||||
; title
|
||||
: The title of the tiddler to be transcluded
|
||||
; mode
|
||||
: The mode of the [[transclude widget|TranscludeWidget]] used inside the macro, defaults to `block`
|
||||
|
||||
<<.macro-examples "translink">>
|
||||
9
editions/tw5.com/tiddlers/macros/examples/translink.tid
Normal file
9
editions/tw5.com/tiddlers/macros/examples/translink.tid
Normal file
@@ -0,0 +1,9 @@
|
||||
created: 20230505092952569
|
||||
modified: 20230505092952569
|
||||
tags: [[translink Macro]] [[Macro Examples]]
|
||||
title: translink Macro (Examples)
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<$macrocall $name=".example" n="1" eg="""<<translink "Philosophy of Tiddlers">>"""/>
|
||||
<$macrocall $name=".example" n="2" eg="""<<translink "Philosophy of Tiddlers" inline>>"""/>
|
||||
<$macrocall $name=".example" n="3" eg="""<<translink Foo>>"""/>
|
||||
@@ -13,7 +13,7 @@ Excises the currently selected text into a new tiddler and replaces it with a li
|
||||
|!Name |!Description |
|
||||
|title |Title of the new tiddler the selected content is excised to|
|
||||
|type |Type of the replacement to be inserted: Can be one of <<.value "transclude">>, <<.value "link">> or <<.value "macro">>|
|
||||
|macro |In case //type=<<.value "macro">>//, specifies the name of the macro to be inserted. The title of the new tiddler is provided as the first parameter to the macro. Defaults to the ''translink'' macro|
|
||||
|macro |In case //type=<<.value "macro">>//, specifies the name of the macro to be inserted. The title of the new tiddler is provided as the first parameter to the macro. Defaults to the [[translink macro|translink Macro]]|
|
||||
|tagnew |If '<<.value "yes">>', will tag the new tiddler with the title of the tiddler currently being edited |
|
||||
|
||||
</div>
|
||||
|
||||
@@ -29,6 +29,8 @@ Each field can be specified as either a ''string'' or ''array'' value to be assi
|
||||
** //extname// the extension of the filename of the file containing the tiddler
|
||||
** //created// the creation date/time of the file containing the tiddler
|
||||
** //modified// the modification date/time of the file containing the tiddler
|
||||
** <<.from-version "5.3.0">> //filepath// the path of the file containing the tiddler, relative to the ''path'' property of the directory (only usable in ''directories'' declarations)
|
||||
** <<.from-version "5.3.0">> //subdirectories// an array of the subdirectories in the file's path relative, to the ''path'' property of the directory (only usable in ''directories'' declarations)
|
||||
* ''prefix'' - (optional) a string to be prepended to the value of the field
|
||||
* ''suffix'' - (optional) a string to be appended to the value of the field
|
||||
|
||||
@@ -52,7 +54,7 @@ Directory specifications in the `directories` array may take the following forms
|
||||
** ''filesRegExp'' - (optional) a [[regular expression|https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions]] that matches the filenames of the files that should be processed within the directory
|
||||
** ''isTiddlerFile'' - (required) if `true`, the file will be treated as a [[tiddler file|TiddlerFiles]] and deserialised to extract the tiddlers. Otherwise, the raw content of the file is assigned to the `text` field without any parsing
|
||||
** ''isEditableFile'' - <<.from-version "5.1.23">> (optional) if `true`, changes to the tiddler be saved back to the original file. The tiddler will be saved back to the original filepath as long as it does not generate a result from the $:/config/FileSystemPath filters, which will override the final filepath generated if a result is returned from a filter.
|
||||
** ''searchSubdirectories'' - <<.from-version "5.1.23">> (optional) if `true`, all subdirectories of the //path// are searched recursively for files that match the (optional) //filesRegExp//. If no //filesRegExp// is provided, all files in all subdirectories of the //path// are loaded. Tiddler titles generated via a //source// attribute (see above) will only include the filename, not any of the subdirectories of the path. If this results in multiple files with loaded with the same tiddler title, then only the last file loaded under that tiddler title will be in memory. In order to prevent this, you must have multiple directory objects listed and customise the title field with a //prefix// or //suffix// alongside the //source// attribute.
|
||||
** ''searchSubdirectories'' - <<.from-version "5.1.23">> (optional) if `true`, all subdirectories of the //path// are searched recursively for files that match the (optional) //filesRegExp//. If no //filesRegExp// is provided, all files in all subdirectories of the //path// are loaded. Tiddler titles generated via the //source// attribute //filename// (see above) will only include the filename, not any of the subdirectories of the path. If this results in multiple files with loaded with the same tiddler title, then only the last file loaded under that tiddler title will be in memory. In order to prevent this, you can use the //filepath// attribute instead of //filename//. Alternately, you can include multiple directory objects and customise the title field with a //prefix// or //suffix// alongside the //source// attribute.
|
||||
** ''fields'' - (required) an object containing values that override or customise the fields provided in the tiddler file (see above)
|
||||
|
||||
Fields can also be overridden for particular files by creating a file with the same name plus the suffix `.meta` -- see TiddlerFiles.
|
||||
@@ -95,6 +97,7 @@ This example retrieves all the files with the extension `.pdf` from a folder spe
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
!! Importing a folder of text files
|
||||
|
||||
This example retrieves all the files with the extension `.txt` from a folder specified by a relative path. This folder is within the wiki's base directory, and the current config file is in a directory within the wiki's "tiddlers/" directory. So, in this case the path starts with "../../" to traverse upwards two directory levels, and then down into the "externalnotes/" directory. Each tiddler is set up with the following fields:
|
||||
@@ -130,4 +133,39 @@ This will load all text files in the `../../externalnotes/` directory into the w
|
||||
|
||||
From the examples in [[Customising Tiddler File Naming]] we see that the final `[!tag[externalnote]addprefix[wiki/]]` filter in the $:/config/FileSystemPaths tiddler excludes all tiddlers tagged with `externalnotes` (that have not matched an earlier filter). These tiddlers have their filepath retrieved from the $:/config/OriginalTiddlerPaths generated upon boot startup.
|
||||
|
||||
Then, the `[tag[.txt]then[.txt]]` filter in the $:/config/FileSystemExtensions tiddler forces all these tiddlers to be saved back to disk as *.txt and accompanying *.txt.meta files (overriding the normal tiddler-type to file-type mapping). In this case, allowing the snippets of Tiddlywiki wikitext or markdown-text to be saved back to "text" *.txt files.
|
||||
Then, the `[tag[.txt]then[.txt]]` filter in the $:/config/FileSystemExtensions tiddler forces all these tiddlers to be saved back to disk as *.txt and accompanying *.txt.meta files (overriding the normal tiddler-type to file-type mapping). In this case, allowing the snippets of Tiddlywiki wikitext or markdown-text to be saved back to "text" *.txt files.
|
||||
|
||||
!! Importing and auto-tagging images
|
||||
|
||||
This example imports all the image files in the `files` directory and all its subdirectories as external-image tiddlers, and tags them based on their filepath. Each tiddler is set up with the following fields:
|
||||
|
||||
* ''title'' - set to the URI decoded base filename of the text file
|
||||
* ''created'' - set to the creation date/time of the text file
|
||||
* ''modified'' - set to the modification date/time of the text file
|
||||
* ''type'' - set to `image/jpeg`. There is currently no way to infer the correct ContentType of the image tiddler from the file, but `image/jpeg` tiddlers should render correctly even with png or gif images. As an alternative, you could create separate definitions for jpg, png, and gif files with the `image/jpeg`, `image/png`, and `image/gif` types respectively.
|
||||
* ''tags'' - generated based on the path of the image relative to the parent directory (`files` in this case). Eg, images in `files/photos` will be tagged with `photos`, those in `files/photos/family` will be tagged with both `photos` and `family`, and those in the root `files` directory will have no tags.
|
||||
* ''text'' - set to an empty string
|
||||
* ''_canonical_uri'' - set to the full filepath of the image relative to the wiki root
|
||||
|
||||
|
||||
```
|
||||
{
|
||||
"directories": [
|
||||
{
|
||||
"path": "../../files/",
|
||||
"filesRegExp": "^.*\\.(?:jpg|jpeg|png|gif)$",
|
||||
"isTiddlerFile": false,
|
||||
"searchSubdirectories": true,
|
||||
"fields": {
|
||||
"title": {"source": "basename-uri-decoded"},
|
||||
"created": {"source": "created"},
|
||||
"modified": {"source": "modified"},
|
||||
"type": "image/jpeg",
|
||||
"tags": { "source": "subdirectories" },
|
||||
"text": "",
|
||||
"_canonical_uri": { "source": "filepath", "prefix": "files/" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -13,5 +13,5 @@ The ''\import'' [[pragma|Pragmas]] is used to import definitions from other tidd
|
||||
For example:
|
||||
|
||||
```
|
||||
\import [all[shadows+tiddlers]tag[$:/tags/Macro]]
|
||||
\import [all[shadows+tiddlers]tag[$:/tags/Global]]
|
||||
```
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
created: 20220917113154900
|
||||
modified: 20230419103154329
|
||||
modified: 20230518143557045
|
||||
tags: Pragmas
|
||||
title: Pragma: \parameters
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.from-version "5.3.0">> The ''\parameters'' [[pragma|Pragmas]] is used within [[procedure|Procedure Definitions]] and [[widget|Widget Definitions]] definitions to declare the parameters that are expected, and their default values. It is a shortcut syntax for the ParametersWidget.
|
||||
<<.from-version "5.3.0">> The ''\parameters'' [[pragma|Pragmas]] is used within [[procedure|Procedure Definitions]] and [[widget|Custom Widgets]] definitions to declare the parameters that are expected, and their default values. It is a shortcut syntax for the ParametersWidget.
|
||||
|
||||
```
|
||||
\parameters (<name>[:<default-value>],<name>[:<default-value>]...)
|
||||
@@ -16,3 +16,11 @@ For example:
|
||||
\parameters (firstname:"Joe",lastname:"Blogs")
|
||||
```
|
||||
|
||||
To illustrate the use of ''\parameters'' pragma, see [[Core Icons]] which are parameterised. The first parameter `size` specified the size at which the icon should be rendered. For example see the text of [[$:/core/images/print-button]] tiddler. The first line defines the size parameter as `\parameters (size:"22pt")`
|
||||
|
||||
<<wikitext-example-without-html """{{$:/core/images/print-button|16px}}
|
||||
<$transclude $tiddler="$:/core/images/print-button" size="32px"/>
|
||||
""">>
|
||||
|
||||
In the above example, the first line shows a simple transclusion of [[$:/core/images/print-button]] icon with `size` parameter passed by position and is set to 16px. The second line is a transclusion of image with `size` parameter passed by name and is set to 32px.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20221007132845007
|
||||
modified: 20230419103154329
|
||||
modified: 20230518152756112
|
||||
tags: Pragmas
|
||||
title: Pragma: \procedure
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -28,7 +28,7 @@ For example:
|
||||
|
||||
```
|
||||
\procedure sayhi(name:"Bugs Bunny")
|
||||
Hi, I'm $name$.
|
||||
Hi, I'm <<name>>.
|
||||
\end
|
||||
|
||||
<<sayhi "Jeremy">>
|
||||
@@ -37,7 +37,7 @@ Hi, I'm $name$.
|
||||
Alternatively, the entire definition can be presented on a single line without an `\end` marker:
|
||||
|
||||
```
|
||||
\procedure sayhi(name:"Bugs Bunny") Hi, I'm $name$.
|
||||
\procedure sayhi(name:"Bugs Bunny") Hi, I'm <<name>>.
|
||||
```
|
||||
|
||||
Procedure definitions can be nested by specifying the name of the procedure in the `\end` marker. For example:
|
||||
@@ -47,9 +47,64 @@ Procedure definitions can be nested by specifying the name of the procedure in t
|
||||
<$action-sendmessage $message="tm-notify" $param="HelloThere"/>
|
||||
\end actions
|
||||
<$button actions=<<actions>>>
|
||||
$caption$
|
||||
<<caption>>
|
||||
</$button>
|
||||
\end special-button
|
||||
|
||||
<<special-button>>
|
||||
""">>
|
||||
|
||||
! Use of Parameters Inside Procedures
|
||||
The parameters can be declared inside procedures. The parameters widget is necessary in a procedure if you want to use computed default values. For example:
|
||||
|
||||
<<wikitext-example-without-html
|
||||
src:"""\procedure myproc()
|
||||
<$parameters name={{$:/SiteTitle}} desc={{$:/SiteSubtitle}}>
|
||||
This is <<name>> demonstrates <<desc>>.
|
||||
</$parameters>
|
||||
\end
|
||||
|
||||
<<myproc>>
|
||||
""">>
|
||||
|
||||
!! Caution in Using Positional Parameters
|
||||
Procedures are a shortcut syntax for the SetVariableWidget with an implicit ParametersWidget, so generally there is no reason to have multiple parameters widgets within a definition. In the below example when passing `x` to `myproc`, it will also be set to `a`:
|
||||
|
||||
<<wikitext-example-without-html
|
||||
src:"""\procedure myproc(x:10)
|
||||
\parameters (a:100, b:200)
|
||||
|
||||
x=<<x>>, a=<<a>>, b=<<b>>
|
||||
\end
|
||||
|
||||
<<myproc 50>>
|
||||
""">>
|
||||
|
||||
The reason for that result is clearer if we consider an equivalent with explicit parameters widgets.
|
||||
|
||||
<$macrocall $name=wikitext-example-without-html
|
||||
src='<$let myprog="""
|
||||
\parameters (x:10)
|
||||
\parameters (a:100, b:200)
|
||||
|
||||
x=<<x>>, a=<<a>>, b=<<b>>
|
||||
""">
|
||||
<<myprog 50>>
|
||||
</$let>'
|
||||
/>
|
||||
|
||||
This is because those two parameters widgets are entirely independent. They are both processed as if the other parameter widget is not there.
|
||||
|
||||
<<.tip "The positional parameters are only required when using the parameterised transclusion shortcut syntax, and that in other cases it is generally clearer to use named parameters.">>
|
||||
|
||||
To prevent such situation of above example, pass parameters by name as below.
|
||||
|
||||
<<wikitext-example-without-html
|
||||
src:"""\procedure myproc(x:10)
|
||||
\parameters (a:100, b:200)
|
||||
|
||||
x=<<x>>, a=<<a>>, b=<<b>>
|
||||
\end
|
||||
|
||||
<<myproc x:50>>
|
||||
""">>
|
||||
@@ -1,4 +1,4 @@
|
||||
caption: Macro Calls
|
||||
caption: Procedure Calls
|
||||
created: 20221007130006705
|
||||
modified: 20230419103154329
|
||||
tags: WikiText Procedures
|
||||
@@ -7,7 +7,7 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
!! Introduction
|
||||
|
||||
This tiddler describes the different ways in which [[macros|Procedures]] can be called.
|
||||
This tiddler describes the different ways in which [[procedure|Procedures]] can be called.
|
||||
|
||||
!! Procedure Call Transclusion Shortcut
|
||||
|
||||
|
||||
@@ -6,15 +6,15 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
!! Introduction
|
||||
|
||||
This tiddler describes the different ways in which [[macros|Procedures]] can be defined.
|
||||
This tiddler describes the different ways in which [[Procedures|Procedures]] can be defined.
|
||||
|
||||
!! Procedure Definition Pragma
|
||||
|
||||
Macros are created using the [[Pragma: \procedure]] at the start of a tiddler. The definitions are available in the rest of the tiddler that defines them, plus any tiddlers that it transcludes.
|
||||
Procedures are created using the [[Pragma: \procedure]] at the start of a tiddler. The definitions are available in the rest of the tiddler that defines them, plus any tiddlers that it transcludes.
|
||||
|
||||
```
|
||||
\define my-procedure(param)
|
||||
This is the macro text (param=<<param>>)
|
||||
This is the procedure text (param=<<param>>)
|
||||
\end
|
||||
```
|
||||
|
||||
@@ -34,10 +34,10 @@ Procedures are implemented as a special kind of [[variable|Variables]] and so in
|
||||
|
||||
The [[Pragma: \import]] or <<.wlink ImportVariablesWidget>> widget can be used to copy procedure definitions from another tiddler.
|
||||
|
||||
!! `$:/tags/Macro` Tag
|
||||
!! `$:/tags/Global` Tag
|
||||
|
||||
Global procedures can be defined using the [[SystemTag: $:/tags/Macro]].
|
||||
Global procedures can be defined using the [[SystemTag: $:/tags/Global]].
|
||||
|
||||
The tag [[SystemTag: $:/tags/Macro/View]] is used to define procedures that should only be available within the main view template and the preview panel.
|
||||
The tag [[SystemTag: $:/tags/Global/View]] is used to define procedures that should only be available within the main view template and the preview panel.
|
||||
|
||||
The tag [[SystemTag: $:/tags/Macro/View/Body]] is used to define procedures that should only be available within the main view template body and the preview panel.
|
||||
The tag [[SystemTag: $:/tags/Global/View/Body]] is used to define procedures that should only be available within the main view template body and the preview panel.
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ReadMe
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
\define tv-wikilink-template() https://tiddlywiki.com/static/$uri_doubleencoded$.html
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
|
||||
Welcome to TiddlyWiki, a non-linear personal web notebook that anyone can use and keep forever, independently of any corporation.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ tags: $:/tags/RawMarkupWikified/TopBody
|
||||
title: $:/SplashScreen
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
|
||||
\procedure show-icon(title)
|
||||
<$wikify name="icon" text={{{ [<title>addprefix[{{]addsuffix[}}]] }}} output="html">
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
title: $:/config/WikiParserRules/Inline/wikilink
|
||||
|
||||
enable
|
||||
@@ -134,7 +134,11 @@ This is an example tiddler. See [[Table-of-Contents Macros (Examples)]].
|
||||
</dl>
|
||||
<blockquote class="doc-example-result">
|
||||
<$reveal default="$egvar$" type="match" text="NO-SUCH-VAR">
|
||||
$eg$
|
||||
|
||||
$$$text/vnd.tiddlywiki
|
||||
$eg$
|
||||
$$$
|
||||
|
||||
</$reveal>
|
||||
<$reveal default="$egvar$" type="nomatch" text="NO-SUCH-VAR">
|
||||
<<$egvar$>>
|
||||
|
||||
@@ -17,14 +17,6 @@ It looks like this browser doesn't run JavaScript. You can use one of these stat
|
||||
|
||||
---
|
||||
|
||||
{{HelloThere}}
|
||||
|
||||
{{TiddlyWiki}}
|
||||
|
||||
{{Features}}
|
||||
|
||||
{{Community}}
|
||||
|
||||
{{HelpingTiddlyWiki}}
|
||||
|
||||
</$reveal>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
caption: $:/tags/Global
|
||||
created: 20230419103154329
|
||||
description: marks global definitions
|
||||
modified: 20230419103154329
|
||||
tags: SystemTags
|
||||
title: SystemTag: $:/tags/Global
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The [[system tag|SystemTags]] `$:/tags/Global` marks global definitions that are made available everywhere.
|
||||
@@ -0,0 +1,9 @@
|
||||
caption: $:/tags/Global/View
|
||||
created: 20230419103154329
|
||||
description: marks global definitions only active in View template
|
||||
modified: 20230419103154329
|
||||
tags: SystemTags
|
||||
title: SystemTag: $:/tags/Global/View
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The [[system tag|SystemTags]] `$:/tags/Global/View` marks definitions that are only made available within the main view templates and the preview panel.
|
||||
@@ -0,0 +1,9 @@
|
||||
caption: $:/tags/Global/View/Body
|
||||
created: 20230419103154329
|
||||
description: marks global definitions only active in View template body
|
||||
modified: 20230419103154329
|
||||
tags: SystemTags
|
||||
title: SystemTag: $:/tags/Global/View/Body
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The [[system tag|SystemTags]] `$:/tags/Global/View/Body` marks definitions that are only made available within the main view template bodies and the preview panel.
|
||||
@@ -6,4 +6,4 @@ tags: SystemTags
|
||||
title: SystemTag: $:/tags/Macro
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The [[system tag|SystemTags]] `$:/tags/Macro` marks global macros
|
||||
The [[system tag|SystemTags]] `$:/tags/Macro` marks global macros. It is now deprecated in favour of [[SystemTag $:/tags/Global]].
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user