1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-01-24 20:04:40 +00:00

Compare commits

..

7 Commits

Author SHA1 Message Date
Jeremy Ruston
08cc320d34 Add tests that the core plugins all have a valid stability field 2024-05-21 11:21:36 +01:00
Jeremy Ruston
5837570196 Docs 2024-05-20 17:31:51 +01:00
Jeremy Ruston
f2f6b72056 Merge branch 'master' into plugin-stability-badges 2024-05-20 11:34:08 +01:00
Jeremy Ruston
21b02e8ba5 Styling tweaks 2024-05-07 18:04:13 +01:00
Jeremy Ruston
404015c455 Need to set plugin library location for prerelease 2024-05-07 18:04:03 +01:00
Jeremy Ruston
25b1900849 Fix plugin library URL 2024-05-07 17:43:31 +01:00
Jeremy Ruston
29373c3359 Initial Commit 2024-05-07 14:20:29 +01:00
229 changed files with 240 additions and 23235 deletions

View File

@@ -393,17 +393,6 @@ node $TW5_BUILD_TIDDLYWIKI \
--rendertiddler $:/core/save/empty plugins/tiddlywiki/highlight/empty.html text/plain \
|| exit 1
# /plugins/tiddlywiki/geospatial/index.html Demo wiki with geospatial plugin
# /plugins/tiddlywiki/geospatial/empty.html Empty wiki with geospatial plugin
node $TW5_BUILD_TIDDLYWIKI \
./editions/geospatialdemo \
--verbose \
--load $TW5_BUILD_OUTPUT/build.tid \
--output $TW5_BUILD_OUTPUT \
--rendertiddler $:/core/save/all plugins/tiddlywiki/geospatial/index.html text/plain \
--rendertiddler $:/core/save/empty plugins/tiddlywiki/geospatial/empty.html text/plain \
|| exit 1
######################################################
#
# Language editions

View File

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

@@ -0,0 +1,3 @@
title: $:/library/sjcl.js
type: application/javascript
library: yes

View File

@@ -1,32 +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.tid",
"isTiddlerFile": true
}
]
}

View File

@@ -1,7 +1,7 @@
title: $:/core/images/standard-layout
title: $:/core/images/default-layout
tags: $:/tags/Image
\parameters (size:"22pt")
<svg width=<<size>> height=<<size>> class="tc-image-standard-layout tc-image-button" viewBox="0 0 128 128">
<svg width=<<size>> height=<<size>> class="tc-image-default-layout tc-image-button" viewBox="0 0 128 128">
<path d="M71.93 72A8.07 8.07 0 0 1 80 80.07v7.86A8.071 8.071 0 0 1 71.93 96H8.07A8.067 8.067 0 0 1 0 87.93v-7.86A8.072 8.072 0 0 1 8.07 72h63.86Zm0 32a8.07 8.07 0 0 1 8.07 8.07v7.86a8.071 8.071 0 0 1-8.07 8.07H8.07A8.067 8.067 0 0 1 0 119.93v-7.86A8.072 8.072 0 0 1 8.07 104h63.86Zm0-104A8.068 8.068 0 0 1 80 8.07v47.86A8.073 8.073 0 0 1 71.93 64H8.07A8.07 8.07 0 0 1 0 55.93V8.07A8.072 8.072 0 0 1 8.07 0h63.86Zm48 0c2.14 0 4.193.85 5.706 2.364A8.067 8.067 0 0 1 128 8.07v111.86c0 2.14-.85 4.193-2.364 5.706A8.067 8.067 0 0 1 119.93 128H96.07c-2.14 0-4.193-.85-5.706-2.364A8.067 8.067 0 0 1 88 119.93V8.07c0-2.14.85-4.193 2.364-5.706A8.067 8.067 0 0 1 96.07 0h23.86ZM116 24h-16a3.995 3.995 0 0 0-2.828 1.172 3.995 3.995 0 0 0 0 5.656A3.995 3.995 0 0 0 100 32h16a3.995 3.995 0 0 0 2.828-1.172 3.995 3.995 0 0 0 0-5.656A3.995 3.995 0 0 0 116 24Z"/>
</svg>

View File

@@ -70,7 +70,7 @@ No: No
OfficialPluginLibrary: Official ~TiddlyWiki Plugin Library
OfficialPluginLibrary/Hint: The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team.
PageTemplate/Description: the default ~TiddlyWiki layout
PageTemplate/Name: Standard Layout
PageTemplate/Name: Default ~PageTemplate
PluginReloadWarning: Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect
RecentChanges/DateFormat: DDth MMM YYYY
Shortcuts/Input/AdvancedSearch/Hint: Open the ~AdvancedSearch panel from within the sidebar search field

View File

@@ -120,7 +120,7 @@ Command.prototype.fetchFile = function(url,options,callback,redirectCount) {
}
});
response.on("error",function(e) {
self.commander.log("Error on GET request: " + e);
console.log("Error on GET request: " + e);
callback(e);
});
});

View File

@@ -47,7 +47,7 @@ Render individual tiddlers and save the results to the specified files
$tw.utils.each(tiddlers,function(title) {
var filepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);
if(self.commander.verbose) {
self.commander.log("Rendering \"" + title + "\" to \"" + filepath + "\"");
console.log("Rendering \"" + title + "\" to \"" + filepath + "\"");
}
var parser = wiki.parseTiddler(template || title),
widgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title,storyTiddler: title})}),
@@ -63,4 +63,4 @@ Render individual tiddlers and save the results to the specified files
exports.Command = Command;
})();

View File

@@ -48,7 +48,7 @@ Saves individual tiddlers in their raw text or binary format to the specified fi
}
});
if(self.commander.verbose) {
self.commander.log("Saving \"" + title + "\" to \"" + filepath + "\"");
console.log("Saving \"" + title + "\" to \"" + fileInfo.filepath + "\"");
}
try {
$tw.utils.saveTiddlerToFileSync(tiddler,fileInfo);

View File

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

View File

@@ -33,13 +33,7 @@ function Server(options) {
this.routes = options.routes || [];
this.authenticators = options.authenticators || [];
this.wiki = options.wiki;
this.logger = new $tw.utils.Logger("server",{colour: "cyan"});
this.logger.setPrefix(":" + process.pid + "-" + (Number(new Date()) - 1095776640000));
this.boot = options.boot || $tw.boot;
// Name the server and init the boot state
this.servername = $tw.utils.transliterateToSafeASCII(this.get("server-name") || this.wiki.getTiddlerText("$:/SiteTitle") || "TiddlyWiki5");
this.boot.origin = this.get("origin")? this.get("origin"): this.protocol+"://"+this.get("host")+":"+this.get("port");
this.boot.pathPrefix = this.get("path-prefix") || "";
// Initialise the variables
this.variables = $tw.utils.extend({},this.defaultVariables);
if(options.variables) {
@@ -98,6 +92,10 @@ function Server(options) {
this.protocol = "https";
}
this.transport = require(this.protocol);
// Name the server and init the boot state
this.servername = $tw.utils.transliterateToSafeASCII(this.get("server-name") || this.wiki.getTiddlerText("$:/SiteTitle") || "TiddlyWiki5");
this.boot.origin = this.get("origin")? this.get("origin"): this.protocol+"://"+this.get("host")+":"+this.get("port");
this.boot.pathPrefix = this.get("path-prefix") || "";
}
/*
@@ -289,9 +287,9 @@ Server.prototype.requestHandler = function(request,response,options) {
var route = self.findMatchingRoute(request,state);
// Optionally output debug info
if(self.get("debug-level") !== "none") {
self.logger.log("Request path:",JSON.stringify(state.urlInfo.href));
self.logger.log("Request headers:",JSON.stringify(request.headers));
self.logger.log("authenticatedUsername:",state.authenticatedUsername);
console.log("Request path:",JSON.stringify(state.urlInfo));
console.log("Request headers:",JSON.stringify(request.headers));
console.log("authenticatedUsername:",state.authenticatedUsername);
}
// Return a 404 if we didn't find a route
if(!route) {

View File

@@ -29,11 +29,7 @@ var THROTTLE_REFRESH_TIMEOUT = 400;
exports.startup = function() {
// Set up the title
$tw.titleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TITLE_TITLE, {
document: $tw.fakeDocument,
parseAsInline: true,
importPageMacros: true,
});
$tw.titleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TITLE_TITLE,{document: $tw.fakeDocument, parseAsInline: true});
$tw.titleContainer = $tw.fakeDocument.createElement("div");
$tw.titleWidgetNode.render($tw.titleContainer,null);
document.title = $tw.titleContainer.textContent;

View File

@@ -39,7 +39,6 @@ exports.startup = function() {
method: params.method,
body: params.body,
binary: params.binary,
useDefaultHeaders: params.useDefaultHeaders,
oncompletion: params.oncompletion,
onprogress: params.onprogress,
bindStatus: params["bind-status"],
@@ -48,11 +47,7 @@ exports.startup = function() {
headers: getPropertiesWithPrefix(params,"header-"),
passwordHeaders: getPropertiesWithPrefix(params,"password-header-"),
queryStrings: getPropertiesWithPrefix(params,"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"]
passwordQueryStrings: getPropertiesWithPrefix(params,"password-query-")
});
});
$tw.rootWidget.addEventListener("tm-http-cancel-all-requests",function(event) {
@@ -73,10 +68,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 && event.paramObject.successNotification,
failureNotification: event.paramObject && event.paramObject.failureNotification
});
$tw.utils.copyToClipboard(event.param);
});
// Install the tm-focus-selector message
$tw.rootWidget.addEventListener("tm-focus-selector",function(event) {

View File

@@ -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") {

View File

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

View File

@@ -69,7 +69,7 @@ HttpClient.prototype.cancelAllHttpRequests = function() {
for(var t=this.requests.length - 1; t--; t>=0) {
var requestInfo = this.requests[t];
requestInfo.request.cancel();
}
}
}
this.requests = [];
this.updateRequestTracker();
@@ -100,10 +100,6 @@ 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;
@@ -116,7 +112,6 @@ function HttpClientRequest(options) {
this.method = options.method || "GET";
this.body = options.body || "";
this.binary = options.binary || "";
this.useDefaultHeaders = options.useDefaultHeaders !== "false" ? true : false,
this.variables = options.variables;
var url = options.url;
$tw.utils.each(options.queryStrings,function(value,name) {
@@ -133,11 +128,6 @@ 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) {
@@ -166,7 +156,6 @@ HttpClientRequest.prototype.send = function(callback) {
this.xhr = $tw.utils.httpRequest({
url: this.url,
type: this.method,
useDefaultHeaders: this.useDefaultHeaders,
headers: this.requestHeaders,
data: this.body,
returnProp: this.binary === "" ? "responseText" : "response",
@@ -242,8 +231,7 @@ Make an HTTP request. Options are:
exports.httpRequest = function(options) {
var type = options.type || "GET",
url = options.url,
useDefaultHeaders = options.useDefaultHeaders !== false ? true : false,
headers = options.headers || (useDefaultHeaders ? {accept: "application/json"} : {}),
headers = options.headers || {accept: "application/json"},
hasHeader = function(targetHeader) {
targetHeader = targetHeader.toLowerCase();
var result = false;
@@ -269,7 +257,7 @@ exports.httpRequest = function(options) {
if(hasHeader("Content-Type") && ["application/x-www-form-urlencoded","multipart/form-data","text/plain"].indexOf(getHeader["Content-Type"]) === -1) {
return false;
}
return true;
return true;
},
returnProp = options.returnProp || "responseText",
request = new XMLHttpRequest(),
@@ -319,10 +307,10 @@ exports.httpRequest = function(options) {
request.setRequestHeader(headerTitle,header);
});
}
if(data && !hasHeader("Content-Type") && useDefaultHeaders) {
if(data && !hasHeader("Content-Type")) {
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
}
if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers) && useDefaultHeaders) {
if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers)) {
request.setRequestHeader("X-Requested-With","TiddlyWiki");
}
// Send data

View File

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

View File

@@ -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() {

View File

@@ -21,7 +21,6 @@ function Logger(componentName,options) {
options = options || {};
this.componentName = componentName || "";
this.colour = options.colour || "white";
this.prefix = options.prefix || "";
this.enable = "enable" in options ? options.enable : true;
this.save = "save" in options ? options.save : true;
this.saveLimit = options.saveLimit || 100 * 1024;
@@ -34,20 +33,6 @@ Logger.prototype.setSaveBuffer = function(logger) {
this.saveBufferLogger = logger;
};
/*
Change the output colour
*/
Logger.prototype.setColour = function(colour) {
this.colour = colour || "white";
};
/*
Change the prefix
*/
Logger.prototype.setPrefix = function(prefix) {
this.prefix = prefix || "";
};
/*
Log a message
*/

View File

@@ -14,12 +14,8 @@ Utilities for working with the TiddlyWiki repository file structure
/*
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 || {};
exports.getAllPlugins = function() {
var fs = require("fs"),
path = require("path"),
tiddlers = {};
@@ -43,9 +39,9 @@ exports.getAllPlugins = function(options) {
}
}
};
$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);
$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);
return tiddlers;
};

View File

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

View File

@@ -31,49 +31,34 @@ DataWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
this.dataPayload = this.computeDataTiddlerValues(); // Array of $tw.Tiddler objects
this.domNode = this.document.createTextNode(this.readDataTiddlerValuesAsJson());
parent.insertBefore(this.domNode,nextSibling);
this.domNodes.push(this.domNode);
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() {
// Nothing to do here
// Construct the child widgets
this.makeChildWidgets();
};
/*
Read the tiddler value(s) from a data widget as an array of tiddler field objects (not $tw.Tiddler objects)
Read the tiddler value(s) from a data widget must be called after the .render() method
*/
DataWidget.prototype.readDataTiddlerValues = function() {
var results = [];
$tw.utils.each(this.dataPayload,function(tiddler,index) {
results.push(tiddler.getFieldStrings());
});
return results;
};
/*
Read the tiddler value(s) from a data widget as an array of tiddler field objects (not $tw.Tiddler objects)
*/
DataWidget.prototype.readDataTiddlerValuesAsJson = function() {
return JSON.stringify(this.readDataTiddlerValues(),null,4);
};
/*
Compute list of tiddlers from a data widget
*/
DataWidget.prototype.computeDataTiddlerValues = function() {
var self = this;
// Read any attributes not prefixed with $
// 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")) {
@@ -101,22 +86,21 @@ DataWidget.prototype.computeDataTiddlerValues = function() {
tiddlers.push.apply(tiddlers,this.extractCompoundTiddler(title));
}
}
// Return the literal item if none of the special attributes were used
if(!this.hasAttribute("$tiddler") && !this.hasAttribute("$filter") && !this.hasAttribute("$compound-tiddler")) {
// Convert the literal item to field strings
item = item.getFieldStrings();
if(tiddlers.length === 0) {
if(Object.keys(item).length > 0 && !!item.title) {
return [new $tw.Tiddler(item)];
return [item];
} else {
return [];
}
} else {
// Apply the item fields to each of the tiddlers
delete item.title; // Do not overwrite the title
if(Object.keys(item).length > 0) {
$tw.utils.each(tiddlers,function(tiddler,index) {
tiddlers[index] = new $tw.Tiddler(tiddler,item);
});
}
return tiddlers;
var results = [];
$tw.utils.each(tiddlers,function(tiddler,index) {
var fields = tiddler.getFieldStrings();
results.push($tw.utils.extend({},fields,item));
});
return results;
}
};
@@ -150,33 +134,12 @@ DataWidget.prototype.extractCompoundTiddler = function(title) {
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
DataWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
var newPayload = this.computeDataTiddlerValues();
if(hasPayloadChanged(this.dataPayload,newPayload)) {
this.dataPayload = newPayload;
this.domNode.textContent = this.readDataTiddlerValuesAsJson();
return true;
} else {
return false;
}
// 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;
};
/*
Compare two arrays of tiddlers and return true if they are different
*/
function hasPayloadChanged(a,b) {
if(a.length === b.length) {
for(var t=0; t<a.length; t++) {
if(!(a[t].isEqual(b[t]))) {
return true;
}
}
return false;
} else {
return true;
}
}
exports.data = DataWidget;
})();

View File

@@ -74,18 +74,6 @@ ParametersWidget.prototype.execute = function() {
self.setVariable(variableName,getValue(name));
}
});
} else {
// There is no parent transclude. i.e. direct rendering.
// We use default values only.
$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(self.parseTreeNode),function(attr,index) {
var name = attr.name;
// If the attribute name starts with $$ then reduce to a single dollar
if(name.substr(0,2) === "$$") {
name = name.substr(1);
}
var value = self.getAttribute(attr.name,"");
self.setVariable(name,value);
});
}
// Construct the child widgets
this.makeChildWidgets();

View File

@@ -77,13 +77,8 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) {
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) {
if(this.testcaseTestOutput && this.testcaseTestExpectedResult) {
var testcaseOutputContainer = $tw.fakeDocument.createElement("div");
var testcaseOutputWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTestOutput,{
document: $tw.fakeDocument,
@@ -106,7 +101,7 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) {
var testResult = "",
outputHTML = "",
expectedHTML = "";
if(shouldRunTests) {
if(this.testcaseTestOutput && this.testcaseTestExpectedResult) {
outputHTML = testcaseOutputContainer.children[0].innerHTML;
expectedHTML = this.testcaseWiki.getTiddlerText(this.testcaseTestExpectedResult);
if(outputHTML === expectedHTML) {
@@ -120,7 +115,7 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) {
this.setVariable("currentTiddler",this.testcaseTestOutput);
}
// Don't display anything if testHideIfPass is "yes" and the tests have passed
if(this.testcaseHideIfPass === "yes" && testResult !== "fail") {
if(this.testcaseHideIfPass === "yes" && testResult === "pass") {
return;
}
// Render the page root template of the subwiki

View File

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

View File

@@ -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,
@@ -316,8 +317,7 @@ Widget.prototype.getStateQualifier = function(name) {
Make a fake widget with specified variables, suitable for variable lookup in filters
*/
Widget.prototype.makeFakeWidgetWithVariables = function(variables) {
var self = this,
variables = variables || {};
var self = this;
return {
getVariable: function(name,opts) {
if($tw.utils.hop(variables,name)) {
@@ -335,7 +335,7 @@ Widget.prototype.makeFakeWidgetWithVariables = function(variables) {
};
} else {
opts = opts || {};
opts.variables = $tw.utils.extend(variables,opts.variables);
opts.variables = variables;
return self.getVariableInfo(name,opts);
};
},
@@ -494,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) {

View File

@@ -1,7 +1,7 @@
title: $:/core/ui/PageTemplate
name: {{$:/language/PageTemplate/Name}}
description: {{$:/language/PageTemplate/Description}}
icon: $:/core/images/standard-layout
icon: $:/core/images/default-layout
code-body: yes
\whitespace trim

View File

@@ -5,7 +5,6 @@ title: $:/core/ui/TestCaseTemplate
<$let
linkTarget="yes"
displayFormat={{!!display-format}}
testcaseTiddler=<<currentTiddler>>
>
<$testcase
testOutput="Output"

View File

@@ -15,7 +15,7 @@ title: $:/core/ui/testcases/DefaultTemplate
<div class="tc-test-case-wrapper">
<div class="tc-test-case-header">
<h2>
<$genesis $type={{{ [<linkTarget>!match[]then[$link]else[div]] }}} to=<<testcaseTiddler>>>
<$genesis $type={{{ [<linkTarget>!match[]then[$link]else[div]] }}}>
<%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]] %>
@@ -55,9 +55,7 @@ title: $:/core/ui/testcases/DefaultTemplate
<pre><$view tiddler="Output" format="plainwikified" mode="block"/></pre>
<%else%>
<$linkcatcher actions=<<linkcatcherActions>>>
<$tiddler tiddler="Output">
<$transclude $tiddler="Output" $mode="block"/>
</$tiddler>
<$transclude $tiddler="Output" $mode="block"/>
</$linkcatcher>
<%endif%>
</div>

View File

@@ -1,6 +1,6 @@
title: $:/config/OfficialPluginLibrary
tags: $:/tags/PluginLibrary
url: https://tiddlywiki.com/library/v5.3.4/index.html
caption: {{$:/language/OfficialPluginLibrary}}
tags: $:/tags/PluginLibrary
title: $:/config/OfficialPluginLibrary
url: https://tiddlywiki5-git-plugin-stability-badges-jermolenes-projects.vercel.app/library/v5.3.3/index.html
{{$:/language/OfficialPluginLibrary/Hint}}
Plugin library for https://tiddlywiki5-git-plugin-stability-badges-jermolenes-projects.vercel.app

View File

@@ -1,4 +0,0 @@
title: $:/DefaultTiddlers
HelloThere
$:/plugins/tiddlywiki/geospatial

View File

@@ -1,14 +0,0 @@
title: GeoFeatures
tags: $:/tags/GeospatialDemo
This is a list of all the tiddlers containing ~GeoJSON feature collections in this wiki (identified by the tag <<tag "$:/tags/GeoFeature">>). A ~GeoJSON feature collection is a list of features, each of which consists of a geometry and associated metadata.
<ul>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/GeoFeature]sort[caption]]">
<li>
<$link>
<$transclude field="caption"><$view field="title"/></$view>
</$link>
</li>
</$list>
</ul>

View File

@@ -1,27 +0,0 @@
title: Flickr Demo
caption: Flickr
tags: $:/tags/GeospatialDemo
! Retrieve Geotagged Flickr Photos
This demo will not work until you have set a Flickr API key in the [[Geospatial plugin settings|$:/plugins/tiddlywiki/geospatial/settings]].
<$button>
<$macrocall $name="flickr-get-album-items" albumID={{$:/config/flickr-param/album-id}}/>
Get Flickr album
</$button> <$edit-text tiddler="$:/config/flickr-param/album-id" tag="input"/> (parameter should be an album ID, e.g. 72157630297432522)
<$button>
<$macrocall $name="flickr-get-interesting-items"/>
Get Flickr interesting items
</$button>
<$button>
<$macrocall $name="flickr-get-photos-of-user-items" userID={{$:/config/flickr-param/user-id}}/>
Get Flickr photos of user
</$button> <$edit-text tiddler="$:/config/flickr-param/user-id" tag="input"/> (parameter should be a user ID, e.g. 35468148136@N01)
<$button>
<$macrocall $name="flickr-get-group-items" groupID={{$:/config/flickr-param/group-id}}/>
Get Flickr group
</$button> <$edit-text tiddler="$:/config/flickr-param/group-id" tag="input"/> (parameter should be an group ID, e.g. 22075379@N00)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 509 KiB

View File

@@ -1,2 +0,0 @@
title: Geospatial Plugin Logo
type: image/png

View File

@@ -1,37 +0,0 @@
title: HelloThere
//The latest build of the Geospatial Plugin can be found at:// https://tiddlywiki5-git-geospatial-plugin-jermolene.vercel.app/plugins/tiddlywiki/geospatial/index.html
!! Introduction
{{$:/plugins/tiddlywiki/geospatial/readme}}
!! Prerequisites
This demo requires that the API keys needed to access external services be obtained by the end user and manually configured. These keys are stored in the browser and so only need to be set up once. See the ''Settings'' tab of [[the plugin|$:/plugins/tiddlywiki/geospatial]] for details.
!! Demos
* Visit the ~GeoFeatures and ~GeoMarkers tabs to see the data loaded into this wiki
* Click on a link to a layer or marker to open the corresponding tiddler that includes a map
* Use the Flickr tab to retrieve geotagged photographs from Flickr
* Visit a ~GeoMarker tiddler and use the "Call ~TravelTime" button to calculate an isochrone from that location using the ~TravelTime API
! Map Showing All Features and Markers
<$geomap
state=<<qualify "$:/state/demo-map">>
startPosition="bounds"
>
<$list filter="[all[tiddlers+shadows]tag[$:/tags/GeoBaseLayer]]">
<$geobaselayer title=<<currentTiddler>>/>
</$list>
<$list filter="[all[tiddlers+shadows]tag[$:/tags/GeoMarker]]">
<$geolayer lat={{!!lat}} long={{!!long}} alt={{!!alt}} color={{!!color}} name={{!!caption}}/>
</$list>
<$list filter="[all[tiddlers+shadows]tag[$:/tags/GeoFeature]]">
<$geolayer json={{!!text}} color={{!!color}} name={{!!caption}}/>
</$list>
</$geomap>
<<tabs tabsList:"[all[tiddlers+shadows]tag[$:/tags/GeospatialDemo]]" default:"GeoMarkers">>

View File

@@ -1,53 +0,0 @@
title: GeoMarkers
tags: $:/tags/GeospatialDemo
\procedure onsuccess()
<$action-setfield
$tiddler="CurrentLocation"
tags="$:/tags/GeoMarker"
timestamp=<<timestamp>>
lat=<<latitude>>
long=<<longitude>>
alt=<<altitude>>
accuracy=<<accuracy>>
altitudeAccuracy=<<altitudeAccuracy>>
heading=<<heading>>
speed=<<speed>>
/>
\end
\procedure onerror()
<$action-setfield
$tiddler="CurrentLocation"
$field="text"
$value=<<error>>
/>
\end
\procedure onclick()
<$action-sendmessage
$message="tm-request-geolocation"
actionsSuccess=<<onsuccess>>
actionsError=<<onerror>>
/>
\end
This is a list of all the tiddlers containing ~GeoJSON markers in this wiki (identified by the tag <<tag "$:/tags/GeoMarker">>). A ~GeoJSON marker identifies a location via latitude and longitude (and optional altitude) and may also contain associated metadata in JSON format.
Click this button to create a marker from the current location. Your browser will ask for permission before granting the request. On some browsers it takes a couple of seconds for the location to appear.
<$button actions=<<onclick>>>
Request location
</$button>
{{CurrentLocation}}
<ul>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/GeoMarker]sort[caption]]">
<li>
<$link>
<$view field="caption"><$view field="title"/></$view>
</$link>
</li>
</$list>
</ul>

View File

@@ -1,3 +0,0 @@
title: $:/SiteSubtitle
Geographic Data Features for ~TiddlyWiki

View File

@@ -1,3 +0,0 @@
title: $:/SiteTitle
[img width=200 [Geospatial Plugin Logo]]<br>Geospatial Plugin

View File

@@ -1,6 +0,0 @@
title: $:/plugins/geospatial/demo/ViewTemplateBodyFilters
tags: $:/tags/ViewTemplateBodyFilter
list-before: $:/config/ViewTemplateBodyFilters/stylesheet
[tag[$:/tags/GeoFeature]then[ui/geofeature]]
[tag[$:/tags/GeoMarker]then[ui/geomarker]]

View File

@@ -1,9 +0,0 @@
title: cities/LimehouseTownHall
tags: $:/tags/GeoMarker
caption: Limehouse Town Hall
lat: 51.51216651476898
long: -0.03138562132137639
alt: 0
This is Limehouse Town Hall!

View File

@@ -1,9 +0,0 @@
title: cities/Motovun
tags: $:/tags/GeoMarker
icon: Motovun Jack.svg
caption: Motovun
lat: 45.336453407749225
long: 13.828231379455806
alt: 0
This is Motovun!

View File

@@ -1,8 +0,0 @@
title: cities/NewYork
tags: $:/tags/GeoMarker
caption: New York
lat: 40.712778
long: -74.006111
alt: 0
This is New York!

View File

@@ -1,8 +0,0 @@
title: cities/Oxford
tags: $:/tags/GeoMarker
caption: Oxford
lat: 51.751944
long: -1.257778
alt: 0
This is Oxford!

View File

@@ -1,8 +0,0 @@
title: cities/Toronto
tags: $:/tags/GeoMarker
caption: Toronto
lat: 43.651070
long: -79.347015
alt: 0
This is Toronto!

View File

@@ -1,8 +0,0 @@
title: cities/Winchester
tags: $:/tags/GeoMarker
caption: Winchester
lat: 51.0632
long: -1.308
alt: 0
This is Winchester!

View File

@@ -1,5 +0,0 @@
title: $:/config/flickr-param/
album-id: 72157630297432522
user-id: 35468148136@N01
group-id: 22075379@N00

View File

@@ -1,4 +0,0 @@
title: $:/config/plugins/tiddlywiki/xlsx-utils/default-import-spec
type: text/vnd.tiddlywiki
$:/_importspec/RealEstate/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -1,2 +0,0 @@
title: $:/favicon.ico
type: image/png

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +0,0 @@
title: $:/geospatialdemo/features/canada-census-subdivision-millesime
caption: Canada Census Subdivisions Millesime
type: application/json
tags: $:/tags/GeoFeature
color: #f8f

View File

@@ -1,109 +0,0 @@
title: $:/geospatialdemo/features/denver/bikerental
caption: Denver bike rentals as ~GeoJSON points
tags: $:/tags/GeoFeature
type: application/json
color: blue
{
"type": "FeatureCollection",
"features": [
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9998241,
39.7471494
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 51
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9983545,
39.7502833
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 52
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9963919,
39.7444271
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 54
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9960754,
39.7498956
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 55
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9933717,
39.7477264
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 57
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9913392,
39.7432392
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 58
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9788452,
39.6933755
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 74
}
]
}

View File

@@ -1,63 +0,0 @@
title: $:/geospatialdemo/features/denver/campus
caption: Denver Auraria West Campus as ~GeoJSON multipolygons
tags: $:/tags/GeoFeature
type: application/json
color: purple
{
"type": "Feature",
"properties": {
"popupContent": "This is the Auraria West Campus",
"style": {
"weight": 2,
"color": "#999",
"opacity": 1,
"fillColor": "#B0DE5C",
"fillOpacity": 0.8
}
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[-105.00432014465332, 39.74732195489861],
[-105.00715255737305, 39.74620006835170],
[-105.00921249389647, 39.74468219277038],
[-105.01067161560059, 39.74362625960105],
[-105.01195907592773, 39.74290029616054],
[-105.00989913940431, 39.74078835902781],
[-105.00758171081543, 39.74059036160317],
[-105.00346183776855, 39.74059036160317],
[-105.00097274780272, 39.74059036160317],
[-105.00062942504881, 39.74072235994946],
[-105.00020027160645, 39.74191033368865],
[-105.00071525573731, 39.74276830198601],
[-105.00097274780272, 39.74369225589818],
[-105.00097274780272, 39.74461619742136],
[-105.00123023986816, 39.74534214278395],
[-105.00183105468751, 39.74613407445653],
[-105.00432014465332, 39.74732195489861]
],[
[-105.00361204147337, 39.74354376414072],
[-105.00301122665405, 39.74278480127163],
[-105.00221729278564, 39.74316428375108],
[-105.00283956527711, 39.74390674342741],
[-105.00361204147337, 39.74354376414072]
]
],[
[
[-105.00942707061768, 39.73989736613708],
[-105.00942707061768, 39.73910536278566],
[-105.00685214996338, 39.73923736397631],
[-105.00384807586671, 39.73910536278566],
[-105.00174522399902, 39.73903936209552],
[-105.00041484832764, 39.73910536278566],
[-105.00041484832764, 39.73979836621592],
[-105.00535011291504, 39.73986436617916],
[-105.00942707061768, 39.73989736613708]
]
]
]
}
}

View File

@@ -1,56 +0,0 @@
title: $:/geospatialdemo/features/denver/freebus
caption: Denver free bus routes as ~GeoJSON linestrings
tags: $:/tags/GeoFeature
type: application/json
color: green
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-105.00341892242432, 39.75383843460583],
[-105.0008225440979, 39.751891803969535]
]
},
"properties": {
"popupContent": "This is a free bus line that will take you across downtown.",
"underConstruction": false
},
"id": 1
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-105.0008225440979, 39.751891803969535],
[-104.99820470809937, 39.74979664004068]
]
},
"properties": {
"popupContent": "This is a free bus line that will take you across downtown.",
"underConstruction": true
},
"id": 2
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-104.99820470809937, 39.74979664004068],
[-104.98689651489258, 39.741052354709055]
]
},
"properties": {
"popupContent": "This is a free bus line that will take you across downtown.",
"underConstruction": false
},
"id": 3
}
]
}

View File

@@ -1,30 +0,0 @@
title: $:/geospatialdemo/features/denver/lightrail
caption: Denver light rail stops as ~GeoJSON points
tags: $:/tags/GeoFeature
type: application/json
color: red
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"popupContent": "18th & California Light Rail Stop"
},
"geometry": {
"type": "Point",
"coordinates": [-104.98999178409576, 39.74683938093904]
}
},{
"type": "Feature",
"properties": {
"popupContent": "20th & Welton Light Rail Stop"
},
"geometry": {
"type": "Point",
"coordinates": [-104.98689115047453, 39.747924136466565]
}
}
]
}

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +0,0 @@
title: $:/geospatialdemo/features/harvard-volcanoes-of-the-world
caption: Harvard Volcanoes of the World
type: application/json
tags: $:/tags/GeoFeature/Hidden
color: #f88

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +0,0 @@
title: $:/geospatialdemo/features/us-states
caption: US State Boundaries
type: application/json
tags: $:/tags/GeoFeature
color: #88f

View File

@@ -1,99 +0,0 @@
title: real-estate-demo
caption: Real Estate Demo
tags: $:/tags/GeospatialDemo
\define default-display-filter() [<currentTiddler>get<fieldname>]
\define default-limit() 10
This is a list of all the tiddlers containing ~GeoJSON markers in this wiki (identified by the tag <<tag "$:/tags/GeoMarker">>) viewed as both a map and a table.
<$let
schema={{real-estate-demo/schema}}
>
<div>
<$list filter="[<schema>jsonindexes[columns]]" variable="index">
<$let
config={{{ [<schema>jsonget[columns],<index>,[name]addprefix[$:/config/geospatial/demo/real-estate-demo/columns/]] }}}
>
<div>
<$checkbox tiddler=<<config>> field="visible" checked="yes" unchecked="no" default="yes">
<$text text={{{ [<schema>jsonget[columns],<index>,[caption]] }}}/>
</$checkbox>
</div>
</$let>
</$list>
</div>
<div>
Sorting by
<$select tiddler="$:/config/geospatial/demo/real-estate-demo/sort-field" default="title">
<$list filter="[<schema>jsonindexes[columns]]" variable="index">
<option value={{{ [<schema>jsonget[columns],<index>,[name]] }}}>
<$text text={{{ [<schema>jsonget[columns],<index>,[caption]] }}}/>
</option>
</$list>
</$select>
<$checkbox tiddler="$:/config/geospatial/demo/real-estate-demo/sort-order" field="text" checked="reverse" unchecked="normal" default="normal">
Reverse sort order
</$checkbox>
</div>
<div>
Search: <$edit-text tiddler="$:/config/geospatial/demo/real-estate-demo/search" tag="input"/>
</div>
<div>
Limit: <$edit-text tiddler="$:/config/geospatial/demo/real-estate-demo/limit" tag="input" placeholder=<<default-limit>>/>
</div>
<table>
<thead>
<tr>
<$list filter="[<schema>jsonindexes[columns]]" variable="index">
<$let
config={{{ [<schema>jsonget[columns],<index>,[name]addprefix[$:/config/geospatial/demo/real-estate-demo/columns/]] }}}
>
<$list filter="[<config>get[visible]else[yes]match[yes]]" variable="ignore">
<th>
<$text text={{{ [<schema>jsonget[columns],<index>,[caption]] }}}/>
</th>
</$list>
</$let>
</$list>
</tr>
</thead>
<tbody>
<$let
sortField={{{ [[$:/config/geospatial/demo/real-estate-demo/sort-field]get[text]else[title]] }}}
sortOrder={{{ [[$:/config/geospatial/demo/real-estate-demo/sort-order]get[text]else[normal]] }}}
limit={{{ [[$:/config/geospatial/demo/real-estate-demo/limit]get[text]] :else[<default-limit>] }}}
>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/GeoMarker]search:*{$:/config/geospatial/demo/real-estate-demo/search}nsort<sortField>order<sortOrder>limit<limit>]">
<$let
rowTiddler=<<currentTiddler>>
>
<$setmultiplevariables
$names="[<schema>jsonindexes[variables]sort[]]"
$values="[<schema>jsonindexes[variables]sort[]] :map[<schema>jsonget[variables],<currentTiddler>] :map[subfilter<currentTiddler>]"
>
<tr>
<$list filter="[<schema>jsonindexes[columns]]" variable="index">
<$let
config={{{ [<schema>jsonget[columns],<index>,[name]addprefix[$:/config/geospatial/demo/real-estate-demo/columns/]] }}}
>
<$list filter="[<config>get[visible]else[yes]match[yes]]" variable="ignore">
<td>
<$let
fieldname={{{ [<schema>jsonget[columns],<index>,[name]] }}}
displayFilter={{{ [<schema>jsonget[columns],<index>,[display]] :else[<default-display-filter>] }}}
>
<$text text={{{ [subfilter<displayFilter>] }}}/>
</$let>
</td>
</$list>
</$let>
</$list>
</tr>
</$setmultiplevariables>
</$let>
</$list>
</$let>
</tbody>
</table>
</$let>

View File

@@ -1,22 +0,0 @@
{
"columns": [
{"name": "address", "caption": "Address", "type": "string"},
{"name": "broker", "caption": "Broker", "type": "string"},
{"name": "city", "caption": "City", "type": "string"},
{"name": "lat", "caption": "Latitude", "type": "number"},
{"name": "long", "caption": "Longitude", "type": "number"},
{"name": "price", "caption": "Price", "type": "number"},
{"name": "salesagent", "caption": "Sales Agent", "type": "string"},
{"name": "state", "caption": "State", "type": "string"},
{"name": "title", "caption": "Title", "type": "string"},
{"name": "zipcode", "caption": "Zip Code", "type": "string"},
{"name": "census-province", "caption": "Census Province", "type": "string", "display": "[<census-data>jsonget[0],[prov_name_en],[0]]"},
{"name": "census-division", "caption": "Census Division", "type": "string", "display": "[<census-data>jsonget[0],[cd_name_en],[0]]"},
{"name": "census-subdivision", "caption": "Census Subdivision", "type": "string", "display": "[<census-data>jsonget[0],[csd_name_en],[0]]"},
{"name": "nearest-volcano", "caption": "Nearest Volcano", "type": "string", "display": "[{$:/geospatialdemo/features/harvard-volcanoes-of-the-world}geonearestpoint<coords>]"}
],
"variables": {
"coords": "[<rowTiddler>] :map[geopoint{!!long},{!!lat}]",
"census-data": "[<rowTiddler>] :map[geopoint{!!long},{!!lat}geolookup{$:/geospatialdemo/features/canada-census-subdivision-millesime}]"
}
}

View File

@@ -1,3 +0,0 @@
title: real-estate-demo/schema
type: application/json

View File

@@ -1,5 +0,0 @@
import-spec-role: row
list: $:/_importspec/RealEstate/PropertiesRow/Field/long $:/_importspec/RealEstate/PropertiesRow/Field/lat $:/_importspec/RealEstate/PropertiesRow/Field/price $:/_importspec/RealEstate/PropertiesRow/Field/broker $:/_importspec/RealEstate/PropertiesRow/Field/salesagent $:/_importspec/RealEstate/PropertiesRow/Field/zipcode $:/_importspec/RealEstate/PropertiesRow/Field/state $:/_importspec/RealEstate/PropertiesRow/Field/city $:/_importspec/RealEstate/PropertiesRow/Field/tags $:/_importspec/RealEstate/PropertiesRow/Field/title $:/_importspec/RealEstate/PropertiesRow/Field/address
tags:
title: $:/_importspec/RealEstate/PropertiesRow
type: text/vnd.tiddlywiki

View File

@@ -1,7 +0,0 @@
import-field-column: Address
import-field-name: address
import-field-source: column
import-spec-role: field
title: $:/_importspec/RealEstate/PropertiesRow/Field/address
type: text/vnd.tiddlywiki

View File

@@ -1,7 +0,0 @@
import-field-column: Broker
import-field-name: broker
import-field-source: column
import-spec-role: field
title: $:/_importspec/RealEstate/PropertiesRow/Field/broker
type: text/vnd.tiddlywiki

View File

@@ -1,7 +0,0 @@
import-field-column: City
import-field-name: city
import-field-source: column
import-spec-role: field
title: $:/_importspec/RealEstate/PropertiesRow/Field/city
type: text/vnd.tiddlywiki

View File

@@ -1,8 +0,0 @@
import-field-column: Latitude
import-field-name: lat
import-field-type: number
import-field-source: column
import-spec-role: field
title: $:/_importspec/RealEstate/PropertiesRow/Field/lat
type: text/vnd.tiddlywiki

View File

@@ -1,8 +0,0 @@
import-field-column: Longitude
import-field-name: long
import-field-type: number
import-field-source: column
import-spec-role: field
title: $:/_importspec/RealEstate/PropertiesRow/Field/long
type: text/vnd.tiddlywiki

View File

@@ -1,8 +0,0 @@
import-field-column: Price
import-field-name: price
import-field-type: number
import-field-source: column
import-spec-role: field
title: $:/_importspec/RealEstate/PropertiesRow/Field/price
type: text/vnd.tiddlywiki

View File

@@ -1,7 +0,0 @@
import-field-column: Sales Agent
import-field-name: salesagent
import-field-source: column
import-spec-role: field
title: $:/_importspec/RealEstate/PropertiesRow/Field/salesagent
type: text/vnd.tiddlywiki

View File

@@ -1,7 +0,0 @@
import-field-column: State
import-field-name: state
import-field-source: column
import-spec-role: field
title: $:/_importspec/RealEstate/PropertiesRow/Field/state
type: text/vnd.tiddlywiki

View File

@@ -1,7 +0,0 @@
import-spec-role: field
import-field-name: tags
import-field-type: string
import-field-source: constant
import-field-value: $:/tags/GeoMarker
title: $:/_importspec/RealEstate/PropertiesRow/Field/tags
type: text/vnd.tiddlywiki

View File

@@ -1,8 +0,0 @@
import-field-column: Address
import-field-name: title
import-field-source: column
import-spec-role: field
import-field-skip-tiddler-if-blank: yes
title: $:/_importspec/RealEstate/PropertiesRow/Field/title
type: text/vnd.tiddlywiki

View File

@@ -1,7 +0,0 @@
import-field-column: Zip Code
import-field-name: zipcode
import-field-source: column
import-spec-role: field
title: $:/_importspec/RealEstate/PropertiesRow/Field/zipcode
type: text/vnd.tiddlywiki

View File

@@ -1,7 +0,0 @@
import-sheet-name: Final Day 1 and 2
import-spec-role: sheet
list: [[$:/_importspec/RealEstate/PropertiesRow]]
tags:
title: $:/_importspec/RealEstate/PropertiesSheet
type: text/vnd.tiddlywiki

View File

@@ -1,7 +0,0 @@
caption: Real Estate Listing Demo
import-spec-role: workbook
list: [[$:/_importspec/RealEstate/PropertiesSheet]]
tags:
title: $:/_importspec/RealEstate/
type: text/vnd.tiddlywiki

View File

@@ -1,2 +0,0 @@
title: $:/themes/tiddlywiki/vanilla/options/sidebarlayout
text: fluid-fixed

View File

@@ -1,39 +0,0 @@
title: ui/geofeature
\define create-intersection()
<$let
intersectLayer={{{ =[<currentTiddler>get[text]] =[<otherFeature>get[text]] +[geointersect[]] }}}
>
<$action-createtiddler $basetitle="$:/temp/_IsochroneLayer" text={{{ [<intersectLayer>] }}} tags="$:/tags/GeoFeature" caption={{{ [<captionThisFeature>addsuffix[ intersected with ]addsuffix<captionOtherFeature>] }}}/>
</$let>
\end
!! Mapped
<$geomap
state=<<qualify "$:/state/demo-map">>
startPosition="bounds"
>
<$geolayer json={{!!text}} color={{!!color}}/>
</$geomap>
!! Intersect with other features
<$let
captionThisFeature={{{ [<currentTiddler>get[caption]else<currentTiddler>] }}}
>
<ul>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/GeoFeature]sort[caption]] -[<currentTiddler>]" variable="otherFeature">
<$let
captionOtherFeature={{{ [<otherFeature>get[caption]else<otherFeature>] }}}
>
<li>
<$link to=<<otherFeature>>><$transclude tiddler=<<otherFeature>> field="caption"><$view tiddler=<<otherFeature>> field="title"/></$transclude></$link>
<$button actions=<<create-intersection>>>
Create intersection
</$button>
</li>
</$let>
</$list>
</ul>
</$let>

View File

@@ -1,128 +0,0 @@
title: ui/geomarker
\define default-traveltime-time() 5400
\define completion-actions()
<$action-log/>
<$action-setfield $tiddler="$:/temp/_StatusCode" text=<<status>>/>
<$action-setfield $tiddler="$:/temp/_StatusText" text=<<statusText>>/>
<$action-setfield $tiddler="$:/temp/_Error" text=<<error>>/>
<$action-setfield $tiddler="$:/temp/_Result" text=<<data>>/>
<$action-setfield $tiddler="$:/temp/_Headers" text=<<headers>>/>
<$list filter="[<status>compare:number:gteq[200]compare:number:lteq[299]]" variable="ignore">
<$action-createtiddler $basetitle="$:/temp/_IsochroneLayer" text={{{ [<data>] }}} tags="$:/tags/GeoFeature" caption={{{ [<currentTiddler>get[caption]else<currentTiddler>addprefix[Travel time from ]] }}}/>
</$list>
\end
\define progress-actions()
<$action-log message="In progress-actions"/>
<$action-log/>
\end
\define payload-source()
\rules only transcludeinline transcludeblock filteredtranscludeinline filteredtranscludeblock
{
"departure_searches": [
{
"id": "My first isochrone",
"coords": {
"lat": {{!!lat}},
"lng": {{!!long}}
},
"departure_time": "2023-02-27T08:00:00Z",
"travel_time": {{{ [[$:/config/plugins/geospatial/traveltime/time]get[text]else<default-traveltime-time>] }}},
"transportation": {
"type": "driving"
}
}
]
}
\end
\define get-traveltime-actions()
<$wikify name="payload" text=<<payload-source>>>
<$action-log $message="Making payload"/>
<$action-log/>
<$action-sendmessage
$message="tm-http-request"
url="https://api.traveltimeapp.com/v4/time-map"
method="POST"
header-accept="application/geo+json"
header-Content-Type="application/json"
password-header-X-Api-Key="traveltime-secret-key"
password-header-X-Application-Id="traveltime-application-id"
body=<<payload>>
var-currentTiddler=<<currentTiddler>>
bind-status="$:/temp/plugins/tiddlywiki/geospatial/demo/traveltime/status"
bind-progress="$:/temp/plugins/tiddlywiki/geospatial/demo/traveltime/progress"
oncompletion=<<completion-actions>>
onprogress=<<progress-actions>>
/>
</$wikify>
\end
!! Mapped
<$geomap
state=<<qualify "$:/state/demo-map">>
startPosition="bounds"
>
<$geolayer lat={{!!lat}} long={{!!long}} alt={{!!alt}} color={{!!color}}/>
</$geomap>
!! Distance to other markers
<$let
thisLocation={{{ [geopoint{!!long},{!!lat}] }}}
>
<ul>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/GeoMarker]sort[caption]] -[<currentTiddler>]">
<li>
<$link><$view field="caption"><$view field="title"/></$view></$link>
--
<$let
otherLocation={{{ [geopoint{!!long},{!!lat}] }}}
>
<$text text={{{ [geodistance<thisLocation>,<otherLocation>,[miles]fixed[0]] }}}/> miles
</$let>
</li>
</$list>
</ul>
</$let>
!! GeoFeature Lookups
<$let
thisLocation={{{ [geopoint{!!long},{!!lat}] }}}
>
<ul>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/GeoFeature]sort[caption]]">
<li>
<$text text={{{ [<currentTiddler>get[caption]] :else[<currentTiddler>] }}}/> --
<$text text={{{ [<thisLocation>geolookup{!!text}] }}}/>
</li>
</$list>
</ul>
</$let>
!! Travel Time
<$button actions=<<get-traveltime-actions>>>
Call ~TravelTime
</$button>
Maximum time: <$edit-text tiddler="$:/config/plugins/geospatial/traveltime/time" default=<<default-traveltime-time>> tag="input"/> seconds
|Status |<$text text={{$:/temp/plugins/tiddlywiki/geospatial/demo/traveltime/status}}/> |
|Progress |<$text text={{$:/temp/plugins/tiddlywiki/geospatial/demo/traveltime/progress}}/> |
|Status Code |<$text text={{$:/temp/_StatusCode}}/> |
|Status Text |<$text text={{$:/temp/_StatusText}}/> |
|Error |<$text text={{$:/temp/_Error}}/> |
<$list filter="[<currentTiddler>has[photo-url]]" variable="ignore">
!! Photo
<img src={{!!photo-url}}/>
</$list>

View File

@@ -1,23 +0,0 @@
{
"description": "Demo of the geospatial plugin for TiddlyWiki",
"plugins": [
"tiddlywiki/geospatial",
"tiddlywiki/jszip",
"tiddlywiki/xlsx-utils",
"tiddlywiki/codemirror"
],
"themes": [
"tiddlywiki/vanilla",
"tiddlywiki/snowwhite"
],
"includeWikis": [
],
"build": {
"index": [
"--render","$:/core/save/all","index.html","text/plain"],
"favicon": [],
"static": [],
"empty": [],
"encrypted": []
}
}

View File

@@ -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,8 +10,6 @@ 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
@@ -22,46 +20,17 @@ The new features include:
* 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
!! Geospatial Plugin
<<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7406">> new Geospatial Plugin that adds new primitives to the TiddlyWiki platform to enable non-developers to build sophisticated interactive geospatial applications.
The Geospatial Plugin incorporates a number of third party libraries and online services:
* [[Leaflet.js|https://leafletjs.com/]], an open source library to display interactive maps
* [[Turf.js|https://turfjs.org/]], an open source library to perform geospatial calculations with [[GeoJSON|https://en.wikipedia.org/wiki/GeoJSON]] objects
* [[TravelTime|https://traveltime.com/]], a commercial API for [[geocoding|https://traveltime.com/features/geocoding]], [[routing|https://traveltime.com/features/multi-modal-routing]] and [[isochrones|https://traveltime.com/features/isochrones]]
* [[Flickr|https://www.flickr.com/services/api/]], a free API for retrieving geotagged photographs
* [[OpenLocationCode|https://github.com/google/open-location-code]], Google's open source library for converting to and from Open Location Codes (also known as [[PlusCodes|https://maps.google.com/pluscodes/]])
Try it out at https://tiddlywiki.com/prerelease/plugins/tiddlywiki/geospatial/
!! <<.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
* French
* 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
@@ -74,19 +43,14 @@ Improvements to the following translations:
! Usability Improvements
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/issues/8121">> new keyboard shortcut for refreshing the page
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/commit/f3614c1e47e6ac5d5fec221b060699e975cd5ef6">> and simplified the splash screen for tiddlywiki.com. See [[Creating a splash screen]] for instructions on creating your own splash screen
! 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
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/8211">> [[tm-permalink|WidgetMessage: tm-permalink]], [[tm-permaview|WidgetMessage: tm-permaview]] and [[tm-copy-to-clipboard|WidgetMessage: tm-copy-to-clipboard]] messages to allow the notification text to be customised
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/8225">> [[WidgetMessage: tm-http-request]] to allow the default headers to be suppressed
! 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
@@ -103,7 +67,6 @@ Improvements to the following translations:
* <<.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
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8098">> backlink parser to prevent it parsing binary tiddlers
! Node.js Improvements
@@ -116,9 +79,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
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8179">> fix `widget.getVariableInfo()` to always return a `params` property
*
! Infrastructure Improvements
@@ -136,7 +97,6 @@ BramChen
btheado
BurningTreeC
catter-fly
Drevarr
eschlon
etardiff
flibbles
@@ -154,7 +114,5 @@ rmunn
saqimtiaz
sarna
Telumire
twMat
xcazin
yaisog
""">>

View File

@@ -1,6 +1,6 @@
title: $:/config/OfficialPluginLibrary
caption: {{$:/language/OfficialPluginLibrary}}
tags: $:/tags/PluginLibrary
url: https://tiddlywiki.com/prerelease/library/v5.3.4/index.html
caption: {{$:/language/OfficialPluginLibrary}} (Prerelease)
title: $:/config/OfficialPluginLibrary
url: https://tiddlywiki5-git-plugin-stability-badges-jermolenes-projects.vercel.app/library/v5.3.3/index.html
The prerelease version of the official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team.
Plugin library for https://tiddlywiki5-git-plugin-stability-badges-jermolenes-projects.vercel.app

View File

@@ -1,27 +0,0 @@
title: Data/ImportCompound
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
description: Importing a compound payload tiddler and adding custom fields
title: Description
text: Importing a compound payload tiddler and adding custom fields
+
title: Output
\whitespace trim
<$testcase template="$:/core/ui/testcases/RawJSONTemplate">
<$data $compound-tiddler="Compound" custom="Alpha"/>
</$testcase>
+
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><div><div>[{"title":"Payload Tiddler","tags":"Alpha Beta Gamma","text":"This is a payload tiddler from a compound tiddler","custom":"Alpha"}]</div></div></p>

View File

@@ -1,28 +0,0 @@
title: Data/ImportFilter
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
description: Importing a payload filter and adding custom fields
title: Description
text: Importing a payload filter and adding custom fields
+
title: Output
\whitespace trim
<$testcase template="$:/core/ui/testcases/RawJSONTemplate">
<$data $filter="[tag[Definitions]]" custom="Alpha"/>
</$testcase>
+
title: HelloThere
tags: Definitions
This is the tiddler HelloThere
+
title: AnotherDefinition
tags: Definitions
This is the tiddler AnotherDefinition
+
title: ExpectedResult
<p><div><div>[{"title":"AnotherDefinition","tags":"Definitions","text":"This is the tiddler AnotherDefinition","custom":"Alpha"},{"title":"HelloThere","tags":"Definitions","text":"This is the tiddler HelloThere","custom":"Alpha"}]</div></div></p>

View File

@@ -1,23 +0,0 @@
title: Data/ImportTiddler
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
description: Importing a payload tiddler and adding custom fields
title: Description
text: Importing a payload tiddler and adding custom fields
+
title: Output
\whitespace trim
<$testcase template="$:/core/ui/testcases/RawJSONTemplate">
<$data $tiddler="HelloThere" custom="Alpha"/>
</$testcase>
+
title: HelloThere
tags: Definitions
This is the tiddler HelloThere
+
title: ExpectedResult
<p><div><div>[{"title":"HelloThere","tags":"Definitions","text":"This is the tiddler HelloThere","custom":"Alpha"}]</div></div></p>

View File

@@ -1,18 +0,0 @@
title: Data/Simple
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
description: Standalone data widget to create individual tiddlers
title: Description
text: Standalone data widget to create individual tiddlers
+
title: Output
\whitespace trim
<$testcase template="$:/core/ui/testcases/RawJSONTemplate">
<$data title="Epsilon" text="Theta"/>
</$testcase>
+
title: ExpectedResult
<p><div><div>[{"title":"Epsilon","text":"Theta"}]</div></div></p>

View File

@@ -1,21 +0,0 @@
title: Functions/FunctionFilterrunVariables3
description: Nested functions in filter runs that set variables
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\define currentTiddler() old-current
\function .inner() [<currentTiddler>]
\function .outer() [<currentTiddler>match[intermediate2]then[new-current]] :map[function[.inner]]
\function .wrappertwo() [<currentTiddler>match[intermediate]addsuffix[2]] :map[function[.outer]]
\function .wrapper() intermediate :map[.wrappertwo[]]
<$text text={{{ [.wrapper[]] }}}/>
+
title: ExpectedResult
new-current

View File

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

View File

@@ -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');
});
});
});
})();

View File

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

View File

@@ -12,44 +12,33 @@ Tests for integrity of the core plugins, languages, themes and editions
/*global $tw: false */
"use strict";
if($tw.node) {
describe("Plugin tests", function() {
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) {
// Get all the plugins as a hashmap by title of a JSON string with the plugin content
var tiddlers = $tw.utils.getAllPlugins();
// 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) {
it("plugin " + title + " should have the required standard fields",function() {
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);
});
expect(fields["plugin-type"]).toMatch(/^(?:plugin|language|theme)$/);
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);
});
expect(!!(fields.name && fields.description && fields.list)).toEqual(true);
expect(fields.stability).toMatch(/^(?:STABILITY_0_DEPRECATED|STABILITY_1_EXPERIMENTAL|STABILITY_2_STABLE|STABILITY_3_LEGACY)$/);
break;
case "language":
it("language " + title + " should have name and description fields",function() {
expect(!!(fields.name && fields.description)).toEqual(true);
});
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);
});
expect(!!(fields.name && fields.description)).toEqual(true);
break;
}
}
});
});
});
}
});
})();

View File

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

View File

@@ -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
@@ -816,26 +775,6 @@ describe("Widget module", function() {
expect(wrapper.innerHTML).toBe("<p>Bval</p>");
});
it("should use default $parameters if directly rendered", function() {
var wiki = new $tw.Wiki();
var text = "<$parameters bee=default $$dollar=bill nothing empty=''>bee=<<bee>>, $dollar=<<$dollar>>, nothing=<<nothing>>, empty=<<empty>></$parameters>";
var widgetNode = createWidgetNode(parseText(text,wiki),wiki);
// Render the widget node to the DOM
var wrapper = renderWidgetNode(widgetNode);
// nothing = true in this attribute form because valueless attributes always equal true.
expect(wrapper.innerHTML).toBe("<p>bee=default, $dollar=bill, nothing=true, empty=</p>");
});
it("should use default \\parameters if directly rendered", function() {
var wiki = new $tw.Wiki();
var text = "\\parameters(bee:default $$dollar:bill nothing)\nbee=<<bee>>, $$dollar=<<$$dollar>>, nothing=<<nothing>>";
var widgetNode = createWidgetNode(parseText(text,wiki),wiki);
// Render the widget node to the DOM
var wrapper = renderWidgetNode(widgetNode);
// nothing = true in this attribute form because valueless attributes always equal true.
expect(wrapper.innerHTML).toBe("<p>bee=default, $$dollar=bill, nothing=</p>");
});
it("can have more than one macroDef variable imported", function() {
var wiki = new $tw.Wiki();
wiki.addTiddlers([

View File

@@ -1,8 +1,7 @@
{
"description": "TiddlyWiki core tests",
"plugins": [
"tiddlywiki/jasmine",
"tiddlywiki/geospatial"
"tiddlywiki/jasmine"
],
"themes": [
"tiddlywiki/vanilla",

View File

@@ -23,4 +23,5 @@ Some payload tiddlers are set aside for special purposes:
|''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 |

View File

@@ -8,6 +8,6 @@ op-input: a [[selection of titles|Title Selection]]
op-parameter: none
op-output: any non-[[system|SystemTiddlers]] titles that contain [[transclusion|Transclusion]] to the input titles
<<.from-version 5.3.4>> Similar to [[backlinks|backlinks Operator]]. Each input title is processed in turn. The corresponding tiddler's list of backtranscludes is generated, sorted alphabetically by title, and then [[dominantly appended|Dominant Append]] to the operator's overall output.
Each input title is processed in turn. The corresponding tiddler's list of backtranscludes is generated, sorted alphabetically by title, and then [[dominantly appended|Dominant Append]] to the operator's overall output.
<<.operator-examples "backtranscludes">>

View File

@@ -6,4 +6,4 @@ tags: shopping
title: Brownies
type: text/vnd.tiddlywiki
//This is a sample shopping list item for the [[reduce Operator (Examples)]]//
//This is a sample shopping list item for the [[Shopping List Example]]//

View File

@@ -6,4 +6,4 @@ tags: shopping
title: Chick Peas
type: text/vnd.tiddlywiki
//This is a sample shopping list item for the [[reduce Operator (Examples)]]//
//This is a sample shopping list item for the [[Shopping List Example]]//

View File

@@ -6,4 +6,4 @@ tags: shopping
title: Milk
type: text/vnd.tiddlywiki
//This is a sample shopping list item for the [[reduce Operator (Examples)]]//
//This is a sample shopping list item for the [[Shopping List Example]]//

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