mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-01-22 19:04:38 +00:00
Compare commits
241 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0dcfc3ad2e | ||
|
|
6a9cc87255 | ||
|
|
ab3109d84b | ||
|
|
a4ab42da8a | ||
|
|
af87727ffc | ||
|
|
6b4e5c74ad | ||
|
|
8af99878cc | ||
|
|
d6d2bc455c | ||
|
|
d5ff723d4c | ||
|
|
1d0af90ba2 | ||
|
|
59572cd75d | ||
|
|
1d16206188 | ||
|
|
37a6ff8521 | ||
|
|
d3ea98fcef | ||
|
|
5022516c61 | ||
|
|
965d8ee014 | ||
|
|
8e50ad1243 | ||
|
|
33f40c47c6 | ||
|
|
1b3c2557b8 | ||
|
|
1a4766c5a1 | ||
|
|
e49dda3b48 | ||
|
|
bd447f0716 | ||
|
|
13faeaa0bd | ||
|
|
7f0fb2b610 | ||
|
|
7d2994388b | ||
|
|
edb5dc3fdc | ||
|
|
df1b1316c8 | ||
|
|
1a0c831216 | ||
|
|
f4365e4bb4 | ||
|
|
75d10a2dc3 | ||
|
|
da7cf7a4f3 | ||
|
|
6452eb56a9 | ||
|
|
9fce8153df | ||
|
|
4cdfa4e3f9 | ||
|
|
d6384df6fc | ||
|
|
f0bd06b38d | ||
|
|
d823856082 | ||
|
|
b02a82ba0f | ||
|
|
c43b013539 | ||
|
|
5548186c93 | ||
|
|
def9b553a8 | ||
|
|
35f7a8ea06 | ||
|
|
54bfb28063 | ||
|
|
80c63b96cf | ||
|
|
2ef9ecbc44 | ||
|
|
88812092fd | ||
|
|
4e01fc1838 | ||
|
|
5cab75f4a7 | ||
|
|
1345384d39 | ||
|
|
927013a57a | ||
|
|
0d11fccba2 | ||
|
|
d78ad756db | ||
|
|
1e4f444b63 | ||
|
|
b6831ed35d | ||
|
|
762de81444 | ||
|
|
ca9f320886 | ||
|
|
d8c3d18a00 | ||
|
|
ee03ee57f5 | ||
|
|
13d1f6d6c1 | ||
|
|
51175616d3 | ||
|
|
32f79d16c6 | ||
|
|
5613bcc884 | ||
|
|
0729d730f8 | ||
|
|
f2422efeb8 | ||
|
|
cbb002ec4b | ||
|
|
c7e8c87f85 | ||
|
|
66ae1d6930 | ||
|
|
8e3885277f | ||
|
|
9293dfa477 | ||
|
|
8a80d89582 | ||
|
|
10ebd93df3 | ||
|
|
d414eef773 | ||
|
|
7d1f0ea8f4 | ||
|
|
f477e90192 | ||
|
|
b4dec78a72 | ||
|
|
60187dc59e | ||
|
|
4453aefad8 | ||
|
|
54cfda76ee | ||
|
|
1e8c2821d6 | ||
|
|
cbc030fbe2 | ||
|
|
b454116163 | ||
|
|
0186c6490f | ||
|
|
853a899c77 | ||
|
|
95a3d7fde2 | ||
|
|
d33e0a05e2 | ||
|
|
cb833b3f65 | ||
|
|
b73c50adeb | ||
|
|
fdfa45329a | ||
|
|
7b1880404c | ||
|
|
2739b1bafe | ||
|
|
cc782ff518 | ||
|
|
492bfbebe9 | ||
|
|
c9fbff265a | ||
|
|
b0f72d0690 | ||
|
|
6070a2c921 | ||
|
|
cb43b91ab6 | ||
|
|
804bc9e9c0 | ||
|
|
4514a67a1f | ||
|
|
edcba4ee16 | ||
|
|
9e28356047 | ||
|
|
44ad8c770f | ||
|
|
2dd4fa41a5 | ||
|
|
f5389b3859 | ||
|
|
65c8d74218 | ||
|
|
f88e3939e1 | ||
|
|
769778b05b | ||
|
|
f84ff0d778 | ||
|
|
ca1aabe21f | ||
|
|
dd801d1571 | ||
|
|
485730483b | ||
|
|
8b6733d792 | ||
|
|
75aabcce64 | ||
|
|
5dfa6b2bb4 | ||
|
|
3798a3c7d0 | ||
|
|
1c4b2243a6 | ||
|
|
c11493ec37 | ||
|
|
b6c8cdae64 | ||
|
|
b80d079d71 | ||
|
|
6512b038c5 | ||
|
|
6d1d497a63 | ||
|
|
6ea7140e8f | ||
|
|
7b311b0e4a | ||
|
|
be3018fe3b | ||
|
|
68095eb392 | ||
|
|
4bb34e4801 | ||
|
|
1348607c8f | ||
|
|
2f86779a27 | ||
|
|
2af632a46d | ||
|
|
05606f72ad | ||
|
|
6d0701e0fa | ||
|
|
76cdc17f3b | ||
|
|
7b076eadfa | ||
|
|
c5ce2a0a94 | ||
|
|
7fcc84156e | ||
|
|
75bf12db7a | ||
|
|
07de96459e | ||
|
|
be036aa9c8 | ||
|
|
0664895670 | ||
|
|
dde1e4bc0f | ||
|
|
122de63b71 | ||
|
|
e3ba880e18 | ||
|
|
e3be15531f | ||
|
|
5a3ff4e3dc | ||
|
|
f7f32f00a3 | ||
|
|
d7d694b14f | ||
|
|
a6feb6dd66 | ||
|
|
ecf10e41c3 | ||
|
|
481edc1cfe | ||
|
|
ff5817ab50 | ||
|
|
80235bf049 | ||
|
|
ecddd5a7be | ||
|
|
f22fc788e5 | ||
|
|
f828a582c3 | ||
|
|
a94f94f352 | ||
|
|
9f34a01577 | ||
|
|
9cd49ed485 | ||
|
|
4ea1a05af6 | ||
|
|
b6eb6d477b | ||
|
|
cce18d8e2e | ||
|
|
45d469ca5c | ||
|
|
fbee714ffe | ||
|
|
2429dcc2e2 | ||
|
|
4d84422f22 | ||
|
|
d98bfbde58 | ||
|
|
983787a8f2 | ||
|
|
7b83c22e78 | ||
|
|
c8c43b2811 | ||
|
|
7e32e2efcf | ||
|
|
6f8e842105 | ||
|
|
ce99c0aa0f | ||
|
|
3ff165402c | ||
|
|
a350a76a00 | ||
|
|
05b9dd1822 | ||
|
|
5207b1c127 | ||
|
|
267c351735 | ||
|
|
f545418e55 | ||
|
|
97dd832d2e | ||
|
|
d7e7d87581 | ||
|
|
bd2efeaaa3 | ||
|
|
a206bf56b9 | ||
|
|
a33e94c4ee | ||
|
|
e9313b1c9d | ||
|
|
8096935d87 | ||
|
|
dcb083abb0 | ||
|
|
6cc76fe6ab | ||
|
|
4f8de1881c | ||
|
|
9caba544eb | ||
|
|
746a8ca17f | ||
|
|
2475e1b501 | ||
|
|
193628d63f | ||
|
|
b6ce353a7d | ||
|
|
7a50603d9d | ||
|
|
d21fabca4b | ||
|
|
daa9a8ae45 | ||
|
|
d9eb5499a3 | ||
|
|
870c7897ad | ||
|
|
95da1c2907 | ||
|
|
2bfe522b72 | ||
|
|
c099bf9893 | ||
|
|
ab0dda1177 | ||
|
|
4f65953da9 | ||
|
|
d77de61a06 | ||
|
|
3287cf56bb | ||
|
|
b5c81d2721 | ||
|
|
d3522854b6 | ||
|
|
2f3f9de7be | ||
|
|
6890952357 | ||
|
|
d695fca301 | ||
|
|
a0d2392f01 | ||
|
|
23b4e03cd5 | ||
|
|
d5f72cb282 | ||
|
|
5f57bf81cd | ||
|
|
e32c9e4658 | ||
|
|
2a73505508 | ||
|
|
4d87ef4231 | ||
|
|
71be167592 | ||
|
|
c543036a0f | ||
|
|
989947b99a | ||
|
|
3d86d62a6e | ||
|
|
0cfe6597d4 | ||
|
|
8ae4428332 | ||
|
|
81b4e99ccc | ||
|
|
2f133a08aa | ||
|
|
6b17e688da | ||
|
|
8654066f03 | ||
|
|
56dae90425 | ||
|
|
1f6ef07860 | ||
|
|
f30a455ee3 | ||
|
|
03bd99cd11 | ||
|
|
cc389ec82b | ||
|
|
f85678b6dc | ||
|
|
8d7c869072 | ||
|
|
8f592d3f0a | ||
|
|
1f2e0ed189 | ||
|
|
4d6c428ba9 | ||
|
|
9b247f6d63 | ||
|
|
62fdaa633a | ||
|
|
79f5e6b498 | ||
|
|
23bd7e7817 | ||
|
|
1b226c7556 | ||
|
|
2bd9cc45fa |
@@ -1,15 +1,8 @@
|
||||
# Known minified files
|
||||
# Ignore "third party" code whose style we will not change.
|
||||
/boot/sjcl.js
|
||||
/core/modules/utils/base64-utf8/base64-utf8.module.js
|
||||
/core/modules/utils/base64-utf8/base64-utf8.module.min.js
|
||||
/core/modules/utils/diff-match-patch/diff_match_patch.js
|
||||
/plugins/tiddlywiki/async/files/async.min.v1.5.0.js
|
||||
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/anyword-hint.js
|
||||
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/css-hint.js
|
||||
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/html-hint.js
|
||||
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/javascript-hint.js
|
||||
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/show-hint.js
|
||||
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/xml-hint.js
|
||||
/plugins/tiddlywiki/codemirror-closebrackets/files/addon/edit/closebrackets.js
|
||||
/plugins/tiddlywiki/codemirror-closebrackets/files/addon/edit/matchbrackets.js
|
||||
/plugins/tiddlywiki/codemirror-closetag/files/addon/edit/closetag.js
|
||||
/plugins/tiddlywiki/codemirror-closetag/files/addon/fold/xml-fold.js
|
||||
/core/modules/utils/diff-match-patch/diff_match_patch_uncompressed.js
|
||||
/core/modules/utils/dom/csscolorparser.js
|
||||
/plugins/tiddlywiki/*/files/
|
||||
|
||||
@@ -64,7 +64,23 @@ rules:
|
||||
init-declarations: 'off'
|
||||
jsx-quotes: error
|
||||
key-spacing: 'off'
|
||||
keyword-spacing: 'off'
|
||||
keyword-spacing:
|
||||
- error
|
||||
- before: true
|
||||
after: false
|
||||
overrides:
|
||||
'case':
|
||||
after: true
|
||||
'do':
|
||||
'after': true
|
||||
'else':
|
||||
after: true
|
||||
'return':
|
||||
after: true
|
||||
'throw':
|
||||
after: true
|
||||
'try':
|
||||
after: true
|
||||
line-comment-position: 'off'
|
||||
linebreak-style: 'off'
|
||||
lines-around-comment: 'off'
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# Default to the current version number for building the plugin library
|
||||
|
||||
if [ -z "$TW5_BUILD_VERSION" ]; then
|
||||
TW5_BUILD_VERSION=v5.2.0
|
||||
TW5_BUILD_VERSION=v5.2.2
|
||||
fi
|
||||
|
||||
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
||||
|
||||
72
boot/boot.js
72
boot/boot.js
@@ -68,6 +68,26 @@ $tw.utils.isArrayEqual = function(array1,array2) {
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
Add an entry to a sorted array if it doesn't already exist, while maintaining the sort order
|
||||
*/
|
||||
$tw.utils.insertSortedArray = function(array,value) {
|
||||
var low = 0, high = array.length - 1, mid, cmp;
|
||||
while(low <= high) {
|
||||
mid = (low + high) >> 1;
|
||||
cmp = value.localeCompare(array[mid]);
|
||||
if(cmp > 0) {
|
||||
low = mid + 1;
|
||||
} else if(cmp < 0) {
|
||||
high = mid - 1;
|
||||
} else {
|
||||
return array;
|
||||
}
|
||||
}
|
||||
array.splice(low,0,value);
|
||||
return array;
|
||||
};
|
||||
|
||||
/*
|
||||
Push entries onto an array, removing them first if they already exist in the array
|
||||
array: array to modify (assumed to be free of duplicates)
|
||||
@@ -256,6 +276,28 @@ $tw.utils.deepDefaults = function(object /*, sourceObjectList */) {
|
||||
return object;
|
||||
};
|
||||
|
||||
/*
|
||||
Convert a URIComponent encoded string to a string safely
|
||||
*/
|
||||
$tw.utils.decodeURIComponentSafe = function(s) {
|
||||
var v = s;
|
||||
try {
|
||||
v = decodeURIComponent(s);
|
||||
} catch(e) {}
|
||||
return v;
|
||||
};
|
||||
|
||||
/*
|
||||
Convert a URI encoded string to a string safely
|
||||
*/
|
||||
$tw.utils.decodeURISafe = function(s) {
|
||||
var v = s;
|
||||
try {
|
||||
v = decodeURI(s);
|
||||
} catch(e) {}
|
||||
return v;
|
||||
};
|
||||
|
||||
/*
|
||||
Convert "&" to &, " " to nbsp, "<" to <, ">" to > and """ to "
|
||||
*/
|
||||
@@ -1059,7 +1101,7 @@ $tw.Wiki = function(options) {
|
||||
tiddlerTitles = null, // Array of tiddler titles
|
||||
getTiddlerTitles = function() {
|
||||
if(!tiddlerTitles) {
|
||||
tiddlerTitles = Object.keys(tiddlers);
|
||||
tiddlerTitles = Object.keys(tiddlers).sort(function(a,b) {return a.localeCompare(b);});
|
||||
}
|
||||
return tiddlerTitles;
|
||||
},
|
||||
@@ -1112,10 +1154,8 @@ $tw.Wiki = function(options) {
|
||||
}
|
||||
// Save the new tiddler
|
||||
tiddlers[title] = tiddler;
|
||||
// Check we've got it's title
|
||||
if(tiddlerTitles && tiddlerTitles.indexOf(title) === -1) {
|
||||
tiddlerTitles.push(title);
|
||||
}
|
||||
// Check we've got the title
|
||||
tiddlerTitles = $tw.utils.insertSortedArray(tiddlerTitles || [],title);
|
||||
// Record the new tiddler state
|
||||
updateDescriptor["new"] = {
|
||||
tiddler: tiddler,
|
||||
@@ -1928,6 +1968,20 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
||||
tiddlers.push({tiddlers: fileTiddlers});
|
||||
}
|
||||
};
|
||||
// Helper to recursively search subdirectories
|
||||
var getAllFiles = function(dirPath, recurse, arrayOfFiles) {
|
||||
recurse = recurse || false;
|
||||
arrayOfFiles = arrayOfFiles || [];
|
||||
var files = fs.readdirSync(dirPath);
|
||||
files.forEach(function(file) {
|
||||
if (recurse && fs.statSync(dirPath + path.sep + file).isDirectory()) {
|
||||
arrayOfFiles = getAllFiles(dirPath + path.sep + file, recurse, arrayOfFiles);
|
||||
} else if(fs.statSync(dirPath + path.sep + file).isFile()){
|
||||
arrayOfFiles.push(path.join(dirPath, path.sep, file));
|
||||
}
|
||||
});
|
||||
return arrayOfFiles;
|
||||
}
|
||||
// Process the listed tiddlers
|
||||
$tw.utils.each(filesInfo.tiddlers,function(tidInfo) {
|
||||
if(tidInfo.prefix && tidInfo.suffix) {
|
||||
@@ -1951,13 +2005,14 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
||||
// Process directory specifier
|
||||
var dirPath = path.resolve(filepath,dirSpec.path);
|
||||
if(fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) {
|
||||
var files = fs.readdirSync(dirPath),
|
||||
var files = getAllFiles(dirPath, dirSpec.searchSubdirectories),
|
||||
fileRegExp = new RegExp(dirSpec.filesRegExp || "^.*$"),
|
||||
metaRegExp = /^.*\.meta$/;
|
||||
for(var t=0; t<files.length; t++) {
|
||||
var filename = files[t];
|
||||
var thisPath = path.relative(filepath, files[t]),
|
||||
filename = path.basename(thisPath);
|
||||
if(filename !== "tiddlywiki.files" && !metaRegExp.test(filename) && fileRegExp.test(filename)) {
|
||||
processFile(dirPath + path.sep + filename,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile);
|
||||
processFile(thisPath,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -2612,3 +2667,4 @@ if(typeof(exports) !== "undefined") {
|
||||
} else {
|
||||
_boot(window.$tw);
|
||||
}
|
||||
//# sourceURL=$:/boot/boot.js
|
||||
|
||||
@@ -117,3 +117,4 @@ if(typeof(exports) === "undefined") {
|
||||
// Export functionality as a module
|
||||
exports.bootprefix = _bootprefix;
|
||||
}
|
||||
//# sourceURL=$:/boot/bootprefix.js
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@ type: text/plain
|
||||
TiddlyWiki created by Jeremy Ruston, (jeremy [at] jermolene [dot] com)
|
||||
|
||||
Copyright (c) 2004-2007, Jeremy Ruston
|
||||
Copyright (c) 2007-2021, UnaMesa Association
|
||||
Copyright (c) 2007-2022, UnaMesa Association
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -27,10 +27,15 @@ Basics/Tiddlers/Prompt: Number of tiddlers
|
||||
Basics/Title/Prompt: Title of this ~TiddlyWiki
|
||||
Basics/Username/Prompt: Username for signing edits
|
||||
Basics/Version/Prompt: ~TiddlyWiki version
|
||||
Cascades/Caption: Cascades
|
||||
Cascades/Hint: These global rules are used to dynamically choose certain templates. The result of the cascade is the result of the first filter in the sequence that returns a result
|
||||
Cascades/TagPrompt: Filters tagged <$macrocall $name="tag" tag=<<currentTiddler>>/>
|
||||
EditorTypes/Caption: Editor Types
|
||||
EditorTypes/Editor/Caption: Editor
|
||||
EditorTypes/Hint: These tiddlers determine which editor is used to edit specific tiddler types.
|
||||
EditorTypes/Type/Caption: Type
|
||||
EditTemplateBody/Caption: Edit Template Body
|
||||
EditTemplateBody/Hint: This rule cascade is used by the default edit template to dynamically choose the template for editing the body of a tiddler.
|
||||
Info/Caption: Info
|
||||
Info/Hint: Information about this TiddlyWiki
|
||||
KeyboardShortcuts/Add/Prompt: Type shortcut here
|
||||
@@ -191,6 +196,8 @@ Settings/TitleLinks/Yes/Description: Display tiddler titles as links
|
||||
Settings/MissingLinks/Caption: Wiki Links
|
||||
Settings/MissingLinks/Hint: Choose whether to link to tiddlers that do not exist yet
|
||||
Settings/MissingLinks/Description: Enable links to missing tiddlers
|
||||
StoryTiddler/Caption: Story Tiddler
|
||||
StoryTiddler/Hint: This rule cascade is used to dynamically choose the template for displaying a tiddler in the story river.
|
||||
StoryView/Caption: Story View
|
||||
StoryView/Prompt: Current view:
|
||||
Stylesheets/Caption: Stylesheets
|
||||
@@ -201,6 +208,10 @@ Theme/Caption: Theme
|
||||
Theme/Prompt: Current theme:
|
||||
TiddlerFields/Caption: Tiddler Fields
|
||||
TiddlerFields/Hint: This is the full set of TiddlerFields in use in this wiki (including system tiddlers but excluding shadow tiddlers).
|
||||
TiddlerColour/Caption: Tiddler Colour
|
||||
TiddlerColour/Hint: This rules cascade is used to dynamically choose the colour for a tiddler (used for the icon and the associated tag pill).
|
||||
TiddlerIcon/Caption: Tiddler Icon
|
||||
TiddlerIcon/Hint: This rules cascade is used to dynamically choose the icon for a tiddler.
|
||||
Toolbars/Caption: Toolbars
|
||||
Toolbars/EditToolbar/Caption: Edit Toolbar
|
||||
Toolbars/EditToolbar/Hint: Choose which buttons are displayed for tiddlers in edit mode. Drag and drop to change the ordering
|
||||
@@ -212,3 +223,7 @@ Toolbars/EditorToolbar/Hint: Choose which buttons are displayed in the editor to
|
||||
Toolbars/ViewToolbar/Caption: View Toolbar
|
||||
Toolbars/ViewToolbar/Hint: Choose which buttons are displayed for tiddlers in view mode. Drag and drop to change the ordering
|
||||
Tools/Download/Full/Caption: Download full wiki
|
||||
ViewTemplateBody/Caption: View Template Body
|
||||
ViewTemplateBody/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the body of a tiddler.
|
||||
ViewTemplateTitle/Caption: View Template Title
|
||||
ViewTemplateTitle/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the title of a tiddler.
|
||||
@@ -3,6 +3,7 @@ title: $:/language/Docs/Fields/
|
||||
_canonical_uri: The full URI of an external image tiddler
|
||||
bag: The name of the bag from which a tiddler came
|
||||
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''
|
||||
color: The CSS color value associated with a tiddler
|
||||
component: The name of the component responsible for an [[alert tiddler|AlertMechanism]]
|
||||
current-tiddler: Used to cache the top tiddler in a [[history list|HistoryMechanism]]
|
||||
@@ -13,9 +14,9 @@ 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.title: For draft tiddlers, contains the proposed new title of the tiddler
|
||||
footer: The footer text for a wizard
|
||||
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
|
||||
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''
|
||||
list: An ordered list of tiddler titles associated with a tiddler
|
||||
list-before: If set, the title of a tiddler before which this tiddler should be added to the ordered list of tiddler titles, or at the start 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
|
||||
@@ -32,7 +33,7 @@ tags: A list of tags associated with a tiddler
|
||||
text: The body text of a tiddler
|
||||
throttle.refresh: If present, throttles refreshes of this tiddler
|
||||
title: The unique name of a tiddler
|
||||
toc-link: Suppresses the tiddler's link in a Table of Contents tree if set to: ''no''
|
||||
toc-link: Suppresses the tiddler's link in a Table of Contents tree if set to ''no''
|
||||
type: The content type of a tiddler
|
||||
version: Version information for a plugin
|
||||
_is_skinny: If present, indicates that the tiddler text field must be loaded from the server
|
||||
|
||||
@@ -14,7 +14,7 @@ ConfirmAction: Do you wish to proceed?
|
||||
Count: count
|
||||
DefaultNewTiddlerTitle: New Tiddler
|
||||
Diffs/CountMessage: <<diff-count>> differences
|
||||
DropMessage: Drop here (or use the 'Escape' key to cancel)
|
||||
DropMessage: Drop now (or use the 'Escape' key to cancel)
|
||||
Encryption/Cancel: Cancel
|
||||
Encryption/ConfirmClearPassword: Do you wish to clear the password? This will remove the encryption applied when saving this wiki
|
||||
Encryption/PromptSetPassword: Set a new password for this TiddlyWiki
|
||||
|
||||
@@ -205,7 +205,7 @@ FramedEngine.prototype.handleInputEvent = function(event) {
|
||||
this.widget.saveChanges(this.getText());
|
||||
this.fixHeight();
|
||||
if(this.widget.editInputActions) {
|
||||
this.widget.invokeActionString(this.widget.editInputActions);
|
||||
this.widget.invokeActionString(this.widget.editInputActions,this,event,{actionValue: this.getText()});
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -133,7 +133,7 @@ SimpleEngine.prototype.handleInputEvent = function(event) {
|
||||
this.widget.saveChanges(this.getText());
|
||||
this.fixHeight();
|
||||
if(this.widget.editInputActions) {
|
||||
this.widget.invokeActionString(this.widget.editInputActions);
|
||||
this.widget.invokeActionString(this.widget.editInputActions,this,event,{actionValue: this.getText()});
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -324,7 +324,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
||||
If there are no Files, let the browser handle it.
|
||||
*/
|
||||
EditTextWidget.prototype.handleDropEvent = function(event) {
|
||||
if(event.dataTransfer.files.length) {
|
||||
if($tw.utils.dragEventContainsFiles(event)) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.dispatchDOMEvent(this.cloneEvent(event,["dataTransfer"]));
|
||||
|
||||
17
core/modules/editor/operations/text/focus-editor.js
Normal file
17
core/modules/editor/operations/text/focus-editor.js
Normal file
@@ -0,0 +1,17 @@
|
||||
/*\
|
||||
title: $:/core/modules/editor/operations/text/focus-editor.js
|
||||
type: application/javascript
|
||||
module-type: texteditoroperation
|
||||
Simply focus the Text editor
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports["focus-editor"] = function(event,operation) {
|
||||
operation = null;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -13,15 +13,17 @@ Text editor operation to wrap the selected lines with a prefix and suffix
|
||||
"use strict";
|
||||
|
||||
exports["wrap-lines"] = function(event,operation) {
|
||||
var prefix = event.paramObject.prefix || "",
|
||||
suffix = event.paramObject.suffix || "";
|
||||
// Cut just past the preceding line break, or the start of the text
|
||||
operation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);
|
||||
// Cut to just past the following line break, or to the end of the text
|
||||
operation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd);
|
||||
// Add the prefix and suffix
|
||||
operation.replacement = event.paramObject.prefix + "\n" +
|
||||
operation.replacement = prefix + "\n" +
|
||||
operation.text.substring(operation.cutStart,operation.cutEnd) + "\n" +
|
||||
event.paramObject.suffix + "\n";
|
||||
operation.newSelStart = operation.cutStart + event.paramObject.prefix.length + 1;
|
||||
suffix + "\n";
|
||||
operation.newSelStart = operation.cutStart + prefix.length + 1;
|
||||
operation.newSelEnd = operation.newSelStart + (operation.cutEnd - operation.cutStart);
|
||||
};
|
||||
|
||||
|
||||
53
core/modules/filterrunprefixes/cascade.js
Normal file
53
core/modules/filterrunprefixes/cascade.js
Normal file
@@ -0,0 +1,53 @@
|
||||
/*\
|
||||
title: $:/core/modules/filterrunprefixes/cascade.js
|
||||
type: application/javascript
|
||||
module-type: filterrunprefix
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter prefix function
|
||||
*/
|
||||
exports.cascade = function(operationSubFunction,options) {
|
||||
return function(results,source,widget) {
|
||||
if(results.length !== 0) {
|
||||
var filterList = operationSubFunction(source,widget),
|
||||
filterFnList = [];
|
||||
var inputResults = results.toArray();
|
||||
results.clear();
|
||||
$tw.utils.each(inputResults,function(title) {
|
||||
var result = ""; // If no filter matches, we return an empty string
|
||||
$tw.utils.each(filterList,function(filter,index) {
|
||||
if(!filterFnList[index]) {
|
||||
filterFnList[index] = options.wiki.compileFilter(filter);
|
||||
}
|
||||
var output = filterFnList[index](options.wiki.makeTiddlerIterator([title]),{
|
||||
getVariable: function(name,opts) {
|
||||
opts = opts || {};
|
||||
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) {
|
||||
result = output[0];
|
||||
return false;
|
||||
}
|
||||
});
|
||||
results.push(result);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -16,23 +16,30 @@ Export our filter function
|
||||
exports.filter = function(operationSubFunction,options) {
|
||||
return function(results,source,widget) {
|
||||
if(results.length > 0) {
|
||||
var resultsToRemove = [];
|
||||
var resultsToRemove = [],
|
||||
index = 0;
|
||||
results.each(function(title) {
|
||||
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
||||
getVariable: function(name) {
|
||||
switch(name) {
|
||||
case "currentTiddler":
|
||||
return "" + title;
|
||||
case "..currentTiddler":
|
||||
return widget.getVariable("currentTiddler");
|
||||
default:
|
||||
return widget.getVariable(name);
|
||||
getVariable: function(name,opts) {
|
||||
opts = opts || {};
|
||||
opts.variables = {
|
||||
"currentTiddler": "" + title,
|
||||
"..currentTiddler": widget.getVariable("currentTiddler"),
|
||||
"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) {
|
||||
resultsToRemove.push(title);
|
||||
}
|
||||
++index;
|
||||
});
|
||||
results.remove(resultsToRemove);
|
||||
}
|
||||
|
||||
@@ -15,22 +15,29 @@ Export our filter prefix function
|
||||
exports.map = function(operationSubFunction,options) {
|
||||
return function(results,source,widget) {
|
||||
if(results.length > 0) {
|
||||
var inputTitles = results.toArray();
|
||||
var inputTitles = results.toArray(),
|
||||
index = 0;
|
||||
results.clear();
|
||||
$tw.utils.each(inputTitles,function(title) {
|
||||
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
||||
getVariable: function(name) {
|
||||
switch(name) {
|
||||
case "currentTiddler":
|
||||
return "" + title;
|
||||
case "..currentTiddler":
|
||||
return widget.getVariable("currentTiddler");
|
||||
default:
|
||||
return widget.getVariable(name);
|
||||
getVariable: function(name,opts) {
|
||||
opts = opts || {};
|
||||
opts.variables = {
|
||||
"currentTiddler": "" + title,
|
||||
"..currentTiddler": widget.getVariable("currentTiddler"),
|
||||
"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);
|
||||
}
|
||||
}
|
||||
});
|
||||
results.push(filtered[0] || "");
|
||||
++index;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,26 +15,24 @@ Export our filter prefix function
|
||||
exports.reduce = function(operationSubFunction,options) {
|
||||
return function(results,source,widget) {
|
||||
if(results.length > 0) {
|
||||
var accumulator = "";
|
||||
var index = 0;
|
||||
var accumulator = "",
|
||||
index = 0;
|
||||
results.each(function(title) {
|
||||
var list = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
||||
getVariable: function(name) {
|
||||
switch(name) {
|
||||
case "currentTiddler":
|
||||
return "" + title;
|
||||
case "..currentTiddler":
|
||||
return widget.getVariable("currentTiddler");
|
||||
case "accumulator":
|
||||
return "" + accumulator;
|
||||
case "index":
|
||||
return "" + index;
|
||||
case "revIndex":
|
||||
return "" + (results.length - 1 - index);
|
||||
case "length":
|
||||
return "" + results.length;
|
||||
default:
|
||||
return widget.getVariable(name);
|
||||
getVariable: function(name,opts) {
|
||||
opts = opts || {};
|
||||
opts.variables = {
|
||||
"currentTiddler": "" + title,
|
||||
"..currentTiddler": widget.getVariable("currentTiddler"),
|
||||
"index": "" + index,
|
||||
"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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -26,14 +26,16 @@ exports.sort = function(operationSubFunction,options) {
|
||||
compareFn;
|
||||
results.each(function(title) {
|
||||
var key = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
||||
getVariable: function(name) {
|
||||
switch(name) {
|
||||
case "currentTiddler":
|
||||
return "" + title;
|
||||
case "..currentTiddler":
|
||||
return widget.getVariable("currentTiddler");
|
||||
default:
|
||||
return widget.getVariable(name);
|
||||
getVariable: function(name,opts) {
|
||||
opts = opts || {};
|
||||
opts.variables = {
|
||||
"currentTiddler": "" + title,
|
||||
"..currentTiddler": widget.getVariable("currentTiddler")
|
||||
};
|
||||
if(name in opts.variables) {
|
||||
return opts.variables[name];
|
||||
} else {
|
||||
return widget.getVariable(name,opts);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -95,10 +95,12 @@ function parseFilterOperation(operators,filterString,p) {
|
||||
if(nextBracketPos === -1) {
|
||||
throw "Missing closing bracket in filter expression";
|
||||
}
|
||||
if(!operator.regexp) {
|
||||
if(operator.regexp) {
|
||||
operand.text = "";
|
||||
} else {
|
||||
operand.text = filterString.substring(p,nextBracketPos);
|
||||
operator.operands.push(operand);
|
||||
}
|
||||
operator.operands.push(operand);
|
||||
p = nextBracketPos + 1;
|
||||
}
|
||||
|
||||
|
||||
27
core/modules/filters/crypto.js
Normal file
27
core/modules/filters/crypto.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/crypto.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operators for cryptography, using the Stanford JavaScript library
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.sha256 = function(source,operator,options) {
|
||||
var results = [],
|
||||
length = parseInt(operator.operand,10) || 20,
|
||||
sha256 = function(text) {
|
||||
return sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(text)).substr(0,length);
|
||||
};
|
||||
source(function(tiddler,title) {
|
||||
results.push(sha256(title));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -103,4 +103,16 @@ exports.nth = function(source,operator,options) {
|
||||
return results.slice(count - 1,count);
|
||||
};
|
||||
|
||||
/*
|
||||
The zero based nth member of the list
|
||||
*/
|
||||
exports.zth = function(source,operator,options) {
|
||||
var count = $tw.utils.getInt(operator.operand,0),
|
||||
results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
});
|
||||
return results.slice(count,count + 1);
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -5,9 +5,11 @@ module-type: filteroperator
|
||||
|
||||
Filter operator that looks up values via a title prefix
|
||||
|
||||
[lookup:<field>[<prefix>]]
|
||||
[lookup:<defaultvalue>:<field OR index>[<prefix>],[<field-name OR index-name>]]
|
||||
|
||||
Prepends the prefix to the selected items and returns the specified field value
|
||||
Prepends the prefix to the selected items and returns the specified
|
||||
field or index value. If the 2nd suffix does not exist, it defaults to field.
|
||||
If the second operand is missing it defaults to "text" for fields, and "0" for indexes
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
@@ -20,10 +22,31 @@ Prepends the prefix to the selected items and returns the specified field value
|
||||
Export our filter function
|
||||
*/
|
||||
exports.lookup = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(options.wiki.getTiddlerText(operator.operand + title) || operator.suffix || '');
|
||||
});
|
||||
var results = [],
|
||||
suffixes = operator.suffixes || [],
|
||||
defaultSuffix = suffixes[0] ? (suffixes[0][0] || "") : "",
|
||||
indexSuffix = (suffixes[1] && suffixes[1][0] === "index") ? true : false,
|
||||
target;
|
||||
if(operator.operands.length == 2) {
|
||||
target = operator.operands[1]
|
||||
} else {
|
||||
target = indexSuffix ? "0": "text";
|
||||
}
|
||||
if(indexSuffix) {
|
||||
source(function(tiddler,title) {
|
||||
var data = options.wiki.extractTiddlerDataItem(operator.operands[0]+title,target,defaultSuffix);
|
||||
results.push(data);
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
var value = defaultSuffix;
|
||||
var targetTiddler = options.wiki.getTiddler(operator.operands[0]+title);
|
||||
if(targetTiddler && targetTiddler.getFieldString(target)) {
|
||||
value = targetTiddler.getFieldString(target);
|
||||
}
|
||||
results.push(value);
|
||||
});
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
|
||||
@@ -165,6 +165,35 @@ exports["standard-deviation"] = makeNumericReducingOperator(
|
||||
}
|
||||
);
|
||||
|
||||
//trigonometry
|
||||
exports.cos = makeNumericBinaryOperator(
|
||||
function(a) {return Math.cos(a)}
|
||||
);
|
||||
|
||||
exports.sin = makeNumericBinaryOperator(
|
||||
function(a) {return Math.sin(a)}
|
||||
);
|
||||
|
||||
exports.tan = makeNumericBinaryOperator(
|
||||
function(a) {return Math.tan(a)}
|
||||
);
|
||||
|
||||
exports.acos = makeNumericBinaryOperator(
|
||||
function(a) {return Math.acos(a)}
|
||||
);
|
||||
|
||||
exports.asin = makeNumericBinaryOperator(
|
||||
function(a) {return Math.asin(a)}
|
||||
);
|
||||
|
||||
exports.atan = makeNumericBinaryOperator(
|
||||
function(a) {return Math.atan(a)}
|
||||
);
|
||||
|
||||
exports.atan2 = makeNumericBinaryOperator(
|
||||
function(a,b) {return Math.atan2(a,b)}
|
||||
);
|
||||
|
||||
//Calculate the variance of a population of numbers in an array given its mean
|
||||
function getVarianceFromArray(values,mean) {
|
||||
var deviationTotal = values.reduce(function(accumulator,value) {
|
||||
|
||||
@@ -40,6 +40,7 @@ exports.search = function(source,operator,options) {
|
||||
invert: invert,
|
||||
field: fields,
|
||||
excludeField: excludeFields,
|
||||
some: hasFlag("some"),
|
||||
caseSensitive: hasFlag("casesensitive"),
|
||||
literal: hasFlag("literal"),
|
||||
whitespace: hasFlag("whitespace"),
|
||||
|
||||
@@ -121,21 +121,23 @@ exports["search-replace"] = function(source,operator,options) {
|
||||
flagSuffix = (suffixes[0] ? (suffixes[0][0] || "") : ""),
|
||||
flags = (flagSuffix.indexOf("g") !== -1 ? "g" : "") + (flagSuffix.indexOf("i") !== -1 ? "i" : "") + (flagSuffix.indexOf("m") !== -1 ? "m" : ""),
|
||||
isRegExp = (suffixes[1] && suffixes[1][0] === "regexp") ? true : false,
|
||||
searchTerm,
|
||||
//Escape regexp characters if the operand is not a regular expression
|
||||
searchTerm = isRegExp ? operator.operand : $tw.utils.escapeRegExp(operator.operand),
|
||||
//Escape $ character in replacement string if not in regular expression mode
|
||||
replacement = isRegExp ? operator.operands[1] : (operator.operands[1]||"").replace(/\$/g,"$$$$"),
|
||||
regExp;
|
||||
try {
|
||||
regExp = new RegExp(searchTerm,flags);
|
||||
} catch(ex) {
|
||||
return ["RegExp error: " + ex];
|
||||
}
|
||||
|
||||
source(function(tiddler,title) {
|
||||
if(title && (operator.operands.length > 1)) {
|
||||
//Escape regexp characters if the operand is not a regular expression
|
||||
searchTerm = isRegExp ? operator.operand : $tw.utils.escapeRegExp(operator.operand);
|
||||
try {
|
||||
regExp = new RegExp(searchTerm,flags);
|
||||
} catch(ex) {
|
||||
return ["RegExp error: " + ex];
|
||||
}
|
||||
results.push(
|
||||
title.replace(regExp,operator.operands[1])
|
||||
title.replace(regExp,replacement)
|
||||
);
|
||||
regExp.lastIndex = 0;
|
||||
} else {
|
||||
results.push(title);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ exports.parse = function() {
|
||||
};
|
||||
|
||||
/*
|
||||
Look for an HTML tag. Returns null if not found, otherwise returns {type: "element", name:, attributes: [], isSelfClosing:, start:, end:,}
|
||||
Look for an HTML tag. Returns null if not found, otherwise returns {type: "element", name:, attributes: {}, orderedAttributes: [], isSelfClosing:, start:, end:,}
|
||||
*/
|
||||
exports.parseTag = function(source,pos,options) {
|
||||
options = options || {};
|
||||
@@ -74,7 +74,8 @@ exports.parseTag = function(source,pos,options) {
|
||||
node = {
|
||||
type: "element",
|
||||
start: pos,
|
||||
attributes: {}
|
||||
attributes: {},
|
||||
orderedAttributes: []
|
||||
};
|
||||
// Define our regexps
|
||||
var reTagName = /([a-zA-Z0-9\-\$]+)/g;
|
||||
@@ -106,6 +107,7 @@ exports.parseTag = function(source,pos,options) {
|
||||
// Process attributes
|
||||
var attribute = $tw.utils.parseAttribute(source,pos);
|
||||
while(attribute) {
|
||||
node.orderedAttributes.push(attribute);
|
||||
node.attributes[attribute.name] = attribute;
|
||||
pos = attribute.end;
|
||||
// Get the next attribute
|
||||
|
||||
@@ -231,7 +231,10 @@ WikiParser.prototype.parseBlock = function(terminatorRegExpString) {
|
||||
return nextMatch.rule.parse();
|
||||
}
|
||||
// Treat it as a paragraph if we didn't find a block rule
|
||||
return [{type: "element", tag: "p", children: this.parseInlineRun(terminatorRegExp)}];
|
||||
var start = this.pos;
|
||||
var children = this.parseInlineRun(terminatorRegExp);
|
||||
var end = this.pos;
|
||||
return [{type: "element", tag: "p", children: children, start: start, end: end }];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -307,7 +310,7 @@ WikiParser.prototype.parseInlineRunUnterminated = function(options) {
|
||||
while(this.pos < this.sourceLength && nextMatch) {
|
||||
// Process the text preceding the run rule
|
||||
if(nextMatch.matchIndex > this.pos) {
|
||||
this.pushTextWidget(tree,this.source.substring(this.pos,nextMatch.matchIndex));
|
||||
this.pushTextWidget(tree,this.source.substring(this.pos,nextMatch.matchIndex),this.pos,nextMatch.matchIndex);
|
||||
this.pos = nextMatch.matchIndex;
|
||||
}
|
||||
// Process the run rule
|
||||
@@ -317,7 +320,7 @@ WikiParser.prototype.parseInlineRunUnterminated = function(options) {
|
||||
}
|
||||
// Process the remaining text
|
||||
if(this.pos < this.sourceLength) {
|
||||
this.pushTextWidget(tree,this.source.substr(this.pos));
|
||||
this.pushTextWidget(tree,this.source.substr(this.pos),this.pos,this.sourceLength);
|
||||
}
|
||||
this.pos = this.sourceLength;
|
||||
return tree;
|
||||
@@ -337,7 +340,7 @@ WikiParser.prototype.parseInlineRunTerminated = function(terminatorRegExp,option
|
||||
if(terminatorMatch) {
|
||||
if(!inlineRuleMatch || inlineRuleMatch.matchIndex >= terminatorMatch.index) {
|
||||
if(terminatorMatch.index > this.pos) {
|
||||
this.pushTextWidget(tree,this.source.substring(this.pos,terminatorMatch.index));
|
||||
this.pushTextWidget(tree,this.source.substring(this.pos,terminatorMatch.index),this.pos,terminatorMatch.index);
|
||||
}
|
||||
this.pos = terminatorMatch.index;
|
||||
if(options.eatTerminator) {
|
||||
@@ -350,7 +353,7 @@ WikiParser.prototype.parseInlineRunTerminated = function(terminatorRegExp,option
|
||||
if(inlineRuleMatch) {
|
||||
// Preceding text
|
||||
if(inlineRuleMatch.matchIndex > this.pos) {
|
||||
this.pushTextWidget(tree,this.source.substring(this.pos,inlineRuleMatch.matchIndex));
|
||||
this.pushTextWidget(tree,this.source.substring(this.pos,inlineRuleMatch.matchIndex),this.pos,inlineRuleMatch.matchIndex);
|
||||
this.pos = inlineRuleMatch.matchIndex;
|
||||
}
|
||||
// Process the inline rule
|
||||
@@ -364,7 +367,7 @@ WikiParser.prototype.parseInlineRunTerminated = function(terminatorRegExp,option
|
||||
}
|
||||
// Process the remaining text
|
||||
if(this.pos < this.sourceLength) {
|
||||
this.pushTextWidget(tree,this.source.substr(this.pos));
|
||||
this.pushTextWidget(tree,this.source.substr(this.pos),this.pos,this.sourceLength);
|
||||
}
|
||||
this.pos = this.sourceLength;
|
||||
return tree;
|
||||
@@ -373,12 +376,12 @@ WikiParser.prototype.parseInlineRunTerminated = function(terminatorRegExp,option
|
||||
/*
|
||||
Push a text widget onto an array, respecting the configTrimWhiteSpace setting
|
||||
*/
|
||||
WikiParser.prototype.pushTextWidget = function(array,text) {
|
||||
WikiParser.prototype.pushTextWidget = function(array,text,start,end) {
|
||||
if(this.configTrimWhiteSpace) {
|
||||
text = $tw.utils.trim(text);
|
||||
}
|
||||
if(text) {
|
||||
array.push({type: "text", text: text});
|
||||
array.push({type: "text", text: text, start: start, end: end});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ exports.handler = function(request,response,state) {
|
||||
if(fields.revision) {
|
||||
delete fields.revision;
|
||||
}
|
||||
state.wiki.addTiddler(new $tw.Tiddler(state.wiki.getCreationFields(),fields,{title: title},state.wiki.getModificationFields()));
|
||||
state.wiki.addTiddler(new $tw.Tiddler(fields,{title: title}));
|
||||
var changeCount = state.wiki.getChangeCount(title).toString();
|
||||
response.writeHead(204, "OK",{
|
||||
Etag: "\"default/" + encodeURIComponent(title) + "/" + changeCount + ":\"",
|
||||
|
||||
@@ -34,7 +34,6 @@ function Server(options) {
|
||||
this.authenticators = options.authenticators || [];
|
||||
this.wiki = options.wiki;
|
||||
this.boot = options.boot || $tw.boot;
|
||||
this.servername = $tw.utils.transliterateToSafeASCII(this.wiki.getTiddlerText("$:/SiteTitle") || "TiddlyWiki5");
|
||||
// Initialise the variables
|
||||
this.variables = $tw.utils.extend({},this.defaultVariables);
|
||||
if(options.variables) {
|
||||
@@ -44,7 +43,8 @@ function Server(options) {
|
||||
}
|
||||
}
|
||||
}
|
||||
$tw.utils.extend({},this.defaultVariables,options.variables);
|
||||
// Setup the default required plugins
|
||||
this.requiredPlugins = this.get("required-plugins").split(',');
|
||||
// Initialise CSRF
|
||||
this.csrfDisable = this.get("csrf-disable") === "yes";
|
||||
// Initialize Gzip compression
|
||||
@@ -52,14 +52,24 @@ function Server(options) {
|
||||
// Initialize browser-caching
|
||||
this.enableBrowserCache = this.get("use-browser-cache") === "yes";
|
||||
// Initialise authorization
|
||||
var authorizedUserName = (this.get("username") && this.get("password")) ? this.get("username") : "(anon)";
|
||||
var authorizedUserName;
|
||||
if(this.get("username") && this.get("password")) {
|
||||
authorizedUserName = this.get("username");
|
||||
} else if(this.get("credentials")) {
|
||||
authorizedUserName = "(authenticated)";
|
||||
} else {
|
||||
authorizedUserName = "(anon)";
|
||||
}
|
||||
this.authorizationPrincipals = {
|
||||
readers: (this.get("readers") || authorizedUserName).split(",").map($tw.utils.trim),
|
||||
writers: (this.get("writers") || authorizedUserName).split(",").map($tw.utils.trim)
|
||||
}
|
||||
if(this.get("admin") || authorizedUserName !== "(anon)") {
|
||||
this.authorizationPrincipals["admin"] = (this.get("admin") || authorizedUserName).split(',').map($tw.utils.trim)
|
||||
}
|
||||
// Load and initialise authenticators
|
||||
$tw.modules.forEachModuleOfType("authenticator", function(title,authenticatorDefinition) {
|
||||
// console.log("Loading server route " + title);
|
||||
// console.log("Loading authenticator " + title);
|
||||
self.addAuthenticator(authenticatorDefinition.AuthenticatorClass);
|
||||
});
|
||||
// Load route handlers
|
||||
@@ -71,15 +81,21 @@ function Server(options) {
|
||||
this.listenOptions = null;
|
||||
this.protocol = "http";
|
||||
var tlsKeyFilepath = this.get("tls-key"),
|
||||
tlsCertFilepath = this.get("tls-cert");
|
||||
tlsCertFilepath = this.get("tls-cert"),
|
||||
tlsPassphrase = this.get("tls-passphrase");
|
||||
if(tlsCertFilepath && tlsKeyFilepath) {
|
||||
this.listenOptions = {
|
||||
key: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsKeyFilepath),"utf8"),
|
||||
cert: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsCertFilepath),"utf8")
|
||||
cert: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsCertFilepath),"utf8"),
|
||||
passphrase: tlsPassphrase || ''
|
||||
};
|
||||
this.protocol = "https";
|
||||
}
|
||||
this.transport = require(this.protocol);
|
||||
// Name the server and init the boot state
|
||||
this.servername = $tw.utils.transliterateToSafeASCII(this.get("server-name") || this.wiki.getTiddlerText("$:/SiteTitle") || "TiddlyWiki5");
|
||||
this.boot.origin = this.get("origin")? this.get("origin"): this.protocol+"://"+this.get("host")+":"+this.get("port");
|
||||
this.boot.pathPrefix = this.get("path-prefix") || "";
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -150,6 +166,7 @@ function sendResponse(request,response,statusCode,headers,data,encoding) {
|
||||
Server.prototype.defaultVariables = {
|
||||
port: "8080",
|
||||
host: "127.0.0.1",
|
||||
"required-plugins": "$:/plugins/tiddlywiki/filesystem,$:/plugins/tiddlywiki/tiddlyweb",
|
||||
"root-tiddler": "$:/core/save/all",
|
||||
"root-render-type": "text/plain",
|
||||
"root-serve-type": "text/html",
|
||||
@@ -239,15 +256,15 @@ Server.prototype.requestHandler = function(request,response,options) {
|
||||
state.pathPrefix = options.pathPrefix || this.get("path-prefix") || "";
|
||||
state.sendResponse = sendResponse.bind(self,request,response);
|
||||
// Get the principals authorized to access this resource
|
||||
var authorizationType = this.methodMappings[request.method] || "readers";
|
||||
state.authorizationType = options.authorizationType || this.methodMappings[request.method] || "readers";
|
||||
// Check for the CSRF header if this is a write
|
||||
if(!this.csrfDisable && authorizationType === "writers" && request.headers["x-requested-with"] !== "TiddlyWiki") {
|
||||
if(!this.csrfDisable && state.authorizationType === "writers" && request.headers["x-requested-with"] !== "TiddlyWiki") {
|
||||
response.writeHead(403,"'X-Requested-With' header required to login to '" + this.servername + "'");
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
// Check whether anonymous access is granted
|
||||
state.allowAnon = this.isAuthorized(authorizationType,null);
|
||||
state.allowAnon = this.isAuthorized(state.authorizationType,null);
|
||||
// Authenticate with the first active authenticator
|
||||
if(this.authenticators.length > 0) {
|
||||
if(!this.authenticators[0].authenticateRequest(request,response,state)) {
|
||||
@@ -256,7 +273,7 @@ Server.prototype.requestHandler = function(request,response,options) {
|
||||
}
|
||||
}
|
||||
// Authorize with the authenticated username
|
||||
if(!this.isAuthorized(authorizationType,state.authenticatedUsername)) {
|
||||
if(!this.isAuthorized(state.authorizationType,state.authenticatedUsername)) {
|
||||
response.writeHead(401,"'" + state.authenticatedUsername + "' is not authorized to access '" + this.servername + "'");
|
||||
response.end();
|
||||
return;
|
||||
@@ -322,8 +339,16 @@ Server.prototype.listen = function(port,host,prefix) {
|
||||
port = process.env[port] || 8080;
|
||||
}
|
||||
// Warn if required plugins are missing
|
||||
if(!this.wiki.getTiddler("$:/plugins/tiddlywiki/tiddlyweb") || !this.wiki.getTiddler("$:/plugins/tiddlywiki/filesystem")) {
|
||||
$tw.utils.warning("Warning: Plugins required for client-server operation (\"tiddlywiki/filesystem\" and \"tiddlywiki/tiddlyweb\") are missing from tiddlywiki.info file");
|
||||
var missing = [];
|
||||
for (var index=0; index<this.requiredPlugins.length; index++) {
|
||||
if (!this.wiki.getTiddler(this.requiredPlugins[index])) {
|
||||
missing.push(this.requiredPlugins[index]);
|
||||
}
|
||||
}
|
||||
if(missing.length > 0) {
|
||||
var error = "Warning: Plugin(s) required for client-server operation are missing.\n"+
|
||||
"\""+ missing.join("\", \"")+"\"";
|
||||
$tw.utils.warning(error);
|
||||
}
|
||||
// Create the server
|
||||
var server;
|
||||
|
||||
@@ -51,6 +51,20 @@ exports.startup = function() {
|
||||
element.focus(event.paramObject);
|
||||
}
|
||||
});
|
||||
// Install the tm-rename-tiddler and tm-relink-tiddler messages
|
||||
var makeRenameHandler = function(method) {
|
||||
return function(event) {
|
||||
var options = {},
|
||||
paramObject = event.paramObject || {},
|
||||
from = paramObject.from || event.tiddlerTitle,
|
||||
to = paramObject.to;
|
||||
options.dontRenameInTags = (paramObject.renameInTags === "false" || paramObject.renameInTags === "no") ? true : false;
|
||||
options.dontRenameInLists = (paramObject.renameInLists === "false" || paramObject.renameInLists === "no") ? true : false;
|
||||
$tw.wiki[method](from,to,options);
|
||||
};
|
||||
};
|
||||
$tw.rootWidget.addEventListener("tm-rename-tiddler",makeRenameHandler("renameTiddler"));
|
||||
$tw.rootWidget.addEventListener("tm-relink-tiddler",makeRenameHandler("relinkTiddler"));
|
||||
// Install the scroller
|
||||
$tw.pageScroller = new $tw.utils.PageScroller();
|
||||
$tw.rootWidget.addEventListener("tm-scroll",function(event) {
|
||||
|
||||
@@ -32,13 +32,15 @@ exports.startup = function() {
|
||||
template = paramObject.template || "$:/core/templates/single.tiddler.window",
|
||||
width = paramObject.width || "700",
|
||||
height = paramObject.height || "600",
|
||||
top = paramObject.top,
|
||||
left = paramObject.left,
|
||||
variables = $tw.utils.extend({},paramObject,{currentTiddler: title});
|
||||
// Open the window
|
||||
var srcWindow,
|
||||
srcDocument;
|
||||
// In case that popup blockers deny opening a new window
|
||||
try {
|
||||
srcWindow = window.open("","external-" + title,"scrollbars,width=" + width + ",height=" + height),
|
||||
srcWindow = window.open("","external-" + title,"scrollbars,width=" + width + ",height=" + height + (top ? ",top=" + top : "" ) + (left ? ",left=" + left : "" )),
|
||||
srcDocument = srcWindow.document;
|
||||
}
|
||||
catch(e) {
|
||||
|
||||
@@ -24,13 +24,13 @@ exports.isDraft = function() {
|
||||
return this.hasField("draft.of");
|
||||
};
|
||||
|
||||
exports.getFieldString = function(field) {
|
||||
exports.getFieldString = function(field,defaultValue) {
|
||||
var value = this.fields[field];
|
||||
// Check for a missing field
|
||||
if(value === undefined || value === null) {
|
||||
return "";
|
||||
return defaultValue || "";
|
||||
}
|
||||
// Parse the field with the associated module (if any)
|
||||
// Stringify the field with the associated tiddler field module (if any)
|
||||
var fieldModule = $tw.Tiddler.fieldModules[field];
|
||||
if(fieldModule && fieldModule.stringify) {
|
||||
return fieldModule.stringify.call(this,value);
|
||||
|
||||
@@ -21,7 +21,7 @@ exports.extractEncryptedStoreArea = function(text) {
|
||||
if(encryptedStoreAreaStart !== -1) {
|
||||
var encryptedStoreAreaEnd = text.indexOf("</pre>",encryptedStoreAreaStart);
|
||||
if(encryptedStoreAreaEnd !== -1) {
|
||||
return $tw.utils.htmlDecode(text.substring(encryptedStoreAreaStart + encryptedStoreAreaStartMarker.length,encryptedStoreAreaEnd-1));
|
||||
return $tw.utils.htmlDecode(text.substring(encryptedStoreAreaStart + encryptedStoreAreaStartMarker.length,encryptedStoreAreaEnd));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -208,10 +208,10 @@ function parseJSONTiddlers(json,fallbackTitle) {
|
||||
return data;
|
||||
};
|
||||
|
||||
exports.dragEventContainsFiles = function(event) {
|
||||
function dragEventContainsType(event,targetType) {
|
||||
if(event.dataTransfer.types) {
|
||||
for(var i=0; i<event.dataTransfer.types.length; i++) {
|
||||
if(event.dataTransfer.types[i] === "Files") {
|
||||
if(event.dataTransfer.types[i] === targetType) {
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
@@ -220,4 +220,10 @@ exports.dragEventContainsFiles = function(event) {
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.dragEventContainsFiles = function(event) {
|
||||
return (dragEventContainsType(event,"Files") && !dragEventContainsType(event,"text/plain"));
|
||||
};
|
||||
|
||||
exports.dragEventContainsType = dragEventContainsType;
|
||||
|
||||
})();
|
||||
|
||||
@@ -49,10 +49,14 @@ Handle an event
|
||||
*/
|
||||
PageScroller.prototype.handleEvent = function(event) {
|
||||
if(event.type === "tm-scroll") {
|
||||
var options = {};
|
||||
if($tw.utils.hop(event.paramObject,"animationDuration")) {
|
||||
options.animationDuration = event.paramObject.animationDuration;
|
||||
}
|
||||
if(event.paramObject && event.paramObject.selector) {
|
||||
this.scrollSelectorIntoView(null,event.paramObject.selector);
|
||||
this.scrollSelectorIntoView(null,event.paramObject.selector,null,options);
|
||||
} else {
|
||||
this.scrollIntoView(event.target);
|
||||
this.scrollIntoView(event.target,null,options);
|
||||
}
|
||||
return false; // Event was handled
|
||||
}
|
||||
@@ -62,10 +66,10 @@ PageScroller.prototype.handleEvent = function(event) {
|
||||
/*
|
||||
Handle a scroll event hitting the page document
|
||||
*/
|
||||
PageScroller.prototype.scrollIntoView = function(element,callback) {
|
||||
PageScroller.prototype.scrollIntoView = function(element,callback,options) {
|
||||
var self = this,
|
||||
duration = $tw.utils.getAnimationDuration(),
|
||||
srcWindow = element ? element.ownerDocument.defaultView : window;
|
||||
duration = $tw.utils.hop(options,"animationDuration") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(),
|
||||
srcWindow = element ? element.ownerDocument.defaultView : window;
|
||||
// Now get ready to scroll the body
|
||||
this.cancelScroll(srcWindow);
|
||||
this.startTime = Date.now();
|
||||
@@ -122,11 +126,11 @@ PageScroller.prototype.scrollIntoView = function(element,callback) {
|
||||
drawFrame();
|
||||
};
|
||||
|
||||
PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) {
|
||||
PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {
|
||||
baseElement = baseElement || document.body;
|
||||
var element = baseElement.querySelector(selector);
|
||||
if(element) {
|
||||
this.scrollIntoView(element,callback);
|
||||
this.scrollIntoView(element,callback,options);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -978,22 +978,4 @@ exports.makeCompareFunction = function(type,options) {
|
||||
return (types[type] || types[options.defaultType] || types.number);
|
||||
};
|
||||
|
||||
exports.decodeURIComponentSafe = function(str) {
|
||||
var value = str;
|
||||
try {
|
||||
value = decodeURIComponent(str);
|
||||
} catch(e) {
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
exports.decodeURISafe = function(str) {
|
||||
var value = str;
|
||||
try {
|
||||
value = decodeURI(str);
|
||||
} catch(e) {
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -39,6 +39,8 @@ SendMessageWidget.prototype.execute = function() {
|
||||
this.actionParam = this.getAttribute("$param");
|
||||
this.actionName = this.getAttribute("$name");
|
||||
this.actionValue = this.getAttribute("$value","");
|
||||
this.actionNames = this.getAttribute("$names");
|
||||
this.actionValues = this.getAttribute("$values");
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -59,13 +61,20 @@ Invoke the action associated with this widget
|
||||
SendMessageWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||
// Get the string parameter
|
||||
var param = this.actionParam;
|
||||
// Assemble the attributes as a hashmap
|
||||
// Assemble the parameters as a hashmap
|
||||
var paramObject = Object.create(null);
|
||||
var count = 0;
|
||||
// Add names/values pairs if present
|
||||
if(this.actionNames && this.actionValues) {
|
||||
var names = this.wiki.filterTiddlers(this.actionNames,this),
|
||||
values = this.wiki.filterTiddlers(this.actionValues,this);
|
||||
$tw.utils.each(names,function(name,index) {
|
||||
paramObject[name] = values[index] || "";
|
||||
});
|
||||
}
|
||||
// Add raw parameters
|
||||
$tw.utils.each(this.attributes,function(attribute,name) {
|
||||
if(name.charAt(0) !== "$") {
|
||||
paramObject[name] = attribute;
|
||||
count++;
|
||||
}
|
||||
});
|
||||
// Add name/value pair if present
|
||||
@@ -73,14 +82,15 @@ SendMessageWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||
paramObject[this.actionName] = this.actionValue;
|
||||
}
|
||||
// Dispatch the message
|
||||
this.dispatchEvent({
|
||||
var params = {
|
||||
type: this.actionMessage,
|
||||
param: param,
|
||||
paramObject: paramObject,
|
||||
event: event,
|
||||
tiddlerTitle: this.getVariable("currentTiddler"),
|
||||
navigateFromTitle: this.getVariable("storyTiddler"),
|
||||
event: event
|
||||
});
|
||||
navigateFromTitle: this.getVariable("storyTiddler")
|
||||
};
|
||||
this.dispatchEvent(params);
|
||||
return true; // Action was invoked
|
||||
};
|
||||
|
||||
|
||||
86
core/modules/widgets/action-setmultiplefields.js
Normal file
86
core/modules/widgets/action-setmultiplefields.js
Normal file
@@ -0,0 +1,86 @@
|
||||
/*\
|
||||
title: $:/core/modules/widgets/action-setmultiplefields.js
|
||||
type: application/javascript
|
||||
module-type: widget
|
||||
|
||||
Action widget to set multiple fields or indexes on a tiddler
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||
|
||||
var SetMultipleFieldsWidget = function(parseTreeNode,options) {
|
||||
this.initialise(parseTreeNode,options);
|
||||
};
|
||||
|
||||
/*
|
||||
Inherit from the base widget class
|
||||
*/
|
||||
SetMultipleFieldsWidget.prototype = new Widget();
|
||||
|
||||
/*
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
SetMultipleFieldsWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
};
|
||||
|
||||
/*
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
SetMultipleFieldsWidget.prototype.execute = function() {
|
||||
this.actionTiddler = this.getAttribute("$tiddler",this.getVariable("currentTiddler"));
|
||||
this.actionFields = this.getAttribute("$fields");
|
||||
this.actionIndexes = this.getAttribute("$indexes");
|
||||
this.actionValues = this.getAttribute("$values");
|
||||
this.actionTimestamp = this.getAttribute("$timestamp","yes") === "yes";
|
||||
};
|
||||
|
||||
/*
|
||||
Refresh the widget by ensuring our attributes are up to date
|
||||
*/
|
||||
SetMultipleFieldsWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if(changedAttributes["$tiddler"] || changedAttributes["$fields"] || changedAttributes["$indexes"] || changedAttributes["$values"] || changedAttributes["$timestamp"]) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
}
|
||||
return this.refreshChildren(changedTiddlers);
|
||||
};
|
||||
|
||||
/*
|
||||
Invoke the action associated with this widget
|
||||
*/
|
||||
SetMultipleFieldsWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||
var tiddler = this.wiki.getTiddler(this.actionTiddler),
|
||||
names, values = this.wiki.filterTiddlers(this.actionValues,this);
|
||||
if(this.actionFields) {
|
||||
var additions = {};
|
||||
names = this.wiki.filterTiddlers(this.actionFields,this);
|
||||
$tw.utils.each(names,function(fieldname,index) {
|
||||
additions[fieldname] = values[index] || "";
|
||||
});
|
||||
var creationFields = this.actionTimestamp ? this.wiki.getCreationFields() : undefined,
|
||||
modificationFields = this.actionTimestamp ? this.wiki.getModificationFields() : undefined;
|
||||
this.wiki.addTiddler(new $tw.Tiddler(creationFields,tiddler,{title: this.actionTiddler},modificationFields,additions));
|
||||
} else if(this.actionIndexes) {
|
||||
var data = this.wiki.getTiddlerData(this.actionTiddler,Object.create(null));
|
||||
names = this.wiki.filterTiddlers(this.actionIndexes,this);
|
||||
$tw.utils.each(names,function(name,index) {
|
||||
data[name] = values[index] || "";
|
||||
});
|
||||
this.wiki.setTiddlerData(this.actionTiddler,data,{},{suppressTimestamp: !this.actionTimestamp});
|
||||
}
|
||||
return true; // Action was invoked
|
||||
};
|
||||
|
||||
exports["action-setmultiplefields"] = SetMultipleFieldsWidget;
|
||||
|
||||
})();
|
||||
|
||||
@@ -52,7 +52,13 @@ CodeBlockWidget.prototype.execute = function() {
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
CodeBlockWidget.prototype.refresh = function(changedTiddlers) {
|
||||
return false;
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if(changedAttributes.code || changedAttributes.language) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
exports.codeblock = CodeBlockWidget;
|
||||
|
||||
@@ -198,7 +198,8 @@ DropZoneWidget.prototype.handleDropEvent = function(event) {
|
||||
this.resetState();
|
||||
// Import any files in the drop
|
||||
var numFiles = 0;
|
||||
if(dataTransfer.files) {
|
||||
// If we have type text/vnd.tiddlywiki then skip trying to import files
|
||||
if(dataTransfer.files && !$tw.utils.dragEventContainsType(event,"text/vnd.tiddler")) {
|
||||
numFiles = this.wiki.readFiles(dataTransfer.files,{
|
||||
callback: readFileCallback,
|
||||
deserializer: this.dropzoneDeserializer
|
||||
|
||||
@@ -111,6 +111,16 @@ ImageWidget.prototype.render = function(parent,nextSibling) {
|
||||
if(this.imageAlt) {
|
||||
domNode.setAttribute("alt",this.imageAlt);
|
||||
}
|
||||
// Add classes when the image loads or fails
|
||||
$tw.utils.addClass(domNode,"tc-image-loading");
|
||||
domNode.addEventListener("load",function() {
|
||||
$tw.utils.removeClass(domNode,"tc-image-loading");
|
||||
$tw.utils.addClass(domNode,"tc-image-loaded");
|
||||
},false);
|
||||
domNode.addEventListener("error",function() {
|
||||
$tw.utils.removeClass(domNode,"tc-image-loading");
|
||||
$tw.utils.addClass(domNode,"tc-image-error");
|
||||
},false);
|
||||
// Insert element
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.domNodes.push(domNode);
|
||||
|
||||
@@ -46,7 +46,7 @@ ImportVariablesWidget.prototype.execute = function(tiddlerList) {
|
||||
this.tiddlerList = tiddlerList || this.wiki.filterTiddlers(this.filter,this);
|
||||
// Accumulate the <$set> widgets from each tiddler
|
||||
$tw.utils.each(this.tiddlerList,function(title) {
|
||||
var parser = widgetPointer.wiki.parseTiddler(title);
|
||||
var parser = widgetPointer.wiki.parseTiddler(title,{parseAsInline:true});
|
||||
if(parser) {
|
||||
var parseTreeNode = parser.tree[0];
|
||||
while(parseTreeNode && parseTreeNode.type === "set") {
|
||||
|
||||
96
core/modules/widgets/let.js
Normal file
96
core/modules/widgets/let.js
Normal file
@@ -0,0 +1,96 @@
|
||||
/*\
|
||||
title: $:/core/modules/widgets/let.js
|
||||
type: application/javascript
|
||||
module-type: widget
|
||||
|
||||
This widget allows defining multiple variables at once, while allowing
|
||||
the later variables to depend upon the earlier ones.
|
||||
|
||||
```
|
||||
\define helloworld() Hello world!
|
||||
<$let currentTiddler="target" value={{!!value}} currentTiddler="different">
|
||||
{{!!value}} will be different from <<value>>
|
||||
</$let>
|
||||
```
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||
|
||||
var LetWidget = function(parseTreeNode,options) {
|
||||
// Initialise
|
||||
this.initialise(parseTreeNode,options);
|
||||
};
|
||||
|
||||
/*
|
||||
Inherit from the base widget class
|
||||
*/
|
||||
LetWidget.prototype = new Widget();
|
||||
|
||||
/*
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
LetWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
this.renderChildren(parent,nextSibling);
|
||||
};
|
||||
|
||||
LetWidget.prototype.computeAttributes = function() {
|
||||
// Before computing attributes, we must make clear that none of the
|
||||
// existing attributes are staged for lookup, even on a refresh
|
||||
var changedAttributes = {},
|
||||
self = this;
|
||||
this.currentValueFor = Object.create(null);
|
||||
$tw.utils.each(this.parseTreeNode.orderedAttributes,function(attribute,index) {
|
||||
var value = self.computeAttribute(attribute),
|
||||
name = attribute.name;
|
||||
if(name.charAt(0) !== "$") {
|
||||
// Now that it's prepped, we're allowed to look this variable up
|
||||
// when defining later variables
|
||||
self.currentValueFor[name] = value;
|
||||
}
|
||||
});
|
||||
// Run through again, setting variables and looking for differences
|
||||
$tw.utils.each(this.currentValueFor,function(value,name) {
|
||||
if (self.attributes[name] !== value) {
|
||||
self.attributes[name] = value;
|
||||
self.setVariable(name,value);
|
||||
changedAttributes[name] = true;
|
||||
}
|
||||
});
|
||||
return changedAttributes;
|
||||
};
|
||||
|
||||
LetWidget.prototype.getVariableInfo = function(name,options) {
|
||||
// Special handling: If this variable exists in this very $let, we can
|
||||
// use it, but only if it's been staged.
|
||||
if ($tw.utils.hop(this.currentValueFor,name)) {
|
||||
return {
|
||||
text: this.currentValueFor[name]
|
||||
};
|
||||
}
|
||||
return Widget.prototype.getVariableInfo.call(this,name,options);
|
||||
};
|
||||
|
||||
/*
|
||||
Refresh the widget by ensuring our attributes are up to date
|
||||
*/
|
||||
LetWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if($tw.utils.count(changedAttributes) > 0) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
}
|
||||
return this.refreshChildren(changedTiddlers);
|
||||
};
|
||||
|
||||
exports["let"] = LetWidget;
|
||||
|
||||
})();
|
||||
@@ -207,7 +207,8 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
|
||||
*/
|
||||
LinkWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if(changedAttributes.to || changedTiddlers[this.to] || changedAttributes["aria-label"] || changedAttributes.tooltip) {
|
||||
if(changedAttributes.to || changedTiddlers[this.to] || changedAttributes["aria-label"] || changedAttributes.tooltip ||
|
||||
changedAttributes["class"] || changedAttributes.tabindex || changedAttributes.draggable || changedAttributes.tag) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,9 @@ ListWidget.prototype.render = function(parent,nextSibling) {
|
||||
} else {
|
||||
this.storyview = null;
|
||||
}
|
||||
if(this.storyview && this.storyview.renderEnd) {
|
||||
this.storyview.renderEnd();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -44,8 +44,7 @@ NavigatorWidget.prototype.render = function(parent,nextSibling) {
|
||||
{type: "tm-fold-tiddler", handler: "handleFoldTiddlerEvent"},
|
||||
{type: "tm-fold-other-tiddlers", handler: "handleFoldOtherTiddlersEvent"},
|
||||
{type: "tm-fold-all-tiddlers", handler: "handleFoldAllTiddlersEvent"},
|
||||
{type: "tm-unfold-all-tiddlers", handler: "handleUnfoldAllTiddlersEvent"},
|
||||
{type: "tm-rename-tiddler", handler: "handleRenameTiddlerEvent"}
|
||||
{type: "tm-unfold-all-tiddlers", handler: "handleUnfoldAllTiddlersEvent"}
|
||||
]);
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
@@ -636,16 +635,6 @@ NavigatorWidget.prototype.handleUnfoldAllTiddlersEvent = function(event) {
|
||||
});
|
||||
};
|
||||
|
||||
NavigatorWidget.prototype.handleRenameTiddlerEvent = function(event) {
|
||||
var options = {},
|
||||
paramObject = event.paramObject || {},
|
||||
from = paramObject.from || event.tiddlerTitle,
|
||||
to = paramObject.to;
|
||||
options.dontRenameInTags = (paramObject.renameInTags === "false" || paramObject.renameInTags === "no") ? true : false;
|
||||
options.dontRenameInLists = (paramObject.renameInLists === "false" || paramObject.renameInLists === "no") ? true : false;
|
||||
this.wiki.renameTiddler(from,to,options);
|
||||
};
|
||||
|
||||
exports.navigator = NavigatorWidget;
|
||||
|
||||
})();
|
||||
|
||||
@@ -64,9 +64,9 @@ RadioWidget.prototype.getValue = function() {
|
||||
tiddler = this.wiki.getTiddler(this.radioTitle);
|
||||
if(tiddler) {
|
||||
if(this.radioIndex) {
|
||||
value = this.wiki.extractTiddlerDataItem(this.radioTitle,this.radioIndex);
|
||||
value = this.wiki.extractTiddlerDataItem(this.radioTitle,this.radioIndex,this.radioDefault);
|
||||
} else {
|
||||
value = tiddler.getFieldString(this.radioField);
|
||||
value = tiddler.getFieldString(this.radioField,this.radioDefault);
|
||||
}
|
||||
} else {
|
||||
value = this.radioDefault;
|
||||
|
||||
@@ -38,10 +38,14 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) {
|
||||
if(this.outerDomNode.scrollWidth <= this.outerDomNode.offsetWidth && this.outerDomNode.scrollHeight <= this.outerDomNode.offsetHeight && this.fallthrough === "yes") {
|
||||
return true;
|
||||
}
|
||||
var options = {};
|
||||
if($tw.utils.hop(event.paramObject,"animationDuration")) {
|
||||
options.animationDuration = event.paramObject.animationDuration;
|
||||
}
|
||||
if(event.paramObject && event.paramObject.selector) {
|
||||
this.scrollSelectorIntoView(null,event.paramObject.selector);
|
||||
this.scrollSelectorIntoView(null,event.paramObject.selector,null,options);
|
||||
} else {
|
||||
this.scrollIntoView(event.target);
|
||||
this.scrollIntoView(event.target,null,options);
|
||||
}
|
||||
return false; // Handled event
|
||||
};
|
||||
@@ -49,9 +53,9 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) {
|
||||
/*
|
||||
Scroll an element into view
|
||||
*/
|
||||
ScrollableWidget.prototype.scrollIntoView = function(element) {
|
||||
var duration = $tw.utils.getAnimationDuration(),
|
||||
srcWindow = element ? element.ownerDocument.defaultView : window;
|
||||
ScrollableWidget.prototype.scrollIntoView = function(element,callback,options) {
|
||||
var duration = $tw.utils.hop(options,"animationDuration") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(),
|
||||
srcWindow = element ? element.ownerDocument.defaultView : window;
|
||||
this.cancelScroll();
|
||||
this.startTime = Date.now();
|
||||
var scrollPosition = {
|
||||
@@ -114,11 +118,11 @@ ScrollableWidget.prototype.scrollIntoView = function(element) {
|
||||
}
|
||||
};
|
||||
|
||||
ScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) {
|
||||
ScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {
|
||||
baseElement = baseElement || document.body;
|
||||
var element = baseElement.querySelector(selector);
|
||||
if(element) {
|
||||
this.scrollIntoView(element,callback);
|
||||
this.scrollIntoView(element,callback,options);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -155,8 +159,6 @@ ScrollableWidget.prototype.render = function(parent,nextSibling) {
|
||||
// Create elements
|
||||
this.outerDomNode = this.document.createElement("div");
|
||||
$tw.utils.setStyle(this.outerDomNode,[
|
||||
{overflowY: "auto"},
|
||||
{overflowX: "auto"},
|
||||
{webkitOverflowScrolling: "touch"}
|
||||
]);
|
||||
this.innerDomNode = this.document.createElement("div");
|
||||
|
||||
81
core/modules/widgets/setmultiplevariables.js
Normal file
81
core/modules/widgets/setmultiplevariables.js
Normal file
@@ -0,0 +1,81 @@
|
||||
/*\
|
||||
title: $:/core/modules/widgets/setmultiplevariables.js
|
||||
type: application/javascript
|
||||
module-type: widget
|
||||
|
||||
Widget to set multiple variables at once from a list of names and a list of values
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||
|
||||
var SetMultipleVariablesWidget = function(parseTreeNode,options) {
|
||||
this.initialise(parseTreeNode,options);
|
||||
};
|
||||
|
||||
/*
|
||||
Inherit from the base widget class
|
||||
*/
|
||||
SetMultipleVariablesWidget.prototype = new Widget();
|
||||
|
||||
/*
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
SetMultipleVariablesWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
this.renderChildren(parent,nextSibling);
|
||||
};
|
||||
|
||||
/*
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
SetMultipleVariablesWidget.prototype.execute = function() {
|
||||
// Setup our variables
|
||||
this.setVariables();
|
||||
// Construct the child widgets
|
||||
this.makeChildWidgets();
|
||||
};
|
||||
|
||||
|
||||
SetMultipleVariablesWidget.prototype.setVariables = function() {
|
||||
// Set the variables
|
||||
var self = this,
|
||||
filterNames = this.getAttribute("$names",""),
|
||||
filterValues = this.getAttribute("$values","");
|
||||
this.variableNames = [];
|
||||
this.variableValues = [];
|
||||
if(filterNames && filterValues) {
|
||||
this.variableNames = this.wiki.filterTiddlers(filterNames,this);
|
||||
this.variableValues = this.wiki.filterTiddlers(filterValues,this);
|
||||
$tw.utils.each(this.variableNames,function(varname,index) {
|
||||
self.setVariable(varname,self.variableValues[index]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Refresh the widget by ensuring our attributes are up to date
|
||||
*/
|
||||
SetMultipleVariablesWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var filterNames = this.getAttribute("$names",""),
|
||||
filterValues = this.getAttribute("$values",""),
|
||||
variableNames = this.wiki.filterTiddlers(filterNames,this),
|
||||
variableValues = this.wiki.filterTiddlers(filterValues,this);
|
||||
if(!$tw.utils.isArrayEqual(this.variableNames,variableNames) || !$tw.utils.isArrayEqual(this.variableValues,variableValues)) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
}
|
||||
return this.refreshChildren(changedTiddlers);
|
||||
};
|
||||
|
||||
exports["setmultiplevariables"] = SetMultipleVariablesWidget;
|
||||
|
||||
})();
|
||||
|
||||
@@ -29,14 +29,12 @@ var VarsWidget = function(parseTreeNode,options) {
|
||||
/*
|
||||
Inherit from the base widget class
|
||||
*/
|
||||
VarsWidget.prototype = Object.create(Widget.prototype);
|
||||
VarsWidget.prototype = new Widget();
|
||||
|
||||
/*
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
VarsWidget.prototype.render = function(parent,nextSibling) {
|
||||
// Call the constructor
|
||||
Widget.call(this);
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
@@ -63,7 +61,7 @@ Refresh the widget by ensuring our attributes are up to date
|
||||
*/
|
||||
VarsWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if(Object.keys(changedAttributes).length) {
|
||||
if($tw.utils.count(changedAttributes) > 0) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ Widget.prototype.getVariableInfo = function(name,options) {
|
||||
});
|
||||
// Only substitute variable references if this variable was defined with the \define pragma
|
||||
if(variable.isMacroDefinition) {
|
||||
value = this.substituteVariableReferences(value);
|
||||
value = this.substituteVariableReferences(value,options);
|
||||
}
|
||||
return {
|
||||
text: value,
|
||||
@@ -175,10 +175,10 @@ Widget.prototype.resolveVariableParameters = function(formalParams,actualParams)
|
||||
return results;
|
||||
};
|
||||
|
||||
Widget.prototype.substituteVariableReferences = function(text) {
|
||||
Widget.prototype.substituteVariableReferences = function(text,options) {
|
||||
var self = this;
|
||||
return (text || "").replace(/\$\(([^\)\$]+)\)\$/g,function(match,p1,offset,string) {
|
||||
return self.getVariable(p1,{defaultValue: ""});
|
||||
return options.variables && options.variables[p1] || (self.getVariable(p1,{defaultValue: ""}));
|
||||
});
|
||||
};
|
||||
|
||||
@@ -263,19 +263,9 @@ Compute the current values of the attributes of the widget. Returns a hashmap of
|
||||
*/
|
||||
Widget.prototype.computeAttributes = function() {
|
||||
var changedAttributes = {},
|
||||
self = this,
|
||||
value;
|
||||
self = this;
|
||||
$tw.utils.each(this.parseTreeNode.attributes,function(attribute,name) {
|
||||
if(attribute.type === "filtered") {
|
||||
value = self.wiki.filterTiddlers(attribute.filter,self)[0] || "";
|
||||
} else if(attribute.type === "indirect") {
|
||||
value = self.wiki.getTextReference(attribute.textReference,"",self.getVariable("currentTiddler"));
|
||||
} else if(attribute.type === "macro") {
|
||||
value = self.getVariable(attribute.value.name,{params: attribute.value.params});
|
||||
} else { // String attribute
|
||||
value = attribute.value;
|
||||
}
|
||||
// Check whether the attribute has changed
|
||||
var value = self.computeAttribute(attribute);
|
||||
if(self.attributes[name] !== value) {
|
||||
self.attributes[name] = value;
|
||||
changedAttributes[name] = true;
|
||||
@@ -284,6 +274,20 @@ Widget.prototype.computeAttributes = function() {
|
||||
return changedAttributes;
|
||||
};
|
||||
|
||||
Widget.prototype.computeAttribute = function(attribute) {
|
||||
var value;
|
||||
if(attribute.type === "filtered") {
|
||||
value = this.wiki.filterTiddlers(attribute.filter,this)[0] || "";
|
||||
} else if(attribute.type === "indirect") {
|
||||
value = this.wiki.getTextReference(attribute.textReference,"",this.getVariable("currentTiddler"));
|
||||
} else if(attribute.type === "macro") {
|
||||
value = this.getVariable(attribute.value.name,{params: attribute.value.params});
|
||||
} else { // String attribute
|
||||
value = attribute.value;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
/*
|
||||
Check for the presence of an attribute
|
||||
*/
|
||||
@@ -310,24 +314,40 @@ excludeEventAttributes: ignores attributes whose name begins with "on"
|
||||
Widget.prototype.assignAttributes = function(domNode,options) {
|
||||
options = options || {};
|
||||
var self = this;
|
||||
$tw.utils.each(this.attributes,function(v,a) {
|
||||
// Check exclusions
|
||||
if(options.excludeEventAttributes && a.substr(0,2) === "on") {
|
||||
v = undefined;
|
||||
var assignAttribute = function(name,value) {
|
||||
// Check for excluded attribute names
|
||||
if(options.excludeEventAttributes && name.substr(0,2) === "on") {
|
||||
value = undefined;
|
||||
}
|
||||
if(v !== undefined) {
|
||||
var b = a.split(":");
|
||||
// Setting certain attributes can cause a DOM error (eg xmlns on the svg element)
|
||||
try {
|
||||
if (b.length == 2 && b[0] == "xlink"){
|
||||
domNode.setAttributeNS("http://www.w3.org/1999/xlink",b[1],v);
|
||||
} else {
|
||||
domNode.setAttributeNS(null,a,v);
|
||||
if(value !== undefined) {
|
||||
// Handle the xlink: namespace
|
||||
var namespace = null;
|
||||
if(name.substr(0,6) === "xlink:" && name.length > 6) {
|
||||
namespace = "http://www.w3.org/1999/xlink";
|
||||
name = name.substr(6);
|
||||
}
|
||||
// Handle styles
|
||||
if(name.substr(0,6) === "style." && name.length > 6) {
|
||||
domNode.style[$tw.utils.unHyphenateCss(name.substr(6))] = value;
|
||||
} else {
|
||||
// Setting certain attributes can cause a DOM error (eg xmlns on the svg element)
|
||||
try {
|
||||
domNode.setAttributeNS(namespace,name,value);
|
||||
} catch(e) {
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// Not all parse tree nodes have the orderedAttributes property
|
||||
if(this.parseTreeNode.orderedAttributes) {
|
||||
$tw.utils.each(this.parseTreeNode.orderedAttributes,function(attribute,index) {
|
||||
assignAttribute(attribute.name,self.attributes[attribute.name]);
|
||||
});
|
||||
} else {
|
||||
$tw.utils.each(Object.keys(self.attributes).sort(),function(name) {
|
||||
assignAttribute(name,self.attributes[name]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -570,7 +590,7 @@ Widget.prototype.invokeActions = function(triggeringWidget,event) {
|
||||
for(var t=0; t<this.children.length; t++) {
|
||||
var child = this.children[t],
|
||||
childIsActionWidget = !!child.invokeAction,
|
||||
actionRefreshPolicy = child.getVariable("tv-action-refresh-policy");
|
||||
actionRefreshPolicy = child.getVariable("tv-action-refresh-policy"); // Default is "once"
|
||||
// Refresh the child if required
|
||||
if(childIsActionWidget || actionRefreshPolicy === "always") {
|
||||
child.refreshSelf();
|
||||
|
||||
@@ -46,26 +46,31 @@ function relinkTiddler(fromTitle,toTitle,options) {
|
||||
if(!tiddler.fields["plugin-type"] && type !== "application/javascript") {
|
||||
var tags = tiddler.fields.tags ? tiddler.fields.tags.slice(0) : undefined,
|
||||
list = tiddler.fields.list ? tiddler.fields.list.slice(0) : undefined,
|
||||
isModified = false;
|
||||
isModified = false,
|
||||
processList = function(listField) {
|
||||
if(listField && listField.indexOf(fromTitle) !== -1) {
|
||||
// Remove any existing instances of the toTitle
|
||||
var p = listField.indexOf(toTitle);
|
||||
while(p !== -1) {
|
||||
listField.splice(p,1);
|
||||
p = listField.indexOf(toTitle);
|
||||
}
|
||||
// Replace the fromTitle with toTitle
|
||||
$tw.utils.each(listField,function (title,index) {
|
||||
if(title === fromTitle) {
|
||||
listField[index] = toTitle;
|
||||
isModified = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
if(!options.dontRenameInTags) {
|
||||
// Rename tags
|
||||
$tw.utils.each(tags,function (title,index) {
|
||||
if(title === fromTitle) {
|
||||
console.log("Renaming tag '" + tags[index] + "' to '" + toTitle + "' of tiddler '" + tiddler.fields.title + "'");
|
||||
tags[index] = toTitle;
|
||||
isModified = true;
|
||||
}
|
||||
});
|
||||
processList(tags);
|
||||
}
|
||||
if(!options.dontRenameInLists) {
|
||||
// Rename lists
|
||||
$tw.utils.each(list,function (title,index) {
|
||||
if(title === fromTitle) {
|
||||
console.log("Renaming list item '" + list[index] + "' to '" + toTitle + "' of tiddler '" + tiddler.fields.title + "'");
|
||||
list[index] = toTitle;
|
||||
isModified = true;
|
||||
}
|
||||
});
|
||||
processList(list);
|
||||
}
|
||||
if(isModified) {
|
||||
var newTiddler = new $tw.Tiddler(tiddler,{tags: tags, list: list},self.getModificationFields())
|
||||
|
||||
@@ -81,7 +81,7 @@ exports.setText = function(title,field,index,value,options) {
|
||||
} else {
|
||||
delete data[index];
|
||||
}
|
||||
this.setTiddlerData(title,data,modificationFields);
|
||||
this.setTiddlerData(title,data,{},{suppressTimestamp: options.suppressTimestamp});
|
||||
} else {
|
||||
var tiddler = this.getTiddler(title),
|
||||
fields = {title: title};
|
||||
@@ -639,14 +639,25 @@ Lookup a given tiddler and return a list of all the tiddlers that include it in
|
||||
*/
|
||||
exports.findListingsOfTiddler = function(targetTitle,fieldName) {
|
||||
fieldName = fieldName || "list";
|
||||
var titles = [];
|
||||
this.each(function(tiddler,title) {
|
||||
var list = $tw.utils.parseStringArray(tiddler.fields[fieldName]);
|
||||
if(list && list.indexOf(targetTitle) !== -1) {
|
||||
titles.push(title);
|
||||
}
|
||||
var wiki = this;
|
||||
var listings = this.getGlobalCache("listings-" + fieldName,function() {
|
||||
var listings = Object.create(null);
|
||||
wiki.each(function(tiddler,title) {
|
||||
var list = $tw.utils.parseStringArray(tiddler.fields[fieldName]);
|
||||
if(list) {
|
||||
for(var i = 0; i < list.length; i++) {
|
||||
var listItem = list[i],
|
||||
listing = listings[listItem] || [];
|
||||
if (listing.indexOf(title) === -1) {
|
||||
listing.push(title);
|
||||
}
|
||||
listings[listItem] = listing;
|
||||
}
|
||||
}
|
||||
});
|
||||
return listings;
|
||||
});
|
||||
return titles;
|
||||
return listings[targetTitle] || [];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -856,19 +867,24 @@ Set a tiddlers content to a JavaScript object. Currently this is done by setting
|
||||
title: title of tiddler
|
||||
data: object that can be serialised to JSON
|
||||
fields: optional hashmap of additional tiddler fields to be set
|
||||
options: optional hashmap of options including:
|
||||
suppressTimestamp: if true, don't set the creation/modification timestamps
|
||||
*/
|
||||
exports.setTiddlerData = function(title,data,fields) {
|
||||
exports.setTiddlerData = function(title,data,fields,options) {
|
||||
options = options || {};
|
||||
var existingTiddler = this.getTiddler(title),
|
||||
creationFields = options.suppressTimestamp ? {} : this.getCreationFields(),
|
||||
modificationFields = options.suppressTimestamp ? {} : this.getModificationFields(),
|
||||
newFields = {
|
||||
title: title
|
||||
};
|
||||
};
|
||||
if(existingTiddler && existingTiddler.fields.type === "application/x-tiddler-dictionary") {
|
||||
newFields.text = $tw.utils.makeTiddlerDictionary(data);
|
||||
} else {
|
||||
newFields.type = "application/json";
|
||||
newFields.text = JSON.stringify(data,null,$tw.config.preferences.jsonSpaces);
|
||||
}
|
||||
this.addTiddler(new $tw.Tiddler(this.getCreationFields(),existingTiddler,fields,newFields,this.getModificationFields()));
|
||||
this.addTiddler(new $tw.Tiddler(creationFields,existingTiddler,fields,newFields,modificationFields));
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1196,23 +1212,28 @@ Return an array of tiddler titles that match a search string
|
||||
text: The text string to search for
|
||||
options: see below
|
||||
Options available:
|
||||
source: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)
|
||||
source: an iterator function for the source tiddlers, called source(iterator),
|
||||
where iterator is called as iterator(tiddler,title)
|
||||
exclude: An array of tiddler titles to exclude from the search
|
||||
invert: If true returns tiddlers that do not contain the specified string
|
||||
caseSensitive: If true forces a case sensitive search
|
||||
field: If specified, restricts the search to the specified field, or an array of field names
|
||||
anchored: If true, forces all but regexp searches to be anchored to the start of text
|
||||
excludeField: If true, the field options are inverted to specify the fields that are not to be searched
|
||||
|
||||
The search mode is determined by the first of these boolean flags to be true
|
||||
literal: searches for literal string
|
||||
whitespace: same as literal except runs of whitespace are treated as a single space
|
||||
regexp: treats the search term as a regular expression
|
||||
words: (default) treats search string as a list of tokens, and matches if all tokens are found, regardless of adjacency or ordering
|
||||
words: (default) treats search string as a list of tokens, and matches if all tokens are found,
|
||||
regardless of adjacency or ordering
|
||||
some: treats search string as a list of tokens, and matches if at least ONE token is found
|
||||
*/
|
||||
exports.search = function(text,options) {
|
||||
options = options || {};
|
||||
var self = this,
|
||||
t,
|
||||
regExpStr="",
|
||||
invert = !!options.invert;
|
||||
// Convert the search string into a regexp for each term
|
||||
var terms, searchTermsRegExps,
|
||||
@@ -1239,7 +1260,18 @@ exports.search = function(text,options) {
|
||||
searchTermsRegExps = null;
|
||||
console.log("Regexp error parsing /(" + text + ")/" + flags + ": ",e);
|
||||
}
|
||||
} else {
|
||||
} else if(options.some) {
|
||||
terms = text.trim().split(/ +/);
|
||||
if(terms.length === 1 && terms[0] === "") {
|
||||
searchTermsRegExps = null;
|
||||
} else {
|
||||
searchTermsRegExps = [];
|
||||
for(t=0; t<terms.length; t++) {
|
||||
regExpStr += (t===0) ? anchor + $tw.utils.escapeRegExp(terms[t]) : "|" + anchor + $tw.utils.escapeRegExp(terms[t]);
|
||||
}
|
||||
searchTermsRegExps.push(new RegExp("(" + regExpStr + ")",flags));
|
||||
}
|
||||
} else { // default: words
|
||||
terms = text.split(/ +/);
|
||||
if(terms.length === 1 && terms[0] === "") {
|
||||
searchTermsRegExps = null;
|
||||
@@ -1250,7 +1282,7 @@ exports.search = function(text,options) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Accumulate the array of fields to be searched or excluded from the search
|
||||
// Accumulate the array of fields to be searched or excluded from the search
|
||||
var fields = [];
|
||||
if(options.field) {
|
||||
if($tw.utils.isArray(options.field)) {
|
||||
|
||||
@@ -6,7 +6,7 @@ title: $:/core/templates/tiddlywiki5.html
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<!--~~ Raw markup for the top of the head section ~~-->
|
||||
`{{{ [<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}`
|
||||
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}`
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
|
||||
<meta name="application-name" content="TiddlyWiki" />
|
||||
<meta name="generator" content="TiddlyWiki" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
title: $:/core/ui/Components/tag-link
|
||||
|
||||
<$link>
|
||||
<$set name="backgroundColor" value={{!!color}}>
|
||||
<$set name="backgroundColor" value={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}>
|
||||
<span style=<<tag-styles>> class="tc-tag-label">
|
||||
<$view field="title" format="text"/>
|
||||
</span>
|
||||
|
||||
9
core/ui/ControlPanel/Cascades.tid
Normal file
9
core/ui/ControlPanel/Cascades.tid
Normal file
@@ -0,0 +1,9 @@
|
||||
title: $:/core/ui/ControlPanel/Cascades
|
||||
tags: $:/tags/ControlPanel/Advanced
|
||||
caption: {{$:/language/ControlPanel/Cascades/Caption}}
|
||||
|
||||
{{$:/language/ControlPanel/Cascades/Hint}}
|
||||
|
||||
<div class="tc-control-panel">
|
||||
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Cascades]!has[draft.of]]" default="$:/core/ui/ControlPanel/StoryTiddler"/>
|
||||
</div>
|
||||
9
core/ui/ControlPanel/Cascades/EditTemplateBody.tid
Normal file
9
core/ui/ControlPanel/Cascades/EditTemplateBody.tid
Normal file
@@ -0,0 +1,9 @@
|
||||
title: $:/core/ui/ControlPanel/EditTemplateBody
|
||||
tags: $:/tags/ControlPanel/Cascades
|
||||
caption: {{$:/language/ControlPanel/EditTemplateBody/Caption}}
|
||||
|
||||
\define lingo-base() $:/language/ControlPanel/EditTemplateBody/
|
||||
|
||||
<<lingo Hint>>
|
||||
|
||||
{{$:/tags/EditTemplateBodyFilter||$:/snippets/ListTaggedCascade}}
|
||||
9
core/ui/ControlPanel/Cascades/StoryTiddler.tid
Normal file
9
core/ui/ControlPanel/Cascades/StoryTiddler.tid
Normal file
@@ -0,0 +1,9 @@
|
||||
title: $:/core/ui/ControlPanel/StoryTiddler
|
||||
tags: $:/tags/ControlPanel/Cascades
|
||||
caption: {{$:/language/ControlPanel/StoryTiddler/Caption}}
|
||||
|
||||
\define lingo-base() $:/language/ControlPanel/StoryTiddler/
|
||||
|
||||
<<lingo Hint>>
|
||||
|
||||
{{$:/tags/StoryTiddlerTemplateFilter||$:/snippets/ListTaggedCascade}}
|
||||
9
core/ui/ControlPanel/Cascades/TiddlerColour.tid
Normal file
9
core/ui/ControlPanel/Cascades/TiddlerColour.tid
Normal file
@@ -0,0 +1,9 @@
|
||||
title: $:/core/ui/ControlPanel/TiddlerColour
|
||||
tags: $:/tags/ControlPanel/Cascades
|
||||
caption: {{$:/language/ControlPanel/TiddlerColour/Caption}}
|
||||
|
||||
\define lingo-base() $:/language/ControlPanel/TiddlerColour/
|
||||
|
||||
<<lingo Hint>>
|
||||
|
||||
{{$:/tags/TiddlerColourFilter||$:/snippets/ListTaggedCascade}}
|
||||
9
core/ui/ControlPanel/Cascades/TiddlerIcon.tid
Normal file
9
core/ui/ControlPanel/Cascades/TiddlerIcon.tid
Normal file
@@ -0,0 +1,9 @@
|
||||
title: $:/core/ui/ControlPanel/TiddlerIcon
|
||||
tags: $:/tags/ControlPanel/Cascades
|
||||
caption: {{$:/language/ControlPanel/TiddlerIcon/Caption}}
|
||||
|
||||
\define lingo-base() $:/language/ControlPanel/TiddlerIcon/
|
||||
|
||||
<<lingo Hint>>
|
||||
|
||||
{{$:/tags/TiddlerIconFilter||$:/snippets/ListTaggedCascade}}
|
||||
9
core/ui/ControlPanel/Cascades/ViewTemplateBody.tid
Normal file
9
core/ui/ControlPanel/Cascades/ViewTemplateBody.tid
Normal file
@@ -0,0 +1,9 @@
|
||||
title: $:/core/ui/ControlPanel/ViewTemplateBody
|
||||
tags: $:/tags/ControlPanel/Cascades
|
||||
caption: {{$:/language/ControlPanel/ViewTemplateBody/Caption}}
|
||||
|
||||
\define lingo-base() $:/language/ControlPanel/ViewTemplateBody/
|
||||
|
||||
<<lingo Hint>>
|
||||
|
||||
{{$:/tags/ViewTemplateBodyFilter||$:/snippets/ListTaggedCascade}}
|
||||
9
core/ui/ControlPanel/Cascades/ViewTemplateTitle.tid
Normal file
9
core/ui/ControlPanel/Cascades/ViewTemplateTitle.tid
Normal file
@@ -0,0 +1,9 @@
|
||||
title: $:/core/ui/ControlPanel/ViewTemplateTitle
|
||||
tags: $:/tags/ControlPanel/Cascades
|
||||
caption: {{$:/language/ControlPanel/ViewTemplateTitle/Caption}}
|
||||
|
||||
\define lingo-base() $:/language/ControlPanel/ViewTemplateTitle/
|
||||
|
||||
<<lingo Hint>>
|
||||
|
||||
{{$:/tags/ViewTemplateTitleFilter||$:/snippets/ListTaggedCascade}}
|
||||
@@ -1,54 +1,4 @@
|
||||
title: $:/core/ui/EditTemplate/body
|
||||
tags: $:/tags/EditTemplate
|
||||
|
||||
\define lingo-base() $:/language/EditTemplate/Body/
|
||||
\define config-visibility-title()
|
||||
$:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$
|
||||
\end
|
||||
|
||||
\define importFileActions()
|
||||
<$action-popup $state=<<importState>> $coords="(0,0,0,0)" $floating="yes"/>
|
||||
\end
|
||||
|
||||
<$list filter="[all[current]has[_canonical_uri]]">
|
||||
|
||||
<div class="tc-message-box">
|
||||
|
||||
<<lingo External/Hint>>
|
||||
|
||||
<a href={{!!_canonical_uri}}><$text text={{!!_canonical_uri}}/></a>
|
||||
|
||||
<$edit-text field="_canonical_uri" class="tc-edit-fields" tabindex={{$:/config/EditTabIndex}} cancelPopups="yes"></$edit-text>
|
||||
|
||||
</div>
|
||||
|
||||
</$list>
|
||||
|
||||
<$list filter="[all[current]!has[_canonical_uri]]">
|
||||
<$vars importTitle=<<qualify $:/ImportImage>> importState=<<qualify $:/state/ImportImage>> >
|
||||
<$dropzone importTitle=<<importTitle>> autoOpenOnImport="no" contentTypesFilter={{$:/config/Editor/ImportContentTypesFilter}} class="tc-dropzone-editor" enable={{{ [{$:/config/DragAndDrop/Enable}match[no]] :else[subfilter{$:/config/Editor/EnableImportFilter}then[yes]else[no]] }}} filesOnly="yes" actions=<<importFileActions>> ><$reveal state="$:/state/showeditpreview" type="match" text="yes">
|
||||
<div class="tc-tiddler-preview">
|
||||
|
||||
<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/>
|
||||
|
||||
<div class="tc-tiddler-preview-preview">
|
||||
|
||||
<$transclude tiddler={{$:/state/editpreviewtype}} mode="inline">
|
||||
|
||||
<$transclude tiddler="$:/core/ui/EditTemplate/body/preview/output" mode="inline"/>
|
||||
|
||||
</$transclude>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</$reveal>
|
||||
|
||||
<$reveal state="$:/state/showeditpreview" type="nomatch" text="yes">
|
||||
|
||||
<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/>
|
||||
|
||||
</$reveal>
|
||||
</$dropzone>
|
||||
</$vars>
|
||||
</$list>
|
||||
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/EditTemplateBodyFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/EditTemplate/body/default]] }}} />
|
||||
|
||||
13
core/ui/EditTemplate/body/canonical-uri.tid
Normal file
13
core/ui/EditTemplate/body/canonical-uri.tid
Normal file
@@ -0,0 +1,13 @@
|
||||
title: $:/core/ui/EditTemplate/body/canonical-uri
|
||||
|
||||
\define lingo-base() $:/language/EditTemplate/Body/
|
||||
|
||||
<div class="tc-message-box">
|
||||
|
||||
<<lingo External/Hint>>
|
||||
|
||||
<a href={{!!_canonical_uri}}><$text text={{!!_canonical_uri}}/></a>
|
||||
|
||||
<$edit-text field="_canonical_uri" class="tc-edit-fields" tabindex={{$:/config/EditTabIndex}} cancelPopups="yes"></$edit-text>
|
||||
|
||||
</div>
|
||||
38
core/ui/EditTemplate/body/default.tid
Normal file
38
core/ui/EditTemplate/body/default.tid
Normal file
@@ -0,0 +1,38 @@
|
||||
title: $:/core/ui/EditTemplate/body/default
|
||||
|
||||
\define config-visibility-title()
|
||||
$:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$
|
||||
\end
|
||||
|
||||
\define importFileActions()
|
||||
<$action-popup $state=<<importState>> $coords="(0,0,0,0)" $floating="yes"/>
|
||||
\end
|
||||
|
||||
<$set name="edit-preview-state" value={{{ [{$:/config/ShowEditPreview/PerTiddler}!match[yes]then[$:/state/showeditpreview]] :else[<qualify "$:/state/showeditpreview">] }}}>
|
||||
<$vars importTitle=<<qualify $:/ImportImage>> importState=<<qualify $:/state/ImportImage>> >
|
||||
<$dropzone importTitle=<<importTitle>> autoOpenOnImport="no" contentTypesFilter={{$:/config/Editor/ImportContentTypesFilter}} class="tc-dropzone-editor" enable={{{ [{$:/config/DragAndDrop/Enable}match[no]] :else[subfilter{$:/config/Editor/EnableImportFilter}then[yes]else[no]] }}} filesOnly="yes" actions=<<importFileActions>> ><$reveal stateTitle=<<edit-preview-state>> type="match" text="yes">
|
||||
<div class="tc-tiddler-preview">
|
||||
|
||||
<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/>
|
||||
|
||||
<div class="tc-tiddler-preview-preview">
|
||||
|
||||
<$transclude tiddler={{$:/state/editpreviewtype}} mode="inline">
|
||||
|
||||
<$transclude tiddler="$:/core/ui/EditTemplate/body/preview/output" mode="inline"/>
|
||||
|
||||
</$transclude>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</$reveal>
|
||||
|
||||
<$reveal stateTitle=<<edit-preview-state>> type="nomatch" text="yes">
|
||||
|
||||
<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/>
|
||||
|
||||
</$reveal>
|
||||
</$dropzone>
|
||||
</$vars>
|
||||
</$set>
|
||||
@@ -29,7 +29,7 @@ color:$(foregroundColor)$;
|
||||
\whitespace trim
|
||||
<div class="tc-edit-tags">
|
||||
<$list filter="[list[!!$tagField$]sort[title]]" storyview="pop">
|
||||
<$macrocall $name="tag-body" colour={{!!color}} palette={{$:/palette}} icon={{!!icon}} tagField=<<__tagField__>>/>
|
||||
<$macrocall $name="tag-body" colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}} palette={{$:/palette}} icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}} tagField=<<__tagField__>>/>
|
||||
</$list>
|
||||
<$vars tabIndex={{$:/config/EditTabIndex}} cancelPopups="yes">
|
||||
<$macrocall $name="tag-picker" tagField=<<__tagField__>>/>
|
||||
|
||||
@@ -23,7 +23,7 @@ first-search-filter: [all[shadows+tiddlers]prefix[$:/language/Docs/Types/]sort[d
|
||||
<$text text={{!!group}}/>
|
||||
</div>
|
||||
<$set name="userInput" value={{{ [<typeInputTiddler>get[text]] }}}>
|
||||
<$list filter="[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]group{!!group}] +[sort[description]] +[removeprefix[$:/language/Docs/Types/]] +[search<userInput>]"><span class={{{ [<currentTiddler>addsuffix[-primaryList]] -[<typeSelectionTiddler>get[text]] +[then[]else[tc-list-item-selected]] }}}><$link to={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]get[name]] }}}><$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field="description"/> (<$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field="name"/>)</$link></span>
|
||||
<$list filter="[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]group{!!group}] +[sort[description]] +[removeprefix[$:/language/Docs/Types/]] +[search<userInput>]"><span class={{{ [<currentTiddler>addsuffix[-primaryList]] -[<typeSelectionTiddler>get[text]] +[then[]else[tc-list-item-selected]] }}}><$link to={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]get[name]] }}}><$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field="description"/><$text text=" "/>(<$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field="name"/>)</$link></span>
|
||||
</$list>
|
||||
</$set>
|
||||
</$list>
|
||||
|
||||
@@ -13,7 +13,7 @@ title: $:/core/ui/EditorToolbar/link-dropdown
|
||||
<$set name="userInput" value={{{ [<storeTitle>get[text]] }}}><$list filter="[<searchTiddler>get[text]!match<userInput>]" emptyMessage="""<$action-deletetiddler $filter="[<searchTiddler>] [<linkTiddler>] [<storeTitle>] [<searchListState>]"/>"""><$action-setfield $tiddler=<<searchTiddler>> text=<<userInput>>/><$action-setfield $tiddler=<<refreshTitle>> text="yes"/></$list></$set>
|
||||
\end
|
||||
|
||||
\define cancel-search-actions() <$list filter="[<storeTitle>!has[text]] +[<searchTiddler>!has[text]]" emptyMessage="""<<cancel-search-actions-inner>>"""><$action-sendmessage $message="tm-edit-text-operation" $param="wrap-selection" prefix="" suffix=""/></$list>
|
||||
\define cancel-search-actions() <$list filter="[<storeTitle>!has[text]] +[<searchTiddler>!has[text]]" emptyMessage="""<<cancel-search-actions-inner>>"""><$action-sendmessage $message="tm-edit-text-operation" $param="focus-editor"/></$list>
|
||||
|
||||
\define external-link()
|
||||
<$button class="tc-btn-invisible" style="width: auto; display: inline-block; background-colour: inherit;" actions=<<add-link-actions>>>
|
||||
|
||||
@@ -8,11 +8,11 @@ condition: [<targetTiddler>]
|
||||
button-classes: tc-text-editor-toolbar-item-start-group
|
||||
shortcuts: ((preview))
|
||||
|
||||
<$reveal state="$:/state/showeditpreview" type="match" text="yes" tag="span">
|
||||
<$reveal state=<<edit-preview-state>> type="match" text="yes" tag="span">
|
||||
{{$:/core/images/preview-open}}
|
||||
<$action-setfield $tiddler="$:/state/showeditpreview" $value="no"/>
|
||||
<$action-setfield $tiddler=<<edit-preview-state>> $value="no"/>
|
||||
</$reveal>
|
||||
<$reveal state="$:/state/showeditpreview" type="nomatch" text="yes" tag="span">
|
||||
<$reveal state=<<edit-preview-state>> type="nomatch" text="yes" tag="span">
|
||||
{{$:/core/images/preview-closed}}
|
||||
<$action-setfield $tiddler="$:/state/showeditpreview" $value="yes"/>
|
||||
<$action-setfield $tiddler=<<edit-preview-state>> $value="yes"/>
|
||||
</$reveal>
|
||||
|
||||
14
core/ui/ListTaggedCascade.tid
Normal file
14
core/ui/ListTaggedCascade.tid
Normal file
@@ -0,0 +1,14 @@
|
||||
title: $:/snippets/ListTaggedCascade
|
||||
|
||||
{{||$:/language/ControlPanel/Cascades/TagPrompt}}
|
||||
|
||||
<ol>
|
||||
<$list filter="[all[shadows+tiddlers]tag<currentTiddler>]">
|
||||
<li>
|
||||
<div>
|
||||
<$link><$text text=<<currentTiddler>>/></$link>
|
||||
</div>
|
||||
<$codeblock code={{!!text}}/>
|
||||
</li>
|
||||
</$list>
|
||||
</ol>
|
||||
@@ -14,7 +14,7 @@ tags: $:/tags/PageTemplate
|
||||
|
||||
</section>
|
||||
|
||||
<$list filter="[list[$:/StoryList]]" history="$:/HistoryList" template={{$:/config/ui/ViewTemplate}} editTemplate={{$:/config/ui/EditTemplate}} storyview={{$:/view}} emptyMessage={{$:/config/EmptyStoryMessage}}/>
|
||||
<$list filter="[list[$:/StoryList]]" history="$:/HistoryList" template="$:/core/ui/StoryTiddlerTemplate" storyview={{$:/view}} emptyMessage={{$:/config/EmptyStoryMessage}}/>
|
||||
|
||||
<section class="story-frontdrop">
|
||||
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
title: $:/core/ui/PluginListItemTemplate
|
||||
|
||||
<div class="tc-menu-list-item">
|
||||
<$link to={{!!title}}><$view field="description"><$view field="title"/></$view></$link>
|
||||
</div>
|
||||
\whitespace trim
|
||||
<$link to={{!!title}} class="tc-plugin-info">
|
||||
<div class="tc-plugin-info-chunk tc-plugin-info-icon">
|
||||
<$transclude tiddler=<<currentTiddler>> subtiddler={{{ [<currentTiddler>addsuffix[/icon]] }}}>
|
||||
<$transclude tiddler={{{ [<currentTiddler>get[plugin-type]addprefix[$:/core/images/plugin-generic-]] }}}/>
|
||||
</$transclude>
|
||||
</div>
|
||||
<div class="tc-plugin-info-chunk tc-plugin-info-description">
|
||||
<h1>
|
||||
''<$text text={{{ [<currentTiddler>get[name]] ~[<currentTiddler>split[/]last[1]] }}}/>'': <$view field="description"><$view field="title"/></$view>
|
||||
</h1>
|
||||
</div>
|
||||
</$link>
|
||||
|
||||
3
core/ui/StoryTiddlerTemplate.tid
Normal file
3
core/ui/StoryTiddlerTemplate.tid
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/core/ui/StoryTiddlerTemplate
|
||||
|
||||
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/StoryTiddlerTemplateFilter]!is[draft]get[text]] :and[!is[blank]else{$:/config/ui/ViewTemplate}] }}} />
|
||||
@@ -13,10 +13,10 @@ title: $:/core/ui/TagPickerTagTemplate
|
||||
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
||||
</$list>
|
||||
<<actions>>
|
||||
<$set name="backgroundColor" value={{!!color}}>
|
||||
<$wikify name="foregroundColor" text="""<$macrocall $name="contrastcolour" target={{!!color}} fallbackTarget=<<fallbackTarget>> colourA=<<colourA>> colourB=<<colourB>>/>""">
|
||||
<$set name="backgroundColor" value={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}>
|
||||
<$wikify name="foregroundColor" text="""<$macrocall $name="contrastcolour" target=<<backgroundColor>> fallbackTarget=<<fallbackTarget>> colourA=<<colourA>> colourB=<<colourB>>/>""">
|
||||
<span class="tc-tag-label tc-btn-invisible" style=<<tag-pill-styles>>>
|
||||
<$transclude tiddler={{!!icon}}/><$view field="title" format="text"/>
|
||||
{{||$:/core/ui/TiddlerIcon}}<$view field="title" format="text"/>
|
||||
</span>
|
||||
</$wikify>
|
||||
</$set>
|
||||
|
||||
@@ -3,7 +3,7 @@ title: $:/core/ui/TagTemplate
|
||||
\whitespace trim
|
||||
<span class="tc-tag-list-item" data-tag-title=<<currentTiddler>>>
|
||||
<$set name="transclusion" value=<<currentTiddler>>>
|
||||
<$macrocall $name="tag-pill-body" tag=<<currentTiddler>> icon={{!!icon}} colour={{!!color}} palette={{$:/palette}} element-tag="""$button""" element-attributes="""popup=<<qualify "$:/state/popup/tag">> dragFilter='[all[current]tagging[]]' tag='span'"""/>
|
||||
<$macrocall $name="tag-pill-body" tag=<<currentTiddler>> icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}} colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}} palette={{$:/palette}} element-tag="""$button""" element-attributes="""popup=<<qualify "$:/state/popup/tag">> dragFilter='[all[current]tagging[]]' tag='span'"""/>
|
||||
<$reveal state=<<qualify "$:/state/popup/tag">> type="popup" position="below" animate="yes" class="tc-drop-down">
|
||||
<$set name="tv-show-missing-links" value="yes">
|
||||
<$transclude tiddler="$:/core/ui/ListItemTemplate"/>
|
||||
|
||||
8
core/ui/TiddlerIcon.tid
Normal file
8
core/ui/TiddlerIcon.tid
Normal file
@@ -0,0 +1,8 @@
|
||||
title: $:/core/ui/TiddlerIcon
|
||||
|
||||
\whitespace trim
|
||||
<$let tiddlerIcon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}>
|
||||
<$list filter="[<tiddlerIcon>!is[blank]]" variable="ignore">
|
||||
<$transclude tiddler=<<tiddlerIcon>>/>
|
||||
</$list>
|
||||
</$let>
|
||||
@@ -3,14 +3,6 @@ tags: $:/tags/ViewTemplate
|
||||
|
||||
<$reveal tag="div" class="tc-tiddler-body" type="nomatch" stateTitle=<<folded-state>> text="hide" retain="yes" animate="yes">
|
||||
|
||||
<$list filter="[all[current]!has[plugin-type]!field:hide-body[yes]]">
|
||||
|
||||
<$transclude>
|
||||
|
||||
<$transclude tiddler="$:/language/MissingTiddler/Hint"/>
|
||||
|
||||
</$transclude>
|
||||
|
||||
</$list>
|
||||
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateBodyFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/body/default]] }}} />
|
||||
|
||||
</$reveal>
|
||||
|
||||
3
core/ui/ViewTemplate/body/blank.tid
Normal file
3
core/ui/ViewTemplate/body/blank.tid
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/core/ui/ViewTemplate/body/blank
|
||||
|
||||
<!-- Intentionally blank -->
|
||||
3
core/ui/ViewTemplate/body/code.tid
Normal file
3
core/ui/ViewTemplate/body/code.tid
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/core/ui/ViewTemplate/body/code
|
||||
|
||||
<$codeblock code={{{ [<currentTiddler>get[text]] }}} language={{{ [<currentTiddler>get[type]else[text/vnd.tiddlywiki]] }}}/>
|
||||
7
core/ui/ViewTemplate/body/default.tid
Normal file
7
core/ui/ViewTemplate/body/default.tid
Normal file
@@ -0,0 +1,7 @@
|
||||
title: $:/core/ui/ViewTemplate/body/default
|
||||
|
||||
<$transclude>
|
||||
|
||||
<$transclude tiddler="$:/language/MissingTiddler/Hint"/>
|
||||
|
||||
</$transclude>
|
||||
@@ -1,5 +1,4 @@
|
||||
title: $:/core/ui/ViewTemplate/import
|
||||
tags: $:/tags/ViewTemplate
|
||||
title: $:/core/ui/ViewTemplate/body/import
|
||||
|
||||
\define lingo-base() $:/language/Import/
|
||||
|
||||
10
core/ui/ViewTemplate/body/plugin.tid
Normal file
10
core/ui/ViewTemplate/body/plugin.tid
Normal file
@@ -0,0 +1,10 @@
|
||||
title: $:/core/ui/ViewTemplate/body/plugin
|
||||
|
||||
<div class="tc-tiddler-plugin-info">
|
||||
<$let plugin-type={{!!plugin-type}}
|
||||
default-popup-state="yes"
|
||||
qualified-state=<<qualify "$:/state/plugin-info">>
|
||||
>
|
||||
{{||$:/core/ui/Components/plugin-info}}
|
||||
</$let>
|
||||
</div>
|
||||
@@ -1,15 +0,0 @@
|
||||
title: $:/core/ui/ViewTemplate/plugin
|
||||
tags: $:/tags/ViewTemplate
|
||||
|
||||
<$reveal tag="div" class="tc-tiddler-plugin-info" type="nomatch" stateTitle=<<folded-state>> text="hide" retain="yes" animate="yes">
|
||||
|
||||
<$list filter="[all[current]has[plugin-type]] -[all[current]field:plugin-type[import]]">
|
||||
<$set name="plugin-type" value={{!!plugin-type}}>
|
||||
<$set name="default-popup-state" value="yes">
|
||||
<$set name="qualified-state" value=<<qualify "$:/state/plugin-info">>>
|
||||
{{||$:/core/ui/Components/plugin-info}}
|
||||
</$set>
|
||||
</$set>
|
||||
</$set>
|
||||
</$list>
|
||||
</$reveal>
|
||||
@@ -12,25 +12,12 @@ fill:$(foregroundColor)$;
|
||||
</span>
|
||||
<$set name="tv-wikilinks" value={{$:/config/Tiddlers/TitleLinks}}>
|
||||
<$link>
|
||||
<$set name="foregroundColor" value={{!!color}}>
|
||||
<$list filter="[all[current]has[icon]]~[[$:/config/DefaultTiddlerIcon]has[text]]">
|
||||
<$let foregroundColor={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}>
|
||||
<span class="tc-tiddler-title-icon" style=<<title-styles>>>
|
||||
<$transclude tiddler={{!!icon}}>
|
||||
<$transclude tiddler={{$:/config/DefaultTiddlerIcon}}/>
|
||||
</$transclude>
|
||||
{{||$:/core/ui/TiddlerIcon}}
|
||||
</span>
|
||||
</$list>
|
||||
</$set>
|
||||
<$list filter="[all[current]removeprefix[$:/]]">
|
||||
<h2 class="tc-title" title={{$:/language/SystemTiddler/Tooltip}}>
|
||||
<span class="tc-system-title-prefix">$:/</span><$text text=<<currentTiddler>>/>
|
||||
</h2>
|
||||
</$list>
|
||||
<$list filter="[all[current]!prefix[$:/]]">
|
||||
<h2 class="tc-title">
|
||||
<$view field="title"/>
|
||||
</h2>
|
||||
</$list>
|
||||
</$let>
|
||||
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateTitleFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/title/default]] }}} />
|
||||
</$link>
|
||||
</$set>
|
||||
</div>
|
||||
|
||||
6
core/ui/ViewTemplate/title/default.tid
Normal file
6
core/ui/ViewTemplate/title/default.tid
Normal file
@@ -0,0 +1,6 @@
|
||||
title: $:/core/ui/ViewTemplate/title/default
|
||||
|
||||
\whitespace trim
|
||||
<h2 class="tc-title">
|
||||
<$view field="title"/>
|
||||
</h2>
|
||||
6
core/ui/ViewTemplate/title/system.tid
Normal file
6
core/ui/ViewTemplate/title/system.tid
Normal file
@@ -0,0 +1,6 @@
|
||||
title: $:/core/ui/ViewTemplate/title/system
|
||||
|
||||
\whitespace trim
|
||||
<h2 class="tc-title" title={{$:/language/SystemTiddler/Tooltip}}>
|
||||
<span class="tc-system-title-prefix">$:/</span><$text text={{{ [<currentTiddler>removeprefix[$:/]] }}}/>
|
||||
</h2>
|
||||
@@ -1,7 +1,7 @@
|
||||
title: $:/snippets/allfields
|
||||
|
||||
\define renderfield(title)
|
||||
<tr class="tc-view-field"><td class="tc-view-field-name">''$title$'':</td><td class="tc-view-field-value">//{{$:/language/Docs/Fields/$title$}}//</td></tr>
|
||||
<tr class="tc-view-field"><td class="tc-view-field-name">''<$text text=<<__title__>>/>'':</td><td class="tc-view-field-value">//{{$:/language/Docs/Fields/$title$}}//</td></tr>
|
||||
\end
|
||||
<table class="tc-view-field-table"><tbody><$list filter="[fields[]sort[title]]" variable="listItem"><$macrocall $name="renderfield" title=<<listItem>>/></$list>
|
||||
</tbody></table>
|
||||
|
||||
5
core/wiki/config/EditTemplateBodyFilters.multids
Normal file
5
core/wiki/config/EditTemplateBodyFilters.multids
Normal file
@@ -0,0 +1,5 @@
|
||||
title: $:/config/EditTemplateBodyFilters/
|
||||
tags: $:/tags/EditTemplateBodyFilter
|
||||
|
||||
canonical-uri: [has[_canonical_uri]then[$:/core/ui/EditTemplate/body/canonical-uri]]
|
||||
default: [[$:/core/ui/EditTemplate/body/default]]
|
||||
@@ -1,6 +1,6 @@
|
||||
title: $:/config/OfficialPluginLibrary
|
||||
tags: $:/tags/PluginLibrary
|
||||
url: https://tiddlywiki.com/library/v5.2.0/index.html
|
||||
url: https://tiddlywiki.com/library/v5.2.2/index.html
|
||||
caption: {{$:/language/OfficialPluginLibrary}}
|
||||
|
||||
{{$:/language/OfficialPluginLibrary/Hint}}
|
||||
|
||||
5
core/wiki/config/StoryTiddlerTemplateFilters.multids
Normal file
5
core/wiki/config/StoryTiddlerTemplateFilters.multids
Normal file
@@ -0,0 +1,5 @@
|
||||
title: $:/config/StoryTiddlerTemplateFilters/
|
||||
tags: $:/tags/StoryTiddlerTemplateFilter
|
||||
|
||||
draft: [is[draft]then{$:/config/ui/EditTemplate}]
|
||||
default: [{$:/config/ui/ViewTemplate}]
|
||||
5
core/wiki/config/TiddlerColourFilters.multids
Normal file
5
core/wiki/config/TiddlerColourFilters.multids
Normal file
@@ -0,0 +1,5 @@
|
||||
title: $:/config/TiddlerColourFilters/
|
||||
tags: $:/tags/TiddlerColourFilter
|
||||
|
||||
color-field: [has[color]then{!!color}]
|
||||
default: [[$:/config/DefaultTiddlerColour]has[text]get[text]trim[]]
|
||||
5
core/wiki/config/TiddlerIconFilters.multids
Normal file
5
core/wiki/config/TiddlerIconFilters.multids
Normal file
@@ -0,0 +1,5 @@
|
||||
title: $:/config/TiddlerIconFilters/
|
||||
tags: $:/tags/TiddlerIconFilter
|
||||
|
||||
icon-field: [has[icon]then{!!icon}]
|
||||
default: [{$:/config/DefaultTiddlerIcon}has[text]]
|
||||
9
core/wiki/config/ViewTemplateBodyFilters.multids
Normal file
9
core/wiki/config/ViewTemplateBodyFilters.multids
Normal file
@@ -0,0 +1,9 @@
|
||||
title: $:/config/ViewTemplateBodyFilters/
|
||||
tags: $:/tags/ViewTemplateBodyFilter
|
||||
|
||||
system: [prefix[$:/boot/]] [prefix[$:/config/]] [prefix[$:/core/macros]] [prefix[$:/core/save/]] [prefix[$:/core/templates/]] [prefix[$:/core/ui/]split[/]count[]compare:number:eq[4]] [prefix[$:/info/]] [prefix[$:/language/]] [prefix[$:/languages/]] [prefix[$:/snippets/]] [prefix[$:/state/]] [prefix[$:/status/]] [prefix[$:/info/]] [prefix[$:/temp/]] +[limit[1]then[$:/core/ui/ViewTemplate/body/code]]
|
||||
code-body: [field:code-body[yes]then[$:/core/ui/ViewTemplate/body/code]]
|
||||
import: [field:plugin-type[import]then[$:/core/ui/ViewTemplate/body/import]]
|
||||
plugin: [has[plugin-type]then[$:/core/ui/ViewTemplate/body/plugin]]
|
||||
hide-body: [field:hide-body[yes]then[$:/core/ui/ViewTemplate/body/blank]]
|
||||
default: [[$:/core/ui/ViewTemplate/body/default]]
|
||||
5
core/wiki/config/ViewTemplateTitleFilters.multids
Normal file
5
core/wiki/config/ViewTemplateTitleFilters.multids
Normal file
@@ -0,0 +1,5 @@
|
||||
title: $:/config/ViewTemplateTitleFilters/
|
||||
tags: $:/tags/ViewTemplateTitleFilter
|
||||
|
||||
system: [prefix[$:/]then[$:/core/ui/ViewTemplate/title/system]]
|
||||
default: [[$:/core/ui/ViewTemplate/title/default]]
|
||||
9
core/wiki/debugstylesheets.tid
Normal file
9
core/wiki/debugstylesheets.tid
Normal file
@@ -0,0 +1,9 @@
|
||||
title: $:/snippets/DebugStylesheets
|
||||
|
||||
<style>[test]{list-style:'❌'}</style>
|
||||
<ul>
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Stylesheet]has[modified]]" counter="n">
|
||||
<style>{{!!text}}[test="<<n>>"]{list-style:disc;}</style>
|
||||
<li test=<<n>>><$link/></li>
|
||||
</$list>
|
||||
</ul>
|
||||
@@ -21,7 +21,9 @@ $actions$<$transclude tiddler="""$icon$"""/><$view tiddler=<<__tag__>> field="ti
|
||||
|
||||
\define tag-pill(tag,element-tag:"span",element-attributes:"",actions:"")
|
||||
<span class="tc-tag-list-item" data-tag-title=<<__tag__>>>
|
||||
<$macrocall $name="tag-pill-body" tag=<<__tag__>> icon={{{ [<__tag__>get[icon]] }}} colour={{{ [<__tag__>get[color]] }}} palette={{$:/palette}} element-tag="""$element-tag$""" element-attributes="""$element-attributes$""" actions="""$actions$"""/>
|
||||
<$let currentTiddler=<<__tag__>>>
|
||||
<$macrocall $name="tag-pill-body" tag=<<__tag__>> icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}} colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}} palette={{$:/palette}} element-tag="""$element-tag$""" element-attributes="""$element-attributes$""" actions="""$actions$"""/>
|
||||
</$let>
|
||||
</span>
|
||||
\end
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
title: $:/snippets/peek-stylesheets
|
||||
|
||||
\define expandable-stylesheets-list()
|
||||
\whitespace trim
|
||||
<ol>
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]">
|
||||
<$vars state=<<qualify "$:/state/peek-stylesheets/open/">>>
|
||||
@@ -38,6 +39,7 @@ title: $:/snippets/peek-stylesheets
|
||||
\end
|
||||
|
||||
\define stylesheets-list()
|
||||
\whitespace trim
|
||||
<ol>
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]">
|
||||
<li>
|
||||
@@ -57,6 +59,7 @@ title: $:/snippets/peek-stylesheets
|
||||
</$list>
|
||||
</ol>
|
||||
\end
|
||||
\whitespace trim
|
||||
|
||||
<$vars modeState=<<qualify "$:/state/peek-stylesheets/mode/">>>
|
||||
|
||||
|
||||
2
core/wiki/tags/EditTemplateBodyFilter.tid
Normal file
2
core/wiki/tags/EditTemplateBodyFilter.tid
Normal file
@@ -0,0 +1,2 @@
|
||||
title: $:/tags/EditTemplateBodyFilter
|
||||
list: $:/config/EditTemplateBodyFilters/canonical-uri $:/config/EditTemplateBodyFilters/default
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user