mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-01-24 20:04:40 +00:00
Compare commits
377 Commits
improved-r
...
this-tiddl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
127ffbb078 | ||
|
|
9926e356c9 | ||
|
|
b61aef27d7 | ||
|
|
a1b706a945 | ||
|
|
2340d48844 | ||
|
|
4e641f4fc0 | ||
|
|
17f18daa89 | ||
|
|
b2aeea0393 | ||
|
|
48b7b5d294 | ||
|
|
1cac177211 | ||
|
|
e33a65a139 | ||
|
|
98af893443 | ||
|
|
6bd4127e88 | ||
|
|
6da74c6104 | ||
|
|
5e329b1da1 | ||
|
|
31de1527f3 | ||
|
|
23b5b7f7d9 | ||
|
|
be67b0714c | ||
|
|
d3ef198842 | ||
|
|
b1c295230d | ||
|
|
bffe538982 | ||
|
|
caac9bee92 | ||
|
|
36d766081d | ||
|
|
54548babc8 | ||
|
|
dccce5878c | ||
|
|
bfcb386343 | ||
|
|
f7c3ac4c54 | ||
|
|
2a19c60e20 | ||
|
|
c28dbd0025 | ||
|
|
29c2260457 | ||
|
|
d7c89de11d | ||
|
|
e0ff54a04e | ||
|
|
042f3c59ad | ||
|
|
07960f1527 | ||
|
|
5cdffd6943 | ||
|
|
ee0a32c8f1 | ||
|
|
4bb3d2ba34 | ||
|
|
e7c0ad484b | ||
|
|
e82053609b | ||
|
|
7926af8541 | ||
|
|
bcca4eca81 | ||
|
|
925ff202a0 | ||
|
|
97bc9039e6 | ||
|
|
e6149e7e29 | ||
|
|
e47f038d2a | ||
|
|
2789bc8ef6 | ||
|
|
3a2831870b | ||
|
|
4cddfa228b | ||
|
|
da1825e6c5 | ||
|
|
4ae2d8422b | ||
|
|
c9e1b91099 | ||
|
|
95f987544c | ||
|
|
308e207a67 | ||
|
|
aa5a6627e6 | ||
|
|
6f038e362e | ||
|
|
95a9c0bd54 | ||
|
|
0a20c08107 | ||
|
|
964993f879 | ||
|
|
e6175227b2 | ||
|
|
f247686970 | ||
|
|
589813f233 | ||
|
|
007b759421 | ||
|
|
714587cdfc | ||
|
|
d8c2ab3baf | ||
|
|
b16d695386 | ||
|
|
2bac676ac4 | ||
|
|
ba01d06962 | ||
|
|
6732d96f78 | ||
|
|
416a2fae7a | ||
|
|
2ce14ac8f9 | ||
|
|
3764ca4760 | ||
|
|
3f478f5689 | ||
|
|
f9604c40d3 | ||
|
|
11ffc83493 | ||
|
|
f343198353 | ||
|
|
3b794fae7f | ||
|
|
4919b4f239 | ||
|
|
1946f173a9 | ||
|
|
7d7ac662a2 | ||
|
|
3627ad1d28 | ||
|
|
b16ed6629d | ||
|
|
d14e775b90 | ||
|
|
d4b10605c3 | ||
|
|
7f1064d14b | ||
|
|
867d647839 | ||
|
|
8c39c9e911 | ||
|
|
c0ce53e3ea | ||
|
|
3a9f848ea0 | ||
|
|
5bce35d90b | ||
|
|
8d39ce95eb | ||
|
|
e313857822 | ||
|
|
ce988f909a | ||
|
|
ba2c9f44b0 | ||
|
|
6479c26b59 | ||
|
|
2271f6885a | ||
|
|
8c378e0d24 | ||
|
|
925ce2b505 | ||
|
|
cf25dae8a7 | ||
|
|
eb8f4d66b9 | ||
|
|
ef03a4a5df | ||
|
|
51a4d39c19 | ||
|
|
55124b4ee6 | ||
|
|
fb99d3050e | ||
|
|
95dc56d850 | ||
|
|
77b418004a | ||
|
|
028dfe39b7 | ||
|
|
81f5141166 | ||
|
|
8567c48be8 | ||
|
|
3da3318396 | ||
|
|
89fd8871b6 | ||
|
|
f249b79e81 | ||
|
|
524cee1489 | ||
|
|
93abe5e3a6 | ||
|
|
c0bca18cab | ||
|
|
d70b6a7d6c | ||
|
|
6404d5652e | ||
|
|
fe2c677ac4 | ||
|
|
3faadd69c0 | ||
|
|
4e5c957e97 | ||
|
|
3d0ec5b1bd | ||
|
|
fb8e5d1417 | ||
|
|
2426cc668d | ||
|
|
75a399a389 | ||
|
|
4c4399c32d | ||
|
|
194df33de3 | ||
|
|
6718f82b4c | ||
|
|
8ef6d78bef | ||
|
|
e6189078ff | ||
|
|
c20c35c0a6 | ||
|
|
51cbf83c23 | ||
|
|
1441138d5c | ||
|
|
a5894946de | ||
|
|
a3a1eceb4a | ||
|
|
aa8f7f77d6 | ||
|
|
5d650e87dd | ||
|
|
67a8f7aeba | ||
|
|
485bf19c3c | ||
|
|
586d44f6ce | ||
|
|
18c790152f | ||
|
|
9541f3c283 | ||
|
|
5aa5fc72b1 | ||
|
|
005dfdadf0 | ||
|
|
af1cc56c0c | ||
|
|
5bf60cd26f | ||
|
|
4546828541 | ||
|
|
1a69fb7e5c | ||
|
|
db88eed88f | ||
|
|
c51816e826 | ||
|
|
e41511c652 | ||
|
|
8f7441f296 | ||
|
|
c8d99c8aad | ||
|
|
166f68cc15 | ||
|
|
fecb7edca4 | ||
|
|
7632a3317a | ||
|
|
0039c2134b | ||
|
|
34643a4279 | ||
|
|
4d040d2499 | ||
|
|
c0615e20ec | ||
|
|
c39ef398bf | ||
|
|
02d28c100b | ||
|
|
dc225da1ff | ||
|
|
aeec6aee23 | ||
|
|
f9efbd93b1 | ||
|
|
b7c420393c | ||
|
|
9574506a89 | ||
|
|
13c0f3c5e2 | ||
|
|
301a0ecec7 | ||
|
|
917975b464 | ||
|
|
c9691bdb27 | ||
|
|
5ea9743cd5 | ||
|
|
0c328a1696 | ||
|
|
b5134951e5 | ||
|
|
6e10918a28 | ||
|
|
0ee53bbc01 | ||
|
|
a52da67563 | ||
|
|
494ee984f8 | ||
|
|
9c70ee34d4 | ||
|
|
c7612ff4ce | ||
|
|
51acc24b0a | ||
|
|
c5ce1d78a2 | ||
|
|
dd6e00687b | ||
|
|
7b7063a7b2 | ||
|
|
a61d644307 | ||
|
|
09cc3b0b73 | ||
|
|
2a2fd1caa8 | ||
|
|
cf25f57acf | ||
|
|
f3ebb258f7 | ||
|
|
574b90cf7a | ||
|
|
67beafe359 | ||
|
|
8ca0bf10e4 | ||
|
|
6f9cf20e77 | ||
|
|
fb8df29948 | ||
|
|
b33b41e1fc | ||
|
|
04810667e6 | ||
|
|
50971db392 | ||
|
|
d57abcbb23 | ||
|
|
8a2fad2499 | ||
|
|
666e2a795f | ||
|
|
42a408146d | ||
|
|
bf8e1ca5b0 | ||
|
|
3bdc18ab84 | ||
|
|
43214c1cc6 | ||
|
|
0b39e47ce8 | ||
|
|
87c3e53299 | ||
|
|
3a7a3d64c2 | ||
|
|
c819b2d365 | ||
|
|
119813529d | ||
|
|
9f69161709 | ||
|
|
18d3ea9d14 | ||
|
|
ae18c2e19b | ||
|
|
95e6168839 | ||
|
|
73507ca8b5 | ||
|
|
4a6e3d4281 | ||
|
|
d217826375 | ||
|
|
a5afed9384 | ||
|
|
b37a356b5e | ||
|
|
55d9a5e16d | ||
|
|
3bab996acd | ||
|
|
7e8380a8df | ||
|
|
44de7918ab | ||
|
|
5ee6af0632 | ||
|
|
ccf444c834 | ||
|
|
ecaa288fc5 | ||
|
|
ceb6999dd6 | ||
|
|
e51dd406b1 | ||
|
|
6ea61ac94f | ||
|
|
caf01f10d6 | ||
|
|
1bd7924e1b | ||
|
|
25b8f26073 | ||
|
|
9160d81cc6 | ||
|
|
0b1a4f3a4d | ||
|
|
8d48964aca | ||
|
|
6cd2fc029d | ||
|
|
6235f29749 | ||
|
|
6385534638 | ||
|
|
ba3cba6170 | ||
|
|
34c9e83bec | ||
|
|
ed9cc84fb2 | ||
|
|
22bc826247 | ||
|
|
6e6efcafc9 | ||
|
|
3c81558d74 | ||
|
|
cc47bb0330 | ||
|
|
0ce5788747 | ||
|
|
1118de319e | ||
|
|
c2d82ccb32 | ||
|
|
a899aac92c | ||
|
|
bef11fe6a2 | ||
|
|
17a1ae23eb | ||
|
|
9f867ad51e | ||
|
|
28c1e6bfc3 | ||
|
|
2db886793e | ||
|
|
8d050e0e69 | ||
|
|
e77006de63 | ||
|
|
80442b7f7f | ||
|
|
10bb3ba09d | ||
|
|
58013ba435 | ||
|
|
ee7bde58a2 | ||
|
|
229159fea7 | ||
|
|
a311e5ebac | ||
|
|
9ff479ce87 | ||
|
|
77053cfe13 | ||
|
|
1bd58db944 | ||
|
|
4be0c17dd0 | ||
|
|
595da5f9f6 | ||
|
|
ff674b9117 | ||
|
|
38dce175d6 | ||
|
|
1ab9f457b4 | ||
|
|
1eddb52de5 | ||
|
|
52fd6ce9c2 | ||
|
|
62308792c8 | ||
|
|
272ba6a4b7 | ||
|
|
90449c9458 | ||
|
|
5b8f36a594 | ||
|
|
acc7224758 | ||
|
|
0db987da60 | ||
|
|
a93a499684 | ||
|
|
2c33502a4a | ||
|
|
451a3454b5 | ||
|
|
45a7eb1c03 | ||
|
|
d03da6085b | ||
|
|
fa4dc2a4e9 | ||
|
|
3918e59cc1 | ||
|
|
f7ccba4c25 | ||
|
|
319d7fbe9c | ||
|
|
67c8f29160 | ||
|
|
856aca2f92 | ||
|
|
34a20463c7 | ||
|
|
56f13133d8 | ||
|
|
684673cbff | ||
|
|
bea1a6b14f | ||
|
|
32a033bb50 | ||
|
|
97f7db169a | ||
|
|
850a4dd351 | ||
|
|
d707e6f825 | ||
|
|
5c378855ab | ||
|
|
ebc1f7e4ce | ||
|
|
2fcbf3b521 | ||
|
|
00927d2e13 | ||
|
|
882e040e62 | ||
|
|
026739e2e0 | ||
|
|
fba9efcf4a | ||
|
|
acfea3a212 | ||
|
|
0dc30086e9 | ||
|
|
cb0d0cfa6d | ||
|
|
d32d559f93 | ||
|
|
8ead7e0624 | ||
|
|
4f7b10e055 | ||
|
|
b8a30091ee | ||
|
|
6955f14c3c | ||
|
|
994c5a2970 | ||
|
|
ea150029f5 | ||
|
|
c663d2ba00 | ||
|
|
39e8c8b125 | ||
|
|
3713ee4fa9 | ||
|
|
a99f934371 | ||
|
|
63803fd99d | ||
|
|
79ec96cb59 | ||
|
|
419b3b3534 | ||
|
|
368963def0 | ||
|
|
830ffe64de | ||
|
|
1483195cd5 | ||
|
|
9b9ff1e843 | ||
|
|
ea3503e30c | ||
|
|
5e116d2a57 | ||
|
|
aa5183a08e | ||
|
|
10cb585dae | ||
|
|
029203dbc0 | ||
|
|
832868ecae | ||
|
|
7f48b6c6ce | ||
|
|
b263ee3c80 | ||
|
|
b097d2ec48 | ||
|
|
ef779c11e8 | ||
|
|
06520c8994 | ||
|
|
710e51fe04 | ||
|
|
af6c017086 | ||
|
|
34353f4065 | ||
|
|
fedc23d73c | ||
|
|
344110e289 | ||
|
|
72f06581b6 | ||
|
|
ae12e8fb69 | ||
|
|
e8148ff978 | ||
|
|
965bd090a9 | ||
|
|
3be9b13814 | ||
|
|
62f26d6630 | ||
|
|
8fe2f6086d | ||
|
|
30af537b91 | ||
|
|
f54ecc23f3 | ||
|
|
67dd3f06bf | ||
|
|
6af3eb539b | ||
|
|
3f55f827a6 | ||
|
|
b9d27e9fd5 | ||
|
|
5b85786f73 | ||
|
|
24dbf69180 | ||
|
|
7b408c7adf | ||
|
|
c19d6d6328 | ||
|
|
941c09fae2 | ||
|
|
b531984f50 | ||
|
|
8f079e2d45 | ||
|
|
cfd894e6fb | ||
|
|
91327c1af0 | ||
|
|
6f98edd6bd | ||
|
|
23e0eeb556 | ||
|
|
f33c7e2aef | ||
|
|
fc586481a9 | ||
|
|
09179d2f62 | ||
|
|
d6ff38095b | ||
|
|
3bbbe77471 | ||
|
|
5657dfec0e | ||
|
|
31ab6dce77 | ||
|
|
4007610d52 | ||
|
|
fb34df84ed | ||
|
|
79e2e317cf | ||
|
|
36896c3db8 | ||
|
|
82de7c9b1a | ||
|
|
1841b0fa4f | ||
|
|
47f80339b2 | ||
|
|
db6abb9703 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,7 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.c9/
|
.c9/
|
||||||
|
.vscode/
|
||||||
tmp/
|
tmp/
|
||||||
output/
|
output/
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
|
|||||||
@@ -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.2.3
|
TW5_BUILD_VERSION=v5.2.8
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
||||||
@@ -233,6 +233,15 @@ node $TW5_BUILD_TIDDLYWIKI \
|
|||||||
--build index \
|
--build index \
|
||||||
|| exit 1
|
|| exit 1
|
||||||
|
|
||||||
|
# /editions/twitter-archivist/index.html Twitter Archivist edition
|
||||||
|
node $TW5_BUILD_TIDDLYWIKI \
|
||||||
|
./editions/twitter-archivist \
|
||||||
|
--verbose \
|
||||||
|
--load $TW5_BUILD_OUTPUT/build.tid \
|
||||||
|
--output $TW5_BUILD_OUTPUT/editions/twitter-archivist/ \
|
||||||
|
--build index \
|
||||||
|
|| exit 1
|
||||||
|
|
||||||
######################################################
|
######################################################
|
||||||
#
|
#
|
||||||
# Plugin demos
|
# Plugin demos
|
||||||
@@ -350,14 +359,14 @@ node $TW5_BUILD_TIDDLYWIKI \
|
|||||||
|
|
||||||
# Delete any existing static content
|
# Delete any existing static content
|
||||||
|
|
||||||
rm $TW5_BUILD_OUTPUT/languages/de-AT/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/de-AT/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/de-DE/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/de-DE/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/es-ES/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/es-ES/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/fr-FR/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/fr-FR/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/ja-JP/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/ja-JP/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/ko-KR/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/ko-KR/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/zh-Hans/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/zh-Hans/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/zh-Hant/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/zh-Hant/static/*
|
||||||
|
|
||||||
# /languages/de-AT/index.html Demo wiki with de-AT language
|
# /languages/de-AT/index.html Demo wiki with de-AT language
|
||||||
# /languages/de-AT/empty.html Empty wiki with de-AT language
|
# /languages/de-AT/empty.html Empty wiki with de-AT language
|
||||||
@@ -450,7 +459,7 @@ node $TW5_BUILD_TIDDLYWIKI \
|
|||||||
--verbose \
|
--verbose \
|
||||||
--load $TW5_BUILD_OUTPUT/build.tid \
|
--load $TW5_BUILD_OUTPUT/build.tid \
|
||||||
--output $TW5_BUILD_OUTPUT/library/$TW5_BUILD_VERSION \
|
--output $TW5_BUILD_OUTPUT/library/$TW5_BUILD_VERSION \
|
||||||
--build \
|
--build library\
|
||||||
|| exit 1
|
|| exit 1
|
||||||
|
|
||||||
# Delete the temporary build tiddler
|
# Delete the temporary build tiddler
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
# Remove any output files
|
# Remove any output files
|
||||||
|
|
||||||
find . -regex "^./editions/[a-z0-9\.-]*/output/.*" -delete
|
find . -regex "^./editions/.*/output/.*" -delete
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ node ./tiddlywiki.js \
|
|||||||
--verbose \
|
--verbose \
|
||||||
--version \
|
--version \
|
||||||
--rendertiddler $:/core/save/all test.html text/plain \
|
--rendertiddler $:/core/save/all test.html text/plain \
|
||||||
|
--test \
|
||||||
|| exit 1
|
|| exit 1
|
||||||
|
|
||||||
echo To run the tests in a browser, open "editions/test/output/test.html"
|
echo To run the tests in a browser, open "editions/test/output/test.html"
|
||||||
|
|||||||
19
boot/boot.js
19
boot/boot.js
@@ -313,7 +313,7 @@ $tw.utils.getLocationHash = function() {
|
|||||||
var idx = href.indexOf('#');
|
var idx = href.indexOf('#');
|
||||||
if(idx === -1) {
|
if(idx === -1) {
|
||||||
return "#";
|
return "#";
|
||||||
} else if(idx < href.length-1 && href[idx+1] === '#') {
|
} else if(href.substr(idx + 1,1) === "#" || href.substr(idx + 1,3) === "%23") {
|
||||||
// Special case: ignore location hash if it itself starts with a #
|
// Special case: ignore location hash if it itself starts with a #
|
||||||
return "#";
|
return "#";
|
||||||
} else {
|
} else {
|
||||||
@@ -375,7 +375,7 @@ $tw.utils.stringifyList = function(value) {
|
|||||||
var result = new Array(value.length);
|
var result = new Array(value.length);
|
||||||
for(var t=0, l=value.length; t<l; t++) {
|
for(var t=0, l=value.length; t<l; t++) {
|
||||||
var entry = value[t] || "";
|
var entry = value[t] || "";
|
||||||
if(entry.indexOf(" ") !== -1) {
|
if(entry.match(/[^\S\xA0]/mg)) {
|
||||||
result[t] = "[[" + entry + "]]";
|
result[t] = "[[" + entry + "]]";
|
||||||
} else {
|
} else {
|
||||||
result[t] = entry;
|
result[t] = entry;
|
||||||
@@ -1881,7 +1881,7 @@ A default set of files for TiddlyWiki to ignore during load.
|
|||||||
This matches what NPM ignores, and adds "*.meta" to ignore tiddler
|
This matches what NPM ignores, and adds "*.meta" to ignore tiddler
|
||||||
metadata files.
|
metadata files.
|
||||||
*/
|
*/
|
||||||
$tw.boot.excludeRegExp = /^\.DS_Store$|^.*\.meta$|^\..*\.swp$|^\._.*$|^\.git$|^\.hg$|^\.lock-wscript$|^\.svn$|^\.wafpickle-.*$|^CVS$|^npm-debug\.log$/;
|
$tw.boot.excludeRegExp = /^\.DS_Store$|^.*\.meta$|^\..*\.swp$|^\._.*$|^\.git$|^\.github$|^\.vscode$|^\.hg$|^\.lock-wscript$|^\.svn$|^\.wafpickle-.*$|^CVS$|^npm-debug\.log$/;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Load all the tiddlers recursively from a directory, including honouring `tiddlywiki.files` files for drawing in external files. Returns an array of {filepath:,type:,tiddlers: [{..fields...}],hasMetaFile:}. Note that no file information is returned for externally loaded tiddlers, just the `tiddlers` property.
|
Load all the tiddlers recursively from a directory, including honouring `tiddlywiki.files` files for drawing in external files. Returns an array of {filepath:,type:,tiddlers: [{..fields...}],hasMetaFile:}. Note that no file information is returned for externally loaded tiddlers, just the `tiddlers` property.
|
||||||
@@ -1920,7 +1920,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
|||||||
// Read the specification
|
// Read the specification
|
||||||
var filesInfo = $tw.utils.parseJSONSafe(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"));
|
var filesInfo = $tw.utils.parseJSONSafe(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"));
|
||||||
// Helper to process a file
|
// Helper to process a file
|
||||||
var processFile = function(filename,isTiddlerFile,fields,isEditableFile) {
|
var processFile = function(filename,isTiddlerFile,fields,isEditableFile,rootPath) {
|
||||||
var extInfo = $tw.config.fileExtensionInfo[path.extname(filename)],
|
var extInfo = $tw.config.fileExtensionInfo[path.extname(filename)],
|
||||||
type = (extInfo || {}).type || fields.type || "text/plain",
|
type = (extInfo || {}).type || fields.type || "text/plain",
|
||||||
typeInfo = $tw.config.contentTypeInfo[type] || {},
|
typeInfo = $tw.config.contentTypeInfo[type] || {},
|
||||||
@@ -1941,6 +1941,12 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
|||||||
} else {
|
} else {
|
||||||
var value = tiddler[name];
|
var value = tiddler[name];
|
||||||
switch(fieldInfo.source) {
|
switch(fieldInfo.source) {
|
||||||
|
case "subdirectories":
|
||||||
|
value = path.relative(rootPath, filename).split('/').slice(0, -1);
|
||||||
|
break;
|
||||||
|
case "filepath":
|
||||||
|
value = path.relative(rootPath, filename);
|
||||||
|
break;
|
||||||
case "filename":
|
case "filename":
|
||||||
value = path.basename(filename);
|
value = path.basename(filename);
|
||||||
break;
|
break;
|
||||||
@@ -2023,7 +2029,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
|||||||
var thisPath = path.relative(filepath, files[t]),
|
var thisPath = path.relative(filepath, files[t]),
|
||||||
filename = path.basename(thisPath);
|
filename = path.basename(thisPath);
|
||||||
if(filename !== "tiddlywiki.files" && !metaRegExp.test(filename) && fileRegExp.test(filename)) {
|
if(filename !== "tiddlywiki.files" && !metaRegExp.test(filename) && fileRegExp.test(filename)) {
|
||||||
processFile(thisPath,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile);
|
processFile(thisPath,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile,dirSpec.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2403,11 +2409,12 @@ $tw.boot.initStartup = function(options) {
|
|||||||
$tw.utils.registerFileType("application/x-font-ttf","base64",".woff");
|
$tw.utils.registerFileType("application/x-font-ttf","base64",".woff");
|
||||||
$tw.utils.registerFileType("application/font-woff2","base64",".woff2");
|
$tw.utils.registerFileType("application/font-woff2","base64",".woff2");
|
||||||
$tw.utils.registerFileType("audio/ogg","base64",".ogg");
|
$tw.utils.registerFileType("audio/ogg","base64",".ogg");
|
||||||
|
$tw.utils.registerFileType("audio/mp4","base64",[".mp4",".m4a"]);
|
||||||
$tw.utils.registerFileType("video/ogg","base64",[".ogm",".ogv",".ogg"]);
|
$tw.utils.registerFileType("video/ogg","base64",[".ogm",".ogv",".ogg"]);
|
||||||
$tw.utils.registerFileType("video/webm","base64",".webm");
|
$tw.utils.registerFileType("video/webm","base64",".webm");
|
||||||
$tw.utils.registerFileType("video/mp4","base64",".mp4");
|
$tw.utils.registerFileType("video/mp4","base64",".mp4");
|
||||||
$tw.utils.registerFileType("audio/mp3","base64",".mp3");
|
$tw.utils.registerFileType("audio/mp3","base64",".mp3");
|
||||||
$tw.utils.registerFileType("audio/mp4","base64",[".mp4",".m4a"]);
|
$tw.utils.registerFileType("audio/mpeg","base64");
|
||||||
$tw.utils.registerFileType("text/markdown","utf8",[".md",".markdown"],{deserializerType:"text/x-markdown"});
|
$tw.utils.registerFileType("text/markdown","utf8",[".md",".markdown"],{deserializerType:"text/x-markdown"});
|
||||||
$tw.utils.registerFileType("text/x-markdown","utf8",[".md",".markdown"]);
|
$tw.utils.registerFileType("text/x-markdown","utf8",[".md",".markdown"]);
|
||||||
$tw.utils.registerFileType("application/enex+xml","utf8",".enex");
|
$tw.utils.registerFileType("application/enex+xml","utf8",".enex");
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ type: text/plain
|
|||||||
TiddlyWiki created by Jeremy Ruston, (jeremy [at] jermolene [dot] com)
|
TiddlyWiki created by Jeremy Ruston, (jeremy [at] jermolene [dot] com)
|
||||||
|
|
||||||
Copyright (c) 2004-2007, Jeremy Ruston
|
Copyright (c) 2004-2007, Jeremy Ruston
|
||||||
Copyright (c) 2007-2022, UnaMesa Association
|
Copyright (c) 2007-2023, UnaMesa Association
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
4
core/images/layout-button.tid
Executable file
4
core/images/layout-button.tid
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
title: $:/core/images/layout-button
|
||||||
|
tags: $:/tags/Image
|
||||||
|
|
||||||
|
<svg width="22pt" height="22pt" class="tc-image-layout-button tc-image-button" viewBox="0 0 24 24" stroke-width="1" stroke="none"><path d="M0 0h24v24H0z" fill="none"/><rect x="2" y="2" width="7" height="7" rx="2"/><rect x="2" y="13" width="7" height="9" rx="2"/><rect x="12" y="2" width="10" height="20" rx="2"/></svg>
|
||||||
6
core/images/mastodon.tid
Normal file
6
core/images/mastodon.tid
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
title: $:/core/images/mastodon
|
||||||
|
tags: $:/tags/Image
|
||||||
|
|
||||||
|
<svg width="22pt" height="22pt" class="tc-image-mastodon tc-image-button" viewBox="0 0 128 128">
|
||||||
|
<path d="M112.716,76.735C111.231,85.764 99.411,95.646 85.836,97.561C78.757,98.559 71.787,99.476 64.355,99.073C52.201,98.415 42.61,95.646 42.61,95.646C42.61,97.044 42.683,98.374 42.829,99.619C44.409,113.79 54.723,114.639 64.493,115.035C74.354,115.434 83.134,112.163 83.134,112.163L83.539,122.695C83.539,122.695 76.642,127.071 64.355,127.875C57.58,128.315 49.167,127.674 39.369,124.61C18.118,117.965 14.463,91.202 13.904,64.048C13.733,55.985 13.839,48.383 13.839,42.024C13.839,14.257 29.238,6.118 29.238,6.118C37.002,1.905 50.326,0.134 64.177,-0L64.517,-0C78.369,0.134 91.701,1.905 99.465,6.118C99.465,6.118 114.864,14.257 114.864,42.024C114.864,42.024 115.057,62.511 112.716,76.735ZM96.7,44.179C96.7,37.307 95.219,31.847 92.245,27.807C89.177,23.767 85.16,21.696 80.174,21.696C74.403,21.696 70.034,24.316 67.146,29.556L64.337,35.118L61.529,29.556C58.64,24.316 54.271,21.696 48.501,21.696C43.514,21.696 39.497,23.767 36.43,27.807C33.455,31.847 31.974,37.307 31.974,44.179L31.974,77.8L43.249,77.8L43.249,45.167C43.249,38.288 45.699,34.796 50.599,34.796C56.017,34.796 58.733,38.938 58.733,47.128L58.733,64.99L69.941,64.99L69.941,47.128C69.941,38.938 72.657,34.796 78.075,34.796C82.975,34.796 85.425,38.288 85.425,45.167L85.425,77.8L96.7,77.8L96.7,44.179Z"/>
|
||||||
|
</svg>
|
||||||
12
core/images/save-button-dynamic.tid
Normal file
12
core/images/save-button-dynamic.tid
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
title: $:/core/images/save-button-dynamic
|
||||||
|
tags: $:/tags/Image
|
||||||
|
|
||||||
|
<svg width="22pt" height="22pt" class="tc-image-save-button-dynamic tc-image-button" viewBox="0 0 128 128">
|
||||||
|
<g class="tc-image-save-button-dynamic-clean">
|
||||||
|
<path fill-rule="evenodd" d="M120.783 34.33c4.641 8.862 7.266 18.948 7.266 29.646 0 35.347-28.653 64-64 64-35.346 0-64-28.653-64-64 0-35.346 28.654-64 64-64 18.808 0 35.72 8.113 47.43 21.03l2.68-2.68c3.13-3.13 8.197-3.132 11.321-.008 3.118 3.118 3.121 8.193-.007 11.32l-4.69 4.691zm-12.058 12.058a47.876 47.876 0 013.324 17.588c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48c14.39 0 27.3 6.332 36.098 16.362L58.941 73.544 41.976 56.578c-3.127-3.127-8.201-3.123-11.32-.005-3.123 3.124-3.119 8.194.006 11.319l22.617 22.617a7.992 7.992 0 005.659 2.347c2.05 0 4.101-.783 5.667-2.349l44.12-44.12z"/>
|
||||||
|
</g>
|
||||||
|
<g class="tc-image-save-button-dynamic-dirty">
|
||||||
|
<path d="M64.856912,0 C100.203136,0 128.856912,28.653776 128.856912,64 C128.856912,99.346224 100.203136,128 64.856912,128 C29.510688,128 0.856911958,99.346224 0.856911958,64 C0.856911958,28.653776 29.510688,0 64.856912,0 Z M64.856912,16 C38.347244,16 16.856912,37.490332 16.856912,64 C16.856912,90.509668 38.347244,112 64.856912,112 C91.3665799,112 112.856912,90.509668 112.856912,64 C112.856912,37.490332 91.3665799,16 64.856912,16 Z"></path>
|
||||||
|
<circle cx="65" cy="64" r="32"></circle>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
@@ -59,6 +59,8 @@ Home/Caption: home
|
|||||||
Home/Hint: Open the default tiddlers
|
Home/Hint: Open the default tiddlers
|
||||||
Language/Caption: language
|
Language/Caption: language
|
||||||
Language/Hint: Choose the user interface language
|
Language/Hint: Choose the user interface language
|
||||||
|
LayoutSwitcher/Hint: Open layout switcher
|
||||||
|
LayoutSwitcher/Caption: layout
|
||||||
Manager/Caption: tiddler manager
|
Manager/Caption: tiddler manager
|
||||||
Manager/Hint: Open tiddler manager
|
Manager/Hint: Open tiddler manager
|
||||||
More/Caption: more
|
More/Caption: more
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Appearance/Hint: Ways to customise the appearance of your TiddlyWiki.
|
|||||||
Basics/AnimDuration/Prompt: Animation duration
|
Basics/AnimDuration/Prompt: Animation duration
|
||||||
Basics/AutoFocus/Prompt: Default focus field for new tiddlers
|
Basics/AutoFocus/Prompt: Default focus field for new tiddlers
|
||||||
Basics/Caption: Basics
|
Basics/Caption: Basics
|
||||||
Basics/DefaultTiddlers/BottomHint: Use [[double square brackets]] for titles with spaces. Or you can choose to <$button set="$:/DefaultTiddlers" setTo="[list[$:/StoryList]]">retain story ordering</$button>
|
Basics/DefaultTiddlers/BottomHint: Use [[double square brackets]] for titles with spaces. Or you can choose to {{retain story ordering||$:/snippets/retain-story-ordering-button}}
|
||||||
Basics/DefaultTiddlers/Prompt: Default tiddlers
|
Basics/DefaultTiddlers/Prompt: Default tiddlers
|
||||||
Basics/DefaultTiddlers/TopHint: Choose which tiddlers are displayed at startup
|
Basics/DefaultTiddlers/TopHint: Choose which tiddlers are displayed at startup
|
||||||
Basics/Language/Prompt: Hello! Current language:
|
Basics/Language/Prompt: Hello! Current language:
|
||||||
@@ -90,8 +90,8 @@ Plugins/Languages/Caption: Languages
|
|||||||
Plugins/Languages/Hint: Language pack plugins
|
Plugins/Languages/Hint: Language pack plugins
|
||||||
Plugins/NoInfoFound/Hint: No ''"<$text text=<<currentTab>>/>"'' found
|
Plugins/NoInfoFound/Hint: No ''"<$text text=<<currentTab>>/>"'' found
|
||||||
Plugins/NotInstalled/Hint: This plugin is not currently installed
|
Plugins/NotInstalled/Hint: This plugin is not currently installed
|
||||||
Plugins/OpenPluginLibrary: open plugin library
|
Plugins/OpenPluginLibrary: Open plugin library
|
||||||
Plugins/ClosePluginLibrary: close plugin library
|
Plugins/ClosePluginLibrary: Close plugin library
|
||||||
Plugins/PluginWillRequireReload: (requires reload)
|
Plugins/PluginWillRequireReload: (requires reload)
|
||||||
Plugins/Plugins/Caption: Plugins
|
Plugins/Plugins/Caption: Plugins
|
||||||
Plugins/Plugins/Hint: Plugins
|
Plugins/Plugins/Hint: Plugins
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
title: $:/language/Docs/Fields/
|
title: $:/language/Docs/Fields/
|
||||||
|
|
||||||
_canonical_uri: The full URI of an external image tiddler
|
_canonical_uri: The full URI of an external image tiddler
|
||||||
|
author: Name of the author of a plugin
|
||||||
bag: The name of the bag from which a tiddler came
|
bag: The name of the bag from which a tiddler came
|
||||||
caption: The text to be displayed on a tab or button
|
caption: The text to be displayed on a tab or button
|
||||||
code-body: The view template will display the tiddler as code if set to ''yes''
|
code-body: The view template will display the tiddler as code if set to ''yes''
|
||||||
color: The CSS color value associated with a tiddler
|
color: The CSS color value associated with a tiddler
|
||||||
component: The name of the component responsible for an [[alert tiddler|AlertMechanism]]
|
component: The name of the component responsible for an [[alert tiddler|AlertMechanism]]
|
||||||
|
core-version: For a plugin, indicates what version of TiddlyWiki with which it is compatible
|
||||||
current-tiddler: Used to cache the top tiddler in a [[history list|HistoryMechanism]]
|
current-tiddler: Used to cache the top tiddler in a [[history list|HistoryMechanism]]
|
||||||
created: The date a tiddler was created
|
created: The date a tiddler was created
|
||||||
creator: The name of the person who created a tiddler
|
creator: The name of the person who created a tiddler
|
||||||
@@ -13,7 +15,7 @@ dependents: For a plugin, lists the dependent plugin titles
|
|||||||
description: The descriptive text for a plugin, or a modal dialogue
|
description: The descriptive text for a plugin, or a modal dialogue
|
||||||
draft.of: For draft tiddlers, contains the title of the tiddler of which this is a draft
|
draft.of: For draft tiddlers, contains the title of the tiddler of which this is a draft
|
||||||
draft.title: For draft tiddlers, contains the proposed new title of the tiddler
|
draft.title: For draft tiddlers, contains the proposed new title of the tiddler
|
||||||
footer: The footer text for a wizard
|
footer: The footer text for a modal
|
||||||
hide-body: The view template will hide bodies of tiddlers if set to ''yes''
|
hide-body: The view template will hide bodies of tiddlers if set to ''yes''
|
||||||
icon: The title of the tiddler containing the icon associated with a tiddler
|
icon: The title of the tiddler containing the icon associated with a tiddler
|
||||||
library: Indicates that a tiddler should be saved as a JavaScript library if set to ''yes''
|
library: Indicates that a tiddler should be saved as a JavaScript library if set to ''yes''
|
||||||
@@ -22,13 +24,15 @@ list-before: If set, the title of a tiddler before which this tiddler should be
|
|||||||
list-after: If set, the title of the tiddler after which this tiddler should be added to the ordered list of tiddler titles, or at the end of the list if this field is present but empty
|
list-after: If set, the title of the tiddler after which this tiddler should be added to the ordered list of tiddler titles, or at the end of the list if this field is present but empty
|
||||||
modified: The date and time at which a tiddler was last modified
|
modified: The date and time at which a tiddler was last modified
|
||||||
modifier: The tiddler title associated with the person who last modified a tiddler
|
modifier: The tiddler title associated with the person who last modified a tiddler
|
||||||
|
module-type: For javascript tiddlers, specifies what kind of module it is
|
||||||
name: The human readable name associated with a plugin tiddler
|
name: The human readable name associated with a plugin tiddler
|
||||||
|
parent-plugin: For a plugin, specifies which plugin of which it is a sub-plugin
|
||||||
plugin-priority: A numerical value indicating the priority of a plugin tiddler
|
plugin-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
|
||||||
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
|
||||||
subtitle: The subtitle text for a wizard
|
subtitle: The subtitle text for a modal
|
||||||
tags: A list of tags associated with a tiddler
|
tags: A list of tags associated with a tiddler
|
||||||
text: The body text of a tiddler
|
text: The body text of a tiddler
|
||||||
throttle.refresh: If present, throttles refreshes of this tiddler
|
throttle.refresh: If present, throttles refreshes of this tiddler
|
||||||
|
|||||||
18
core/language/en-GB/Help/commands.tid
Normal file
18
core/language/en-GB/Help/commands.tid
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
title: $:/language/Help/commands
|
||||||
|
description: Run commands returned from a filter
|
||||||
|
|
||||||
|
Sequentially run the command tokens returned from a filter
|
||||||
|
|
||||||
|
```
|
||||||
|
--commands <filter>
|
||||||
|
```
|
||||||
|
|
||||||
|
Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
--commands "[enlist{$:/build-commands-as-text}]"
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
--commands "[{$:/build-commands-as-json}jsonindexes[]] :map[{$:/build-commands-as-json}jsonget<currentTiddler>]"
|
||||||
|
```
|
||||||
@@ -40,6 +40,7 @@ Error/RetrievingSkinny: Error retrieving skinny tiddler list
|
|||||||
Error/SavingToTWEdit: Error saving to TWEdit
|
Error/SavingToTWEdit: Error saving to TWEdit
|
||||||
Error/WhileSaving: Error while saving
|
Error/WhileSaving: Error while saving
|
||||||
Error/XMLHttpRequest: XMLHttpRequest error code
|
Error/XMLHttpRequest: XMLHttpRequest error code
|
||||||
|
Error/ZoominTextNode: Story View Error: It appears you tried to interact with a tiddler that displays in a custom container. This is most likely caused by using `$:/tags/StoryTiddlerTemplateFilter` with a template that contains text or whitespace at the start. Please use the pragma `\whitespace trim` and ensure the whole contents of the tiddler is wrapped in a single HTML element. The text that caused this issue:
|
||||||
InternalJavaScriptError/Title: Internal JavaScript Error
|
InternalJavaScriptError/Title: Internal JavaScript Error
|
||||||
InternalJavaScriptError/Hint: Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser
|
InternalJavaScriptError/Hint: Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser
|
||||||
LayoutSwitcher/Description: Open the layout switcher
|
LayoutSwitcher/Description: Open the layout switcher
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
title: $:/language/Modals/SaveInstructions
|
|
||||||
subtitle: Save your work
|
|
||||||
footer: <$button message="tm-close-tiddler">Close</$button>
|
|
||||||
help: https://tiddlywiki.com/static/SavingChanges.html
|
|
||||||
|
|
||||||
Your changes to this wiki need to be saved as a ~TiddlyWiki HTML file.
|
|
||||||
|
|
||||||
!!! Desktop browsers
|
|
||||||
|
|
||||||
# Select ''Save As'' from the ''File'' menu
|
|
||||||
# Choose a filename and location
|
|
||||||
#* Some browsers also require you to explicitly specify the file saving format as ''Webpage, HTML only'' or similar
|
|
||||||
# Close this tab
|
|
||||||
|
|
||||||
!!! Smartphone browsers
|
|
||||||
|
|
||||||
# Create a bookmark to this page
|
|
||||||
#* If you've got iCloud or Google Sync set up then the bookmark will automatically sync to your desktop where you can open it and save it as above
|
|
||||||
# Close this tab
|
|
||||||
|
|
||||||
//If you open the bookmark again in Mobile Safari you will see this message again. If you want to go ahead and use the file, just click the ''close'' button below//
|
|
||||||
42
core/modules/commands/commands.js
Normal file
42
core/modules/commands/commands.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/commands/commands.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: command
|
||||||
|
|
||||||
|
Runs the commands returned from a filter
|
||||||
|
|
||||||
|
\*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
exports.info = {
|
||||||
|
name: "commands",
|
||||||
|
synchronous: true
|
||||||
|
};
|
||||||
|
|
||||||
|
var Command = function(params, commander) {
|
||||||
|
this.params = params;
|
||||||
|
this.commander = commander;
|
||||||
|
};
|
||||||
|
|
||||||
|
Command.prototype.execute = function() {
|
||||||
|
// Parse the filter
|
||||||
|
var filter = this.params[0];
|
||||||
|
if(!filter) {
|
||||||
|
return "No filter specified";
|
||||||
|
}
|
||||||
|
var commands = this.commander.wiki.filterTiddlers(filter)
|
||||||
|
if(commands.length === 0) {
|
||||||
|
return "No tiddlers found for filter '" + filter + "'";
|
||||||
|
}
|
||||||
|
this.commander.addCommandTokens(commands);
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.Command = Command;
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -57,7 +57,7 @@ Command.prototype.execute = function() {
|
|||||||
exportPath = path.resolve(outputPath,macroPath + extension);
|
exportPath = path.resolve(outputPath,macroPath + extension);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var finalPath = exportPath || path.resolve(pathname,encodeURIComponent(title) + extension);
|
var finalPath = exportPath || path.resolve(pathname,$tw.utils.encodeURIComponentExtended(title) + extension);
|
||||||
$tw.utils.createFileDirectories(finalPath);
|
$tw.utils.createFileDirectories(finalPath);
|
||||||
fs.writeFileSync(finalPath,text,"utf8");
|
fs.writeFileSync(finalPath,text,"utf8");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ Command.prototype.execute = function() {
|
|||||||
$tw.utils.each(filteredPluginList,function(title) {
|
$tw.utils.each(filteredPluginList,function(title) {
|
||||||
var tiddler = containerData.tiddlers[title];
|
var tiddler = containerData.tiddlers[title];
|
||||||
// Save each JSON file and collect the skinny data
|
// Save each JSON file and collect the skinny data
|
||||||
var pathname = path.resolve(self.commander.outputPath,basepath + encodeURIComponent(title) + ".json");
|
var pathname = path.resolve(self.commander.outputPath,basepath + $tw.utils.encodeURIComponentExtended(title) + ".json");
|
||||||
$tw.utils.createFileDirectories(pathname);
|
$tw.utils.createFileDirectories(pathname);
|
||||||
fs.writeFileSync(pathname,JSON.stringify(tiddler),"utf8");
|
fs.writeFileSync(pathname,JSON.stringify(tiddler),"utf8");
|
||||||
// Collect the skinny list data
|
// Collect the skinny list data
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ Command.prototype.execute = function() {
|
|||||||
var tiddler = self.commander.wiki.getTiddler(title),
|
var tiddler = self.commander.wiki.getTiddler(title),
|
||||||
type = tiddler.fields.type || "text/vnd.tiddlywiki",
|
type = tiddler.fields.type || "text/vnd.tiddlywiki",
|
||||||
contentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: "utf8"},
|
contentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: "utf8"},
|
||||||
filename = path.resolve(pathname,encodeURIComponent(title));
|
filename = path.resolve(pathname,$tw.utils.encodeURIComponentExtended(title));
|
||||||
fs.writeFileSync(filename,tiddler.fields.text,contentTypeInfo.encoding);
|
fs.writeFileSync(filename,tiddler.fields.text,contentTypeInfo.encoding);
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ exports.textPrimitives.wikiLink = exports.textPrimitives.upperLetter + "+" +
|
|||||||
exports.textPrimitives.upperLetter +
|
exports.textPrimitives.upperLetter +
|
||||||
exports.textPrimitives.anyLetter + "*";
|
exports.textPrimitives.anyLetter + "*";
|
||||||
|
|
||||||
exports.htmlEntities = {quot:34, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 };
|
exports.htmlEntities = {quot:34, dollar:36, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 };
|
||||||
|
|
||||||
exports.htmlVoidElements = "area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",");
|
exports.htmlVoidElements = "area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",");
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ function FramedEngine(options) {
|
|||||||
$tw.utils.addEventListeners(this.domNode,[
|
$tw.utils.addEventListeners(this.domNode,[
|
||||||
{name: "click",handlerObject: this,handlerMethod: "handleClickEvent"},
|
{name: "click",handlerObject: this,handlerMethod: "handleClickEvent"},
|
||||||
{name: "input",handlerObject: this,handlerMethod: "handleInputEvent"},
|
{name: "input",handlerObject: this,handlerMethod: "handleInputEvent"},
|
||||||
{name: "keydown",handlerObject: this.widget,handlerMethod: "handleKeydownEvent"},
|
{name: "keydown",handlerObject: this,handlerMethod: "handleKeydownEvent"},
|
||||||
{name: "focus",handlerObject: this,handlerMethod: "handleFocusEvent"}
|
{name: "focus",handlerObject: this,handlerMethod: "handleFocusEvent"}
|
||||||
]);
|
]);
|
||||||
// Add drag and drop event listeners if fileDrop is enabled
|
// Add drag and drop event listeners if fileDrop is enabled
|
||||||
@@ -162,13 +162,13 @@ FramedEngine.prototype.fixHeight = function() {
|
|||||||
if(this.widget.editAutoHeight) {
|
if(this.widget.editAutoHeight) {
|
||||||
if(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {
|
if(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {
|
||||||
var newHeight = $tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);
|
var newHeight = $tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);
|
||||||
this.iframeNode.style.height = (newHeight + 14) + "px"; // +14 for the border on the textarea
|
this.iframeNode.style.height = newHeight + "px";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,"400px"),10);
|
var fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,"400px"),10);
|
||||||
fixedHeight = Math.max(fixedHeight,20);
|
fixedHeight = Math.max(fixedHeight,20);
|
||||||
this.domNode.style.height = fixedHeight + "px";
|
this.domNode.style.height = fixedHeight + "px";
|
||||||
this.iframeNode.style.height = (fixedHeight + 14) + "px";
|
this.iframeNode.style.height = fixedHeight + "px";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -177,9 +177,11 @@ FramedEngine.prototype.fixHeight = function() {
|
|||||||
Focus the engine node
|
Focus the engine node
|
||||||
*/
|
*/
|
||||||
FramedEngine.prototype.focus = function() {
|
FramedEngine.prototype.focus = function() {
|
||||||
if(this.domNode.focus && this.domNode.select) {
|
if(this.domNode.focus) {
|
||||||
this.domNode.focus();
|
this.domNode.focus();
|
||||||
this.domNode.select();
|
}
|
||||||
|
if(this.domNode.select) {
|
||||||
|
$tw.utils.setSelectionByPosition(this.domNode,this.widget.editFocusSelectFromStart,this.widget.editFocusSelectFromEnd);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -192,6 +194,17 @@ FramedEngine.prototype.handleFocusEvent = function(event) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Handle a keydown event
|
||||||
|
*/
|
||||||
|
FramedEngine.prototype.handleKeydownEvent = function(event) {
|
||||||
|
if ($tw.keyboardManager.handleKeydownEvent(event, {onlyPriority: true})) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.widget.handleKeydownEvent(event);
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Handle a click
|
Handle a click
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -119,10 +119,12 @@ SimpleEngine.prototype.fixHeight = function() {
|
|||||||
/*
|
/*
|
||||||
Focus the engine node
|
Focus the engine node
|
||||||
*/
|
*/
|
||||||
SimpleEngine.prototype.focus = function() {
|
SimpleEngine.prototype.focus = function() {
|
||||||
if(this.domNode.focus && this.domNode.select) {
|
if(this.domNode.focus) {
|
||||||
this.domNode.focus();
|
this.domNode.focus();
|
||||||
this.domNode.select();
|
}
|
||||||
|
if(this.domNode.select) {
|
||||||
|
$tw.utils.setSelectionByPosition(this.domNode,this.widget.editFocusSelectFromStart,this.widget.editFocusSelectFromEnd);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -180,6 +180,8 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
|||||||
this.editMinHeight = this.getAttribute("minHeight",DEFAULT_MIN_TEXT_AREA_HEIGHT);
|
this.editMinHeight = this.getAttribute("minHeight",DEFAULT_MIN_TEXT_AREA_HEIGHT);
|
||||||
this.editFocusPopup = this.getAttribute("focusPopup");
|
this.editFocusPopup = this.getAttribute("focusPopup");
|
||||||
this.editFocus = this.getAttribute("focus");
|
this.editFocus = this.getAttribute("focus");
|
||||||
|
this.editFocusSelectFromStart = $tw.utils.parseNumber(this.getAttribute("focusSelectFromStart","0"));
|
||||||
|
this.editFocusSelectFromEnd = $tw.utils.parseNumber(this.getAttribute("focusSelectFromEnd","0"));
|
||||||
this.editTabIndex = this.getAttribute("tabindex");
|
this.editTabIndex = this.getAttribute("tabindex");
|
||||||
this.editCancelPopups = this.getAttribute("cancelPopups","") === "yes";
|
this.editCancelPopups = this.getAttribute("cancelPopups","") === "yes";
|
||||||
this.editInputActions = this.getAttribute("inputActions");
|
this.editInputActions = this.getAttribute("inputActions");
|
||||||
@@ -218,7 +220,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
|||||||
EditTextWidget.prototype.refresh = function(changedTiddlers) {
|
EditTextWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
var changedAttributes = this.computeAttributes();
|
var changedAttributes = this.computeAttributes();
|
||||||
// Completely rerender if any of our attributes have changed
|
// Completely rerender if any of our attributes have changed
|
||||||
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedAttributes.disabled || changedAttributes.fileDrop) {
|
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedTiddlers["$:/palette"] || changedAttributes.disabled || changedAttributes.fileDrop) {
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
} else if (changedTiddlers[this.editRefreshTitle]) {
|
} else if (changedTiddlers[this.editRefreshTitle]) {
|
||||||
@@ -298,7 +300,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
|||||||
Propogate keydown events to our container for the keyboard widgets benefit
|
Propogate keydown events to our container for the keyboard widgets benefit
|
||||||
*/
|
*/
|
||||||
EditTextWidget.prototype.propogateKeydownEvent = function(event) {
|
EditTextWidget.prototype.propogateKeydownEvent = function(event) {
|
||||||
var newEvent = this.cloneEvent(event,["keyCode","which","metaKey","ctrlKey","altKey","shiftKey"]);
|
var newEvent = this.cloneEvent(event,["keyCode","code","which","key","metaKey","ctrlKey","altKey","shiftKey"]);
|
||||||
return !this.parentDomNode.dispatchEvent(newEvent);
|
return !this.parentDomNode.dispatchEvent(newEvent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -25,20 +25,10 @@ exports.cascade = function(operationSubFunction,options) {
|
|||||||
if(!filterFnList[index]) {
|
if(!filterFnList[index]) {
|
||||||
filterFnList[index] = options.wiki.compileFilter(filter);
|
filterFnList[index] = options.wiki.compileFilter(filter);
|
||||||
}
|
}
|
||||||
var output = filterFnList[index](options.wiki.makeTiddlerIterator([title]),{
|
var output = filterFnList[index](options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name,opts) {
|
"currentTiddler": "" + title,
|
||||||
opts = opts || {};
|
"..currentTiddler": widget.getVariable("currentTiddler","")
|
||||||
opts.variables = {
|
}));
|
||||||
"currentTiddler": "" + title,
|
|
||||||
"..currentTiddler": widget.getVariable("currentTiddler")
|
|
||||||
};
|
|
||||||
if(name in opts.variables) {
|
|
||||||
return opts.variables[name];
|
|
||||||
} else {
|
|
||||||
return widget.getVariable(name,opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(output.length !== 0) {
|
if(output.length !== 0) {
|
||||||
result = output[0];
|
result = output[0];
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -19,23 +19,13 @@ exports.filter = function(operationSubFunction,options) {
|
|||||||
var resultsToRemove = [],
|
var resultsToRemove = [],
|
||||||
index = 0;
|
index = 0;
|
||||||
results.each(function(title) {
|
results.each(function(title) {
|
||||||
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name,opts) {
|
"currentTiddler": "" + title,
|
||||||
opts = opts || {};
|
"..currentTiddler": widget.getVariable("currentTiddler",""),
|
||||||
opts.variables = {
|
"index": "" + index,
|
||||||
"currentTiddler": "" + title,
|
"revIndex": "" + (results.length - 1 - index),
|
||||||
"..currentTiddler": widget.getVariable("currentTiddler"),
|
"length": "" + results.length
|
||||||
"index": "" + index,
|
}));
|
||||||
"revIndex": "" + (results.length - 1 - index),
|
|
||||||
"length": "" + results.length
|
|
||||||
};
|
|
||||||
if(name in opts.variables) {
|
|
||||||
return opts.variables[name];
|
|
||||||
} else {
|
|
||||||
return widget.getVariable(name,opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(filtered.length === 0) {
|
if(filtered.length === 0) {
|
||||||
resultsToRemove.push(title);
|
resultsToRemove.push(title);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,23 +21,13 @@ exports.map = function(operationSubFunction,options) {
|
|||||||
flatten = (suffixes[0] && suffixes[0][0] === "flat") ? true : false;
|
flatten = (suffixes[0] && suffixes[0][0] === "flat") ? true : false;
|
||||||
results.clear();
|
results.clear();
|
||||||
$tw.utils.each(inputTitles,function(title) {
|
$tw.utils.each(inputTitles,function(title) {
|
||||||
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name,opts) {
|
"currentTiddler": "" + title,
|
||||||
opts = opts || {};
|
"..currentTiddler": widget.getVariable("currentTiddler",""),
|
||||||
opts.variables = {
|
"index": "" + index,
|
||||||
"currentTiddler": "" + title,
|
"revIndex": "" + (inputTitles.length - 1 - index),
|
||||||
"..currentTiddler": widget.getVariable("currentTiddler"),
|
"length": "" + inputTitles.length
|
||||||
"index": "" + index,
|
}));
|
||||||
"revIndex": "" + (inputTitles.length - 1 - index),
|
|
||||||
"length": "" + inputTitles.length
|
|
||||||
};
|
|
||||||
if(name in opts.variables) {
|
|
||||||
return opts.variables[name];
|
|
||||||
} else {
|
|
||||||
return widget.getVariable(name,opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(filtered.length && flatten) {
|
if(filtered.length && flatten) {
|
||||||
$tw.utils.each(filtered,function(value) {
|
$tw.utils.each(filtered,function(value) {
|
||||||
results.push(value);
|
results.push(value);
|
||||||
|
|||||||
@@ -18,24 +18,14 @@ exports.reduce = function(operationSubFunction,options) {
|
|||||||
var accumulator = "",
|
var accumulator = "",
|
||||||
index = 0;
|
index = 0;
|
||||||
results.each(function(title) {
|
results.each(function(title) {
|
||||||
var list = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
var list = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name,opts) {
|
"currentTiddler": "" + title,
|
||||||
opts = opts || {};
|
"..currentTiddler": widget.getVariable("currentTiddler"),
|
||||||
opts.variables = {
|
"index": "" + index,
|
||||||
"currentTiddler": "" + title,
|
"revIndex": "" + (results.length - 1 - index),
|
||||||
"..currentTiddler": widget.getVariable("currentTiddler"),
|
"length": "" + results.length,
|
||||||
"index": "" + index,
|
"accumulator": "" + accumulator
|
||||||
"revIndex": "" + (results.length - 1 - index),
|
}));
|
||||||
"length": "" + results.length,
|
|
||||||
"accumulator": "" + accumulator
|
|
||||||
};
|
|
||||||
if(name in opts.variables) {
|
|
||||||
return opts.variables[name];
|
|
||||||
} else {
|
|
||||||
return widget.getVariable(name,opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(list.length > 0) {
|
if(list.length > 0) {
|
||||||
accumulator = "" + list[0];
|
accumulator = "" + list[0];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,20 +25,10 @@ exports.sort = function(operationSubFunction,options) {
|
|||||||
indexes = new Array(inputTitles.length),
|
indexes = new Array(inputTitles.length),
|
||||||
compareFn;
|
compareFn;
|
||||||
results.each(function(title) {
|
results.each(function(title) {
|
||||||
var key = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
var key = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name,opts) {
|
"currentTiddler": "" + title,
|
||||||
opts = opts || {};
|
"..currentTiddler": widget.getVariable("currentTiddler")
|
||||||
opts.variables = {
|
}));
|
||||||
"currentTiddler": "" + title,
|
|
||||||
"..currentTiddler": widget.getVariable("currentTiddler")
|
|
||||||
};
|
|
||||||
if(name in opts.variables) {
|
|
||||||
return opts.variables[name];
|
|
||||||
} else {
|
|
||||||
return widget.getVariable(name,opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
sortKeys.push(key[0] || "");
|
sortKeys.push(key[0] || "");
|
||||||
});
|
});
|
||||||
results.clear();
|
results.clear();
|
||||||
|
|||||||
@@ -255,19 +255,21 @@ exports.compileFilter = function(filterString) {
|
|||||||
var operands = [],
|
var operands = [],
|
||||||
operatorFunction;
|
operatorFunction;
|
||||||
if(!operator.operator) {
|
if(!operator.operator) {
|
||||||
|
// Use the "title" operator if no operator is specified
|
||||||
operatorFunction = filterOperators.title;
|
operatorFunction = filterOperators.title;
|
||||||
} else if(!filterOperators[operator.operator]) {
|
} else if(!filterOperators[operator.operator]) {
|
||||||
operatorFunction = filterOperators.field;
|
// Unknown operators treated as "[unknown]" - at run time we can distinguish between a custom operator and falling back to the default "field" operator
|
||||||
|
operatorFunction = filterOperators["[unknown]"];
|
||||||
} else {
|
} else {
|
||||||
|
// Use the operator function
|
||||||
operatorFunction = filterOperators[operator.operator];
|
operatorFunction = filterOperators[operator.operator];
|
||||||
}
|
}
|
||||||
|
|
||||||
$tw.utils.each(operator.operands,function(operand) {
|
$tw.utils.each(operator.operands,function(operand) {
|
||||||
if(operand.indirect) {
|
if(operand.indirect) {
|
||||||
operand.value = self.getTextReference(operand.text,"",currTiddlerTitle);
|
operand.value = self.getTextReference(operand.text,"",currTiddlerTitle);
|
||||||
} else if(operand.variable) {
|
} else if(operand.variable) {
|
||||||
var varTree = $tw.utils.parseFilterVariable(operand.text);
|
var varTree = $tw.utils.parseFilterVariable(operand.text);
|
||||||
operand.value = widget.getVariable(varTree.name,{params:varTree.params,defaultValue: ""});
|
operand.value = widget.evaluateVariable(varTree.name,{params: varTree.params, source: source})[0] || "";
|
||||||
} else {
|
} else {
|
||||||
operand.value = operand.text;
|
operand.value = operand.text;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,22 @@ Filter operator for applying decodeURIComponent() to each item.
|
|||||||
Export our filter functions
|
Export our filter functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
exports.decodebase64 = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
source(function(tiddler,title) {
|
||||||
|
results.push($tw.utils.base64Decode(title));
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.encodebase64 = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
source(function(tiddler,title) {
|
||||||
|
results.push($tw.utils.base64Encode(title));
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
exports.decodeuricomponent = function(source,operator,options) {
|
exports.decodeuricomponent = function(source,operator,options) {
|
||||||
var results = [];
|
var results = [];
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
@@ -27,7 +43,7 @@ exports.decodeuricomponent = function(source,operator,options) {
|
|||||||
exports.encodeuricomponent = function(source,operator,options) {
|
exports.encodeuricomponent = function(source,operator,options) {
|
||||||
var results = [];
|
var results = [];
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
results.push(encodeURIComponent(title));
|
results.push($tw.utils.encodeURIComponentExtended(title));
|
||||||
});
|
});
|
||||||
return results;
|
return results;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,18 +20,10 @@ exports.filter = function(source,operator,options) {
|
|||||||
results = [],
|
results = [],
|
||||||
target = operator.prefix !== "!";
|
target = operator.prefix !== "!";
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
var list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),{
|
var list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),options.widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name) {
|
"currentTiddler": "" + title,
|
||||||
switch(name) {
|
"..currentTiddler": options.widget.getVariable("currentTiddler","")
|
||||||
case "currentTiddler":
|
}));
|
||||||
return "" + title;
|
|
||||||
case "..currentTiddler":
|
|
||||||
return options.widget.getVariable("currentTiddler");
|
|
||||||
default:
|
|
||||||
return options.widget.getVariable(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if((list.length > 0) === target) {
|
if((list.length > 0) === target) {
|
||||||
results.push(title);
|
results.push(title);
|
||||||
}
|
}
|
||||||
|
|||||||
32
core/modules/filters/function.js
Normal file
32
core/modules/filters/function.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/function.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator returning those input titles that are returned from a function
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.function = function(source,operator,options) {
|
||||||
|
var functionName = operator.operands[0],
|
||||||
|
variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(functionName);
|
||||||
|
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
|
||||||
|
return options.widget.evaluateVariable(functionName,{params: operator.operands.slice(1), source: source});
|
||||||
|
}
|
||||||
|
// Return the input list if the function wasn't found
|
||||||
|
var results = [];
|
||||||
|
source(function(tiddler,title) {
|
||||||
|
results.push(title);
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -19,13 +19,13 @@ exports.variable = function(source,prefix,options) {
|
|||||||
var results = [];
|
var results = [];
|
||||||
if(prefix === "!") {
|
if(prefix === "!") {
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
if(!(title in options.widget.variables)) {
|
if(options.widget.getVariable(title) === undefined) {
|
||||||
results.push(title);
|
results.push(title);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
if(title in options.widget.variables) {
|
if(options.widget.getVariable(title) !== undefined) {
|
||||||
results.push(title);
|
results.push(title);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,9 +17,23 @@ exports["jsonget"] = function(source,operator,options) {
|
|||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
var data = $tw.utils.parseJSONSafe(title,title);
|
var data = $tw.utils.parseJSONSafe(title,title);
|
||||||
if(data) {
|
if(data) {
|
||||||
var item = getDataItemValueAsString(data,operator.operands);
|
var items = getDataItemValueAsStrings(data,operator.operands);
|
||||||
|
if(items !== undefined) {
|
||||||
|
results.push.apply(results,items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports["jsonextract"] = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
source(function(tiddler,title) {
|
||||||
|
var data = $tw.utils.parseJSONSafe(title,title);
|
||||||
|
if(data) {
|
||||||
|
var item = getDataItem(data,operator.operands);
|
||||||
if(item !== undefined) {
|
if(item !== undefined) {
|
||||||
results.push(item);
|
results.push(JSON.stringify(item));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -31,9 +45,9 @@ exports["jsonindexes"] = function(source,operator,options) {
|
|||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
var data = $tw.utils.parseJSONSafe(title,title);
|
var data = $tw.utils.parseJSONSafe(title,title);
|
||||||
if(data) {
|
if(data) {
|
||||||
var item = getDataItemKeysAsStrings(data,operator.operands);
|
var items = getDataItemKeysAsStrings(data,operator.operands);
|
||||||
if(item !== undefined) {
|
if(items !== undefined) {
|
||||||
results.push.apply(results,item);
|
results.push.apply(results,items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -57,11 +71,11 @@ exports["jsontype"] = function(source,operator,options) {
|
|||||||
/*
|
/*
|
||||||
Given a JSON data structure and an array of index strings, return an array of the string representation of the values at the end of the index chain, or "undefined" if any of the index strings are invalid
|
Given a JSON data structure and an array of index strings, return an array of the string representation of the values at the end of the index chain, or "undefined" if any of the index strings are invalid
|
||||||
*/
|
*/
|
||||||
function getDataItemValueAsString(data,indexes) {
|
function getDataItemValueAsStrings(data,indexes) {
|
||||||
// Get the item
|
// Get the item
|
||||||
var item = getDataItem(data,indexes);
|
var item = getDataItem(data,indexes);
|
||||||
// Return the item as a string
|
// Return the item as a string list
|
||||||
return convertDataItemValueToString(item);
|
return convertDataItemValueToStrings(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -77,15 +91,34 @@ function getDataItemKeysAsStrings(data,indexes) {
|
|||||||
/*
|
/*
|
||||||
Return an array of the string representation of the values of a data item, or "undefined" if the item is undefined
|
Return an array of the string representation of the values of a data item, or "undefined" if the item is undefined
|
||||||
*/
|
*/
|
||||||
function convertDataItemValueToString(item) {
|
function convertDataItemValueToStrings(item) {
|
||||||
// Return the item as a string
|
// Return the item as a string
|
||||||
if(item === undefined) {
|
if(item === undefined) {
|
||||||
return item;
|
return undefined;
|
||||||
|
} else if(item === null) {
|
||||||
|
return ["null"]
|
||||||
|
} else if(typeof item === "object") {
|
||||||
|
var results = [],i,t;
|
||||||
|
if($tw.utils.isArray(item)) {
|
||||||
|
// Return all the items in arrays recursively
|
||||||
|
for(i=0; i<item.length; i++) {
|
||||||
|
t = convertDataItemValueToStrings(item[i])
|
||||||
|
if(t !== undefined) {
|
||||||
|
results.push.apply(results,t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Return all the values in objects recursively
|
||||||
|
$tw.utils.each(Object.keys(item).sort(),function(key) {
|
||||||
|
t = convertDataItemValueToStrings(item[key]);
|
||||||
|
if(t !== undefined) {
|
||||||
|
results.push.apply(results,t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
if(typeof item === "object") {
|
return [item.toString()];
|
||||||
return JSON.stringify(item);
|
|
||||||
}
|
|
||||||
return item.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -143,7 +176,11 @@ function getDataItem(data,indexes) {
|
|||||||
var item = data;
|
var item = data;
|
||||||
for(var i=0; i<indexes.length; i++) {
|
for(var i=0; i<indexes.length; i++) {
|
||||||
if(item !== undefined) {
|
if(item !== undefined) {
|
||||||
item = item[indexes[i]];
|
if(item !== null && ["number","string","boolean"].indexOf(typeof item) === -1) {
|
||||||
|
item = item[indexes[i]];
|
||||||
|
} else {
|
||||||
|
item = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
|
|||||||
@@ -26,26 +26,14 @@ exports.reduce = function(source,operator,options) {
|
|||||||
accumulator = operator.operands[1] || "";
|
accumulator = operator.operands[1] || "";
|
||||||
for(var index=0; index<results.length; index++) {
|
for(var index=0; index<results.length; index++) {
|
||||||
var title = results[index],
|
var title = results[index],
|
||||||
list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),{
|
list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),options.widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name) {
|
"currentTiddler": "" + title,
|
||||||
switch(name) {
|
"..currentTiddler": options.widget.getVariable("currentTiddler"),
|
||||||
case "currentTiddler":
|
"accumulator": "" + accumulator,
|
||||||
return "" + title;
|
"index": "" + index,
|
||||||
case "..currentTiddler":
|
"revIndex": "" + (results.length - 1 - index),
|
||||||
return options.widget.getVariable("currentTiddler");
|
"length": "" + results.length
|
||||||
case "accumulator":
|
}));
|
||||||
return "" + accumulator;
|
|
||||||
case "index":
|
|
||||||
return "" + index;
|
|
||||||
case "revIndex":
|
|
||||||
return "" + (results.length - 1 - index);
|
|
||||||
case "length":
|
|
||||||
return "" + results.length;
|
|
||||||
default:
|
|
||||||
return options.widget.getVariable(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(list.length > 0) {
|
if(list.length > 0) {
|
||||||
accumulator = "" + list[0];
|
accumulator = "" + list[0];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,18 +25,10 @@ exports.sortsub = function(source,operator,options) {
|
|||||||
inputTitles.push(title);
|
inputTitles.push(title);
|
||||||
var r = filterFn.call(options.wiki,function(iterator) {
|
var r = filterFn.call(options.wiki,function(iterator) {
|
||||||
iterator(options.wiki.getTiddler(title),title);
|
iterator(options.wiki.getTiddler(title),title);
|
||||||
},{
|
},options.widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name) {
|
"currentTiddler": "" + title,
|
||||||
switch(name) {
|
"..currentTiddler": options.widget.getVariable("currentTiddler")
|
||||||
case "currentTiddler":
|
}));
|
||||||
return "" + title;
|
|
||||||
case "..currentTiddler":
|
|
||||||
return options.widget.getVariable("currentTiddler");
|
|
||||||
default:
|
|
||||||
return options.widget.getVariable(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
sortKeys.push(r[0] || "");
|
sortKeys.push(r[0] || "");
|
||||||
});
|
});
|
||||||
// Rather than sorting the titles array, we'll sort the indexes so that we can consult both arrays
|
// Rather than sorting the titles array, we'll sort the indexes so that we can consult both arrays
|
||||||
|
|||||||
@@ -74,6 +74,113 @@ exports.join = makeStringReducingOperator(
|
|||||||
},null
|
},null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var dmp = require("$:/core/modules/utils/diff-match-patch/diff_match_patch.js");
|
||||||
|
|
||||||
|
exports.levenshtein = makeStringBinaryOperator(
|
||||||
|
function(a,b) {
|
||||||
|
var dmpObject = new dmp.diff_match_patch(),
|
||||||
|
diffs = dmpObject.diff_main(a,b);
|
||||||
|
return [dmpObject.diff_levenshtein(diffs) + ""];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// these two functions are adapted from https://github.com/google/diff-match-patch/wiki/Line-or-Word-Diffs
|
||||||
|
function diffLineWordMode(text1,text2,mode) {
|
||||||
|
var dmpObject = new dmp.diff_match_patch();
|
||||||
|
var a = diffPartsToChars(text1,text2,mode);
|
||||||
|
var lineText1 = a.chars1;
|
||||||
|
var lineText2 = a.chars2;
|
||||||
|
var lineArray = a.lineArray;
|
||||||
|
var diffs = dmpObject.diff_main(lineText1,lineText2,false);
|
||||||
|
dmpObject.diff_charsToLines_(diffs,lineArray);
|
||||||
|
return diffs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function diffPartsToChars(text1,text2,mode) {
|
||||||
|
var lineArray = [];
|
||||||
|
var lineHash = {};
|
||||||
|
lineArray[0] = '';
|
||||||
|
|
||||||
|
function diff_linesToPartsMunge_(text,mode) {
|
||||||
|
var chars = '';
|
||||||
|
var lineStart = 0;
|
||||||
|
var lineEnd = -1;
|
||||||
|
var lineArrayLength = lineArray.length,
|
||||||
|
regexpResult;
|
||||||
|
var searchRegexp = /\W+/g;
|
||||||
|
while(lineEnd < text.length - 1) {
|
||||||
|
if(mode === "words") {
|
||||||
|
regexpResult = searchRegexp.exec(text);
|
||||||
|
lineEnd = searchRegexp.lastIndex;
|
||||||
|
if(regexpResult === null) {
|
||||||
|
lineEnd = text.length;
|
||||||
|
}
|
||||||
|
lineEnd = --lineEnd;
|
||||||
|
} else {
|
||||||
|
lineEnd = text.indexOf('\n', lineStart);
|
||||||
|
if(lineEnd == -1) {
|
||||||
|
lineEnd = text.length - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var line = text.substring(lineStart, lineEnd + 1);
|
||||||
|
|
||||||
|
if(lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : (lineHash[line] !== undefined)) {
|
||||||
|
chars += String.fromCharCode(lineHash[line]);
|
||||||
|
} else {
|
||||||
|
if (lineArrayLength == maxLines) {
|
||||||
|
line = text.substring(lineStart);
|
||||||
|
lineEnd = text.length;
|
||||||
|
}
|
||||||
|
chars += String.fromCharCode(lineArrayLength);
|
||||||
|
lineHash[line] = lineArrayLength;
|
||||||
|
lineArray[lineArrayLength++] = line;
|
||||||
|
}
|
||||||
|
lineStart = lineEnd + 1;
|
||||||
|
}
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
var maxLines = 40000;
|
||||||
|
var chars1 = diff_linesToPartsMunge_(text1,mode);
|
||||||
|
maxLines = 65535;
|
||||||
|
var chars2 = diff_linesToPartsMunge_(text2,mode);
|
||||||
|
return {chars1: chars1, chars2: chars2, lineArray: lineArray};
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.makepatches = function(source,operator,options) {
|
||||||
|
var dmpObject = new dmp.diff_match_patch(),
|
||||||
|
suffix = operator.suffix || "",
|
||||||
|
result = [];
|
||||||
|
|
||||||
|
source(function(tiddler,title) {
|
||||||
|
var diffs, patches;
|
||||||
|
if(suffix === "lines" || suffix === "words") {
|
||||||
|
diffs = diffLineWordMode(title,operator.operand,suffix);
|
||||||
|
patches = dmpObject.patch_make(title,diffs);
|
||||||
|
} else {
|
||||||
|
patches = dmpObject.patch_make(title,operator.operand);
|
||||||
|
}
|
||||||
|
Array.prototype.push.apply(result,[dmpObject.patch_toText(patches)]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.applypatches = makeStringBinaryOperator(
|
||||||
|
function(a,b) {
|
||||||
|
var dmpObject = new dmp.diff_match_patch(),
|
||||||
|
patches;
|
||||||
|
try {
|
||||||
|
patches = dmpObject.patch_fromText(b);
|
||||||
|
} catch(e) {
|
||||||
|
}
|
||||||
|
if(patches) {
|
||||||
|
return [dmpObject.patch_apply(patches,a)[0]];
|
||||||
|
} else {
|
||||||
|
return [a];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
function makeStringBinaryOperator(fnCalc) {
|
function makeStringBinaryOperator(fnCalc) {
|
||||||
return function(source,operator,options) {
|
return function(source,operator,options) {
|
||||||
var result = [];
|
var result = [];
|
||||||
@@ -184,4 +291,4 @@ exports.charcode = function(source,operator,options) {
|
|||||||
return [chars.join("")];
|
return [chars.join("")];
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
45
core/modules/filters/unknown.js
Normal file
45
core/modules/filters/unknown.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/unknown.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for handling unknown filter operators.
|
||||||
|
|
||||||
|
Not intended to be used directly by end users, hence the square brackets around the name.
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var fieldFilterOperatorFn = require("$:/core/modules/filters/field.js").field;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports["[unknown]"] = function(source,operator,options) {
|
||||||
|
// Check for a user defined filter operator
|
||||||
|
if(operator.operator.charAt(0) === ".") {
|
||||||
|
var variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(operator.operator);
|
||||||
|
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
|
||||||
|
var list = options.widget.evaluateVariable(operator.operator,{params: operator.operands, source: source});
|
||||||
|
if(operator.prefix === "!") {
|
||||||
|
var results = [];
|
||||||
|
source(function(tiddler,title) {
|
||||||
|
if(list.indexOf(title) === -1) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
} else {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Otherwise, use the "field" operator
|
||||||
|
return fieldFilterOperatorFn(source,operator,options);
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -16,9 +16,15 @@ Filter operator for returning the names of the active variables
|
|||||||
Export our filter function
|
Export our filter function
|
||||||
*/
|
*/
|
||||||
exports.variables = function(source,operator,options) {
|
exports.variables = function(source,operator,options) {
|
||||||
var names = [];
|
var names = [],
|
||||||
for(var variable in options.widget.variables) {
|
widget = options.widget;
|
||||||
names.push(variable);
|
while(widget && !widget.hasOwnProperty("variables")) {
|
||||||
|
widget = widget.parentWidget;
|
||||||
|
}
|
||||||
|
if(widget && widget.variables) {
|
||||||
|
for(var variable in widget.variables) {
|
||||||
|
names.push(variable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return names.sort();
|
return names.sort();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,18 +32,18 @@ FieldIndexer.prototype.setMaxIndexedValueLength = function(length) {
|
|||||||
|
|
||||||
FieldIndexer.prototype.addIndexMethods = function() {
|
FieldIndexer.prototype.addIndexMethods = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
// get all tiddlers, including those overwrite shadow tiddlers
|
||||||
this.wiki.each.byField = function(name,value) {
|
this.wiki.each.byField = function(name,value) {
|
||||||
var titles = self.wiki.allTitles(),
|
var lookup = self.lookup(name,value);
|
||||||
lookup = self.lookup(name,value);
|
|
||||||
return lookup && lookup.filter(function(title) {
|
return lookup && lookup.filter(function(title) {
|
||||||
return titles.indexOf(title) !== -1;
|
return self.wiki.tiddlerExists(title)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
// get shadow tiddlers, including shadow tiddlers that is overwritten
|
||||||
this.wiki.eachShadow.byField = function(name,value) {
|
this.wiki.eachShadow.byField = function(name,value) {
|
||||||
var titles = self.wiki.allShadowTitles(),
|
var lookup = self.lookup(name,value);
|
||||||
lookup = self.lookup(name,value);
|
|
||||||
return lookup && lookup.filter(function(title) {
|
return lookup && lookup.filter(function(title) {
|
||||||
return titles.indexOf(title) !== -1;
|
return self.wiki.isShadowTiddler(title)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
this.wiki.eachTiddlerPlusShadows.byField = function(name,value) {
|
this.wiki.eachTiddlerPlusShadows.byField = function(name,value) {
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ function KeyboardManager(options) {
|
|||||||
this.shortcutKeysList = [], // Stores the shortcut-key descriptors
|
this.shortcutKeysList = [], // Stores the shortcut-key descriptors
|
||||||
this.shortcutActionList = [], // Stores the corresponding action strings
|
this.shortcutActionList = [], // Stores the corresponding action strings
|
||||||
this.shortcutParsedList = []; // Stores the parsed key descriptors
|
this.shortcutParsedList = []; // Stores the parsed key descriptors
|
||||||
|
this.shortcutPriorityList = []; // Stores the parsed shortcut priority
|
||||||
this.lookupNames = ["shortcuts"];
|
this.lookupNames = ["shortcuts"];
|
||||||
this.lookupNames.push($tw.platform.isMac ? "shortcuts-mac" : "shortcuts-not-mac")
|
this.lookupNames.push($tw.platform.isMac ? "shortcuts-mac" : "shortcuts-not-mac")
|
||||||
this.lookupNames.push($tw.platform.isWindows ? "shortcuts-windows" : "shortcuts-not-windows");
|
this.lookupNames.push($tw.platform.isWindows ? "shortcuts-windows" : "shortcuts-not-windows");
|
||||||
@@ -318,12 +319,23 @@ KeyboardManager.prototype.updateShortcutLists = function(tiddlerList) {
|
|||||||
this.shortcutKeysList[i] = tiddlerFields.key !== undefined ? tiddlerFields.key : undefined;
|
this.shortcutKeysList[i] = tiddlerFields.key !== undefined ? tiddlerFields.key : undefined;
|
||||||
this.shortcutActionList[i] = tiddlerFields.text;
|
this.shortcutActionList[i] = tiddlerFields.text;
|
||||||
this.shortcutParsedList[i] = this.shortcutKeysList[i] !== undefined ? this.parseKeyDescriptors(this.shortcutKeysList[i]) : undefined;
|
this.shortcutParsedList[i] = this.shortcutKeysList[i] !== undefined ? this.parseKeyDescriptors(this.shortcutKeysList[i]) : undefined;
|
||||||
|
this.shortcutPriorityList[i] = tiddlerFields.priority === "yes" ? true : false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
KeyboardManager.prototype.handleKeydownEvent = function(event) {
|
/*
|
||||||
|
event: the keyboard event object
|
||||||
|
options:
|
||||||
|
onlyPriority: true if only priority global shortcuts should be invoked
|
||||||
|
*/
|
||||||
|
KeyboardManager.prototype.handleKeydownEvent = function(event, options) {
|
||||||
|
options = options || {};
|
||||||
var key, action;
|
var key, action;
|
||||||
for(var i=0; i<this.shortcutTiddlers.length; i++) {
|
for(var i=0; i<this.shortcutTiddlers.length; i++) {
|
||||||
|
if(options.onlyPriority && this.shortcutPriorityList[i] !== true) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(this.shortcutParsedList[i] !== undefined && this.checkKeyDescriptors(event,this.shortcutParsedList[i])) {
|
if(this.shortcutParsedList[i] !== undefined && this.checkKeyDescriptors(event,this.shortcutParsedList[i])) {
|
||||||
key = this.shortcutParsedList[i];
|
key = this.shortcutParsedList[i];
|
||||||
action = this.shortcutActionList[i];
|
action = this.shortcutActionList[i];
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ var AudioParser = function(type,text,options) {
|
|||||||
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
||||||
}
|
}
|
||||||
this.tree = [element];
|
this.tree = [element];
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["audio/ogg"] = AudioParser;
|
exports["audio/ogg"] = AudioParser;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ var BinaryParser = function(type,text,options) {
|
|||||||
children: [{
|
children: [{
|
||||||
type: "transclude",
|
type: "transclude",
|
||||||
attributes: {
|
attributes: {
|
||||||
tiddler: {type: "string", value: BINARY_WARNING_MESSAGE}
|
"$tiddler": {type: "string", value: BINARY_WARNING_MESSAGE}
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
@@ -38,7 +38,7 @@ var BinaryParser = function(type,text,options) {
|
|||||||
children: [{
|
children: [{
|
||||||
type: "transclude",
|
type: "transclude",
|
||||||
attributes: {
|
attributes: {
|
||||||
tiddler: {type: "string", value: EXPORT_BUTTON_IMAGE}
|
"$tiddler": {type: "string", value: EXPORT_BUTTON_IMAGE}
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
@@ -64,6 +64,8 @@ var BinaryParser = function(type,text,options) {
|
|||||||
children: [warn, link]
|
children: [warn, link]
|
||||||
}
|
}
|
||||||
this.tree = [element];
|
this.tree = [element];
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["application/octet-stream"] = BinaryParser;
|
exports["application/octet-stream"] = BinaryParser;
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ The CSV text parser processes CSV files into a table wrapped in a scrollable wid
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var CsvParser = function(type,text,options) {
|
var CsvParser = function(type,text,options) {
|
||||||
|
// Special handler for tab-delimited files
|
||||||
|
if (type === 'text/tab-delimited-values' && !options.separator) {
|
||||||
|
options.separator = "\t";
|
||||||
|
}
|
||||||
|
|
||||||
// Table framework
|
// Table framework
|
||||||
this.tree = [{
|
this.tree = [{
|
||||||
"type": "scrollable", "children": [{
|
"type": "scrollable", "children": [{
|
||||||
@@ -24,30 +29,35 @@ var CsvParser = function(type,text,options) {
|
|||||||
}]
|
}]
|
||||||
}];
|
}];
|
||||||
// Split the text into lines
|
// Split the text into lines
|
||||||
var lines = text.split(/\r?\n/mg),
|
var lines = $tw.utils.parseCsvString(text, options),
|
||||||
tag = "th";
|
tag = "th";
|
||||||
|
var maxColumns = 0;
|
||||||
|
$tw.utils.each(lines, function(columns) {
|
||||||
|
maxColumns = Math.max(columns.length, maxColumns);
|
||||||
|
});
|
||||||
|
|
||||||
for(var line=0; line<lines.length; line++) {
|
for(var line=0; line<lines.length; line++) {
|
||||||
var lineText = lines[line];
|
var columns = lines[line];
|
||||||
if(lineText) {
|
var row = {
|
||||||
var row = {
|
"type": "element", "tag": "tr", "children": []
|
||||||
"type": "element", "tag": "tr", "children": []
|
};
|
||||||
};
|
for(var column=0; column<maxColumns; column++) {
|
||||||
var columns = lineText.split(",");
|
row.children.push({
|
||||||
for(var column=0; column<columns.length; column++) {
|
"type": "element", "tag": tag, "children": [{
|
||||||
row.children.push({
|
"type": "text",
|
||||||
"type": "element", "tag": tag, "children": [{
|
"text": columns[column] || ''
|
||||||
"type": "text",
|
}]
|
||||||
"text": columns[column]
|
});
|
||||||
}]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
tag = "td";
|
|
||||||
this.tree[0].children[0].children[0].children.push(row);
|
|
||||||
}
|
}
|
||||||
|
tag = "td";
|
||||||
|
this.tree[0].children[0].children[0].children.push(row);
|
||||||
}
|
}
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["text/csv"] = CsvParser;
|
exports["text/csv"] = CsvParser;
|
||||||
|
exports["text/tab-delimited-values"] = CsvParser;
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ var HtmlParser = function(type,text,options) {
|
|||||||
if($tw.wiki.getTiddlerText("$:/config/HtmlParser/DisableSandbox","no") !== "yes") {
|
if($tw.wiki.getTiddlerText("$:/config/HtmlParser/DisableSandbox","no") !== "yes") {
|
||||||
this.tree[0].attributes.sandbox = {type: "string", value: $tw.wiki.getTiddlerText("$:/config/HtmlParser/SandboxTokens","")};
|
this.tree[0].attributes.sandbox = {type: "string", value: $tw.wiki.getTiddlerText("$:/config/HtmlParser/SandboxTokens","")};
|
||||||
}
|
}
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["text/html"] = HtmlParser;
|
exports["text/html"] = HtmlParser;
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ var ImageParser = function(type,text,options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.tree = [element];
|
this.tree = [element];
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["image/svg+xml"] = ImageParser;
|
exports["image/svg+xml"] = ImageParser;
|
||||||
|
|||||||
@@ -123,6 +123,36 @@ exports.parseStringLiteral = function(source,pos) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns an array of {name:} with an optional "default" property. Options include:
|
||||||
|
requireParenthesis: require the parameter definition to be wrapped in parenthesis
|
||||||
|
*/
|
||||||
|
exports.parseParameterDefinition = function(paramString,options) {
|
||||||
|
options = options || {};
|
||||||
|
if(options.requireParenthesis) {
|
||||||
|
var parenMatch = /^\s*\((.*)\)\s*$/g.exec(paramString);
|
||||||
|
if(!parenMatch) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
paramString = parenMatch[1];
|
||||||
|
}
|
||||||
|
var params = [],
|
||||||
|
reParam = /\s*([^:),\s]+)(?:\s*:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|([^,"'\s]+)))?/mg,
|
||||||
|
paramMatch = reParam.exec(paramString);
|
||||||
|
while(paramMatch) {
|
||||||
|
// Save the parameter details
|
||||||
|
var paramInfo = {name: paramMatch[1]},
|
||||||
|
defaultValue = paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5];
|
||||||
|
if(defaultValue !== undefined) {
|
||||||
|
paramInfo["default"] = defaultValue;
|
||||||
|
}
|
||||||
|
params.push(paramInfo);
|
||||||
|
// Look for the next parameter
|
||||||
|
paramMatch = reParam.exec(paramString);
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
exports.parseMacroParameters = function(node,source,pos) {
|
exports.parseMacroParameters = function(node,source,pos) {
|
||||||
// Process parameters
|
// Process parameters
|
||||||
var parameter = $tw.utils.parseMacroParameter(source,pos);
|
var parameter = $tw.utils.parseMacroParameter(source,pos);
|
||||||
@@ -175,7 +205,36 @@ exports.parseMacroParameter = function(source,pos) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Look for a macro invocation. Returns null if not found, or {type: "macrocall", name:, parameters:, start:, end:}
|
Look for a macro invocation. Returns null if not found, or {type: "transclude", attributes:, start:, end:}
|
||||||
|
*/
|
||||||
|
exports.parseMacroInvocationAsTransclusion = function(source,pos) {
|
||||||
|
var node = $tw.utils.parseMacroInvocation(source,pos);
|
||||||
|
if(node) {
|
||||||
|
var positionalName = 0,
|
||||||
|
transclusion = {
|
||||||
|
type: "transclude",
|
||||||
|
start: node.start,
|
||||||
|
end: node.end
|
||||||
|
};
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(transclusion,"$variable",node.name);
|
||||||
|
$tw.utils.each(node.params,function(param) {
|
||||||
|
var name = param.name;
|
||||||
|
if(name) {
|
||||||
|
if(name.charAt(0) === "$") {
|
||||||
|
name = "$" + name;
|
||||||
|
}
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(transclusion,{name: name,type: "string", value: param.value, start: param.start, end: param.end});
|
||||||
|
} else {
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(transclusion,{name: (positionalName++) + "",type: "string", value: param.value, start: param.start, end: param.end});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return transclusion;
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Look for a macro invocation. Returns null if not found, or {type: "macrocall", name:, params:, start:, end:}
|
||||||
*/
|
*/
|
||||||
exports.parseMacroInvocation = function(source,pos) {
|
exports.parseMacroInvocation = function(source,pos) {
|
||||||
var node = {
|
var node = {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ The PDF parser embeds a PDF viewer
|
|||||||
var ImageParser = function(type,text,options) {
|
var ImageParser = function(type,text,options) {
|
||||||
var element = {
|
var element = {
|
||||||
type: "element",
|
type: "element",
|
||||||
tag: "embed",
|
tag: "iframe",
|
||||||
attributes: {}
|
attributes: {}
|
||||||
},
|
},
|
||||||
src;
|
src;
|
||||||
@@ -25,6 +25,8 @@ var ImageParser = function(type,text,options) {
|
|||||||
element.attributes.src = {type: "string", value: "data:application/pdf;base64," + text};
|
element.attributes.src = {type: "string", value: "data:application/pdf;base64," + text};
|
||||||
}
|
}
|
||||||
this.tree = [element];
|
this.tree = [element];
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["application/pdf"] = ImageParser;
|
exports["application/pdf"] = ImageParser;
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ var TextParser = function(type,text,options) {
|
|||||||
language: {type: "string", value: type}
|
language: {type: "string", value: type}
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["text/plain"] = TextParser;
|
exports["text/plain"] = TextParser;
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ var VideoParser = function(type,text,options) {
|
|||||||
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
||||||
}
|
}
|
||||||
this.tree = [element];
|
this.tree = [element];
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["video/ogg"] = VideoParser;
|
exports["video/ogg"] = VideoParser;
|
||||||
|
|||||||
97
core/modules/parsers/wikiparser/rules/fnprocdef.js
Normal file
97
core/modules/parsers/wikiparser/rules/fnprocdef.js
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/parsers/wikiparser/rules/fnprocdef.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: wikirule
|
||||||
|
|
||||||
|
Wiki pragma rule for function, procedure and widget definitions
|
||||||
|
|
||||||
|
```
|
||||||
|
\function name(param:defaultvalue,param2:defaultvalue)
|
||||||
|
definition text
|
||||||
|
\end
|
||||||
|
|
||||||
|
\procedure name(param:defaultvalue,param2:defaultvalue)
|
||||||
|
definition text
|
||||||
|
\end
|
||||||
|
|
||||||
|
\widget $mywidget(param:defaultvalue,param2:defaultvalue)
|
||||||
|
definition text
|
||||||
|
\end
|
||||||
|
```
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
exports.name = "fnprocdef";
|
||||||
|
exports.types = {pragma: true};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Instantiate parse rule
|
||||||
|
*/
|
||||||
|
exports.init = function(parser) {
|
||||||
|
this.parser = parser;
|
||||||
|
// Regexp to match
|
||||||
|
this.matchRegExp = /^\\(function|procedure|widget)\s+([^(\s]+)\((\s*([^)]*))?\)(\s*\r?\n)?/mg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse the most recent match
|
||||||
|
*/
|
||||||
|
exports.parse = function() {
|
||||||
|
// Move past the macro name and parameters
|
||||||
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
|
// Parse the parameters
|
||||||
|
var params = [];
|
||||||
|
if(this.match[3]) {
|
||||||
|
params = $tw.utils.parseParameterDefinition(this.match[4]);
|
||||||
|
}
|
||||||
|
// Is this a multiline definition?
|
||||||
|
var reEnd;
|
||||||
|
if(this.match[5]) {
|
||||||
|
// If so, the end of the body is marked with \end
|
||||||
|
reEnd = new RegExp("(\\r?\\n\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[2]) + ")?(?:$|\\r?\\n))","mg");
|
||||||
|
} else {
|
||||||
|
// Otherwise, the end of the definition is marked by the end of the line
|
||||||
|
reEnd = /($|\r?\n)/mg;
|
||||||
|
// Move past any whitespace
|
||||||
|
this.parser.pos = $tw.utils.skipWhiteSpace(this.parser.source,this.parser.pos);
|
||||||
|
}
|
||||||
|
// Find the end of the definition
|
||||||
|
reEnd.lastIndex = this.parser.pos;
|
||||||
|
var text,
|
||||||
|
endMatch = reEnd.exec(this.parser.source);
|
||||||
|
if(endMatch) {
|
||||||
|
text = this.parser.source.substring(this.parser.pos,endMatch.index);
|
||||||
|
this.parser.pos = endMatch.index + endMatch[0].length;
|
||||||
|
} else {
|
||||||
|
// We didn't find the end of the definition, so we'll make it blank
|
||||||
|
text = "";
|
||||||
|
}
|
||||||
|
// Save the macro definition
|
||||||
|
var parseTreeNodes = [{
|
||||||
|
type: "set",
|
||||||
|
attributes: {},
|
||||||
|
children: [],
|
||||||
|
params: params
|
||||||
|
}];
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"name",this.match[2]);
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"value",text);
|
||||||
|
if(this.match[1] === "function") {
|
||||||
|
parseTreeNodes[0].isFunctionDefinition = true;
|
||||||
|
} else if(this.match[1] === "procedure") {
|
||||||
|
parseTreeNodes[0].isProcedureDefinition = true;
|
||||||
|
} else if(this.match[1] === "widget") {
|
||||||
|
parseTreeNodes[0].isWidgetDefinition = true;
|
||||||
|
}
|
||||||
|
if(this.parser.configTrimWhiteSpace) {
|
||||||
|
parseTreeNodes[0].configTrimWhiteSpace = true;
|
||||||
|
}
|
||||||
|
return parseTreeNodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
@@ -93,9 +93,6 @@ exports.parseTag = function(source,pos,options) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
node.tag = token.match[1];
|
node.tag = token.match[1];
|
||||||
if(node.tag.slice(1).indexOf("$") !== -1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if(node.tag.charAt(0) === "$") {
|
if(node.tag.charAt(0) === "$") {
|
||||||
node.type = node.tag.substr(1);
|
node.type = node.tag.substr(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Instantiate parse rule
|
|||||||
exports.init = function(parser) {
|
exports.init = function(parser) {
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
// Regexp to match
|
// Regexp to match
|
||||||
this.matchRegExp = /^\\import[^\S\n]/mg;
|
this.matchRegExp = /\\import[^\S\n]/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ exports.findNextMatch = function(startPos) {
|
|||||||
var nextStart = startPos;
|
var nextStart = startPos;
|
||||||
// Try parsing at all possible macrocall openers until we match
|
// Try parsing at all possible macrocall openers until we match
|
||||||
while((nextStart = this.parser.source.indexOf("<<",nextStart)) >= 0) {
|
while((nextStart = this.parser.source.indexOf("<<",nextStart)) >= 0) {
|
||||||
var nextCall = $tw.utils.parseMacroInvocation(this.parser.source,nextStart);
|
var nextCall = $tw.utils.parseMacroInvocationAsTransclusion(this.parser.source,nextStart);
|
||||||
if(nextCall) {
|
if(nextCall) {
|
||||||
var c = this.parser.source.charAt(nextCall.end);
|
var c = this.parser.source.charAt(nextCall.end);
|
||||||
// Ensure EOL after parsed macro
|
// Ensure EOL after parsed macro
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ exports.findNextMatch = function(startPos) {
|
|||||||
var nextStart = startPos;
|
var nextStart = startPos;
|
||||||
// Try parsing at all possible macrocall openers until we match
|
// Try parsing at all possible macrocall openers until we match
|
||||||
while((nextStart = this.parser.source.indexOf("<<",nextStart)) >= 0) {
|
while((nextStart = this.parser.source.indexOf("<<",nextStart)) >= 0) {
|
||||||
this.nextCall = $tw.utils.parseMacroInvocation(this.parser.source,nextStart);
|
this.nextCall = $tw.utils.parseMacroInvocationAsTransclusion(this.parser.source,nextStart);
|
||||||
if(this.nextCall) {
|
if(this.nextCall) {
|
||||||
return nextStart;
|
return nextStart;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Instantiate parse rule
|
|||||||
exports.init = function(parser) {
|
exports.init = function(parser) {
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
// Regexp to match
|
// Regexp to match
|
||||||
this.matchRegExp = /^\\define\s+([^(\s]+)\(\s*([^)]*)\)(\s*\r?\n)?/mg;
|
this.matchRegExp = /\\define\s+([^(\s]+)\(\s*([^)]*)\)(\s*\r?\n)?/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -58,7 +58,7 @@ exports.parse = function() {
|
|||||||
var reEnd;
|
var reEnd;
|
||||||
if(this.match[3]) {
|
if(this.match[3]) {
|
||||||
// If so, the end of the body is marked with \end
|
// If so, the end of the body is marked with \end
|
||||||
reEnd = /(\r?\n\\end[^\S\n\r]*(?:$|\r?\n))/mg;
|
reEnd = new RegExp("(\\r?\\n[^\\S\\n\\r]*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[1]) + ")?(?:$|\\r?\\n))","mg");
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, the end of the definition is marked by the end of the line
|
// Otherwise, the end of the definition is marked by the end of the line
|
||||||
reEnd = /($|\r?\n)/mg;
|
reEnd = /($|\r?\n)/mg;
|
||||||
@@ -77,16 +77,16 @@ exports.parse = function() {
|
|||||||
text = "";
|
text = "";
|
||||||
}
|
}
|
||||||
// Save the macro definition
|
// Save the macro definition
|
||||||
return [{
|
var parseTreeNodes = [{
|
||||||
type: "set",
|
type: "set",
|
||||||
attributes: {
|
attributes: {},
|
||||||
name: {type: "string", value: this.match[1]},
|
|
||||||
value: {type: "string", value: text}
|
|
||||||
},
|
|
||||||
children: [],
|
children: [],
|
||||||
params: params,
|
params: params,
|
||||||
isMacroDefinition: true
|
isMacroDefinition: true
|
||||||
}];
|
}];
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"name",this.match[1]);
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"value",text);
|
||||||
|
return parseTreeNodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
60
core/modules/parsers/wikiparser/rules/parameters.js
Normal file
60
core/modules/parsers/wikiparser/rules/parameters.js
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/parsers/wikiparser/rules/parameters.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: wikirule
|
||||||
|
|
||||||
|
Wiki pragma rule for parameter definitions
|
||||||
|
|
||||||
|
```
|
||||||
|
\parameters(param:defaultvalue,param2:defaultvalue)
|
||||||
|
definition text
|
||||||
|
```
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
exports.name = "parameters";
|
||||||
|
exports.types = {pragma: true};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Instantiate parse rule
|
||||||
|
*/
|
||||||
|
exports.init = function(parser) {
|
||||||
|
this.parser = parser;
|
||||||
|
// Regexp to match
|
||||||
|
this.matchRegExp = /^\\parameters\s*\(([^)]*)\)\s*\r?\n/mg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse the most recent match
|
||||||
|
*/
|
||||||
|
exports.parse = function() {
|
||||||
|
// Move past the macro name and parameters
|
||||||
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
|
// Parse the parameters
|
||||||
|
var params = $tw.utils.parseParameterDefinition(this.match[1]);
|
||||||
|
var attributes = Object.create(null),
|
||||||
|
orderedAttributes = [];
|
||||||
|
$tw.utils.each(params,function(param) {
|
||||||
|
var name = param.name;
|
||||||
|
// Parameter names starting with dollar must be escaped to double dollars for the parameters widget
|
||||||
|
if(name.charAt(0) === "$") {
|
||||||
|
name = "$" + name;
|
||||||
|
}
|
||||||
|
var attribute = {name: name, type: "string", value: param["default"] || ""};
|
||||||
|
attributes[name] = attribute;
|
||||||
|
orderedAttributes.push(attribute);
|
||||||
|
});
|
||||||
|
// Save the macro definition
|
||||||
|
return [{
|
||||||
|
type: "parameters",
|
||||||
|
attributes: attributes,
|
||||||
|
orderedAttributes: orderedAttributes
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
68
core/modules/parsers/wikiparser/rules/parsermode.js
Normal file
68
core/modules/parsers/wikiparser/rules/parsermode.js
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/parsers/wikiparser/rules/parsermode.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: wikirule
|
||||||
|
|
||||||
|
Wiki pragma rule for parser mode specifications
|
||||||
|
|
||||||
|
```
|
||||||
|
\parsermode block
|
||||||
|
\parsermode inline
|
||||||
|
```
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
exports.name = "parsermode";
|
||||||
|
exports.types = {pragma: true};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Instantiate parse rule
|
||||||
|
*/
|
||||||
|
exports.init = function(parser) {
|
||||||
|
this.parser = parser;
|
||||||
|
// Regexp to match
|
||||||
|
this.matchRegExp = /\\parsermode[^\S\n]/mg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse the most recent match
|
||||||
|
*/
|
||||||
|
exports.parse = function() {
|
||||||
|
// Move past the pragma invocation
|
||||||
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
|
// Parse whitespace delimited tokens terminated by a line break
|
||||||
|
var reMatch = /[^\S\n]*(\S+)|(\r?\n)/mg,
|
||||||
|
parserMode = undefined;
|
||||||
|
reMatch.lastIndex = this.parser.pos;
|
||||||
|
var match = reMatch.exec(this.parser.source);
|
||||||
|
while(match && match.index === this.parser.pos) {
|
||||||
|
this.parser.pos = reMatch.lastIndex;
|
||||||
|
// Exit if we've got the line break
|
||||||
|
if(match[2]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Process the token
|
||||||
|
if(match[1]) {
|
||||||
|
parserMode = match[1];
|
||||||
|
}
|
||||||
|
// Match the next token
|
||||||
|
match = reMatch.exec(this.parser.source);
|
||||||
|
}
|
||||||
|
// Process the tokens
|
||||||
|
if(parserMode !== undefined) {
|
||||||
|
if(parserMode === "block") {
|
||||||
|
this.parser.parseAsInline = false;
|
||||||
|
} else if(parserMode === "inline") {
|
||||||
|
this.parser.parseAsInline = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// No parse tree nodes to return
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -26,7 +26,7 @@ Instantiate parse rule
|
|||||||
exports.init = function(parser) {
|
exports.init = function(parser) {
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
// Regexp to match
|
// Regexp to match
|
||||||
this.matchRegExp = /^\\rules[^\S\n]/mg;
|
this.matchRegExp = /\\rules[^\S\n]/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -41,9 +41,6 @@ exports.parse = function() {
|
|||||||
var node = {
|
var node = {
|
||||||
type: "element",
|
type: "element",
|
||||||
tag: "span",
|
tag: "span",
|
||||||
attributes: {
|
|
||||||
"class": {type: "string", value: "tc-inline-style"}
|
|
||||||
},
|
|
||||||
children: tree
|
children: tree
|
||||||
};
|
};
|
||||||
if(classString) {
|
if(classString) {
|
||||||
@@ -52,6 +49,9 @@ exports.parse = function() {
|
|||||||
if(stylesString) {
|
if(stylesString) {
|
||||||
$tw.utils.addAttributeToParseTreeNode(node,"style",stylesString);
|
$tw.utils.addAttributeToParseTreeNode(node,"style",stylesString);
|
||||||
}
|
}
|
||||||
|
if(!classString && !stylesString) {
|
||||||
|
$tw.utils.addClassToParseTreeNode(node,"tc-inline-style");
|
||||||
|
}
|
||||||
return [node];
|
return [node];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ exports.types = {block: true};
|
|||||||
exports.init = function(parser) {
|
exports.init = function(parser) {
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
// Regexp to match
|
// Regexp to match
|
||||||
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?\}\}(?:\r?\n|$)/mg;
|
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}(?:\r?\n|$)/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
@@ -31,13 +31,22 @@ exports.parse = function() {
|
|||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Get the match details
|
// Get the match details
|
||||||
var template = $tw.utils.trim(this.match[2]),
|
var template = $tw.utils.trim(this.match[2]),
|
||||||
textRef = $tw.utils.trim(this.match[1]);
|
textRef = $tw.utils.trim(this.match[1]),
|
||||||
|
params = this.match[3] ? this.match[3].split("|") : [];
|
||||||
// Prepare the transclude widget
|
// Prepare the transclude widget
|
||||||
var transcludeNode = {
|
var transcludeNode = {
|
||||||
type: "transclude",
|
type: "transclude",
|
||||||
attributes: {},
|
attributes: {},
|
||||||
isBlock: true
|
isBlock: true
|
||||||
};
|
};
|
||||||
|
$tw.utils.each(params,function(paramValue,index) {
|
||||||
|
var name = "" + index;
|
||||||
|
transcludeNode.attributes[name] = {
|
||||||
|
name: name,
|
||||||
|
type: "string",
|
||||||
|
value: paramValue
|
||||||
|
}
|
||||||
|
});
|
||||||
// Prepare the tiddler widget
|
// Prepare the tiddler widget
|
||||||
var tr, targetTitle, targetField, targetIndex, tiddlerNode;
|
var tr, targetTitle, targetField, targetIndex, tiddlerNode;
|
||||||
if(textRef) {
|
if(textRef) {
|
||||||
@@ -48,14 +57,14 @@ exports.parse = function() {
|
|||||||
tiddlerNode = {
|
tiddlerNode = {
|
||||||
type: "tiddler",
|
type: "tiddler",
|
||||||
attributes: {
|
attributes: {
|
||||||
tiddler: {type: "string", value: targetTitle}
|
tiddler: {name: "tiddler", type: "string", value: targetTitle}
|
||||||
},
|
},
|
||||||
isBlock: true,
|
isBlock: true,
|
||||||
children: [transcludeNode]
|
children: [transcludeNode]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if(template) {
|
if(template) {
|
||||||
transcludeNode.attributes.tiddler = {type: "string", value: template};
|
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: template};
|
||||||
if(textRef) {
|
if(textRef) {
|
||||||
return [tiddlerNode];
|
return [tiddlerNode];
|
||||||
} else {
|
} else {
|
||||||
@@ -63,12 +72,12 @@ exports.parse = function() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(textRef) {
|
if(textRef) {
|
||||||
transcludeNode.attributes.tiddler = {type: "string", value: targetTitle};
|
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: targetTitle};
|
||||||
if(targetField) {
|
if(targetField) {
|
||||||
transcludeNode.attributes.field = {type: "string", value: targetField};
|
transcludeNode.attributes["$field"] = {name: "$field", type: "string", value: targetField};
|
||||||
}
|
}
|
||||||
if(targetIndex) {
|
if(targetIndex) {
|
||||||
transcludeNode.attributes.index = {type: "string", value: targetIndex};
|
transcludeNode.attributes["$index"] = {name: "$index", type: "string", value: targetIndex};
|
||||||
}
|
}
|
||||||
return [tiddlerNode];
|
return [tiddlerNode];
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ exports.types = {inline: true};
|
|||||||
exports.init = function(parser) {
|
exports.init = function(parser) {
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
// Regexp to match
|
// Regexp to match
|
||||||
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?\}\}/mg;
|
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
@@ -31,12 +31,21 @@ exports.parse = function() {
|
|||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Get the match details
|
// Get the match details
|
||||||
var template = $tw.utils.trim(this.match[2]),
|
var template = $tw.utils.trim(this.match[2]),
|
||||||
textRef = $tw.utils.trim(this.match[1]);
|
textRef = $tw.utils.trim(this.match[1]),
|
||||||
|
params = this.match[3] ? this.match[3].split("|") : [];
|
||||||
// Prepare the transclude widget
|
// Prepare the transclude widget
|
||||||
var transcludeNode = {
|
var transcludeNode = {
|
||||||
type: "transclude",
|
type: "transclude",
|
||||||
attributes: {}
|
attributes: {}
|
||||||
};
|
};
|
||||||
|
$tw.utils.each(params,function(paramValue,index) {
|
||||||
|
var name = "" + index;
|
||||||
|
transcludeNode.attributes[name] = {
|
||||||
|
name: name,
|
||||||
|
type: "string",
|
||||||
|
value: paramValue
|
||||||
|
}
|
||||||
|
});
|
||||||
// Prepare the tiddler widget
|
// Prepare the tiddler widget
|
||||||
var tr, targetTitle, targetField, targetIndex, tiddlerNode;
|
var tr, targetTitle, targetField, targetIndex, tiddlerNode;
|
||||||
if(textRef) {
|
if(textRef) {
|
||||||
@@ -47,13 +56,13 @@ exports.parse = function() {
|
|||||||
tiddlerNode = {
|
tiddlerNode = {
|
||||||
type: "tiddler",
|
type: "tiddler",
|
||||||
attributes: {
|
attributes: {
|
||||||
tiddler: {type: "string", value: targetTitle}
|
tiddler: {name: "tiddler", type: "string", value: targetTitle}
|
||||||
},
|
},
|
||||||
children: [transcludeNode]
|
children: [transcludeNode]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if(template) {
|
if(template) {
|
||||||
transcludeNode.attributes.tiddler = {type: "string", value: template};
|
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: template};
|
||||||
if(textRef) {
|
if(textRef) {
|
||||||
return [tiddlerNode];
|
return [tiddlerNode];
|
||||||
} else {
|
} else {
|
||||||
@@ -61,12 +70,12 @@ exports.parse = function() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(textRef) {
|
if(textRef) {
|
||||||
transcludeNode.attributes.tiddler = {type: "string", value: targetTitle};
|
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: targetTitle};
|
||||||
if(targetField) {
|
if(targetField) {
|
||||||
transcludeNode.attributes.field = {type: "string", value: targetField};
|
transcludeNode.attributes["$field"] = {name: "$field", type: "string", value: targetField};
|
||||||
}
|
}
|
||||||
if(targetIndex) {
|
if(targetIndex) {
|
||||||
transcludeNode.attributes.index = {type: "string", value: targetIndex};
|
transcludeNode.attributes["$index"] = {name: "$index", type: "string", value: targetIndex};
|
||||||
}
|
}
|
||||||
return [tiddlerNode];
|
return [tiddlerNode];
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Instantiate parse rule
|
|||||||
exports.init = function(parser) {
|
exports.init = function(parser) {
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
// Regexp to match
|
// Regexp to match
|
||||||
this.matchRegExp = /^\\whitespace[^\S\n]/mg;
|
this.matchRegExp = /\\whitespace[^\S\n]/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ options: see below:
|
|||||||
parseAsInline: true to parse text as inline instead of block
|
parseAsInline: true to parse text as inline instead of block
|
||||||
wiki: reference to wiki to use
|
wiki: reference to wiki to use
|
||||||
_canonical_uri: optional URI of content if text is missing or empty
|
_canonical_uri: optional URI of content if text is missing or empty
|
||||||
|
configTrimWhiteSpace: true to trim whitespace
|
||||||
*/
|
*/
|
||||||
var WikiParser = function(type,text,options) {
|
var WikiParser = function(type,text,options) {
|
||||||
this.wiki = options.wiki;
|
this.wiki = options.wiki;
|
||||||
@@ -46,7 +47,9 @@ var WikiParser = function(type,text,options) {
|
|||||||
this.source = text || "";
|
this.source = text || "";
|
||||||
this.sourceLength = this.source.length;
|
this.sourceLength = this.source.length;
|
||||||
// Flag for ignoring whitespace
|
// Flag for ignoring whitespace
|
||||||
this.configTrimWhiteSpace = false;
|
this.configTrimWhiteSpace = options.configTrimWhiteSpace !== undefined ? options.configTrimWhiteSpace : false;
|
||||||
|
// Parser mode
|
||||||
|
this.parseAsInline = options.parseAsInline;
|
||||||
// Set current parse position
|
// Set current parse position
|
||||||
this.pos = 0;
|
this.pos = 0;
|
||||||
// Start with empty output
|
// Start with empty output
|
||||||
@@ -83,7 +86,7 @@ var WikiParser = function(type,text,options) {
|
|||||||
// Parse any pragmas
|
// Parse any pragmas
|
||||||
var topBranch = this.parsePragmas();
|
var topBranch = this.parsePragmas();
|
||||||
// Parse the text into inline runs or blocks
|
// Parse the text into inline runs or blocks
|
||||||
if(options.parseAsInline) {
|
if(this.parseAsInline) {
|
||||||
topBranch.push.apply(topBranch,this.parseInlineRun());
|
topBranch.push.apply(topBranch,this.parseInlineRun());
|
||||||
} else {
|
} else {
|
||||||
topBranch.push.apply(topBranch,this.parseBlocks());
|
topBranch.push.apply(topBranch,this.parseBlocks());
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/core/modules/savers/beaker.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: saver
|
|
||||||
|
|
||||||
Saves files using the Beaker browser's (https://beakerbrowser.com) Dat protocol (https://datproject.org/)
|
|
||||||
Compatible with beaker >= V0.7.2
|
|
||||||
|
|
||||||
\*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
/*jslint node: true, browser: true */
|
|
||||||
/*global $tw: false */
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/*
|
|
||||||
Set up the saver
|
|
||||||
*/
|
|
||||||
var BeakerSaver = function(wiki) {
|
|
||||||
this.wiki = wiki;
|
|
||||||
};
|
|
||||||
|
|
||||||
BeakerSaver.prototype.save = function(text,method,callback) {
|
|
||||||
var dat = new DatArchive("" + window.location),
|
|
||||||
pathname = ("" + window.location.pathname).split("#")[0];
|
|
||||||
dat.stat(pathname).then(function(value) {
|
|
||||||
if(value.isDirectory()) {
|
|
||||||
pathname = pathname + "/index.html";
|
|
||||||
}
|
|
||||||
dat.writeFile(pathname,text,"utf8").then(function(value) {
|
|
||||||
callback(null);
|
|
||||||
},function(reason) {
|
|
||||||
callback("Beaker Saver Write Error: " + reason);
|
|
||||||
});
|
|
||||||
},function(reason) {
|
|
||||||
callback("Beaker Saver Stat Error: " + reason);
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Information about this saver
|
|
||||||
*/
|
|
||||||
BeakerSaver.prototype.info = {
|
|
||||||
name: "beaker",
|
|
||||||
priority: 3000,
|
|
||||||
capabilities: ["save", "autosave"]
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Static method that returns true if this saver is capable of working
|
|
||||||
*/
|
|
||||||
exports.canSave = function(wiki) {
|
|
||||||
return !!window.DatArchive && location.protocol==="dat:";
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Create an instance of this saver
|
|
||||||
*/
|
|
||||||
exports.create = function(wiki) {
|
|
||||||
return new BeakerSaver(wiki);
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/core/modules/savers/hyperdrive.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: saver
|
|
||||||
|
|
||||||
Saves files using the Hyperdrive Protocol (https://hypercore-protocol.org/#hyperdrive) Beaker browser beta-1.0 and later (https://beakerbrowser.com)
|
|
||||||
Compatible with beaker >= V1.0.0
|
|
||||||
|
|
||||||
\*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
/*jslint node: true, browser: true */
|
|
||||||
/*global $tw: false */
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/*
|
|
||||||
Set up the saver
|
|
||||||
*/
|
|
||||||
var HyperdriveSaver = function(wiki) {
|
|
||||||
this.wiki = wiki;
|
|
||||||
};
|
|
||||||
|
|
||||||
HyperdriveSaver.prototype.save = function(text,method,callback) {
|
|
||||||
var dat = beaker.hyperdrive.drive("" + window.location),
|
|
||||||
pathname = ("" + window.location.pathname).split("#")[0];
|
|
||||||
dat.stat(pathname).then(function(value) {
|
|
||||||
if(value.isDirectory()) {
|
|
||||||
pathname = pathname + "/index.html";
|
|
||||||
}
|
|
||||||
dat.writeFile(pathname,text,"utf8").then(function(value) {
|
|
||||||
callback(null);
|
|
||||||
},function(reason) {
|
|
||||||
callback("Hyperdrive Saver Write Error: " + reason);
|
|
||||||
});
|
|
||||||
},function(reason) {
|
|
||||||
callback("Hyperdrive Saver Stat Error: " + reason);
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Information about this saver
|
|
||||||
*/
|
|
||||||
HyperdriveSaver.prototype.info = {
|
|
||||||
name: "beaker-1.x",
|
|
||||||
priority: 3000,
|
|
||||||
capabilities: ["save", "autosave"]
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Static method that returns true if this saver is capable of working
|
|
||||||
*/
|
|
||||||
exports.canSave = function(wiki) {
|
|
||||||
return !!window.beaker && !!beaker.hyperdrive && location.protocol==="hyper:";
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Create an instance of this saver
|
|
||||||
*/
|
|
||||||
exports.create = function(wiki) {
|
|
||||||
return new HyperdriveSaver(wiki);
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
||||||
@@ -21,6 +21,7 @@ exports.handler = function(request,response,state) {
|
|||||||
username: state.authenticatedUsername || state.server.get("anon-username") || "",
|
username: state.authenticatedUsername || state.server.get("anon-username") || "",
|
||||||
anonymous: !state.authenticatedUsername,
|
anonymous: !state.authenticatedUsername,
|
||||||
read_only: !state.server.isAuthorized("writers",state.authenticatedUsername),
|
read_only: !state.server.isAuthorized("writers",state.authenticatedUsername),
|
||||||
|
logout_is_available: false,
|
||||||
space: {
|
space: {
|
||||||
recipe: "default"
|
recipe: "default"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -30,6 +30,16 @@ exports.handler = function(request,response,state) {
|
|||||||
if(fields.revision) {
|
if(fields.revision) {
|
||||||
delete fields.revision;
|
delete fields.revision;
|
||||||
}
|
}
|
||||||
|
// If this is a skinny tiddler, it means the client never got the full
|
||||||
|
// version of the tiddler to edit. So we must preserve whatever text
|
||||||
|
// already exists on the server, or else we'll inadvertently delete it.
|
||||||
|
if(fields._is_skinny !== undefined) {
|
||||||
|
var tiddler = state.wiki.getTiddler(title);
|
||||||
|
if(tiddler) {
|
||||||
|
fields.text = tiddler.fields.text;
|
||||||
|
}
|
||||||
|
delete fields._is_skinny;
|
||||||
|
}
|
||||||
state.wiki.addTiddler(new $tw.Tiddler(fields,{title: title}));
|
state.wiki.addTiddler(new $tw.Tiddler(fields,{title: title}));
|
||||||
var changeCount = state.wiki.getChangeCount(title).toString();
|
var changeCount = state.wiki.getChangeCount(title).toString();
|
||||||
response.writeHead(204, "OK",{
|
response.writeHead(204, "OK",{
|
||||||
|
|||||||
@@ -87,13 +87,6 @@ exports.startup = function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// If we're being viewed on a data: URI then give instructions for how to save
|
|
||||||
if(document.location.protocol === "data:") {
|
|
||||||
$tw.rootWidget.dispatchEvent({
|
|
||||||
type: "tm-modal",
|
|
||||||
param: "$:/language/Modals/SaveInstructions"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -121,7 +121,11 @@ exports.startup = function() {
|
|||||||
});
|
});
|
||||||
// Set up the syncer object if we've got a syncadaptor
|
// Set up the syncer object if we've got a syncadaptor
|
||||||
if($tw.syncadaptor) {
|
if($tw.syncadaptor) {
|
||||||
$tw.syncer = new $tw.Syncer({wiki: $tw.wiki, syncadaptor: $tw.syncadaptor});
|
$tw.syncer = new $tw.Syncer({
|
||||||
|
wiki: $tw.wiki,
|
||||||
|
syncadaptor: $tw.syncadaptor,
|
||||||
|
logging: $tw.wiki.getTiddlerText('$:/config/SyncLogging', "yes") === "yes"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// Setup the saver handler
|
// Setup the saver handler
|
||||||
$tw.saverHandler = new $tw.SaverHandler({
|
$tw.saverHandler = new $tw.SaverHandler({
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ var easing = "cubic-bezier(0.645, 0.045, 0.355, 1)"; // From http://easings.net/
|
|||||||
var ZoominListView = function(listWidget) {
|
var ZoominListView = function(listWidget) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.listWidget = listWidget;
|
this.listWidget = listWidget;
|
||||||
|
this.textNodeLogger = new $tw.utils.Logger("zoomin story river view", {
|
||||||
|
enable: true,
|
||||||
|
colour: 'red'
|
||||||
|
});
|
||||||
// Get the index of the tiddler that is at the top of the history
|
// Get the index of the tiddler that is at the top of the history
|
||||||
var history = this.listWidget.wiki.getTiddlerDataCached(this.listWidget.historyTitle,[]),
|
var history = this.listWidget.wiki.getTiddlerDataCached(this.listWidget.historyTitle,[]),
|
||||||
targetTiddler;
|
targetTiddler;
|
||||||
@@ -48,7 +52,10 @@ ZoominListView.prototype.navigateTo = function(historyInfo) {
|
|||||||
var listItemWidget = this.listWidget.children[listElementIndex],
|
var listItemWidget = this.listWidget.children[listElementIndex],
|
||||||
targetElement = listItemWidget.findFirstDomNode();
|
targetElement = listItemWidget.findFirstDomNode();
|
||||||
// Abandon if the list entry isn't a DOM element (it might be a text node)
|
// Abandon if the list entry isn't a DOM element (it might be a text node)
|
||||||
if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {
|
if(!targetElement) {
|
||||||
|
return;
|
||||||
|
} else if (targetElement.nodeType === Node.TEXT_NODE) {
|
||||||
|
this.logTextNodeRoot(targetElement);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Make the new tiddler be position absolute and visible so that we can measure it
|
// Make the new tiddler be position absolute and visible so that we can measure it
|
||||||
@@ -130,7 +137,10 @@ function findTitleDomNode(widget,targetClass) {
|
|||||||
ZoominListView.prototype.insert = function(widget) {
|
ZoominListView.prototype.insert = function(widget) {
|
||||||
var targetElement = widget.findFirstDomNode();
|
var targetElement = widget.findFirstDomNode();
|
||||||
// Abandon if the list entry isn't a DOM element (it might be a text node)
|
// Abandon if the list entry isn't a DOM element (it might be a text node)
|
||||||
if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {
|
if(!targetElement) {
|
||||||
|
return;
|
||||||
|
} else if (targetElement.nodeType === Node.TEXT_NODE) {
|
||||||
|
this.logTextNodeRoot(targetElement);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Make the newly inserted node position absolute and hidden
|
// Make the newly inserted node position absolute and hidden
|
||||||
@@ -173,16 +183,21 @@ ZoominListView.prototype.remove = function(widget) {
|
|||||||
var toWidgetDomNode = toWidget && toWidget.findFirstDomNode();
|
var toWidgetDomNode = toWidget && toWidget.findFirstDomNode();
|
||||||
// Set up the tiddler we're moving back in
|
// Set up the tiddler we're moving back in
|
||||||
if(toWidgetDomNode) {
|
if(toWidgetDomNode) {
|
||||||
$tw.utils.addClass(toWidgetDomNode,"tc-storyview-zoomin-tiddler");
|
if (toWidgetDomNode.nodeType === Node.TEXT_NODE) {
|
||||||
$tw.utils.setStyle(toWidgetDomNode,[
|
this.logTextNodeRoot(toWidgetDomNode);
|
||||||
{display: "block"},
|
toWidgetDomNode = null;
|
||||||
{transformOrigin: "50% 50%"},
|
} else {
|
||||||
{transform: "translateX(0px) translateY(0px) scale(10)"},
|
$tw.utils.addClass(toWidgetDomNode,"tc-storyview-zoomin-tiddler");
|
||||||
{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms " + easing + ", opacity " + duration + "ms " + easing},
|
$tw.utils.setStyle(toWidgetDomNode,[
|
||||||
{opacity: "0"},
|
{display: "block"},
|
||||||
{zIndex: "500"}
|
{transformOrigin: "50% 50%"},
|
||||||
]);
|
{transform: "translateX(0px) translateY(0px) scale(10)"},
|
||||||
this.currentTiddlerDomNode = toWidgetDomNode;
|
{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms " + easing + ", opacity " + duration + "ms " + easing},
|
||||||
|
{opacity: "0"},
|
||||||
|
{zIndex: "500"}
|
||||||
|
]);
|
||||||
|
this.currentTiddlerDomNode = toWidgetDomNode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Animate them both
|
// Animate them both
|
||||||
// Force layout
|
// Force layout
|
||||||
@@ -206,6 +221,10 @@ ZoominListView.prototype.remove = function(widget) {
|
|||||||
return true; // Indicate that we'll delete the DOM node
|
return true; // Indicate that we'll delete the DOM node
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ZoominListView.prototype.logTextNodeRoot = function(node) {
|
||||||
|
this.textNodeLogger.log($tw.language.getString("Error/ZoominTextNode") + " " + node.textContent);
|
||||||
|
};
|
||||||
|
|
||||||
exports.zoomin = ZoominListView;
|
exports.zoomin = ZoominListView;
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -402,6 +402,7 @@ Syncer.prototype.handleLazyLoadEvent = function(title) {
|
|||||||
// Mark the tiddler as needing loading, and having already been lazily loaded
|
// Mark the tiddler as needing loading, and having already been lazily loaded
|
||||||
this.titlesToBeLoaded[title] = true;
|
this.titlesToBeLoaded[title] = true;
|
||||||
this.titlesHaveBeenLazyLoaded[title] = true;
|
this.titlesHaveBeenLazyLoaded[title] = true;
|
||||||
|
this.processTaskQueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,35 +12,113 @@ A barebones CSV parser
|
|||||||
/*global $tw: false */
|
/*global $tw: false */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var QUOTE = '"';
|
||||||
|
|
||||||
|
var getCellInfo = function(text, start, length, SEPARATOR) {
|
||||||
|
var isCellQuoted = text.charAt(start) === QUOTE;
|
||||||
|
var cellStart = isCellQuoted ? start + 1 : start;
|
||||||
|
|
||||||
|
if (text.charAt(i) === SEPARATOR) {
|
||||||
|
return [cellStart, cellStart, false];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = cellStart; i < length; i++) {
|
||||||
|
var cellCharacter = text.charAt(i);
|
||||||
|
var isEOL = cellCharacter === "\n" || cellCharacter === "\r";
|
||||||
|
|
||||||
|
if (isEOL && !isCellQuoted) {
|
||||||
|
return [cellStart, i, false];
|
||||||
|
|
||||||
|
} else if (cellCharacter === SEPARATOR && !isCellQuoted) {
|
||||||
|
return [cellStart, i, false];
|
||||||
|
|
||||||
|
} else if (cellCharacter === QUOTE && isCellQuoted) {
|
||||||
|
var nextCharacter = i + 1 < length ? text.charAt(i + 1) : '';
|
||||||
|
if (nextCharacter !== QUOTE) {
|
||||||
|
return [cellStart, i, true];
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [cellStart, i, isCellQuoted];
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.parseCsvString = function(text, options) {
|
||||||
|
if (!text) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
var SEPARATOR = options.separator || ",",
|
||||||
|
length = text.length,
|
||||||
|
rows = [],
|
||||||
|
nextRow = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < length; i++) {
|
||||||
|
var cellInfo = getCellInfo(text, i, length, SEPARATOR);
|
||||||
|
var cellText = text.substring(cellInfo[0], cellInfo[1]);
|
||||||
|
if (cellInfo[2]) {
|
||||||
|
cellText = cellText.replace(/""/g, '"');
|
||||||
|
cellInfo[1]++;
|
||||||
|
}
|
||||||
|
nextRow.push(cellText);
|
||||||
|
|
||||||
|
i = cellInfo[1];
|
||||||
|
|
||||||
|
var character = text.charAt(i);
|
||||||
|
var nextCharacter = i + 1 < length ? text.charAt(i + 1) : '';
|
||||||
|
|
||||||
|
if (character === "\r" || character === "\n") {
|
||||||
|
// Edge case for empty rows
|
||||||
|
if (nextRow.length === 1 && nextRow[0] === '') {
|
||||||
|
nextRow.length = 0;
|
||||||
|
}
|
||||||
|
rows.push(nextRow);
|
||||||
|
nextRow = [];
|
||||||
|
|
||||||
|
if (character === "\r") {
|
||||||
|
var nextCharacter = i + 1 < length ? text.charAt(i + 1) : '';
|
||||||
|
|
||||||
|
if (nextCharacter === "\n") {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special case if last cell in last row is an empty cell
|
||||||
|
if (text.charAt(length - 1) === SEPARATOR) {
|
||||||
|
nextRow.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
rows.push(nextRow);
|
||||||
|
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Parse a CSV string with a header row and return an array of hashmaps.
|
Parse a CSV string with a header row and return an array of hashmaps.
|
||||||
*/
|
*/
|
||||||
exports.parseCsvStringWithHeader = function(text,options) {
|
exports.parseCsvStringWithHeader = function(text,options) {
|
||||||
options = options || {};
|
var csv = $tw.utils.parseCsvString(text, options);
|
||||||
var separator = options.separator || ",",
|
var headers = csv[0];
|
||||||
rows = text.split(/\r?\n/mg).map(function(row) {
|
|
||||||
return $tw.utils.trim(row);
|
csv = csv.slice(1);
|
||||||
}).filter(function(row) {
|
for (var i = 0; i < csv.length; i++) {
|
||||||
return row !== "";
|
var row = csv[i];
|
||||||
});
|
var rowObject = Object.create(null);
|
||||||
if(rows.length < 1) {
|
|
||||||
return "Missing header row";
|
for(var columnIndex=0; columnIndex<headers.length; columnIndex++) {
|
||||||
}
|
var columnName = headers[columnIndex];
|
||||||
var headings = rows[0].split(separator),
|
if (columnName) {
|
||||||
results = [];
|
rowObject[columnName] = $tw.utils.trim(row[columnIndex] || "");
|
||||||
for(var row=1; row<rows.length; row++) {
|
}
|
||||||
var columns = rows[row].split(separator),
|
|
||||||
columnResult = Object.create(null);
|
|
||||||
if(columns.length !== headings.length) {
|
|
||||||
return "Malformed CSV row '" + rows[row] + "'";
|
|
||||||
}
|
}
|
||||||
for(var column=0; column<columns.length; column++) {
|
csv[i] = rowObject;
|
||||||
var columnName = headings[column];
|
|
||||||
columnResult[columnName] = $tw.utils.trim(columns[column] || "");
|
|
||||||
}
|
|
||||||
results.push(columnResult);
|
|
||||||
}
|
}
|
||||||
return results;
|
return csv;
|
||||||
}
|
}
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ Various static DOM-related utility functions.
|
|||||||
/*global $tw: false */
|
/*global $tw: false */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var Popup = require("$:/core/modules/utils/dom/popup.js");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Determines whether element 'a' contains element 'b'
|
Determines whether element 'a' contains element 'b'
|
||||||
Code thanks to John Resig, http://ejohn.org/blog/comparing-document-position/
|
Code thanks to John Resig, http://ejohn.org/blog/comparing-document-position/
|
||||||
@@ -26,6 +28,24 @@ exports.domMatchesSelector = function(node,selector) {
|
|||||||
return node.matches ? node.matches(selector) : node.msMatchesSelector(selector);
|
return node.matches ? node.matches(selector) : node.msMatchesSelector(selector);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Select text in a an input or textarea (setSelectionRange crashes on certain input types)
|
||||||
|
*/
|
||||||
|
exports.setSelectionRangeSafe = function(node,start,end,direction) {
|
||||||
|
try {
|
||||||
|
node.setSelectionRange(start,end,direction);
|
||||||
|
} catch(e) {
|
||||||
|
node.select();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Select the text in an input or textarea by position
|
||||||
|
*/
|
||||||
|
exports.setSelectionByPosition = function(node,selectFromStart,selectFromEnd) {
|
||||||
|
$tw.utils.setSelectionRangeSafe(node,selectFromStart,node.value.length - selectFromEnd);
|
||||||
|
};
|
||||||
|
|
||||||
exports.removeChildren = function(node) {
|
exports.removeChildren = function(node) {
|
||||||
while(node.hasChildNodes()) {
|
while(node.hasChildNodes()) {
|
||||||
node.removeChild(node.firstChild);
|
node.removeChild(node.firstChild);
|
||||||
@@ -294,8 +314,21 @@ exports.collectDOMVariables = function(selectedNode,domNode,event) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if(selectedNode.offsetLeft) {
|
if(selectedNode.offsetLeft) {
|
||||||
// Add a variable with a popup coordinate string for the selected node
|
// Add variables with a (relative and absolute) popup coordinate string for the selected node
|
||||||
variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")";
|
var nodeRect = {
|
||||||
|
left: selectedNode.offsetLeft,
|
||||||
|
top: selectedNode.offsetTop,
|
||||||
|
width: selectedNode.offsetWidth,
|
||||||
|
height: selectedNode.offsetHeight
|
||||||
|
};
|
||||||
|
variables["tv-popup-coords"] = Popup.buildCoordinates(Popup.coordinatePrefix.csOffsetParent,nodeRect);
|
||||||
|
|
||||||
|
var absRect = $tw.utils.extend({}, nodeRect);
|
||||||
|
for (var currentNode = selectedNode.offsetParent; currentNode; currentNode = currentNode.offsetParent) {
|
||||||
|
absRect.left += currentNode.offsetLeft;
|
||||||
|
absRect.top += currentNode.offsetTop;
|
||||||
|
}
|
||||||
|
variables["tv-popup-abs-coords"] = Popup.buildCoordinates(Popup.coordinatePrefix.csAbsolute,absRect);
|
||||||
|
|
||||||
// Add variables for offset of selected node
|
// Add variables for offset of selected node
|
||||||
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();
|
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ Display a modal dialogue
|
|||||||
options: see below
|
options: see below
|
||||||
Options include:
|
Options include:
|
||||||
downloadLink: Text of a big download link to include
|
downloadLink: Text of a big download link to include
|
||||||
|
event: widget event
|
||||||
|
variables: from event.paramObject
|
||||||
*/
|
*/
|
||||||
Modal.prototype.display = function(title,options) {
|
Modal.prototype.display = function(title,options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
@@ -209,6 +211,10 @@ Modal.prototype.display = function(title,options) {
|
|||||||
headerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
|
headerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
|
||||||
bodyWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
|
bodyWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
|
||||||
footerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
|
footerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
|
||||||
|
// Whether to close the modal dialog when the mask (area outside the modal) is clicked
|
||||||
|
if(tiddler.fields && (tiddler.fields["mask-closable"] === "yes" || tiddler.fields["mask-closable"] === "true")) {
|
||||||
|
modalBackdrop.addEventListener("click",closeHandler,false);
|
||||||
|
}
|
||||||
// Set the initial styles for the message
|
// Set the initial styles for the message
|
||||||
$tw.utils.setStyle(modalBackdrop,[
|
$tw.utils.setStyle(modalBackdrop,[
|
||||||
{opacity: "0"}
|
{opacity: "0"}
|
||||||
|
|||||||
@@ -22,6 +22,19 @@ var Popup = function(options) {
|
|||||||
this.popups = []; // Array of {title:,wiki:,domNode:} objects
|
this.popups = []; // Array of {title:,wiki:,domNode:} objects
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Global regular expression for parsing the location of a popup.
|
||||||
|
This is also used by the Reveal widget.
|
||||||
|
*/
|
||||||
|
exports.popupLocationRegExp = /^(@?)\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Objekt containing the available prefixes for coordinates build with the `buildCoordinates` function:
|
||||||
|
- csOffsetParent: Uses a coordinate system based on the offset parent (no prefix).
|
||||||
|
- csAbsolute: Use an absolute coordinate system (prefix "@").
|
||||||
|
*/
|
||||||
|
exports.coordinatePrefix = { csOffsetParent: "", csAbsolute: "@" }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Trigger a popup open or closed. Parameters are in a hashmap:
|
Trigger a popup open or closed. Parameters are in a hashmap:
|
||||||
title: title of the tiddler where the popup details are stored
|
title: title of the tiddler where the popup details are stored
|
||||||
@@ -136,8 +149,17 @@ Popup.prototype.show = function(options) {
|
|||||||
height: options.domNode.offsetHeight
|
height: options.domNode.offsetHeight
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var popupRect = "(" + rect.left + "," + rect.top + "," +
|
if(options.absolute && options.domNode) {
|
||||||
rect.width + "," + rect.height + ")";
|
// Walk the offsetParent chain and add the position of the offsetParents to make
|
||||||
|
// the position absolute to the root node of the page.
|
||||||
|
var currentNode = options.domNode.offsetParent;
|
||||||
|
while(currentNode) {
|
||||||
|
rect.left += currentNode.offsetLeft;
|
||||||
|
rect.top += currentNode.offsetTop;
|
||||||
|
currentNode = currentNode.offsetParent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var popupRect = exports.buildCoordinates(options.absolute?exports.coordinatePrefix.csAbsolute:exports.coordinatePrefix.csOffsetParent,rect);
|
||||||
if(options.noStateReference) {
|
if(options.noStateReference) {
|
||||||
options.wiki.setText(options.title,"text",undefined,popupRect);
|
options.wiki.setText(options.title,"text",undefined,popupRect);
|
||||||
} else {
|
} else {
|
||||||
@@ -172,13 +194,54 @@ Popup.prototype.cancel = function(level) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns true if the specified title and text identifies an active popup
|
Returns true if the specified title and text identifies an active popup.
|
||||||
|
This function is safe to call, even if the popup class was not initialized.
|
||||||
*/
|
*/
|
||||||
Popup.prototype.readPopupState = function(text) {
|
exports.readPopupState = function(text) {
|
||||||
var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/;
|
return exports.popupLocationRegExp.test(text);
|
||||||
return popupLocationRegExp.test(text);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parses a coordinate string in the format `(x,y,w,h)` or `@(x,y,z,h)` and returns
|
||||||
|
an object containing the position, width and height. The absolute-Mark is boolean
|
||||||
|
value that indicates the coordinate system of the coordinates. If they start with
|
||||||
|
an `@`, `absolute` is set to true and the coordinates are relative to the root
|
||||||
|
element. If the initial `@` is missing, they are relative to the offset parent
|
||||||
|
element and `absoute` is false.
|
||||||
|
This function is safe to call, even if the popup class was not initialized.
|
||||||
|
*/
|
||||||
|
exports.parseCoordinates = function(coordinates) {
|
||||||
|
var match = exports.popupLocationRegExp.exec(coordinates);
|
||||||
|
if(match) {
|
||||||
|
return {
|
||||||
|
absolute: (match[1] === "@"),
|
||||||
|
left: parseFloat(match[2]),
|
||||||
|
top: parseFloat(match[3]),
|
||||||
|
width: parseFloat(match[4]),
|
||||||
|
height: parseFloat(match[5])
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Builds a coordinate string from a coordinate system identifier and an object
|
||||||
|
containing the left, top, width and height values.
|
||||||
|
Use constants defined in coordinatePrefix to specify a coordinate system.
|
||||||
|
If one of the parameters is invalid for building a coordinate string `(0,0,0,0)`
|
||||||
|
will be returned.
|
||||||
|
This function is safe to call, even if the popup class was not initialized.
|
||||||
|
*/
|
||||||
|
exports.buildCoordinates = function(prefix,position) {
|
||||||
|
var coord = prefix + "(" + position.left + "," + position.top + "," + position.width + "," + position.height + ")";
|
||||||
|
if (exports.popupLocationRegExp.test(coord)) {
|
||||||
|
return coord;
|
||||||
|
} else {
|
||||||
|
return "(0,0,0,0)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
exports.Popup = Popup;
|
exports.Popup = Popup;
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ exports.generateTiddlerFileInfo = function(tiddler,options) {
|
|||||||
hasUnsafeFields = hasUnsafeFields || /[\x00-\x1F]/mg.test(value);
|
hasUnsafeFields = hasUnsafeFields || /[\x00-\x1F]/mg.test(value);
|
||||||
hasUnsafeFields = hasUnsafeFields || ($tw.utils.trim(value) !== value);
|
hasUnsafeFields = hasUnsafeFields || ($tw.utils.trim(value) !== value);
|
||||||
}
|
}
|
||||||
hasUnsafeFields = hasUnsafeFields || /:/mg.test(fieldName);
|
hasUnsafeFields = hasUnsafeFields || /:|#/mg.test(fieldName);
|
||||||
});
|
});
|
||||||
// Check for field values
|
// Check for field values
|
||||||
if(hasUnsafeFields) {
|
if(hasUnsafeFields) {
|
||||||
@@ -238,7 +238,7 @@ exports.generateTiddlerFileInfo = function(tiddler,options) {
|
|||||||
} else {
|
} else {
|
||||||
// Save as a .tid or a text/binary file plus a .meta file
|
// Save as a .tid or a text/binary file plus a .meta file
|
||||||
var tiddlerType = tiddler.fields.type || "text/vnd.tiddlywiki";
|
var tiddlerType = tiddler.fields.type || "text/vnd.tiddlywiki";
|
||||||
if(tiddlerType === "text/vnd.tiddlywiki") {
|
if(tiddlerType === "text/vnd.tiddlywiki" || tiddler.hasField("_canonical_uri")) {
|
||||||
// Save as a .tid file
|
// Save as a .tid file
|
||||||
fileInfo.type = "application/x-tiddler";
|
fileInfo.type = "application/x-tiddler";
|
||||||
fileInfo.hasMetaFile = false;
|
fileInfo.hasMetaFile = false;
|
||||||
@@ -393,7 +393,7 @@ exports.generateTiddlerFilepath = function(title,options) {
|
|||||||
} while(fs.existsSync(fullPath));
|
} 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 encodeURIComponent() and resolve to tiddler directory.
|
// or the 'originalpath' directory, then $tw.utils.encodeURIComponentExtended() and resolve to tiddler directory.
|
||||||
var writePath = $tw.hooks.invokeHook("th-make-tiddler-path",fullPath,fullPath),
|
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) {
|
||||||
@@ -403,7 +403,7 @@ exports.generateTiddlerFilepath = function(title,options) {
|
|||||||
writePath.indexOf(path.resolve($tw.boot.wikiTiddlersPath,originalpath)) == 0 );
|
writePath.indexOf(path.resolve($tw.boot.wikiTiddlersPath,originalpath)) == 0 );
|
||||||
}
|
}
|
||||||
if(encode) {
|
if(encode) {
|
||||||
writePath = path.resolve(directory,encodeURIComponent(fullPath));
|
writePath = path.resolve(directory,$tw.utils.encodeURIComponentExtended(fullPath));
|
||||||
}
|
}
|
||||||
// Return the full path to the file
|
// Return the full path to the file
|
||||||
return writePath;
|
return writePath;
|
||||||
|
|||||||
@@ -15,10 +15,11 @@ function LinkedList() {
|
|||||||
|
|
||||||
LinkedList.prototype.clear = function() {
|
LinkedList.prototype.clear = function() {
|
||||||
// LinkedList performs the duty of both the head and tail node
|
// LinkedList performs the duty of both the head and tail node
|
||||||
this.next = Object.create(null);
|
this.next = new LLMap();
|
||||||
this.prev = Object.create(null);
|
this.prev = new LLMap();
|
||||||
this.first = undefined;
|
// Linked list head initially points to itself
|
||||||
this.last = undefined;
|
this.next.set(null, null);
|
||||||
|
this.prev.set(null, null);
|
||||||
this.length = 0;
|
this.length = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,28 +42,29 @@ Push behaves like array.push and accepts multiple string arguments. But it also
|
|||||||
accepts a single array argument too, to be consistent with its other methods.
|
accepts a single array argument too, to be consistent with its other methods.
|
||||||
*/
|
*/
|
||||||
LinkedList.prototype.push = function(/* values */) {
|
LinkedList.prototype.push = function(/* values */) {
|
||||||
var values = arguments;
|
var i, values = arguments;
|
||||||
if($tw.utils.isArray(values[0])) {
|
if($tw.utils.isArray(values[0])) {
|
||||||
values = values[0];
|
values = values[0];
|
||||||
}
|
}
|
||||||
for(var i = 0; i < values.length; i++) {
|
for(i = 0; i < values.length; i++) {
|
||||||
_assertString(values[i]);
|
_assertString(values[i]);
|
||||||
}
|
}
|
||||||
for(var i = 0; i < values.length; i++) {
|
for(i = 0; i < values.length; i++) {
|
||||||
_linkToEnd(this,values[i]);
|
_linkToEnd(this,values[i]);
|
||||||
}
|
}
|
||||||
return this.length;
|
return this.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
LinkedList.prototype.pushTop = function(value) {
|
LinkedList.prototype.pushTop = function(value) {
|
||||||
|
var t;
|
||||||
if($tw.utils.isArray(value)) {
|
if($tw.utils.isArray(value)) {
|
||||||
for (var t=0; t<value.length; t++) {
|
for (t=0; t<value.length; t++) {
|
||||||
_assertString(value[t]);
|
_assertString(value[t]);
|
||||||
}
|
}
|
||||||
for(var t=0; t<value.length; t++) {
|
for(t=0; t<value.length; t++) {
|
||||||
_removeOne(this,value[t]);
|
_removeOne(this,value[t]);
|
||||||
}
|
}
|
||||||
for(var t=0; t<value.length; t++) {
|
for(t=0; t<value.length; t++) {
|
||||||
_linkToEnd(this,value[t]);
|
_linkToEnd(this,value[t]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -74,11 +76,11 @@ LinkedList.prototype.pushTop = function(value) {
|
|||||||
|
|
||||||
LinkedList.prototype.each = function(callback) {
|
LinkedList.prototype.each = function(callback) {
|
||||||
var visits = Object.create(null),
|
var visits = Object.create(null),
|
||||||
value = this.first;
|
value = this.next.get(null);
|
||||||
while(value !== undefined) {
|
while(value !== null) {
|
||||||
callback(value);
|
callback(value);
|
||||||
var next = this.next[value];
|
var next = this.next.get(value);
|
||||||
if(typeof next === "object") {
|
if(Array.isArray(next)) {
|
||||||
var i = visits[value] || 0;
|
var i = visits[value] || 0;
|
||||||
visits[value] = i+1;
|
visits[value] = i+1;
|
||||||
value = next[i];
|
value = next[i];
|
||||||
@@ -105,91 +107,79 @@ LinkedList.prototype.makeTiddlerIterator = function(wiki) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function _removeOne(list,value) {
|
function _removeOne(list,value) {
|
||||||
var prevEntry = list.prev[value],
|
var nextEntry = list.next.get(value);
|
||||||
nextEntry = list.next[value],
|
if(nextEntry === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var prevEntry = list.prev.get(value),
|
||||||
prev = prevEntry,
|
prev = prevEntry,
|
||||||
next = nextEntry;
|
next = nextEntry,
|
||||||
if(typeof nextEntry === "object") {
|
ref;
|
||||||
|
if(Array.isArray(nextEntry)) {
|
||||||
next = nextEntry[0];
|
next = nextEntry[0];
|
||||||
prev = prevEntry[0];
|
prev = prevEntry[0];
|
||||||
}
|
}
|
||||||
// Relink preceding element.
|
// Relink preceding element.
|
||||||
if(list.first === value) {
|
ref = list.next.get(prev);
|
||||||
list.first = next
|
if(Array.isArray(ref)) {
|
||||||
} else if(prev !== undefined) {
|
var i = ref.indexOf(value);
|
||||||
if(typeof list.next[prev] === "object") {
|
ref[i] = next;
|
||||||
if(next === undefined) {
|
|
||||||
// Must have been last, and 'i' would be last element.
|
|
||||||
list.next[prev].pop();
|
|
||||||
} else {
|
|
||||||
var i = list.next[prev].indexOf(value);
|
|
||||||
list.next[prev][i] = next;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
list.next[prev] = next;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return;
|
list.next.set(prev,next);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now relink following element
|
// Now relink following element
|
||||||
// Check "next !== undefined" rather than "list.last === value" because
|
ref = list.prev.get(next);
|
||||||
// we need to know if the FIRST value is the last in the list, not the last.
|
if(Array.isArray(ref)) {
|
||||||
if(next !== undefined) {
|
var i = ref.indexOf(value);
|
||||||
if(typeof list.prev[next] === "object") {
|
ref[i] = prev;
|
||||||
if(prev === undefined) {
|
|
||||||
// Must have been first, and 'i' would be 0.
|
|
||||||
list.prev[next].shift();
|
|
||||||
} else {
|
|
||||||
var i = list.prev[next].indexOf(value);
|
|
||||||
list.prev[next][i] = prev;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
list.prev[next] = prev;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
list.last = prev;
|
list.prev.set(next,prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delink actual value. If it uses arrays, just remove first entries.
|
// Delink actual value. If it uses arrays, just remove first entries.
|
||||||
if(typeof nextEntry === "object") {
|
if(Array.isArray(nextEntry) && nextEntry.length > 1) {
|
||||||
nextEntry.shift();
|
nextEntry.shift();
|
||||||
prevEntry.shift();
|
prevEntry.shift();
|
||||||
} else {
|
} else {
|
||||||
list.next[value] = undefined;
|
list.next.set(value,undefined);
|
||||||
list.prev[value] = undefined;
|
list.prev.set(value,undefined);
|
||||||
}
|
}
|
||||||
list.length -= 1;
|
list.length -= 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sticks the given node onto the end of the list.
|
// Sticks the given node onto the end of the list.
|
||||||
function _linkToEnd(list,value) {
|
function _linkToEnd(list,value) {
|
||||||
if(list.first === undefined) {
|
var old = list.next.get(value);
|
||||||
list.first = value;
|
var last = list.prev.get(null);
|
||||||
|
// Does it already exists?
|
||||||
|
if(old !== undefined) {
|
||||||
|
if(!Array.isArray(old)) {
|
||||||
|
old = [old];
|
||||||
|
list.next.set(value,old);
|
||||||
|
list.prev.set(value,[list.prev.get(value)]);
|
||||||
|
}
|
||||||
|
old.push(null);
|
||||||
|
list.prev.get(value).push(last);
|
||||||
} else {
|
} else {
|
||||||
// Does it already exists?
|
list.next.set(value,null);
|
||||||
if(list.first === value || list.prev[value] !== undefined) {
|
list.prev.set(value,last);
|
||||||
if(typeof list.next[value] === "string") {
|
}
|
||||||
list.next[value] = [list.next[value]];
|
// Make the old last point to this new one.
|
||||||
list.prev[value] = [list.prev[value]];
|
if(value !== last) {
|
||||||
} else if(typeof list.next[value] === "undefined") {
|
var array = list.next.get(last);
|
||||||
// list.next[value] must be undefined.
|
if(Array.isArray(array)) {
|
||||||
// Special case. List already has 1 value. It's at the end.
|
array[array.length-1] = value;
|
||||||
list.next[value] = [];
|
} else {
|
||||||
list.prev[value] = [list.prev[value]];
|
list.next.set(last,value);
|
||||||
}
|
}
|
||||||
list.prev[value].push(list.last);
|
list.prev.set(null,value);
|
||||||
// We do NOT append a new value onto "next" list. Iteration will
|
} else {
|
||||||
// figure out it must point to End-of-List on its own.
|
// Edge case, the pushed value was already the last value.
|
||||||
} else {
|
// The second-to-last nextPtr for that value must point to itself now.
|
||||||
list.prev[value] = list.last;
|
var array = list.next.get(last);
|
||||||
}
|
array[array.length-2] = value;
|
||||||
// Make the old last point to this new one.
|
|
||||||
if(typeof list.next[list.last] === "object") {
|
|
||||||
list.next[list.last].push(value);
|
|
||||||
} else {
|
|
||||||
list.next[list.last] = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
list.last = value;
|
|
||||||
list.length += 1;
|
list.length += 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -199,6 +189,20 @@ function _assertString(value) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var LLMap = function() {
|
||||||
|
this.map = Object.create(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Just a wrapper so our object map can also accept null.
|
||||||
|
LLMap.prototype = {
|
||||||
|
set: function(key,val) {
|
||||||
|
(key === null) ? (this.null = val) : (this.map[key] = val);
|
||||||
|
},
|
||||||
|
get: function(key) {
|
||||||
|
return (key === null) ? this.null : this.map[key];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
exports.LinkedList = LinkedList;
|
exports.LinkedList = LinkedList;
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -65,10 +65,8 @@ exports.addClassToParseTreeNode = function(node,classString) {
|
|||||||
// If the class attribute does not exist, we must create it first.
|
// If the class attribute does not exist, we must create it first.
|
||||||
attribute = {name: "class", type: "string", value: ""};
|
attribute = {name: "class", type: "string", value: ""};
|
||||||
node.attributes["class"] = attribute;
|
node.attributes["class"] = attribute;
|
||||||
if(node.orderedAttributes) {
|
node.orderedAttributes = node.orderedAttributes || [];
|
||||||
// If there are orderedAttributes, we've got to add them there too.
|
node.orderedAttributes.push(attribute);
|
||||||
node.orderedAttributes.push(attribute);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(attribute.type === "string") {
|
if(attribute.type === "string") {
|
||||||
if(attribute.value !== "") {
|
if(attribute.value !== "") {
|
||||||
@@ -88,10 +86,8 @@ exports.addStyleToParseTreeNode = function(node,name,value) {
|
|||||||
if(!attribute) {
|
if(!attribute) {
|
||||||
attribute = {name: "style", type: "string", value: ""};
|
attribute = {name: "style", type: "string", value: ""};
|
||||||
node.attributes.style = attribute;
|
node.attributes.style = attribute;
|
||||||
if(node.orderedAttributes) {
|
node.orderedAttributes = node.orderedAttributes || [];
|
||||||
// If there are orderedAttributes, we've got to add them there too.
|
node.orderedAttributes.push(attribute);
|
||||||
node.orderedAttributes.push(attribute);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(attribute.type === "string") {
|
if(attribute.type === "string") {
|
||||||
attribute.value += name + ":" + value + ";";
|
attribute.value += name + ":" + value + ";";
|
||||||
|
|||||||
@@ -354,6 +354,9 @@ exports.formatDateString = function(date,template) {
|
|||||||
var result = "",
|
var result = "",
|
||||||
t = template,
|
t = template,
|
||||||
matches = [
|
matches = [
|
||||||
|
[/^TIMESTAMP/, function() {
|
||||||
|
return date.getTime();
|
||||||
|
}],
|
||||||
[/^0hh12/, function() {
|
[/^0hh12/, function() {
|
||||||
return $tw.utils.pad($tw.utils.getHours12(date));
|
return $tw.utils.pad($tw.utils.getHours12(date));
|
||||||
}],
|
}],
|
||||||
@@ -682,9 +685,19 @@ exports.escapeRegExp = function(s) {
|
|||||||
return s.replace(/[\-\/\\\^\$\*\+\?\.\(\)\|\[\]\{\}]/g, '\\$&');
|
return s.replace(/[\-\/\\\^\$\*\+\?\.\(\)\|\[\]\{\}]/g, '\\$&');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Extended version of encodeURIComponent that encodes additional characters including
|
||||||
|
those that are illegal within filepaths on various platforms including Windows
|
||||||
|
*/
|
||||||
|
exports.encodeURIComponentExtended = function(s) {
|
||||||
|
return encodeURIComponent(s).replace(/[!'()*]/g,function(c) {
|
||||||
|
return "%" + c.charCodeAt(0).toString(16).toUpperCase();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Checks whether a link target is external, i.e. not a tiddler title
|
// Checks whether a link target is external, i.e. not a tiddler title
|
||||||
exports.isLinkExternal = function(to) {
|
exports.isLinkExternal = function(to) {
|
||||||
var externalRegExp = /^(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\s<>{}\[\]`|"\\^]+(?:\/|\b)/i;
|
var externalRegExp = /^(?:file|http|https|mailto|ftp|irc|news|obsidian|data|skype):[^\s<>{}\[\]`|"\\^]+(?:\/|\b)/i;
|
||||||
return externalRegExp.test(to);
|
return externalRegExp.test(to);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ Action widget to trigger a popup.
|
|||||||
|
|
||||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||||
|
|
||||||
|
var Popup = require("$:/core/modules/utils/dom/popup.js");
|
||||||
|
|
||||||
var ActionPopupWidget = function(parseTreeNode,options) {
|
var ActionPopupWidget = function(parseTreeNode,options) {
|
||||||
this.initialise(parseTreeNode,options);
|
this.initialise(parseTreeNode,options);
|
||||||
};
|
};
|
||||||
@@ -57,20 +59,20 @@ Invoke the action associated with this widget
|
|||||||
*/
|
*/
|
||||||
ActionPopupWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
ActionPopupWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||||
// Trigger the popup
|
// Trigger the popup
|
||||||
var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/,
|
var coordinates = Popup.parseCoordinates(this.actionCoords || "");
|
||||||
match = popupLocationRegExp.exec(this.actionCoords || "");
|
if(coordinates) {
|
||||||
if(match) {
|
|
||||||
$tw.popup.triggerPopup({
|
$tw.popup.triggerPopup({
|
||||||
domNode: null,
|
domNode: null,
|
||||||
domNodeRect: {
|
domNodeRect: {
|
||||||
left: parseFloat(match[1]),
|
left: coordinates.left,
|
||||||
top: parseFloat(match[2]),
|
top: coordinates.top,
|
||||||
width: parseFloat(match[3]),
|
width: coordinates.width,
|
||||||
height: parseFloat(match[4])
|
height: coordinates.height
|
||||||
},
|
},
|
||||||
title: this.actionState,
|
title: this.actionState,
|
||||||
wiki: this.wiki,
|
wiki: this.wiki,
|
||||||
floating: this.floating
|
floating: this.floating,
|
||||||
|
absolute: coordinates.absolute
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
$tw.popup.cancel(0);
|
$tw.popup.cancel(0);
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ Button widget
|
|||||||
|
|
||||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||||
|
|
||||||
|
var Popup = require("$:/core/modules/utils/dom/popup.js");
|
||||||
|
|
||||||
var ButtonWidget = function(parseTreeNode,options) {
|
var ButtonWidget = function(parseTreeNode,options) {
|
||||||
this.initialise(parseTreeNode,options);
|
this.initialise(parseTreeNode,options);
|
||||||
};
|
};
|
||||||
@@ -147,7 +149,7 @@ ButtonWidget.prototype.isSelected = function() {
|
|||||||
|
|
||||||
ButtonWidget.prototype.isPoppedUp = function() {
|
ButtonWidget.prototype.isPoppedUp = function() {
|
||||||
var tiddler = this.popupTitle ? this.wiki.getTiddler(this.popupTitle) : this.wiki.getTiddler(this.popup);
|
var tiddler = this.popupTitle ? this.wiki.getTiddler(this.popupTitle) : this.wiki.getTiddler(this.popup);
|
||||||
var result = tiddler && tiddler.fields.text ? $tw.popup.readPopupState(tiddler.fields.text) : false;
|
var result = tiddler && tiddler.fields.text ? Popup.readPopupState(tiddler.fields.text) : false;
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -173,6 +175,7 @@ ButtonWidget.prototype.triggerPopup = function(event) {
|
|||||||
if(this.popupTitle) {
|
if(this.popupTitle) {
|
||||||
$tw.popup.triggerPopup({
|
$tw.popup.triggerPopup({
|
||||||
domNode: this.domNodes[0],
|
domNode: this.domNodes[0],
|
||||||
|
absolute: (this.popupAbsCoords === "yes"),
|
||||||
title: this.popupTitle,
|
title: this.popupTitle,
|
||||||
wiki: this.wiki,
|
wiki: this.wiki,
|
||||||
noStateReference: true
|
noStateReference: true
|
||||||
@@ -180,6 +183,7 @@ ButtonWidget.prototype.triggerPopup = function(event) {
|
|||||||
} else {
|
} else {
|
||||||
$tw.popup.triggerPopup({
|
$tw.popup.triggerPopup({
|
||||||
domNode: this.domNodes[0],
|
domNode: this.domNodes[0],
|
||||||
|
absolute: (this.popupAbsCoords === "yes"),
|
||||||
title: this.popup,
|
title: this.popup,
|
||||||
wiki: this.wiki
|
wiki: this.wiki
|
||||||
});
|
});
|
||||||
@@ -223,6 +227,7 @@ ButtonWidget.prototype.execute = function() {
|
|||||||
this.setField = this.getAttribute("setField");
|
this.setField = this.getAttribute("setField");
|
||||||
this.setIndex = this.getAttribute("setIndex");
|
this.setIndex = this.getAttribute("setIndex");
|
||||||
this.popupTitle = this.getAttribute("popupTitle");
|
this.popupTitle = this.getAttribute("popupTitle");
|
||||||
|
this.popupAbsCoords = this.getAttribute("popupAbsCoords", "no");
|
||||||
this.tabIndex = this.getAttribute("tabindex");
|
this.tabIndex = this.getAttribute("tabindex");
|
||||||
this.isDisabled = this.getAttribute("disabled","no");
|
this.isDisabled = this.getAttribute("disabled","no");
|
||||||
// Make child widgets
|
// Make child widgets
|
||||||
@@ -252,7 +257,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.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) {
|
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"]) {
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
} else if(changedAttributes["class"]) {
|
} else if(changedAttributes["class"]) {
|
||||||
|
|||||||
@@ -232,12 +232,34 @@ DropZoneWidget.prototype.handleDropEvent = function(event) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DropZoneWidget.prototype.handlePasteEvent = function(event) {
|
DropZoneWidget.prototype.handlePasteEvent = function(event) {
|
||||||
var self = this,
|
var self = this;
|
||||||
readFileCallback = function(tiddlerFieldsArray) {
|
var readFileCallback = function(tiddlerFieldsArray) {
|
||||||
self.readFileCallback(tiddlerFieldsArray);
|
self.readFileCallback(tiddlerFieldsArray);
|
||||||
};
|
};
|
||||||
|
var getItem = function(type) {
|
||||||
|
type = type || "text/plain";
|
||||||
|
return function(str) {
|
||||||
|
// Use the deserializer specified if any
|
||||||
|
if(self.dropzoneDeserializer) {
|
||||||
|
tiddlerFields = self.wiki.deserializeTiddlers(null,str,{title: self.wiki.generateNewTitle("Untitled " + type)},{deserializer:self.dropzoneDeserializer});
|
||||||
|
if(tiddlerFields && tiddlerFields.length) {
|
||||||
|
readFileCallback(tiddlerFields);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tiddlerFields = {
|
||||||
|
title: self.wiki.generateNewTitle("Untitled " + type),
|
||||||
|
text: str,
|
||||||
|
type: type
|
||||||
|
};
|
||||||
|
if($tw.log.IMPORT) {
|
||||||
|
console.log("Importing string '" + str + "', type: '" + type + "'");
|
||||||
|
}
|
||||||
|
readFileCallback([tiddlerFields]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
// Let the browser handle it if we're in a textarea or input box
|
// Let the browser handle it if we're in a textarea or input box
|
||||||
if(["TEXTAREA","INPUT"].indexOf(event.target.tagName) == -1 && !event.target.isContentEditable) {
|
if(["TEXTAREA","INPUT"].indexOf(event.target.tagName) == -1 && !event.target.isContentEditable && !event.twEditor) {
|
||||||
var self = this,
|
var self = this,
|
||||||
items = event.clipboardData.items;
|
items = event.clipboardData.items;
|
||||||
// Enumerate the clipboard items
|
// Enumerate the clipboard items
|
||||||
@@ -251,27 +273,10 @@ DropZoneWidget.prototype.handlePasteEvent = function(event) {
|
|||||||
});
|
});
|
||||||
} else if(item.kind === "string") {
|
} else if(item.kind === "string") {
|
||||||
// Create tiddlers from string items
|
// Create tiddlers from string items
|
||||||
var tiddlerFields,
|
var tiddlerFields;
|
||||||
type = item.type;
|
// It's important to give getAsString a closure with the right type
|
||||||
item.getAsString(function(str) {
|
// So it can be added to the import queue
|
||||||
// Use the deserializer specified if any
|
item.getAsString(getItem(item.type));
|
||||||
if(self.dropzoneDeserializer) {
|
|
||||||
tiddlerFields = self.wiki.deserializeTiddlers(null,str,{title: self.wiki.generateNewTitle("Untitled")},{deserializer:self.dropzoneDeserializer});
|
|
||||||
if(tiddlerFields && tiddlerFields.length) {
|
|
||||||
readFileCallback(tiddlerFields);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tiddlerFields = {
|
|
||||||
title: self.wiki.generateNewTitle("Untitled"),
|
|
||||||
text: str,
|
|
||||||
type: type
|
|
||||||
};
|
|
||||||
if($tw.log.IMPORT) {
|
|
||||||
console.log("Importing string '" + str + "', type: '" + type + "'");
|
|
||||||
}
|
|
||||||
readFileCallback([tiddlerFields]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Tell the browser that we've handled the paste
|
// Tell the browser that we've handled the paste
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ ElementWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
if($tw.config.htmlUnsafeElements.indexOf(this.tag) !== -1) {
|
if($tw.config.htmlUnsafeElements.indexOf(this.tag) !== -1) {
|
||||||
this.tag = "safe-" + this.tag;
|
this.tag = "safe-" + this.tag;
|
||||||
}
|
}
|
||||||
|
// Restrict tag name to digits, letts and dashes
|
||||||
|
this.tag = this.tag.replace(/[^0-9a-zA-Z\-]/mg,"");
|
||||||
|
// Default to a span
|
||||||
|
this.tag = this.tag || "span";
|
||||||
// Adjust headings by the current base level
|
// Adjust headings by the current base level
|
||||||
var headingLevel = ["h1","h2","h3","h4","h5","h6"].indexOf(this.tag);
|
var headingLevel = ["h1","h2","h3","h4","h5","h6"].indexOf(this.tag);
|
||||||
if(headingLevel !== -1) {
|
if(headingLevel !== -1) {
|
||||||
|
|||||||
30
core/modules/widgets/fill.js
Normal file
30
core/modules/widgets/fill.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/widgets/fill.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: widget
|
||||||
|
|
||||||
|
Sub-widget used by the transclude widget for specifying values for slots within transcluded content. It doesn't do anything by itself because the transclude widget only ever deals with the parse tree nodes, and doesn't instantiate the widget itself
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||||
|
|
||||||
|
var FillWidget = function(parseTreeNode,options) {
|
||||||
|
// Initialise
|
||||||
|
this.initialise(parseTreeNode,options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inherit from the base widget class
|
||||||
|
*/
|
||||||
|
FillWidget.prototype = new Widget();
|
||||||
|
|
||||||
|
exports.fill = FillWidget;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
@@ -42,10 +42,16 @@ Compute the internal state of the widget
|
|||||||
GenesisWidget.prototype.execute = function() {
|
GenesisWidget.prototype.execute = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
// Collect attributes
|
// Collect attributes
|
||||||
this.genesisType = this.getAttribute("$type","element");
|
this.genesisType = this.getAttribute("$type");
|
||||||
this.genesisRemappable = this.getAttribute("$remappable","yes") === "yes";
|
this.genesisRemappable = this.getAttribute("$remappable","yes") === "yes";
|
||||||
this.genesisNames = this.getAttribute("$names","");
|
this.genesisNames = this.getAttribute("$names","");
|
||||||
this.genesisValues = this.getAttribute("$values","");
|
this.genesisValues = this.getAttribute("$values","");
|
||||||
|
this.genesisIsBlock = this.getAttribute("$mode",this.parseTreeNode.isBlock && "block") === "block";
|
||||||
|
// Do not create a child widget if the $type attribute is missing or blank
|
||||||
|
if(!this.genesisType) {
|
||||||
|
this.makeChildWidgets(this.parseTreeNode.children);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Construct parse tree
|
// Construct parse tree
|
||||||
var isElementWidget = this.genesisType.charAt(0) !== "$",
|
var isElementWidget = this.genesisType.charAt(0) !== "$",
|
||||||
nodeType = isElementWidget ? "element" : this.genesisType.substr(1),
|
nodeType = isElementWidget ? "element" : this.genesisType.substr(1),
|
||||||
@@ -55,6 +61,7 @@ GenesisWidget.prototype.execute = function() {
|
|||||||
tag: nodeTag,
|
tag: nodeTag,
|
||||||
attributes: {},
|
attributes: {},
|
||||||
orderedAttributes: [],
|
orderedAttributes: [],
|
||||||
|
isBlock: this.genesisIsBlock,
|
||||||
children: this.parseTreeNode.children || [],
|
children: this.parseTreeNode.children || [],
|
||||||
isNotRemappable: !this.genesisRemappable
|
isNotRemappable: !this.genesisRemappable
|
||||||
}];
|
}];
|
||||||
|
|||||||
@@ -52,38 +52,44 @@ ImportVariablesWidget.prototype.execute = function(tiddlerList) {
|
|||||||
var parser = widgetPointer.wiki.parseTiddler(title,{parseAsInline:true});
|
var parser = widgetPointer.wiki.parseTiddler(title,{parseAsInline:true});
|
||||||
if(parser) {
|
if(parser) {
|
||||||
var parseTreeNode = parser.tree[0];
|
var parseTreeNode = parser.tree[0];
|
||||||
while(parseTreeNode && parseTreeNode.type === "set") {
|
while(parseTreeNode && ["setvariable","set","parameters"].indexOf(parseTreeNode.type) !== -1) {
|
||||||
var node = {
|
var node = {
|
||||||
type: "set",
|
type: "set",
|
||||||
attributes: parseTreeNode.attributes,
|
attributes: parseTreeNode.attributes,
|
||||||
params: parseTreeNode.params,
|
params: parseTreeNode.params,
|
||||||
isMacroDefinition: parseTreeNode.isMacroDefinition
|
isMacroDefinition: parseTreeNode.isMacroDefinition,
|
||||||
|
isFunctionDefinition: parseTreeNode.isFunctionDefinition,
|
||||||
|
isProcedureDefinition: parseTreeNode.isProcedureDefinition,
|
||||||
|
isWidgetDefinition: parseTreeNode.isWidgetDefinition,
|
||||||
|
configTrimWhiteSpace: parseTreeNode.configTrimWhiteSpace
|
||||||
};
|
};
|
||||||
if (parseTreeNode.isMacroDefinition) {
|
if(parseTreeNode.type === "set" || parseTreeNode.type === "setvariable") {
|
||||||
// Macro definitions can be folded into
|
if(parseTreeNode.isMacroDefinition || parseTreeNode.isProcedureDefinition || parseTreeNode.isWidgetDefinition || parseTreeNode.isFunctionDefinition) {
|
||||||
// current widget instead of adding
|
// Macro definitions can be folded into
|
||||||
// another link to the chain.
|
// current widget instead of adding
|
||||||
var widget = widgetPointer.makeChildWidget(node);
|
// another link to the chain.
|
||||||
widget.computeAttributes();
|
var widget = widgetPointer.makeChildWidget(node);
|
||||||
widget.execute();
|
widget.computeAttributes();
|
||||||
// We SHALLOW copy over all variables
|
widget.execute();
|
||||||
// in widget. We can't use
|
// We SHALLOW copy over all variables
|
||||||
// $tw.utils.assign, because that copies
|
// in widget. We can't use
|
||||||
// up the prototype chain, which we
|
// $tw.utils.assign, because that copies
|
||||||
// don't want.
|
// up the prototype chain, which we
|
||||||
$tw.utils.each(Object.keys(widget.variables), function(key) {
|
// don't want.
|
||||||
widgetPointer.variables[key] = widget.variables[key];
|
$tw.utils.each(Object.keys(widget.variables), function(key) {
|
||||||
});
|
widgetPointer.variables[key] = widget.variables[key];
|
||||||
} else {
|
});
|
||||||
widgetPointer.children = [widgetPointer.makeChildWidget(node)];
|
} else {
|
||||||
// No more regenerating children for
|
widgetPointer.children = [widgetPointer.makeChildWidget(node)];
|
||||||
// this widget. If it needs to refresh,
|
// No more regenerating children for
|
||||||
// it'll do so along with the the whole
|
// this widget. If it needs to refresh,
|
||||||
// importvariable tree.
|
// it'll do so along with the the whole
|
||||||
if (widgetPointer != this) {
|
// importvariable tree.
|
||||||
widgetPointer.makeChildWidgets = function(){};
|
if (widgetPointer != this) {
|
||||||
|
widgetPointer.makeChildWidgets = function(){};
|
||||||
|
}
|
||||||
|
widgetPointer = widgetPointer.children[0];
|
||||||
}
|
}
|
||||||
widgetPointer = widgetPointer.children[0];
|
|
||||||
}
|
}
|
||||||
parseTreeNode = parseTreeNode.children && parseTreeNode.children[0];
|
parseTreeNode = parseTreeNode.children && parseTreeNode.children[0];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ KeyboardWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
KeyboardWidget.prototype.handleChangeEvent = function(event) {
|
KeyboardWidget.prototype.handleChangeEvent = function(event) {
|
||||||
|
if ($tw.keyboardManager.handleKeydownEvent(event, {onlyPriority: true})) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var keyInfo = $tw.keyboardManager.getMatchingKeyDescriptor(event,this.keyInfoArray);
|
var keyInfo = $tw.keyboardManager.getMatchingKeyDescriptor(event,this.keyInfoArray);
|
||||||
if(keyInfo) {
|
if(keyInfo) {
|
||||||
var handled = this.invokeActions(this,event);
|
var handled = this.invokeActions(this,event);
|
||||||
|
|||||||
@@ -53,7 +53,9 @@ LetWidget.prototype.computeAttributes = function() {
|
|||||||
name = attribute.name;
|
name = attribute.name;
|
||||||
// Now that it's prepped, we're allowed to look this variable up
|
// Now that it's prepped, we're allowed to look this variable up
|
||||||
// when defining later variables
|
// when defining later variables
|
||||||
self.currentValueFor[name] = value;
|
if(value !== undefined) {
|
||||||
|
self.currentValueFor[name] = value;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// Run through again, setting variables and looking for differences
|
// Run through again, setting variables and looking for differences
|
||||||
$tw.utils.each(this.currentValueFor,function(value,name) {
|
$tw.utils.each(this.currentValueFor,function(value,name) {
|
||||||
|
|||||||
@@ -97,8 +97,8 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
|||||||
// Expand the tv-wikilink-template variable to construct the href
|
// Expand the tv-wikilink-template variable to construct the href
|
||||||
var wikiLinkTemplateMacro = this.getVariable("tv-wikilink-template"),
|
var wikiLinkTemplateMacro = this.getVariable("tv-wikilink-template"),
|
||||||
wikiLinkTemplate = wikiLinkTemplateMacro ? wikiLinkTemplateMacro.trim() : "#$uri_encoded$";
|
wikiLinkTemplate = wikiLinkTemplateMacro ? wikiLinkTemplateMacro.trim() : "#$uri_encoded$";
|
||||||
wikiLinkText = $tw.utils.replaceString(wikiLinkTemplate,"$uri_encoded$",encodeURIComponent(this.to));
|
wikiLinkText = $tw.utils.replaceString(wikiLinkTemplate,"$uri_encoded$",$tw.utils.encodeURIComponentExtended(this.to));
|
||||||
wikiLinkText = $tw.utils.replaceString(wikiLinkText,"$uri_doubleencoded$",encodeURIComponent(encodeURIComponent(this.to)));
|
wikiLinkText = $tw.utils.replaceString(wikiLinkText,"$uri_doubleencoded$",$tw.utils.encodeURIComponentExtended($tw.utils.encodeURIComponentExtended(this.to)));
|
||||||
}
|
}
|
||||||
// Override with the value of tv-get-export-link if defined
|
// Override with the value of tv-get-export-link if defined
|
||||||
wikiLinkText = this.getVariable("tv-get-export-link",{params: [{name: "to",value: this.to}],defaultValue: wikiLinkText});
|
wikiLinkText = this.getVariable("tv-get-export-link",{params: [{name: "to",value: this.to}],defaultValue: wikiLinkText});
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ MacroCallWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
Compute the internal state of the widget
|
Compute the internal state of the widget
|
||||||
*/
|
*/
|
||||||
MacroCallWidget.prototype.execute = function() {
|
MacroCallWidget.prototype.execute = function() {
|
||||||
// Get the parse type if specified
|
this.macroName = this.parseTreeNode.name || this.getAttribute("$name"),
|
||||||
this.parseType = this.getAttribute("$type","text/vnd.tiddlywiki");
|
this.parseType = this.getAttribute("$type","text/vnd.tiddlywiki");
|
||||||
this.renderOutput = this.getAttribute("$output","text/html");
|
this.renderOutput = this.getAttribute("$output","text/html");
|
||||||
// Merge together the parameters specified in the parse tree with the specified attributes
|
// Merge together the parameters specified in the parse tree with the specified attributes
|
||||||
@@ -47,49 +47,26 @@ MacroCallWidget.prototype.execute = function() {
|
|||||||
params.push({name: name, value: attribute});
|
params.push({name: name, value: attribute});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Get the macro value
|
// Make a transclude widget
|
||||||
var macroName = this.parseTreeNode.name || this.getAttribute("$name"),
|
var positionalName = 0,
|
||||||
variableInfo = this.getVariableInfo(macroName,{params: params}),
|
|
||||||
text = variableInfo.text,
|
|
||||||
parseTreeNodes;
|
|
||||||
// Are we rendering to HTML?
|
|
||||||
if(this.renderOutput === "text/html") {
|
|
||||||
// If so we'll return the parsed macro
|
|
||||||
// Check if we've already cached parsing this macro
|
|
||||||
var mode = this.parseTreeNode.isBlock ? "blockParser" : "inlineParser",
|
|
||||||
parser;
|
|
||||||
if(variableInfo.srcVariable && variableInfo.srcVariable[mode]) {
|
|
||||||
parser = variableInfo.srcVariable[mode];
|
|
||||||
} else {
|
|
||||||
parser = this.wiki.parseText(this.parseType,text,
|
|
||||||
{parseAsInline: !this.parseTreeNode.isBlock});
|
|
||||||
if(variableInfo.isCacheable && variableInfo.srcVariable) {
|
|
||||||
variableInfo.srcVariable[mode] = parser;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var parseTreeNodes = parser ? parser.tree : [];
|
|
||||||
// Wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
|
|
||||||
var attributes = {};
|
|
||||||
$tw.utils.each(variableInfo.params,function(param) {
|
|
||||||
var name = "__" + param.name + "__";
|
|
||||||
attributes[name] = {
|
|
||||||
name: name,
|
|
||||||
type: "string",
|
|
||||||
value: param.value
|
|
||||||
};
|
|
||||||
});
|
|
||||||
parseTreeNodes = [{
|
parseTreeNodes = [{
|
||||||
type: "vars",
|
type: "transclude",
|
||||||
attributes: attributes,
|
isBlock: this.parseTreeNode.isBlock
|
||||||
children: parseTreeNodes
|
|
||||||
}];
|
}];
|
||||||
} else if(this.renderOutput === "text/raw") {
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$variable",this.macroName);
|
||||||
parseTreeNodes = [{type: "text", text: text}];
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$type",this.parseType);
|
||||||
} else {
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$output",this.renderOutput);
|
||||||
// Otherwise, we'll render the text
|
$tw.utils.each(params,function(param) {
|
||||||
var plainText = this.wiki.renderText("text/plain",this.parseType,text,{parentWidget: this});
|
var name = param.name;
|
||||||
parseTreeNodes = [{type: "text", text: plainText}];
|
if(name) {
|
||||||
}
|
if(name.charAt(0) === "$") {
|
||||||
|
name = "$" + name;
|
||||||
|
}
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],name,param.value);
|
||||||
|
} else {
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],(positionalName++) + "",param.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
// Construct the child widgets
|
// Construct the child widgets
|
||||||
this.makeChildWidgets(parseTreeNodes);
|
this.makeChildWidgets(parseTreeNodes);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ MessageCatcherWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Render children
|
// Render children
|
||||||
this.renderChildren(parent,null);
|
this.renderChildren(parent,nextSibling);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -227,10 +227,7 @@ NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {
|
|||||||
originalTitle = tiddler ? tiddler.fields["draft.of"] : "",
|
originalTitle = tiddler ? tiddler.fields["draft.of"] : "",
|
||||||
originalTiddler = originalTitle ? this.wiki.getTiddler(originalTitle) : undefined,
|
originalTiddler = originalTitle ? this.wiki.getTiddler(originalTitle) : undefined,
|
||||||
confirmationTitle,
|
confirmationTitle,
|
||||||
win = event.event && event.event.view ? event.event.view : window;
|
win = event.event && event.event.view ? event.event.view : window;
|
||||||
if(!tiddler) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Check if the tiddler we're deleting is in draft mode
|
// Check if the tiddler we're deleting is in draft mode
|
||||||
if(originalTitle) {
|
if(originalTitle) {
|
||||||
// If so, we'll prompt for confirmation referencing the original tiddler
|
// If so, we'll prompt for confirmation referencing the original tiddler
|
||||||
@@ -240,7 +237,7 @@ NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {
|
|||||||
confirmationTitle = title;
|
confirmationTitle = title;
|
||||||
}
|
}
|
||||||
// Seek confirmation
|
// Seek confirmation
|
||||||
if((this.wiki.getTiddler(originalTitle) || (tiddler.fields.text || "") !== "") && !win.confirm($tw.language.getString(
|
if(((originalTitle && this.wiki.getTiddler(originalTitle)) || (tiddler && ((tiddler.fields.text || "") !== ""))) && !win.confirm($tw.language.getString(
|
||||||
"ConfirmDeleteTiddler",
|
"ConfirmDeleteTiddler",
|
||||||
{variables:
|
{variables:
|
||||||
{title: confirmationTitle}
|
{title: confirmationTitle}
|
||||||
@@ -257,8 +254,10 @@ NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {
|
|||||||
this.removeTitleFromStory(storyList,originalTitle);
|
this.removeTitleFromStory(storyList,originalTitle);
|
||||||
}
|
}
|
||||||
// Invoke the hook function and delete this tiddler
|
// Invoke the hook function and delete this tiddler
|
||||||
$tw.hooks.invokeHook("th-deleting-tiddler",tiddler);
|
if(tiddler) {
|
||||||
this.wiki.deleteTiddler(title);
|
$tw.hooks.invokeHook("th-deleting-tiddler",tiddler);
|
||||||
|
this.wiki.deleteTiddler(title);
|
||||||
|
}
|
||||||
// Remove the closed tiddler from the story
|
// Remove the closed tiddler from the story
|
||||||
this.removeTitleFromStory(storyList,title);
|
this.removeTitleFromStory(storyList,title);
|
||||||
this.saveStoryList(storyList);
|
this.saveStoryList(storyList);
|
||||||
@@ -500,7 +499,8 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
|
|||||||
// Get the tiddlers
|
// Get the tiddlers
|
||||||
var tiddlers = $tw.utils.parseJSONSafe(event.param,[]);
|
var tiddlers = $tw.utils.parseJSONSafe(event.param,[]);
|
||||||
// Get the current $:/Import tiddler
|
// Get the current $:/Import tiddler
|
||||||
var importTitle = event.importTitle ? event.importTitle : IMPORT_TITLE,
|
var paramObject = event.paramObject || {},
|
||||||
|
importTitle = event.importTitle || paramObject.importTitle || IMPORT_TITLE,
|
||||||
importTiddler = this.wiki.getTiddler(importTitle),
|
importTiddler = this.wiki.getTiddler(importTitle),
|
||||||
importData = this.wiki.getTiddlerData(importTitle,{}),
|
importData = this.wiki.getTiddlerData(importTitle,{}),
|
||||||
newFields = new Object({
|
newFields = new Object({
|
||||||
@@ -541,7 +541,7 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
|
|||||||
newFields.text = JSON.stringify(importData,null,$tw.config.preferences.jsonSpaces);
|
newFields.text = JSON.stringify(importData,null,$tw.config.preferences.jsonSpaces);
|
||||||
this.wiki.addTiddler(new $tw.Tiddler(importTiddler,newFields));
|
this.wiki.addTiddler(new $tw.Tiddler(importTiddler,newFields));
|
||||||
// Update the story and history details
|
// Update the story and history details
|
||||||
var autoOpenOnImport = event.autoOpenOnImport ? event.autoOpenOnImport : this.getVariable("tv-auto-open-on-import");
|
var autoOpenOnImport = event.autoOpenOnImport || paramObject.autoOpenOnImport || this.getVariable("tv-auto-open-on-import");
|
||||||
if(autoOpenOnImport !== "no") {
|
if(autoOpenOnImport !== "no") {
|
||||||
var storyList = this.getStoryList(),
|
var storyList = this.getStoryList(),
|
||||||
history = [];
|
history = [];
|
||||||
|
|||||||
96
core/modules/widgets/parameters.js
Normal file
96
core/modules/widgets/parameters.js
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/widgets/parameters.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: widget
|
||||||
|
|
||||||
|
Widget for definition of transclusion parameters
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Widget = require("$:/core/modules/widgets/widget.js").widget,
|
||||||
|
TranscludeWidget = require("$:/core/modules/widgets/transclude.js").transclude;
|
||||||
|
|
||||||
|
var ParametersWidget = function(parseTreeNode,options) {
|
||||||
|
// Initialise
|
||||||
|
this.initialise(parseTreeNode,options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inherit from the base widget class
|
||||||
|
*/
|
||||||
|
ParametersWidget.prototype = new Widget();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Render this widget into the DOM
|
||||||
|
*/
|
||||||
|
ParametersWidget.prototype.render = function(parent,nextSibling) {
|
||||||
|
// Call the constructor
|
||||||
|
Widget.call(this);
|
||||||
|
this.parentDomNode = parent;
|
||||||
|
this.computeAttributes();
|
||||||
|
this.execute();
|
||||||
|
this.renderChildren(parent,nextSibling);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compute the internal state of the widget
|
||||||
|
*/
|
||||||
|
ParametersWidget.prototype.execute = function() {
|
||||||
|
var self = this;
|
||||||
|
this.parametersDepth = Math.max(parseInt(this.getAttribute("$depth","1"),10) || 1,1);
|
||||||
|
// Find the parent transclusions
|
||||||
|
var pointer = this.parentWidget,
|
||||||
|
depth = this.parametersDepth;
|
||||||
|
while(pointer) {
|
||||||
|
if(pointer instanceof TranscludeWidget) {
|
||||||
|
depth--;
|
||||||
|
if(depth <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pointer = pointer.parentWidget;
|
||||||
|
}
|
||||||
|
// Process each parameter
|
||||||
|
if(pointer instanceof TranscludeWidget) {
|
||||||
|
// Get the value for each defined parameter
|
||||||
|
$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 = pointer.getTransclusionParameter(name,index,self.getAttribute(attr.name,""));
|
||||||
|
self.setVariable(name,value);
|
||||||
|
});
|
||||||
|
// Assign any metaparameters
|
||||||
|
$tw.utils.each(pointer.getTransclusionMetaParameters(),function(getValue,name) {
|
||||||
|
var variableName = self.getAttribute("$" + name);
|
||||||
|
if(variableName) {
|
||||||
|
self.setVariable(variableName,getValue(name));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Construct the child widgets
|
||||||
|
this.makeChildWidgets();
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Refresh the widget by ensuring our attributes are up to date
|
||||||
|
*/
|
||||||
|
ParametersWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
|
var changedAttributes = this.computeAttributes();
|
||||||
|
if(Object.keys(changedAttributes).length) {
|
||||||
|
this.refreshSelf();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return this.refreshChildren(changedTiddlers);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.parameters = ParametersWidget;
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -14,6 +14,8 @@ Reveal widget
|
|||||||
|
|
||||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||||
|
|
||||||
|
var Popup = require("$:/core/modules/utils/dom/popup.js");
|
||||||
|
|
||||||
var RevealWidget = function(parseTreeNode,options) {
|
var RevealWidget = function(parseTreeNode,options) {
|
||||||
this.initialise(parseTreeNode,options);
|
this.initialise(parseTreeNode,options);
|
||||||
};
|
};
|
||||||
@@ -94,6 +96,13 @@ RevealWidget.prototype.positionPopup = function(domNode) {
|
|||||||
left = Math.max(0,left);
|
left = Math.max(0,left);
|
||||||
top = Math.max(0,top);
|
top = Math.max(0,top);
|
||||||
}
|
}
|
||||||
|
if (this.popup.absolute) {
|
||||||
|
// Traverse the offsetParent chain and correct the offset to make it relative to the parent node.
|
||||||
|
for (var offsetParentDomNode = domNode.offsetParent; offsetParentDomNode; offsetParentDomNode = offsetParentDomNode.offsetParent) {
|
||||||
|
left -= offsetParentDomNode.offsetLeft;
|
||||||
|
top -= offsetParentDomNode.offsetTop;
|
||||||
|
}
|
||||||
|
}
|
||||||
domNode.style.left = left + "px";
|
domNode.style.left = left + "px";
|
||||||
domNode.style.top = top + "px";
|
domNode.style.top = top + "px";
|
||||||
};
|
};
|
||||||
@@ -183,19 +192,11 @@ RevealWidget.prototype.compareStateText = function(state) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
RevealWidget.prototype.readPopupState = function(state) {
|
RevealWidget.prototype.readPopupState = function(state) {
|
||||||
var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/,
|
this.popup = Popup.parseCoordinates(state);
|
||||||
match = popupLocationRegExp.exec(state);
|
|
||||||
// Check if the state matches the location regexp
|
// Check if the state matches the location regexp
|
||||||
if(match) {
|
if(this.popup) {
|
||||||
// If so, we're open
|
// If so, we're open
|
||||||
this.isOpen = true;
|
this.isOpen = true;
|
||||||
// Get the location
|
|
||||||
this.popup = {
|
|
||||||
left: parseFloat(match[1]),
|
|
||||||
top: parseFloat(match[2]),
|
|
||||||
width: parseFloat(match[3]),
|
|
||||||
height: parseFloat(match[4])
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
// If not, we're closed
|
// If not, we're closed
|
||||||
this.isOpen = false;
|
this.isOpen = false;
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ SelectWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
this.execute();
|
this.execute();
|
||||||
this.renderChildren(parent,nextSibling);
|
this.renderChildren(parent,nextSibling);
|
||||||
this.setSelectValue();
|
this.setSelectValue();
|
||||||
|
if(this.selectFocus == "yes") {
|
||||||
|
this.getSelectDomNode().focus();
|
||||||
|
}
|
||||||
$tw.utils.addEventListeners(this.getSelectDomNode(),[
|
$tw.utils.addEventListeners(this.getSelectDomNode(),[
|
||||||
{name: "change", handlerObject: this, handlerMethod: "handleChangeEvent"}
|
{name: "change", handlerObject: this, handlerMethod: "handleChangeEvent"}
|
||||||
]);
|
]);
|
||||||
@@ -143,6 +146,7 @@ SelectWidget.prototype.execute = function() {
|
|||||||
this.selectMultiple = this.getAttribute("multiple", false);
|
this.selectMultiple = this.getAttribute("multiple", false);
|
||||||
this.selectSize = this.getAttribute("size");
|
this.selectSize = this.getAttribute("size");
|
||||||
this.selectTooltip = this.getAttribute("tooltip");
|
this.selectTooltip = this.getAttribute("tooltip");
|
||||||
|
this.selectFocus = this.getAttribute("focus");
|
||||||
// Make the child widgets
|
// Make the child widgets
|
||||||
var selectNode = {
|
var selectNode = {
|
||||||
type: "element",
|
type: "element",
|
||||||
@@ -175,6 +179,11 @@ SelectWidget.prototype.refresh = function(changedTiddlers) {
|
|||||||
return true;
|
return true;
|
||||||
// If the target tiddler value has changed, just update setting and refresh the children
|
// If the target tiddler value has changed, just update setting and refresh the children
|
||||||
} else {
|
} else {
|
||||||
|
if(changedAttributes.class) {
|
||||||
|
this.selectClass = this.getAttribute("class");
|
||||||
|
this.getSelectDomNode().setAttribute("class",this.selectClass);
|
||||||
|
}
|
||||||
|
|
||||||
var childrenRefreshed = this.refreshChildren(changedTiddlers);
|
var childrenRefreshed = this.refreshChildren(changedTiddlers);
|
||||||
if(changedTiddlers[this.selectTitle] || childrenRefreshed) {
|
if(changedTiddlers[this.selectTitle] || childrenRefreshed) {
|
||||||
this.setSelectValue();
|
this.setSelectValue();
|
||||||
|
|||||||
@@ -48,7 +48,17 @@ SetWidget.prototype.execute = function() {
|
|||||||
this.setValue = this.getAttribute("value");
|
this.setValue = this.getAttribute("value");
|
||||||
this.setEmptyValue = this.getAttribute("emptyValue");
|
this.setEmptyValue = this.getAttribute("emptyValue");
|
||||||
// Set context variable
|
// Set context variable
|
||||||
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,!!this.parseTreeNode.isMacroDefinition);
|
if(this.parseTreeNode.isMacroDefinition) {
|
||||||
|
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,true);
|
||||||
|
} else if(this.parseTreeNode.isFunctionDefinition) {
|
||||||
|
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isFunctionDefinition: true});
|
||||||
|
} else if(this.parseTreeNode.isProcedureDefinition) {
|
||||||
|
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isProcedureDefinition: true, configTrimWhiteSpace: this.parseTreeNode.configTrimWhiteSpace});
|
||||||
|
} else if(this.parseTreeNode.isWidgetDefinition) {
|
||||||
|
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isWidgetDefinition: true, configTrimWhiteSpace: this.parseTreeNode.configTrimWhiteSpace});
|
||||||
|
} else {
|
||||||
|
this.setVariable(this.setName,this.getValue());
|
||||||
|
}
|
||||||
// Construct the child widgets
|
// Construct the child widgets
|
||||||
this.makeChildWidgets();
|
this.makeChildWidgets();
|
||||||
};
|
};
|
||||||
|
|||||||
82
core/modules/widgets/slot.js
Normal file
82
core/modules/widgets/slot.js
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/widgets/slot.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: widget
|
||||||
|
|
||||||
|
Widget for definition of slots within transcluded content. The values provided by the translusion are passed to the slot.
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Widget = require("$:/core/modules/widgets/widget.js").widget,
|
||||||
|
TranscludeWidget = require("$:/core/modules/widgets/transclude.js").transclude;
|
||||||
|
|
||||||
|
var SlotWidget = function(parseTreeNode,options) {
|
||||||
|
// Initialise
|
||||||
|
this.initialise(parseTreeNode,options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inherit from the base widget class
|
||||||
|
*/
|
||||||
|
SlotWidget.prototype = new Widget();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Render this widget into the DOM
|
||||||
|
*/
|
||||||
|
SlotWidget.prototype.render = function(parent,nextSibling) {
|
||||||
|
// Call the constructor
|
||||||
|
Widget.call(this);
|
||||||
|
this.parentDomNode = parent;
|
||||||
|
this.computeAttributes();
|
||||||
|
this.execute();
|
||||||
|
this.renderChildren(parent,nextSibling);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compute the internal state of the widget
|
||||||
|
*/
|
||||||
|
SlotWidget.prototype.execute = function() {
|
||||||
|
var self = this;
|
||||||
|
this.slotName = this.getAttribute("$name");
|
||||||
|
this.slotDepth = parseInt(this.getAttribute("$depth","1"),10) || 1;
|
||||||
|
// Find the parent transclusions
|
||||||
|
var pointer = this.parentWidget,
|
||||||
|
depth = this.slotDepth;
|
||||||
|
while(pointer) {
|
||||||
|
if(pointer instanceof TranscludeWidget) {
|
||||||
|
depth--;
|
||||||
|
if(depth <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pointer = pointer.parentWidget;
|
||||||
|
}
|
||||||
|
var parseTreeNodes = [{type: "text", attributes: {text: {type: "string", value: "Missing slot reference!"}}}];
|
||||||
|
if(pointer instanceof TranscludeWidget) {
|
||||||
|
// Get the parse tree nodes comprising the slot contents
|
||||||
|
parseTreeNodes = pointer.getTransclusionSlotFill(this.slotName,this.parseTreeNode.children);
|
||||||
|
}
|
||||||
|
// Construct the child widgets
|
||||||
|
this.makeChildWidgets(parseTreeNodes);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Refresh the widget by ensuring our attributes are up to date
|
||||||
|
*/
|
||||||
|
SlotWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
|
var changedAttributes = this.computeAttributes();
|
||||||
|
if(changedAttributes["$name"] || changedAttributes["$depth"]) {
|
||||||
|
this.refreshSelf();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return this.refreshChildren(changedTiddlers);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.slot = SlotWidget;
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -37,48 +37,349 @@ TranscludeWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
Compute the internal state of the widget
|
Compute the internal state of the widget
|
||||||
*/
|
*/
|
||||||
TranscludeWidget.prototype.execute = function() {
|
TranscludeWidget.prototype.execute = function() {
|
||||||
// Get our parameters
|
// Get our attributes, string parameters, and slot values into properties of the widget object
|
||||||
this.transcludeTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
|
this.collectAttributes();
|
||||||
this.transcludeSubTiddler = this.getAttribute("subtiddler");
|
this.collectStringParameters();
|
||||||
this.transcludeField = this.getAttribute("field");
|
this.collectSlotFillParameters();
|
||||||
this.transcludeIndex = this.getAttribute("index");
|
// Get the parse tree nodes that we are transcluding
|
||||||
this.transcludeMode = this.getAttribute("mode");
|
var target = this.getTransclusionTarget(),
|
||||||
this.recursionMarker = this.getAttribute("recursionMarker","yes");
|
parseTreeNodes = target.parseTreeNodes;
|
||||||
// Parse the text reference
|
this.sourceText = target.text;
|
||||||
|
this.sourceType = target.type;
|
||||||
|
this.parseAsInline = target.parseAsInline;
|
||||||
|
// Process the transclusion according to the output type
|
||||||
|
switch(this.transcludeOutput || "text/html") {
|
||||||
|
case "text/html":
|
||||||
|
// No further processing required
|
||||||
|
break;
|
||||||
|
case "text/raw":
|
||||||
|
// Just return the raw text
|
||||||
|
parseTreeNodes = [{type: "text", text: this.sourceText}];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// text/plain
|
||||||
|
var plainText = this.wiki.renderText("text/plain",this.sourceType,this.sourceText,{parentWidget: this});
|
||||||
|
parseTreeNodes = [{type: "text", text: plainText}];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Set the legacy transclusion context variables only if we're not transcluding a variable
|
||||||
|
if(!this.transcludeVariable) {
|
||||||
|
var recursionMarker = this.makeRecursionMarker();
|
||||||
|
this.setVariable("transclusion",recursionMarker);
|
||||||
|
}
|
||||||
|
// Construct the child widgets
|
||||||
|
this.makeChildWidgets(parseTreeNodes);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Collect the attributes we need, in the process determining whether we're being used in legacy mode
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.collectAttributes = function() {
|
||||||
|
var self = this;
|
||||||
|
// Detect legacy mode
|
||||||
|
this.legacyMode = true;
|
||||||
|
$tw.utils.each(this.attributes,function(value,name) {
|
||||||
|
if(name.charAt(0) === "$") {
|
||||||
|
self.legacyMode = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Get the attributes for the appropriate mode
|
||||||
|
if(this.legacyMode) {
|
||||||
|
this.transcludeTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
|
||||||
|
this.transcludeSubTiddler = this.getAttribute("subtiddler");
|
||||||
|
this.transcludeField = this.getAttribute("field");
|
||||||
|
this.transcludeIndex = this.getAttribute("index");
|
||||||
|
this.transcludeMode = this.getAttribute("mode");
|
||||||
|
this.recursionMarker = this.getAttribute("recursionMarker","yes");
|
||||||
|
} else {
|
||||||
|
this.transcludeVariable = this.getAttribute("$variable");
|
||||||
|
this.transcludeType = this.getAttribute("$type");
|
||||||
|
this.transcludeOutput = this.getAttribute("$output","text/html");
|
||||||
|
this.transcludeTitle = this.getAttribute("$tiddler",this.getVariable("currentTiddler"));
|
||||||
|
this.transcludeSubTiddler = this.getAttribute("$subtiddler");
|
||||||
|
this.transcludeField = this.getAttribute("$field");
|
||||||
|
this.transcludeIndex = this.getAttribute("$index");
|
||||||
|
this.transcludeMode = this.getAttribute("$mode");
|
||||||
|
this.recursionMarker = this.getAttribute("$recursionMarker","yes");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Collect string parameters
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.collectStringParameters = function() {
|
||||||
|
var self = this;
|
||||||
|
this.stringParametersByName = Object.create(null);
|
||||||
|
if(!this.legacyMode) {
|
||||||
|
$tw.utils.each(this.attributes,function(value,name) {
|
||||||
|
if(name.charAt(0) === "$") {
|
||||||
|
if(name.charAt(1) === "$") {
|
||||||
|
// Attributes starting $$ represent parameters starting with a single $
|
||||||
|
name = name.slice(1);
|
||||||
|
} else {
|
||||||
|
// Attributes starting with a single $ are reserved for the widget
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.stringParametersByName[name] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Collect slot value parameters
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.collectSlotFillParameters = function() {
|
||||||
|
var self = this;
|
||||||
|
this.slotFillParseTrees = Object.create(null);
|
||||||
|
if(this.legacyMode) {
|
||||||
|
this.slotFillParseTrees["ts-missing"] = this.parseTreeNode.children;
|
||||||
|
} else {
|
||||||
|
this.slotFillParseTrees["ts-raw"] = this.parseTreeNode.children;
|
||||||
|
var noFillWidgetsFound = true,
|
||||||
|
searchParseTreeNodes = function(nodes) {
|
||||||
|
$tw.utils.each(nodes,function(node) {
|
||||||
|
if(node.type === "fill") {
|
||||||
|
if(node.attributes["$name"] && node.attributes["$name"].type === "string") {
|
||||||
|
var slotValueName = node.attributes["$name"].value;
|
||||||
|
self.slotFillParseTrees[slotValueName] = node.children || [];
|
||||||
|
}
|
||||||
|
noFillWidgetsFound = false;
|
||||||
|
} else {
|
||||||
|
searchParseTreeNodes(node.children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
searchParseTreeNodes(this.parseTreeNode.children);
|
||||||
|
if(noFillWidgetsFound) {
|
||||||
|
this.slotFillParseTrees["ts-missing"] = this.parseTreeNode.children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get transcluded parse tree nodes as an object {parser:,text:,type:}
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.getTransclusionTarget = function() {
|
||||||
|
var self = this;
|
||||||
|
// Determine whether we're being used in inline or block mode
|
||||||
var parseAsInline = !this.parseTreeNode.isBlock;
|
var parseAsInline = !this.parseTreeNode.isBlock;
|
||||||
if(this.transcludeMode === "inline") {
|
if(this.transcludeMode === "inline") {
|
||||||
parseAsInline = true;
|
parseAsInline = true;
|
||||||
} else if(this.transcludeMode === "block") {
|
} else if(this.transcludeMode === "block") {
|
||||||
parseAsInline = false;
|
parseAsInline = false;
|
||||||
}
|
}
|
||||||
var parser = this.wiki.parseTextReference(
|
var parser;
|
||||||
|
// Get the parse tree
|
||||||
|
if(this.transcludeVariable) {
|
||||||
|
// Transcluding a variable
|
||||||
|
var variableInfo = this.getVariableInfo(this.transcludeVariable,{params: this.getOrderedTransclusionParameters()}),
|
||||||
|
srcVariable = variableInfo && variableInfo.srcVariable;
|
||||||
|
if(srcVariable) {
|
||||||
|
if(srcVariable.isFunctionDefinition) {
|
||||||
|
// Function to return parameters by name or position
|
||||||
|
var fnGetParam = function(name,index) {
|
||||||
|
// Parameter names starting with dollar must be escaped to double dollars
|
||||||
|
if(name.charAt(0) === "$") {
|
||||||
|
name = "$" + name;
|
||||||
|
}
|
||||||
|
// Look for the parameter by name
|
||||||
|
if(self.hasAttribute(name)) {
|
||||||
|
return self.getAttribute(name);
|
||||||
|
// Look for the parameter by index
|
||||||
|
} else if(self.hasAttribute(index + "")) {
|
||||||
|
return self.getAttribute(index + "");
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
result = this.evaluateVariable(this.transcludeVariable,{params: fnGetParam})[0] || "";
|
||||||
|
parser = {
|
||||||
|
tree: [{
|
||||||
|
type: "text",
|
||||||
|
text: result
|
||||||
|
}],
|
||||||
|
source: result,
|
||||||
|
type: "text/vnd.tiddlywiki"
|
||||||
|
};
|
||||||
|
if(parseAsInline) {
|
||||||
|
parser.tree[0] = {
|
||||||
|
type: "text",
|
||||||
|
text: result
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
parser.tree[0] = {
|
||||||
|
type: "element",
|
||||||
|
tag: "p",
|
||||||
|
children: [{
|
||||||
|
type: "text",
|
||||||
|
text: result
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var cacheKey = (parseAsInline ? "inlineParser" : "blockParser") + (this.transcludeType || "");
|
||||||
|
if(variableInfo.isCacheable && srcVariable[cacheKey]) {
|
||||||
|
parser = srcVariable[cacheKey];
|
||||||
|
} else {
|
||||||
|
parser = this.wiki.parseText(this.transcludeType,variableInfo.text || "",{parseAsInline: parseAsInline, configTrimWhiteSpace: srcVariable.configTrimWhiteSpace});
|
||||||
|
if(variableInfo.isCacheable) {
|
||||||
|
srcVariable[cacheKey] = parser;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(parser) {
|
||||||
|
// Add parameters widget for procedures and custom widgets
|
||||||
|
if(srcVariable.isProcedureDefinition || srcVariable.isWidgetDefinition) {
|
||||||
|
parser = {
|
||||||
|
tree: [
|
||||||
|
{
|
||||||
|
type: "parameters",
|
||||||
|
children: parser.tree
|
||||||
|
}
|
||||||
|
],
|
||||||
|
source: parser.source,
|
||||||
|
type: parser.type
|
||||||
|
}
|
||||||
|
$tw.utils.each(srcVariable.params,function(param) {
|
||||||
|
var name = param.name;
|
||||||
|
// Parameter names starting with dollar must be escaped to double dollars
|
||||||
|
if(name.charAt(0) === "$") {
|
||||||
|
name = "$" + name;
|
||||||
|
}
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],name,param["default"])
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// For macros and ordinary variables, wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
|
||||||
|
parser = {
|
||||||
|
tree: [
|
||||||
|
{
|
||||||
|
type: "vars",
|
||||||
|
children: parser.tree
|
||||||
|
}
|
||||||
|
],
|
||||||
|
source: parser.source,
|
||||||
|
type: parser.type
|
||||||
|
}
|
||||||
|
$tw.utils.each(variableInfo.params,function(param) {
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],"__" + param.name + "__",param.value)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Transcluding a text reference
|
||||||
|
parser = this.wiki.parseTextReference(
|
||||||
this.transcludeTitle,
|
this.transcludeTitle,
|
||||||
this.transcludeField,
|
this.transcludeField,
|
||||||
this.transcludeIndex,
|
this.transcludeIndex,
|
||||||
{
|
{
|
||||||
parseAsInline: parseAsInline,
|
parseAsInline: parseAsInline,
|
||||||
subTiddler: this.transcludeSubTiddler
|
subTiddler: this.transcludeSubTiddler,
|
||||||
}),
|
defaultType: this.transcludeType
|
||||||
parseTreeNodes = parser ? parser.tree : this.parseTreeNode.children;
|
});
|
||||||
this.sourceText = parser ? parser.source : null;
|
|
||||||
this.parserType = parser? parser.type : null;
|
|
||||||
// Set context variables for recursion detection
|
|
||||||
var recursionMarker = this.makeRecursionMarker();
|
|
||||||
if(this.recursionMarker === "yes") {
|
|
||||||
this.setVariable("transclusion",recursionMarker);
|
|
||||||
}
|
}
|
||||||
// Check for recursion
|
// Set 'thisTiddler'
|
||||||
|
this.setVariable("thisTiddler",this.transcludeTitle);
|
||||||
|
// Return the parse tree
|
||||||
if(parser) {
|
if(parser) {
|
||||||
if(this.parentWidget && this.parentWidget.hasVariable("transclusion",recursionMarker)) {
|
return {
|
||||||
parseTreeNodes = [{type: "element", tag: "span", attributes: {
|
parser: parser,
|
||||||
"class": {type: "string", value: "tc-error"}
|
parseTreeNodes: parser.tree,
|
||||||
}, children: [
|
parseAsInline: parseAsInline,
|
||||||
{type: "text", text: $tw.language.getString("Error/RecursiveTransclusion")}
|
text: parser.source,
|
||||||
]}];
|
type: parser.type
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// If there's no parse tree then return the missing slot value
|
||||||
|
return {
|
||||||
|
parser: null,
|
||||||
|
parseTreeNodes: (this.slotFillParseTrees["ts-missing"] || []),
|
||||||
|
parseAsInline: parseAsInline,
|
||||||
|
text: null,
|
||||||
|
type: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fetch all the string parameters as an ordered array of {name:, value:} where the name is optional
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.getOrderedTransclusionParameters = function() {
|
||||||
|
var result = [];
|
||||||
|
// Collect the parameters
|
||||||
|
for(var name in this.stringParametersByName) {
|
||||||
|
var value = this.stringParametersByName[name];
|
||||||
|
result.push({name: name, value: value});
|
||||||
|
}
|
||||||
|
// Sort numerical parameter names first
|
||||||
|
result.sort(function(a,b) {
|
||||||
|
var aIsNumeric = !isNaN(a.name),
|
||||||
|
bIsNumeric = !isNaN(b.name);
|
||||||
|
if(aIsNumeric && bIsNumeric) {
|
||||||
|
return a.name - b.name;
|
||||||
|
} else if(aIsNumeric) {
|
||||||
|
return -1;
|
||||||
|
} else if(bIsNumeric) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return a.name === b.name ? 0 : (a.name < b.name ? -1 : 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Remove names from numerical parameters
|
||||||
|
$tw.utils.each(result,function(param,index) {
|
||||||
|
if(!isNaN(param.name)) {
|
||||||
|
delete param.name;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fetch the value of a parameter
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.getTransclusionParameter = function(name,index,defaultValue) {
|
||||||
|
if(name in this.stringParametersByName) {
|
||||||
|
return this.stringParametersByName[name];
|
||||||
|
} else {
|
||||||
|
var name = "" + index;
|
||||||
|
if(name in this.stringParametersByName) {
|
||||||
|
return this.stringParametersByName[name];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Construct the child widgets
|
return defaultValue;
|
||||||
this.makeChildWidgets(parseTreeNodes);
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get one of the special parameters to be provided by the parameters widget
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.getTransclusionMetaParameters = function() {
|
||||||
|
var self = this;
|
||||||
|
return {
|
||||||
|
"parseMode": function() {
|
||||||
|
return self.parseAsInline ? "inline" : "block";
|
||||||
|
},
|
||||||
|
"parseTreeNodes": function() {
|
||||||
|
return JSON.stringify(self.parseTreeNode.children || []);
|
||||||
|
},
|
||||||
|
"slotFillParseTreeNodes": function() {
|
||||||
|
return JSON.stringify(self.slotFillParseTrees);
|
||||||
|
},
|
||||||
|
"params": function() {
|
||||||
|
return JSON.stringify(self.stringParametersByName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fetch the value of a slot
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.getTransclusionSlotFill = function(name,defaultParseTreeNodes) {
|
||||||
|
if(name && this.slotFillParseTrees[name] && this.slotFillParseTrees[name].length > 0) {
|
||||||
|
return this.slotFillParseTrees[name];
|
||||||
|
} else {
|
||||||
|
return defaultParseTreeNodes || [];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -101,6 +402,7 @@ TranscludeWidget.prototype.makeRecursionMarker = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TranscludeWidget.prototype.parserNeedsRefresh = function() {
|
TranscludeWidget.prototype.parserNeedsRefresh = function() {
|
||||||
|
// Doesn't need to consider transcluded variables because a parent variable can't change once a widget has been created
|
||||||
var parserInfo = this.wiki.getTextReferenceParserInfo(this.transcludeTitle,this.transcludeField,this.transcludeIndex,{subTiddler:this.transcludeSubTiddler});
|
var parserInfo = this.wiki.getTextReferenceParserInfo(this.transcludeTitle,this.transcludeField,this.transcludeIndex,{subTiddler:this.transcludeSubTiddler});
|
||||||
return (this.sourceText === undefined || parserInfo.sourceText !== this.sourceText || parserInfo.parserType !== this.parserType)
|
return (this.sourceText === undefined || parserInfo.sourceText !== this.sourceText || parserInfo.parserType !== this.parserType)
|
||||||
};
|
};
|
||||||
@@ -110,7 +412,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
|
|||||||
*/
|
*/
|
||||||
TranscludeWidget.prototype.refresh = function(changedTiddlers) {
|
TranscludeWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
var changedAttributes = this.computeAttributes();
|
var changedAttributes = this.computeAttributes();
|
||||||
if(($tw.utils.count(changedAttributes) > 0) || (changedTiddlers[this.transcludeTitle] && this.parserNeedsRefresh())) {
|
if(($tw.utils.count(changedAttributes) > 0) || (!this.transcludeVariable && changedTiddlers[this.transcludeTitle] && this.parserNeedsRefresh())) {
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -168,11 +168,11 @@ ViewWidget.prototype.getValueAsHtmlTextEncoded = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ViewWidget.prototype.getValueAsUrlEncoded = function() {
|
ViewWidget.prototype.getValueAsUrlEncoded = function() {
|
||||||
return encodeURIComponent(this.getValueAsText());
|
return $tw.utils.encodeURIComponentExtended(this.getValueAsText());
|
||||||
};
|
};
|
||||||
|
|
||||||
ViewWidget.prototype.getValueAsDoubleUrlEncoded = function() {
|
ViewWidget.prototype.getValueAsDoubleUrlEncoded = function() {
|
||||||
return encodeURIComponent(encodeURIComponent(this.getValueAsText()));
|
return $tw.utils.encodeURIComponentExtended($tw.utils.encodeURIComponentExtended(this.getValueAsText()));
|
||||||
};
|
};
|
||||||
|
|
||||||
ViewWidget.prototype.getValueAsDate = function(format) {
|
ViewWidget.prototype.getValueAsDate = function(format) {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user