1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-01-24 11:54:41 +00:00

Compare commits

..

3 Commits

Author SHA1 Message Date
jeremy@jermolene.com
374a0fe56d Add new example from @kookma 2023-04-23 13:14:46 +01:00
jeremy@jermolene.com
06758183d3 Improve splash screen macro for rendering icons 2023-04-23 12:21:11 +01:00
jeremy@jermolene.com
46d323c902 Parameterise all the icons 2023-04-23 10:27:55 +01:00
179 changed files with 565 additions and 2050 deletions

1
.gitignore vendored
View File

@@ -1,6 +1,5 @@
.DS_Store
.c9/
.vs/
.vscode/
tmp/
output/

View File

@@ -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.3.0
TW5_BUILD_VERSION=v5.2.8
fi
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"

View File

@@ -569,23 +569,10 @@ $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,sandbox,allowGlobals) {
$tw.utils.evalGlobal = function(code,context,filename) {
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 = [];
@@ -594,38 +581,25 @@ $tw.utils.evalGlobal = function(code,context,filename,sandbox,allowGlobals) {
contextValues.push(value);
});
// Add the code prologue and epilogue
code = [
"(function(" + contextNames.join(",") + ") {",
" (function(){\n" + code + "\n;})();",
(!$tw.browser && sandbox && !allowGlobals) ? globalCheck : "",
" return exports;\n",
"})"
].join("\n");
code = "(function(" + contextNames.join(",") + ") {(function(){\n" + code + "\n;})();\nreturn exports;\n})\n";
// Compile the code into a function
var fn;
if($tw.browser) {
fn = window["eval"](code + "\n\n//# sourceURL=" + filename);
} else {
if(sandbox){
fn = vm.runInContext(code,sandbox,filename)
} else {
fn = vm.runInThisContext(code,filename);
}
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,allowGlobals) {
return $tw.utils.evalGlobal(
code,context,filename,
allowGlobals ? vm.createContext({}) : $tw.utils.sandbox,
allowGlobals
);
$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;
};
/*
@@ -1946,7 +1920,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,rootPath) {
var processFile = function(filename,isTiddlerFile,fields,isEditableFile) {
var extInfo = $tw.config.fileExtensionInfo[path.extname(filename)],
type = (extInfo || {}).type || fields.type || "text/plain",
typeInfo = $tw.config.contentTypeInfo[type] || {},
@@ -1967,12 +1941,6 @@ $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;
@@ -2055,7 +2023,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,dirSpec.path);
processFile(thisPath,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile);
}
}
} else {
@@ -2080,11 +2048,7 @@ $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"),function() {return null;});
if(!pluginInfo) {
console.log("warning: invalid JSON in plugin.info file at " + infoPath);
pluginInfo = {};
}
var pluginInfo = $tw.utils.parseJSONSafe(fs.readFileSync(infoPath,"utf8"));
// Read the plugin files
var pluginFiles = $tw.loadTiddlersFromPath(filepath,excludeRegExp);
// Save the plugin tiddlers into the plugin info
@@ -2201,11 +2165,7 @@ $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"),function() {return null;});
if(!wikiInfo) {
console.log("warning: invalid JSON in tiddlywiki.info file at " + wikiInfoPath);
wikiInfo = {};
}
wikiInfo = $tw.utils.parseJSONSafe(fs.readFileSync(wikiInfoPath,"utf8"));
} else {
return null;
}
@@ -2448,7 +2408,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",[".mp3",".m2a",".mp2",".mpa",".mpg",".mpga"]);
$tw.utils.registerFileType("audio/mpeg","base64");
$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");

View File

@@ -3,7 +3,7 @@ title: $:/Acknowledgements
TiddlyWiki incorporates code from these fine OpenSource projects:
* [[The Stanford Javascript Crypto Library|http://bitwiseshiftleft.github.io/sjcl/]]
* [[The Jasmine JavaScript Test Framework|https://jasmine.github.io/]]
* [[The Jasmine JavaScript Test Framework|http://pivotal.github.io/jasmine/]]
* [[Normalize.css by Nicolas Gallagher|http://necolas.github.io/normalize.css/]]
And media from these projects:

View File

@@ -1,11 +0,0 @@
title: $:/core/images/network-activity
tags: $:/tags/Image
<svg width="22pt" height="22pt" class="tc-image-network-activity tc-image-button" viewBox="0 0 128 128"><g class={{{ [{$:/state/http-requests}match[0]then[]else[tc-network-activity-background]] }}}>
<$list filter="[{$:/state/http-requests}match[0]]" variable="ignore">
<path d="M64.043 45.153a4.002 4.002 0 0 1 4.367 2.21l.084.188 30.403 73.4a4 4 0 0 1-7.307 3.25l-.084-.188-3.103-7.49-8.898 8.899a3.985 3.985 0 0 1-2.624 1.166l-.205.005a3.987 3.987 0 0 1-2.828-1.171l-9.849-9.848-9.847 9.848a3.985 3.985 0 0 1-2.624 1.166l-.204.005a3.987 3.987 0 0 1-2.829-1.171l-8.899-8.9-3.102 7.491a4 4 0 1 1-7.391-3.062l30.403-73.4a4.001 4.001 0 0 1 4.495-2.39l.042-.008Zm13.636 56.74-8.023 8.024 7.02 7.019 8.023-8.022-7.02-7.02Zm-27.353.008-7.019 7.019 8.016 8.016 7.019-7.02-8.016-8.015Zm13.68-13.68-8.023 8.023 8.016 8.016 8.023-8.023-8.016-8.016Zm-8.971-8.971-4.687 11.315 8.001-8.001-3.314-3.314Zm17.933.009-3.305 3.305 7.979 7.979-4.674-11.284ZM64 57.607l-5.666 13.68c.096.072.188.15.278.232l.133.126 5.261 5.262 5.262-5.262c.128-.127.261-.244.4-.35L64 57.607Zm0-34.69a8 8 0 1 1 0 16 8 8 0 0 1 0-16Z"/>
</$list>
<$list filter="[{$:/state/http-requests}!match[0]]" variable="ignore">
<path d="M109.395.952a4.002 4.002 0 0 1 3.787 2.708C117.529 11.62 120 20.753 120 30.462c0 15.186-6.044 28.96-15.858 39.047a4 4 0 1 1-6.47-4.626l-.12-.094C106.466 56.074 112 43.914 112 30.462c0-8.492-2.205-16.469-6.074-23.39l.054-.036a4 4 0 0 1 3.415-6.084Zm-90.762 0a4 4 0 0 1 3.072 6.562l.093.06A47.786 47.786 0 0 0 16 30.463c0 13.315 5.42 25.363 14.176 34.058l-.01.007a4 4 0 1 1-6.312 4.863l-.063.05C14.017 59.359 8 45.613 8 30.462c0-9.77 2.502-18.956 6.9-26.952A4.002 4.002 0 0 1 18.634.952Z"/><path d="M64.043 44.698a4.002 4.002 0 0 1 4.367 2.21l.084.188 30.403 73.4a4 4 0 0 1-7.307 3.25l-.084-.188-3.103-7.49-8.898 8.9a3.985 3.985 0 0 1-2.624 1.166l-.205.005a3.987 3.987 0 0 1-2.828-1.172l-9.849-9.848-9.847 9.848a3.985 3.985 0 0 1-2.624 1.167l-.204.005a3.987 3.987 0 0 1-2.829-1.172l-8.899-8.899-3.102 7.49a4 4 0 0 1-7.391-3.061l30.403-73.4a4.001 4.001 0 0 1 4.495-2.39l.042-.009ZM77.68 101.44l-8.023 8.023 7.02 7.019 8.023-8.022-7.02-7.02Zm-27.353.007-7.019 7.019 8.016 8.016 7.019-7.019-8.016-8.016Zm13.68-13.68-8.023 8.023 8.016 8.016 8.023-8.023-8.016-8.016Zm-8.971-8.971L50.348 90.11l8.001-8.001-3.314-3.314Zm17.933.009-3.305 3.305 7.979 7.979-4.674-11.284ZM64 57.152l-5.666 13.68c.096.073.188.15.278.232l.133.127 5.261 5.261 5.262-5.261c.128-.128.261-.244.4-.351L64 57.152ZM38.503 1.058a4 4 0 0 1 2.7 6.952l.17-.175C35.582 13.625 32 21.625 32 30.462c0 8.838 3.582 16.838 9.374 22.629a4 4 0 0 1-5.659 5.658l-.01.01C28.473 51.52 24 41.526 24 30.485 24 19.567 28.374 9.67 35.466 2.453a3.995 3.995 0 0 1 3.037-1.395ZM89.369.952c1.14 0 2.17.478 2.899 1.244l.005-.006C99.518 9.43 104 19.434 104 30.485c0 10.826-4.3 20.648-11.287 27.85a4 4 0 1 1-6.054-5.213l-.032-.032C92.418 47.299 96 39.299 96 30.462c0-8.73-3.496-16.643-9.164-22.416A4 4 0 0 1 89.368.952Zm-39.282 11.14a4 4 0 0 1 2.59 7.048l.01.009A15.95 15.95 0 0 0 48 30.462a15.95 15.95 0 0 0 4.687 11.315l-.01.01a4 4 0 1 1-5.82 5.47l.173.177A23.925 23.925 0 0 1 40 30.462a23.925 23.925 0 0 1 7.03-16.97l.01.01a3.991 3.991 0 0 1 3.047-1.41Zm27.895.07a3.99 3.99 0 0 1 2.984 1.336l.006-.005A23.925 23.925 0 0 1 88 30.463a23.92 23.92 0 0 1-6.707 16.642l-.3.305a4 4 0 1 1-5.679-5.632v-.002A15.95 15.95 0 0 0 80 30.462a15.95 15.95 0 0 0-4.685-11.312 4.012 4.012 0 0 1-1.333-2.987 4 4 0 0 1 4-4ZM64 22.463a8 8 0 1 1 0 16 8 8 0 0 1 0-16Z"/>
</$list>
</g></svg>

View File

@@ -67,8 +67,6 @@ More/Caption: more
More/Hint: More actions
NewHere/Caption: new here
NewHere/Hint: Create a new tiddler tagged with this one
NetworkActivity/Caption: network activity
NetworkActivity/Hint: Cancel all network activity
NewJournal/Caption: new journal
NewJournal/Hint: Create a new journal tiddler
NewJournalHere/Caption: new journal here

View File

@@ -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 request header to be used for trusted authentication.
* ''authenticated-user-header'' - optional name of 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")

View File

@@ -25,8 +25,6 @@ Encryption/RepeatPassword: Repeat password
Encryption/PasswordNoMatch: Passwords do not match
Encryption/SetPassword: Set password
Error/Caption: Error
Error/DeserializeOperator/MissingOperand: Filter Error: Missing operand for 'deserialize' operator
Error/DeserializeOperator/UnknownDeserializer: Filter Error: Unknown deserializer provided as operand for the 'deserialize' operator
Error/Filter: Filter error
Error/FilterSyntax: Syntax error in filter expression
Error/FilterRunPrefix: Filter Error: Unknown prefix for filter run

View File

@@ -1,3 +1,3 @@
title: $:/SiteTitle
My TiddlyWiki
My ~TiddlyWiki

View File

@@ -118,8 +118,6 @@ 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");
};
/*

View File

@@ -12,8 +12,6 @@ Adds tiddler filtering methods to the $tw.Wiki object.
/*global $tw: false */
"use strict";
var widgetClass = require("$:/core/modules/widgets/widget.js").widget;
/* Maximum permitted filter recursion depth */
var MAX_FILTER_DEPTH = 300;
@@ -271,7 +269,7 @@ exports.compileFilter = function(filterString) {
operand.value = self.getTextReference(operand.text,"",currTiddlerTitle);
} else if(operand.variable) {
var varTree = $tw.utils.parseFilterVariable(operand.text);
operand.value = widgetClass.evaluateVariable(widget,varTree.name,{params: varTree.params, source: source})[0] || "";
operand.value = widget.evaluateVariable(varTree.name,{params: varTree.params, source: source})[0] || "";
} else {
operand.value = operand.text;
}

View File

@@ -1,39 +0,0 @@
/*\
title: $:/core/modules/filters/deserialize.js
type: application/javascript
module-type: filteroperator
Filter operator for deserializing string data into JSON representing tiddlers
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports["deserialize"] = function(source,operator,options) {
var results = [],
deserializer;
if(operator.operand) {
// Get the deserializer identified by the operand
deserializer = $tw.Wiki.tiddlerDeserializerModules[operator.operand];
if(deserializer) {
source(function(tiddler,title) {
var tiddlers;
try {
tiddlers = deserializer(title);
} catch(e) {
// Return an empty array if we could not extract any tiddlers
tiddlers = [];
}
results.push(JSON.stringify(tiddlers));
});
} else {
return [$tw.language.getString("Error/DeserializeOperator/UnknownDeserializer")];
}
} else {
return [$tw.language.getString("Error/DeserializeOperator/MissingOperand")];
}
return results;
}
})();

View File

@@ -1,25 +0,0 @@
/*\
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;
};
})();

View File

@@ -17,13 +17,9 @@ Export our filter function
*/
exports.function = function(source,operator,options) {
var functionName = operator.operands[0],
params = [];
$tw.utils.each(operator.operands.slice(1),function(param) {
params.push({value: param});
});
var variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(functionName,{params: params, source: source});
variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(functionName);
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
return variableInfo.resultList ? variableInfo.resultList : [variableInfo.text];
return options.widget.evaluateVariable(functionName,{params: operator.operands.slice(1), source: source});
}
// Return the input list if the function wasn't found
var results = [];

View File

@@ -21,14 +21,10 @@ Export our filter function
*/
exports["[unknown]"] = function(source,operator,options) {
// Check for a user defined filter operator
if(operator.operator.indexOf(".") !== -1) {
var params = [];
$tw.utils.each(operator.operands,function(param) {
params.push({value: param});
});
var variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(operator.operator,{params: params, source: source});
if(variableInfo && variableInfo.srcVariable) {
var list = variableInfo.resultList ? variableInfo.resultList : [variableInfo.text];
if(operator.operator.charAt(0) === ".") {
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});
if(operator.prefix === "!") {
var results = [];
source(function(tiddler,title) {

View File

@@ -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);

View File

@@ -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;
};
/*

View File

@@ -1,40 +0,0 @@
/*\
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)}];
};
})();

View File

@@ -37,7 +37,7 @@ HeaderAuthenticator.prototype.authenticateRequest = function(request,response,st
return false;
} else {
// authenticatedUsername will be undefined for anonymous users
state.authenticatedUsername = $tw.utils.decodeURIComponentSafe(username);
state.authenticatedUsername = username;
return true;
}
};

View File

@@ -20,38 +20,6 @@ exports.before = ["story"];
exports.synchronous = true;
exports.startup = function() {
// Install the HTTP client event handler
$tw.httpClient = new $tw.utils.HttpClient();
var getPropertiesWithPrefix = function(properties,prefix) {
var result = Object.create(null);
$tw.utils.each(properties,function(value,name) {
if(name.indexOf(prefix) === 0) {
result[name.substring(prefix.length)] = properties[name];
}
});
return result;
};
$tw.rootWidget.addEventListener("tm-http-request",function(event) {
var params = event.paramObject || {};
$tw.httpClient.initiateHttpRequest({
wiki: event.widget.wiki,
url: params.url,
method: params.method,
body: params.body,
oncompletion: params.oncompletion,
onprogress: params.onprogress,
bindStatus: params["bind-status"],
bindProgress: params["bind-progress"],
variables: getPropertiesWithPrefix(params,"var-"),
headers: getPropertiesWithPrefix(params,"header-"),
passwordHeaders: getPropertiesWithPrefix(params,"password-header-"),
queryStrings: getPropertiesWithPrefix(params,"query-"),
passwordQueryStrings: getPropertiesWithPrefix(params,"password-query-")
});
});
$tw.rootWidget.addEventListener("tm-http-cancel-all-requests",function(event) {
$tw.httpClient.cancelAllHttpRequests();
});
// Install the modal message mechanism
$tw.modal = new $tw.utils.Modal($tw.wiki);
$tw.rootWidget.addEventListener("tm-modal",function(event) {
@@ -73,8 +41,12 @@ exports.startup = function() {
$tw.rootWidget.addEventListener("tm-focus-selector",function(event) {
var selector = event.param || "",
element,
baseElement = event.event && event.event.target ? event.event.target.ownerDocument : document;
element = $tw.utils.querySelectorSafe(selector,baseElement);
doc = event.event && event.event.target ? event.event.target.ownerDocument : document;
try {
element = doc.querySelector(selector);
} catch(e) {
console.log("Error in selector: ",selector)
}
if(element && element.focus) {
element.focus(event.paramObject);
}

View File

@@ -129,7 +129,7 @@ function findTitleDomNode(widget,targetClass) {
targetClass = targetClass || "tc-title";
var domNode = widget.findFirstDomNode();
if(domNode && domNode.querySelector) {
return $tw.utils.querySelectorSafe("." + targetClass,domNode);
return domNode.querySelector("." + targetClass);
}
return null;
}

View File

@@ -365,25 +365,5 @@ 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);
}
};
})();

View File

@@ -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,36 +173,6 @@ 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);
@@ -235,13 +205,7 @@ var importDataTypes = [
return [{title: fallbackTitle, text: data}];
}},
{type: "text/uri-list", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
// 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
}
return [{title: fallbackTitle, text: data}];
}}
];

View File

@@ -3,7 +3,7 @@ title: $:/core/modules/utils/dom/http.js
type: application/javascript
module-type: utils
HTTP support
Browser HTTP support
\*/
(function(){
@@ -13,204 +13,11 @@ HTTP support
"use strict";
/*
Manage tm-http-request events. Options include:
wiki: Reference to the wiki to be used for state tiddler tracking
stateTrackerTitle: Title of tiddler to be used for state tiddler tracking
*/
function HttpClient(options) {
options = options || {};
this.nextId = 1;
this.wiki = options.wiki || $tw.wiki;
this.stateTrackerTitle = options.stateTrackerTitle || "$:/state/http-requests";
this.requests = []; // Array of {id: string,request: HttpClientRequest}
this.updateRequestTracker();
}
/*
Return the index into this.requests[] corresponding to a given ID. Returns null if not found
*/
HttpClient.prototype.getRequestIndex = function(targetId) {
var targetIndex = null;
$tw.utils.each(this.requests,function(requestInfo,index) {
if(requestInfo.id === targetId) {
targetIndex = index;
}
});
return targetIndex;
};
/*
Update the state tiddler that is tracking the outstanding requests
*/
HttpClient.prototype.updateRequestTracker = function() {
this.wiki.addTiddler({title: this.stateTrackerTitle, text: "" + this.requests.length});
};
HttpClient.prototype.initiateHttpRequest = function(options) {
var self = this,
id = this.nextId,
request = new HttpClientRequest(options);
this.nextId += 1;
this.requests.push({id: id, request: request});
this.updateRequestTracker();
request.send(function(err) {
var targetIndex = self.getRequestIndex(id);
if(targetIndex !== null) {
self.requests.splice(targetIndex,1);
self.updateRequestTracker();
}
});
return id;
};
HttpClient.prototype.cancelAllHttpRequests = function() {
var self = this;
if(this.requests.length > 0) {
for(var t=this.requests.length - 1; t--; t>=0) {
var requestInfo = this.requests[t];
requestInfo.request.cancel();
}
}
this.requests = [];
this.updateRequestTracker();
};
HttpClient.prototype.cancelHttpRequest = function(targetId) {
var targetIndex = this.getRequestIndex(targetId);
if(targetIndex !== null) {
this.requests[targetIndex].request.cancel();
this.requests.splice(targetIndex,1);
this.updateRequestTracker();
}
};
/*
Initiate an HTTP request. Options:
wiki: wiki to be used for executing action strings
url: URL for request
method: method eg GET, POST
body: text of request body
oncompletion: action string to be invoked on completion
onprogress: action string to be invoked on progress updates
bindStatus: optional title of tiddler to which status ("pending", "complete", "error") should be written
bindProgress: optional title of tiddler to which the progress of the request (0 to 100) should be bound
variables: hashmap of variable name to string value passed to action strings
headers: hashmap of header name to header value to be sent with the request
passwordHeaders: hashmap of header name to password store name to be sent with the request
queryStrings: hashmap of query string parameter name to parameter value to be sent with the request
passwordQueryStrings: hashmap of query string parameter name to password store name to be sent with the request
*/
function HttpClientRequest(options) {
var self = this;
console.log("Initiating an HTTP request",options)
this.wiki = options.wiki;
this.completionActions = options.oncompletion;
this.progressActions = options.onprogress;
this.bindStatus = options["bind-status"];
this.bindProgress = options["bind-progress"];
this.method = options.method || "GET";
this.body = options.body || "";
this.variables = options.variables;
var url = options.url;
$tw.utils.each(options.queryStrings,function(value,name) {
url = $tw.utils.setQueryStringParameter(url,name,value);
});
$tw.utils.each(options.passwordQueryStrings,function(value,name) {
url = $tw.utils.setQueryStringParameter(url,name,$tw.utils.getPassword(value) || "");
});
this.url = url;
this.requestHeaders = {};
$tw.utils.each(options.headers,function(value,name) {
self.requestHeaders[name] = value;
});
$tw.utils.each(options.passwordHeaders,function(value,name) {
self.requestHeaders[name] = $tw.utils.getPassword(value) || "";
});
}
HttpClientRequest.prototype.send = function(callback) {
var self = this,
setBinding = function(title,text) {
if(title) {
this.wiki.addTiddler(new $tw.Tiddler({title: title, text: text}));
}
};
if(this.url) {
setBinding(this.bindStatus,"pending");
setBinding(this.bindProgress,"0");
// Set the request tracker tiddler
var requestTrackerTitle = this.wiki.generateNewTitle("$:/temp/HttpRequest");
this.wiki.addTiddler({
title: requestTrackerTitle,
tags: "$:/tags/HttpRequest",
text: JSON.stringify({
url: this.url,
type: this.method,
status: "inprogress",
headers: this.requestHeaders,
data: this.body
})
});
this.xhr = $tw.utils.httpRequest({
url: this.url,
type: this.method,
headers: this.requestHeaders,
data: this.body,
callback: function(err,data,xhr) {
var hasSucceeded = xhr.status >= 200 && xhr.status < 300,
completionCode = hasSucceeded ? "complete" : "error",
headers = {};
$tw.utils.each(xhr.getAllResponseHeaders().split("\r\n"),function(line) {
var pos = line.indexOf(":");
if(pos !== -1) {
headers[line.substr(0,pos)] = line.substr(pos + 1).trim();
}
});
setBinding(self.bindStatus,completionCode);
setBinding(self.bindProgress,"100");
var resultVariables = {
status: xhr.status.toString(),
statusText: xhr.statusText,
error: (err || "").toString(),
data: (data || "").toString(),
headers: JSON.stringify(headers)
};
self.wiki.addTiddler(new $tw.Tiddler(self.wiki.getTiddler(requestTrackerTitle),{
status: completionCode,
}));
self.wiki.invokeActionString(self.completionActions,undefined,$tw.utils.extend({},self.variables,resultVariables),{parentWidget: $tw.rootWidget});
callback(hasSucceeded ? null : xhr.statusText);
// console.log("Back!",err,data,xhr);
},
progress: function(lengthComputable,loaded,total) {
if(lengthComputable) {
setBinding(self.bindProgress,"" + Math.floor((loaded/total) * 100))
}
self.wiki.invokeActionString(self.progressActions,undefined,{
lengthComputable: lengthComputable ? "yes" : "no",
loaded: loaded,
total: total
},{parentWidget: $tw.rootWidget});
}
});
}
};
HttpClientRequest.prototype.cancel = function() {
if(this.xhr) {
this.xhr.abort();
}
};
exports.HttpClient = HttpClient;
/*
Make an HTTP request. Options are:
A quick and dirty HTTP function; to be refactored later. Options are:
url: URL to retrieve
headers: hashmap of headers to send
type: GET, PUT, POST etc
callback: function invoked with (err,data,xhr)
progress: optional function invoked with (lengthComputable,loaded,total)
returnProp: string name of the property to return as first argument of callback
*/
exports.httpRequest = function(options) {
@@ -276,16 +83,8 @@ exports.httpRequest = function(options) {
options.callback($tw.language.getString("Error/XMLHttpRequest") + ": " + this.status,null,this);
}
};
// Handle progress
if(options.progress) {
request.onprogress = function(event) {
console.log("Progress event",event)
options.progress(event.lengthComputable,event.loaded,event.total);
};
}
// Make the request
request.open(type,url,true);
// Headers
if(headers) {
$tw.utils.each(headers,function(header,headerTitle,object) {
request.setRequestHeader(headerTitle,header);
@@ -297,7 +96,6 @@ exports.httpRequest = function(options) {
if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers)) {
request.setRequestHeader("X-Requested-With","TiddlyWiki");
}
// Send data
try {
request.send(data);
} catch(e) {
@@ -306,19 +104,4 @@ exports.httpRequest = function(options) {
return request;
};
exports.setQueryStringParameter = function(url,paramName,paramValue) {
var URL = $tw.browser ? window.URL : require("url").URL,
newUrl;
try {
newUrl = new URL(url);
} catch(e) {
}
if(newUrl && paramName) {
newUrl.searchParams.set(paramName,paramValue || "");
return newUrl.toString();
} else {
return url;
}
};
})();

View File

@@ -127,8 +127,8 @@ PageScroller.prototype.scrollIntoView = function(element,callback,options) {
};
PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {
baseElement = baseElement || document;
var element = $tw.utils.querySelectorSafe(selector,baseElement);
baseElement = baseElement || document.body;
var element = baseElement.querySelector(selector);
if(element) {
this.scrollIntoView(element,callback,options);
}

View File

@@ -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,20 +208,16 @@ 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 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;
listContents = $tw.utils.parseStringArray(fieldContents) || [];
// No need to copy since parseStringArray returns a fresh array, not refrenced elsewhere
}
oldPos = notValue ? listContents.indexOf(notValue) : -1;
newPos = value ? listContents.indexOf(value) : -1;

View File

@@ -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":

View File

@@ -271,20 +271,6 @@ 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;

View File

@@ -92,9 +92,12 @@ 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(event);
// 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
});
}
return false;
};

View File

@@ -51,8 +51,7 @@ MacroCallWidget.prototype.execute = function() {
var positionalName = 0,
parseTreeNodes = [{
type: "transclude",
isBlock: this.parseTreeNode.isBlock,
children: this.parseTreeNode.children
isBlock: this.parseTreeNode.isBlock
}];
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$variable",this.macroName);
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$type",this.parseType);

View File

@@ -119,8 +119,8 @@ ScrollableWidget.prototype.scrollIntoView = function(element,callback,options) {
};
ScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {
baseElement = baseElement || document;
var element = $tw.utils.querySelectorSafe(selector,baseElement);
baseElement = baseElement || document.body;
var element = baseElement.querySelector(selector);
if(element) {
this.scrollIntoView(element,callback,options);
}

View File

@@ -48,7 +48,7 @@ SlotWidget.prototype.execute = function() {
var pointer = this.parentWidget,
depth = this.slotDepth;
while(pointer) {
if(pointer instanceof TranscludeWidget && pointer.hasVisibleSlots()) {
if(pointer instanceof TranscludeWidget) {
depth--;
if(depth <= 0) {
break;

View File

@@ -45,7 +45,7 @@ TranscludeWidget.prototype.execute = function() {
var target = this.getTransclusionTarget(),
parseTreeNodes = target.parseTreeNodes;
this.sourceText = target.text;
this.parserType = target.type;
this.sourceType = 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.parserType,this.sourceText,{parentWidget: this});
var plainText = this.wiki.renderText("text/plain",this.sourceType,this.sourceText,{parentWidget: this});
parseTreeNodes = [{type: "text", text: plainText}];
break;
}
@@ -171,88 +171,101 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
}
var parser;
// Get the parse tree
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 result = (variableInfo.resultList ? variableInfo.resultList[0] : variableInfo.text) || "";
parser = {
tree: [{
type: "text",
text: result
}],
source: result,
type: "text/vnd.tiddlywiki"
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
};
if(parseAsInline) {
parser.tree[0] = {
} else {
parser.tree[0] = {
type: "element",
tag: "p",
children: [{
type: "text",
text: result
};
} else {
parser.tree[0] = {
type: "element",
tag: "p",
children: [{
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;
}
$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)
});
}
}
}
} else {
// Transcluding a text reference
@@ -266,8 +279,6 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
defaultType: this.transcludeType
});
}
// Set 'thisTiddler'
this.setVariable("thisTiddler",this.transcludeTitle);
// Return the parse tree
if(parser) {
return {
@@ -369,13 +380,6 @@ 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
*/

View File

@@ -112,18 +112,14 @@ Get the prevailing value of a context variable
name: name of variable
options: see below
Options include
params: array of {name:, value:} for each parameter
defaultValue: default value if the variable is not defined
source: optional source iterator for evaluating function invocations
allowSelfAssigned: if true, includes the current widget in the context chain instead of just the parent
Returns an object with the following fields:
params: array of {name:,value:} or {value:} of parameters to be applied
params: array of {name:,value:} of parameters passed to wikitext variables
text: text of variable, with parameters properly substituted
resultList: result of variable evaluation as an array
srcVariable: reference to the object defining the variable
*/
Widget.prototype.getVariableInfo = function(name,options) {
options = options || {};
@@ -139,8 +135,7 @@ Widget.prototype.getVariableInfo = function(name,options) {
if(variable) {
var originalValue = variable.value,
value = originalValue,
params = [],
resultList = [value];
params = [];
// Only substitute parameter and variable references if this variable was defined with the \define pragma
if(variable.isMacroDefinition) {
params = self.resolveVariableParameters(variable.params,actualParams);
@@ -149,28 +144,10 @@ Widget.prototype.getVariableInfo = function(name,options) {
value = $tw.utils.replaceString(value,new RegExp("\\$" + $tw.utils.escapeRegExp(param.name) + "\\$","mg"),param.value);
});
value = self.substituteVariableReferences(value,options);
resultList = [value];
} else if(variable.isFunctionDefinition) {
// Function evaluations
params = self.resolveVariableParameters(variable.params,actualParams);
var variables = Object.create(null);
// Apply default parameter values
$tw.utils.each(variable.params,function(param,index) {
if(param["default"]) {
variables[param.name] = param["default"];
}
});
// Parameters are an array of {value:} or {name:, value:} pairs
$tw.utils.each(params,function(param) {
variables[param.name] = param.value;
});
resultList = this.wiki.filterTiddlers(value,this.makeFakeWidgetWithVariables(variables),options.source);
value = resultList[0] || "";
}
return {
text: value,
params: params,
resultList: resultList,
srcVariable: variable,
isCacheable: originalValue === value
};
@@ -182,7 +159,6 @@ Widget.prototype.getVariableInfo = function(name,options) {
}
return {
text: text,
resultList: [text],
srcVariable: {}
};
};
@@ -341,11 +317,62 @@ Widget.prototype.makeFakeWidgetWithVariables = function(variables) {
};
},
makeFakeWidgetWithVariables: self.makeFakeWidgetWithVariables,
evaluateVariable: self.evaluateVariable,
resolveVariableParameters: self.resolveVariableParameters,
wiki: self.wiki
};
};
/*
Evaluate a variable and associated actual parameters and result 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
* Procedures and widgets are returned as plain text
Options are:
params - the actual parameters may be one of:
* an array of values that may be an anonymous string value, or a {name:, value:} pair
* a hashmap of {name: value} pairs
* a function invoked with parameters (name,index) that returns a parameter value by name or position
source - iterator for source tiddlers
*/
Widget.prototype.evaluateVariable = function(name,options) {
options = options || {};
var params = options.params || [];
// Get the details of the variable (includes processing text substitution for macros
var variableInfo = this.getVariableInfo(name,{params: params,defaultValue: ""});
// Process function parameters
var variables = Object.create(null);
if(variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
// Apply default parameter values
$tw.utils.each(variableInfo.srcVariable.params,function(param,index) {
if(param["default"]) {
variables[param.name] = param["default"];
}
});
if($tw.utils.isArray(params)) {
// Parameters are an array of values or {name:, value:} pairs
$tw.utils.each(this.resolveVariableParameters(variableInfo.srcVariable.params,params),function(param) {
variables[param.name] = param.value;
});
} else if(typeof params === "function") {
// Parameters are passed via a function
$tw.utils.each(variableInfo.srcVariable.params,function(param,index) {
variables[param.name] = params(param.name,index) || param["default"] || "";
});
} else {
// Parameters are a hashmap
$tw.utils.each(params,function(value,name) {
variables[name] = value;
});
}
return this.wiki.filterTiddlers(variableInfo.text,this.makeFakeWidgetWithVariables(variables),options.source);
} else {
return [variableInfo.text];
}
};
/*
Compute the current values of the attributes of the widget. Returns a hashmap of the names of the attributes that have changed.
Options include:
@@ -376,10 +403,16 @@ 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});
value = variableInfo.text;
if(variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
// It is a function definition. Go through each of the defined parameters, and make a variable with the value of the corresponding provided parameter
var paramArray = this.resolveVariableParameters(variableInfo.srcVariable.params,attribute.value.params);
value = this.evaluateVariable(attribute.value.name,{params: paramArray})[0] || "";
} else {
value = variableInfo.text;
}
} else { // String attribute
value = attribute.value;
}
@@ -513,8 +546,8 @@ Widget.prototype.makeChildWidget = function(parseTreeNode,options) {
var variableDefinitionName = "$" + parseTreeNode.type;
if(this.variables[variableDefinitionName]) {
var isOverrideable = function() {
// 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);
// 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);
};
if(!parseTreeNode.isNotRemappable && isOverrideable()) {
var variableInfo = this.getVariableInfo(variableDefinitionName,{allowSelfAssigned: true});
@@ -796,20 +829,6 @@ Widget.prototype.allowActionPropagation = function() {
return true;
};
/*
Evaluate a variable with parameters. This is a static convenience method that attempts to evaluate a variable as a function, returning an array of strings
*/
Widget.evaluateVariable = function(widget,name,options) {
var result;
if(widget.getVariableInfo) {
var variableInfo = widget.getVariableInfo(name,options);
result = variableInfo.resultList || [variableInfo.text];
} else {
result = [widget.getVariable(name)];
}
return result;
};
exports.widget = Widget;
})();

View File

@@ -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 = this.getTiddlerText("$:/core/config/GlobalImportFilter");
parseTreeImportVariables.attributes.filter.value = "[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]";
}
parseTreeDiv.tree[0].children.push(parseTreeImportVariables);
parseTreeImportVariables.children.push(parseTreeTransclude);
@@ -1415,14 +1415,6 @@ exports.checkTiddlerText = function(title,targetText,options) {
return text === targetText;
}
/*
Execute an action string without an associated context widget
*/
exports.invokeActionString = function(actions,event,variables,options) {
var widget = this.makeWidget(null,{parentWidget: options.parentWidget});
widget.invokeActionString(actions,null,event,variables);
};
/*
Read an array of browser File objects, invoking callback(tiddlerFieldsArray) once they're all read
*/

View File

@@ -54,7 +54,6 @@ modal-footer-background: #f5f5f5
modal-footer-border: #dddddd
modal-header-border: #eeeeee
muted-foreground: #bbb
network-activity-foreground: #448844
notification-background: #ffffdd
notification-border: #999999
page-background: #f4f4f4

View File

@@ -3,5 +3,5 @@ title: $:/core/templates/exporters/StaticRiver/Content
\define renderContent()
{{{ $(exportFilter)$ ||$:/core/templates/static-tiddler}}}
\end
\import [subfilter{$:/core/config/GlobalImportFilter}]
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
<<renderContent>>

View File

@@ -7,5 +7,5 @@ condition: [<count>compare:lte[1]]
\define renderContent()
{{{ $(exportFilter)$ +[limit[1]] ||$:/core/templates/tid-tiddler}}}
\end
\import [subfilter{$:/core/config/GlobalImportFilter}]
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
<<renderContent>>

View File

@@ -1,14 +1,11 @@
title: $:/core/save/all-external-js
\whitespace trim
\import [subfilter{$:/core/config/GlobalImportFilter}]
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
\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>

View File

@@ -1,7 +1,7 @@
title: $:/core/save/offline-external-js
\whitespace trim
\import [subfilter{$:/core/config/GlobalImportFilter}]
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
\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

View File

@@ -1,6 +1,6 @@
title: $:/core/save/all
\import [subfilter{$:/core/config/GlobalImportFilter}]
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
\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

View File

@@ -2,7 +2,7 @@ title: $:/core/templates/server/static.tiddler.html
\whitespace trim
\define tv-wikilink-template() $uri_encoded$
\import [subfilter{$:/core/config/GlobalImportFilter}]
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

View File

@@ -4,7 +4,7 @@ title: $:/core/templates/single.tiddler.window
\define containerClasses()
tc-page-container tc-page-view-$(storyviewTitle)$ tc-language-$(languageTitle)$
\end
\import [subfilter{$:/core/config/GlobalImportFilter}]
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
<$vars
tv-config-toolbar-icons={{$:/config/Toolbar/Icons}}

View File

@@ -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 [subfilter{$:/core/config/GlobalImportFilter}]
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
`<!doctype html>
<html>
<head>

View File

@@ -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>> $$fillignore="yes">
<$genesis $type="$transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" recursionMarker="no" mode=<<mode>>>
<!-- Reach back up to the grandparent transclusion to get the correct slot value -->
<$slot $name="ts-raw"/>
<$slot $name="ts-raw" $depth="2"/>
</$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>> $$fillignore="yes">
<$genesis $type="$transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" $$recursionMarker="no" $$mode=<<mode>>>
<!-- Reach back up to the grandparent transclusion to get the correct slot fill value -->
<$slot $name="ts-raw"/>
<$slot $name="ts-raw" $depth="2"/>
</$genesis>
</$list>
</$genesis>

View File

@@ -211,7 +211,7 @@ $:/state/add-plugin-info/$(connectionTiddler)$/$(assetInfo)$
</div>
\end
\import [subfilter{$:/core/config/GlobalImportFilter}]
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
\whitespace trim
<div>

View File

@@ -2,6 +2,18 @@ title: $:/core/ui/ControlPanel/Settings
tags: $:/tags/ControlPanel
caption: {{$:/language/ControlPanel/Settings/Caption}}
<div class="tc-control-panel">
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/SettingsTab]!has[draft.of]]" default="$:/core/ui/ControlPanel/Settings/TiddlyWiki" explicitState="$:/state/tab--697582678"/>
</div>
\define lingo-base() $:/language/ControlPanel/Settings/
<<lingo Hint>>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Settings]]">
<div style="border-top:1px solid #eee;">
!! <$link><$transclude field="caption"/></$link>
<$transclude/>
</div>
</$list>

View File

@@ -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]!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]]
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]] [all[shadows+tiddlers]tag[$:/tags/Macro/View/Body]!has[draft.of]]
<$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]] }}} />

View File

@@ -14,8 +14,8 @@ color:$(foregroundColor)$;
\define tag-body-inner(colour,fallbackTarget,colourA,colourB,icon,tagField:"tags")
\whitespace trim
<$vars foregroundColor=<<contrastcolour target:"""$colour$""" fallbackTarget:"""$fallbackTarget$""" colourA:"""$colourA$""" colourB:"""$colourB$""">> backgroundColor="""$colour$""">
<span style=<<tag-styles>> class="tc-tag-label tc-tag-list-item tc-small-gap-right" data-tag-title=<<currentTiddler>>>
<$transclude tiddler="""$icon$"""/><$view field="title" format="text"/>
<span style=<<tag-styles>> class="tc-tag-label tc-tag-list-item tc-small-gap-right">
<$transclude tiddler="""$icon$"""/><$view field="title" format="text" />
<$button class="tc-btn-invisible tc-remove-tag-button" style=<<tag-styles>>><$action-listops $tiddler=<<saveTiddler>> $field=<<__tagField__>> $subfilter="-[{!!title}]"/>{{$:/core/images/close-button}}</$button>
</span>
</$vars>

View File

@@ -1,16 +0,0 @@
title: $:/core/ui/Buttons/network-activity
tags: $:/tags/PageControls
caption: {{$:/core/images/network-activity}} {{$:/language/Buttons/NetworkActivity/Caption}}
description: {{$:/language/Buttons/NetworkActivity/Hint}}
\whitespace trim
<$button message="tm-http-cancel-all-requests" tooltip={{$:/language/Buttons/NetworkActivity/Hint}} aria-label={{$:/language/Buttons/NetworkActivity/Caption}} class=<<tv-config-toolbar-class>>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{$:/core/images/network-activity}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text">
<$text text={{$:/language/Buttons/NetworkActivity/Caption}}/>
</span>
</$list>
</$button>

View File

@@ -1,6 +1,6 @@
title: $:/core/ui/PageStylesheet
\import [subfilter{$:/core/config/GlobalImportFilter}]
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
\whitespace trim
<$set name="currentTiddler" value={{$:/language}}>

View File

@@ -4,7 +4,7 @@ description: {{$:/language/PageTemplate/Description}}
icon: $:/core/images/layout-button
\whitespace trim
\import [subfilter{$:/core/config/GlobalImportFilter}]
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
<$vars
tv-config-toolbar-icons={{$:/config/Toolbar/Icons}}

View File

@@ -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/>"/>
<$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>"/>
</div>
</$list>
<$tiddler tiddler="">

View File

@@ -1,3 +1,3 @@
title: $:/core/ui/StoryTiddlerTemplate
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/StoryTiddlerTemplateFilter]!is[draft]get[text]] :and[has[title]else[$:/core/ui/ViewTemplate]] }}} />
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/StoryTiddlerTemplateFilter]!is[draft]get[text]] :and[!is[blank]else{$:/config/ui/ViewTemplate}] }}} />

View File

@@ -15,7 +15,7 @@ title: $:/core/ui/TagPickerTagTemplate
<<actions>>
<$set name="backgroundColor" value={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}>
<$wikify name="foregroundColor" text="""<$macrocall $name="contrastcolour" target=<<backgroundColor>> fallbackTarget=<<fallbackTarget>> colourA=<<colourA>> colourB=<<colourB>>/>""">
<span class="tc-tag-label tc-btn-invisible" style=<<tag-pill-styles>> data-tag-title=<<currentTiddler>> >
<span class="tc-tag-label tc-btn-invisible" style=<<tag-pill-styles>>>
{{||$:/core/ui/TiddlerIcon}}<$view field="title" format="text"/>
</span>
</$wikify>

View File

@@ -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]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global/View]!is[draft]]
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]]
<$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]!is[draft]]" variable="listItem">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem">
<$transclude tiddler=<<listItem>>/>
</$list>
</div>

View File

@@ -1,7 +1,7 @@
title: $:/core/ui/ViewTemplate/body
tags: $:/tags/ViewTemplate
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View/Body]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global/View/Body]!is[draft]]
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View/Body]!has[draft.of]]
<$reveal tag="div" class="tc-tiddler-body" type="nomatch" stateTitle=<<folded-state>> text="hide" retain="yes" animate="yes">

View File

@@ -1,2 +0,0 @@
title: $:/core/config/GlobalImportFilter
text: [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global]!is[draft]]

View File

@@ -13,7 +13,6 @@ core/ui/Buttons/language: hide
core/ui/Buttons/tag-manager: hide
core/ui/Buttons/manager: hide
core/ui/Buttons/more-page-actions: hide
core/ui/Buttons/network-activity: hide
core/ui/Buttons/new-journal: hide
core/ui/Buttons/new-image: hide
core/ui/Buttons/palette: hide

View File

@@ -1,3 +1,3 @@
title: $:/config/WikiParserRules/Inline/wikilink
disable
enable

View File

@@ -3,26 +3,14 @@ tags: $:/tags/Macro
\define translink(title,mode:"block")
\whitespace trim
<$list filter="[<__mode__>match[block]]">
<div class="tc-translink">
<div>
<$link to="""$title$""">
<h1><$text text="""$title$"""/></h1>
</$link>
<$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">
<div style="border:1px solid #ccc; padding: 0.5em; background: black; foreground; white;">
<$link to="""$title$""">
<$text text="""$title$"""/>
</$link>
&#32;(<$transclude tiddler="""$title$""" mode="inline">
<$set name="currentTiddler" value="""$title$"""><$transclude tiddler="$:/language/MissingTiddler/Hint"/></$set>
</$transclude>)
</span>
</$list>
<div style="border:1px solid #ccc; padding: 0.5em; background: white; foreground; black;">
<$transclude tiddler="""$title$""" mode="$mode$">
"<$text text="""$title$"""/>" is missing
</$transclude>
</div>
</div>
\end

View File

@@ -1,2 +1,2 @@
title: $:/tags/PageControls
list: [[$:/core/ui/Buttons/home]] [[$:/core/ui/Buttons/close-all]] [[$:/core/ui/Buttons/fold-all]] [[$:/core/ui/Buttons/unfold-all]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/new-tiddler]] [[$:/core/ui/Buttons/new-journal]] [[$:/core/ui/Buttons/new-image]] [[$:/core/ui/Buttons/import]] [[$:/core/ui/Buttons/export-page]] [[$:/core/ui/Buttons/control-panel]] [[$:/core/ui/Buttons/advanced-search]] [[$:/core/ui/Buttons/manager]] [[$:/core/ui/Buttons/tag-manager]] [[$:/core/ui/Buttons/language]] [[$:/core/ui/Buttons/palette]] [[$:/core/ui/Buttons/theme]] [[$:/core/ui/Buttons/layout]] [[$:/core/ui/Buttons/storyview]] [[$:/core/ui/Buttons/encryption]] [[$:/core/ui/Buttons/timestamp]] [[$:/core/ui/Buttons/full-screen]] [[$:/core/ui/Buttons/print]] [[$:/core/ui/Buttons/save-wiki]] [[$:/core/ui/Buttons/refresh]] [[$:/core/ui/Buttons/network-activity]] [[$:/core/ui/Buttons/more-page-actions]]
list: [[$:/core/ui/Buttons/home]] [[$:/core/ui/Buttons/close-all]] [[$:/core/ui/Buttons/fold-all]] [[$:/core/ui/Buttons/unfold-all]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/new-tiddler]] [[$:/core/ui/Buttons/new-journal]] [[$:/core/ui/Buttons/new-image]] [[$:/core/ui/Buttons/import]] [[$:/core/ui/Buttons/export-page]] [[$:/core/ui/Buttons/control-panel]] [[$:/core/ui/Buttons/advanced-search]] [[$:/core/ui/Buttons/manager]] [[$:/core/ui/Buttons/tag-manager]] [[$:/core/ui/Buttons/language]] [[$:/core/ui/Buttons/palette]] [[$:/core/ui/Buttons/theme]] [[$:/core/ui/Buttons/layout]] [[$:/core/ui/Buttons/storyview]] [[$:/core/ui/Buttons/encryption]] [[$:/core/ui/Buttons/timestamp]] [[$:/core/ui/Buttons/full-screen]] [[$:/core/ui/Buttons/print]] [[$:/core/ui/Buttons/save-wiki]] [[$:/core/ui/Buttons/refresh]] [[$:/core/ui/Buttons/more-page-actions]]

View File

@@ -2,7 +2,7 @@ modified: 20141013085608911
tags: Mechanisms
title: TestingMechanism
TiddlyWiki5 incorporates the Jasmine JavaScript testing framework (see https://jasmine.github.io/). It allows the same tests to be run both in the browser and under Node.js.
TiddlyWiki5 incorporates the Jasmine JavaScript testing framework (see http://pivotal.github.io/jasmine/). It allows the same tests to be run both in the browser and under Node.js.
! TiddlyWiki5 Testing Components

View File

@@ -15,10 +15,6 @@
<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>
@@ -34,18 +30,6 @@
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>

View File

@@ -1,3 +0,0 @@
title: $:/config/WikiParserRules/Inline/wikilink
enable

View File

@@ -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]!is[draft]] [all[shadows+tiddlers]tag[$:/tags/Global/View]!is[draft]]
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]]
<$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>] }}}>

View File

@@ -6,7 +6,7 @@ type: text/vnd.tiddlywiki
TiddlyWiki incorpora código de los siguientes proyectos OpenSource:
* [[The Stanford Javascript Crypto Library|http://bitwiseshiftleft.github.io/sjcl/]]
* [[The Jasmine JavaScript Test Framework|https://jasmine.github.io/]]
* [[The Jasmine JavaScript Test Framework|http://pivotal.github.io/jasmine/]]
* [[Normalize.css by Nicolas Gallagher|http://necolas.github.io/normalize.css/]]
...y materiales de estos otros proyectos:

View File

@@ -6,7 +6,7 @@ type: text/vnd.tiddlywiki
TiddlyWiki intègre du code provenant de ces excellents projets OpenSource<<dp>>
* [[The Stanford Javascript Crypto Library|http://bitwiseshiftleft.github.io/sjcl/]]
* [[The Jasmine JavaScript Test Framework|https://jasmine.github.io/]]
* [[The Jasmine JavaScript Test Framework|http://pivotal.github.io/jasmine/]]
* [[Normalize.css by Nicolas Gallagher|http://necolas.github.io/normalize.css/]]
Et des contenus provenenant de ces sources<<dp>>

View File

@@ -5,7 +5,7 @@ type: text/vnd.tiddlywiki
\define tv-wikilink-template() https://tiddlywiki.com/static/$uri_doubleencoded$.html
<$importvariables filter={{$:/core/config/GlobalImportFilter}}>
<$importvariables filter="[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]">
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.

View File

@@ -8,6 +8,6 @@ Tiddlers can contain formatted text:
Formatting is typed with special codes:
<$edit-text tiddler="FormattingDemoText" class="tc-edit-texteditor" minHeight="100px"/>
<$edit-text tiddler="FormattingDemoText" class="tc-edit-texteditor" minHeight="10px"/>
TiddlyWiki is not just for text. [[Images]] are first class citizens, too.

View File

@@ -49,6 +49,14 @@
],
"build": {
"index": [
"--rendertiddler","$:/core/save/all","index.html","text/plain"]
"--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"]
}
}

View File

@@ -1,19 +1,19 @@
caption: 5.3.0
created: 20230506164543446
modified: 20230506164543446
created: 20230419103154368
modified: 20230419103154368
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/v5.2.7...master]]//
//[[See GitHub for detailed change history of this release|https://github.com/Jermolene/TiddlyWiki5/compare/master...parameterised-transclusions]]//
! Overview of v5.3.0
! About v5.3.0
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.
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.
! Introduction to Parameterised Transclusion, Procedures, Functions and Custom Widgets
! Introduction to v5.3.0
<<.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.
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,15 +30,9 @@ 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
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7493">> [[CodeMirror Plugin]] to add an option to make trailing spaces visible
*
! Translation improvement
@@ -60,30 +54,15 @@ Improvements to the following translations:
! Filter improvements
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7511"> new [[deserialize Operator]] for converting various textual representations of tiddlers into JSON data
* <<.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>>)
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7529">> size of buttons in dropdown for editor "link" toolbar button
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/8e132948b6bec623d81d300fbe6dc3a0307bcc6d">> crash when transcluding a lazily loaded tiddler as an attribute value
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7462">> DiffTextWidget crash with missing or empty attributes
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7448">> CheckboxWidget to avoid writing to date fields
*
! Developer Improvements
@@ -91,36 +70,14 @@ Improvements to the following translations:
! Node.js Improvements
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/7471">> [[WebServer Parameter: authenticated-user-header]] to require URI encoding of authenticated username header, permitting non-ASCII characters in usernames
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7253">> support for `filepath` source attribute to [[tiddlywiki.files Files]]
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/48b22abdaab62c281c207127c66883b50898f9dd">> a warning message for JSON errors in [[tiddlywiki.info Files]] or [[plugin.info Files|PluginFolders]]
*
! 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
BramChen
btheado
donmor
flibbles
GameDungeon
JoshuaFontany
kookma
linonetwo
Marxsal
mateuszwilczek
michsa
muzimuzhi
pmario
rmunn
saqimtiaz
tavin
twMat
yaisog
""">>

View File

@@ -1,3 +0,0 @@
title: $:/config/WikiParserRules/Inline/wikilink
enable

View File

@@ -1,7 +0,0 @@
created: 20230314153132081
modified: 20230314153243008
title: $:/DefaultTiddlers
type: text/vnd.tiddlywiki
GettingStarted
[[Using the external JavaScript template]]

View File

@@ -1,4 +0,0 @@
title: $:/config/SaveWikiButton/Filename
type: text/vnd.tiddlywiki
external-<<version>>.html

View File

@@ -1,8 +0,0 @@
{
"tiddlers": [
{
"file": "../../../tw5.com/tiddlers/webserver/Using the external JavaScript template.tid",
"isTiddlerFile": true
}
]
}

View File

@@ -2,7 +2,8 @@
"description": "Client-server edition with external tiddlywiki.js",
"plugins": [
"tiddlywiki/tiddlyweb",
"tiddlywiki/filesystem"
"tiddlywiki/filesystem",
"tiddlywiki/highlight"
],
"themes": [
"tiddlywiki/vanilla",
@@ -12,7 +13,7 @@
"listen": [
"--listen","root-tiddler=$:/core/save/all-external-js","use-browser-cache=yes"],
"index": [
"--render","$:/core/save/offline-external-js","[[external-]addsuffix<version>addsuffix[.html]]","text/plain",
"--render","$:/core/save/offline-external-js","index.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",

View File

@@ -1,8 +0,0 @@
title: dezerializer test data case 6
type: application/json
[
{"created":"20230601125557184","text":"Before you start storing important information in ~TiddlyWiki it is vital to make sure that you can reliably save changes. See https://tiddlywiki.com/#GettingStarted for details\n\n","title":"GettingStarted","modified":"20230601125601619"},
{"created":"20230601125507054","text":"Welcome to \"TiddlyWiki\".\n\nThis is a test tiddler.","tags":"","title":"Hello There \"Welcome\"","modified":"20230601125551144"},
{"title":"TiddlyWiki","created":"20130822170700000","modified":"20170127221451610","tags":"Concepts","type":"text/vnd.tiddlywiki","text":"~TiddlyWiki is a rich, interactive tool for manipulating complex data with structure that doesn't easily fit into conventional tools like spreadsheets or wordprocessors.\n\n~TiddlyWiki is designed to fit around your brain, helping you deal with the things that won't fit."}
]

View File

@@ -1,29 +0,0 @@
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>

View File

@@ -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

View File

@@ -12,21 +12,21 @@ title: Output
title: TiddlerOne
\whitespace trim
<!-- Define the <$my.widget> widget by defining a transcludable variable with that name -->
\widget $my.widget(one:'Jaguar')
<!-- Define the <$$mywidget> widget by defining a transcludable variable with that name -->
\widget $$mywidget(one:'Jaguar')
\whitespace trim
<$text text=<<one>>/>
<$slot $name="ts-raw">
Whale
</$slot>
\end
<$my.widget one="Dingo">
<$$mywidget one="Dingo">
Crocodile
</$my.widget>
<$my.widget one="BumbleBee">
</$$mywidget>
<$$mywidget one="BumbleBee">
Squirrel
</$my.widget>
<$my.widget/>
</$$mywidget>
<$$mywidget/>
+
title: ExpectedResult

View File

@@ -6,13 +6,13 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\widget $my.widget()
\widget $$mywidget()
<$slot $name=ts-raw>the body is empty</$slot>
\end
#<$my.widget/>
#<$my.widget></$my.widget>
#<$my.widget>the body is not empty</$my.widget>
#<$$mywidget/>
#<$$mywidget></$$mywidget>
#<$$mywidget>the body is not empty</$$mywidget>
+
title: ExpectedResult

View File

@@ -6,21 +6,21 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\widget $my.widget(one:'Jaguar')
\widget $$mywidget(one:'Jaguar')
\whitespace trim
<$text text=<<one>>/>
<$slot $name="ts-stuff">
Whale
</$slot>
\end
<$my.widget one="Dingo">
<$$mywidget one="Dingo">
<$fill $name="ts-stuff">
Crocodile
</$fill>
</$my.widget>
<$my.widget one="BumbleBee">
</$$mywidget>
<$$mywidget one="BumbleBee">
Squirrel
</$my.widget>
</$$mywidget>
+
title: ExpectedResult

View File

@@ -12,17 +12,17 @@ title: Output
title: TiddlerOne
\whitespace trim
<!-- Redefine the <$my.widget> widget by defining a transcludable variable with that name -->
\widget $my.widget($variable:'Jaguar')
<!-- Redefine the <$$mywidget> widget by defining a transcludable variable with that name -->
\widget $$mywidget($variable:'Jaguar')
\whitespace trim
<$text text=<<$variable>>/>
<$slot $name="ts-raw">
Whale
</$slot>
\end
<$my.widget $variable="Dingo">
<$$mywidget $variable="Dingo">
Crocodile
</$my.widget>
</$$mywidget>
+
title: ExpectedResult

View File

@@ -1,40 +0,0 @@
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>

View File

@@ -56,7 +56,7 @@ Tests the checkbox widget thoroughly.
* Test data for checkbox widget tests
*/
var fieldModeTests = [
const fieldModeTests = [
{
testName: "field mode checked",
tiddlers: [{title: "TiddlerOne", text: "Jolly Old World", expand: "yes"}],
@@ -95,16 +95,16 @@ Tests the checkbox widget thoroughly.
},
];
var indexModeTests = fieldModeTests.map(data => {
var newData = {...data};
var newName = data.testName.replace('field mode', 'index mode');
var newTiddlers = data.tiddlers.map(tiddler => {
const indexModeTests = fieldModeTests.map(data => {
const newData = {...data};
const newName = data.testName.replace('field mode', 'index mode');
const newTiddlers = data.tiddlers.map(tiddler => {
return {title: tiddler.title, type: "application/x-tiddler-dictionary", text: `one: a\nexpand: ${tiddler.expand}\ntwo: b`}
});
var newWidgetText = data.widgetText.replace("field='expand'", "index='expand'");
var newChange = {};
for (var key of Object.keys(data.expectedChange)) {
var oldChange = data.expectedChange[key];
const newWidgetText = data.widgetText.replace("field='expand'", "index='expand'");
const newChange = {};
for (const key of Object.keys(data.expectedChange)) {
const oldChange = data.expectedChange[key];
if (oldChange.expand) {
newChange[key] = { text: `one: a\nexpand: ${oldChange.expand}\ntwo: b` }
} else {
@@ -119,26 +119,7 @@ Tests the checkbox widget thoroughly.
return newData;
});
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 = [
const listModeTests = [
{
testName: "list mode add",
tiddlers: [{title: "Colors", colors: "orange yellow"}],
@@ -254,11 +235,11 @@ Tests the checkbox widget thoroughly.
];
// https://github.com/Jermolene/TiddlyWiki5/issues/6871
var listModeTestsWithListField = (
const listModeTestsWithListField = (
listModeTests
.filter(data => data.widgetText.includes("listField='colors'"))
.map(data => {
var newData = {
const newData = {
...data,
tiddlers: data.tiddlers.map(tiddler => ({...tiddler, list: tiddler.colors, colors: undefined})),
widgetText: data.widgetText.replace("listField='colors'", "listField='list'"),
@@ -269,11 +250,11 @@ Tests the checkbox widget thoroughly.
return newData;
})
);
var listModeTestsWithTagsField = (
const listModeTestsWithTagsField = (
listModeTests
.filter(data => data.widgetText.includes("listField='colors'"))
.map(data => {
var newData = {
const newData = {
...data,
tiddlers: data.tiddlers.map(tiddler => ({...tiddler, tags: tiddler.colors, colors: undefined})),
widgetText: data.widgetText.replace("listField='colors'", "listField='tags'"),
@@ -285,20 +266,20 @@ Tests the checkbox widget thoroughly.
})
);
var indexListModeTests = listModeTests.map(data => {
var newData = {...data};
var newName = data.testName.replace('list mode', 'index list mode');
var newTiddlers = data.tiddlers.map(tiddler => {
const indexListModeTests = listModeTests.map(data => {
const newData = {...data};
const newName = data.testName.replace('list mode', 'index list mode');
const 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`}
}
});
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];
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];
if (oldChange.colors) {
newChange[key] = { text: `one: a\ncolors: ${oldChange.colors}\ntwo: b` }
} else if (oldChange.someField !== undefined) {
@@ -315,7 +296,7 @@ Tests the checkbox widget thoroughly.
return newData;
});
var filterModeTests = [
const filterModeTests = [
{
testName: "filter mode false -> true",
tiddlers: [{title: "Colors", colors: "red orange yellow"}],
@@ -501,10 +482,9 @@ Tests the checkbox widget thoroughly.
},
];
var checkboxTestData = fieldModeTests.concat(
const checkboxTestData = fieldModeTests.concat(
indexModeTests,
listModeTests,
listModeTestsForDateFields,
listModeTestsWithListField,
listModeTestsWithTagsField,
indexListModeTests,
@@ -514,7 +494,7 @@ Tests the checkbox widget thoroughly.
/*
* Checkbox widget tests using the test data above
*/
for (var data of checkboxTestData) {
for (const data of checkboxTestData) {
it('checkbox widget test: ' + data.testName, function() {
// Setup
@@ -525,7 +505,7 @@ Tests the checkbox widget thoroughly.
// Check initial state
var widget = findNodeOfType('checkbox', widgetNode);
const widget = findNodeOfType('checkbox', widgetNode);
// Verify that the widget is or is not checked as expected
expect(widget.getValue()).toBe(data.startsOutChecked);
@@ -539,16 +519,16 @@ Tests the checkbox widget thoroughly.
widget.handleChangeEvent(null);
// Check state again: in most tests, checkbox should be inverse of what it was
var finalValue = data.hasOwnProperty('finalValue') ? data.finalValue : !data.startsOutChecked;
const 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 (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];
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];
expect(fieldValue).toEqual(expectedValue);
}
}

View File

@@ -1,44 +0,0 @@
/*\
title: test-deserialize-operator.js
type: application/javascript
tags: [[$:/tags/test-spec]]
Tests deserialize[] filter operator with various core deserializers
\*/
(function(){
/* jslint node: true, browser: true */
/* eslint-env node, browser, jasmine */
/* eslint no-mixed-spaces-and-tabs: ["error", "smart-tabs"]*/
/* global $tw, require */
"use strict";
describe("deserialize operator tests", function() {
it("should support the deserialize[] operator", function() {
//Unknown deserializer as operand
expect($tw.wiki.filterTiddlers("[{dezerializer test data case 4}deserialize[unknown/deserializer]]")).toEqual([$tw.language.getString("Error/DeserializeOperator/UnknownDeserializer")]);
//Missing operand
expect($tw.wiki.filterTiddlers("[{dezerializer test data case 4}deserialize[]]")).toEqual([$tw.language.getString("Error/DeserializeOperator/MissingOperand")]);
//Deserialize TiddlyWiki file
expect($tw.wiki.filterTiddlers("[{dezerializer test data case 4}deserialize[text/html]]")).toEqual(['[{"type":"text/vnd.tiddlywiki","text":"Abacus","title":"Hello \\"There\\""},{"title":"Hello \\"There\\"","text":"Calculator"}]']);
expect($tw.wiki.filterTiddlers("[{dezerializer test data case 5}deserialize[text/html]]")).toEqual(['[{"type":"text/vnd.tiddlywiki","text":"Abacus","title":"Hello \\"There\\""},{"title":"Hello \\"There\\"","text":"Calculator"},{"title":"Hello \\"There\\"","text":"Protractor"}]']);
// Deserialize JSON payload containing tiddlers
expect($tw.wiki.filterTiddlers("[{dezerializer test data case 6}deserialize[application/json]]")).toEqual( [ `[{"created":"20230601125557184","text":"Before you start storing important information in ~TiddlyWiki it is vital to make sure that you can reliably save changes. See https://tiddlywiki.com/#GettingStarted for details\\n\\n","title":"GettingStarted","modified":"20230601125601619"},{"created":"20230601125507054","text":"Welcome to \\"TiddlyWiki\\".\\n\\nThis is a test tiddler.","tags":"","title":"Hello There \\"Welcome\\"","modified":"20230601125551144"},{"title":"TiddlyWiki","created":"20130822170700000","modified":"20170127221451610","tags":"Concepts","type":"text/vnd.tiddlywiki","text":"~TiddlyWiki is a rich, interactive tool for manipulating complex data with structure that doesn't easily fit into conventional tools like spreadsheets or wordprocessors.\\n\\n~TiddlyWiki is designed to fit around your brain, helping you deal with the things that won't fit."}]` ]);
expect($tw.wiki.filterTiddlers("[{dezerializer test data case 6}deserialize[application/json]jsonindexes[]] :map[{dezerializer test data case 6}jsonget<currentTiddler>,[title]]")).toEqual([ 'GettingStarted', 'Hello There "Welcome"', 'TiddlyWiki' ]);
//Deserialize TiddlyWiki file with an mismatched deserializer
expect($tw.wiki.filterTiddlers("[{dezerializer test data case 5}deserialize[application/json]]")).toEqual([jasmine.stringMatching('JSON error')]);
});
});
})();

View File

@@ -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,$:/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("[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("[[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,9 +1060,6 @@ 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() {

View File

@@ -45,6 +45,16 @@ 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>");

View File

@@ -6,8 +6,6 @@ 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
@@ -15,4 +13,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]]">>

View File

@@ -6,8 +6,6 @@ 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
@@ -16,4 +14,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]]">>

View File

@@ -6,8 +6,6 @@ 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:

View File

@@ -6,8 +6,6 @@ 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
@@ -15,4 +13,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]]">>

View File

@@ -6,8 +6,6 @@ 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
@@ -15,4 +13,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]]">>

View File

@@ -6,8 +6,6 @@ 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
@@ -15,4 +13,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]]">>

View File

@@ -45,7 +45,7 @@ Special tags assign special behaviour or appearance to all of the tiddlers to wh
For example:
* $:/tags/Global causes the definitions in a tiddler to be available globally
* $:/tags/Macro causes the macros defined 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

View File

@@ -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. It is implemented as a serverless application on Amazon Web Services.
Xememex is a multiuser TiddlyWiki from [[Federatial]]. It allows large groups of people to work together on intertwingled wikis that can share content.
The largest customer implementation has hundreds of online wikis with thousands of users. See https://manuals.annafreud.org/

View File

@@ -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 [subfilter{$:/core/config/GlobalImportFilter}]
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
```
!! Post-Render Startup Actions

View File

@@ -1,26 +0,0 @@
caption: deserialize
created: 20230601195749377
from-version: 5.3.0
modified: 20230602105513132
op-input: a selection of strings
op-output: JSON representations of tiddlers extracted from input titles.
op-parameter: the deserializer module to be used to extract tiddlers from the input
op-purpose: extract JSON representation of tiddlers from the input strings
tags: [[Filter Operators]] [[Special Operators]]
title: deserialize Operator
type: text/vnd.tiddlywiki
<<.tip "Deserializer modules parse text in various formats into their JSON representation as tiddlers. You can see the deserializers available in a wiki using the [[deserializers operator|deserializers Operator]].">>
|!Deserializer |!Description |
|(DOM)|Extracts tiddlers from a DOM node, should not be used with the <<.op deserialize[]>> operator |
|application/javascript|Parses a JavaScript module as a tiddler extracting fields from the header comment|
|application/json|Parses [[JSON|JSON in TiddlyWiki]] into tiddlers|
|application/x-tiddler|Parses the [[.tid file format|TiddlerFiles]] as a tiddler|
|application/x-tiddler-html-div|Parses the [[<DIV>.tiddler file format|TiddlerFiles]] as a tiddler|
|application/x-tiddlers|Parses the [[MultiTiddlerFile format|MultiTiddlerFiles]] as tiddlers|
|text/css|Parses CSS as a tiddler extracting fields from the header comment|
|text/html|Parses an HTML file into tiddlers. Supports ~TiddlyWiki Classic HTML files, ~TiddlyWiki5 HTML files and ordinary HTML files|
|text/plain|Parses plain text as a tiddler|
<<.operator-examples "deserialize">>

View File

@@ -1,29 +0,0 @@
created: 20230601200356736
modified: 20230602105036887
tags: [[Operator Examples]] [[deserialize Operator]]
title: deserialize Operator (Examples)
type: text/vnd.tiddlywiki
\define html-data()
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test Data</title>
</head>
<body>
<!--~~ Ordinary tiddlers ~~-->
<div id="storeArea" style="display:none;"><div title="Hello &quot;There&quot;" type="text/vnd.tiddlywiki">
<pre>Abacus</pre>
</div>
</div>
<script class="tiddlywiki-tiddler-store" type="application/json">[{"title":"Hello \"There\"","text":"Calculator"},{"title":"Hello \"There\"","text":"Protractor"}]</script>
</body>
</html>
\end
This example uses the predefined variable `html-data`:
<$codeblock code=<<html-data>> language="HTML"/>
<<.operator-example 1 "[<html-data>deserialize[text/html]]">>

Some files were not shown because too many files have changed in this diff Show More