1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-01-22 19:04:38 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Jeremy Ruston
afc042a967 Initial Commit 2024-03-27 10:33:22 +00:00
383 changed files with 802 additions and 25697 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

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

View File

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

View File

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

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

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

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

@@ -43,12 +43,10 @@ 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) {
self.commander.log("Saving \"" + title + "\" to \"" + filepath + "\"");
console.log("Saving \"" + title + "\" to \"" + fileInfo.filepath + "\"");
}
try {
$tw.utils.saveTiddlerToFileSync(tiddler,fileInfo);

View File

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

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

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

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") || "";
}
/*
@@ -142,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,
@@ -289,9 +282,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;
@@ -85,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
@@ -107,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);

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"],
@@ -73,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 && 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

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

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();
@@ -116,7 +116,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) {
@@ -166,7 +165,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 +240,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 +266,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(),
@@ -295,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;
@@ -319,10 +316,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

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

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

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

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

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

View File

@@ -1,182 +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();
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);
};
/*
Compute the internal state of the widget
*/
DataWidget.prototype.execute = function() {
// Nothing to do here
};
/*
Read the tiddler value(s) from a data widget as an array of tiddler field objects (not $tw.Tiddler objects)
*/
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 $
var item = Object.create(null);
$tw.utils.each(this.attributes,function(value,name) {
if(name.charAt(0) !== "$") {
item[name] = value;
}
});
// 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));
}
}
// Return the literal item if none of the special attributes were used
if(!this.hasAttribute("$tiddler") && !this.hasAttribute("$filter") && !this.hasAttribute("$compound-tiddler")) {
if(Object.keys(item).length > 0 && !!item.title) {
return [new $tw.Tiddler(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;
}
};
/*
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) {
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;
}
};
/*
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

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

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) {
@@ -811,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
*/

View File

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

View File

@@ -5,6 +5,5 @@
"author": "JeremyRuston",
"core-version": ">=5.0.0",
"plugin-priority": "0",
"list": "readme",
"stability": "STABILITY_2_STABLE"
"list": "readme"
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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>:
&#32;
<$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">

View File

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

View File

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

View File

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

View File

@@ -1,5 +0,0 @@
title: $:/core/ui/KeyboardShortcuts/refresh
tags: $:/tags/KeyboardShortcut
key: ((refresh))
<$action-sendmessage $message="tm-browser-refresh"/>

View File

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

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

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

View File

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

View File

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

View File

@@ -1,4 +0,0 @@
title: $:/core/ui/testcases/RawJSONTemplate
\whitespace trim
<$text text=<<payloadTiddlers>>/>

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,4 +6,3 @@ underline: ctrl-U
new-image: alt-I
new-journal: alt-J
new-tiddler: alt-N
refresh: ctrl-R

View File

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

View File

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

View File

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

View File

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

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

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