mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-01-24 20:04:40 +00:00
Compare commits
196 Commits
tm-http-re
...
v5.3.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2426b5ed9 | ||
|
|
e2b40c3a14 | ||
|
|
46f6fe88a2 | ||
|
|
1eb1af2589 | ||
|
|
98ebbc32f7 | ||
|
|
d41fabd472 | ||
|
|
906ac3817d | ||
|
|
7071fdef8a | ||
|
|
cec30738f4 | ||
|
|
e644b5cb46 | ||
|
|
5758d0b313 | ||
|
|
753b289ba9 | ||
|
|
ad5661ef1c | ||
|
|
bc18bd9261 | ||
|
|
5aa889859a | ||
|
|
eb6f3a423a | ||
|
|
eeeb9f97a9 | ||
|
|
8f1792df20 | ||
|
|
e19f86482a | ||
|
|
53924de313 | ||
|
|
d2c2ada33c | ||
|
|
b906515c69 | ||
|
|
8928b6e603 | ||
|
|
73163386c1 | ||
|
|
32c75cbb68 | ||
|
|
b60abadf33 | ||
|
|
a9b6de8c35 | ||
|
|
84d1c81bb2 | ||
|
|
c25b8e3056 | ||
|
|
b81a1f22fe | ||
|
|
703edd154c | ||
|
|
64e6a9a946 | ||
|
|
068b76b07d | ||
|
|
f060ba75ff | ||
|
|
7beaddb293 | ||
|
|
1937789ee2 | ||
|
|
2f2806c00c | ||
|
|
87adbe0b14 | ||
|
|
6554b5c9f4 | ||
|
|
c93d4c52fc | ||
|
|
f3b129c245 | ||
|
|
74c9e4465d | ||
|
|
0f4bc93a7e | ||
|
|
05bff57b65 | ||
|
|
0dcf7e91bf | ||
|
|
f50c2a2e64 | ||
|
|
a42dad6a5c | ||
|
|
cff685ea11 | ||
|
|
791c7fac63 | ||
|
|
b90c3841c9 | ||
|
|
a5e05e4eec | ||
|
|
05792a9de3 | ||
|
|
1c1f0ff4e8 | ||
|
|
d253503335 | ||
|
|
a16dab9710 | ||
|
|
18152aa7c8 | ||
|
|
f15b6a26da | ||
|
|
5d06b922d3 | ||
|
|
0031a95dfe | ||
|
|
eecd40723e | ||
|
|
5b9f4751ea | ||
|
|
b6cf098c5f | ||
|
|
5c63262feb | ||
|
|
3b88f0e741 | ||
|
|
b49ecf886b | ||
|
|
02ccec7ea8 | ||
|
|
14c5628d35 | ||
|
|
4bd3576432 | ||
|
|
756ef697dd | ||
|
|
11f562a918 | ||
|
|
083489102e | ||
|
|
cd8c483f67 | ||
|
|
c8cbf6853e | ||
|
|
153b66e4ee | ||
|
|
93c9323d0f | ||
|
|
4cd66697ad | ||
|
|
741aef55e4 | ||
|
|
8eb08820ac | ||
|
|
4ca883fd9b | ||
|
|
2f4c21e374 | ||
|
|
6239384e7b | ||
|
|
ead36cf329 | ||
|
|
cdd3f4b6a2 | ||
|
|
fdb86e7881 | ||
|
|
b4ac1e6b35 | ||
|
|
91e0b2afb6 | ||
|
|
2d5b935b1c | ||
|
|
177ba4b56e | ||
|
|
6f248bf5b5 | ||
|
|
4bda8cfee6 | ||
|
|
93d32d59aa | ||
|
|
e30746d5e5 | ||
|
|
3e1d8fa598 | ||
|
|
32cbc97a0c | ||
|
|
d276e0aa25 | ||
|
|
3243adc3a5 | ||
|
|
bf9865af20 | ||
|
|
08c7a8805b | ||
|
|
12c551ef05 | ||
|
|
a67c0e1399 | ||
|
|
7ec8334005 | ||
|
|
1a57d08feb | ||
|
|
5db3eeeaa2 | ||
|
|
e4c682d04b | ||
|
|
240496d85c | ||
|
|
78ace99685 | ||
|
|
3ddd10d373 | ||
|
|
6833ccdb97 | ||
|
|
36a9e3f54e | ||
|
|
789d64f768 | ||
|
|
25ec52b912 | ||
|
|
4be81b2bf4 | ||
|
|
423075e89d | ||
|
|
51ad11401b | ||
|
|
352272905e | ||
|
|
eb15dc8408 | ||
|
|
33bc77f46f | ||
|
|
4860b14315 | ||
|
|
913d15dc53 | ||
|
|
9e1babdf82 | ||
|
|
ea173ec83d | ||
|
|
40801f3c29 | ||
|
|
312b3b2037 | ||
|
|
f8ae96118a | ||
|
|
7337b6da63 | ||
|
|
416c6ee0d4 | ||
|
|
743bc4933f | ||
|
|
4055501f71 | ||
|
|
ac855b0065 | ||
|
|
7a50b2b554 | ||
|
|
65d9384261 | ||
|
|
da8d4ecfae | ||
|
|
6a84ae332d | ||
|
|
e35793bc38 | ||
|
|
3af2a0ae6f | ||
|
|
f3614c1e47 | ||
|
|
78fb4a2c1d | ||
|
|
928f3fc413 | ||
|
|
47029bac9e | ||
|
|
6910be795f | ||
|
|
cd2d4b3eb7 | ||
|
|
5856bd8342 | ||
|
|
15001020fe | ||
|
|
0f17ff0f6c | ||
|
|
4274e8fd7f | ||
|
|
1b6e8e1a79 | ||
|
|
9756b79683 | ||
|
|
613ee13294 | ||
|
|
b5bd4c9673 | ||
|
|
2312cd3301 | ||
|
|
dbe912ba5d | ||
|
|
a463783283 | ||
|
|
e3f9be995b | ||
|
|
e932b09016 | ||
|
|
074d35c388 | ||
|
|
18d23048da | ||
|
|
970f829c83 | ||
|
|
f9df4f0741 | ||
|
|
fc0de10cd1 | ||
|
|
01b2e864c1 | ||
|
|
0adc6024d1 | ||
|
|
4d2aa1dc95 | ||
|
|
5aa3646df5 | ||
|
|
3e27093c94 | ||
|
|
71d77fe428 | ||
|
|
ece8b0ee01 | ||
|
|
f1299120a6 | ||
|
|
0b475628de | ||
|
|
24dceb1bce | ||
|
|
64f5dd942c | ||
|
|
9007e0b8c8 | ||
|
|
07a048975d | ||
|
|
b4e0a9b28b | ||
|
|
67845f8ebe | ||
|
|
a081e58273 | ||
|
|
1d48909012 | ||
|
|
d3722a6602 | ||
|
|
5f74f4c2fa | ||
|
|
9167b190d2 | ||
|
|
df8731f760 | ||
|
|
1fb9098c76 | ||
|
|
e9aa3c6c93 | ||
|
|
105e8195d5 | ||
|
|
eeb4e7a7f7 | ||
|
|
7ce85a2ddb | ||
|
|
804f227815 | ||
|
|
9939759690 | ||
|
|
b595651fe1 | ||
|
|
9cd6affcae | ||
|
|
e43cd2d989 | ||
|
|
f1e707bff4 | ||
|
|
2d92a6fd78 | ||
|
|
2e0e541ebf | ||
|
|
b4d7e34a5a | ||
|
|
b6eab1afd6 | ||
|
|
32cbd53423 |
@@ -5,7 +5,7 @@
|
|||||||
# Default to the current version number for building the plugin library
|
# Default to the current version number for building the plugin library
|
||||||
|
|
||||||
if [ -z "$TW5_BUILD_VERSION" ]; then
|
if [ -z "$TW5_BUILD_VERSION" ]; then
|
||||||
TW5_BUILD_VERSION=v5.3.3
|
TW5_BUILD_VERSION=v5.3.5
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
||||||
@@ -393,6 +393,17 @@ node $TW5_BUILD_TIDDLYWIKI \
|
|||||||
--rendertiddler $:/core/save/empty plugins/tiddlywiki/highlight/empty.html text/plain \
|
--rendertiddler $:/core/save/empty plugins/tiddlywiki/highlight/empty.html text/plain \
|
||||||
|| exit 1
|
|| 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
|
# Language editions
|
||||||
|
|||||||
47
boot/boot.js
47
boot/boot.js
@@ -142,15 +142,15 @@ $tw.utils.each = function(object,callback) {
|
|||||||
var next,f,length;
|
var next,f,length;
|
||||||
if(object) {
|
if(object) {
|
||||||
if(Object.prototype.toString.call(object) == "[object Array]") {
|
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);
|
next = callback(object[f],f,object);
|
||||||
if(next === false) {
|
if(next === false) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var keys = Object.keys(object);
|
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];
|
var key = keys[f];
|
||||||
next = callback(object[key],key,object);
|
next = callback(object[key],key,object);
|
||||||
if(next === false) {
|
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.extend = function(object /*, sourceObjectList */) {
|
||||||
$tw.utils.each(Array.prototype.slice.call(arguments,1),function(source) {
|
$tw.utils.each(Array.prototype.slice.call(arguments,1),function(source) {
|
||||||
if(source) {
|
if(source) {
|
||||||
for (var p in source) {
|
for(var p in source) {
|
||||||
object[p] = source[p];
|
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.deepDefaults = function(object /*, sourceObjectList */) {
|
||||||
$tw.utils.each(Array.prototype.slice.call(arguments,1),function(source) {
|
$tw.utils.each(Array.prototype.slice.call(arguments,1),function(source) {
|
||||||
if(source) {
|
if(source) {
|
||||||
for (var p in source) {
|
for(var p in source) {
|
||||||
if(object[p] === null || object[p] === undefined) {
|
if(object[p] === null || object[p] === undefined) {
|
||||||
object[p] = source[p];
|
object[p] = source[p];
|
||||||
}
|
}
|
||||||
@@ -893,8 +893,8 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
|
|||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
CommonJS optional require.main property:
|
CommonJS optional require.main property:
|
||||||
In a browser we offer a fake main module which points back to the boot function
|
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)
|
(Theoretically, this may allow TW to eventually load itself as a module in the browser)
|
||||||
*/
|
*/
|
||||||
Object.defineProperty(sandbox.require, "main", {
|
Object.defineProperty(sandbox.require, "main", {
|
||||||
value: (typeof(require) !== "undefined") ? require.main : {TiddlyWiki: _boot},
|
value: (typeof(require) !== "undefined") ? require.main : {TiddlyWiki: _boot},
|
||||||
@@ -936,9 +936,9 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
|
|||||||
moduleInfo.exports = moduleInfo.definition;
|
moduleInfo.exports = moduleInfo.definition;
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if (e instanceof SyntaxError) {
|
if(e instanceof SyntaxError) {
|
||||||
var line = e.lineNumber || e.line; // Firefox || Safari
|
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);
|
$tw.utils.error("Syntax error in boot module " + name + ":" + line + ":\n" + e.stack);
|
||||||
} else if(!$tw.browser) {
|
} else if(!$tw.browser) {
|
||||||
// this is the only way to get node.js to display the line at which the syntax error appeared,
|
// 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() {
|
$tw.Wiki.prototype.defineTiddlerModules = function() {
|
||||||
this.each(function(tiddler,title) {
|
this.each(function(tiddler,title) {
|
||||||
if(tiddler.hasField("module-type")) {
|
if(tiddler.hasField("module-type")) {
|
||||||
switch (tiddler.fields.type) {
|
switch(tiddler.fields.type) {
|
||||||
case "application/javascript":
|
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
|
// 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)) {
|
if(!$tw.utils.hop($tw.modules.titles,tiddler.fields.title)) {
|
||||||
@@ -2043,7 +2043,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
|||||||
arrayOfFiles = arrayOfFiles || [];
|
arrayOfFiles = arrayOfFiles || [];
|
||||||
var files = fs.readdirSync(dirPath);
|
var files = fs.readdirSync(dirPath);
|
||||||
files.forEach(function(file) {
|
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);
|
arrayOfFiles = getAllFiles(dirPath + path.sep + file, recurse, arrayOfFiles);
|
||||||
} else if(fs.statSync(dirPath + path.sep + file).isFile()){
|
} else if(fs.statSync(dirPath + path.sep + file).isFile()){
|
||||||
arrayOfFiles.push(path.join(dirPath, path.sep, file));
|
arrayOfFiles.push(path.join(dirPath, path.sep, file));
|
||||||
@@ -2188,13 +2188,16 @@ Returns an array of search paths
|
|||||||
*/
|
*/
|
||||||
$tw.getLibraryItemSearchPaths = function(libraryPath,envVar) {
|
$tw.getLibraryItemSearchPaths = function(libraryPath,envVar) {
|
||||||
var pluginPaths = [path.resolve($tw.boot.corePath,libraryPath)],
|
var pluginPaths = [path.resolve($tw.boot.corePath,libraryPath)],
|
||||||
|
env;
|
||||||
|
if(envVar) {
|
||||||
env = process.env[envVar];
|
env = process.env[envVar];
|
||||||
if(env) {
|
if(env) {
|
||||||
env.split(path.delimiter).map(function(item) {
|
env.split(path.delimiter).map(function(item) {
|
||||||
if(item) {
|
if(item) {
|
||||||
pluginPaths.push(item);
|
pluginPaths.push(item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return pluginPaths;
|
return pluginPaths;
|
||||||
};
|
};
|
||||||
@@ -2280,7 +2283,7 @@ $tw.loadWikiTiddlers = function(wikiPath,options) {
|
|||||||
}
|
}
|
||||||
$tw.wiki.addTiddlers(tiddlerFile.tiddlers);
|
$tw.wiki.addTiddlers(tiddlerFile.tiddlers);
|
||||||
});
|
});
|
||||||
if ($tw.boot.wikiPath == wikiPath) {
|
if($tw.boot.wikiPath == wikiPath) {
|
||||||
// Save the original tiddler file locations if requested
|
// Save the original tiddler file locations if requested
|
||||||
var output = {}, relativePath, fileInfo;
|
var output = {}, relativePath, fileInfo;
|
||||||
for(var title in $tw.boot.files) {
|
for(var title in $tw.boot.files) {
|
||||||
@@ -2634,14 +2637,14 @@ $tw.boot.doesTaskMatchPlatform = function(taskModule) {
|
|||||||
var platforms = taskModule.platforms;
|
var platforms = taskModule.platforms;
|
||||||
if(platforms) {
|
if(platforms) {
|
||||||
for(var t=0; t<platforms.length; t++) {
|
for(var t=0; t<platforms.length; t++) {
|
||||||
switch (platforms[t]) {
|
switch(platforms[t]) {
|
||||||
case "browser":
|
case "browser":
|
||||||
if ($tw.browser) {
|
if($tw.browser) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "node":
|
case "node":
|
||||||
if ($tw.node) {
|
if($tw.node) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2724,7 +2727,7 @@ Invoke the hook by key
|
|||||||
$tw.hooks.invokeHook = function(hookName /*, value,... */) {
|
$tw.hooks.invokeHook = function(hookName /*, value,... */) {
|
||||||
var args = Array.prototype.slice.call(arguments,1);
|
var args = Array.prototype.slice.call(arguments,1);
|
||||||
if($tw.utils.hop($tw.hooks.names,hookName)) {
|
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);
|
args[0] = $tw.hooks.names[hookName][i].apply(null,args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
title: $:/library/sjcl.js
|
|
||||||
type: application/javascript
|
|
||||||
library: yes
|
|
||||||
32
boot/tiddlywiki.files
Normal file
32
boot/tiddlywiki.files
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
5
core/images/input-button.tid
Normal file
5
core/images/input-button.tid
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
title: $:/core/images/input-button
|
||||||
|
tags: $:/tags/Image
|
||||||
|
|
||||||
|
\parameters (size:"22pt")
|
||||||
|
<svg width=<<size>> height=<<size>> class="tc-image-input-button tc-image-button" viewBox="0 0 22 22"><path d="M1.375 22h19.249c.365 0 .716-.145.973-.404v.001c.258-.257.404-.607.403-.972v-11a1.376 1.376 0 0 0-2.75 0v9.625H2.75V9.625a1.376 1.376 0 0 0-2.75 0v11C0 21.384.617 22 1.375 22Z"/><path d="m9.732 11.904-1.541-1.541a1.375 1.375 0 1 0-1.944 1.944l3.887 3.888c.258.258.608.402.973.402h-.001c.353 0 .705-.134.974-.402l3.888-3.889a1.376 1.376 0 0 0 .001-1.944 1.377 1.377 0 0 0-1.946 0l-1.541 1.542V1.376a1.375 1.375 0 1 0-2.75 0v10.528Z"/></svg>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
title: $:/core/images/default-layout
|
title: $:/core/images/standard-layout
|
||||||
tags: $:/tags/Image
|
tags: $:/tags/Image
|
||||||
|
|
||||||
\parameters (size:"22pt")
|
\parameters (size:"22pt")
|
||||||
<svg width=<<size>> height=<<size>> class="tc-image-default-layout tc-image-button" viewBox="0 0 128 128">
|
<svg width=<<size>> height=<<size>> class="tc-image-standard-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"/>
|
<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>
|
</svg>
|
||||||
@@ -104,6 +104,8 @@ ShowSideBar/Caption: show sidebar
|
|||||||
ShowSideBar/Hint: Show sidebar
|
ShowSideBar/Hint: Show sidebar
|
||||||
TagManager/Caption: tag manager
|
TagManager/Caption: tag manager
|
||||||
TagManager/Hint: Open tag manager
|
TagManager/Hint: Open tag manager
|
||||||
|
TestCaseImport/Caption: import tiddlers
|
||||||
|
TestCaseImport/Hint: Import tiddlers
|
||||||
Timestamp/Caption: timestamps
|
Timestamp/Caption: timestamps
|
||||||
Timestamp/Hint: Choose whether modifications update timestamps
|
Timestamp/Hint: Choose whether modifications update timestamps
|
||||||
Timestamp/On/Caption: timestamps are on
|
Timestamp/On/Caption: timestamps are on
|
||||||
|
|||||||
@@ -206,6 +206,12 @@ Stylesheets/Caption: Stylesheets
|
|||||||
Stylesheets/Expand/Caption: Expand All
|
Stylesheets/Expand/Caption: Expand All
|
||||||
Stylesheets/Hint: This is the rendered CSS of the current stylesheet tiddlers tagged with <<tag "$:/tags/Stylesheet">>
|
Stylesheets/Hint: This is the rendered CSS of the current stylesheet tiddlers tagged with <<tag "$:/tags/Stylesheet">>
|
||||||
Stylesheets/Restore/Caption: Restore
|
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/Caption: Theme
|
||||||
Theme/Prompt: Current theme:
|
Theme/Prompt: Current theme:
|
||||||
TiddlerFields/Caption: Tiddler Fields
|
TiddlerFields/Caption: Tiddler Fields
|
||||||
|
|||||||
@@ -65,6 +65,13 @@ sidebar-tab-foreground-selected: Sidebar tab foreground for selected tabs
|
|||||||
sidebar-tab-foreground: Sidebar tab foreground
|
sidebar-tab-foreground: Sidebar tab foreground
|
||||||
sidebar-tiddler-link-foreground-hover: Sidebar tiddler link foreground hover
|
sidebar-tiddler-link-foreground-hover: Sidebar tiddler link foreground hover
|
||||||
sidebar-tiddler-link-foreground: Sidebar tiddler link foreground
|
sidebar-tiddler-link-foreground: Sidebar tiddler link foreground
|
||||||
|
stability-stable: Badge for stability level "stable"
|
||||||
|
stability-experimental: Badge for stability level "experimental"
|
||||||
|
stability-deprecated: Badge for stability level "deprecated"
|
||||||
|
stability-legacy: Badge for stability level "legacy"
|
||||||
|
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
|
site-title-foreground: Site title foreground
|
||||||
static-alert-foreground: Static alert foreground
|
static-alert-foreground: Static alert foreground
|
||||||
tab-background-selected: Tab background for selected tabs
|
tab-background-selected: Tab background for selected tabs
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ 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
|
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-priority: A numerical value indicating the priority of a plugin tiddler
|
||||||
plugin-type: The type of plugin in 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
|
revision: The revision of the tiddler held at the server
|
||||||
released: Date of a TiddlyWiki release
|
released: Date of a TiddlyWiki release
|
||||||
source: The source URL associated with a tiddler
|
source: The source URL associated with a tiddler
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ No: No
|
|||||||
OfficialPluginLibrary: Official ~TiddlyWiki Plugin Library
|
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.
|
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/Description: the default ~TiddlyWiki layout
|
||||||
PageTemplate/Name: Default ~PageTemplate
|
PageTemplate/Name: Standard Layout
|
||||||
PluginReloadWarning: Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect
|
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
|
RecentChanges/DateFormat: DDth MMM YYYY
|
||||||
Shortcuts/Input/AdvancedSearch/Hint: Open the ~AdvancedSearch panel from within the sidebar search field
|
Shortcuts/Input/AdvancedSearch/Hint: Open the ~AdvancedSearch panel from within the sidebar search field
|
||||||
|
|||||||
@@ -27,33 +27,8 @@ var Command = function(params,commander,callback) {
|
|||||||
|
|
||||||
Command.prototype.execute = function() {
|
Command.prototype.execute = function() {
|
||||||
var wiki = this.commander.wiki,
|
var wiki = this.commander.wiki,
|
||||||
fs = require("fs"),
|
|
||||||
path = require("path"),
|
|
||||||
upgradeLibraryTitle = this.params[0] || UPGRADE_LIBRARY_TITLE,
|
upgradeLibraryTitle = this.params[0] || UPGRADE_LIBRARY_TITLE,
|
||||||
tiddlers = {};
|
tiddlers = $tw.utils.getAllPlugins();
|
||||||
// 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
|
// Save the upgrade library tiddler
|
||||||
var pluginFields = {
|
var pluginFields = {
|
||||||
title: upgradeLibraryTitle,
|
title: upgradeLibraryTitle,
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ Saves individual tiddlers in their raw text or binary format to the specified fi
|
|||||||
directory: path.resolve(self.commander.outputPath),
|
directory: path.resolve(self.commander.outputPath),
|
||||||
pathFilters: [filenameFilter],
|
pathFilters: [filenameFilter],
|
||||||
wiki: wiki,
|
wiki: wiki,
|
||||||
fileInfo: {}
|
fileInfo: {
|
||||||
|
overwrite: true
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if(self.commander.verbose) {
|
if(self.commander.verbose) {
|
||||||
console.log("Saving \"" + title + "\" to \"" + fileInfo.filepath + "\"");
|
console.log("Saving \"" + title + "\" to \"" + fileInfo.filepath + "\"");
|
||||||
|
|||||||
@@ -176,7 +176,10 @@ WikiFolderMaker.prototype.saveCustomPlugin = function(pluginTiddler) {
|
|||||||
this.saveJSONFile(directory + path.sep + "plugin.info",pluginInfo);
|
this.saveJSONFile(directory + path.sep + "plugin.info",pluginInfo);
|
||||||
self.log("Writing " + directory + path.sep + "plugin.info: " + JSON.stringify(pluginInfo,null,$tw.config.preferences.jsonSpaces));
|
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
|
var pluginTiddlers = $tw.utils.parseJSONSafe(pluginTiddler.fields.text).tiddlers; // A hashmap of tiddlers in the plugin
|
||||||
$tw.utils.each(pluginTiddlers,function(tiddler) {
|
$tw.utils.each(pluginTiddlers,function(tiddler,title) {
|
||||||
|
if(!tiddler.title) {
|
||||||
|
tiddler.title = title;
|
||||||
|
}
|
||||||
self.saveTiddler(directory,new $tw.Tiddler(tiddler));
|
self.saveTiddler(directory,new $tw.Tiddler(tiddler));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ Filter operator for returning all the backtranscludes from a tiddler
|
|||||||
Export our filter function
|
Export our filter function
|
||||||
*/
|
*/
|
||||||
exports.backtranscludes = function(source,operator,options) {
|
exports.backtranscludes = function(source,operator,options) {
|
||||||
var results = [];
|
var results = new $tw.utils.LinkedList();
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
$tw.utils.pushTop(results,options.wiki.getTiddlerBacktranscludes(title));
|
results.pushTop(options.wiki.getTiddlerBacktranscludes(title));
|
||||||
});
|
});
|
||||||
return results;
|
return results.makeTiddlerIterator(options.wiki);
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ function diffPartsToChars(text1,text2,mode) {
|
|||||||
if(lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : (lineHash[line] !== undefined)) {
|
if(lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : (lineHash[line] !== undefined)) {
|
||||||
chars += String.fromCharCode(lineHash[line]);
|
chars += String.fromCharCode(lineHash[line]);
|
||||||
} else {
|
} else {
|
||||||
if (lineArrayLength == maxLines) {
|
if(lineArrayLength == maxLines) {
|
||||||
line = text.substring(lineStart);
|
line = text.substring(lineStart);
|
||||||
lineEnd = text.length;
|
lineEnd = text.length;
|
||||||
}
|
}
|
||||||
@@ -217,7 +217,10 @@ exports.splitregexp = function(source,operator,options) {
|
|||||||
return ["RegExp error: " + ex];
|
return ["RegExp error: " + ex];
|
||||||
}
|
}
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
Array.prototype.push.apply(result,title.split(regExp));
|
var parts = title.split(regExp).map(function(part){
|
||||||
|
return part || ""; // make sure it's a string
|
||||||
|
});
|
||||||
|
Array.prototype.push.apply(result,parts);
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
@@ -264,7 +267,7 @@ exports.pad = function(source,operator,options) {
|
|||||||
} else {
|
} else {
|
||||||
var padString = "",
|
var padString = "",
|
||||||
padStringLength = targetLength - title.length;
|
padStringLength = targetLength - title.length;
|
||||||
while (padStringLength > padString.length) {
|
while(padStringLength > padString.length) {
|
||||||
padString += fill;
|
padString += fill;
|
||||||
}
|
}
|
||||||
//make sure we do not exceed the specified length
|
//make sure we do not exceed the specified length
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ exports.transcludes = function(source,operator,options) {
|
|||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
results.pushTop(options.wiki.getTiddlerTranscludes(title));
|
results.pushTop(options.wiki.getTiddlerTranscludes(title));
|
||||||
});
|
});
|
||||||
return results.toArray();
|
return results.makeTiddlerIterator(options.wiki);
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -70,9 +70,12 @@ BackSubIndexer.prototype.rebuild = function() {
|
|||||||
* Get things that is being referenced in the text, e.g. tiddler names in the link syntax.
|
* Get things that is being referenced in the text, e.g. tiddler names in the link syntax.
|
||||||
*/
|
*/
|
||||||
BackSubIndexer.prototype._getTarget = function(tiddler) {
|
BackSubIndexer.prototype._getTarget = function(tiddler) {
|
||||||
|
if(this.wiki.isBinaryTiddler(tiddler.fields.text)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
var parser = this.wiki.parseText(tiddler.fields.type, tiddler.fields.text, {});
|
var parser = this.wiki.parseText(tiddler.fields.type, tiddler.fields.text, {});
|
||||||
if(parser) {
|
if(parser) {
|
||||||
return this.wiki[this.extractor](parser.tree);
|
return this.wiki[this.extractor](parser.tree, tiddler.fields.title);
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ exports.parseStringLiteral = function(source,pos) {
|
|||||||
var match = reString.exec(source);
|
var match = reString.exec(source);
|
||||||
if(match && match.index === pos) {
|
if(match && match.index === pos) {
|
||||||
node.value = match[1] !== undefined ? match[1] :(
|
node.value = match[1] !== undefined ? match[1] :(
|
||||||
match[2] !== undefined ? match[2] : match[3]
|
match[2] !== undefined ? match[2] : match[3]
|
||||||
);
|
);
|
||||||
node.end = pos + match[0].length;
|
node.end = pos + match[0].length;
|
||||||
return node;
|
return node;
|
||||||
|
|||||||
@@ -29,13 +29,16 @@ exports.init = function(parser) {
|
|||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
var reEnd = /(\r?\n```$)/mg;
|
var reEnd = /(\r?\n```$)/mg;
|
||||||
|
var languageStart = this.parser.pos + 3,
|
||||||
|
languageEnd = languageStart + this.match[1].length;
|
||||||
// Move past the match
|
// Move past the match
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
|
|
||||||
// Look for the end of the block
|
// Look for the end of the block
|
||||||
reEnd.lastIndex = this.parser.pos;
|
reEnd.lastIndex = this.parser.pos;
|
||||||
var match = reEnd.exec(this.parser.source),
|
var match = reEnd.exec(this.parser.source),
|
||||||
text;
|
text,
|
||||||
|
codeStart = this.parser.pos;
|
||||||
// Process the block
|
// Process the block
|
||||||
if(match) {
|
if(match) {
|
||||||
text = this.parser.source.substring(this.parser.pos,match.index);
|
text = this.parser.source.substring(this.parser.pos,match.index);
|
||||||
@@ -48,8 +51,8 @@ exports.parse = function() {
|
|||||||
return [{
|
return [{
|
||||||
type: "codeblock",
|
type: "codeblock",
|
||||||
attributes: {
|
attributes: {
|
||||||
code: {type: "string", value: text},
|
code: {type: "string", value: text, start: codeStart, end: this.parser.pos},
|
||||||
language: {type: "string", value: this.match[1]}
|
language: {type: "string", value: this.match[1], start: languageStart, end: languageEnd}
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ exports.parse = function() {
|
|||||||
// Look for the end marker
|
// Look for the end marker
|
||||||
reEnd.lastIndex = this.parser.pos;
|
reEnd.lastIndex = this.parser.pos;
|
||||||
var match = reEnd.exec(this.parser.source),
|
var match = reEnd.exec(this.parser.source),
|
||||||
text;
|
text,
|
||||||
|
start = this.parser.pos;
|
||||||
// Process the text
|
// Process the text
|
||||||
if(match) {
|
if(match) {
|
||||||
text = this.parser.source.substring(this.parser.pos,match.index);
|
text = this.parser.source.substring(this.parser.pos,match.index);
|
||||||
@@ -47,7 +48,9 @@ exports.parse = function() {
|
|||||||
tag: "code",
|
tag: "code",
|
||||||
children: [{
|
children: [{
|
||||||
type: "text",
|
type: "text",
|
||||||
text: text
|
text: text,
|
||||||
|
start: start,
|
||||||
|
end: this.parser.pos
|
||||||
}]
|
}]
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ exports.init = function(parser) {
|
|||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
// Move past the match
|
// Move past the match
|
||||||
|
var start = this.parser.pos;
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Create the link unless it is suppressed
|
// Create the link unless it is suppressed
|
||||||
if(this.match[0].substr(0,1) === "~") {
|
if(this.match[0].substr(0,1) === "~") {
|
||||||
@@ -46,7 +47,7 @@ exports.parse = function() {
|
|||||||
rel: {type: "string", value: "noopener noreferrer"}
|
rel: {type: "string", value: "noopener noreferrer"}
|
||||||
},
|
},
|
||||||
children: [{
|
children: [{
|
||||||
type: "text", text: this.match[0]
|
type: "text", text: this.match[0], start: start, end: this.parser.pos
|
||||||
}]
|
}]
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,16 @@ exports.init = function(parser) {
|
|||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
// Move past the match
|
// Move past the match
|
||||||
|
var filterStart = this.parser.pos + 3;
|
||||||
|
var filterEnd = filterStart + this.match[1].length;
|
||||||
|
var toolTipStart = filterEnd + 1;
|
||||||
|
var toolTipEnd = toolTipStart + (this.match[2] ? this.match[2].length : 0);
|
||||||
|
var templateStart = toolTipEnd + 2;
|
||||||
|
var templateEnd = templateStart + (this.match[3] ? this.match[3].length : 0);
|
||||||
|
var styleStart = templateEnd + 2;
|
||||||
|
var styleEnd = styleStart + (this.match[4] ? this.match[4].length : 0);
|
||||||
|
var classesStart = styleEnd + 1;
|
||||||
|
var classesEnd = classesStart + (this.match[5] ? this.match[5].length : 0);
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Get the match details
|
// Get the match details
|
||||||
var filter = this.match[1],
|
var filter = this.match[1],
|
||||||
@@ -42,21 +52,21 @@ exports.parse = function() {
|
|||||||
var node = {
|
var node = {
|
||||||
type: "list",
|
type: "list",
|
||||||
attributes: {
|
attributes: {
|
||||||
filter: {type: "string", value: filter}
|
filter: {type: "string", value: filter, start: filterStart, end: filterEnd},
|
||||||
},
|
},
|
||||||
isBlock: true
|
isBlock: true
|
||||||
};
|
};
|
||||||
if(tooltip) {
|
if(tooltip) {
|
||||||
node.attributes.tooltip = {type: "string", value: tooltip};
|
node.attributes.tooltip = {type: "string", value: tooltip, start: toolTipStart, end: toolTipEnd};
|
||||||
}
|
}
|
||||||
if(template) {
|
if(template) {
|
||||||
node.attributes.template = {type: "string", value: template};
|
node.attributes.template = {type: "string", value: template, start: templateStart, end: templateEnd};
|
||||||
}
|
}
|
||||||
if(style) {
|
if(style) {
|
||||||
node.attributes.style = {type: "string", value: style};
|
node.attributes.style = {type: "string", value: style, start: styleStart, end: styleEnd};
|
||||||
}
|
}
|
||||||
if(classes) {
|
if(classes) {
|
||||||
node.attributes.itemClass = {type: "string", value: classes.split(".").join(" ")};
|
node.attributes.itemClass = {type: "string", value: classes.split(".").join(" "), start: classesStart, end: classesEnd};
|
||||||
}
|
}
|
||||||
return [node];
|
return [node];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,6 +30,16 @@ exports.init = function(parser) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
|
var filterStart = this.parser.pos + 3;
|
||||||
|
var filterEnd = filterStart + this.match[1].length;
|
||||||
|
var toolTipStart = filterEnd + 1;
|
||||||
|
var toolTipEnd = toolTipStart + (this.match[2] ? this.match[2].length : 0);
|
||||||
|
var templateStart = toolTipEnd + 2;
|
||||||
|
var templateEnd = templateStart + (this.match[3] ? this.match[3].length : 0);
|
||||||
|
var styleStart = templateEnd + 2;
|
||||||
|
var styleEnd = styleStart + (this.match[4] ? this.match[4].length : 0);
|
||||||
|
var classesStart = styleEnd + 1;
|
||||||
|
var classesEnd = classesStart + (this.match[5] ? this.match[5].length : 0);
|
||||||
// Move past the match
|
// Move past the match
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Get the match details
|
// Get the match details
|
||||||
@@ -42,20 +52,20 @@ exports.parse = function() {
|
|||||||
var node = {
|
var node = {
|
||||||
type: "list",
|
type: "list",
|
||||||
attributes: {
|
attributes: {
|
||||||
filter: {type: "string", value: filter}
|
filter: {type: "string", value: filter, start: filterStart, end: filterEnd},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if(tooltip) {
|
if(tooltip) {
|
||||||
node.attributes.tooltip = {type: "string", value: tooltip};
|
node.attributes.tooltip = {type: "string", value: tooltip, start: toolTipStart, end: toolTipEnd};
|
||||||
}
|
}
|
||||||
if(template) {
|
if(template) {
|
||||||
node.attributes.template = {type: "string", value: template};
|
node.attributes.template = {type: "string", value: template, start: templateStart, end: templateEnd};
|
||||||
}
|
}
|
||||||
if(style) {
|
if(style) {
|
||||||
node.attributes.style = {type: "string", value: style};
|
node.attributes.style = {type: "string", value: style, start: styleStart, end: styleEnd};
|
||||||
}
|
}
|
||||||
if(classes) {
|
if(classes) {
|
||||||
node.attributes.itemClass = {type: "string", value: classes.split(".").join(" ")};
|
node.attributes.itemClass = {type: "string", value: classes.split(".").join(" "), start: classesStart, end: classesEnd};
|
||||||
}
|
}
|
||||||
return [node];
|
return [node];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,10 +45,11 @@ exports.parse = function() {
|
|||||||
reEnd.lastIndex = this.parser.pos;
|
reEnd.lastIndex = this.parser.pos;
|
||||||
match = reEnd.exec(this.parser.source);
|
match = reEnd.exec(this.parser.source);
|
||||||
if(match) {
|
if(match) {
|
||||||
|
var start = this.parser.pos;
|
||||||
this.parser.pos = reEnd.lastIndex;
|
this.parser.pos = reEnd.lastIndex;
|
||||||
// Add a line break if the terminator was a line break
|
// Add a line break if the terminator was a line break
|
||||||
if(match[2]) {
|
if(match[2]) {
|
||||||
tree.push({type: "element", tag: "br"});
|
tree.push({type: "element", tag: "br", start: start, end: this.parser.pos});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(match && !match[1]);
|
} while(match && !match[1]);
|
||||||
|
|||||||
@@ -30,15 +30,17 @@ exports.parse = function() {
|
|||||||
// Move past the !s
|
// Move past the !s
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Parse any classes, whitespace and then the heading itself
|
// Parse any classes, whitespace and then the heading itself
|
||||||
|
var classStart = this.parser.pos;
|
||||||
var classes = this.parser.parseClasses();
|
var classes = this.parser.parseClasses();
|
||||||
|
var classEnd = this.parser.pos;
|
||||||
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
|
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
|
||||||
var tree = this.parser.parseInlineRun(/(\r?\n)/mg);
|
var tree = this.parser.parseInlineRun(/(\r?\n)/mg);
|
||||||
// Return the heading
|
// Return the heading
|
||||||
return [{
|
return [{
|
||||||
type: "element",
|
type: "element",
|
||||||
tag: "h" + headingLevel,
|
tag: "h" + headingLevel,
|
||||||
attributes: {
|
attributes: {
|
||||||
"class": {type: "string", value: classes.join(" ")}
|
"class": {type: "string", value: classes.join(" "), start: classStart, end: classEnd}
|
||||||
},
|
},
|
||||||
children: tree
|
children: tree
|
||||||
}];
|
}];
|
||||||
|
|||||||
@@ -44,6 +44,10 @@ Parse the most recent match
|
|||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
// Retrieve the most recent match so that recursive calls don't overwrite it
|
// Retrieve the most recent match so that recursive calls don't overwrite it
|
||||||
var tag = this.nextTag;
|
var tag = this.nextTag;
|
||||||
|
if (!tag.isSelfClosing) {
|
||||||
|
tag.openTagStart = tag.start;
|
||||||
|
tag.openTagEnd = tag.end;
|
||||||
|
}
|
||||||
this.nextTag = null;
|
this.nextTag = null;
|
||||||
// Advance the parser position to past the tag
|
// Advance the parser position to past the tag
|
||||||
this.parser.pos = tag.end;
|
this.parser.pos = tag.end;
|
||||||
@@ -60,6 +64,27 @@ exports.parse = function() {
|
|||||||
var reEnd = new RegExp("(" + reEndString + ")","mg");
|
var reEnd = new RegExp("(" + reEndString + ")","mg");
|
||||||
tag.children = this.parser.parseInlineRun(reEnd,{eatTerminator: true});
|
tag.children = this.parser.parseInlineRun(reEnd,{eatTerminator: true});
|
||||||
}
|
}
|
||||||
|
tag.end = this.parser.pos;
|
||||||
|
tag.closeTagEnd = tag.end;
|
||||||
|
if (tag.closeTagEnd === tag.openTagEnd || this.parser.source[tag.closeTagEnd - 1] !== '>') {
|
||||||
|
tag.closeTagStart = tag.end;
|
||||||
|
} else {
|
||||||
|
tag.closeTagStart = tag.closeTagEnd - 2;
|
||||||
|
var closeTagMinPos = tag.children.length > 0 ? tag.children[tag.children.length-1].end : tag.openTagEnd;
|
||||||
|
if (!Number.isSafeInteger(closeTagMinPos)) closeTagMinPos = tag.openTagEnd;
|
||||||
|
while (tag.closeTagStart >= closeTagMinPos) {
|
||||||
|
var char = this.parser.source[tag.closeTagStart];
|
||||||
|
if (char === '>') {
|
||||||
|
tag.closeTagStart = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (char === '<') break;
|
||||||
|
tag.closeTagStart -= 1;
|
||||||
|
}
|
||||||
|
if (tag.closeTagStart < closeTagMinPos) {
|
||||||
|
tag.closeTagStart = tag.end;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Return the tag
|
// Return the tag
|
||||||
return [tag];
|
return [tag];
|
||||||
|
|||||||
@@ -122,9 +122,9 @@ exports.parseImage = function(source,pos) {
|
|||||||
}
|
}
|
||||||
pos = token.end;
|
pos = token.end;
|
||||||
if(token.match[1]) {
|
if(token.match[1]) {
|
||||||
node.attributes.tooltip = {type: "string", value: token.match[1].trim()};
|
node.attributes.tooltip = {type: "string", value: token.match[1].trim(),start: token.start,end:token.start + token.match[1].length - 1};
|
||||||
}
|
}
|
||||||
node.attributes.source = {type: "string", value: (token.match[2] || "").trim()};
|
node.attributes.source = {type: "string", value: (token.match[2] || "").trim(), start: token.start + (token.match[1] ? token.match[1].length : 0), end: token.end - 2};
|
||||||
// Update the end position
|
// Update the end position
|
||||||
node.end = pos;
|
node.end = pos;
|
||||||
return node;
|
return node;
|
||||||
|
|||||||
@@ -38,13 +38,14 @@ exports.parse = function() {
|
|||||||
// Parse the filter terminated by a line break
|
// Parse the filter terminated by a line break
|
||||||
var reMatch = /(.*)(?:$|\r?\n)/mg;
|
var reMatch = /(.*)(?:$|\r?\n)/mg;
|
||||||
reMatch.lastIndex = this.parser.pos;
|
reMatch.lastIndex = this.parser.pos;
|
||||||
|
var filterStart = this.parser.source;
|
||||||
var match = reMatch.exec(this.parser.source);
|
var match = reMatch.exec(this.parser.source);
|
||||||
this.parser.pos = reMatch.lastIndex;
|
this.parser.pos = reMatch.lastIndex;
|
||||||
// Parse tree nodes to return
|
// Parse tree nodes to return
|
||||||
return [{
|
return [{
|
||||||
type: "importvariables",
|
type: "importvariables",
|
||||||
attributes: {
|
attributes: {
|
||||||
filter: {type: "string", value: match[1]}
|
filter: {type: "string", value: match[1], start: filterStart, end: this.parser.pos}
|
||||||
},
|
},
|
||||||
children: []
|
children: []
|
||||||
}];
|
}];
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ exports.parse = function() {
|
|||||||
// Match the list marker
|
// Match the list marker
|
||||||
var reMatch = /([\*#;:>]+)/mg;
|
var reMatch = /([\*#;:>]+)/mg;
|
||||||
reMatch.lastIndex = this.parser.pos;
|
reMatch.lastIndex = this.parser.pos;
|
||||||
|
var start = this.parser.pos;
|
||||||
var match = reMatch.exec(this.parser.source);
|
var match = reMatch.exec(this.parser.source);
|
||||||
if(!match || match.index !== this.parser.pos) {
|
if(!match || match.index !== this.parser.pos) {
|
||||||
break;
|
break;
|
||||||
@@ -94,9 +95,21 @@ exports.parse = function() {
|
|||||||
}
|
}
|
||||||
// Construct the list element or reuse the previous one at this level
|
// Construct the list element or reuse the previous one at this level
|
||||||
if(listStack.length <= t) {
|
if(listStack.length <= t) {
|
||||||
var listElement = {type: "element", tag: listInfo.listTag, children: [
|
var listElement = {
|
||||||
{type: "element", tag: listInfo.itemTag, children: []}
|
type: "element",
|
||||||
]};
|
tag: listInfo.listTag,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: "element",
|
||||||
|
tag: listInfo.itemTag,
|
||||||
|
children: [],
|
||||||
|
start: start,
|
||||||
|
end: this.parser.pos,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
start: start,
|
||||||
|
end: this.parser.pos,
|
||||||
|
};
|
||||||
// Link this list element into the last child item of the parent list item
|
// Link this list element into the last child item of the parent list item
|
||||||
if(t) {
|
if(t) {
|
||||||
var prevListItem = listStack[t-1].children[listStack[t-1].children.length-1];
|
var prevListItem = listStack[t-1].children[listStack[t-1].children.length-1];
|
||||||
@@ -105,21 +118,33 @@ exports.parse = function() {
|
|||||||
// Save this element in the stack
|
// Save this element in the stack
|
||||||
listStack[t] = listElement;
|
listStack[t] = listElement;
|
||||||
} else if(t === (match[0].length - 1)) {
|
} else if(t === (match[0].length - 1)) {
|
||||||
listStack[t].children.push({type: "element", tag: listInfo.itemTag, children: []});
|
listStack[t].children.push({
|
||||||
|
type: "element",
|
||||||
|
tag: listInfo.itemTag,
|
||||||
|
children: [],
|
||||||
|
start: start,
|
||||||
|
end: this.parser.pos,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(listStack.length > match[0].length) {
|
if(listStack.length > match[0].length) {
|
||||||
listStack.splice(match[0].length,listStack.length - match[0].length);
|
listStack.splice(match[0].length,listStack.length - match[0].length);
|
||||||
}
|
}
|
||||||
// Process the body of the list item into the last list item
|
// Process the body of the list item into the last list item
|
||||||
|
var classStart = this.parser.pos;
|
||||||
var lastListChildren = listStack[listStack.length-1].children,
|
var lastListChildren = listStack[listStack.length-1].children,
|
||||||
lastListItem = lastListChildren[lastListChildren.length-1],
|
lastListItem = lastListChildren[lastListChildren.length-1],
|
||||||
classes = this.parser.parseClasses();
|
classes = this.parser.parseClasses();
|
||||||
|
var classEnd = this.parser.pos;
|
||||||
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
|
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
|
||||||
var tree = this.parser.parseInlineRun(/(\r?\n)/mg);
|
var tree = this.parser.parseInlineRun(/(\r?\n)/mg);
|
||||||
lastListItem.children.push.apply(lastListItem.children,tree);
|
lastListItem.children.push.apply(lastListItem.children,tree);
|
||||||
|
lastListItem.end = this.parser.pos;
|
||||||
|
listStack[listStack.length-1].end = this.parser.pos;
|
||||||
if(classes.length > 0) {
|
if(classes.length > 0) {
|
||||||
$tw.utils.addClassToParseTreeNode(lastListItem,classes.join(" "));
|
$tw.utils.addClassToParseTreeNode(lastListItem,classes.join(" "));
|
||||||
|
lastListItem.attributes.class.start = classStart;
|
||||||
|
lastListItem.attributes.class.end = classEnd;
|
||||||
}
|
}
|
||||||
// Consume any whitespace following the list item
|
// Consume any whitespace following the list item
|
||||||
this.parser.skipWhitespace();
|
this.parser.skipWhitespace();
|
||||||
|
|||||||
@@ -96,15 +96,20 @@ exports.parseLink = function(source,pos) {
|
|||||||
splitPos = null;
|
splitPos = null;
|
||||||
}
|
}
|
||||||
// Pull out the tooltip and URL
|
// Pull out the tooltip and URL
|
||||||
var tooltip, URL;
|
var tooltip, URL, urlStart;
|
||||||
|
textNode.start = pos;
|
||||||
if(splitPos) {
|
if(splitPos) {
|
||||||
|
urlStart = splitPos + 1;
|
||||||
URL = source.substring(splitPos + 1,closePos).trim();
|
URL = source.substring(splitPos + 1,closePos).trim();
|
||||||
textNode.text = source.substring(pos,splitPos).trim();
|
textNode.text = source.substring(pos,splitPos).trim();
|
||||||
|
textNode.end = splitPos;
|
||||||
} else {
|
} else {
|
||||||
|
urlStart = pos;
|
||||||
URL = source.substring(pos,closePos).trim();
|
URL = source.substring(pos,closePos).trim();
|
||||||
textNode.text = URL;
|
textNode.text = URL;
|
||||||
|
textNode.end = closePos;
|
||||||
}
|
}
|
||||||
node.attributes.href = {type: "string", value: URL};
|
node.attributes.href = {type: "string", value: URL, start: urlStart, end: closePos};
|
||||||
node.attributes.target = {type: "string", value: "_blank"};
|
node.attributes.target = {type: "string", value: "_blank"};
|
||||||
node.attributes.rel = {type: "string", value: "noopener noreferrer"};
|
node.attributes.rel = {type: "string", value: "noopener noreferrer"};
|
||||||
// Update the end position
|
// Update the end position
|
||||||
|
|||||||
@@ -29,32 +29,39 @@ exports.init = function(parser) {
|
|||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
// Move past the match
|
// Move past the match
|
||||||
|
var start = this.parser.pos + 2;
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Process the link
|
// Process the link
|
||||||
var text = this.match[1],
|
var text = this.match[1],
|
||||||
link = this.match[2] || text;
|
link = this.match[2] || text,
|
||||||
|
textEndPos = this.parser.source.indexOf("|", start);
|
||||||
|
if (textEndPos < 0 || textEndPos > this.matchRegExp.lastIndex) {
|
||||||
|
textEndPos = this.matchRegExp.lastIndex - 2;
|
||||||
|
}
|
||||||
|
var linkStart = this.match[2] ? (start + this.match[1].length + 1) : start;
|
||||||
|
var linkEnd = linkStart + link.length;
|
||||||
if($tw.utils.isLinkExternal(link)) {
|
if($tw.utils.isLinkExternal(link)) {
|
||||||
return [{
|
return [{
|
||||||
type: "element",
|
type: "element",
|
||||||
tag: "a",
|
tag: "a",
|
||||||
attributes: {
|
attributes: {
|
||||||
href: {type: "string", value: link},
|
href: {type: "string", value: link, start: linkStart, end: linkEnd},
|
||||||
"class": {type: "string", value: "tc-tiddlylink-external"},
|
"class": {type: "string", value: "tc-tiddlylink-external"},
|
||||||
target: {type: "string", value: "_blank"},
|
target: {type: "string", value: "_blank"},
|
||||||
rel: {type: "string", value: "noopener noreferrer"}
|
rel: {type: "string", value: "noopener noreferrer"}
|
||||||
},
|
},
|
||||||
children: [{
|
children: [{
|
||||||
type: "text", text: text
|
type: "text", text: text, start: start, end: textEndPos
|
||||||
}]
|
}]
|
||||||
}];
|
}];
|
||||||
} else {
|
} else {
|
||||||
return [{
|
return [{
|
||||||
type: "link",
|
type: "link",
|
||||||
attributes: {
|
attributes: {
|
||||||
to: {type: "string", value: link}
|
to: {type: "string", value: link, start: linkStart, end: linkEnd}
|
||||||
},
|
},
|
||||||
children: [{
|
children: [{
|
||||||
type: "text", text: text
|
type: "text", text: text, start: start, end: textEndPos
|
||||||
}]
|
}]
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,30 +3,7 @@ title: $:/core/modules/parsers/wikiparser/rules/quoteblock.js
|
|||||||
type: application/javascript
|
type: application/javascript
|
||||||
module-type: wikirule
|
module-type: wikirule
|
||||||
|
|
||||||
Wiki text rule for quote blocks. For example:
|
Wiki text rule for quote blocks.
|
||||||
|
|
||||||
```
|
|
||||||
<<<.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(){
|
(function(){
|
||||||
@@ -47,33 +24,42 @@ exports.init = function(parser) {
|
|||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
var classes = ["tc-quote"];
|
var classes = ["tc-quote"];
|
||||||
// Get all the details of the match
|
// Get all the details of the match
|
||||||
var reEndString = "^" + this.match[1] + "(?!<)";
|
var reEndString = "^\\s*" + this.match[1] + "(?!<)";
|
||||||
// Move past the <s
|
// Move past the <s
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
|
|
||||||
// Parse any classes, whitespace and then the optional cite itself
|
// Parse any classes, whitespace and then the optional cite itself
|
||||||
|
var classStart = this.parser.pos;
|
||||||
classes.push.apply(classes, this.parser.parseClasses());
|
classes.push.apply(classes, this.parser.parseClasses());
|
||||||
|
var classEnd = this.parser.pos;
|
||||||
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
|
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
|
||||||
|
var citeStart = this.parser.pos;
|
||||||
var cite = this.parser.parseInlineRun(/(\r?\n)/mg);
|
var cite = this.parser.parseInlineRun(/(\r?\n)/mg);
|
||||||
|
var citeEnd = this.parser.pos;
|
||||||
// before handling the cite, parse the body of the quote
|
// 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 we got a cite, put it before the text
|
||||||
if(cite.length > 0) {
|
if(cite.length > 0) {
|
||||||
tree.unshift({
|
tree.unshift({
|
||||||
type: "element",
|
type: "element",
|
||||||
tag: "cite",
|
tag: "cite",
|
||||||
children: cite
|
children: cite,
|
||||||
|
start: citeStart,
|
||||||
|
end: citeEnd
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Parse any optional cite
|
// Parse any optional cite
|
||||||
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
|
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
|
||||||
|
citeStart = this.parser.pos;
|
||||||
cite = this.parser.parseInlineRun(/(\r?\n)/mg);
|
cite = this.parser.parseInlineRun(/(\r?\n)/mg);
|
||||||
|
citeEnd = this.parser.pos;
|
||||||
// If we got a cite, push it
|
// If we got a cite, push it
|
||||||
if(cite.length > 0) {
|
if(cite.length > 0) {
|
||||||
tree.push({
|
tree.push({
|
||||||
type: "element",
|
type: "element",
|
||||||
tag: "cite",
|
tag: "cite",
|
||||||
children: cite
|
children: cite,
|
||||||
|
start: citeStart,
|
||||||
|
end: citeEnd
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Return the blockquote element
|
// Return the blockquote element
|
||||||
@@ -81,7 +67,7 @@ exports.parse = function() {
|
|||||||
type: "element",
|
type: "element",
|
||||||
tag: "blockquote",
|
tag: "blockquote",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: { type: "string", value: classes.join(" ") },
|
class: { type: "string", value: classes.join(" "), start: classStart, end: classEnd },
|
||||||
},
|
},
|
||||||
children: tree
|
children: tree
|
||||||
}];
|
}];
|
||||||
|
|||||||
@@ -29,10 +29,11 @@ exports.init = function(parser) {
|
|||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
var match = this.match[0];
|
var match = this.match[0];
|
||||||
// Move past the match
|
// Move past the match
|
||||||
|
var start = this.parser.pos;
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Create the link unless it is suppressed
|
// Create the link unless it is suppressed
|
||||||
if(match.substr(0,1) === "~") {
|
if(match.substr(0,1) === "~") {
|
||||||
return [{type: "text", text: match.substr(1)}];
|
return [{type: "text", text: match.substr(1), start: start+1, end: this.parser.pos}];
|
||||||
} else {
|
} else {
|
||||||
return [{
|
return [{
|
||||||
type: "link",
|
type: "link",
|
||||||
@@ -41,10 +42,12 @@ exports.parse = function() {
|
|||||||
},
|
},
|
||||||
children: [{
|
children: [{
|
||||||
type: "text",
|
type: "text",
|
||||||
text: match
|
text: match,
|
||||||
|
start: start,
|
||||||
|
end: this.parser.pos
|
||||||
}]
|
}]
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ exports.parse = function() {
|
|||||||
} else {
|
} else {
|
||||||
// Otherwise, create a new row if this one is of a different type
|
// Otherwise, create a new row if this one is of a different type
|
||||||
if(rowType !== currRowType) {
|
if(rowType !== currRowType) {
|
||||||
rowContainer = {type: "element", tag: rowContainerTypes[rowType], children: []};
|
rowContainer = {type: "element", tag: rowContainerTypes[rowType], children: [], start: this.parser.pos, end: this.parser.pos};
|
||||||
table.children.push(rowContainer);
|
table.children.push(rowContainer);
|
||||||
currRowType = rowType;
|
currRowType = rowType;
|
||||||
}
|
}
|
||||||
@@ -178,6 +178,7 @@ exports.parse = function() {
|
|||||||
// Increment the row count
|
// Increment the row count
|
||||||
rowCount++;
|
rowCount++;
|
||||||
}
|
}
|
||||||
|
rowContainer.end = this.parser.pos;
|
||||||
}
|
}
|
||||||
rowMatch = rowRegExp.exec(this.parser.source);
|
rowMatch = rowRegExp.exec(this.parser.source);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ exports.parse = function() {
|
|||||||
renderType = this.match[2];
|
renderType = this.match[2];
|
||||||
// Move past the match
|
// Move past the match
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
|
var start = this.parser.pos;
|
||||||
// Look for the end of the block
|
// Look for the end of the block
|
||||||
reEnd.lastIndex = this.parser.pos;
|
reEnd.lastIndex = this.parser.pos;
|
||||||
var match = reEnd.exec(this.parser.source),
|
var match = reEnd.exec(this.parser.source),
|
||||||
@@ -74,7 +75,9 @@ exports.parse = function() {
|
|||||||
tag: "pre",
|
tag: "pre",
|
||||||
children: [{
|
children: [{
|
||||||
type: "text",
|
type: "text",
|
||||||
text: text
|
text: text,
|
||||||
|
start: start,
|
||||||
|
end: this.parser.pos
|
||||||
}]
|
}]
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ exports.parse = function() {
|
|||||||
// Get the details of the match
|
// Get the details of the match
|
||||||
var linkText = this.match[0];
|
var linkText = this.match[0];
|
||||||
// Move past the macro call
|
// Move past the macro call
|
||||||
|
var start = this.parser.pos;
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// If the link starts with the unwikilink character then just output it as plain text
|
// If the link starts with the unwikilink character then just output it as plain text
|
||||||
if(linkText.substr(0,1) === $tw.config.textPrimitives.unWikiLink) {
|
if(linkText.substr(0,1) === $tw.config.textPrimitives.unWikiLink) {
|
||||||
@@ -57,7 +58,9 @@ exports.parse = function() {
|
|||||||
},
|
},
|
||||||
children: [{
|
children: [{
|
||||||
type: "text",
|
type: "text",
|
||||||
text: linkText
|
text: linkText,
|
||||||
|
start: start,
|
||||||
|
end: this.parser.pos
|
||||||
}]
|
}]
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -91,6 +91,11 @@ var WikiParser = function(type,text,options) {
|
|||||||
} else {
|
} else {
|
||||||
topBranch.push.apply(topBranch,this.parseBlocks());
|
topBranch.push.apply(topBranch,this.parseBlocks());
|
||||||
}
|
}
|
||||||
|
// Build rules' name map
|
||||||
|
this.usingRuleMap = {};
|
||||||
|
$tw.utils.each(this.pragmaRules, function (ruleInfo) { self.usingRuleMap[ruleInfo.rule.name] = Object.getPrototypeOf(ruleInfo.rule); });
|
||||||
|
$tw.utils.each(this.blockRules, function (ruleInfo) { self.usingRuleMap[ruleInfo.rule.name] = Object.getPrototypeOf(ruleInfo.rule); });
|
||||||
|
$tw.utils.each(this.inlineRules, function (ruleInfo) { self.usingRuleMap[ruleInfo.rule.name] = Object.getPrototypeOf(ruleInfo.rule); });
|
||||||
// Return the parse tree
|
// Return the parse tree
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -209,8 +214,13 @@ WikiParser.prototype.parsePragmas = function() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Process the pragma rule
|
// Process the pragma rule
|
||||||
|
var start = this.pos;
|
||||||
var subTree = nextMatch.rule.parse();
|
var subTree = nextMatch.rule.parse();
|
||||||
if(subTree.length > 0) {
|
if(subTree.length > 0) {
|
||||||
|
// Set the start and end positions of the pragma rule if
|
||||||
|
if (subTree[0].start === undefined) subTree[0].start = start;
|
||||||
|
if (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos;
|
||||||
|
$tw.utils.each(subTree, function (node) { node.rule = nextMatch.rule.name; });
|
||||||
// Quick hack; we only cope with a single parse tree node being returned, which is true at the moment
|
// Quick hack; we only cope with a single parse tree node being returned, which is true at the moment
|
||||||
currentTreeBranch.push.apply(currentTreeBranch,subTree);
|
currentTreeBranch.push.apply(currentTreeBranch,subTree);
|
||||||
subTree[0].children = [];
|
subTree[0].children = [];
|
||||||
@@ -235,7 +245,15 @@ WikiParser.prototype.parseBlock = function(terminatorRegExpString) {
|
|||||||
// Look for a block rule that applies at the current position
|
// Look for a block rule that applies at the current position
|
||||||
var nextMatch = this.findNextMatch(this.blockRules,this.pos);
|
var nextMatch = this.findNextMatch(this.blockRules,this.pos);
|
||||||
if(nextMatch && nextMatch.matchIndex === this.pos) {
|
if(nextMatch && nextMatch.matchIndex === this.pos) {
|
||||||
return nextMatch.rule.parse();
|
var start = this.pos;
|
||||||
|
var subTree = nextMatch.rule.parse();
|
||||||
|
// Set the start and end positions of the first and last blocks if they're not already set
|
||||||
|
if (subTree.length > 0) {
|
||||||
|
if (subTree[0].start === undefined) subTree[0].start = start;
|
||||||
|
if (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos;
|
||||||
|
}
|
||||||
|
$tw.utils.each(subTree, function (node) { node.rule = nextMatch.rule.name; });
|
||||||
|
return subTree;
|
||||||
}
|
}
|
||||||
// Treat it as a paragraph if we didn't find a block rule
|
// Treat it as a paragraph if we didn't find a block rule
|
||||||
var start = this.pos;
|
var start = this.pos;
|
||||||
@@ -332,7 +350,16 @@ WikiParser.prototype.parseInlineRunUnterminated = function(options) {
|
|||||||
this.pos = nextMatch.matchIndex;
|
this.pos = nextMatch.matchIndex;
|
||||||
}
|
}
|
||||||
// Process the run rule
|
// Process the run rule
|
||||||
tree.push.apply(tree,nextMatch.rule.parse());
|
var start = this.pos;
|
||||||
|
var subTree = nextMatch.rule.parse();
|
||||||
|
// Set the start and end positions of the first and last child if they're not already set
|
||||||
|
if (subTree.length > 0) {
|
||||||
|
// Set the start and end positions of the first and last child if they're not already set
|
||||||
|
if (subTree[0].start === undefined) subTree[0].start = start;
|
||||||
|
if (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos;
|
||||||
|
}
|
||||||
|
$tw.utils.each(subTree, function (node) { node.rule = nextMatch.rule.name; });
|
||||||
|
tree.push.apply(tree,subTree);
|
||||||
// Look for the next run rule
|
// Look for the next run rule
|
||||||
nextMatch = this.findNextMatch(this.inlineRules,this.pos);
|
nextMatch = this.findNextMatch(this.inlineRules,this.pos);
|
||||||
}
|
}
|
||||||
@@ -383,7 +410,15 @@ WikiParser.prototype.parseInlineRunTerminatedExtended = function(terminatorRegEx
|
|||||||
this.pos = inlineRuleMatch.matchIndex;
|
this.pos = inlineRuleMatch.matchIndex;
|
||||||
}
|
}
|
||||||
// Process the inline rule
|
// Process the inline rule
|
||||||
tree.push.apply(tree,inlineRuleMatch.rule.parse());
|
var start = this.pos;
|
||||||
|
var subTree = inlineRuleMatch.rule.parse();
|
||||||
|
// Set the start and end positions of the first and last child if they're not already set
|
||||||
|
if (subTree.length > 0) {
|
||||||
|
if (subTree[0].start === undefined) subTree[0].start = start;
|
||||||
|
if (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos;
|
||||||
|
}
|
||||||
|
$tw.utils.each(subTree, function (node) { node.rule = inlineRuleMatch.rule.name; });
|
||||||
|
tree.push.apply(tree,subTree);
|
||||||
// Look for the next inline rule
|
// Look for the next inline rule
|
||||||
inlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);
|
inlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);
|
||||||
// Look for the next terminator match
|
// Look for the next terminator match
|
||||||
@@ -409,7 +444,7 @@ WikiParser.prototype.pushTextWidget = function(array,text,start,end) {
|
|||||||
text = $tw.utils.trim(text);
|
text = $tw.utils.trim(text);
|
||||||
}
|
}
|
||||||
if(text) {
|
if(text) {
|
||||||
array.push({type: "text", text: text, start: start, end: end});
|
array.push({type: "text", text: text, start: start, end: end});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -462,4 +497,3 @@ WikiParser.prototype.amendRules = function(type,names) {
|
|||||||
exports["text/vnd.tiddlywiki"] = WikiParser;
|
exports["text/vnd.tiddlywiki"] = WikiParser;
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ function SaverHandler(options) {
|
|||||||
if($tw.browser) {
|
if($tw.browser) {
|
||||||
$tw.rootWidget.addEventListener("tm-save-wiki",function(event) {
|
$tw.rootWidget.addEventListener("tm-save-wiki",function(event) {
|
||||||
self.saveWiki({
|
self.saveWiki({
|
||||||
|
wiki: event.widget.wiki,
|
||||||
template: event.param,
|
template: event.param,
|
||||||
downloadType: "text/plain",
|
downloadType: "text/plain",
|
||||||
variables: event.paramObject
|
variables: event.paramObject
|
||||||
@@ -102,6 +103,7 @@ function SaverHandler(options) {
|
|||||||
});
|
});
|
||||||
$tw.rootWidget.addEventListener("tm-download-file",function(event) {
|
$tw.rootWidget.addEventListener("tm-download-file",function(event) {
|
||||||
self.saveWiki({
|
self.saveWiki({
|
||||||
|
wiki: event.widget.wiki,
|
||||||
method: "download",
|
method: "download",
|
||||||
template: event.param,
|
template: event.param,
|
||||||
downloadType: "text/plain",
|
downloadType: "text/plain",
|
||||||
@@ -147,20 +149,22 @@ Save the wiki contents. Options are:
|
|||||||
method: "save", "autosave" or "download"
|
method: "save", "autosave" or "download"
|
||||||
template: the tiddler containing the template to save
|
template: the tiddler containing the template to save
|
||||||
downloadType: the content type for the saved file
|
downloadType: the content type for the saved file
|
||||||
|
wiki: optional wiki, overriding the default wiki specified in the constructor
|
||||||
*/
|
*/
|
||||||
SaverHandler.prototype.saveWiki = function(options) {
|
SaverHandler.prototype.saveWiki = function(options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var self = this,
|
var self = this,
|
||||||
|
wiki = options.wiki || this.wiki,
|
||||||
method = options.method || "save";
|
method = options.method || "save";
|
||||||
// Ignore autosave if disabled
|
// Ignore autosave if disabled
|
||||||
if(method === "autosave" && ($tw.config.disableAutoSave || this.wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes")) {
|
if(method === "autosave" && ($tw.config.disableAutoSave || wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var variables = options.variables || {},
|
var variables = options.variables || {},
|
||||||
template = (options.template ||
|
template = (options.template ||
|
||||||
this.wiki.getTiddlerText("$:/config/SaveWikiButton/Template","$:/core/save/all")).trim(),
|
wiki.getTiddlerText("$:/config/SaveWikiButton/Template","$:/core/save/all")).trim(),
|
||||||
downloadType = options.downloadType || "text/plain",
|
downloadType = options.downloadType || "text/plain",
|
||||||
text = this.wiki.renderTiddler(downloadType,template,options),
|
text = wiki.renderTiddler(downloadType,template,options),
|
||||||
callback = function(err) {
|
callback = function(err) {
|
||||||
if(err) {
|
if(err) {
|
||||||
alert($tw.language.getString("Error/WhileSaving") + ":\n\n" + err);
|
alert($tw.language.getString("Error/WhileSaving") + ":\n\n" + err);
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ HeaderAuthenticator.prototype.authenticateRequest = function(request,response,st
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// authenticatedUsername will be undefined for anonymous users
|
// authenticatedUsername will be undefined for anonymous users
|
||||||
state.authenticatedUsername = $tw.utils.decodeURIComponentSafe(username);
|
if(username) {
|
||||||
|
state.authenticatedUsername = $tw.utils.decodeURIComponentSafe(username);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -140,6 +140,11 @@ function sendResponse(request,response,statusCode,headers,data,encoding) {
|
|||||||
return;
|
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,
|
If the gzip=yes is set, check if the user agent permits compression. If so,
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ exports.startup = function() {
|
|||||||
// Collect the shadow tiddlers of any modified plugins
|
// Collect the shadow tiddlers of any modified plugins
|
||||||
$tw.utils.each(changes.modifiedPlugins,function(pluginTitle) {
|
$tw.utils.each(changes.modifiedPlugins,function(pluginTitle) {
|
||||||
var pluginInfo = $tw.wiki.getPluginInfo(pluginTitle);
|
var pluginInfo = $tw.wiki.getPluginInfo(pluginTitle);
|
||||||
if(pluginInfo) {
|
if(pluginInfo && pluginInfo.tiddlers) {
|
||||||
$tw.utils.each(Object.keys(pluginInfo.tiddlers),function(title) {
|
$tw.utils.each(Object.keys(pluginInfo.tiddlers),function(title) {
|
||||||
changedShadowTiddlers[title] = false;
|
changedShadowTiddlers[title] = false;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -29,7 +29,11 @@ var THROTTLE_REFRESH_TIMEOUT = 400;
|
|||||||
|
|
||||||
exports.startup = function() {
|
exports.startup = function() {
|
||||||
// Set up the title
|
// Set up the title
|
||||||
$tw.titleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TITLE_TITLE,{document: $tw.fakeDocument, parseAsInline: true});
|
$tw.titleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TITLE_TITLE, {
|
||||||
|
document: $tw.fakeDocument,
|
||||||
|
parseAsInline: true,
|
||||||
|
importPageMacros: true,
|
||||||
|
});
|
||||||
$tw.titleContainer = $tw.fakeDocument.createElement("div");
|
$tw.titleContainer = $tw.fakeDocument.createElement("div");
|
||||||
$tw.titleWidgetNode.render($tw.titleContainer,null);
|
$tw.titleWidgetNode.render($tw.titleContainer,null);
|
||||||
document.title = $tw.titleContainer.textContent;
|
document.title = $tw.titleContainer.textContent;
|
||||||
@@ -81,6 +85,8 @@ exports.startup = function() {
|
|||||||
deferredChanges = Object.create(null);
|
deferredChanges = Object.create(null);
|
||||||
$tw.hooks.invokeHook("th-page-refreshed");
|
$tw.hooks.invokeHook("th-page-refreshed");
|
||||||
}
|
}
|
||||||
|
var throttledRefresh = $tw.perf.report("throttledRefresh",refresh);
|
||||||
|
|
||||||
// Add the change event handler
|
// Add the change event handler
|
||||||
$tw.wiki.addEventListener("change",$tw.perf.report("mainRefresh",function(changes) {
|
$tw.wiki.addEventListener("change",$tw.perf.report("mainRefresh",function(changes) {
|
||||||
// Check if only tiddlers that are throttled have changed
|
// Check if only tiddlers that are throttled have changed
|
||||||
@@ -101,7 +107,7 @@ exports.startup = function() {
|
|||||||
if(isNaN(timeout)) {
|
if(isNaN(timeout)) {
|
||||||
timeout = THROTTLE_REFRESH_TIMEOUT;
|
timeout = THROTTLE_REFRESH_TIMEOUT;
|
||||||
}
|
}
|
||||||
timerId = setTimeout(refresh,timeout);
|
timerId = setTimeout(throttledRefresh,timeout);
|
||||||
$tw.utils.extend(deferredChanges,changes);
|
$tw.utils.extend(deferredChanges,changes);
|
||||||
} else {
|
} else {
|
||||||
$tw.utils.extend(deferredChanges,changes);
|
$tw.utils.extend(deferredChanges,changes);
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ exports.startup = function() {
|
|||||||
method: params.method,
|
method: params.method,
|
||||||
body: params.body,
|
body: params.body,
|
||||||
binary: params.binary,
|
binary: params.binary,
|
||||||
|
useDefaultHeaders: params.useDefaultHeaders,
|
||||||
oncompletion: params.oncompletion,
|
oncompletion: params.oncompletion,
|
||||||
onprogress: params.onprogress,
|
onprogress: params.onprogress,
|
||||||
bindStatus: params["bind-status"],
|
bindStatus: params["bind-status"],
|
||||||
@@ -72,7 +73,10 @@ exports.startup = function() {
|
|||||||
});
|
});
|
||||||
// Install the copy-to-clipboard mechanism
|
// Install the copy-to-clipboard mechanism
|
||||||
$tw.rootWidget.addEventListener("tm-copy-to-clipboard",function(event) {
|
$tw.rootWidget.addEventListener("tm-copy-to-clipboard",function(event) {
|
||||||
$tw.utils.copyToClipboard(event.param);
|
$tw.utils.copyToClipboard(event.param,{
|
||||||
|
successNotification: event.paramObject && event.paramObject.successNotification,
|
||||||
|
failureNotification: event.paramObject && event.paramObject.failureNotification
|
||||||
|
});
|
||||||
});
|
});
|
||||||
// Install the tm-focus-selector message
|
// Install the tm-focus-selector message
|
||||||
$tw.rootWidget.addEventListener("tm-focus-selector",function(event) {
|
$tw.rootWidget.addEventListener("tm-focus-selector",function(event) {
|
||||||
|
|||||||
@@ -93,7 +93,9 @@ exports.startup = function() {
|
|||||||
updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permalink" : "none",
|
updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permalink" : "none",
|
||||||
updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(),
|
updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(),
|
||||||
targetTiddler: event.param || event.tiddlerTitle,
|
targetTiddler: event.param || event.tiddlerTitle,
|
||||||
copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permalink" : "none"
|
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
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// Listen for the tm-permaview message
|
// Listen for the tm-permaview message
|
||||||
@@ -102,7 +104,9 @@ exports.startup = function() {
|
|||||||
updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permaview" : "none",
|
updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permaview" : "none",
|
||||||
updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(),
|
updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(),
|
||||||
targetTiddler: event.param || event.tiddlerTitle,
|
targetTiddler: event.param || event.tiddlerTitle,
|
||||||
copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permaview" : "none"
|
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
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -177,6 +181,8 @@ options.updateAddressBar: "permalink", "permaview" or "no" (defaults to "permavi
|
|||||||
options.updateHistory: "yes" or "no" (defaults to "no")
|
options.updateHistory: "yes" or "no" (defaults to "no")
|
||||||
options.copyToClipboard: "permalink", "permaview" or "no" (defaults to "no")
|
options.copyToClipboard: "permalink", "permaview" or "no" (defaults to "no")
|
||||||
options.targetTiddler: optional title of target tiddler for permalink
|
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) {
|
function updateLocationHash(options) {
|
||||||
// Get the story and the history stack
|
// Get the story and the history stack
|
||||||
@@ -205,14 +211,18 @@ function updateLocationHash(options) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Copy URL to the clipboard
|
// Copy URL to the clipboard
|
||||||
|
var url = "";
|
||||||
switch(options.copyToClipboard) {
|
switch(options.copyToClipboard) {
|
||||||
case "permalink":
|
case "permalink":
|
||||||
$tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler));
|
url = $tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler);
|
||||||
break;
|
break;
|
||||||
case "permaview":
|
case "permaview":
|
||||||
$tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList)));
|
url = $tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList));
|
||||||
break;
|
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
|
// Only change the location hash if we must, thus avoiding unnecessary onhashchange events
|
||||||
if($tw.utils.getLocationHash() !== $tw.locationHash) {
|
if($tw.utils.getLocationHash() !== $tw.locationHash) {
|
||||||
if(options.updateHistory === "yes") {
|
if(options.updateHistory === "yes") {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ exports.startup = function() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Initialise the document
|
// Initialise the document
|
||||||
srcDocument.write("<html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>");
|
srcDocument.write("<!DOCTYPE html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>");
|
||||||
srcDocument.close();
|
srcDocument.close();
|
||||||
srcDocument.title = windowTitle;
|
srcDocument.title = windowTitle;
|
||||||
srcWindow.addEventListener("beforeunload",function(event) {
|
srcWindow.addEventListener("beforeunload",function(event) {
|
||||||
|
|||||||
@@ -292,7 +292,9 @@ exports.copyToClipboard = function(text,options) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
}
|
}
|
||||||
if(!options.doNotNotify) {
|
if(!options.doNotNotify) {
|
||||||
$tw.notifier.display(succeeded ? "$:/language/Notifications/CopiedToClipboard/Succeeded" : "$:/language/Notifications/CopiedToClipboard/Failed");
|
var successNotification = options.successNotification || "$:/language/Notifications/CopiedToClipboard/Succeeded",
|
||||||
|
failureNotification = options.failureNotification || "$:/language/Notifications/CopiedToClipboard/Failed"
|
||||||
|
$tw.notifier.display(succeeded ? successNotification : failureNotification);
|
||||||
}
|
}
|
||||||
document.body.removeChild(textArea);
|
document.body.removeChild(textArea);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ HttpClient.prototype.cancelAllHttpRequests = function() {
|
|||||||
for(var t=this.requests.length - 1; t--; t>=0) {
|
for(var t=this.requests.length - 1; t--; t>=0) {
|
||||||
var requestInfo = this.requests[t];
|
var requestInfo = this.requests[t];
|
||||||
requestInfo.request.cancel();
|
requestInfo.request.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.requests = [];
|
this.requests = [];
|
||||||
this.updateRequestTracker();
|
this.updateRequestTracker();
|
||||||
@@ -116,6 +116,7 @@ function HttpClientRequest(options) {
|
|||||||
this.method = options.method || "GET";
|
this.method = options.method || "GET";
|
||||||
this.body = options.body || "";
|
this.body = options.body || "";
|
||||||
this.binary = options.binary || "";
|
this.binary = options.binary || "";
|
||||||
|
this.useDefaultHeaders = options.useDefaultHeaders !== "false" ? true : false,
|
||||||
this.variables = options.variables;
|
this.variables = options.variables;
|
||||||
var url = options.url;
|
var url = options.url;
|
||||||
$tw.utils.each(options.queryStrings,function(value,name) {
|
$tw.utils.each(options.queryStrings,function(value,name) {
|
||||||
@@ -165,6 +166,7 @@ HttpClientRequest.prototype.send = function(callback) {
|
|||||||
this.xhr = $tw.utils.httpRequest({
|
this.xhr = $tw.utils.httpRequest({
|
||||||
url: this.url,
|
url: this.url,
|
||||||
type: this.method,
|
type: this.method,
|
||||||
|
useDefaultHeaders: this.useDefaultHeaders,
|
||||||
headers: this.requestHeaders,
|
headers: this.requestHeaders,
|
||||||
data: this.body,
|
data: this.body,
|
||||||
returnProp: this.binary === "" ? "responseText" : "response",
|
returnProp: this.binary === "" ? "responseText" : "response",
|
||||||
@@ -240,7 +242,8 @@ Make an HTTP request. Options are:
|
|||||||
exports.httpRequest = function(options) {
|
exports.httpRequest = function(options) {
|
||||||
var type = options.type || "GET",
|
var type = options.type || "GET",
|
||||||
url = options.url,
|
url = options.url,
|
||||||
headers = options.headers || {accept: "application/json"},
|
useDefaultHeaders = options.useDefaultHeaders !== false ? true : false,
|
||||||
|
headers = options.headers || (useDefaultHeaders ? {accept: "application/json"} : {}),
|
||||||
hasHeader = function(targetHeader) {
|
hasHeader = function(targetHeader) {
|
||||||
targetHeader = targetHeader.toLowerCase();
|
targetHeader = targetHeader.toLowerCase();
|
||||||
var result = false;
|
var result = false;
|
||||||
@@ -266,7 +269,7 @@ exports.httpRequest = function(options) {
|
|||||||
if(hasHeader("Content-Type") && ["application/x-www-form-urlencoded","multipart/form-data","text/plain"].indexOf(getHeader["Content-Type"]) === -1) {
|
if(hasHeader("Content-Type") && ["application/x-www-form-urlencoded","multipart/form-data","text/plain"].indexOf(getHeader["Content-Type"]) === -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
returnProp = options.returnProp || "responseText",
|
returnProp = options.returnProp || "responseText",
|
||||||
request = new XMLHttpRequest(),
|
request = new XMLHttpRequest(),
|
||||||
@@ -292,7 +295,7 @@ exports.httpRequest = function(options) {
|
|||||||
// Set up the state change handler
|
// Set up the state change handler
|
||||||
request.onreadystatechange = function() {
|
request.onreadystatechange = function() {
|
||||||
if(this.readyState === 4) {
|
if(this.readyState === 4) {
|
||||||
if(this.status === 200 || this.status === 201 || this.status === 204) {
|
if(this.status >= 200 && this.status < 300) {
|
||||||
// Success!
|
// Success!
|
||||||
options.callback(null,this[returnProp],this);
|
options.callback(null,this[returnProp],this);
|
||||||
return;
|
return;
|
||||||
@@ -316,10 +319,10 @@ exports.httpRequest = function(options) {
|
|||||||
request.setRequestHeader(headerTitle,header);
|
request.setRequestHeader(headerTitle,header);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if(data && !hasHeader("Content-Type")) {
|
if(data && !hasHeader("Content-Type") && useDefaultHeaders) {
|
||||||
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
|
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
|
||||||
}
|
}
|
||||||
if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers)) {
|
if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers) && useDefaultHeaders) {
|
||||||
request.setRequestHeader("X-Requested-With","TiddlyWiki");
|
request.setRequestHeader("X-Requested-With","TiddlyWiki");
|
||||||
}
|
}
|
||||||
// Send data
|
// Send data
|
||||||
|
|||||||
23
core/modules/utils/errors.js
Normal file
23
core/modules/utils/errors.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/utils/errors.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: utils
|
||||||
|
|
||||||
|
Custom errors for TiddlyWiki.
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
function TranscludeRecursionError() {
|
||||||
|
Error.apply(this,arguments);
|
||||||
|
this.signatures = Object.create(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Maximum permitted depth of the widget tree for recursion detection */
|
||||||
|
TranscludeRecursionError.MAX_WIDGET_TREE_DEPTH = 1000;
|
||||||
|
|
||||||
|
TranscludeRecursionError.prototype = Object.create(Error);
|
||||||
|
|
||||||
|
exports.TranscludeRecursionError = TranscludeRecursionError;
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -42,7 +42,7 @@ var TW_TextNode = function(text) {
|
|||||||
this.textContent = text + "";
|
this.textContent = text + "";
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.setPrototypeOf(TW_TextNode,TW_Node.prototype);
|
Object.setPrototypeOf(TW_TextNode.prototype,TW_Node.prototype);
|
||||||
|
|
||||||
Object.defineProperty(TW_TextNode.prototype, "nodeType", {
|
Object.defineProperty(TW_TextNode.prototype, "nodeType", {
|
||||||
get: function() {
|
get: function() {
|
||||||
@@ -67,7 +67,7 @@ var TW_Element = function(tag,namespace) {
|
|||||||
this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml";
|
this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml";
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.setPrototypeOf(TW_Element,TW_Node.prototype);
|
Object.setPrototypeOf(TW_Element.prototype,TW_Node.prototype);
|
||||||
|
|
||||||
Object.defineProperty(TW_Element.prototype, "style", {
|
Object.defineProperty(TW_Element.prototype, "style", {
|
||||||
get: function() {
|
get: function() {
|
||||||
|
|||||||
@@ -316,11 +316,13 @@ Options include:
|
|||||||
pathFilters: optional array of filters to be used to generate the base path
|
pathFilters: optional array of filters to be used to generate the base path
|
||||||
wiki: optional wiki for evaluating the pathFilters
|
wiki: optional wiki for evaluating the pathFilters
|
||||||
fileInfo: an existing fileInfo object to check against
|
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) {
|
exports.generateTiddlerFilepath = function(title,options) {
|
||||||
var directory = options.directory || "",
|
var directory = options.directory || "",
|
||||||
extension = options.extension || "",
|
extension = options.extension || "",
|
||||||
originalpath = (options.fileInfo && options.fileInfo.originalpath) ? options.fileInfo.originalpath : "",
|
originalpath = (options.fileInfo && options.fileInfo.originalpath) ? options.fileInfo.originalpath : "",
|
||||||
|
overwrite = options.fileInfo && options.fileInfo.overwrite || false,
|
||||||
filepath;
|
filepath;
|
||||||
// Check if any of the pathFilters applies
|
// Check if any of the pathFilters applies
|
||||||
if(options.pathFilters && options.wiki) {
|
if(options.pathFilters && options.wiki) {
|
||||||
@@ -381,19 +383,20 @@ exports.generateTiddlerFilepath = function(title,options) {
|
|||||||
filepath += char.charCodeAt(0).toString();
|
filepath += char.charCodeAt(0).toString();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Add a uniquifier if the file already exists
|
// Add a uniquifier if the file already exists (default)
|
||||||
var fullPath, oldPath = (options.fileInfo) ? options.fileInfo.filepath : undefined,
|
var fullPath = path.resolve(directory, filepath + extension);
|
||||||
|
if (!overwrite) {
|
||||||
|
var oldPath = (options.fileInfo) ? options.fileInfo.filepath : undefined,
|
||||||
count = 0;
|
count = 0;
|
||||||
do {
|
do {
|
||||||
fullPath = path.resolve(directory,filepath + (count ? "_" + count : "") + extension);
|
fullPath = path.resolve(directory,filepath + (count ? "_" + count : "") + extension);
|
||||||
if(oldPath && oldPath == fullPath) {
|
if(oldPath && oldPath == fullPath) break;
|
||||||
break;
|
count++;
|
||||||
}
|
} while(fs.existsSync(fullPath));
|
||||||
count++;
|
}
|
||||||
} while(fs.existsSync(fullPath));
|
|
||||||
// If the last write failed with an error, or if path does not start with:
|
// 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,
|
// the resolved options.directory, the resolved wikiPath directory, the wikiTiddlersPath directory,
|
||||||
// or the 'originalpath' directory, then $tw.utils.encodeURIComponentExtended() and resolve to tiddler directory.
|
// or the 'originalpath' directory, then $tw.utils.encodeURIComponentExtended() and resolve to options.directory.
|
||||||
var writePath = $tw.hooks.invokeHook("th-make-tiddler-path",fullPath,fullPath),
|
var writePath = $tw.hooks.invokeHook("th-make-tiddler-path",fullPath,fullPath),
|
||||||
encode = (options.fileInfo || {writeError: false}).writeError == true;
|
encode = (options.fileInfo || {writeError: false}).writeError == true;
|
||||||
if(!encode) {
|
if(!encode) {
|
||||||
|
|||||||
52
core/modules/utils/repository.js
Normal file
52
core/modules/utils/repository.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/utils/repository.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: utils
|
||||||
|
|
||||||
|
Utilities for working with the TiddlyWiki repository file structure
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get an object containing all the plugins as a hashmap by title of the JSON representation of the plugin
|
||||||
|
Options:
|
||||||
|
|
||||||
|
ignoreEnvironmentVariables: defaults to false
|
||||||
|
*/
|
||||||
|
exports.getAllPlugins = function(options) {
|
||||||
|
options = options || {};
|
||||||
|
var fs = require("fs"),
|
||||||
|
path = require("path"),
|
||||||
|
tiddlers = {};
|
||||||
|
// Collect up the library plugins
|
||||||
|
var collectPlugins = function(folder) {
|
||||||
|
var pluginFolders = $tw.utils.getSubdirectories(folder) || [];
|
||||||
|
for(var p=0; p<pluginFolders.length; p++) {
|
||||||
|
if(!$tw.boot.excludeRegExp.test(pluginFolders[p])) {
|
||||||
|
var pluginFields = $tw.loadPluginFolder(path.resolve(folder,"./" + pluginFolders[p]));
|
||||||
|
if(pluginFields && pluginFields.title) {
|
||||||
|
tiddlers[pluginFields.title] = pluginFields;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
collectPublisherPlugins = function(folder) {
|
||||||
|
var publisherFolders = $tw.utils.getSubdirectories(folder) || [];
|
||||||
|
for(var t=0; t<publisherFolders.length; t++) {
|
||||||
|
if(!$tw.boot.excludeRegExp.test(publisherFolders[t])) {
|
||||||
|
collectPlugins(path.resolve(folder,"./" + publisherFolders[t]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.pluginsPath,options.ignoreEnvironmentVariables ? undefined : $tw.config.pluginsEnvVar),collectPublisherPlugins);
|
||||||
|
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.themesPath,options.ignoreEnvironmentVariables ? undefined : $tw.config.themesEnvVar),collectPublisherPlugins);
|
||||||
|
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.languagesPath,options.ignoreEnvironmentVariables ? undefined : $tw.config.languagesEnvVar),collectPlugins);
|
||||||
|
return tiddlers;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -825,7 +825,7 @@ options.length .. number of characters returned defaults to 64
|
|||||||
*/
|
*/
|
||||||
exports.sha256 = function(str, options) {
|
exports.sha256 = function(str, options) {
|
||||||
options = options || {}
|
options = options || {}
|
||||||
return sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(str)).substr(0,options.length || 64);
|
return $tw.sjcl.codec.hex.fromBits($tw.sjcl.hash.sha256.hash(str)).substr(0,options.length || 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ Compute the internal state of the widget
|
|||||||
DeleteFieldWidget.prototype.execute = function() {
|
DeleteFieldWidget.prototype.execute = function() {
|
||||||
this.actionTiddler = this.getAttribute("$tiddler",this.getVariable("currentTiddler"));
|
this.actionTiddler = this.getAttribute("$tiddler",this.getVariable("currentTiddler"));
|
||||||
this.actionField = this.getAttribute("$field",null);
|
this.actionField = this.getAttribute("$field",null);
|
||||||
|
this.actionTimestamp = this.getAttribute("$timestamp","yes") === "yes";
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -69,11 +70,15 @@ DeleteFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
|||||||
$tw.utils.each(this.attributes,function(attribute,name) {
|
$tw.utils.each(this.attributes,function(attribute,name) {
|
||||||
if(name.charAt(0) !== "$" && name !== "title") {
|
if(name.charAt(0) !== "$" && name !== "title") {
|
||||||
removeFields[name] = undefined;
|
removeFields[name] = undefined;
|
||||||
hasChanged = true;
|
if(name in tiddler.fields) {
|
||||||
|
hasChanged = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if(hasChanged) {
|
if(hasChanged) {
|
||||||
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,removeFields,this.wiki.getModificationFields()));
|
var creationFields = this.actionTimestamp ? this.wiki.getCreationFields() : {};
|
||||||
|
var modificationFields = this.actionTimestamp ? this.wiki.getModificationFields() : {};
|
||||||
|
this.wiki.addTiddler(new $tw.Tiddler(creationFields,tiddler,removeFields,modificationFields));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true; // Action was invoked
|
return true; // Action was invoked
|
||||||
|
|||||||
@@ -66,7 +66,12 @@ LogWidget.prototype.log = function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for(var v in this.variables) {
|
for(var v in this.variables) {
|
||||||
allVars[v] = this.getVariable(v,{defaultValue:""});
|
var variable = this.parentWidget && this.parentWidget.variables[v];
|
||||||
|
if(variable && variable.isFunctionDefinition) {
|
||||||
|
allVars[v] = variable.value;
|
||||||
|
} else {
|
||||||
|
allVars[v] = this.getVariable(v,{defaultValue:""});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(this.filter) {
|
if(this.filter) {
|
||||||
filteredVars = this.wiki.compileFilter(this.filter).call(this.wiki,this.wiki.makeTiddlerIterator(allVars));
|
filteredVars = this.wiki.compileFilter(this.filter).call(this.wiki,this.wiki.makeTiddlerIterator(allVars));
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
|
|||||||
*/
|
*/
|
||||||
ButtonWidget.prototype.refresh = function(changedTiddlers) {
|
ButtonWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
var changedAttributes = this.computeAttributes();
|
var changedAttributes = this.computeAttributes();
|
||||||
if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.popupAbsCoords || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) {
|
if(changedAttributes.tooltip || changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.popupAbsCoords || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) {
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
184
core/modules/widgets/data.js
Normal file
184
core/modules/widgets/data.js
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
/*\
|
||||||
|
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);
|
||||||
|
if(tiddler) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -74,6 +74,18 @@ ParametersWidget.prototype.execute = function() {
|
|||||||
self.setVariable(variableName,getValue(name));
|
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
|
// Construct the child widgets
|
||||||
this.makeChildWidgets();
|
this.makeChildWidgets();
|
||||||
|
|||||||
165
core/modules/widgets/testcase.js
Normal file
165
core/modules/widgets/testcase.js
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/widgets/testcase.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: widget
|
||||||
|
|
||||||
|
Widget to display a test case
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||||
|
|
||||||
|
var TestCaseWidget = function(parseTreeNode,options) {
|
||||||
|
this.initialise(parseTreeNode,options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inherit from the base widget class
|
||||||
|
*/
|
||||||
|
TestCaseWidget.prototype = new Widget();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Render this widget into the DOM
|
||||||
|
*/
|
||||||
|
TestCaseWidget.prototype.render = function(parent,nextSibling) {
|
||||||
|
var self = this;
|
||||||
|
this.parentDomNode = parent;
|
||||||
|
this.computeAttributes();
|
||||||
|
this.execute();
|
||||||
|
// Create container DOM node
|
||||||
|
var domNode = this.document.createElement("div");
|
||||||
|
this.domNodes.push(domNode);
|
||||||
|
parent.insertBefore(domNode,nextSibling);
|
||||||
|
// Render the children into a hidden DOM node
|
||||||
|
var parser = {
|
||||||
|
tree: [{
|
||||||
|
type: "widget",
|
||||||
|
attributes: {},
|
||||||
|
orderedAttributes: [],
|
||||||
|
children: this.parseTreeNode.children || []
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
this.contentRoot = this.wiki.makeWidget(parser,{
|
||||||
|
document: $tw.fakeDocument,
|
||||||
|
parentWidget: this
|
||||||
|
});
|
||||||
|
this.contentContainer = $tw.fakeDocument.createElement("div");
|
||||||
|
this.contentRoot.render(this.contentContainer,null);
|
||||||
|
// Create a wiki
|
||||||
|
this.testcaseWiki = new $tw.Wiki();
|
||||||
|
// Always load the core plugin
|
||||||
|
var loadTiddler = function(title) {
|
||||||
|
var tiddler = self.wiki.getTiddler(title);
|
||||||
|
if(tiddler) {
|
||||||
|
self.testcaseWiki.addTiddler(tiddler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadTiddler("$:/core");
|
||||||
|
loadTiddler("$:/plugins/tiddlywiki/codemirror");
|
||||||
|
// Load tiddlers from child data widgets
|
||||||
|
var tiddlers = [];
|
||||||
|
this.findChildrenDataWidgets(this.contentRoot.children,"data",function(widget) {
|
||||||
|
Array.prototype.push.apply(tiddlers,widget.readDataTiddlerValues());
|
||||||
|
});
|
||||||
|
var jsonPayload = JSON.stringify(tiddlers);
|
||||||
|
this.testcaseWiki.addTiddlers(tiddlers);
|
||||||
|
// Unpack plugin tiddlers
|
||||||
|
this.testcaseWiki.readPluginInfo();
|
||||||
|
this.testcaseWiki.registerPluginTiddlers("plugin");
|
||||||
|
this.testcaseWiki.unpackPluginTiddlers();
|
||||||
|
this.testcaseWiki.addIndexersToWiki();
|
||||||
|
// Generate a `transclusion` variable that depends on the values of the payload tiddlers so that the template can easily make unique state tiddlers
|
||||||
|
this.setVariable("transclusion",$tw.utils.hashString(jsonPayload));
|
||||||
|
// Generate a `payloadTiddlers` variable that contains the payload in JSON format
|
||||||
|
this.setVariable("payloadTiddlers",jsonPayload);
|
||||||
|
// Only run the tests if the testcase output and expected results were specified, and those tiddlers actually exist in the wiki
|
||||||
|
var shouldRunTests = false;
|
||||||
|
if(this.testcaseTestOutput && this.testcaseWiki.tiddlerExists(this.testcaseTestOutput) && this.testcaseTestExpectedResult && this.testcaseWiki.tiddlerExists(this.testcaseTestExpectedResult)) {
|
||||||
|
shouldRunTests = true;
|
||||||
|
}
|
||||||
|
// Render the test rendering if required
|
||||||
|
if(shouldRunTests) {
|
||||||
|
var testcaseOutputContainer = $tw.fakeDocument.createElement("div");
|
||||||
|
var testcaseOutputWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTestOutput,{
|
||||||
|
document: $tw.fakeDocument,
|
||||||
|
parseAsInline: false,
|
||||||
|
parentWidget: this,
|
||||||
|
variables: {
|
||||||
|
currentTiddler: this.testcaseTestOutput
|
||||||
|
}
|
||||||
|
});
|
||||||
|
testcaseOutputWidget.render(testcaseOutputContainer);
|
||||||
|
}
|
||||||
|
// Clear changes queue
|
||||||
|
this.testcaseWiki.clearTiddlerEventQueue();
|
||||||
|
// Run the actions if provided
|
||||||
|
if(this.testcaseWiki.tiddlerExists(this.testcaseTestActions)) {
|
||||||
|
testcaseOutputWidget.invokeActionString(this.testcaseWiki.getTiddlerText(this.testcaseTestActions));
|
||||||
|
testcaseOutputWidget.refresh(this.testcaseWiki.changedTiddlers,testcaseOutputContainer);
|
||||||
|
}
|
||||||
|
// Set up the test result variables
|
||||||
|
var testResult = "",
|
||||||
|
outputHTML = "",
|
||||||
|
expectedHTML = "";
|
||||||
|
if(shouldRunTests) {
|
||||||
|
outputHTML = testcaseOutputContainer.children[0].innerHTML;
|
||||||
|
expectedHTML = this.testcaseWiki.getTiddlerText(this.testcaseTestExpectedResult);
|
||||||
|
if(outputHTML === expectedHTML) {
|
||||||
|
testResult = "pass";
|
||||||
|
} else {
|
||||||
|
testResult = "fail";
|
||||||
|
}
|
||||||
|
this.setVariable("outputHTML",outputHTML);
|
||||||
|
this.setVariable("expectedHTML",expectedHTML);
|
||||||
|
this.setVariable("testResult",testResult);
|
||||||
|
this.setVariable("currentTiddler",this.testcaseTestOutput);
|
||||||
|
}
|
||||||
|
// Don't display anything if testHideIfPass is "yes" and the tests have passed
|
||||||
|
if(this.testcaseHideIfPass === "yes" && testResult !== "fail") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Render the page root template of the subwiki
|
||||||
|
var rootWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTemplate,{
|
||||||
|
document: this.document,
|
||||||
|
parseAsInline: false,
|
||||||
|
parentWidget: this
|
||||||
|
});
|
||||||
|
rootWidget.render(domNode);
|
||||||
|
// Trap changes in the wiki and refresh the rendering
|
||||||
|
this.testcaseWiki.addEventListener("change",function(changes) {
|
||||||
|
rootWidget.refresh(changes,domNode);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compute the internal state of the widget
|
||||||
|
*/
|
||||||
|
TestCaseWidget.prototype.execute = function() {
|
||||||
|
this.testcaseTemplate = this.getAttribute("template","$:/core/ui/testcases/DefaultTemplate");
|
||||||
|
this.testcaseTestOutput = this.getAttribute("testOutput");
|
||||||
|
this.testcaseTestActions = this.getAttribute("testActions");
|
||||||
|
this.testcaseTestExpectedResult = this.getAttribute("testExpectedResult");
|
||||||
|
this.testcaseHideIfPass = this.getAttribute("testHideIfPass");
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||||
|
*/
|
||||||
|
TestCaseWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
|
var changedAttributes = this.computeAttributes();
|
||||||
|
if($tw.utils.count(changedAttributes) > 0) {
|
||||||
|
this.refreshSelf();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return this.contentRoot.refresh(changedTiddlers);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports["testcase"] = TestCaseWidget;
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -30,7 +30,30 @@ TranscludeWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
this.parentDomNode = parent;
|
this.parentDomNode = parent;
|
||||||
this.computeAttributes();
|
this.computeAttributes();
|
||||||
this.execute();
|
this.execute();
|
||||||
this.renderChildren(parent,nextSibling);
|
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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ Widget base class
|
|||||||
/*global $tw: false */
|
/*global $tw: false */
|
||||||
"use strict";
|
"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
|
Create a widget object for a parse tree node
|
||||||
parseTreeNode: reference to the parse tree node to be rendered
|
parseTreeNode: reference to the parse tree node to be rendered
|
||||||
@@ -166,6 +163,8 @@ Widget.prototype.getVariableInfo = function(name,options) {
|
|||||||
});
|
});
|
||||||
resultList = this.wiki.filterTiddlers(value,this.makeFakeWidgetWithVariables(variables),options.source);
|
resultList = this.wiki.filterTiddlers(value,this.makeFakeWidgetWithVariables(variables),options.source);
|
||||||
value = resultList[0] || "";
|
value = resultList[0] || "";
|
||||||
|
} else {
|
||||||
|
params = variable.params;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
text: value,
|
text: value,
|
||||||
@@ -317,7 +316,8 @@ Widget.prototype.getStateQualifier = function(name) {
|
|||||||
Make a fake widget with specified variables, suitable for variable lookup in filters
|
Make a fake widget with specified variables, suitable for variable lookup in filters
|
||||||
*/
|
*/
|
||||||
Widget.prototype.makeFakeWidgetWithVariables = function(variables) {
|
Widget.prototype.makeFakeWidgetWithVariables = function(variables) {
|
||||||
var self = this;
|
var self = this,
|
||||||
|
variables = variables || {};
|
||||||
return {
|
return {
|
||||||
getVariable: function(name,opts) {
|
getVariable: function(name,opts) {
|
||||||
if($tw.utils.hop(variables,name)) {
|
if($tw.utils.hop(variables,name)) {
|
||||||
@@ -335,7 +335,7 @@ Widget.prototype.makeFakeWidgetWithVariables = function(variables) {
|
|||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
opts.variables = variables;
|
opts.variables = $tw.utils.extend(variables,opts.variables);
|
||||||
return self.getVariableInfo(name,opts);
|
return self.getVariableInfo(name,opts);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -494,10 +494,8 @@ Widget.prototype.makeChildWidgets = function(parseTreeNodes,options) {
|
|||||||
this.children = [];
|
this.children = [];
|
||||||
var self = this;
|
var self = this;
|
||||||
// Check for too much recursion
|
// Check for too much recursion
|
||||||
if(this.getAncestorCount() > MAX_WIDGET_TREE_DEPTH) {
|
if(this.getAncestorCount() > $tw.utils.TranscludeRecursionError.MAX_WIDGET_TREE_DEPTH) {
|
||||||
this.children.push(this.makeChildWidget({type: "error", attributes: {
|
throw new $tw.utils.TranscludeRecursionError();
|
||||||
"$message": {type: "string", value: $tw.language.getString("Error/RecursiveTransclusion")}
|
|
||||||
}}));
|
|
||||||
} else {
|
} else {
|
||||||
// Create set variable widgets for each variable
|
// Create set variable widgets for each variable
|
||||||
$tw.utils.each(options.variables,function(value,name) {
|
$tw.utils.each(options.variables,function(value,name) {
|
||||||
@@ -813,6 +811,21 @@ Widget.prototype.allowActionPropagation = function() {
|
|||||||
return true;
|
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
|
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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -551,28 +551,41 @@ exports.getTiddlerBacklinks = function(targetTitle) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Return an array of tiddler titles that are directly transcluded within the given parse tree
|
Return an array of tiddler titles that are directly transcluded within the given parse tree. `title` is the tiddler being parsed, we will ignore its self-referential transclusions, only return
|
||||||
*/
|
*/
|
||||||
exports.extractTranscludes = function(parseTreeRoot) {
|
exports.extractTranscludes = function(parseTreeRoot, title) {
|
||||||
// Count up the transcludes
|
// Count up the transcludes
|
||||||
var transcludes = [],
|
var transcludes = [],
|
||||||
checkParseTree = function(parseTree, parentNode) {
|
checkParseTree = function(parseTree, parentNode) {
|
||||||
for(var t=0; t<parseTree.length; t++) {
|
for(var t=0; t<parseTree.length; t++) {
|
||||||
var parseTreeNode = parseTree[t];
|
var parseTreeNode = parseTree[t];
|
||||||
if(parseTreeNode.type === "transclude" && parseTreeNode.attributes.$tiddler && parseTreeNode.attributes.$tiddler.type === "string") {
|
if(parseTreeNode.type === "transclude") {
|
||||||
var value;
|
if(parseTreeNode.attributes.$tiddler && parseTreeNode.attributes.$tiddler.type === "string") {
|
||||||
// if it is Transclusion with Templates like `{{Index||$:/core/ui/TagTemplate}}`, the `$tiddler` will point to the template. We need to find the actual target tiddler from parent node
|
var value;
|
||||||
if(parentNode && parentNode.type === "tiddler" && parentNode.attributes.tiddler && parentNode.attributes.tiddler.type === "string") {
|
// if it is Transclusion with Templates like `{{Index||$:/core/ui/TagTemplate}}`, the `$tiddler` will point to the template. We need to find the actual target tiddler from parent node
|
||||||
value = parentNode.attributes.tiddler.value;
|
if(parentNode && parentNode.type === "tiddler" && parentNode.attributes.tiddler && parentNode.attributes.tiddler.type === "string") {
|
||||||
} else {
|
// Empty value (like `{{!!field}}`) means self-referential transclusion.
|
||||||
value = parseTreeNode.attributes.$tiddler.value;
|
value = parentNode.attributes.tiddler.value || title;
|
||||||
|
} else {
|
||||||
|
value = parseTreeNode.attributes.$tiddler.value;
|
||||||
|
}
|
||||||
|
} else if(parseTreeNode.attributes.tiddler && parseTreeNode.attributes.tiddler.type === "string") {
|
||||||
|
// Old transclude widget usage
|
||||||
|
value = parseTreeNode.attributes.tiddler.value;
|
||||||
|
} else if(parseTreeNode.attributes.$field && parseTreeNode.attributes.$field.type === "string") {
|
||||||
|
// Empty value (like `<$transclude $field='created'/>`) means self-referential transclusion.
|
||||||
|
value = title;
|
||||||
|
} else if(parseTreeNode.attributes.field && parseTreeNode.attributes.field.type === "string") {
|
||||||
|
// Old usage with Empty value (like `<$transclude field='created'/>`)
|
||||||
|
value = title;
|
||||||
}
|
}
|
||||||
if(transcludes.indexOf(value) === -1) {
|
// Deduplicate the result.
|
||||||
transcludes.push(value);
|
if(value && transcludes.indexOf(value) === -1) {
|
||||||
|
$tw.utils.pushTop(transcludes,value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(parseTreeNode.children) {
|
if(parseTreeNode.children) {
|
||||||
checkParseTree(parseTreeNode.children, parseTreeNode);
|
checkParseTree(parseTreeNode.children,parseTreeNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -591,7 +604,8 @@ exports.getTiddlerTranscludes = function(title) {
|
|||||||
// Parse the tiddler
|
// Parse the tiddler
|
||||||
var parser = self.parseTiddler(title);
|
var parser = self.parseTiddler(title);
|
||||||
if(parser) {
|
if(parser) {
|
||||||
return self.extractTranscludes(parser.tree);
|
// this will ignore self-referential transclusions from `title`
|
||||||
|
return self.extractTranscludes(parser.tree,title);
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -82,6 +82,10 @@ sidebar-tab-foreground: <<colour tab-foreground>>
|
|||||||
sidebar-tiddler-link-foreground-hover: #458588
|
sidebar-tiddler-link-foreground-hover: #458588
|
||||||
sidebar-tiddler-link-foreground: #98971a
|
sidebar-tiddler-link-foreground: #98971a
|
||||||
site-title-foreground: <<colour tiddler-title-foreground>>
|
site-title-foreground: <<colour tiddler-title-foreground>>
|
||||||
|
stability-deprecated: #cc241d
|
||||||
|
stability-experimental: #d79921
|
||||||
|
stability-legacy: #458588
|
||||||
|
stability-stable: #98971a
|
||||||
static-alert-foreground: #B48EAD
|
static-alert-foreground: #B48EAD
|
||||||
tab-background-selected: #ebdbb2
|
tab-background-selected: #ebdbb2
|
||||||
tab-background: #665c54
|
tab-background: #665c54
|
||||||
|
|||||||
@@ -82,6 +82,10 @@ sidebar-tab-foreground: <<colour tab-foreground>>
|
|||||||
sidebar-tiddler-link-foreground-hover: #A3BE8C
|
sidebar-tiddler-link-foreground-hover: #A3BE8C
|
||||||
sidebar-tiddler-link-foreground: #81A1C1
|
sidebar-tiddler-link-foreground: #81A1C1
|
||||||
site-title-foreground: <<colour tiddler-title-foreground>>
|
site-title-foreground: <<colour tiddler-title-foreground>>
|
||||||
|
stability-deprecated: #bf616a
|
||||||
|
stability-experimental: #d08770
|
||||||
|
stability-legacy: #88c0d0
|
||||||
|
stability-stable: #a3be8c
|
||||||
static-alert-foreground: #B48EAD
|
static-alert-foreground: #B48EAD
|
||||||
tab-background-selected: #ECEFF4
|
tab-background-selected: #ECEFF4
|
||||||
tab-background: #4C566A
|
tab-background: #4C566A
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ button-foreground: #93a1a1
|
|||||||
code-background: #073642
|
code-background: #073642
|
||||||
code-border: #586e75
|
code-border: #586e75
|
||||||
code-foreground: #93a1a1
|
code-foreground: #93a1a1
|
||||||
dirty-indicator: inherit
|
dirty-indicator: #dc322f
|
||||||
download-background: #859900
|
download-background: #859900
|
||||||
download-foreground: #073642
|
download-foreground: #073642
|
||||||
dragger-background: #073642
|
dragger-background: #073642
|
||||||
@@ -72,6 +72,10 @@ sidebar-tab-foreground-selected: #93a1a1
|
|||||||
sidebar-tiddler-link-foreground: #2aa198
|
sidebar-tiddler-link-foreground: #2aa198
|
||||||
sidebar-tiddler-link-foreground-hover: #eee8d5
|
sidebar-tiddler-link-foreground-hover: #eee8d5
|
||||||
site-title-foreground: #d33682
|
site-title-foreground: #d33682
|
||||||
|
stability-deprecated: #dc322f
|
||||||
|
stability-experimental: #b58900
|
||||||
|
stability-legacy: #268bd2
|
||||||
|
stability-stable: #859900
|
||||||
static-alert-foreground: #93a1a1
|
static-alert-foreground: #93a1a1
|
||||||
tab-background: #073642
|
tab-background: #073642
|
||||||
tab-background-selected: #002b36
|
tab-background-selected: #002b36
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ button-foreground: #586e75
|
|||||||
code-background: #eee8d5
|
code-background: #eee8d5
|
||||||
code-border: #93a1a1
|
code-border: #93a1a1
|
||||||
code-foreground: #586e75
|
code-foreground: #586e75
|
||||||
dirty-indicator: inherit
|
dirty-indicator: #dc322f
|
||||||
download-background: #859900
|
download-background: #859900
|
||||||
download-foreground: #eee8d5
|
download-foreground: #eee8d5
|
||||||
dragger-background: #eee8d5
|
dragger-background: #eee8d5
|
||||||
@@ -72,6 +72,10 @@ sidebar-tab-foreground-selected: #586e75
|
|||||||
sidebar-tiddler-link-foreground: #2aa198
|
sidebar-tiddler-link-foreground: #2aa198
|
||||||
sidebar-tiddler-link-foreground-hover: #002b36
|
sidebar-tiddler-link-foreground-hover: #002b36
|
||||||
site-title-foreground: #d33682
|
site-title-foreground: #d33682
|
||||||
|
stability-deprecated: #dc322f
|
||||||
|
stability-experimental: #b58900
|
||||||
|
stability-legacy: #268bd2
|
||||||
|
stability-stable: #859900
|
||||||
static-alert-foreground: #586e75
|
static-alert-foreground: #586e75
|
||||||
tab-background: #eee8d5
|
tab-background: #eee8d5
|
||||||
tab-background-selected: #fdf6e3
|
tab-background-selected: #fdf6e3
|
||||||
|
|||||||
@@ -82,6 +82,10 @@ sidebar-tab-foreground: <<colour tab-foreground>>
|
|||||||
sidebar-tiddler-link-foreground-hover: #444444
|
sidebar-tiddler-link-foreground-hover: #444444
|
||||||
sidebar-tiddler-link-foreground: #999999
|
sidebar-tiddler-link-foreground: #999999
|
||||||
site-title-foreground: <<colour tiddler-title-foreground>>
|
site-title-foreground: <<colour tiddler-title-foreground>>
|
||||||
|
stability-stable: #008000
|
||||||
|
stability-experimental: #c07c00
|
||||||
|
stability-deprecated: #ff0000
|
||||||
|
stability-legacy: #0000ff
|
||||||
static-alert-foreground: #aaaaaa
|
static-alert-foreground: #aaaaaa
|
||||||
tab-background-selected: #ffffff
|
tab-background-selected: #ffffff
|
||||||
tab-background: #d8d8d8
|
tab-background: #d8d8d8
|
||||||
@@ -95,6 +99,9 @@ table-footer-background: #a8a8a8
|
|||||||
table-header-background: #f0f0f0
|
table-header-background: #f0f0f0
|
||||||
tag-background: #ec6
|
tag-background: #ec6
|
||||||
tag-foreground: #ffffff
|
tag-foreground: #ffffff
|
||||||
|
testcase-accent-level-1: #c1eaff
|
||||||
|
testcase-accent-level-2: #E3B740
|
||||||
|
testcase-accent-level-3: #5FD564
|
||||||
tiddler-background: <<colour background>>
|
tiddler-background: <<colour background>>
|
||||||
tiddler-border: <<colour background>>
|
tiddler-border: <<colour background>>
|
||||||
tiddler-controls-foreground-hover: #888888
|
tiddler-controls-foreground-hover: #888888
|
||||||
|
|||||||
@@ -5,5 +5,6 @@
|
|||||||
"author": "JeremyRuston",
|
"author": "JeremyRuston",
|
||||||
"core-version": ">=5.0.0",
|
"core-version": ">=5.0.0",
|
||||||
"plugin-priority": "0",
|
"plugin-priority": "0",
|
||||||
"list": "readme"
|
"list": "readme",
|
||||||
|
"stability": "STABILITY_2_STABLE"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: $:/core/save/all-external-js
|
|||||||
\whitespace trim
|
\whitespace trim
|
||||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||||
\define saveTiddlerFilter()
|
\define saveTiddlerFilter()
|
||||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
[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)$
|
||||||
\end
|
\end
|
||||||
|
|
||||||
<!-- Important: core library is provided by serving URI encoded $:/core/templates/tiddlywiki5.js -->
|
<!-- Important: core library is provided by serving URI encoded $:/core/templates/tiddlywiki5.js -->
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: $:/core/save/offline-external-js
|
|||||||
\whitespace trim
|
\whitespace trim
|
||||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||||
\define saveTiddlerFilter()
|
\define saveTiddlerFilter()
|
||||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
[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)$
|
||||||
\end
|
\end
|
||||||
\define defaultCoreURL() tiddlywikicore-$(version)$.js
|
\define defaultCoreURL() tiddlywikicore-$(version)$.js
|
||||||
<$let coreURL={{{ [[coreURL]is[variable]then<coreURL>else<defaultCoreURL>] }}}>
|
<$let coreURL={{{ [[coreURL]is[variable]then<coreURL>else<defaultCoreURL>] }}}>
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ title: $:/core/save/all
|
|||||||
|
|
||||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||||
\define saveTiddlerFilter()
|
\define saveTiddlerFilter()
|
||||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
[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)$
|
||||||
\end
|
\end
|
||||||
{{$:/core/templates/tiddlywiki5.html}}
|
{{$:/core/templates/tiddlywiki5.html}}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
title: $:/core/save/empty
|
title: $:/core/save/empty
|
||||||
|
|
||||||
\define saveTiddlerFilter()
|
\define saveTiddlerFilter()
|
||||||
[is[system]] -[prefix[$:/state/popup/]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]
|
[is[system]] -[prefix[$:/state/popup/]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]
|
||||||
\end
|
\end
|
||||||
{{$:/core/templates/tiddlywiki5.html}}
|
{{$:/core/templates/tiddlywiki5.html}}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
title: $:/core/save/lazy-all
|
title: $:/core/save/lazy-all
|
||||||
|
|
||||||
\define saveTiddlerFilter()
|
\define saveTiddlerFilter()
|
||||||
[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]]
|
[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]]
|
||||||
\end
|
\end
|
||||||
\define skinnySaveTiddlerFilter()
|
\define skinnySaveTiddlerFilter()
|
||||||
[!is[system]] -[type[application/javascript]]
|
[!is[system]] -[type[application/javascript]]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
title: $:/core/save/lazy-images
|
title: $:/core/save/lazy-images
|
||||||
|
|
||||||
\define saveTiddlerFilter()
|
\define saveTiddlerFilter()
|
||||||
[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]]
|
[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]]
|
||||||
\end
|
\end
|
||||||
\define skinnySaveTiddlerFilter()
|
\define skinnySaveTiddlerFilter()
|
||||||
[!is[system]is[image]]
|
[!is[system]is[image]]
|
||||||
|
|||||||
@@ -45,7 +45,17 @@ $:/config/Plugins/Disabled/$(currentTiddler)$
|
|||||||
<$view field="title"/>
|
<$view field="title"/>
|
||||||
</h2>
|
</h2>
|
||||||
<h2>
|
<h2>
|
||||||
<div><em><$view field="version"/></em></div>
|
<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>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
\end
|
\end
|
||||||
|
|||||||
@@ -70,9 +70,20 @@ $:/state/add-plugin-info/$(connectionTiddler)$/$(assetInfo)$
|
|||||||
<div class="tc-plugin-info-chunk tc-plugin-info-description">
|
<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>:
|
<h1><strong><$text text={{{ [<assetInfo>get[name]] ~[<assetInfo>get[original-title]split[/]last[1]] }}}/></strong>:
|
||||||
 
|
 
|
||||||
<$view tiddler=<<assetInfo>> field="description"/></h1>
|
<$view tiddler=<<assetInfo>> field="description"/>
|
||||||
|
</h1>
|
||||||
<h2><$view tiddler=<<assetInfo>> field="original-title"/></h2>
|
<h2><$view tiddler=<<assetInfo>> field="original-title"/></h2>
|
||||||
<div><em><$view tiddler=<<assetInfo>> field="version"/></em></div>
|
<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>
|
||||||
<$list filter="[<assetInfo>get[original-title]get[version]]" variable="installedVersion"><div><em>{{$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint}}</em></div></$list>
|
<$list filter="[<assetInfo>get[original-title]get[version]]" variable="installedVersion"><div><em>{{$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint}}</em></div></$list>
|
||||||
</div>
|
</div>
|
||||||
<div class="tc-plugin-info-chunk tc-plugin-info-buttons">
|
<div class="tc-plugin-info-chunk tc-plugin-info-buttons">
|
||||||
|
|||||||
10
core/ui/ControlPanel/TestCases.tid
Normal file
10
core/ui/ControlPanel/TestCases.tid
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
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>
|
||||||
24
core/ui/ControlPanel/TestCasesAll.tid
Normal file
24
core/ui/ControlPanel/TestCasesAll.tid
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
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>
|
||||||
15
core/ui/ControlPanel/TestCasesFailed.tid
Normal file
15
core/ui/ControlPanel/TestCasesFailed.tid
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
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>
|
||||||
@@ -9,7 +9,7 @@ list-before:
|
|||||||
|
|
||||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Settings]]">
|
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Settings]]">
|
||||||
|
|
||||||
<div class="tc-control-panel-setting" data-setting-title=<<currentTiddler>> style="border-top:1px solid #eee;">
|
<div class="tc-control-panel-setting" data-setting-title=<<currentTiddler>> >
|
||||||
|
|
||||||
!!.tc-control-panel-accent <$link><$transclude field="caption"/></$link>
|
!!.tc-control-panel-accent <$link><$transclude field="caption"/></$link>
|
||||||
|
|
||||||
|
|||||||
5
core/ui/KeyboardShortcuts/refresh.tid
Normal file
5
core/ui/KeyboardShortcuts/refresh.tid
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
title: $:/core/ui/KeyboardShortcuts/refresh
|
||||||
|
tags: $:/tags/KeyboardShortcut
|
||||||
|
key: ((refresh))
|
||||||
|
|
||||||
|
<$action-sendmessage $message="tm-browser-refresh"/>
|
||||||
@@ -1,16 +1,14 @@
|
|||||||
title: $:/core/ui/PageTemplate/pagecontrols
|
title: $:/core/ui/PageTemplate/pagecontrols
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
\define config-title() $:/config/PageControlButtons/Visibility/$(listItem)$
|
\function config-title() [[$:/config/PageControlButtons/Visibility/$(listItem)$]substitute[]]
|
||||||
|
|
||||||
<div class="tc-page-controls">
|
<div class="tc-page-controls">
|
||||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]" variable="listItem">
|
<$list filter="[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]" variable="listItem">
|
||||||
<$set name="hidden" value=<<config-title>>>
|
<$list filter="[<config-title>!text[hide]]" storyview="pop" variable="ignore">
|
||||||
<$list filter="[<hidden>!text[hide]]" storyview="pop" variable="ignore">
|
<$let tv-config-toolbar-class={{{ [enlist<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]] +[join[ ]] }}}>
|
||||||
<$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]">
|
<$transclude $tiddler=<<listItem>> $mode="inline"/>
|
||||||
<$transclude tiddler=<<listItem>> mode="inline"/>
|
</$let>
|
||||||
</$set>
|
</$list>
|
||||||
</$list>
|
|
||||||
</$set>
|
|
||||||
</$list>
|
</$list>
|
||||||
</div>
|
</div>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
title: $:/core/ui/PageTemplate
|
title: $:/core/ui/PageTemplate
|
||||||
name: {{$:/language/PageTemplate/Name}}
|
name: {{$:/language/PageTemplate/Name}}
|
||||||
description: {{$:/language/PageTemplate/Description}}
|
description: {{$:/language/PageTemplate/Description}}
|
||||||
icon: $:/core/images/default-layout
|
icon: $:/core/images/standard-layout
|
||||||
code-body: yes
|
code-body: yes
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
19
core/ui/TestCaseTemplate.tid
Normal file
19
core/ui/TestCaseTemplate.tid
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
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>
|
||||||
91
core/ui/TestCases/DefaultTemplate.tid
Normal file
91
core/ui/TestCases/DefaultTemplate.tid
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
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[span]] }}} 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>
|
||||||
|
<span class="tc-test-case-toolbar">
|
||||||
|
<$button popup=`$(state)$-more`
|
||||||
|
tooltip={{$:/language/Buttons/More/Hint}}
|
||||||
|
aria-label={{$:/language/Buttons/More/Caption}}
|
||||||
|
class="tc-btn-invisible"
|
||||||
|
selectedClass="tc-selected"
|
||||||
|
>
|
||||||
|
{{$:/core/images/down-arrow}}
|
||||||
|
</$button>
|
||||||
|
<$let
|
||||||
|
tv-config-toolbar-icons="yes"
|
||||||
|
tv-config-toolbar-text="yes"
|
||||||
|
tv-config-toolbar-class="tc-btn-invisible"
|
||||||
|
>
|
||||||
|
<$reveal state=`$(state)$-more` type="popup" position="belowleft" animate="yes">
|
||||||
|
<div class="tc-drop-down">
|
||||||
|
<$list filter="[all[shadows+tiddlers]tag[$:/tags/TestCase/Actions]!has[draft.of]]"
|
||||||
|
variable="listItem"
|
||||||
|
>
|
||||||
|
<$transclude tiddler=<<listItem>> mode="inline"/>
|
||||||
|
</$list>
|
||||||
|
</div>
|
||||||
|
</$reveal>
|
||||||
|
</$let>
|
||||||
|
</span>
|
||||||
|
</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 -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>
|
||||||
27
core/ui/TestCases/DefaultTemplateSourceTabs.tid
Normal file
27
core/ui/TestCases/DefaultTemplateSourceTabs.tid
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
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>>/>
|
||||||
|
<div class="tc-test-case-footer-toolbar">
|
||||||
|
<$macrocall $name="copy-to-clipboard" src={{{ [<currentTab>get[text]] }}}/>
|
||||||
|
</div>
|
||||||
|
\end
|
||||||
|
|
||||||
|
<$transclude $variable="body" $mode="inline"/>
|
||||||
4
core/ui/TestCases/RawJSONTemplate.tid
Normal file
4
core/ui/TestCases/RawJSONTemplate.tid
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
title: $:/core/ui/testcases/RawJSONTemplate
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
<$text text=<<payloadTiddlers>>/>
|
||||||
4
core/ui/TestCases/actions/Export.tid
Normal file
4
core/ui/TestCases/actions/Export.tid
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
title: $:/core/ui/testcases/actions/Export
|
||||||
|
tags: $:/tags/TestCase/Actions
|
||||||
|
|
||||||
|
<$macrocall $name="exportButton" exportFilter="[all[tiddlers]sort[]] -[prefix[$:/state/]] -Description -Narrative -ExpectedResult -Output Output +[putfirst[]] -[has[plugin-type]]" lingoBase="$:/language/Buttons/ExportTiddlers/"/>
|
||||||
11
core/ui/TestCases/actions/Import.tid
Normal file
11
core/ui/TestCases/actions/Import.tid
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
title: $:/core/ui/testcases/actions/Import
|
||||||
|
tags: $:/tags/TestCase/Actions
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
<$button tooltip={{$:/language/Buttons/TestCaseImport/Hint}} aria-label={{$:/language/Buttons/TestCaseImport/Caption}} class=<<tv-config-toolbar-class>>>
|
||||||
|
<$action-sendmessage $message="tm-import-tiddlers" $param=<<payloadTiddlers>>/>
|
||||||
|
{{$:/core/images/input-button}}
|
||||||
|
<span class="tc-btn-text">
|
||||||
|
<$text text={{$:/language/Buttons/TestCaseImport/Caption}}/>
|
||||||
|
</span>
|
||||||
|
</$button>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
title: $:/config/OfficialPluginLibrary
|
title: $:/config/OfficialPluginLibrary
|
||||||
tags: $:/tags/PluginLibrary
|
tags: $:/tags/PluginLibrary
|
||||||
url: https://tiddlywiki.com/library/v5.3.3/index.html
|
url: https://tiddlywiki.com/library/v5.3.5/index.html
|
||||||
caption: {{$:/language/OfficialPluginLibrary}}
|
caption: {{$:/language/OfficialPluginLibrary}}
|
||||||
|
|
||||||
{{$:/language/OfficialPluginLibrary/Hint}}
|
{{$:/language/OfficialPluginLibrary/Hint}}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ new-tiddler: {{$:/language/Buttons/NewTiddler/Hint}}
|
|||||||
picture: {{$:/language/Buttons/Picture/Hint}}
|
picture: {{$:/language/Buttons/Picture/Hint}}
|
||||||
preview: {{$:/language/Buttons/Preview/Hint}}
|
preview: {{$:/language/Buttons/Preview/Hint}}
|
||||||
quote: {{$:/language/Buttons/Quote/Hint}}
|
quote: {{$:/language/Buttons/Quote/Hint}}
|
||||||
|
refresh: {{$:/language/Buttons/Refresh/Hint}}
|
||||||
save-tiddler: {{$:/language/Buttons/Save/Hint}}
|
save-tiddler: {{$:/language/Buttons/Save/Hint}}
|
||||||
save-wiki: {{$:/language/Buttons/SaveWiki/Hint}}
|
save-wiki: {{$:/language/Buttons/SaveWiki/Hint}}
|
||||||
sidebar-search: {{$:/language/Buttons/SidebarSearch/Hint}}
|
sidebar-search: {{$:/language/Buttons/SidebarSearch/Hint}}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
title: $:/config/ViewTemplateBodyFilters/
|
title: $:/config/ViewTemplateBodyFilters/
|
||||||
tags: $:/tags/ViewTemplateBodyFilter
|
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]]
|
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]]
|
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]]
|
system: [prefix[$:/boot/]] [prefix[$:/config/]] [prefix[$:/core/macros]] [prefix[$:/core/save/]] [prefix[$:/core/templates/]] [prefix[$:/info/]] [prefix[$:/language/]] [prefix[$:/languages/]] [prefix[$:/snippets/]] [prefix[$:/state/]] [prefix[$:/status/]] [prefix[$:/info/]] [prefix[$:/temp/]] +[!is[image]limit[1]then[$:/core/ui/ViewTemplate/body/code]]
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ underline: meta-U
|
|||||||
new-image: ctrl-I
|
new-image: ctrl-I
|
||||||
new-journal: ctrl-J
|
new-journal: ctrl-J
|
||||||
new-tiddler: ctrl-N
|
new-tiddler: ctrl-N
|
||||||
|
refresh: meta-R
|
||||||
save-wiki: meta-S
|
save-wiki: meta-S
|
||||||
|
|||||||
@@ -6,3 +6,4 @@ underline: ctrl-U
|
|||||||
new-image: alt-I
|
new-image: alt-I
|
||||||
new-journal: alt-J
|
new-journal: alt-J
|
||||||
new-tiddler: alt-N
|
new-tiddler: alt-N
|
||||||
|
refresh: ctrl-R
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
title: $:/core/macros/CSS
|
title: $:/core/macros/CSS
|
||||||
tags: $:/tags/Macro $:/tags/Global
|
tags: $:/tags/Macro $:/tags/Global
|
||||||
|
|
||||||
\procedure colour(name)
|
<!-- Needs to stay that way for backwards compatibility. See GH issue: #8326 -->
|
||||||
|
\define colour(name)
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$transclude $tiddler={{$:/palette}} $index=`$(name)$`>
|
<$transclude tiddler={{$:/palette}} index="$name$">
|
||||||
<$transclude $tiddler="$:/palettes/Vanilla" $index=`$(name)$`>
|
<$transclude tiddler="$:/palettes/Vanilla" index="$name$">
|
||||||
<$transclude $tiddler=`$:/config/DefaultColourMappings/$(name)$`/>
|
<$transclude tiddler="$:/config/DefaultColourMappings/$name$"/>
|
||||||
</$transclude>
|
</$transclude>
|
||||||
</$transclude>
|
</$transclude>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\procedure color(name)
|
\define color(name) <<colour $name$>>
|
||||||
<$macrocall $name=colour name=`$(name)$`/>
|
|
||||||
\end
|
|
||||||
|
|
||||||
\function box-shadow(shadow)
|
\function box-shadow(shadow)
|
||||||
[[ -webkit-box-shadow: $(shadow)$;
|
[[ -webkit-box-shadow: $(shadow)$;
|
||||||
|
|||||||
@@ -1,167 +1,188 @@
|
|||||||
title: $:/core/macros/tag-picker
|
title: $:/core/macros/tag-picker
|
||||||
tags: $:/tags/Macro $:/tags/Global
|
tags: $:/tags/Macro $:/tags/Global
|
||||||
first-search-filter: [tags[]!is[system]search:title<userInput>sort[]]
|
first-search-filter: [subfilter<tagListFilter>!is[system]search:title<userInput>]
|
||||||
second-search-filter: [tags[]is[system]search:title<userInput>sort[]]
|
second-search-filter: [subfilter<tagListFilter>is[system]search:title<userInput>]
|
||||||
|
|
||||||
\procedure get-tagpicker-focus-selector()
|
<!--
|
||||||
\function currentTiddlerCSSEscaped() [<saveTiddler>escapecss[]]
|
Fields: "first-search-filter", "second-search-filter" are assigned to the keyboard-driven input macro with parameter: "configTiddlerFilter"
|
||||||
[data-tiddler-title=`$(currentTiddlerCSSEscaped)$`] .tc-add-tag-name input
|
They __need to be the same__ as used for variables: "nonSystemTagsFilter" and "systemTagsFilter". See code below!
|
||||||
|
-->
|
||||||
|
|
||||||
|
\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[/]]
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\procedure delete-tag-state-tiddlers() <$action-deletetiddler $filter="[<newTagNameTiddler>] [<storeTitle>] [<tagSelectionState>]"/>
|
\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[ ]]
|
||||||
|
|
||||||
|
<!-- 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()
|
\procedure add-tag-actions()
|
||||||
\whitespace trim
|
<$let tag=<<_tf.getTag>> >
|
||||||
<$let tag=<<tag>>>
|
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter='+[toggle<tag>trim[]]'/>
|
||||||
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter='+[toggle<tag>trim[]]'/>
|
<% if [<tag>] :intersection[<saveTiddler>get<tagField>enlist-input[]] %>
|
||||||
<$list
|
<!-- tag has been removed - do nothing -->
|
||||||
filter="[<tag>] :intersection[<saveTiddler>get<tagField>enlist-input[]]"
|
<% else %>
|
||||||
variable="ignore"
|
<<actions>>
|
||||||
emptyMessage="<<actions>>"
|
<% endif %>
|
||||||
/>
|
|
||||||
</$let>
|
|
||||||
<<delete-tag-state-tiddlers>>
|
|
||||||
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
|
||||||
\end
|
|
||||||
|
|
||||||
\procedure clear-tags-actions-inner()
|
|
||||||
\whitespace trim
|
|
||||||
<$list
|
|
||||||
filter="[<storeTitle>has[text]] ~[<newTagNameTiddler>has[text]]"
|
|
||||||
variable="ignore"
|
|
||||||
emptyMessage="<<cancel-delete-tiddler-actions 'cancel'>>"
|
|
||||||
>
|
|
||||||
<<delete-tag-state-tiddlers>>
|
<<delete-tag-state-tiddlers>>
|
||||||
</$list>
|
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
||||||
|
</$let>
|
||||||
|
\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]] %>
|
||||||
|
<<delete-tag-state-tiddlers>>
|
||||||
|
<% else %>
|
||||||
|
<<cancel-delete-tiddler-actions "cancel">>
|
||||||
|
<% endif %>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
<!-- triggered by keyboard only -->
|
||||||
\procedure clear-tags-actions()
|
\procedure clear-tags-actions()
|
||||||
\whitespace trim
|
<$let userInput=<<_tf.getUserInput>> >
|
||||||
<$let userInput=<<userInput>>>
|
<!-- this list __cannot__ be transformed to conditional IF. The list variable is used! -->
|
||||||
<$list
|
<$list filter="[<newTagNameTiddler>get[text]!match<userInput>]" >
|
||||||
filter="[<newTagNameTiddler>get[text]!match<userInput>]"
|
<$list-empty>
|
||||||
emptyMessage="<<clear-tags-actions-inner>>"
|
<<clear-tags-actions-inner>>
|
||||||
>
|
</$list-empty>
|
||||||
<$action-setfield $tiddler=<<newTagNameTiddler>> text=<<userInput>>/>
|
<$action-setfield $tiddler=<<newTagNameTiddler>> text=<<userInput>>/>
|
||||||
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
||||||
</$list>
|
</$list>
|
||||||
</$let>
|
</$let>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
<!-- similar to add-tag-actions __but__ add-only -->
|
||||||
\procedure add-button-actions()
|
\procedure add-button-actions()
|
||||||
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter="[<tag>trim[]]"/>
|
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter="[<tag>trim[]]"/>
|
||||||
<<actions>>
|
<<actions>>
|
||||||
<<delete-tag-state-tiddlers>>
|
<<delete-tag-state-tiddlers>>
|
||||||
<$action-sendmessage $message="tm-focus-selector" $param=<<get-tagpicker-focus-selector>>/>
|
<$action-sendmessage $message="tm-focus-selector" $param=<<tf.get-tagpicker-focus-selector>>/>
|
||||||
\end
|
\end
|
||||||
|
<!-- <$action-log /> -->
|
||||||
|
|
||||||
\procedure list-tags(filter, suffix)
|
<!-- create dropdown list -->
|
||||||
\whitespace trim
|
\procedure tag-picker-listTags(filter, suffix)
|
||||||
<$list
|
<$let userInput=<<_tf.getUserInput>> >
|
||||||
filter="[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]"
|
<$list filter="[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]"
|
||||||
emptyMessage="<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>" variable="listItem"
|
emptyMessage="<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>" variable="listItem"
|
||||||
>
|
>
|
||||||
<$list filter=<<filter>> variable="tag">
|
<$list filter=<<filter>> variable="tag">
|
||||||
<$let
|
<!-- The buttonClasses filter is used to define tc-tag-button-selected state -->
|
||||||
button-classes=`tc-btn-invisible ${ [<tag>addsuffix<suffix>] -[<tagSelectionState>get[text]] :then[[]] ~tc-tag-button-selected }$`
|
<!-- tf.get-tagpicker-focus-selector has to be resolved for $:/core/ui/TagPickerTagTemplate,
|
||||||
currentTiddler=<<tag>>
|
othwerwise qualify in tf.tagpicker-dropdown-id causes problems -->
|
||||||
>
|
<$let currentTiddler=<<tag>>
|
||||||
{{||$:/core/ui/TagPickerTagTemplate}}
|
button-classes=`tc-btn-invisible ${[<tag>addsuffix<suffix>] -[<tagSelectionState>get[text]] :then[[]] ~tc-tag-button-selected }$`
|
||||||
</$let>
|
get-tagpicker-focus-selector=`${[<tf.get-tagpicker-focus-selector>]}$`
|
||||||
|
>
|
||||||
|
{{||$:/core/ui/TagPickerTagTemplate}}
|
||||||
|
</$let>
|
||||||
|
</$list>
|
||||||
</$list>
|
</$list>
|
||||||
</$list>
|
</$let>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
<!-- tag-picker-inner is the main function -->
|
||||||
\procedure tag-picker-inner()
|
\procedure tag-picker-inner()
|
||||||
\whitespace trim
|
<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}}
|
||||||
|
>
|
||||||
|
{{$:/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>
|
||||||
|
\end
|
||||||
|
|
||||||
|
<!-- prepare all variables for tag-picker keyboard handling -->
|
||||||
|
\procedure tag-picker(actions, tagField:"tags", tiddler, tagListFilter:"[tags[]sort[]]")
|
||||||
|
|
||||||
|
\function _tf.getUserInput() [<storeTitle>get[text]]
|
||||||
|
\function _tf.getTag() [<newTagNameTiddler>get[text]]
|
||||||
|
<!-- Use this function if tag-picker is a stand alone macro. Otherwise use "newTagNameTiddler" defined for fieldmangler in EditTemplate -->
|
||||||
|
\function _tf.makeTagNameTiddler() [[$:/temp/NewTagName]] [<tagField>!match[tags]] +[join[/]] [<qualify>] +[join[]]
|
||||||
|
|
||||||
|
<!-- keep those variables because they may "bleed" into macros using old syntax -->
|
||||||
|
<!-- "nonSystemTagsFilter", "systemTagsFilter" __need to be the same__ as fields: "first-search-filter", "second-search-filter" -->
|
||||||
<$let
|
<$let
|
||||||
newTagNameInputTiddlerQualified=<<qualify "$:/temp/NewTagName/input">>
|
palette={{$:/palette}}
|
||||||
newTagNameSelectionTiddlerQualified=<<qualify "$:/temp/NewTagName/selected-item">>
|
|
||||||
fallbackTarget={{{ [<palette>getindex[tag-background]] }}}
|
|
||||||
colourA={{{ [<palette>getindex[foreground]] }}}
|
colourA={{{ [<palette>getindex[foreground]] }}}
|
||||||
colourB={{{ [<palette>getindex[background]] }}}
|
colourB={{{ [<palette>getindex[background]] }}}
|
||||||
|
fallbackTarget={{{ [<palette>getindex[tag-background]] }}}
|
||||||
|
|
||||||
storeTitle={{{ [<newTagNameInputTiddler>!match[]] ~[<newTagNameInputTiddlerQualified>] }}}
|
saveTiddler={{{ [<tiddler>is[blank]then<currentTiddler>else<tiddler>] }}}
|
||||||
|
|
||||||
|
newTagNameTiddler={{{ [[newTagNameTiddler]is[variable]then<newTagNameTiddler>] :else[<_tf.makeTagNameTiddler>] }}}
|
||||||
|
storeTitle={{{ [[$:/temp/NewTagName/input]] [<tagField>!match[tags]] +[join[/]] [<qualify>] +[join[]] }}}
|
||||||
|
|
||||||
|
newTagNameSelectionTiddlerQualified=<<qualify "$:/temp/NewTagName/selected-item">>
|
||||||
tagSelectionState={{{ [<newTagNameSelectionTiddler>!match[]] ~[<newTagNameSelectionTiddlerQualified>] }}}
|
tagSelectionState={{{ [<newTagNameSelectionTiddler>!match[]] ~[<newTagNameSelectionTiddlerQualified>] }}}
|
||||||
tagAutoComplete=<<qualify "$:/state/popup/tags-auto-complete">>
|
|
||||||
|
|
||||||
refreshTitle=<<qualify "$:/temp/NewTagName/refresh">>
|
refreshTitle=<<qualify "$:/temp/NewTagName/refresh">>
|
||||||
nonSystemTagsFilter="[tags[]!is[system]search:title<userInput>sort[]]"
|
|
||||||
systemTagsFilter="[tags[]is[system]search:title<userInput>sort[]]"
|
nonSystemTagsFilter="[subfilter<tagListFilter>!is[system]search:title<userInput>]"
|
||||||
|
systemTagsFilter="[subfilter<tagListFilter>is[system]search:title<userInput>]"
|
||||||
|
|
||||||
|
cancelPopups="yes"
|
||||||
>
|
>
|
||||||
<div class="tc-edit-add-tag">
|
<$macrocall $name="tag-picker-inner"/>
|
||||||
<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
|
|
||||||
|
|
||||||
\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>
|
</$let>
|
||||||
\end
|
\end
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ color:$(foregroundColor)$;
|
|||||||
>
|
>
|
||||||
<<__actions__>>
|
<<__actions__>>
|
||||||
<$transclude tiddler=<<__icon__>>/>
|
<$transclude tiddler=<<__icon__>>/>
|
||||||
<$view tiddler=<<__tag__>> field="title" format="text" />
|
<span class={{{ [<__tag__>is[missing]then[tc-tag-missing]else[tc-tag-exists]] }}}>
|
||||||
|
<$view tiddler=<<__tag__>> field="title" format="text" />
|
||||||
|
</span>
|
||||||
</$element-tag$>
|
</$element-tag$>
|
||||||
</$let>
|
</$let>
|
||||||
\end
|
\end
|
||||||
|
|||||||
10
core/wiki/macros/testcase.tid
Normal file
10
core/wiki/macros/testcase.tid
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
title: $:/core/macros/testcase
|
||||||
|
tags: $:/tags/Macro $:/tags/Global
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
|
||||||
|
\procedure testcase(tiddler)
|
||||||
|
<$tiddler tiddler=<<tiddler>>>
|
||||||
|
<$transclude $tiddler="$:/core/ui/TestCaseTemplate">
|
||||||
|
</$tiddler>
|
||||||
|
\end
|
||||||
2
core/wiki/tags/TestCaseActions.tid
Normal file
2
core/wiki/tags/TestCaseActions.tid
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
title: $:/tags/TestCase/Actions
|
||||||
|
list:
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user