mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-01-23 11:24:40 +00:00
Compare commits
1 Commits
custom-cop
...
tm-http-re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afc042a967 |
@@ -1,3 +1,6 @@
|
||||
title: $:/boot/boot.css
|
||||
type: text/css
|
||||
|
||||
/*
|
||||
Basic styles used before we boot up the parsing engine
|
||||
*/
|
||||
47
boot/boot.js
47
boot/boot.js
@@ -142,15 +142,15 @@ $tw.utils.each = function(object,callback) {
|
||||
var next,f,length;
|
||||
if(object) {
|
||||
if(Object.prototype.toString.call(object) == "[object Array]") {
|
||||
for(f=0, length=object.length; f<length; f++) {
|
||||
for (f=0, length=object.length; f<length; f++) {
|
||||
next = callback(object[f],f,object);
|
||||
if(next === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var keys = Object.keys(object);
|
||||
for(f=0, length=keys.length; f<length; f++) {
|
||||
for (f=0, length=keys.length; f<length; f++) {
|
||||
var key = keys[f];
|
||||
next = callback(object[key],key,object);
|
||||
if(next === false) {
|
||||
@@ -275,7 +275,7 @@ Extend an object with the properties from a list of source objects
|
||||
$tw.utils.extend = function(object /*, sourceObjectList */) {
|
||||
$tw.utils.each(Array.prototype.slice.call(arguments,1),function(source) {
|
||||
if(source) {
|
||||
for(var p in source) {
|
||||
for (var p in source) {
|
||||
object[p] = source[p];
|
||||
}
|
||||
}
|
||||
@@ -289,7 +289,7 @@ Fill in any null or undefined properties of an object with the properties from a
|
||||
$tw.utils.deepDefaults = function(object /*, sourceObjectList */) {
|
||||
$tw.utils.each(Array.prototype.slice.call(arguments,1),function(source) {
|
||||
if(source) {
|
||||
for(var p in source) {
|
||||
for (var p in source) {
|
||||
if(object[p] === null || object[p] === undefined) {
|
||||
object[p] = source[p];
|
||||
}
|
||||
@@ -893,8 +893,8 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
|
||||
} else {
|
||||
/*
|
||||
CommonJS optional require.main property:
|
||||
In a browser we offer a fake main module which points back to the boot function
|
||||
(Theoretically, this may allow TW to eventually load itself as a module in the browser)
|
||||
In a browser we offer a fake main module which points back to the boot function
|
||||
(Theoretically, this may allow TW to eventually load itself as a module in the browser)
|
||||
*/
|
||||
Object.defineProperty(sandbox.require, "main", {
|
||||
value: (typeof(require) !== "undefined") ? require.main : {TiddlyWiki: _boot},
|
||||
@@ -936,9 +936,9 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
|
||||
moduleInfo.exports = moduleInfo.definition;
|
||||
}
|
||||
} catch(e) {
|
||||
if(e instanceof SyntaxError) {
|
||||
if (e instanceof SyntaxError) {
|
||||
var line = e.lineNumber || e.line; // Firefox || Safari
|
||||
if(typeof(line) != "undefined" && line !== null) {
|
||||
if (typeof(line) != "undefined" && line !== null) {
|
||||
$tw.utils.error("Syntax error in boot module " + name + ":" + line + ":\n" + e.stack);
|
||||
} else if(!$tw.browser) {
|
||||
// this is the only way to get node.js to display the line at which the syntax error appeared,
|
||||
@@ -1533,7 +1533,7 @@ Define all modules stored in ordinary tiddlers
|
||||
$tw.Wiki.prototype.defineTiddlerModules = function() {
|
||||
this.each(function(tiddler,title) {
|
||||
if(tiddler.hasField("module-type")) {
|
||||
switch(tiddler.fields.type) {
|
||||
switch (tiddler.fields.type) {
|
||||
case "application/javascript":
|
||||
// We only define modules that haven't already been defined, because in the browser modules in system tiddlers are defined in inline script
|
||||
if(!$tw.utils.hop($tw.modules.titles,tiddler.fields.title)) {
|
||||
@@ -2043,7 +2043,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
||||
arrayOfFiles = arrayOfFiles || [];
|
||||
var files = fs.readdirSync(dirPath);
|
||||
files.forEach(function(file) {
|
||||
if(recurse && fs.statSync(dirPath + path.sep + file).isDirectory()) {
|
||||
if (recurse && fs.statSync(dirPath + path.sep + file).isDirectory()) {
|
||||
arrayOfFiles = getAllFiles(dirPath + path.sep + file, recurse, arrayOfFiles);
|
||||
} else if(fs.statSync(dirPath + path.sep + file).isFile()){
|
||||
arrayOfFiles.push(path.join(dirPath, path.sep, file));
|
||||
@@ -2188,16 +2188,13 @@ Returns an array of search paths
|
||||
*/
|
||||
$tw.getLibraryItemSearchPaths = function(libraryPath,envVar) {
|
||||
var pluginPaths = [path.resolve($tw.boot.corePath,libraryPath)],
|
||||
env;
|
||||
if(envVar) {
|
||||
env = process.env[envVar];
|
||||
if(env) {
|
||||
env.split(path.delimiter).map(function(item) {
|
||||
if(item) {
|
||||
pluginPaths.push(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
if(env) {
|
||||
env.split(path.delimiter).map(function(item) {
|
||||
if(item) {
|
||||
pluginPaths.push(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
return pluginPaths;
|
||||
};
|
||||
@@ -2283,7 +2280,7 @@ $tw.loadWikiTiddlers = function(wikiPath,options) {
|
||||
}
|
||||
$tw.wiki.addTiddlers(tiddlerFile.tiddlers);
|
||||
});
|
||||
if($tw.boot.wikiPath == wikiPath) {
|
||||
if ($tw.boot.wikiPath == wikiPath) {
|
||||
// Save the original tiddler file locations if requested
|
||||
var output = {}, relativePath, fileInfo;
|
||||
for(var title in $tw.boot.files) {
|
||||
@@ -2637,14 +2634,14 @@ $tw.boot.doesTaskMatchPlatform = function(taskModule) {
|
||||
var platforms = taskModule.platforms;
|
||||
if(platforms) {
|
||||
for(var t=0; t<platforms.length; t++) {
|
||||
switch(platforms[t]) {
|
||||
switch (platforms[t]) {
|
||||
case "browser":
|
||||
if($tw.browser) {
|
||||
if ($tw.browser) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case "node":
|
||||
if($tw.node) {
|
||||
if ($tw.node) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@@ -2727,7 +2724,7 @@ Invoke the hook by key
|
||||
$tw.hooks.invokeHook = function(hookName /*, value,... */) {
|
||||
var args = Array.prototype.slice.call(arguments,1);
|
||||
if($tw.utils.hop($tw.hooks.names,hookName)) {
|
||||
for(var i = 0; i < $tw.hooks.names[hookName].length; i++) {
|
||||
for (var i = 0; i < $tw.hooks.names[hookName].length; i++) {
|
||||
args[0] = $tw.hooks.names[hookName][i].apply(null,args);
|
||||
}
|
||||
}
|
||||
|
||||
3
boot/sjcl.js.meta
Normal file
3
boot/sjcl.js.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/library/sjcl.js
|
||||
type: application/javascript
|
||||
library: yes
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"tiddlers": [
|
||||
{
|
||||
"file": "sjcl.js",
|
||||
"fields": {
|
||||
"title": "$:/library/sjcl.js",
|
||||
"type": "application/javascript",
|
||||
"library": "yes"
|
||||
},
|
||||
"prefix": "(function(define) {\n",
|
||||
"suffix": "\n})(function (_,defined){window.sjcl = defined()})\n"
|
||||
},
|
||||
{
|
||||
"file": "boot.js",
|
||||
"fields": {
|
||||
"title": "$:/boot/boot.js",
|
||||
"type": "application/javascript"
|
||||
}
|
||||
},
|
||||
{
|
||||
"file": "bootprefix.js",
|
||||
"fields": {
|
||||
"title": "$:/boot/bootprefix.js",
|
||||
"type": "application/javascript"
|
||||
}
|
||||
},
|
||||
{
|
||||
"file": "boot.css",
|
||||
"fields": {
|
||||
"title": "$:/boot/boot.css",
|
||||
"type": "text/css"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -206,12 +206,6 @@ Stylesheets/Caption: Stylesheets
|
||||
Stylesheets/Expand/Caption: Expand All
|
||||
Stylesheets/Hint: This is the rendered CSS of the current stylesheet tiddlers tagged with <<tag "$:/tags/Stylesheet">>
|
||||
Stylesheets/Restore/Caption: Restore
|
||||
TestCases/Caption: Test Cases
|
||||
TestCases/Hint: Test cases are self contained examples for testing and learning
|
||||
TestCases/All/Caption: All Test Cases
|
||||
TestCases/All/Hint: All Test Cases
|
||||
TestCases/Failed/Caption: Failed Test Cases
|
||||
TestCases/Failed/Hint: Only Failed Test Cases
|
||||
Theme/Caption: Theme
|
||||
Theme/Prompt: Current theme:
|
||||
TiddlerFields/Caption: Tiddler Fields
|
||||
|
||||
@@ -65,9 +65,6 @@ sidebar-tab-foreground-selected: Sidebar tab foreground for selected tabs
|
||||
sidebar-tab-foreground: Sidebar tab foreground
|
||||
sidebar-tiddler-link-foreground-hover: Sidebar tiddler link foreground hover
|
||||
sidebar-tiddler-link-foreground: Sidebar tiddler link foreground
|
||||
testcase-accent-level-1: Test case accent colour with no nesting
|
||||
testcase-accent-level-2: Test case accent colour with 2nd level nesting
|
||||
testcase-accent-level-3: Test case accent colour with 3rd level nesting or higher
|
||||
site-title-foreground: Site title foreground
|
||||
static-alert-foreground: Static alert foreground
|
||||
tab-background-selected: Tab background for selected tabs
|
||||
|
||||
@@ -30,7 +30,6 @@ name: The human readable name associated with a plugin tiddler
|
||||
parent-plugin: For a plugin, specifies which plugin of which it is a sub-plugin
|
||||
plugin-priority: A numerical value indicating the priority of a plugin tiddler
|
||||
plugin-type: The type of plugin in a plugin tiddler
|
||||
stability: The development status of a plugin: deprecated, experimental, stable, or legacy
|
||||
revision: The revision of the tiddler held at the server
|
||||
released: Date of a TiddlyWiki release
|
||||
source: The source URL associated with a tiddler
|
||||
|
||||
@@ -27,8 +27,33 @@ var Command = function(params,commander,callback) {
|
||||
|
||||
Command.prototype.execute = function() {
|
||||
var wiki = this.commander.wiki,
|
||||
fs = require("fs"),
|
||||
path = require("path"),
|
||||
upgradeLibraryTitle = this.params[0] || UPGRADE_LIBRARY_TITLE,
|
||||
tiddlers = $tw.utils.getAllPlugins();
|
||||
tiddlers = {};
|
||||
// Collect up the library plugins
|
||||
var collectPlugins = function(folder) {
|
||||
var pluginFolders = $tw.utils.getSubdirectories(folder) || [];
|
||||
for(var p=0; p<pluginFolders.length; p++) {
|
||||
if(!$tw.boot.excludeRegExp.test(pluginFolders[p])) {
|
||||
pluginFields = $tw.loadPluginFolder(path.resolve(folder,"./" + pluginFolders[p]));
|
||||
if(pluginFields && pluginFields.title) {
|
||||
tiddlers[pluginFields.title] = pluginFields;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
collectPublisherPlugins = function(folder) {
|
||||
var publisherFolders = $tw.utils.getSubdirectories(folder) || [];
|
||||
for(var t=0; t<publisherFolders.length; t++) {
|
||||
if(!$tw.boot.excludeRegExp.test(publisherFolders[t])) {
|
||||
collectPlugins(path.resolve(folder,"./" + publisherFolders[t]));
|
||||
}
|
||||
}
|
||||
};
|
||||
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.pluginsPath,$tw.config.pluginsEnvVar),collectPublisherPlugins);
|
||||
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.themesPath,$tw.config.themesEnvVar),collectPublisherPlugins);
|
||||
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.languagesPath,$tw.config.languagesEnvVar),collectPlugins);
|
||||
// Save the upgrade library tiddler
|
||||
var pluginFields = {
|
||||
title: upgradeLibraryTitle,
|
||||
|
||||
@@ -43,9 +43,7 @@ Saves individual tiddlers in their raw text or binary format to the specified fi
|
||||
directory: path.resolve(self.commander.outputPath),
|
||||
pathFilters: [filenameFilter],
|
||||
wiki: wiki,
|
||||
fileInfo: {
|
||||
overwrite: true
|
||||
}
|
||||
fileInfo: {}
|
||||
});
|
||||
if(self.commander.verbose) {
|
||||
console.log("Saving \"" + title + "\" to \"" + fileInfo.filepath + "\"");
|
||||
|
||||
@@ -176,10 +176,7 @@ WikiFolderMaker.prototype.saveCustomPlugin = function(pluginTiddler) {
|
||||
this.saveJSONFile(directory + path.sep + "plugin.info",pluginInfo);
|
||||
self.log("Writing " + directory + path.sep + "plugin.info: " + JSON.stringify(pluginInfo,null,$tw.config.preferences.jsonSpaces));
|
||||
var pluginTiddlers = $tw.utils.parseJSONSafe(pluginTiddler.fields.text).tiddlers; // A hashmap of tiddlers in the plugin
|
||||
$tw.utils.each(pluginTiddlers,function(tiddler,title) {
|
||||
if(!tiddler.title) {
|
||||
tiddler.title = title;
|
||||
}
|
||||
$tw.utils.each(pluginTiddlers,function(tiddler) {
|
||||
self.saveTiddler(directory,new $tw.Tiddler(tiddler));
|
||||
});
|
||||
};
|
||||
|
||||
@@ -70,9 +70,6 @@ BackSubIndexer.prototype.rebuild = function() {
|
||||
* Get things that is being referenced in the text, e.g. tiddler names in the link syntax.
|
||||
*/
|
||||
BackSubIndexer.prototype._getTarget = function(tiddler) {
|
||||
if(this.wiki.isBinaryTiddler(tiddler.fields.text)) {
|
||||
return [];
|
||||
}
|
||||
var parser = this.wiki.parseText(tiddler.fields.type, tiddler.fields.text, {});
|
||||
if(parser) {
|
||||
return this.wiki[this.extractor](parser.tree);
|
||||
|
||||
@@ -3,7 +3,30 @@ title: $:/core/modules/parsers/wikiparser/rules/quoteblock.js
|
||||
type: application/javascript
|
||||
module-type: wikirule
|
||||
|
||||
Wiki text rule for quote blocks.
|
||||
Wiki text rule for quote blocks. For example:
|
||||
|
||||
```
|
||||
<<<.optionalClass(es) optional cited from
|
||||
a quote
|
||||
<<<
|
||||
|
||||
<<<.optionalClass(es)
|
||||
a quote
|
||||
<<< optional cited from
|
||||
```
|
||||
|
||||
Quotes can be quoted by putting more <s
|
||||
|
||||
```
|
||||
<<<
|
||||
Quote Level 1
|
||||
|
||||
<<<<
|
||||
QuoteLevel 2
|
||||
<<<<
|
||||
|
||||
<<<
|
||||
```
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
@@ -24,15 +47,16 @@ exports.init = function(parser) {
|
||||
exports.parse = function() {
|
||||
var classes = ["tc-quote"];
|
||||
// Get all the details of the match
|
||||
var reEndString = "^\\s*" + this.match[1] + "(?!<)";
|
||||
var reEndString = "^" + this.match[1] + "(?!<)";
|
||||
// Move past the <s
|
||||
this.parser.pos = this.matchRegExp.lastIndex;
|
||||
|
||||
// Parse any classes, whitespace and then the optional cite itself
|
||||
classes.push.apply(classes, this.parser.parseClasses());
|
||||
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
|
||||
var cite = this.parser.parseInlineRun(/(\r?\n)/mg);
|
||||
// before handling the cite, parse the body of the quote
|
||||
var tree = this.parser.parseBlocks(reEndString);
|
||||
var tree= this.parser.parseBlocks(reEndString);
|
||||
// If we got a cite, put it before the text
|
||||
if(cite.length > 0) {
|
||||
tree.unshift({
|
||||
|
||||
@@ -140,11 +140,6 @@ function sendResponse(request,response,statusCode,headers,data,encoding) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// RFC 7231, 6.1. Overview of Status Codes:
|
||||
// Browser clients may cache 200, 203, 204, 206, 300, 301,
|
||||
// 404, 405, 410, 414, and 501 unless given explicit cache controls
|
||||
headers["Cache-Control"] = headers["Cache-Control"] || "no-store";
|
||||
}
|
||||
/*
|
||||
If the gzip=yes is set, check if the user agent permits compression. If so,
|
||||
|
||||
@@ -81,8 +81,6 @@ exports.startup = function() {
|
||||
deferredChanges = Object.create(null);
|
||||
$tw.hooks.invokeHook("th-page-refreshed");
|
||||
}
|
||||
var throttledRefresh = $tw.perf.report("throttledRefresh",refresh);
|
||||
|
||||
// Add the change event handler
|
||||
$tw.wiki.addEventListener("change",$tw.perf.report("mainRefresh",function(changes) {
|
||||
// Check if only tiddlers that are throttled have changed
|
||||
@@ -103,7 +101,7 @@ exports.startup = function() {
|
||||
if(isNaN(timeout)) {
|
||||
timeout = THROTTLE_REFRESH_TIMEOUT;
|
||||
}
|
||||
timerId = setTimeout(throttledRefresh,timeout);
|
||||
timerId = setTimeout(refresh,timeout);
|
||||
$tw.utils.extend(deferredChanges,changes);
|
||||
} else {
|
||||
$tw.utils.extend(deferredChanges,changes);
|
||||
|
||||
@@ -47,7 +47,11 @@ exports.startup = function() {
|
||||
headers: getPropertiesWithPrefix(params,"header-"),
|
||||
passwordHeaders: getPropertiesWithPrefix(params,"password-header-"),
|
||||
queryStrings: getPropertiesWithPrefix(params,"query-"),
|
||||
passwordQueryStrings: getPropertiesWithPrefix(params,"password-query-")
|
||||
passwordQueryStrings: getPropertiesWithPrefix(params,"password-query-"),
|
||||
basicAuthUsername: params["basic-auth-username"],
|
||||
basicAuthUsernameFromStore: params["basic-auth-username-from-store"],
|
||||
basicAuthPassword: params["basic-auth-password"],
|
||||
basicAuthPasswordFromStore: params["basic-auth-password-from-store"]
|
||||
});
|
||||
});
|
||||
$tw.rootWidget.addEventListener("tm-http-cancel-all-requests",function(event) {
|
||||
@@ -68,10 +72,7 @@ exports.startup = function() {
|
||||
});
|
||||
// Install the copy-to-clipboard mechanism
|
||||
$tw.rootWidget.addEventListener("tm-copy-to-clipboard",function(event) {
|
||||
$tw.utils.copyToClipboard(event.param,{
|
||||
successNotification: event.paramObject.successNotification,
|
||||
failureNotification: event.paramObject.failureNotification
|
||||
});
|
||||
$tw.utils.copyToClipboard(event.param);
|
||||
});
|
||||
// Install the tm-focus-selector message
|
||||
$tw.rootWidget.addEventListener("tm-focus-selector",function(event) {
|
||||
|
||||
@@ -93,9 +93,7 @@ exports.startup = function() {
|
||||
updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permalink" : "none",
|
||||
updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(),
|
||||
targetTiddler: event.param || event.tiddlerTitle,
|
||||
copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permalink" : "none",
|
||||
successNotification: event.paramObject && event.paramObject.successNotification,
|
||||
failureNotification: event.paramObject && event.paramObject.failureNotification
|
||||
copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permalink" : "none"
|
||||
});
|
||||
});
|
||||
// Listen for the tm-permaview message
|
||||
@@ -104,9 +102,7 @@ exports.startup = function() {
|
||||
updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permaview" : "none",
|
||||
updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(),
|
||||
targetTiddler: event.param || event.tiddlerTitle,
|
||||
copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permaview" : "none",
|
||||
successNotification: event.paramObject && event.paramObject.successNotification,
|
||||
failureNotification: event.paramObject && event.paramObject.failureNotification
|
||||
copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permaview" : "none"
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -181,8 +177,6 @@ options.updateAddressBar: "permalink", "permaview" or "no" (defaults to "permavi
|
||||
options.updateHistory: "yes" or "no" (defaults to "no")
|
||||
options.copyToClipboard: "permalink", "permaview" or "no" (defaults to "no")
|
||||
options.targetTiddler: optional title of target tiddler for permalink
|
||||
options.successNotification: optional title of tiddler to use as the notification in case of success
|
||||
options.failureNotification: optional title of tiddler to use as the notification in case of failure
|
||||
*/
|
||||
function updateLocationHash(options) {
|
||||
// Get the story and the history stack
|
||||
@@ -211,18 +205,14 @@ function updateLocationHash(options) {
|
||||
break;
|
||||
}
|
||||
// Copy URL to the clipboard
|
||||
var url = "";
|
||||
switch(options.copyToClipboard) {
|
||||
case "permalink":
|
||||
url = $tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler);
|
||||
$tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler));
|
||||
break;
|
||||
case "permaview":
|
||||
url = $tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList));
|
||||
$tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList)));
|
||||
break;
|
||||
}
|
||||
if(url) {
|
||||
$tw.utils.copyToClipboard(url,{successNotification: options.successNotification, failureNotification: options.failureNotification});
|
||||
}
|
||||
// Only change the location hash if we must, thus avoiding unnecessary onhashchange events
|
||||
if($tw.utils.getLocationHash() !== $tw.locationHash) {
|
||||
if(options.updateHistory === "yes") {
|
||||
|
||||
@@ -56,7 +56,7 @@ exports.startup = function() {
|
||||
return;
|
||||
}
|
||||
// Initialise the document
|
||||
srcDocument.write("<!DOCTYPE html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>");
|
||||
srcDocument.write("<html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>");
|
||||
srcDocument.close();
|
||||
srcDocument.title = windowTitle;
|
||||
srcWindow.addEventListener("beforeunload",function(event) {
|
||||
|
||||
@@ -292,9 +292,7 @@ exports.copyToClipboard = function(text,options) {
|
||||
} catch (err) {
|
||||
}
|
||||
if(!options.doNotNotify) {
|
||||
var successNotification = options.successNotification || "$:/language/Notifications/CopiedToClipboard/Succeeded",
|
||||
failureNotification = options.failureNotification || "$:/language/Notifications/CopiedToClipboard/Failed"
|
||||
$tw.notifier.display(succeeded ? successNotification : failureNotification);
|
||||
$tw.notifier.display(succeeded ? "$:/language/Notifications/CopiedToClipboard/Succeeded" : "$:/language/Notifications/CopiedToClipboard/Failed");
|
||||
}
|
||||
document.body.removeChild(textArea);
|
||||
};
|
||||
|
||||
@@ -100,6 +100,10 @@ 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
|
||||
basicAuthUsername: plain username for basic authentication
|
||||
basicAuthUsernameFromStore: name of password store entry containing username
|
||||
basicAuthPassword: plain password for basic authentication
|
||||
basicAuthPasswordFromStore: name of password store entry containing password
|
||||
*/
|
||||
function HttpClientRequest(options) {
|
||||
var self = this;
|
||||
@@ -128,6 +132,11 @@ function HttpClientRequest(options) {
|
||||
$tw.utils.each(options.passwordHeaders,function(value,name) {
|
||||
self.requestHeaders[name] = $tw.utils.getPassword(value) || "";
|
||||
});
|
||||
this.basicAuthUsername = options.basicAuthUsername || (options.basicAuthUsernameFromStore && $tw.utils.getPassword(options.basicAuthUsernameFromStore)) || "";
|
||||
this.basicAuthPassword = options.basicAuthPassword || (options.basicAuthPasswordFromStore && $tw.utils.getPassword(options.basicAuthPasswordFromStore)) || "";
|
||||
if(this.basicAuthUsername && this.basicAuthPassword) {
|
||||
this.requestHeaders.Authorization = "Basic " + $tw.utils.base64Encode(this.basicAuthUsername + ":" + this.basicAuthPassword);
|
||||
}
|
||||
}
|
||||
|
||||
HttpClientRequest.prototype.send = function(callback) {
|
||||
@@ -283,7 +292,7 @@ exports.httpRequest = function(options) {
|
||||
// Set up the state change handler
|
||||
request.onreadystatechange = function() {
|
||||
if(this.readyState === 4) {
|
||||
if(this.status >= 200 && this.status < 300) {
|
||||
if(this.status === 200 || this.status === 201 || this.status === 204) {
|
||||
// Success!
|
||||
options.callback(null,this[returnProp],this);
|
||||
return;
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/*\
|
||||
title: $:/core/modules/utils/errors.js
|
||||
type: application/javascript
|
||||
module-type: utils
|
||||
|
||||
Custom errors for TiddlyWiki.
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
function TranscludeRecursionError() {
|
||||
Error.apply(this,arguments);
|
||||
this.signatures = Object.create(null);
|
||||
};
|
||||
|
||||
/* Maximum permitted depth of the widget tree for recursion detection */
|
||||
TranscludeRecursionError.MAX_WIDGET_TREE_DEPTH = 1000;
|
||||
|
||||
TranscludeRecursionError.prototype = Object.create(Error);
|
||||
|
||||
exports.TranscludeRecursionError = TranscludeRecursionError;
|
||||
|
||||
})();
|
||||
@@ -42,7 +42,7 @@ var TW_TextNode = function(text) {
|
||||
this.textContent = text + "";
|
||||
};
|
||||
|
||||
Object.setPrototypeOf(TW_TextNode.prototype,TW_Node.prototype);
|
||||
Object.setPrototypeOf(TW_TextNode,TW_Node.prototype);
|
||||
|
||||
Object.defineProperty(TW_TextNode.prototype, "nodeType", {
|
||||
get: function() {
|
||||
@@ -67,7 +67,7 @@ var TW_Element = function(tag,namespace) {
|
||||
this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml";
|
||||
};
|
||||
|
||||
Object.setPrototypeOf(TW_Element.prototype,TW_Node.prototype);
|
||||
Object.setPrototypeOf(TW_Element,TW_Node.prototype);
|
||||
|
||||
Object.defineProperty(TW_Element.prototype, "style", {
|
||||
get: function() {
|
||||
|
||||
@@ -316,13 +316,11 @@ Options include:
|
||||
pathFilters: optional array of filters to be used to generate the base path
|
||||
wiki: optional wiki for evaluating the pathFilters
|
||||
fileInfo: an existing fileInfo object to check against
|
||||
fileInfo.overwrite: if true, turns off filename clash numbers (defaults to false)
|
||||
*/
|
||||
exports.generateTiddlerFilepath = function(title,options) {
|
||||
var directory = options.directory || "",
|
||||
extension = options.extension || "",
|
||||
originalpath = (options.fileInfo && options.fileInfo.originalpath) ? options.fileInfo.originalpath : "",
|
||||
overwrite = options.fileInfo && options.fileInfo.overwrite || false,
|
||||
filepath;
|
||||
// Check if any of the pathFilters applies
|
||||
if(options.pathFilters && options.wiki) {
|
||||
@@ -383,20 +381,19 @@ exports.generateTiddlerFilepath = function(title,options) {
|
||||
filepath += char.charCodeAt(0).toString();
|
||||
});
|
||||
}
|
||||
// Add a uniquifier if the file already exists (default)
|
||||
var fullPath = path.resolve(directory, filepath + extension);
|
||||
if (!overwrite) {
|
||||
var oldPath = (options.fileInfo) ? options.fileInfo.filepath : undefined,
|
||||
// Add a uniquifier if the file already exists
|
||||
var fullPath, oldPath = (options.fileInfo) ? options.fileInfo.filepath : undefined,
|
||||
count = 0;
|
||||
do {
|
||||
fullPath = path.resolve(directory,filepath + (count ? "_" + count : "") + extension);
|
||||
if(oldPath && oldPath == fullPath) break;
|
||||
count++;
|
||||
} while(fs.existsSync(fullPath));
|
||||
}
|
||||
do {
|
||||
fullPath = path.resolve(directory,filepath + (count ? "_" + count : "") + extension);
|
||||
if(oldPath && oldPath == fullPath) {
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
} while(fs.existsSync(fullPath));
|
||||
// If the last write failed with an error, or if path does not start with:
|
||||
// the resolved options.directory, the resolved wikiPath directory, the wikiTiddlersPath directory,
|
||||
// or the 'originalpath' directory, then $tw.utils.encodeURIComponentExtended() and resolve to options.directory.
|
||||
// or the 'originalpath' directory, then $tw.utils.encodeURIComponentExtended() and resolve to tiddler directory.
|
||||
var writePath = $tw.hooks.invokeHook("th-make-tiddler-path",fullPath,fullPath),
|
||||
encode = (options.fileInfo || {writeError: false}).writeError == true;
|
||||
if(!encode) {
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*\
|
||||
title: $:/core/modules/utils/repository.js
|
||||
type: application/javascript
|
||||
module-type: utils
|
||||
|
||||
Utilities for working with the TiddlyWiki repository file structure
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Get an object containing all the plugins as a hashmap by title of the JSON representation of the plugin
|
||||
Options:
|
||||
|
||||
ignoreEnvironmentVariables: defaults to false
|
||||
*/
|
||||
exports.getAllPlugins = function(options) {
|
||||
options = options || {};
|
||||
var fs = require("fs"),
|
||||
path = require("path"),
|
||||
tiddlers = {};
|
||||
// Collect up the library plugins
|
||||
var collectPlugins = function(folder) {
|
||||
var pluginFolders = $tw.utils.getSubdirectories(folder) || [];
|
||||
for(var p=0; p<pluginFolders.length; p++) {
|
||||
if(!$tw.boot.excludeRegExp.test(pluginFolders[p])) {
|
||||
var pluginFields = $tw.loadPluginFolder(path.resolve(folder,"./" + pluginFolders[p]));
|
||||
if(pluginFields && pluginFields.title) {
|
||||
tiddlers[pluginFields.title] = pluginFields;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
collectPublisherPlugins = function(folder) {
|
||||
var publisherFolders = $tw.utils.getSubdirectories(folder) || [];
|
||||
for(var t=0; t<publisherFolders.length; t++) {
|
||||
if(!$tw.boot.excludeRegExp.test(publisherFolders[t])) {
|
||||
collectPlugins(path.resolve(folder,"./" + publisherFolders[t]));
|
||||
}
|
||||
}
|
||||
};
|
||||
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.pluginsPath,options.ignoreEnvironmentVariables ? undefined : $tw.config.pluginsEnvVar),collectPublisherPlugins);
|
||||
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.themesPath,options.ignoreEnvironmentVariables ? undefined : $tw.config.themesEnvVar),collectPublisherPlugins);
|
||||
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.languagesPath,options.ignoreEnvironmentVariables ? undefined : $tw.config.languagesEnvVar),collectPlugins);
|
||||
return tiddlers;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -825,7 +825,7 @@ options.length .. number of characters returned defaults to 64
|
||||
*/
|
||||
exports.sha256 = function(str, options) {
|
||||
options = options || {}
|
||||
return $tw.sjcl.codec.hex.fromBits($tw.sjcl.hash.sha256.hash(str)).substr(0,options.length || 64);
|
||||
return sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(str)).substr(0,options.length || 64);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -37,7 +37,6 @@ Compute the internal state of the widget
|
||||
DeleteFieldWidget.prototype.execute = function() {
|
||||
this.actionTiddler = this.getAttribute("$tiddler",this.getVariable("currentTiddler"));
|
||||
this.actionField = this.getAttribute("$field",null);
|
||||
this.actionTimestamp = this.getAttribute("$timestamp","yes") === "yes";
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -70,15 +69,11 @@ DeleteFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||
$tw.utils.each(this.attributes,function(attribute,name) {
|
||||
if(name.charAt(0) !== "$" && name !== "title") {
|
||||
removeFields[name] = undefined;
|
||||
if(name in tiddler.fields) {
|
||||
hasChanged = true;
|
||||
}
|
||||
hasChanged = true;
|
||||
}
|
||||
});
|
||||
if(hasChanged) {
|
||||
var creationFields = this.actionTimestamp ? this.wiki.getCreationFields() : {};
|
||||
var modificationFields = this.actionTimestamp ? this.wiki.getModificationFields() : {};
|
||||
this.wiki.addTiddler(new $tw.Tiddler(creationFields,tiddler,removeFields,modificationFields));
|
||||
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,removeFields,this.wiki.getModificationFields()));
|
||||
}
|
||||
}
|
||||
return true; // Action was invoked
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
/*\
|
||||
title: $:/core/modules/widgets/data.js
|
||||
type: application/javascript
|
||||
module-type: widget
|
||||
|
||||
Widget to dynamically represent one or more tiddlers
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||
|
||||
var DataWidget = function(parseTreeNode,options) {
|
||||
this.dataWidgetTag = parseTreeNode.type;
|
||||
this.initialise(parseTreeNode,options);
|
||||
};
|
||||
|
||||
/*
|
||||
Inherit from the base widget class
|
||||
*/
|
||||
DataWidget.prototype = new Widget();
|
||||
|
||||
/*
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
DataWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
var jsonPayload = JSON.stringify(this.readDataTiddlerValues(),null,4);
|
||||
var textNode = this.document.createTextNode(jsonPayload);
|
||||
parent.insertBefore(textNode,nextSibling);
|
||||
this.domNodes.push(textNode);
|
||||
};
|
||||
|
||||
/*
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
DataWidget.prototype.execute = function() {
|
||||
// Construct the child widgets
|
||||
this.makeChildWidgets();
|
||||
};
|
||||
|
||||
/*
|
||||
Read the tiddler value(s) from a data widget – must be called after the .render() method
|
||||
*/
|
||||
DataWidget.prototype.readDataTiddlerValues = function() {
|
||||
var self = this;
|
||||
// Start with a blank object
|
||||
var item = Object.create(null);
|
||||
// Read any attributes not prefixed with $
|
||||
$tw.utils.each(this.attributes,function(value,name) {
|
||||
if(name.charAt(0) !== "$") {
|
||||
item[name] = value;
|
||||
}
|
||||
});
|
||||
item = new $tw.Tiddler(item);
|
||||
// Deal with $tiddler, $filter or $compound-tiddler attributes
|
||||
var tiddlers = [],title;
|
||||
if(this.hasAttribute("$tiddler")) {
|
||||
title = this.getAttribute("$tiddler");
|
||||
if(title) {
|
||||
var tiddler = this.wiki.getTiddler(title);
|
||||
if(tiddler) {
|
||||
tiddlers.push(tiddler);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(this.hasAttribute("$filter")) {
|
||||
var filter = this.getAttribute("$filter");
|
||||
if(filter) {
|
||||
var titles = this.wiki.filterTiddlers(filter);
|
||||
$tw.utils.each(titles,function(title) {
|
||||
var tiddler = self.wiki.getTiddler(title);
|
||||
tiddlers.push(tiddler);
|
||||
});
|
||||
}
|
||||
}
|
||||
if(this.hasAttribute("$compound-tiddler")) {
|
||||
title = this.getAttribute("$compound-tiddler");
|
||||
if(title) {
|
||||
tiddlers.push.apply(tiddlers,this.extractCompoundTiddler(title));
|
||||
}
|
||||
}
|
||||
// Convert the literal item to field strings
|
||||
item = item.getFieldStrings();
|
||||
if(tiddlers.length === 0) {
|
||||
if(Object.keys(item).length > 0 && !!item.title) {
|
||||
return [item];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
var results = [];
|
||||
$tw.utils.each(tiddlers,function(tiddler,index) {
|
||||
var fields = tiddler.getFieldStrings();
|
||||
results.push($tw.utils.extend({},fields,item));
|
||||
});
|
||||
return results;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Helper to extract tiddlers from text/vnd.tiddlywiki-multiple tiddlers
|
||||
*/
|
||||
DataWidget.prototype.extractCompoundTiddler = function(title) {
|
||||
var tiddler = this.wiki.getTiddler(title);
|
||||
if(tiddler && tiddler.fields.type === "text/vnd.tiddlywiki-multiple") {
|
||||
var text = tiddler.fields.text || "",
|
||||
rawTiddlers = text.split(/\r?\n\+\r?\n/),
|
||||
tiddlers = [];
|
||||
$tw.utils.each(rawTiddlers,function(rawTiddler) {
|
||||
var fields = Object.create(null),
|
||||
split = rawTiddler.split(/\r?\n\r?\n/mg);
|
||||
if(split.length >= 1) {
|
||||
fields = $tw.utils.parseFields(split[0],fields);
|
||||
}
|
||||
if(split.length >= 2) {
|
||||
fields.text = split.slice(1).join("\n\n");
|
||||
}
|
||||
tiddlers.push(new $tw.Tiddler(fields));
|
||||
});
|
||||
return tiddlers;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
DataWidget.prototype.refresh = function(changedTiddlers) {
|
||||
// It would be expensive to calculate whether the changedTiddlers impact the filter
|
||||
// identified by the $filter attribute so we just refresh ourselves unconditionally
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
};
|
||||
|
||||
exports.data = DataWidget;
|
||||
|
||||
})();
|
||||
@@ -1,165 +0,0 @@
|
||||
/*\
|
||||
title: $:/core/modules/widgets/testcase.js
|
||||
type: application/javascript
|
||||
module-type: widget
|
||||
|
||||
Widget to display a test case
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||
|
||||
var TestCaseWidget = function(parseTreeNode,options) {
|
||||
this.initialise(parseTreeNode,options);
|
||||
};
|
||||
|
||||
/*
|
||||
Inherit from the base widget class
|
||||
*/
|
||||
TestCaseWidget.prototype = new Widget();
|
||||
|
||||
/*
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
TestCaseWidget.prototype.render = function(parent,nextSibling) {
|
||||
var self = this;
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
// Create container DOM node
|
||||
var domNode = this.document.createElement("div");
|
||||
this.domNodes.push(domNode);
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
// Render the children into a hidden DOM node
|
||||
var parser = {
|
||||
tree: [{
|
||||
type: "widget",
|
||||
attributes: {},
|
||||
orderedAttributes: [],
|
||||
children: this.parseTreeNode.children || []
|
||||
}]
|
||||
};
|
||||
this.contentRoot = this.wiki.makeWidget(parser,{
|
||||
document: $tw.fakeDocument,
|
||||
parentWidget: this
|
||||
});
|
||||
this.contentContainer = $tw.fakeDocument.createElement("div");
|
||||
this.contentRoot.render(this.contentContainer,null);
|
||||
// Create a wiki
|
||||
this.testcaseWiki = new $tw.Wiki();
|
||||
// Always load the core plugin
|
||||
var loadTiddler = function(title) {
|
||||
var tiddler = self.wiki.getTiddler(title);
|
||||
if(tiddler) {
|
||||
self.testcaseWiki.addTiddler(tiddler);
|
||||
}
|
||||
}
|
||||
loadTiddler("$:/core");
|
||||
loadTiddler("$:/plugins/tiddlywiki/codemirror");
|
||||
// Load tiddlers from child data widgets
|
||||
var tiddlers = [];
|
||||
this.findChildrenDataWidgets(this.contentRoot.children,"data",function(widget) {
|
||||
Array.prototype.push.apply(tiddlers,widget.readDataTiddlerValues());
|
||||
});
|
||||
var jsonPayload = JSON.stringify(tiddlers);
|
||||
this.testcaseWiki.addTiddlers(tiddlers);
|
||||
// Unpack plugin tiddlers
|
||||
this.testcaseWiki.readPluginInfo();
|
||||
this.testcaseWiki.registerPluginTiddlers("plugin");
|
||||
this.testcaseWiki.unpackPluginTiddlers();
|
||||
this.testcaseWiki.addIndexersToWiki();
|
||||
// Generate a `transclusion` variable that depends on the values of the payload tiddlers so that the template can easily make unique state tiddlers
|
||||
this.setVariable("transclusion",$tw.utils.hashString(jsonPayload));
|
||||
// Generate a `payloadTiddlers` variable that contains the payload in JSON format
|
||||
this.setVariable("payloadTiddlers",jsonPayload);
|
||||
// Only run the tests if the testcase output and expected results were specified, and those tiddlers actually exist in the wiki
|
||||
var shouldRunTests = false;
|
||||
if(this.testcaseTestOutput && this.testcaseWiki.tiddlerExists(this.testcaseTestOutput) && this.testcaseTestExpectedResult && this.testcaseWiki.tiddlerExists(this.testcaseTestExpectedResult)) {
|
||||
shouldRunTests = true;
|
||||
}
|
||||
// Render the test rendering if required
|
||||
if(shouldRunTests) {
|
||||
var testcaseOutputContainer = $tw.fakeDocument.createElement("div");
|
||||
var testcaseOutputWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTestOutput,{
|
||||
document: $tw.fakeDocument,
|
||||
parseAsInline: false,
|
||||
parentWidget: this,
|
||||
variables: {
|
||||
currentTiddler: this.testcaseTestOutput
|
||||
}
|
||||
});
|
||||
testcaseOutputWidget.render(testcaseOutputContainer);
|
||||
}
|
||||
// Clear changes queue
|
||||
this.testcaseWiki.clearTiddlerEventQueue();
|
||||
// Run the actions if provided
|
||||
if(this.testcaseWiki.tiddlerExists(this.testcaseTestActions)) {
|
||||
testcaseOutputWidget.invokeActionString(this.testcaseWiki.getTiddlerText(this.testcaseTestActions));
|
||||
testcaseOutputWidget.refresh(this.testcaseWiki.changedTiddlers,testcaseOutputContainer);
|
||||
}
|
||||
// Set up the test result variables
|
||||
var testResult = "",
|
||||
outputHTML = "",
|
||||
expectedHTML = "";
|
||||
if(shouldRunTests) {
|
||||
outputHTML = testcaseOutputContainer.children[0].innerHTML;
|
||||
expectedHTML = this.testcaseWiki.getTiddlerText(this.testcaseTestExpectedResult);
|
||||
if(outputHTML === expectedHTML) {
|
||||
testResult = "pass";
|
||||
} else {
|
||||
testResult = "fail";
|
||||
}
|
||||
this.setVariable("outputHTML",outputHTML);
|
||||
this.setVariable("expectedHTML",expectedHTML);
|
||||
this.setVariable("testResult",testResult);
|
||||
this.setVariable("currentTiddler",this.testcaseTestOutput);
|
||||
}
|
||||
// Don't display anything if testHideIfPass is "yes" and the tests have passed
|
||||
if(this.testcaseHideIfPass === "yes" && testResult !== "fail") {
|
||||
return;
|
||||
}
|
||||
// Render the page root template of the subwiki
|
||||
var rootWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTemplate,{
|
||||
document: this.document,
|
||||
parseAsInline: false,
|
||||
parentWidget: this
|
||||
});
|
||||
rootWidget.render(domNode);
|
||||
// Trap changes in the wiki and refresh the rendering
|
||||
this.testcaseWiki.addEventListener("change",function(changes) {
|
||||
rootWidget.refresh(changes,domNode);
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
TestCaseWidget.prototype.execute = function() {
|
||||
this.testcaseTemplate = this.getAttribute("template","$:/core/ui/testcases/DefaultTemplate");
|
||||
this.testcaseTestOutput = this.getAttribute("testOutput");
|
||||
this.testcaseTestActions = this.getAttribute("testActions");
|
||||
this.testcaseTestExpectedResult = this.getAttribute("testExpectedResult");
|
||||
this.testcaseHideIfPass = this.getAttribute("testHideIfPass");
|
||||
};
|
||||
|
||||
/*
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
TestCaseWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if($tw.utils.count(changedAttributes) > 0) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else {
|
||||
return this.contentRoot.refresh(changedTiddlers);
|
||||
}
|
||||
};
|
||||
|
||||
exports["testcase"] = TestCaseWidget;
|
||||
|
||||
})();
|
||||
@@ -30,30 +30,7 @@ TranscludeWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
try {
|
||||
this.renderChildren(parent,nextSibling);
|
||||
} catch(error) {
|
||||
if(error instanceof $tw.utils.TranscludeRecursionError) {
|
||||
// We were infinite looping.
|
||||
// We need to try and abort as much of the loop as we can, so we will keep "throwing" upward until we find a transclusion that has a different signature.
|
||||
// Hopefully that will land us just outside where the loop began. That's where we want to issue an error.
|
||||
// Rendering widgets beneath this point may result in a freezing browser if they explode exponentially.
|
||||
var transcludeSignature = this.getVariable("transclusion");
|
||||
if(this.getAncestorCount() > $tw.utils.TranscludeRecursionError.MAX_WIDGET_TREE_DEPTH - 50) {
|
||||
// For the first fifty transcludes we climb up, we simply collect signatures.
|
||||
// We're assuming that those first 50 will likely include all transcludes involved in the loop.
|
||||
error.signatures[transcludeSignature] = true;
|
||||
} else if(!error.signatures[transcludeSignature]) {
|
||||
// Now that we're past the first 50, let's look for the first signature that wasn't in the loop. That'll be where we print the error and resume rendering.
|
||||
this.children = [this.makeChildWidget({type: "error", attributes: {
|
||||
"$message": {type: "string", value: $tw.language.getString("Error/RecursiveTransclusion")}
|
||||
}})];
|
||||
this.renderChildren(parent,nextSibling);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
this.renderChildren(parent,nextSibling);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -12,6 +12,9 @@ Widget base class
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/* Maximum permitted depth of the widget tree for recursion detection */
|
||||
var MAX_WIDGET_TREE_DEPTH = 1000;
|
||||
|
||||
/*
|
||||
Create a widget object for a parse tree node
|
||||
parseTreeNode: reference to the parse tree node to be rendered
|
||||
@@ -163,8 +166,6 @@ Widget.prototype.getVariableInfo = function(name,options) {
|
||||
});
|
||||
resultList = this.wiki.filterTiddlers(value,this.makeFakeWidgetWithVariables(variables),options.source);
|
||||
value = resultList[0] || "";
|
||||
} else {
|
||||
params = variable.params;
|
||||
}
|
||||
return {
|
||||
text: value,
|
||||
@@ -493,8 +494,10 @@ Widget.prototype.makeChildWidgets = function(parseTreeNodes,options) {
|
||||
this.children = [];
|
||||
var self = this;
|
||||
// Check for too much recursion
|
||||
if(this.getAncestorCount() > $tw.utils.TranscludeRecursionError.MAX_WIDGET_TREE_DEPTH) {
|
||||
throw new $tw.utils.TranscludeRecursionError();
|
||||
if(this.getAncestorCount() > MAX_WIDGET_TREE_DEPTH) {
|
||||
this.children.push(this.makeChildWidget({type: "error", attributes: {
|
||||
"$message": {type: "string", value: $tw.language.getString("Error/RecursiveTransclusion")}
|
||||
}}));
|
||||
} else {
|
||||
// Create set variable widgets for each variable
|
||||
$tw.utils.each(options.variables,function(value,name) {
|
||||
@@ -810,21 +813,6 @@ Widget.prototype.allowActionPropagation = function() {
|
||||
return true;
|
||||
};
|
||||
|
||||
/*
|
||||
Find child <$data> widgets recursively. The tag name allows aliased versions of the widget to be found too
|
||||
*/
|
||||
Widget.prototype.findChildrenDataWidgets = function(children,tag,callback) {
|
||||
var self = this;
|
||||
$tw.utils.each(children,function(child) {
|
||||
if(child.dataWidgetTag === tag) {
|
||||
callback(child);
|
||||
}
|
||||
if(child.children) {
|
||||
self.findChildrenDataWidgets(child.children,tag,callback);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
@@ -95,9 +95,6 @@ table-footer-background: #a8a8a8
|
||||
table-header-background: #f0f0f0
|
||||
tag-background: #ec6
|
||||
tag-foreground: #ffffff
|
||||
testcase-accent-level-1: #84C5E6
|
||||
testcase-accent-level-2: #E3B740
|
||||
testcase-accent-level-3: #5FD564
|
||||
tiddler-background: <<colour background>>
|
||||
tiddler-border: <<colour background>>
|
||||
tiddler-controls-foreground-hover: #888888
|
||||
|
||||
@@ -5,6 +5,5 @@
|
||||
"author": "JeremyRuston",
|
||||
"core-version": ">=5.0.0",
|
||||
"plugin-priority": "0",
|
||||
"list": "readme",
|
||||
"stability": "STABILITY_2_STABLE"
|
||||
"list": "readme"
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ title: $:/core/save/all-external-js
|
||||
\whitespace trim
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
\define saveTiddlerFilter()
|
||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
||||
[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 -->
|
||||
|
||||
@@ -3,7 +3,7 @@ title: $:/core/save/offline-external-js
|
||||
\whitespace trim
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
\define saveTiddlerFilter()
|
||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
||||
[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
|
||||
\define defaultCoreURL() tiddlywikicore-$(version)$.js
|
||||
<$let coreURL={{{ [[coreURL]is[variable]then<coreURL>else<defaultCoreURL>] }}}>
|
||||
|
||||
@@ -2,6 +2,6 @@ title: $:/core/save/all
|
||||
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
\define saveTiddlerFilter()
|
||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
||||
[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
|
||||
{{$:/core/templates/tiddlywiki5.html}}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
title: $:/core/save/empty
|
||||
|
||||
\define saveTiddlerFilter()
|
||||
[is[system]] -[prefix[$:/state/popup/]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]
|
||||
[is[system]] -[prefix[$:/state/popup/]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]
|
||||
\end
|
||||
{{$:/core/templates/tiddlywiki5.html}}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
title: $:/core/save/lazy-all
|
||||
|
||||
\define saveTiddlerFilter()
|
||||
[is[system]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] [is[tiddler]type[application/javascript]] +[sort[title]]
|
||||
[is[system]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] [is[tiddler]type[application/javascript]] +[sort[title]]
|
||||
\end
|
||||
\define skinnySaveTiddlerFilter()
|
||||
[!is[system]] -[type[application/javascript]]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
title: $:/core/save/lazy-images
|
||||
|
||||
\define saveTiddlerFilter()
|
||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[!is[system]is[image]] +[sort[title]]
|
||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[!is[system]is[image]] +[sort[title]]
|
||||
\end
|
||||
\define skinnySaveTiddlerFilter()
|
||||
[!is[system]is[image]]
|
||||
|
||||
@@ -45,17 +45,7 @@ $:/config/Plugins/Disabled/$(currentTiddler)$
|
||||
<$view field="title"/>
|
||||
</h2>
|
||||
<h2>
|
||||
<div>
|
||||
<%if [<currentTiddler>get[stability]match[STABILITY_0_DEPRECATED]] %>
|
||||
<span class="tc-plugin-info-stability tc-plugin-info-stability-deprecated">DEPRECATED</span>
|
||||
<%elseif [<currentTiddler>get[stability]match[STABILITY_1_EXPERIMENTAL]] %>
|
||||
<span class="tc-plugin-info-stability tc-plugin-info-stability-experimental">EXPERIMENTAL</span>
|
||||
<%elseif [<currentTiddler>get[stability]match[STABILITY_2_STABLE]] %>
|
||||
<span class="tc-plugin-info-stability tc-plugin-info-stability-stable">STABLE</span>
|
||||
<%elseif [<currentTiddler>get[stability]match[STABILITY_3_LEGACY]] %>
|
||||
<span class="tc-plugin-info-stability tc-plugin-info-stability-legacy">LEGACY</span>
|
||||
<%endif%>
|
||||
<em><$view field="version"/></em></div>
|
||||
<div><em><$view field="version"/></em></div>
|
||||
</h2>
|
||||
</div>
|
||||
\end
|
||||
|
||||
@@ -70,20 +70,9 @@ $:/state/add-plugin-info/$(connectionTiddler)$/$(assetInfo)$
|
||||
<div class="tc-plugin-info-chunk tc-plugin-info-description">
|
||||
<h1><strong><$text text={{{ [<assetInfo>get[name]] ~[<assetInfo>get[original-title]split[/]last[1]] }}}/></strong>:
|
||||
 
|
||||
<$view tiddler=<<assetInfo>> field="description"/>
|
||||
</h1>
|
||||
<$view tiddler=<<assetInfo>> field="description"/></h1>
|
||||
<h2><$view tiddler=<<assetInfo>> field="original-title"/></h2>
|
||||
<div>
|
||||
<%if [<assetInfo>get[stability]match[STABILITY_0_DEPRECATED]] %>
|
||||
<span class="tc-plugin-info-stability tc-plugin-info-stability-deprecated">DEPRECATED</span>
|
||||
<%elseif [<assetInfo>get[stability]match[STABILITY_1_EXPERIMENTAL]] %>
|
||||
<span class="tc-plugin-info-stability tc-plugin-info-stability-experimental">EXPERIMENTAL</span>
|
||||
<%elseif [<assetInfo>get[stability]match[STABILITY_2_STABLE]] %>
|
||||
<span class="tc-plugin-info-stability tc-plugin-info-stability-stable">STABLE</span>
|
||||
<%elseif [<assetInfo>get[stability]match[STABILITY_3_LEGACY]] %>
|
||||
<span class="tc-plugin-info-stability tc-plugin-info-stability-legacy">LEGACY</span>
|
||||
<%endif%>
|
||||
<em><$view tiddler=<<assetInfo>> field="version"/></em></div>
|
||||
<div><em><$view tiddler=<<assetInfo>> field="version"/></em></div>
|
||||
<$list filter="[<assetInfo>get[original-title]get[version]]" variable="installedVersion"><div><em>{{$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint}}</em></div></$list>
|
||||
</div>
|
||||
<div class="tc-plugin-info-chunk tc-plugin-info-buttons">
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
title: $:/core/ui/ControlPanel/TestCases
|
||||
tags: $:/tags/ControlPanel/Advanced
|
||||
caption: {{$:/language/ControlPanel/TestCases/Caption}}
|
||||
|
||||
\whitespace trim
|
||||
{{$:/language/ControlPanel/TestCases/Hint}}
|
||||
|
||||
<div class="tc-control-panel">
|
||||
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/TestCases]!has[draft.of]]" default="$:/core/ui/ControlPanel/TestCases/All"/>
|
||||
</div>
|
||||
@@ -1,24 +0,0 @@
|
||||
title: $:/core/ui/ControlPanel/TestCases/All
|
||||
tags: $:/tags/ControlPanel/TestCases
|
||||
caption: {{$:/language/ControlPanel/TestCases/All/Caption}}
|
||||
|
||||
\define lingo-base() $:/language/ControlPanel/
|
||||
<<lingo TestCases/All/Hint>>
|
||||
|
||||
<$list filter="[all[tiddlers+shadows]tag[$:/tags/wiki-test-spec]type[text/vnd.tiddlywiki-multiple]] [all[tiddlers+shadows]tag[$:/tags/wiki-test-spec-failing]type[text/vnd.tiddlywiki-multiple]]">
|
||||
|
||||
<h2>
|
||||
|
||||
<$link>
|
||||
|
||||
<$text text=<<currentTiddler>>/>
|
||||
|
||||
</$link>
|
||||
|
||||
</h2>
|
||||
|
||||
<$transclude
|
||||
$tiddler="$:/core/ui/TestCaseTemplate"
|
||||
/>
|
||||
|
||||
</$list>
|
||||
@@ -1,15 +0,0 @@
|
||||
title: $:/core/ui/ControlPanel/TestCases/Failed
|
||||
tags: $:/tags/ControlPanel/TestCases
|
||||
caption: {{$:/language/ControlPanel/TestCases/Failed/Caption}}
|
||||
|
||||
\define lingo-base() $:/language/ControlPanel/
|
||||
<<lingo TestCases/Failed/Hint>>
|
||||
|
||||
<$list filter="[all[tiddlers+shadows]tag[$:/tags/wiki-test-spec]type[text/vnd.tiddlywiki-multiple]] [all[tiddlers+shadows]tag[$:/tags/wiki-test-spec-failing]type[text/vnd.tiddlywiki-multiple]]">
|
||||
|
||||
<$transclude
|
||||
$tiddler="$:/core/ui/TestCaseTemplate"
|
||||
hideIfPass="yes"
|
||||
/>
|
||||
|
||||
</$list>
|
||||
@@ -1,5 +0,0 @@
|
||||
title: $:/core/ui/KeyboardShortcuts/refresh
|
||||
tags: $:/tags/KeyboardShortcut
|
||||
key: ((refresh))
|
||||
|
||||
<$action-sendmessage $message="tm-browser-refresh"/>
|
||||
@@ -1,14 +1,16 @@
|
||||
title: $:/core/ui/PageTemplate/pagecontrols
|
||||
|
||||
\whitespace trim
|
||||
\function config-title() [[$:/config/PageControlButtons/Visibility/$(listItem)$]substitute[]]
|
||||
\define config-title() $:/config/PageControlButtons/Visibility/$(listItem)$
|
||||
|
||||
<div class="tc-page-controls">
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]" variable="listItem">
|
||||
<$list filter="[<config-title>!text[hide]]" storyview="pop" variable="ignore">
|
||||
<$let tv-config-toolbar-class={{{ [enlist<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]] +[join[ ]] }}}>
|
||||
<$transclude $tiddler=<<listItem>> $mode="inline"/>
|
||||
</$let>
|
||||
</$list>
|
||||
<$set name="hidden" value=<<config-title>>>
|
||||
<$list filter="[<hidden>!text[hide]]" storyview="pop" variable="ignore">
|
||||
<$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]">
|
||||
<$transclude tiddler=<<listItem>> mode="inline"/>
|
||||
</$set>
|
||||
</$list>
|
||||
</$set>
|
||||
</$list>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
title: $:/core/ui/TestCaseTemplate
|
||||
|
||||
\parameters (hideIfPass:"no")
|
||||
\whitespace trim
|
||||
<$let
|
||||
linkTarget="yes"
|
||||
displayFormat={{!!display-format}}
|
||||
testcaseTiddler=<<currentTiddler>>
|
||||
>
|
||||
<$testcase
|
||||
testOutput="Output"
|
||||
testExpectedResult="ExpectedResult"
|
||||
testActions="Actions"
|
||||
testHideIfPass=<<hideIfPass>>
|
||||
>
|
||||
<$data $compound-tiddler=<<currentTiddler>>/>
|
||||
<$data title="Description" text={{!!description}}/>
|
||||
</$testcase>
|
||||
</$let>
|
||||
@@ -1,66 +0,0 @@
|
||||
title: $:/core/ui/testcases/DefaultTemplate
|
||||
|
||||
\whitespace trim
|
||||
\procedure linkcatcherActions()
|
||||
<%if [<navigateTo>has[title]] %>
|
||||
<$qualify title=<<state>> name="qualifiedState">
|
||||
<$action-setfield $tiddler=<<qualifiedState>> text=<<navigateTo>>/>
|
||||
</$qualify>
|
||||
<%endif%>
|
||||
\end
|
||||
|
||||
<$let
|
||||
state={{{ [<qualify "$:/state/testcase">] }}}
|
||||
>
|
||||
<div class="tc-test-case-wrapper">
|
||||
<div class="tc-test-case-header">
|
||||
<h2>
|
||||
<$genesis $type={{{ [<linkTarget>!match[]then[$link]else[div]] }}} to=<<testcaseTiddler>>>
|
||||
<%if [<testResult>!match[]] %>
|
||||
<span class={{{ tc-test-case-result-icon [<testResult>!match[fail]then[tc-test-case-result-icon-pass]] [<testResult>match[fail]then[tc-test-case-result-icon-fail]] +[join[ ]] }}}>
|
||||
<%if [<testResult>!match[fail]] %>
|
||||
{{$:/core/images/done-button}}
|
||||
<%else%>
|
||||
{{$:/core/images/close-button}}
|
||||
<%endif%>
|
||||
</span>
|
||||
<%endif%>
|
||||
<$view tiddler="Description" mode="inline"/>
|
||||
</$genesis>
|
||||
</h2>
|
||||
</div>
|
||||
<%if [[Narrative]is[tiddler]] %>
|
||||
<div class="tc-test-case-narrative">
|
||||
<$transclude $tiddler="Narrative" mode="block"/>
|
||||
</div>
|
||||
<%endif%>
|
||||
<%if [<testResult>match[fail]] %>
|
||||
<div class="tc-test-case-result-fail">
|
||||
<div class="tc-test-case-result-fail-header">
|
||||
TEST FAILED
|
||||
</div>
|
||||
<div class="tc-test-case-result-fail-body">
|
||||
<$diff-text source=<<expectedHTML>> dest=<<outputHTML>>/>
|
||||
</div>
|
||||
</div>
|
||||
<%endif%>
|
||||
<div class="tc-test-case-panes">
|
||||
<div class="tc-test-case-source">
|
||||
<$macrocall $name="tabs" tabsList="[all[tiddlers]sort[]] -[prefix<state>] -Description -Narrative -ExpectedResult -Output Output +[putfirst[]] -[has[plugin-type]]" state=<<state>> default="Output" template="$:/core/ui/testcases/DefaultTemplate/SourceTabs"/>
|
||||
</div>
|
||||
<div class="tc-test-case-divider">
|
||||
</div>
|
||||
<div class="tc-test-case-output">
|
||||
<%if [<displayFormat>!match[]else[wikitext]match[plaintext]] %>
|
||||
<pre><$view tiddler="Output" format="plainwikified" mode="block"/></pre>
|
||||
<%else%>
|
||||
<$linkcatcher actions=<<linkcatcherActions>>>
|
||||
<$tiddler tiddler="Output">
|
||||
<$transclude $tiddler="Output" $mode="block"/>
|
||||
</$tiddler>
|
||||
</$linkcatcher>
|
||||
<%endif%>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</$let>
|
||||
@@ -1,24 +0,0 @@
|
||||
title: $:/core/ui/testcases/DefaultTemplate/SourceTabs
|
||||
|
||||
\whitespace trim
|
||||
\procedure body()
|
||||
<$list filter="[<currentTab>fields[]] -text +[limit[1]]" variable="ignore">
|
||||
<table class="tc-field-table">
|
||||
<tbody>
|
||||
<$list filter="[<currentTab>fields[]sort[]] -text -title title +[putfirst[]]" variable="fieldName">
|
||||
<tr>
|
||||
<td>
|
||||
<$text text=<<fieldName>>/>
|
||||
</td>
|
||||
<td>
|
||||
<$view tiddler=<<currentTab>> field=<<fieldName>>/>
|
||||
</td>
|
||||
</tr>
|
||||
</$list>
|
||||
</tbody>
|
||||
</table>
|
||||
</$list>
|
||||
<$edit class="tc-edit-texteditor" tiddler=<<currentTab>>/>
|
||||
\end
|
||||
|
||||
<$transclude $variable="body" $mode="inline"/>
|
||||
@@ -1,4 +0,0 @@
|
||||
title: $:/core/ui/testcases/RawJSONTemplate
|
||||
|
||||
\whitespace trim
|
||||
<$text text=<<payloadTiddlers>>/>
|
||||
@@ -1,6 +1,6 @@
|
||||
title: $:/config/OfficialPluginLibrary
|
||||
tags: $:/tags/PluginLibrary
|
||||
url: https://tiddlywiki.com/library/v5.3.4/index.html
|
||||
url: https://tiddlywiki.com/library/v5.3.3/index.html
|
||||
caption: {{$:/language/OfficialPluginLibrary}}
|
||||
|
||||
{{$:/language/OfficialPluginLibrary/Hint}}
|
||||
|
||||
@@ -35,7 +35,6 @@ new-tiddler: {{$:/language/Buttons/NewTiddler/Hint}}
|
||||
picture: {{$:/language/Buttons/Picture/Hint}}
|
||||
preview: {{$:/language/Buttons/Preview/Hint}}
|
||||
quote: {{$:/language/Buttons/Quote/Hint}}
|
||||
refresh: {{$:/language/Buttons/Refresh/Hint}}
|
||||
save-tiddler: {{$:/language/Buttons/Save/Hint}}
|
||||
save-wiki: {{$:/language/Buttons/SaveWiki/Hint}}
|
||||
sidebar-search: {{$:/language/Buttons/SidebarSearch/Hint}}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
title: $:/config/ViewTemplateBodyFilters/
|
||||
tags: $:/tags/ViewTemplateBodyFilter
|
||||
|
||||
testcase: [tag[$:/tags/wiki-test-spec]type[text/vnd.tiddlywiki-multiple]then[$:/core/ui/TestCaseTemplate]] [tag[$:/tags/wiki-test-spec-failing]type[text/vnd.tiddlywiki-multiple]then[$:/core/ui/TestCaseTemplate]]
|
||||
stylesheet: [tag[$:/tags/Stylesheet]then[$:/core/ui/ViewTemplate/body/rendered-plain-text]]
|
||||
core-ui-tags: [tag[$:/tags/PageTemplate]] [tag[$:/tags/EditTemplate]] [tag[$:/tags/ViewTemplate]] [tag[$:/tags/KeyboardShortcut]] [tag[$:/tags/ImportPreview]] [tag[$:/tags/EditPreview]][tag[$:/tags/EditorToolbar]] [tag[$:/tags/Actions]] :then[[$:/core/ui/ViewTemplate/body/code]]
|
||||
system: [prefix[$:/boot/]] [prefix[$:/config/]] [prefix[$:/core/macros]] [prefix[$:/core/save/]] [prefix[$:/core/templates/]] [prefix[$:/info/]] [prefix[$:/language/]] [prefix[$:/languages/]] [prefix[$:/snippets/]] [prefix[$:/state/]] [prefix[$:/status/]] [prefix[$:/info/]] [prefix[$:/temp/]] +[!is[image]limit[1]then[$:/core/ui/ViewTemplate/body/code]]
|
||||
|
||||
@@ -6,5 +6,4 @@ underline: meta-U
|
||||
new-image: ctrl-I
|
||||
new-journal: ctrl-J
|
||||
new-tiddler: ctrl-N
|
||||
refresh: meta-R
|
||||
save-wiki: meta-S
|
||||
|
||||
@@ -6,4 +6,3 @@ underline: ctrl-U
|
||||
new-image: alt-I
|
||||
new-journal: alt-J
|
||||
new-tiddler: alt-N
|
||||
refresh: ctrl-R
|
||||
|
||||
@@ -1,182 +1,167 @@
|
||||
title: $:/core/macros/tag-picker
|
||||
tags: tags: $:/tags/Macro $:/tags/Global
|
||||
first-search-filter: [subfilter<tagListFilter>!is[system]search:title<userInput>sort[]]
|
||||
second-search-filter: [subfilter<tagListFilter>is[system]search:title<userInput>sort[]]
|
||||
tags: $:/tags/Macro $:/tags/Global
|
||||
first-search-filter: [tags[]!is[system]search:title<userInput>sort[]]
|
||||
second-search-filter: [tags[]is[system]search:title<userInput>sort[]]
|
||||
|
||||
<!-- first-search-filter and second-search-filter fields are not used here in the code, but they are defined as parameters for keyboard-driven-input macro -->
|
||||
|
||||
\whitespace trim
|
||||
|
||||
<!-- tf.tagpicker-dropdown-id is needed if several tap-pickers are shown in one tiddler -->
|
||||
\function tf.tagpicker-dropdown-id()
|
||||
[<qualify $:/state/popup/tags-auto-complete>]
|
||||
[[$(saveTiddler)$-[$(tagField)$-$(tagListFilter)$]substitute[]sha256[]] +[join[/]]
|
||||
\procedure get-tagpicker-focus-selector()
|
||||
\function currentTiddlerCSSEscaped() [<saveTiddler>escapecss[]]
|
||||
[data-tiddler-title=`$(currentTiddlerCSSEscaped)$`] .tc-add-tag-name input
|
||||
\end
|
||||
|
||||
\function tf.tagpicker-dropdown-class() [<tf.tagpicker-dropdown-id>sha256[]addprefix[tc-]]
|
||||
\function tf.get-tagpicker-focus-selector() [<tf.tagpicker-dropdown-class>addprefix[.]] .tc-popup-handle +[join[ ]]
|
||||
\procedure delete-tag-state-tiddlers() <$action-deletetiddler $filter="[<newTagNameTiddler>] [<storeTitle>] [<tagSelectionState>]"/>
|
||||
|
||||
<!-- clean up temporary tiddlers, so the next "pick" starts with a clean input -->
|
||||
<!-- This could probably be optimized / removed if we would use different temp-tiddlers
|
||||
(future improvement because keeping track is comlex for humans)
|
||||
-->
|
||||
\procedure delete-tag-state-tiddlers()
|
||||
<$action-deletetiddler $filter="[<newTagNameTiddler>] [<storeTitle>] [<tagSelectionState>]"/>
|
||||
\end
|
||||
|
||||
<!-- trigger __toggle tag__ by keyboard -->
|
||||
\procedure add-tag-actions()
|
||||
<$let tag=<<_tf.getTag>> >
|
||||
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter='+[toggle<tag>trim[]]'/>
|
||||
<% if [<tag>] :intersection[<saveTiddler>get<tagField>enlist-input[]] %>
|
||||
<!-- tag has been removed - do nothing -->
|
||||
<% else %>
|
||||
<<actions>>
|
||||
<% endif %>
|
||||
<<delete-tag-state-tiddlers>>
|
||||
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
||||
\whitespace trim
|
||||
<$let tag=<<tag>>>
|
||||
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter='+[toggle<tag>trim[]]'/>
|
||||
<$list
|
||||
filter="[<tag>] :intersection[<saveTiddler>get<tagField>enlist-input[]]"
|
||||
variable="ignore"
|
||||
emptyMessage="<<actions>>"
|
||||
/>
|
||||
</$let>
|
||||
<<delete-tag-state-tiddlers>>
|
||||
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
||||
\end
|
||||
<!-- <$action-log /> -->
|
||||
|
||||
<!-- ESC key removes the text from the input
|
||||
The second ESC tries to close the "draft tiddler"
|
||||
-->
|
||||
\procedure clear-tags-actions-inner()
|
||||
<% if [<storeTitle>has[text]] ~[<newTagNameTiddler>has[text]] %>
|
||||
\whitespace trim
|
||||
<$list
|
||||
filter="[<storeTitle>has[text]] ~[<newTagNameTiddler>has[text]]"
|
||||
variable="ignore"
|
||||
emptyMessage="<<cancel-delete-tiddler-actions 'cancel'>>"
|
||||
>
|
||||
<<delete-tag-state-tiddlers>>
|
||||
<% else %>
|
||||
<<cancel-delete-tiddler-actions "cancel">>
|
||||
<% endif %>
|
||||
</$list>
|
||||
\end
|
||||
|
||||
<!-- triggered by keyboard only -->
|
||||
\procedure clear-tags-actions()
|
||||
<$let userInput=<<_tf.getUserInput>> >
|
||||
<!-- this list __cannot__ be transformed to conditional IF. The list variable is used! -->
|
||||
<$list filter="[<newTagNameTiddler>get[text]!match<userInput>]" >
|
||||
<$list-empty>
|
||||
<<clear-tags-actions-inner>>
|
||||
</$list-empty>
|
||||
\whitespace trim
|
||||
<$let userInput=<<userInput>>>
|
||||
<$list
|
||||
filter="[<newTagNameTiddler>get[text]!match<userInput>]"
|
||||
emptyMessage="<<clear-tags-actions-inner>>"
|
||||
>
|
||||
<$action-setfield $tiddler=<<newTagNameTiddler>> text=<<userInput>>/>
|
||||
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
||||
</$list>
|
||||
</$let>
|
||||
\end
|
||||
|
||||
<!-- similar to add-tag-actions __but__ add-only -->
|
||||
\procedure add-button-actions()
|
||||
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter="[<tag>trim[]]"/>
|
||||
<<actions>>
|
||||
<<delete-tag-state-tiddlers>>
|
||||
<$action-sendmessage $message="tm-focus-selector" $param=<<tf.get-tagpicker-focus-selector>>/>
|
||||
\end
|
||||
<!-- <$action-log /> -->
|
||||
|
||||
<!-- create dropdown list -->
|
||||
\procedure tag-picker-listTags(filter, suffix)
|
||||
<$let userInput=<<_tf.getUserInput>> >
|
||||
<$list filter="[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]"
|
||||
emptyMessage="<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>" variable="listItem"
|
||||
>
|
||||
<$list filter=<<filter>> variable="tag">
|
||||
<!-- The buttonClasses filter is used to define tc-tag-button-selected state -->
|
||||
<!-- tf.get-tagpicker-focus-selector has to be resolved for $:/core/ui/TagPickerTagTemplate,
|
||||
othwerwise qualify in tf.tagpicker-dropdown-id causes problems -->
|
||||
<$let currentTiddler=<<tag>>
|
||||
button-classes=`tc-btn-invisible ${[<tag>addsuffix<suffix>] -[<tagSelectionState>get[text]] :then[[]] ~tc-tag-button-selected }$`
|
||||
get-tagpicker-focus-selector=`${[<tf.get-tagpicker-focus-selector>]}$`
|
||||
>
|
||||
{{||$:/core/ui/TagPickerTagTemplate}}
|
||||
</$let>
|
||||
</$list>
|
||||
</$list>
|
||||
</$let>
|
||||
<$action-sendmessage $message="tm-focus-selector" $param=<<get-tagpicker-focus-selector>>/>
|
||||
\end
|
||||
|
||||
<!-- tag-picker-inner is the main function -->
|
||||
\procedure tag-picker-inner()
|
||||
<div class={{{ [[tc-edit-add-tag]] [<tf.tagpicker-dropdown-class>] +[join[ ]] }}}>
|
||||
<div class="tc-edit-add-tag-ui">
|
||||
<span class="tc-add-tag-name tc-small-gap-right">
|
||||
<$macrocall $name="keyboard-driven-input"
|
||||
tiddler=<<newTagNameTiddler>>
|
||||
storeTitle=<<storeTitle>>
|
||||
refreshTitle=<<refreshTitle>>
|
||||
selectionStateTitle=<<tagSelectionState>>
|
||||
inputAcceptActions=<<add-tag-actions>>
|
||||
inputCancelActions=<<clear-tags-actions>>
|
||||
tag="input"
|
||||
placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}}
|
||||
focusPopup=<<tf.tagpicker-dropdown-id>>
|
||||
class="tc-edit-texteditor tc-popup-handle"
|
||||
tabindex=<<tabIndex>>
|
||||
focus={{{ [{$:/config/AutoFocus}match[tags]then[true]] ~[[false]] }}}
|
||||
filterMinLength={{$:/config/Tags/MinLength}}
|
||||
cancelPopups=<<cancelPopups>>
|
||||
configTiddlerFilter="[[$:/core/macros/tag-picker]]"
|
||||
/>
|
||||
</span>
|
||||
<$button popup=<<tf.tagpicker-dropdown-id>> class="tc-btn-invisible tc-btn-dropdown"
|
||||
tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}}
|
||||
\procedure list-tags(filter, suffix)
|
||||
\whitespace trim
|
||||
<$list
|
||||
filter="[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]"
|
||||
emptyMessage="<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>" variable="listItem"
|
||||
>
|
||||
<$list filter=<<filter>> variable="tag">
|
||||
<$let
|
||||
button-classes=`tc-btn-invisible ${ [<tag>addsuffix<suffix>] -[<tagSelectionState>get[text]] :then[[]] ~tc-tag-button-selected }$`
|
||||
currentTiddler=<<tag>>
|
||||
>
|
||||
{{$:/core/images/down-arrow}}
|
||||
</$button>
|
||||
<% if [<storeTitle>has[text]] %>
|
||||
<$button actions=<<delete-tag-state-tiddlers>> class="tc-btn-invisible tc-small-gap tc-btn-dropdown"
|
||||
tooltip={{$:/language/EditTemplate/Tags/ClearInput/Hint}} aria-label={{$:/language/EditTemplate/Tags/ClearInput/Caption}}
|
||||
>
|
||||
{{$:/core/images/close-button}}
|
||||
</$button>
|
||||
<% endif %>
|
||||
<span class="tc-add-tag-button tc-small-gap-left">
|
||||
<$let tag=<<_tf.getTag>>>
|
||||
<$button set=<<newTagNameTiddler>> actions=<<add-button-actions>> >
|
||||
{{$:/language/EditTemplate/Tags/Add/Button}}
|
||||
</$button>
|
||||
</$let>
|
||||
</span>
|
||||
</div>
|
||||
<div class="tc-block-dropdown-wrapper">
|
||||
<% if [<tf.tagpicker-dropdown-id>has[text]] %>
|
||||
<div class="tc-block-dropdown tc-block-tags-dropdown">
|
||||
<$macrocall $name="tag-picker-listTags" filter=<<nonSystemTagsFilter>> suffix="-primaryList" />
|
||||
<hr>
|
||||
<$macrocall $name="tag-picker-listTags" filter=<<systemTagsFilter>> suffix="-secondaryList" />
|
||||
</div>
|
||||
<% endif %>
|
||||
</div>
|
||||
</div>
|
||||
{{||$:/core/ui/TagPickerTagTemplate}}
|
||||
</$let>
|
||||
</$list>
|
||||
</$list>
|
||||
\end
|
||||
|
||||
<!-- prepare all variables for tag-picker keyboard handling -->
|
||||
\procedure tag-picker(actions, tagField:"tags", tiddler, tagListFilter:"[tags[]]")
|
||||
|
||||
\function _tf.getUserInput() [<storeTitle>get[text]]
|
||||
\function _tf.getTag() [<newTagNameTiddler>get[text]]
|
||||
|
||||
<!-- keep those variables because they may "blead" into macros using old syntax -->
|
||||
\procedure tag-picker-inner()
|
||||
\whitespace trim
|
||||
<$let
|
||||
palette={{$:/palette}}
|
||||
newTagNameInputTiddlerQualified=<<qualify "$:/temp/NewTagName/input">>
|
||||
newTagNameSelectionTiddlerQualified=<<qualify "$:/temp/NewTagName/selected-item">>
|
||||
fallbackTarget={{{ [<palette>getindex[tag-background]] }}}
|
||||
colourA={{{ [<palette>getindex[foreground]] }}}
|
||||
colourB={{{ [<palette>getindex[background]] }}}
|
||||
fallbackTarget={{{ [<palette>getindex[tag-background]] }}}
|
||||
|
||||
saveTiddler={{{ [<tiddler>is[blank]then<currentTiddler>else<tiddler>] }}}
|
||||
|
||||
newTagNameTiddler={{{ [[$:/temp/NewTagName]] [<tagField>!match[tags]] +[join[/]] [<qualify>] +[join[]] }}}
|
||||
storeTitle={{{ [[$:/temp/NewTagName/input]] [<tagField>!match[tags]] +[join[/]] [<qualify>] +[join[]] }}}
|
||||
|
||||
newTagNameSelectionTiddlerQualified=<<qualify "$:/temp/NewTagName/selected-item">>
|
||||
storeTitle={{{ [<newTagNameInputTiddler>!match[]] ~[<newTagNameInputTiddlerQualified>] }}}
|
||||
tagSelectionState={{{ [<newTagNameSelectionTiddler>!match[]] ~[<newTagNameSelectionTiddlerQualified>] }}}
|
||||
tagAutoComplete=<<qualify "$:/state/popup/tags-auto-complete">>
|
||||
|
||||
refreshTitle=<<qualify "$:/temp/NewTagName/refresh">>
|
||||
|
||||
nonSystemTagsFilter="[subfilter<tagListFilter>!is[system]search:title<userInput>sort[]]"
|
||||
systemTagsFilter="[subfilter<tagListFilter>is[system]search:title<userInput>sort[]]"
|
||||
|
||||
cancelPopups="yes"
|
||||
refreshTitle=<<qualify "$:/temp/NewTagName/refresh">>
|
||||
nonSystemTagsFilter="[tags[]!is[system]search:title<userInput>sort[]]"
|
||||
systemTagsFilter="[tags[]is[system]search:title<userInput>sort[]]"
|
||||
>
|
||||
<$macrocall $name="tag-picker-inner"/>
|
||||
<div class="tc-edit-add-tag">
|
||||
<div>
|
||||
<span class="tc-add-tag-name tc-small-gap-right">
|
||||
<$transclude
|
||||
$variable="keyboard-driven-input"
|
||||
tiddler=<<newTagNameTiddler>>
|
||||
storeTitle=<<storeTitle>>
|
||||
refreshTitle=<<refreshTitle>>
|
||||
selectionStateTitle=<<tagSelectionState>>
|
||||
inputAcceptActions=<<add-tag-actions>>
|
||||
inputCancelActions=<<clear-tags-actions>>
|
||||
tag="input"
|
||||
placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}}
|
||||
focusPopup=<<tagAutoComplete>>
|
||||
class="tc-edit-texteditor tc-popup-handle"
|
||||
tabindex=<<tabIndex>>
|
||||
focus={{{ [{$:/config/AutoFocus}match[tags]then[true]] ~[[false]] }}}
|
||||
filterMinLength={{$:/config/Tags/MinLength}}
|
||||
cancelPopups=<<cancelPopups>>
|
||||
configTiddlerFilter="[[$:/core/macros/tag-picker]]"
|
||||
/>
|
||||
</span>
|
||||
<$button popup=<<tagAutoComplete>>
|
||||
class="tc-btn-invisible tc-btn-dropdown"
|
||||
tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}}
|
||||
aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}}
|
||||
>
|
||||
{{$:/core/images/down-arrow}}
|
||||
</$button>
|
||||
<$reveal state=<<storeTitle>> type="nomatch" text="">
|
||||
<$button actions=<<delete-tag-state-tiddlers>>
|
||||
class="tc-btn-invisible tc-small-gap tc-btn-dropdown"
|
||||
tooltip={{$:/language/EditTemplate/Tags/ClearInput/Hint}}
|
||||
aria-label={{$:/language/EditTemplate/Tags/ClearInput/Caption}}
|
||||
>
|
||||
{{$:/core/images/close-button}}
|
||||
</$button>
|
||||
</$reveal>
|
||||
<span class="tc-add-tag-button tc-small-gap-left">
|
||||
<$let tag=<<tag>>>
|
||||
<$button set=<<newTagNameTiddler>> setTo=""
|
||||
actions=<<add-button-actions>>
|
||||
>
|
||||
{{$:/language/EditTemplate/Tags/Add/Button}}
|
||||
</$button>
|
||||
</$let>
|
||||
</span>
|
||||
</div>
|
||||
<div class="tc-block-dropdown-wrapper">
|
||||
<$reveal state=<<tagAutoComplete>> type="nomatch" text="">
|
||||
<div class="tc-block-dropdown tc-block-tags-dropdown">
|
||||
<$let userInput=<<userInput>>>
|
||||
<$transclude $variable="list-tags" filter=<<nonSystemTagsFilter>> suffix="-primaryList" />
|
||||
<hr>
|
||||
<$transclude $variable="list-tags" filter=<<systemTagsFilter>> suffix="-secondaryList" />
|
||||
</$let>
|
||||
</div>
|
||||
</$reveal>
|
||||
</div>
|
||||
</div>
|
||||
</$let>
|
||||
\end
|
||||
\end
|
||||
|
||||
\procedure tag-picker(actions, tagField:"tags")
|
||||
\function userInput() [<storeTitle>get[text]]
|
||||
\function tag() [<newTagNameTiddler>get[text]]
|
||||
\whitespace trim
|
||||
<$let
|
||||
saveTiddler=<<currentTiddler>>
|
||||
palette={{$:/palette}}
|
||||
qualified=<<qualify "$:/temp/NewTagName">>
|
||||
newTagNameTiddler={{{ [<newTagNameTiddler>!match[]] ~[<qualified>] }}}
|
||||
>
|
||||
<$transclude $variable="tag-picker-inner" />
|
||||
</$let>
|
||||
\end
|
||||
|
||||
@@ -21,9 +21,7 @@ color:$(foregroundColor)$;
|
||||
>
|
||||
<<__actions__>>
|
||||
<$transclude tiddler=<<__icon__>>/>
|
||||
<span class={{{ [<__tag__>is[missing]then[tc-tag-missing]else[tc-tag-exists]] }}}>
|
||||
<$view tiddler=<<__tag__>> field="title" format="text" />
|
||||
</span>
|
||||
<$view tiddler=<<__tag__>> field="title" format="text" />
|
||||
</$element-tag$>
|
||||
</$let>
|
||||
\end
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
title: $:/core/macros/testcase
|
||||
tags: $:/tags/Macro $:/tags/Global
|
||||
|
||||
\whitespace trim
|
||||
|
||||
\procedure testcase(tiddler)
|
||||
<$tiddler tiddler=<<tiddler>>>
|
||||
<$transclude $tiddler="$:/core/ui/TestCaseTemplate">
|
||||
</$tiddler>
|
||||
\end
|
||||
@@ -1,2 +1,2 @@
|
||||
title: $:/tags/ViewTemplateBodyFilter
|
||||
list: $:/config/ViewTemplateBodyFilters/testcase $:/config/ViewTemplateBodyFilters/hide-body $:/config/ViewTemplateBodyFilters/code-body $:/config/ViewTemplateBodyFilters/stylesheet $:/config/ViewTemplateBodyFilters/core-ui-advanced-search $:/config/ViewTemplateBodyFilters/core-ui-tags $:/config/ViewTemplateBodyFilters/system $:/config/ViewTemplateBodyFilters/import $:/config/ViewTemplateBodyFilters/plugin $:/config/ViewTemplateBodyFilters/default
|
||||
list: $:/config/ViewTemplateBodyFilters/hide-body $:/config/ViewTemplateBodyFilters/code-body $:/config/ViewTemplateBodyFilters/stylesheet $:/config/ViewTemplateBodyFilters/core-ui-advanced-search $:/config/ViewTemplateBodyFilters/core-ui-tags $:/config/ViewTemplateBodyFilters/system $:/config/ViewTemplateBodyFilters/import $:/config/ViewTemplateBodyFilters/plugin $:/config/ViewTemplateBodyFilters/default
|
||||
@@ -1,6 +1,6 @@
|
||||
caption: 5.3.4
|
||||
created: 20240529100240232
|
||||
modified: 20240529100240232
|
||||
created: 20231223102229103
|
||||
modified: 20231223102229103
|
||||
tags: ReleaseNotes
|
||||
title: Release 5.3.4
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -10,86 +10,36 @@ description: Under development
|
||||
|
||||
! Major Improvements
|
||||
|
||||
!! Tour Plugin
|
||||
|
||||
<<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7734">> several new features that together allow interactive learning tours to be created and presented in TiddlyWiki.
|
||||
|
||||
The demo TiddlyWiki interactive tour can be seen at https://tiddlywiki.com/prerelease/tour
|
||||
|
||||
The new features include:
|
||||
|
||||
* The new Tour Plugin itself
|
||||
* The new Confetti Plugin that allows animated bursts of confetti to be displayed
|
||||
* Improvements to the Dynannotate Plugin to add the ability to highlight screen elements using an animated spotlight effect
|
||||
|
||||
!! <<.wlink TestCaseWidget>> Widget
|
||||
|
||||
<<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7817">> new <<.wlink TestCaseWidget>> widget that is intended to solve a problem with the examples that we feature in the documentation. The existing macros are workable for simple, self-contained examples, but can be hard to follow in cases where the examples use additional tiddlers. The <<.wlink TestCaseWidget>> widget displays complete, self-contained interactive examples showing the output together with a tabbed display of the constituent tiddlers that produce it:
|
||||
|
||||
<<testcase "TestCases/TestCaseWidget/TwoPlusTwo">>
|
||||
|
||||
The payload tiddlers for a test case are specified with the <<.wlink DataWidget>> widget. Test cases are run as an independent, self-contained nested wiki in a similar way to the [[Innerwiki Plugin]], but are much more lightweight. The disadvantage is that test cases are rendered as part of the main page, and so any styling changes will leak out to the rest of the page.
|
||||
|
||||
Test cases can also specify the raw HTML of the expected result which causes them to be executed as tests, with success or failure indicated by an icon:
|
||||
|
||||
<<testcase "TestCases/TestCaseWidget/FailingTest">>
|
||||
|
||||
The easiest way to use the <<.wlink TestCaseWidget>> is by creating TestCaseTiddlers using the new CompoundTiddlers format. There are also many test cases to view in the TiddlyWiki test edition at https://tiddlywiki.com/prerelease/test.html
|
||||
|
||||
! Translation improvements
|
||||
|
||||
Improvements to the following translations:
|
||||
|
||||
* Chinese
|
||||
* Macedonian
|
||||
* Polish
|
||||
*
|
||||
|
||||
! Plugin Improvements
|
||||
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/8198">> badges to the core plugins to indicate their [[stability level|Plugin Stability]] from "deprecated", "experimental", "stable" and "legacy". These badges are shown in the plugin library and in the control panel
|
||||
*
|
||||
|
||||
! Widget Improvements
|
||||
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/8115">> ''$timestamp'' attribute to ActionDeleteFieldWidget
|
||||
|
||||
! Filter Improvements
|
||||
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7966">> new [[backtranscludes Operator]]
|
||||
*
|
||||
|
||||
! Usability Improvements
|
||||
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/issues/8121">> new keyboard shortcut for refreshing the page
|
||||
*
|
||||
|
||||
! Hackability Improvements
|
||||
|
||||
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7882">> infinite recursion handling using a custom exception
|
||||
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7966">> button to the JavaScript error popup allowing tiddlers to be saved to a local JSON file
|
||||
* <<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/issues/8120">> to latest version of modern-normalize 2.0.0
|
||||
*
|
||||
|
||||
! Bug Fixes
|
||||
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8186">> nested [[Block Quotes in WikiText]]
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7933">> TiddlyWikiClassic build process
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7935">> LinkWidget not refreshing when the `to` attribute changes
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/3460">> parsing bug with empty procedures/macros
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7907">> functions to use variables set by filter runs
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7943">> edit widget not refreshing when the editor type changes
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7922">> editor preview width
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/9bf3c0602d4fd3fe5ac7411db697b51f87a79056">> [[WidgetMessage: tm-http-request]] not returning data in the event of an error
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/8150">> [[WidgetMessage: tm-http-request]] incorrectly interpreting 2XX status codes
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7949">> processing of path separators in `tiddlywiki.files` files on Windows
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7975">> incorrect state reference in advanced search
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7985">> clipping of popups in preview pane
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/8039">> JavaScript error when attempting to export missing tiddlers to a CSV file
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7909">> imported procedures defaulting to `\whitespace trim`
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/801ed0ea1164aab4f88547322f9d73704388143f">> crash with [[cycle Operator]] if the the step size is larger than the number of operands
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/8095">> proper DOCTYPE for the open window template
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7945">> theme font size settings to open in new window CSS
|
||||
*
|
||||
|
||||
! Node.js Improvements
|
||||
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/8141">> usage of "Cache-Control" header
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7878">> SaveCommand not overwriting files when required
|
||||
*
|
||||
|
||||
! Performance Improvements
|
||||
|
||||
@@ -97,8 +47,7 @@ Improvements to the following translations:
|
||||
|
||||
! Developer Improvements
|
||||
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8195">> issue with fakedom TW_Node inheritence
|
||||
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8099">> SJCL library creating variables in global scope
|
||||
*
|
||||
|
||||
! Infrastructure Improvements
|
||||
|
||||
@@ -109,30 +58,4 @@ Improvements to the following translations:
|
||||
[[@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 """
|
||||
andjar
|
||||
AnthonyMuscio
|
||||
bimlas
|
||||
BramChen
|
||||
btheado
|
||||
BurningTreeC
|
||||
catter-fly
|
||||
eschlon
|
||||
etardiff
|
||||
flibbles
|
||||
FSpark
|
||||
hoelzro
|
||||
jinix6
|
||||
joshuafontany
|
||||
linonetwo
|
||||
mateuszwilczek
|
||||
mklauber
|
||||
oeyoews
|
||||
pmario
|
||||
PotOfCoffee2Go
|
||||
rmunn
|
||||
saqimtiaz
|
||||
sarna
|
||||
Telumire
|
||||
twMat
|
||||
yaisog
|
||||
""">>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
title: $:/config/OfficialPluginLibrary
|
||||
tags: $:/tags/PluginLibrary
|
||||
url: https://tiddlywiki.com/prerelease/library/v5.3.4/index.html
|
||||
url: https://tiddlywiki.com/prerelease/library/v5.3.3/index.html
|
||||
caption: {{$:/language/OfficialPluginLibrary}} (Prerelease)
|
||||
|
||||
The prerelease version of the official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team.
|
||||
|
||||
@@ -3,7 +3,3 @@ title: HelloThere
|
||||
This is TiddlyWiki's browser-based test runner for version <<version>>. See the bottom of this page for the test results.
|
||||
|
||||
https://tiddlywiki.com/
|
||||
|
||||
! Test Cases
|
||||
|
||||
{{$:/core/ui/ControlPanel/TestCases}}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
title: Macros/unusedtitle/basic-draft-exists
|
||||
description: test <<unusedtitle>> with basic macro parameters but they are empty
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Draft of 'test'
|
||||
draft.of: test
|
||||
draft.title: test
|
||||
|
||||
+
|
||||
title: Draft of 'asdf 0'
|
||||
draft.of: asdf 0
|
||||
draft.title: asdf 0
|
||||
|
||||
+
|
||||
title: Output
|
||||
|
||||
<!-- hanled in wiki.js -->
|
||||
<<unusedtitle baseName:"test">>
|
||||
|
||||
<!-- handled in unusedtitle.js -->
|
||||
<<unusedtitle baseName:"asdf" separator:" " template:"$basename$$separator$$count:1$">>
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>test 1</p><p>asdf 1</p>
|
||||
@@ -1,23 +0,0 @@
|
||||
title: Macros/unusedtitle/basic-params-empty-tiddler-exists
|
||||
description: test <<unusedtitle>> with basic macro parameters but they are empty
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: New Tiddler
|
||||
|
||||
+
|
||||
title: Output
|
||||
|
||||
<!-- hanled in wiki.js -->
|
||||
<<unusedtitle separator:"">>
|
||||
|
||||
<!-- handled in unusedtitle.js -->
|
||||
<<unusedtitle baseName:"">>
|
||||
|
||||
<!-- handled in wiki.js -->
|
||||
<<unusedtitle template:"">>
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>New Tiddler 1</p><p>New Tiddler 1</p><p>New Tiddler 1</p>
|
||||
@@ -1,20 +0,0 @@
|
||||
title: Macros/unusedtitle/basic-params-empty
|
||||
description: test <<unusedtitle>> with basic macro parameters but they are empty
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
<!-- hanled in wiki.js -->
|
||||
<<unusedtitle separator:"">>
|
||||
|
||||
<!-- handled in unusedtitle.js -->
|
||||
<<unusedtitle baseName:"">>
|
||||
|
||||
<!-- handled in wiki.js -->
|
||||
<<unusedtitle template:"">>
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>New Tiddler</p><p>New Tiddler</p><p>New Tiddler</p>
|
||||
@@ -1,28 +0,0 @@
|
||||
title: Macros/unusedtitle/basic-params-tiddlers-exist
|
||||
description: test <<unusedtitle>> with basic macro parameters, where new-name tiddlers already exist
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: New Tiddler
|
||||
|
||||
+
|
||||
title: anotherBase
|
||||
|
||||
+
|
||||
title: About
|
||||
|
||||
+
|
||||
title: Output
|
||||
|
||||
<<unusedtitle>>
|
||||
|
||||
<<unusedtitle separator:"-">>
|
||||
|
||||
<<unusedtitle baseName:"anotherBase">>
|
||||
|
||||
<<unusedtitle baseName:"About" separator:"-">>
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>New Tiddler 1</p><p>New Tiddler-1</p><p>anotherBase 1</p><p>About-1</p>
|
||||
@@ -1,20 +0,0 @@
|
||||
title: Macros/unusedtitle/basic-params
|
||||
description: test <<unusedtitle>> with basic macro parameters
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
<<unusedtitle>>
|
||||
|
||||
<!-- EDGECASE: separator is ignored if tiddler title does not exist -->
|
||||
<<unusedtitle separator:"-">>
|
||||
|
||||
<<unusedtitle baseName:"anotherBase">>
|
||||
|
||||
<<unusedtitle baseName:"About" separator:"-">>
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>New Tiddler</p><p>New Tiddler</p><p>anotherBase</p><p>About</p>
|
||||
@@ -1,50 +0,0 @@
|
||||
title: Macros/unusedtitle/template-empty-params-tiddler-exist
|
||||
description: test <<unusedtitle>> with templates where parameters are empty
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: New Tiddler
|
||||
|
||||
+
|
||||
title: xxx
|
||||
|
||||
+
|
||||
title: 00-New Tiddler
|
||||
|
||||
+
|
||||
title: 0000 asdf
|
||||
|
||||
+
|
||||
title: 0001 asdf
|
||||
|
||||
+
|
||||
title: 0000 abc
|
||||
|
||||
+
|
||||
title: Output
|
||||
|
||||
<!-- empty template - no template handling at all -->
|
||||
<<unusedtitle template:"">>
|
||||
|
||||
<!--
|
||||
uses basename AND separator if tiddler exists
|
||||
because it uses default naming build rules - no template handling
|
||||
-->
|
||||
<<unusedtitle template:"" separator:"-y-" baseName:"xxx">>
|
||||
|
||||
<<unusedtitle baseName:"" template:"$count:2$-$basename$">>
|
||||
|
||||
<!--
|
||||
EDGECASE: if separator is empty it will be initialized with a single space " "
|
||||
to have the same rules for templates and default title creation
|
||||
-->
|
||||
<<unusedtitle baseName:"asdf" separator:"" template:"$count:4$$separator$$basename$">>
|
||||
|
||||
<!-- separator = " " -->
|
||||
<<unusedtitle baseName:"abc" separator:" " template:"$count:4$$separator$$basename$">>
|
||||
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>New Tiddler 1</p><p>xxx-y-1</p><p>01-New Tiddler</p><p>0002 asdf</p><p>0001 abc</p>
|
||||
@@ -1,24 +0,0 @@
|
||||
title: Macros/unusedtitle/template-empty-params
|
||||
description: test <<unusedtitle>> with templates where parameters are empty
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
<!-- empty template -->
|
||||
<<unusedtitle template:"">>
|
||||
|
||||
<!--
|
||||
uses basename but ignores separator,
|
||||
because it uses default naming build rules -- no template handling is active
|
||||
-->
|
||||
<<unusedtitle template:"" separator:"-x-" baseName:"xxx">>
|
||||
|
||||
<<unusedtitle baseName:"" template:"$count:2$-$basename$">>
|
||||
|
||||
<<unusedtitle baseName:"asdf" separator:"" template:"$count:4$$separator$$basename$">>
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>New Tiddler</p><p>xxx</p><p>00-New Tiddler</p><p>0000 asdf</p>
|
||||
@@ -1,28 +0,0 @@
|
||||
title: Macros/unusedtitle/template
|
||||
description: test <<unusedtitle>> with templates
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
<!-- empty template - standard rules are used -->
|
||||
<<unusedtitle template:"">>
|
||||
|
||||
<<unusedtitle template:"count-missing">>
|
||||
|
||||
<<unusedtitle template:"$count:2$-new">>
|
||||
|
||||
<!-- template is handled using $tw.utils.formatTitleString -->
|
||||
<<unusedtitle baseName:"base" template:"$count:2$-$basename$">>
|
||||
|
||||
<<unusedtitle baseName:"" template:"$count:2$-$basename$">>
|
||||
|
||||
<!-- UPPERCASES are intentional in template strings. They should be case-insensistive -->
|
||||
<<unusedtitle baseName:"asdf" separator:"-" template:"$coUNT:2$$sepaRATor$$baseName$">>
|
||||
|
||||
<<unusedtitle baseName:"asdf" separator:"" template:"$count:2$$separator$$basename$">>
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>New Tiddler</p><p>count-missing</p><p>00-new</p><p>00-base</p><p>00-New Tiddler</p><p>00-asdf</p><p>00 asdf</p>
|
||||
@@ -7,8 +7,7 @@ title: Output
|
||||
|
||||
\whitespace trim
|
||||
<$transclude $tiddler="Output"/>
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<span class="tc-error">Recursive transclusion error in transclude widget</span>
|
||||
<p><span class="tc-error">Recursive transclusion error in transclude widget</span></p>
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"directories": [
|
||||
"../../../../tw5.com/tiddlers/testcases"
|
||||
]
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
/*\
|
||||
title: test-action-deletefield.js
|
||||
type: application/javascript
|
||||
tags: [[$:/tags/test-spec]]
|
||||
|
||||
Tests <$action-deletefield />.
|
||||
|
||||
\*/
|
||||
(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("<$action-deletefield /> tests", function() {
|
||||
|
||||
const TEST_TIDDLER_TITLE = "TargetTiddler";
|
||||
const TEST_TIDDLER_MODIFIED = "20240313114828368";
|
||||
|
||||
function setupWiki(condition, targetField, wikiOptions) {
|
||||
// Create a wiki
|
||||
var wiki = new $tw.Wiki({});
|
||||
var tiddlers = [{
|
||||
title: "Root",
|
||||
text: "Some dummy content"
|
||||
}];
|
||||
var tiddler;
|
||||
if(condition.targetTiddlerExists) {
|
||||
var fields = {
|
||||
title: TEST_TIDDLER_TITLE,
|
||||
};
|
||||
if(condition.modifiedFieldExists) {
|
||||
fields.modified = TEST_TIDDLER_MODIFIED;
|
||||
}
|
||||
if(condition.targetFieldExists) {
|
||||
fields[targetField] = "some text";
|
||||
}
|
||||
var tiddler = new $tw.Tiddler(fields);
|
||||
tiddlers.push(tiddler);
|
||||
}
|
||||
wiki.addTiddlers(tiddlers);
|
||||
wiki.addIndexersToWiki();
|
||||
var widgetNode = wiki.makeTranscludeWidget("Root",{document: $tw.fakeDocument, parseAsInline: true});
|
||||
var container = $tw.fakeDocument.createElement("div");
|
||||
widgetNode.render(container,null);
|
||||
return {
|
||||
wiki: wiki,
|
||||
widgetNode: widgetNode,
|
||||
contaienr: container,
|
||||
tiddler: tiddler,
|
||||
};
|
||||
}
|
||||
|
||||
function generateTestConditions() {
|
||||
var conditions = [];
|
||||
|
||||
$tw.utils.each([true, false], function(tiddlerArgumentIsPresent) {
|
||||
$tw.utils.each([true, false], function(targetTiddlerExists) {
|
||||
$tw.utils.each([true, false], function(targetFieldExists) {
|
||||
$tw.utils.each([true, false], function(fieldArgumentIsUsed) {
|
||||
$tw.utils.each([true, false], function(modifiedFieldExists) {
|
||||
$tw.utils.each(["", "yes", "no"], function(timestampArgument) {
|
||||
conditions.push({
|
||||
tiddlerArgumentIsPresent: tiddlerArgumentIsPresent,
|
||||
targetTiddlerExists: targetTiddlerExists,
|
||||
targetFieldExists: targetFieldExists,
|
||||
fieldArgumentIsUsed: fieldArgumentIsUsed,
|
||||
modifiedFieldExists: modifiedFieldExists,
|
||||
timestampArgument: timestampArgument,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return conditions;
|
||||
}
|
||||
|
||||
function generateActionWikitext(condition, targetField) {
|
||||
var actionPieces = [
|
||||
"<$action-deletefield",
|
||||
(condition.tiddlerArgumentIsPresent ? "$tiddler='" + TEST_TIDDLER_TITLE + "'" : ""),
|
||||
(condition.fieldArgumentIsUsed ? "$field='" + targetField + "'" : targetField),
|
||||
(condition.timestampArgument !== "" ? "$timestamp='" + condition.timestampArgument + "'" : ""),
|
||||
"/>",
|
||||
];
|
||||
|
||||
return actionPieces.join(" ");
|
||||
}
|
||||
|
||||
function generateTestContext(action, tiddler) {
|
||||
var expectationContext = "action: " + action + "\ntiddler:\n\n";
|
||||
if(tiddler) {
|
||||
expectationContext += tiddler.getFieldStringBlock({exclude: ["text"]});
|
||||
if(tiddler.text) {
|
||||
expectationContext += "\n\n" + tiddler.text;
|
||||
}
|
||||
expectationContext += "\n\n";
|
||||
} else {
|
||||
expectationContext += "null";
|
||||
}
|
||||
|
||||
return expectationContext;
|
||||
}
|
||||
|
||||
it("should correctly delete fields", function() {
|
||||
var fields = ['caption', 'description', 'text'];
|
||||
|
||||
var conditions = generateTestConditions();
|
||||
|
||||
$tw.utils.each(conditions, function(condition) {
|
||||
$tw.utils.each(fields, function(field) {
|
||||
var info = setupWiki(condition, field);
|
||||
var originalTiddler = info.tiddler;
|
||||
|
||||
var invokeActions = function(actions) {
|
||||
info.widgetNode.invokeActionString(actions,info.widgetNode,null,{
|
||||
currentTiddler: TEST_TIDDLER_TITLE,
|
||||
});
|
||||
};
|
||||
|
||||
var action = generateActionWikitext(condition,field);
|
||||
|
||||
invokeActions(action);
|
||||
|
||||
var testContext = generateTestContext(action,originalTiddler);
|
||||
|
||||
var tiddler = info.wiki.getTiddler(TEST_TIDDLER_TITLE);
|
||||
if(originalTiddler) {
|
||||
// assert that the tiddler doesn't have the target field anymore
|
||||
expect(tiddler.hasField(field)).withContext(testContext).toBeFalsy();
|
||||
|
||||
var targetFieldWasPresent = originalTiddler.hasField(field);
|
||||
var updateTimestamps = condition.timestampArgument !== "no";
|
||||
|
||||
// "created" should exist if it did beforehand, or if the tiddler changed and we asked the widget to update timestamps
|
||||
var createdFieldShouldExist = originalTiddler.hasField("created") || (targetFieldWasPresent && updateTimestamps);
|
||||
|
||||
// "created" should change only if it didn't exist beforehand and the tiddler changed and we asked the widget to update timestamps
|
||||
var createdFieldShouldChange = !originalTiddler.hasField("created") && (targetFieldWasPresent && updateTimestamps);
|
||||
|
||||
// "modified" should exist if it did beforehand, or if the tiddler changed and we asked the widget to update timestamps
|
||||
var modifiedFieldShouldExist = originalTiddler.hasField("modified") || (targetFieldWasPresent && updateTimestamps);
|
||||
|
||||
// "modified" should change if the tiddler changed and we asked the widget to update timestamps
|
||||
var modifiedFieldShouldChange = targetFieldWasPresent && updateTimestamps;
|
||||
|
||||
expect(tiddler.hasField("created")).withContext(testContext).toBe(createdFieldShouldExist);
|
||||
expect(tiddler.hasField("modified")).withContext(testContext).toBe(modifiedFieldShouldExist);
|
||||
|
||||
if(createdFieldShouldChange) {
|
||||
expect(tiddler.fields.created).withContext(testContext).not.toEqual(originalTiddler.fields.created);
|
||||
} else {
|
||||
expect(tiddler.fields.created).withContext(testContext).toEqual(originalTiddler.fields.created);
|
||||
}
|
||||
|
||||
if(modifiedFieldShouldChange) {
|
||||
expect(tiddler.fields.modified).withContext(testContext).not.toEqual(originalTiddler.fields.modified);
|
||||
} else {
|
||||
expect(tiddler.fields.modified).withContext(testContext).toEqual(originalTiddler.fields.modified);
|
||||
}
|
||||
} else {
|
||||
// assert that the tiddler didn't get created if it didn't exist already
|
||||
expect(tiddler).withContext(testContext).toBeUndefined();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
||||
@@ -12,24 +12,6 @@ Tests the backlinks mechanism.
|
||||
"use strict";
|
||||
|
||||
describe('Backlinks tests', function() {
|
||||
function setupWiki(wikiOptions) {
|
||||
wikiOptions = wikiOptions || {};
|
||||
// Create a wiki
|
||||
var wiki = new $tw.Wiki(wikiOptions);
|
||||
wiki.addIndexersToWiki();
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestIncoming',
|
||||
text: '',
|
||||
});
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestOutgoing',
|
||||
text: 'A link to [[TestIncoming]]',
|
||||
});
|
||||
return wiki;
|
||||
}
|
||||
|
||||
describe('a tiddler with no links to it', function() {
|
||||
var wiki = new $tw.Wiki();
|
||||
|
||||
@@ -43,7 +25,15 @@ describe('Backlinks tests', function() {
|
||||
});
|
||||
|
||||
describe('A tiddler added to the wiki with a link to it', function() {
|
||||
var wiki = setupWiki();
|
||||
var wiki = new $tw.Wiki();
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestIncoming',
|
||||
text: ''});
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestOutgoing',
|
||||
text: 'A link to [[TestIncoming]]'});
|
||||
|
||||
it('should have a backlink', function() {
|
||||
expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing');
|
||||
@@ -52,7 +42,15 @@ describe('Backlinks tests', function() {
|
||||
|
||||
describe('A tiddler that has a link added to it later', function() {
|
||||
it('should have an additional backlink', function() {
|
||||
var wiki = setupWiki();
|
||||
var wiki = new $tw.Wiki();
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestIncoming',
|
||||
text: ''});
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestOutgoing',
|
||||
text: 'A link to [[TestIncoming]]'});
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestOutgoing2',
|
||||
@@ -69,7 +67,15 @@ describe('Backlinks tests', function() {
|
||||
});
|
||||
|
||||
describe('A tiddler that has a link remove from it later', function() {
|
||||
var wiki = setupWiki();
|
||||
var wiki = new $tw.Wiki();
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestIncoming',
|
||||
text: ''});
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestOutgoing',
|
||||
text: 'A link to [[TestIncoming]]'});
|
||||
|
||||
it('should have one fewer backlink', function() {
|
||||
expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing');
|
||||
@@ -83,7 +89,15 @@ describe('Backlinks tests', function() {
|
||||
});
|
||||
|
||||
describe('A tiddler linking to another that gets renamed', function() {
|
||||
var wiki = setupWiki();
|
||||
var wiki = new $tw.Wiki();
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestIncoming',
|
||||
text: ''});
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestOutgoing',
|
||||
text: 'A link to [[TestIncoming]]'});
|
||||
|
||||
it('should have its name changed in the backlinks', function() {
|
||||
expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing');
|
||||
@@ -95,7 +109,15 @@ describe('Backlinks tests', function() {
|
||||
});
|
||||
|
||||
describe('A tiddler linking to another that gets deleted', function() {
|
||||
var wiki = setupWiki();
|
||||
var wiki = new $tw.Wiki();
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestIncoming',
|
||||
text: ''});
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestOutgoing',
|
||||
text: 'A link to [[TestIncoming]]'});
|
||||
|
||||
it('should be removed from backlinks', function() {
|
||||
expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing');
|
||||
@@ -105,41 +127,6 @@ describe('Backlinks tests', function() {
|
||||
expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Binary tiddlers should not be parsed', function() {
|
||||
var wiki = setupWiki();
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestDoc.doc',
|
||||
text: 'A link to [[TestOutgoing]]',
|
||||
type: 'application/msword'
|
||||
});
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestExcel.xls',
|
||||
text: 'A link to [[TestOutgoing]]',
|
||||
type: 'application/excel'
|
||||
});
|
||||
|
||||
wiki.addTiddler({
|
||||
title: 'TestOutgoing',
|
||||
text: 'Some links to [[TestDoc.doc]] and [[TestExcel.xls]].'
|
||||
});
|
||||
|
||||
it('should ignore office files', function() {
|
||||
expect(wiki.getIndexer("BackIndexer").subIndexers.link._getTarget(wiki.getTiddler('TestExcel.xls'))).toEqual([]);
|
||||
|
||||
expect(wiki.filterTiddlers('[all[]] +[backlinks[]]').join(',')).toBe('TestOutgoing');
|
||||
|
||||
// make it tw5 tiddler
|
||||
wiki.addTiddler({
|
||||
title: 'TestExcel.xls',
|
||||
text: 'A link to [[TestOutgoing]]'
|
||||
});
|
||||
|
||||
expect(wiki.filterTiddlers('[all[]] +[backlinks[]]').join(',')).toBe('TestOutgoing,TestExcel.xls');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*\
|
||||
title: test-fakedom.js
|
||||
type: application/javascript
|
||||
tags: [[$:/tags/test-spec]]
|
||||
|
||||
Tests the fakedom that Tiddlywiki occasionally uses.
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
describe("fakedom tests", function() {
|
||||
|
||||
it("properly assigns nodeType based on DOM standards", function() {
|
||||
// According to MDN, ELEMENT_NODE == 1 && TEXT_NODE == 3
|
||||
// There are others, but currently they're not implemented in fakedom
|
||||
expect($tw.fakeDocument.createElement("div").nodeType).toBe(1);
|
||||
expect($tw.fakeDocument.createElement("div").ELEMENT_NODE).toBe(1);
|
||||
expect($tw.fakeDocument.createTextNode("text").nodeType).toBe(3);
|
||||
expect($tw.fakeDocument.createTextNode("text").TEXT_NODE).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
||||
@@ -1,55 +0,0 @@
|
||||
/*\
|
||||
title: test-plugins.js
|
||||
type: application/javascript
|
||||
tags: [[$:/tags/test-spec]]
|
||||
|
||||
Tests for integrity of the core plugins, languages, themes and editions
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
if($tw.node) {
|
||||
|
||||
describe("Plugin tests", function() {
|
||||
|
||||
// Get all the plugins as a hashmap by title of a JSON string with the plugin content
|
||||
var tiddlers = $tw.utils.getAllPlugins({ignoreEnvironmentVariables: true});
|
||||
// console.log(JSON.stringify(Object.keys(tiddlers),null,4));
|
||||
describe("every plugin should have the required standard fields", function() {
|
||||
var titles = Object.keys(tiddlers);
|
||||
$tw.utils.each(titles,function(title) {
|
||||
var fields = tiddlers[title];
|
||||
it("plugin should have a recognised plugin-type field",function() {
|
||||
expect(["plugin","language","theme"].indexOf(fields["plugin-type"]) !== -1).toEqual(true);
|
||||
});
|
||||
switch(fields["plugin-type"]) {
|
||||
case "plugin":
|
||||
it("plugin " + title + " should have name, description and list fields",function() {
|
||||
expect(!!(fields.name && fields.description && fields.list)).toBe(true);
|
||||
});
|
||||
it("plugin " + title + " should have a valid stability field",function() {
|
||||
expect(["STABILITY_0_DEPRECATED","STABILITY_1_EXPERIMENTAL","STABILITY_2_STABLE","STABILITY_3_LEGACY"].indexOf(fields.stability) !== -1).toBe(true);
|
||||
});
|
||||
break;
|
||||
case "language":
|
||||
it("language " + title + " should have name and description fields",function() {
|
||||
expect(!!(fields.name && fields.description)).toEqual(true);
|
||||
});
|
||||
break;
|
||||
case "theme":
|
||||
it("theme " + title + " should have name and description fields",function() {
|
||||
expect(!!(fields.name && fields.description)).toEqual(true);
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
})();
|
||||
@@ -1,95 +0,0 @@
|
||||
/*\
|
||||
title: test-widget-getVariableInfo.js
|
||||
type: application/javascript
|
||||
tags: [[$:/tags/test-spec]]
|
||||
|
||||
Tests the wikitext rendering pipeline end-to-end. We also need tests that individually test parsers, rendertreenodes etc., but this gets us started.
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
describe("Widget module", function() {
|
||||
|
||||
var widget = require("$:/core/modules/widgets/widget.js");
|
||||
|
||||
function createWidgetNode(parseTreeNode,wiki) {
|
||||
return new widget.widget(parseTreeNode,{
|
||||
wiki: wiki,
|
||||
document: $tw.fakeDocument
|
||||
});
|
||||
}
|
||||
|
||||
function parseText(text,wiki,options) {
|
||||
var parser = wiki.parseText("text/vnd.tiddlywiki",text,options);
|
||||
return parser ? {type: "widget", children: parser.tree} : undefined;
|
||||
}
|
||||
|
||||
function renderWidgetNode(widgetNode) {
|
||||
$tw.fakeDocument.setSequenceNumber(0);
|
||||
var wrapper = $tw.fakeDocument.createElement("div");
|
||||
widgetNode.render(wrapper,null);
|
||||
// console.log(require("util").inspect(wrapper,{depth: 8}));
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
function refreshWidgetNode(widgetNode,wrapper,changes) {
|
||||
var changedTiddlers = {};
|
||||
if(changes) {
|
||||
$tw.utils.each(changes,function(title) {
|
||||
changedTiddlers[title] = true;
|
||||
});
|
||||
}
|
||||
widgetNode.refresh(changedTiddlers,wrapper,null);
|
||||
// console.log(require("util").inspect(wrapper,{depth: 8}));
|
||||
}
|
||||
|
||||
it("should make sure that getVariableInfo returns all expected parameters", function() {
|
||||
var wiki = new $tw.Wiki();
|
||||
wiki.addTiddlers([
|
||||
{title: "A", text: "\\define macro(a:aa) aaa"},
|
||||
{title: "B", text: "\\function fn(f:ff) fff\n\\function x() [<fn>]"},
|
||||
{title: "C", text: "\\procedure proc(p:pp) ppp"},
|
||||
{title: "D", text: "\\widget $my.widget(w:ww) www"}
|
||||
]);
|
||||
var text = "\\import A B C D\n\n<$let abc=def>";
|
||||
var widgetNode = createWidgetNode(parseText(text,wiki),wiki);
|
||||
// Render the widget node to the DOM
|
||||
renderWidgetNode(widgetNode);
|
||||
var childNode = widgetNode;
|
||||
while(childNode.children.length > 0) {
|
||||
childNode = childNode.children[0];
|
||||
}
|
||||
|
||||
expect(childNode.getVariableInfo("macro",{allowSelfAssigned:true}).params).toEqual([{name:"a",value:"aa"}]);
|
||||
|
||||
// function params
|
||||
expect(childNode.getVariableInfo("fn", {allowSelfAssigned:true}).params).toEqual([{name:"f",value:"ff"}]);
|
||||
// functions have a text and a value
|
||||
expect(childNode.getVariableInfo("x", {allowSelfAssigned:true}).text).toBe("fff");
|
||||
expect(childNode.getVariableInfo("x", {allowSelfAssigned:true}).srcVariable.value).toBe("[<fn>]");
|
||||
|
||||
// procedures and widgets failed prior to v5.3.4
|
||||
expect(childNode.getVariableInfo("proc", {allowSelfAssigned:true}).params).toEqual([{name:"p",default:"pp"}]);
|
||||
expect(childNode.getVariableInfo("$my.widget", {allowSelfAssigned:true}).params).toEqual([{name:"w",default:"ww"}]);
|
||||
|
||||
// no params expected
|
||||
expect(childNode.getVariableInfo("abc", {allowSelfAssigned:true})).toEqual({text:"def"});
|
||||
|
||||
// debugger; Find code in browser
|
||||
|
||||
// Find values to be compated to
|
||||
// console.log("macro", childNode.getVariableInfo("macro",{allowSelfAssigned:true}));
|
||||
// console.log("function", childNode.getVariableInfo("fn",{allowSelfAssigned:true}));
|
||||
// console.log("function x", childNode.getVariableInfo("x",{allowSelfAssigned:true}));
|
||||
// console.log("procedure", childNode.getVariableInfo("proc",{allowSelfAssigned:true}));
|
||||
// console.log("widget", childNode.getVariableInfo("$my.widget",{allowSelfAssigned:true}));
|
||||
// console.log("let", childNode.getVariableInfo("abc",{allowSelfAssigned:true}));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
||||
@@ -160,47 +160,6 @@ describe("Widget module", function() {
|
||||
expect(wrapper.innerHTML).toBe("<span class=\"tc-error\">Recursive transclusion error in transclude widget</span>");
|
||||
});
|
||||
|
||||
it("should handle single-tiddler recursion with branching nodes", function() {
|
||||
var wiki = new $tw.Wiki();
|
||||
// Add a tiddler
|
||||
wiki.addTiddlers([
|
||||
{title: "TiddlerOne", text: "<$tiddler tiddler='TiddlerOne'><$transclude /> <$transclude /></$tiddler>"},
|
||||
]);
|
||||
// Test parse tree
|
||||
var parseTreeNode = {type: "widget", children: [
|
||||
{type: "transclude", attributes: {
|
||||
"tiddler": {type: "string", value: "TiddlerOne"}
|
||||
}}
|
||||
]};
|
||||
// Construct the widget node
|
||||
var widgetNode = createWidgetNode(parseTreeNode,wiki);
|
||||
// Render the widget node to the DOM
|
||||
var wrapper = renderWidgetNode(widgetNode);
|
||||
// Test the rendering
|
||||
expect(wrapper.innerHTML).toBe("<span class=\"tc-error\">Recursive transclusion error in transclude widget</span> <span class=\"tc-error\">Recursive transclusion error in transclude widget</span>");
|
||||
});
|
||||
|
||||
it("should handle many-tiddler recursion with branching nodes", function() {
|
||||
var wiki = new $tw.Wiki();
|
||||
// Add a tiddler
|
||||
wiki.addTiddlers([
|
||||
{title: "TiddlerOne", text: "<$transclude tiddler='TiddlerTwo'/> <$transclude tiddler='TiddlerTwo'/>"},
|
||||
{title: "TiddlerTwo", text: "<$transclude tiddler='TiddlerOne'/>"}
|
||||
]);
|
||||
// Test parse tree
|
||||
var parseTreeNode = {type: "widget", children: [
|
||||
{type: "transclude", attributes: {
|
||||
"tiddler": {type: "string", value: "TiddlerOne"}
|
||||
}}
|
||||
]};
|
||||
// Construct the widget node
|
||||
var widgetNode = createWidgetNode(parseTreeNode,wiki);
|
||||
// Render the widget node to the DOM
|
||||
var wrapper = renderWidgetNode(widgetNode);
|
||||
// Test the rendering
|
||||
expect(wrapper.innerHTML).toBe("<span class=\"tc-error\">Recursive transclusion error in transclude widget</span>");
|
||||
});
|
||||
|
||||
it("should deal with SVG elements", function() {
|
||||
var wiki = new $tw.Wiki();
|
||||
// Construct the widget node
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
title: CompoundTiddlers
|
||||
modified: 20240507221902644
|
||||
created: 20240507221902644
|
||||
tags: Concepts
|
||||
|
||||
Compound tiddlers are a special type of tiddler that can store one or more payload tiddlers. The tiddlers within a compound tiddler are only accessible via special operations, typically with the TestCaseWidget.
|
||||
|
||||
The compound tiddler format is extremely simple, and includes the notable flaw that it does not permit tiddlers that contain a plus sign (`+`) on a line by itself. It is not intended as a general purpose way of storing tiddler data.
|
||||
|
||||
Compound tiddlers are identified by having their type field set to `text/vnd.tiddlywiki-multiple`.
|
||||
|
||||
The content of a compound tiddler consists of a sequence of tiddlers separated by a plus sign (`+`) on a line by itself. Each tiddler uses the same format as [[.tid files|TiddlerFiles]].
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
title: First
|
||||
tags: one two
|
||||
|
||||
This is the first tiddler
|
||||
+
|
||||
title: Second
|
||||
tags: three four
|
||||
|
||||
This is the second tiddler
|
||||
+
|
||||
title: third
|
||||
tags: five six
|
||||
|
||||
This is the third tiddler
|
||||
```
|
||||
@@ -1,26 +0,0 @@
|
||||
title: TestCaseTiddlers
|
||||
modified: 20240507221902644
|
||||
created: 20240507221902644
|
||||
tags: Concepts
|
||||
|
||||
Test case tiddlers encapsulate one or more tiddlers that can be displayed as a [[test case|TestCaseWidget]]: an independent embedded wiki that can be used for testing or learning purposes.
|
||||
|
||||
Test case tiddlers are formatted as CompoundTiddlers, allowing them to contain multiple tiddlers packed into one.
|
||||
|
||||
Test case tiddlers have the following fields:
|
||||
|
||||
|!Field |!Description |
|
||||
|<<.field type>> | Should be set to `text/vnd.tiddlywiki-multiple` |
|
||||
|<<.field tags>> | Test cases are tagged [[$:/tags/wiki-test-spec]]. Test cases that intentionally fail are tagged [[$:/tags/wiki-test-spec-failing]] |
|
||||
|<<.field description>> |Descriptive heading for the test, intended to make it easy to identify the test |
|
||||
|<<.field display-format>> |Optional, defaults to `wikitext`. Set to `plaintext` to cause the output to be rended as plain text |
|
||||
|
||||
Test case tiddlers with the appropriate tag are shown in $:/ControlPanel
|
||||
|
||||
Some payload tiddlers are set aside for special purposes:
|
||||
|
||||
|!Tiddler |!Description |
|
||||
|''Narrative'' |Narrative description of the test, intended to explain the purpose and operation of the test |
|
||||
|''Output'' |The tiddler that produces the test output |
|
||||
|''~ExpectedResult'' |HTML of expected result of rendering the ''Output'' tiddler |
|
||||
|''Description'' |Set to the text of the <<.field description>> field |
|
||||
@@ -1,11 +1,11 @@
|
||||
created: 20130825213300000
|
||||
modified: 20240520162904479
|
||||
modified: 20220109101407050
|
||||
tags: Concepts
|
||||
title: TiddlerFields
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
\define lingo-base() $:/language/Docs/Fields/
|
||||
~TiddlerFields are name:value pairs that make up a [[tiddler|Tiddlers]]. Field names may contain any combination of characters (prior to [[v5.2.0|Release 5.2.0]], fields were constrained to be lowercase letters, digits or the characters `-` (dash), `_` (underscore) and `.` (period)).
|
||||
~TiddlerFields are name:value pairs that make up a [[tiddler|Tiddlers]]. Field names must be lowercase letters, digits or the characters `-` (dash), `_` (underscore) and `.` (period).
|
||||
|
||||
The standard fields are:
|
||||
|
||||
@@ -39,7 +39,6 @@ Other fields used by the core are:
|
||||
|`name` |<<lingo name>> |
|
||||
|`plugin-priority` |<<lingo plugin-priority>> |
|
||||
|`plugin-type` |<<lingo plugin-type>> |
|
||||
|`stability` |<<lingo stability>> |
|
||||
|`source` |<<lingo source>> |
|
||||
|`subtitle` |<<lingo subtitle>> |
|
||||
|`throttle.refresh` |<<lingo throttle.refresh>> |
|
||||
|
||||
@@ -4,7 +4,7 @@ tags: [[Filter Expression]]
|
||||
title: Filter Run Prefix
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
There are 2 types of filter run prefixes that are interchangeable; [[named prefixes|Named Filter Run Prefix]] and [[shortcut prefixes|Shortcut Filter Run Prefix]].
|
||||
There are 2 types of filter run prefixes that are interchangeable. Named prefixes and shortcut prefixes.
|
||||
|
||||
<$railroad text="""
|
||||
\start none
|
||||
|
||||
@@ -5,7 +5,7 @@ tags: TableOfContents
|
||||
title: HelloThere
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
!!.tc-hero-heading ''Welcome to TiddlyWiki, a unique [[non-linear|Philosophy of Tiddlers]] notebook for [[capturing|Creating and editing tiddlers]], [[organising|Structuring TiddlyWiki]] and [[sharing|Sharing your tiddlers with others]] complex information''
|
||||
!!.tc-hero-heading ''Welcome to TiddlyWiki, a unique [[non-linear|Philosophy of Tiddlers]] notebook for [[capturing|Creating and editing tiddlers]], [[organising|Structuring TiddlyWiki]] and [[sharing|Sharing your tiddlers with others]] complex information''
|
||||
|
||||
Use it to keep your [[to-do list|TaskManagementExample]], to plan an [[essay or novel|"TiddlyWiki for Scholars" by Alberto Molina]], or to organise your wedding. Record every thought that crosses your brain, or build a flexible and responsive website.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
caption: tag
|
||||
created: 20141206130540337
|
||||
modified: 20240228131301798
|
||||
modified: 20230725201240201
|
||||
tags: Macros [[Core Macros]]
|
||||
title: tag Macro
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -11,35 +11,7 @@ The <<.def tag>> [[macro|Macros]] generates a tag pill for a specified tag. Clic
|
||||
|
||||
!! Parameters
|
||||
|
||||
; tag
|
||||
;tag
|
||||
: The title of the tag, defaulting to the [[current tiddler|Current Tiddler]]
|
||||
|
||||
!! CSS classes
|
||||
|
||||
<<.from-version "v5.3.4">>
|
||||
|
||||
; `tc-tag-missing`
|
||||
: This class is defined if a tag does ''not exist'' as a tiddler.
|
||||
|
||||
; `tc-tag-exists`
|
||||
: This class is defined if a tag does exist as a tiddler
|
||||
|
||||
!!! Defining the class
|
||||
|
||||
To define the `tc-tag-missing` class a stylesheet tiddler needs to be created. The default font-style for missing tiddler links is //italic//, so it's used for the example code below. Eg:
|
||||
|
||||
''title:'' `myTagsStylesheet`<br>
|
||||
''tag:'' `$:/tags/Stylesheet`
|
||||
|
||||
<<copy-to-clipboard-above-right src:"""
|
||||
.tc-tag-missing {
|
||||
font-style: italic;
|
||||
}
|
||||
""">>
|
||||
```
|
||||
.tc-tag-missing {
|
||||
font-style: italic;
|
||||
}
|
||||
```
|
||||
|
||||
<<.macro-examples "tag">>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20150221211317000
|
||||
modified: 20240228131331605
|
||||
modified: 20230725203751870
|
||||
tags: [[tag Macro]] [[Macro Examples]]
|
||||
title: tag Macro (Examples)
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -7,26 +7,22 @@ type: text/vnd.tiddlywiki
|
||||
<$macrocall $name=".example" n="1" eg="""<<tag>>"""/>
|
||||
<$macrocall $name=".example" n="2" eg="""<<tag Concepts>>"""/>
|
||||
|
||||
The Following tag can be shown with a font-style: //italic// if the corresponding stylesheet exists. See: [[tag Macro]]
|
||||
|
||||
<$macrocall $name=".example" n="3" eg="""<<tag "Does not exist">>"""/>
|
||||
|
||||
If a [[list widget|ListWidget]] generates multiple tag macros for the same tag, clicking any of them opens dropdowns on all of them, as in the example below. This is usually unwanted.
|
||||
<$macrocall $name=".example" n="4" eg="""<$list filter="[tag[HelloThere]]">
|
||||
<$macrocall $name=".example" n="3" eg="""<$list filter="[tag[HelloThere]]">
|
||||
|
||||
* <$link/> is tagged with: <$list filter="[<currentTiddler>tags[]]"> <<tag>> </$list>
|
||||
|
||||
</$list>"""/>
|
||||
|
||||
Adding the `counter="transclusion"` attribute to the list widget that generates multiple identical tag macros causes each of them to be identified as a unique one. Clicking on any of them opens only a single dropdown.
|
||||
<$macrocall $name=".example" n="5" eg="""<$list filter="[tag[HelloThere]]" counter="transclusion">
|
||||
<$macrocall $name=".example" n="4" eg="""<$list filter="[tag[HelloThere]]" counter="transclusion">
|
||||
|
||||
* <$link/> is tagged with: <$list filter="[<currentTiddler>tags[]]"> <<tag>> </$list>
|
||||
|
||||
</$list>"""/>
|
||||
|
||||
A slightly more performant option is to use the `variable="transclusion"` attribute in the list widget. In this case, the variable `<<transclusion>>` has to be used inside the list widget instead of the `<<currentTiddler>>` .
|
||||
<$macrocall $name=".example" n="6" eg="""<$list filter="[tag[HelloThere]]" variable="transclusion">
|
||||
<$macrocall $name=".example" n="5" eg="""<$list filter="[tag[HelloThere]]" variable="transclusion">
|
||||
|
||||
* <$link to=<<transclusion>>/> is tagged with: <$list filter="[<transclusion>tags[]]"> <<tag>> </$list>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
caption: tag-picker
|
||||
created: 20161128191316701
|
||||
modified: 20230616114543787
|
||||
modified: 20161128191435641
|
||||
tags: Macros [[Core Macros]]
|
||||
title: tag-picker Macro
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -9,17 +9,9 @@ The <<.def tag-picker>> [[macro|Macros]] generates a combination of a text box a
|
||||
|
||||
!! Parameters
|
||||
|
||||
; actions
|
||||
: Action widgets to be triggered when the pill is clicked. Within the text, the variable <<.var tag>> contains the title of the selected tag.
|
||||
|
||||
; tagField
|
||||
: <<.from-version 5.1.23>> The specified ''field'' that gets updated with the selected tag. Defaults to `tags`.
|
||||
|
||||
; tiddler
|
||||
: <<.from-version 5.3.4>> Defines the target tiddler, which should be manipulated. Defaults to: <<.var currentTiddler>>.
|
||||
|
||||
; tagListFilter
|
||||
: <<.from-version 5.3.4>> This parameter defaults to: `[tags[]]` which creates a list of all existing tags. If the tag list should come from a different source the filter should look similar to eg: `[<listSource>get[field-name]enlist-input[]]`.
|
||||
|
||||
;actions
|
||||
: Action widgets to be triggered when the pill is clicked. Within the text, the variable ''tag'' contains the title of the selected tag.
|
||||
;tagField
|
||||
: <<.from-version 5.1.23>> The ''field'' that gets updated with the selected tag. Defaults to ''tags''.
|
||||
|
||||
<<.macro-examples "tag-picker">>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20130826122000000
|
||||
modified: 20240520162828577
|
||||
modified: 20220613124446953
|
||||
tags: Mechanisms
|
||||
title: PluginMechanism
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -16,10 +16,6 @@ By convention, plugin titles have the form `$:/plugins/<publisher>/<name>`. Plug
|
||||
|
||||
When [[running TiddlyWiki under Node.js|TiddlyWiki on Node.js]], plugins can also be stored as individual tiddler files in [[PluginFolders]].
|
||||
|
||||
! Plugin Stability
|
||||
|
||||
{{Plugin Stability}}
|
||||
|
||||
! Plugin Types
|
||||
|
||||
{{Plugin Types}}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
caption: tm-copy-to-clipboard
|
||||
created: 20171215150056004
|
||||
modified: 20240523174013095
|
||||
modified: 20171215150600888
|
||||
tags: Messages
|
||||
title: WidgetMessage: tm-copy-to-clipboard
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -11,8 +11,6 @@ It requires the following properties on the `event` object:
|
||||
|
||||
|!Name |!Description |
|
||||
|param |Text to be copied to the clipboard |
|
||||
|successNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation succeeds |
|
||||
|failureNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation fails |
|
||||
|
||||
This message is usually generated with the ButtonWidget. It is handled by the TiddlyWiki core.
|
||||
|
||||
|
||||
@@ -23,6 +23,10 @@ The following parameters are used:
|
||||
|header-* |Headers with string values |
|
||||
|password-header-* |Headers with values taken from the password store |
|
||||
|password-query-* |Query string parameters with values taken from the password store |
|
||||
|basic-auth-username |<<.from-version "5.3.4">> Optional username for HTTP basic authentication |
|
||||
|basic-auth-username-from-store |<<.from-version "5.3.4">> Optional username for HTTP basic authentication, specified as the name of the entry in the password store containing the username |
|
||||
|basic-auth-password |<<.from-version "5.3.4">> Optional password for HTTP basic authentication |
|
||||
|basic-auth-password-from-store |<<.from-version "5.3.4">> Optional password for HTTP basic authentication, specified as the name of the entry in the password store containing the password |
|
||||
|var-* |Variables to be passed to the completion and progress handlers (without the "var-" prefix) |
|
||||
|bind-status |Title of tiddler to which the status of the request ("pending", "complete", "error") should be bound |
|
||||
|bind-progress |Title of tiddler to which the progress of the request (0 to 100) should be bound |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20140723103751357
|
||||
modified: 20240523174013095
|
||||
modified: 20140723103751357
|
||||
tags: Messages
|
||||
title: WidgetMessage: tm-permalink
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -12,7 +12,5 @@ The permalink message supports the following properties on the `event` object:
|
||||
|!Name |!Description |
|
||||
|param |Title of the tiddler to be permalinked |
|
||||
|tiddlerTitle |The current tiddler (used by default if the tiddler title isn't specified in the `param`) |
|
||||
|successNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation succeeds |
|
||||
|failureNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation fails |
|
||||
|
||||
The permalink message can be generated by the ButtonWidget, and is handled by the story mechanism.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20140723103751357
|
||||
modified: 20240523174013095
|
||||
modified: 20140723103751357
|
||||
tags: Messages
|
||||
title: WidgetMessage: tm-permaview
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -12,7 +12,5 @@ The permaview message supports the following properties on the `event` object:
|
||||
|!Name |!Description |
|
||||
|param |Title of the tiddler to be navigated within the permaview |
|
||||
|tiddlerTitle |The current tiddler (used by default if the tiddler title isn't specified in the `param`) |
|
||||
|successNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation succeeds |
|
||||
|failureNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation fails |
|
||||
|
||||
The permaview message can be generated by the ButtonWidget, and is handled by the story mechanism.
|
||||
|
||||
@@ -4,7 +4,7 @@ tags: [[Releases]]
|
||||
title: TiddlyWiki5 Versioning
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
Each release of TiddlyWiki5 is identified by a version number that complies with a variant of [[Semantic Versioning 2.0.0|http://semver.org/]] standard.
|
||||
Each release of TiddlyWiki5 is identified by a version number that complies with the [[Semantic Versioning 2.0.0|http://semver.org/]] standard.
|
||||
|
||||
! TiddlyWiki Core Version
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
created: 20240520155341641
|
||||
modified: 20240520162820882
|
||||
tags: PluginMechanism
|
||||
title: Plugin Stability
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
Plugins are recommended to have a `stability` field that communicates the state of development of the plugin. It can contain the following values:
|
||||
|
||||
* ''STABILITY_0_DEPRECATED'' - Deprecated. This plugin is not recommended for new projects
|
||||
* ''STABILITY_1_EXPERIMENTAL'' - Experimental. Non-backward compatible changes or removal may occur in any future release. Use of the plugin is not recommended in production environments
|
||||
* ''STABILITY_2_STABLE'' - Stable.
|
||||
* ''STABILITY_3_LEGACY'' - Legacy. Although this plugin is unlikely to be removed, it is no longer actively maintained, and other alternatives are available
|
||||
|
||||
These stability levels are taken from the Node.js project - https://nodejs.org/api/documentation.html#stability-index.
|
||||
@@ -1,8 +1,8 @@
|
||||
code-body: yes
|
||||
created: 20150117152607000
|
||||
modified: 20240317091700545
|
||||
modified: 20240229155550000
|
||||
tags: $:/tags/Macro
|
||||
title: $:/editions/tw5.com/doc-macros
|
||||
code-body: yes
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
\whitespace trim
|
||||
@@ -165,7 +165,7 @@ This is an example tiddler. See [[Table-of-Contents Macros (Examples)]].
|
||||
<dd><$button set=<<.state>> setTo="">Hide</$button></dd>
|
||||
</dl>
|
||||
<blockquote class="doc-example-result">
|
||||
<$transclude $variable="eg" $mode="block"/>
|
||||
<<eg>>
|
||||
</blockquote>
|
||||
</$reveal>
|
||||
</$list>
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
created: 20230616104546608
|
||||
modified: 20240214174032498
|
||||
tags: [[tag-picker Macro]] [[Macro Examples]]
|
||||
title: tag-picker Macro (Examples)
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.warning """The first example will set the tag of the <<.tid currentTiddler>> so you should copy / paste it to a new tiddler for testing. Otherwise you'll change "this tiddler" """>>
|
||||
|
||||
<$macrocall $name=".example" n="1"
|
||||
eg="""Use all existing tags and set the ''tags'' field here: <<tag-picker>>
|
||||
"""/>
|
||||
|
||||
----
|
||||
|
||||
<$let transclusion=test>
|
||||
|
||||
<<.tip """The following examples use a temporary tiddler: $:/temp/test/tag-picker. So this tiddler will not be changed """>>
|
||||
|
||||
|
||||
<$macrocall $name=".example" n="2"
|
||||
eg="""$:/temp/test/tag-picker ''tags'': <$text text={{{ [[$:/temp/test/tag-picker]get[tags]enlist-input[]join[, ]else[n/a]] }}}/>
|
||||
|
||||
Use all existing tags and set the $:/temp/test/tag-picker ''tags'' field: <<tag-picker tiddler:"$:/temp/test/tag-picker">>
|
||||
"""/>
|
||||
|
||||
----
|
||||
|
||||
<<.tip """Use the following example to populate the $:/temp/test/tag-picker ''foo''-field, which are needed by some examples below """>>
|
||||
|
||||
<$macrocall $name=".example" n="3"
|
||||
eg="""$:/temp/test/tag-picker ''foo'': <$text text={{{ [[$:/temp/test/tag-picker]get[foo]enlist-input[]join[, ]else[n/a]] }}}/>
|
||||
|
||||
Use all existing tags and set the $:/temp/test/tag-picker ''foo'' field: <<tag-picker tagField:"foo" tiddler:"$:/temp/test/tag-picker">>
|
||||
"""/>
|
||||
|
||||
----
|
||||
|
||||
<<.tip """The following example expects some values in the "foo" field of the tiddler $:/temp/test/tag-picker, which can be created by the example above.""">>
|
||||
|
||||
<$macrocall $name=".example" n="4" eg="""\procedure listSource() $:/temp/test/tag-picker
|
||||
|
||||
$:/temp/test/tag-picker foo: <$text text={{{ [[$:/temp/test/tag-picker]get[foo]enlist-input[]join[, ]else[n/a]] }}}/><br>
|
||||
$:/temp/test/tag-picker bar: <$text text={{{ [[$:/temp/test/tag-picker]get[bar]enlist-input[]join[, ]else[n/a]] }}}/>
|
||||
|
||||
Use $:/temp/test/tag-picker ''foo'' field as source and set ''bar'': <<tag-picker tagField:"bar" tagListFilter:"[<listSource>get[foo]enlist-input[]]" tiddler:"$:/temp/test/tag-picker">>
|
||||
"""/>
|
||||
|
||||
----
|
||||
|
||||
<<.tip """The following example expects some values in the "foo" field of the tiddler $:/temp/test/tag-picker, which can be created by the example above.<br>
|
||||
It will also add completely new tags to the bar-field and the source tiddlers foo-field. New tags can be entered by typing into the tag-name input
|
||||
""">>
|
||||
|
||||
<$macrocall $name=".example" n="5" eg="""
|
||||
\procedure listSource() $:/temp/test/tag-picker
|
||||
\procedure listSourceField() foo
|
||||
|
||||
\procedure addNewTagToSource()
|
||||
<$action-listops $tiddler=<<listSource>> $field=<<listSourceField>> $subfilter='[<listSource>get<listSourceField>enlist-input[]] [<tag>trim[]]'/>
|
||||
\end
|
||||
|
||||
$:/temp/test/tag-picker foo: <$text text={{{ [[$:/temp/test/tag-picker]get[foo]enlist-input[]join[, ]else[n/a]] }}}/><br>
|
||||
$:/temp/test/tag-picker ''bar'': <$text text={{{ [[$:/temp/test/tag-picker]get[bar]enlist-input[]join[, ]else[n/a]] }}}/>
|
||||
|
||||
Use $:/temp/test/tag-picker ''foo'' field as source and set ''bar'': <$macrocall $name="tag-picker" tagField="bar" tagListFilter="[<listSource>get<listSourceField>enlist-input[]]" tiddler="$:/temp/test/tag-picker" actions=<<addNewTagToSource>>/>
|
||||
|
||||
"""/>
|
||||
|
||||
</$let>
|
||||
@@ -1,33 +0,0 @@
|
||||
title: TestCases/DataWidget/ImportCompound
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
description: Importing a compound payload tiddler and adding custom fields
|
||||
display-format: plaintext
|
||||
|
||||
title: Narrative
|
||||
|
||||
Using the data widget to import a tiddler stored in a compound tiddler
|
||||
+
|
||||
title: Output
|
||||
|
||||
<$data $compound-tiddler="Compound" custom="Alpha"/>
|
||||
+
|
||||
title: Compound
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Payload Tiddler
|
||||
tags: Alpha Beta Gamma
|
||||
|
||||
This is a payload tiddler from a compound tiddler
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>[
|
||||
{
|
||||
"title": "Payload Tiddler",
|
||||
"tags": "Alpha Beta Gamma",
|
||||
"text": "This is a payload tiddler from a compound tiddler",
|
||||
"custom": "Alpha"
|
||||
}
|
||||
]</p>
|
||||
@@ -1,49 +0,0 @@
|
||||
title: TestCases/DataWidget/ImportedFilter
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
description: Imported filter definition
|
||||
display-format: plaintext
|
||||
|
||||
title: Narrative
|
||||
|
||||
Using the data widget to create copies of all the tiddlers with the title prefix "Day: T", adding the field "custom" set to "Beta"
|
||||
+
|
||||
title: Output
|
||||
|
||||
<$data $filter="[prefix[Day: T]]" custom="Beta"/>
|
||||
+
|
||||
title: Day: Monday
|
||||
text: Today is Monday
|
||||
+
|
||||
title: Day: Tuesday
|
||||
text: Today is Tuesday
|
||||
+
|
||||
title: Day: Wednesday
|
||||
text: Today is Wednesday
|
||||
+
|
||||
title: Day: Thursday
|
||||
text: Today is Thursday
|
||||
+
|
||||
title: Day: Friday
|
||||
text: Today is Friday
|
||||
+
|
||||
title: Day: Saturday
|
||||
text: Today is Saturday
|
||||
+
|
||||
title: Day: Sunday
|
||||
text: Today is Sunday
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>[
|
||||
{
|
||||
"title": "Day: Thursday",
|
||||
"text": "Today is Thursday",
|
||||
"custom": "Beta"
|
||||
},
|
||||
{
|
||||
"title": "Day: Tuesday",
|
||||
"text": "Today is Tuesday",
|
||||
"custom": "Beta"
|
||||
}
|
||||
]</p>
|
||||
@@ -1,29 +0,0 @@
|
||||
title: TestCases/DataWidget/ImportedTiddler
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
description: Imported tiddler definition
|
||||
display-format: plaintext
|
||||
|
||||
title: Narrative
|
||||
|
||||
Using the data widget to create a tiddler that is a copy of the tiddler "Hello" with the addition of the field "custom" set to "Alpha"
|
||||
+
|
||||
title: Output
|
||||
|
||||
<$data $tiddler="Hello" custom="Alpha"/>
|
||||
+
|
||||
title: Hello
|
||||
modifier: JoeBloggs
|
||||
|
||||
This is the Hello tiddler
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>[
|
||||
{
|
||||
"title": "Hello",
|
||||
"modifier": "JoeBloggs",
|
||||
"text": "This is the Hello tiddler",
|
||||
"custom": "Alpha"
|
||||
}
|
||||
]</p>
|
||||
@@ -1,30 +0,0 @@
|
||||
title: TestCases/DataWidget/Refreshing
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
description: Refreshing the data widget
|
||||
display-format: plaintext
|
||||
|
||||
title: Narrative
|
||||
|
||||
Verifying that the JSON output of the data widget is correctly refreshed when the data changes
|
||||
+
|
||||
title: Output
|
||||
|
||||
<$data title="Epsilon" text={{Subject}}/>
|
||||
+
|
||||
title: Subject
|
||||
|
||||
Nothing
|
||||
+
|
||||
title: Actions
|
||||
|
||||
<$action-setfield $tiddler="Subject" text="Theta"/>
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>[
|
||||
{
|
||||
"title": "Epsilon",
|
||||
"text": "Theta"
|
||||
}
|
||||
]</p>
|
||||
@@ -1,22 +0,0 @@
|
||||
title: TestCases/DataWidget/SimpleTiddler
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
description: Simple tiddler definition
|
||||
display-format: plaintext
|
||||
|
||||
title: Narrative
|
||||
|
||||
Using the data widget to create a tiddler with the title "Epsilon" and the text "Theta"
|
||||
+
|
||||
title: Output
|
||||
|
||||
<$data title="Epsilon" text="Theta"/>
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>[
|
||||
{
|
||||
"title": "Epsilon",
|
||||
"text": "Theta"
|
||||
}
|
||||
]</p>
|
||||
@@ -1,15 +0,0 @@
|
||||
title: TestCases/TestCaseWidget/FailingTest
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec-failing]]
|
||||
description: An example of a failing test
|
||||
|
||||
title: Narrative
|
||||
|
||||
This test case intentionally fails (in order to show how failures are displayed)
|
||||
+
|
||||
title: Output
|
||||
|
||||
The sum is <$text text={{{ [[2]add[2]] }}}/>.
|
||||
+
|
||||
title: ExpectedResult
|
||||
text: <p>The sum is not 8.</p>
|
||||
@@ -1,12 +0,0 @@
|
||||
title: TestCases/TestCaseWidget/NoExpectedResults
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
description: A testcase that does not specify expected results
|
||||
|
||||
title: Narrative
|
||||
|
||||
This testcase will display without the pass/fail icons because it does not include an `ExpectedResults` tiddler, and so will only be rendered, and not be executed as a test
|
||||
+
|
||||
title: Output
|
||||
|
||||
This is the output
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user