mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-01-23 19:34:39 +00:00
Compare commits
251 Commits
v5.0.7-bet
...
v5.0.8-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
622d4a2d50 | ||
|
|
0cff397111 | ||
|
|
fbf4486d92 | ||
|
|
2714e0939f | ||
|
|
bde6f8d2b8 | ||
|
|
4194f9f20f | ||
|
|
2c6e7ef489 | ||
|
|
cc5be5eb15 | ||
|
|
be8efe1bc7 | ||
|
|
db3c06ecd0 | ||
|
|
947b48bcf9 | ||
|
|
bed6cc7d67 | ||
|
|
63cb0eb3db | ||
|
|
89c7310a53 | ||
|
|
f244293cac | ||
|
|
3994f0dbc6 | ||
|
|
66bb7ad6ba | ||
|
|
84928ac99c | ||
|
|
6b4ec343a7 | ||
|
|
3ff85e9507 | ||
|
|
cd09cf3874 | ||
|
|
9ce79b0795 | ||
|
|
e2f964ae73 | ||
|
|
2aca526d4e | ||
|
|
0aa9f26d51 | ||
|
|
9e820a602b | ||
|
|
d38c513512 | ||
|
|
83b2a5d305 | ||
|
|
bcc282016e | ||
|
|
cdc99ac29c | ||
|
|
cf4eed0129 | ||
|
|
70306de1b1 | ||
|
|
a1a5ada68f | ||
|
|
9233069065 | ||
|
|
e5103c32f3 | ||
|
|
cadeb9654c | ||
|
|
2ed8df0d1f | ||
|
|
3636744d4f | ||
|
|
8ce7c3920c | ||
|
|
470c056b8d | ||
|
|
fd3ce5f668 | ||
|
|
f42246f171 | ||
|
|
599f5978c9 | ||
|
|
042698b508 | ||
|
|
a1ad735822 | ||
|
|
3f6bf2452a | ||
|
|
886d648568 | ||
|
|
dd299bf769 | ||
|
|
f3930ad69c | ||
|
|
b0394f1560 | ||
|
|
327403b3c9 | ||
|
|
6cd13efd48 | ||
|
|
6947f8ebc2 | ||
|
|
0623dd5b7f | ||
|
|
99ccdf4584 | ||
|
|
a332b82df5 | ||
|
|
7f5f4df562 | ||
|
|
2b4dfba2ff | ||
|
|
260080164f | ||
|
|
3f7ff22280 | ||
|
|
51c1a863f8 | ||
|
|
823b4fa61b | ||
|
|
c3f9cf41d5 | ||
|
|
ecb845f1cd | ||
|
|
0737e62161 | ||
|
|
39ee69910e | ||
|
|
2ab0facf3a | ||
|
|
6bff3e3163 | ||
|
|
ec606c89d2 | ||
|
|
9e0f1240c5 | ||
|
|
199fdb090d | ||
|
|
d6a44b67a3 | ||
|
|
2e7efe2dc0 | ||
|
|
639fd4be20 | ||
|
|
75ff9fb6c0 | ||
|
|
57c956716e | ||
|
|
cfa6f0a8a6 | ||
|
|
0961b0426b | ||
|
|
cf5fa875aa | ||
|
|
a812c6e386 | ||
|
|
dfbb6e1fba | ||
|
|
31975e0042 | ||
|
|
38ef4fa609 | ||
|
|
7f66df78ff | ||
|
|
96dc489ba8 | ||
|
|
34a7fc6084 | ||
|
|
41575b8012 | ||
|
|
cb5b95add2 | ||
|
|
372553d9da | ||
|
|
747ec243ff | ||
|
|
1bc2700137 | ||
|
|
4ee277f41b | ||
|
|
894588db54 | ||
|
|
68bcbff753 | ||
|
|
d4baf515ed | ||
|
|
d5c31ed07f | ||
|
|
9b6c59e9a6 | ||
|
|
ec0769d7ca | ||
|
|
93f5e736e7 | ||
|
|
c4058c4662 | ||
|
|
f59b84e63b | ||
|
|
c17844b815 | ||
|
|
c761bbe2ed | ||
|
|
279f32080d | ||
|
|
06a0d21734 | ||
|
|
d8513b23c2 | ||
|
|
49b4e86091 | ||
|
|
f522a96064 | ||
|
|
8f9d88f25b | ||
|
|
e88f8ad4e9 | ||
|
|
0480bf023d | ||
|
|
e3c1906eaf | ||
|
|
45f29f6425 | ||
|
|
f4c7a269bd | ||
|
|
46b2c9e24c | ||
|
|
f46864fff5 | ||
|
|
5bc408fa75 | ||
|
|
921ff6ae39 | ||
|
|
b9e72fb676 | ||
|
|
1258c16e2b | ||
|
|
35eb3aee35 | ||
|
|
12016bd0f8 | ||
|
|
3817ba642d | ||
|
|
d6ef67e817 | ||
|
|
a51a5e969f | ||
|
|
ae9d0f8288 | ||
|
|
b26b620548 | ||
|
|
d21fb85d94 | ||
|
|
bcd86d5861 | ||
|
|
5417b8c4d7 | ||
|
|
2744671211 | ||
|
|
88ffb2ad12 | ||
|
|
aa27305134 | ||
|
|
a186b6f978 | ||
|
|
e55e7ab31b | ||
|
|
e1dfb621f5 | ||
|
|
bd552aedde | ||
|
|
3f89d2d0fa | ||
|
|
c999d82a23 | ||
|
|
118b841aa2 | ||
|
|
ca1daf5a4e | ||
|
|
5e9dae8fb4 | ||
|
|
d00a82e9e9 | ||
|
|
3307604130 | ||
|
|
1ff8d225d9 | ||
|
|
489509c810 | ||
|
|
aa6e02ce8e | ||
|
|
df8ff9eb26 | ||
|
|
e051eb7d90 | ||
|
|
75b9de222e | ||
|
|
5a45fffa9e | ||
|
|
5252328dd9 | ||
|
|
a763610db1 | ||
|
|
c43cd325ca | ||
|
|
e9ba7f3d70 | ||
|
|
68809f9333 | ||
|
|
42b8b86e52 | ||
|
|
69c0b5e031 | ||
|
|
30997f3f24 | ||
|
|
bea8730a47 | ||
|
|
c3254bc981 | ||
|
|
e43a190dab | ||
|
|
4836cf83e2 | ||
|
|
44678b2ea2 | ||
|
|
70a120d4a6 | ||
|
|
28212f08b2 | ||
|
|
9bb600299f | ||
|
|
9db887748b | ||
|
|
800bc639f9 | ||
|
|
dc8e84fcb7 | ||
|
|
ad4e7ccb17 | ||
|
|
4654f6b971 | ||
|
|
6f23aeabb4 | ||
|
|
21eae0135d | ||
|
|
470beabf17 | ||
|
|
523eae83ff | ||
|
|
ca0c352278 | ||
|
|
0dc8de9dd2 | ||
|
|
b5225f5ca8 | ||
|
|
1a8d6811b7 | ||
|
|
d56eec40c9 | ||
|
|
b72d7f1447 | ||
|
|
ecad2bf7a8 | ||
|
|
f67e216b3a | ||
|
|
8b3bfa6805 | ||
|
|
01fa82fac1 | ||
|
|
d5b526914b | ||
|
|
5c66bc6dbc | ||
|
|
1eab3ecbb2 | ||
|
|
280bbde329 | ||
|
|
dd451800c7 | ||
|
|
190ced7cdd | ||
|
|
7a62a86baf | ||
|
|
1086c51019 | ||
|
|
daa79a8612 | ||
|
|
441d9078fa | ||
|
|
f0ab607ea1 | ||
|
|
afaf5b23c9 | ||
|
|
f68d48fcd3 | ||
|
|
10891081ca | ||
|
|
ecba4f71ea | ||
|
|
e003889171 | ||
|
|
1f41daf433 | ||
|
|
a2cbc2deb5 | ||
|
|
dea08ed4f8 | ||
|
|
d1bc053a9c | ||
|
|
73c30716dc | ||
|
|
8ad34e2db9 | ||
|
|
b26a32b93a | ||
|
|
f54122b90e | ||
|
|
828fc9dcd0 | ||
|
|
f0d512edf0 | ||
|
|
2758e586bd | ||
|
|
68bcfe1c8c | ||
|
|
dbd63e6fe7 | ||
|
|
a01bbd4b9c | ||
|
|
8e8e31fb9f | ||
|
|
6d3d3322e5 | ||
|
|
d02ce5dbf3 | ||
|
|
32f290dc13 | ||
|
|
1d685df928 | ||
|
|
4882f70557 | ||
|
|
7eafd51a7d | ||
|
|
e6fa9b8a85 | ||
|
|
1a54d590e1 | ||
|
|
d72d245523 | ||
|
|
7b054440ca | ||
|
|
6ed8a7624d | ||
|
|
e3a05625b2 | ||
|
|
9acb10f781 | ||
|
|
8487221654 | ||
|
|
6780a16ce9 | ||
|
|
92aa682bc5 | ||
|
|
405b4a9007 | ||
|
|
0c20092644 | ||
|
|
758d461823 | ||
|
|
29c4ed20ce | ||
|
|
fa59382215 | ||
|
|
02ba92c6b5 | ||
|
|
e58d9c7008 | ||
|
|
ac163a59e8 | ||
|
|
175e86078c | ||
|
|
3b255561b7 | ||
|
|
59379b14fa | ||
|
|
5af30086c0 | ||
|
|
b342f6db67 | ||
|
|
5d3dda1a17 | ||
|
|
70ed6e6ad3 | ||
|
|
8d031afa94 | ||
|
|
a42ba1a310 | ||
|
|
b4b524deae |
52
bld-languages.sh
Normal file
52
bld-languages.sh
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Abbreviated version of bld.sh for quicker builds
|
||||
|
||||
# Set up the build output directory
|
||||
|
||||
if [ -z "$TW5_BUILD_OUTPUT" ]; then
|
||||
TW5_BUILD_OUTPUT=../jermolene.github.com
|
||||
fi
|
||||
|
||||
if [ ! -d "$TW5_BUILD_OUTPUT" ]; then
|
||||
echo 'A valid TW5_BUILD_OUTPUT environment variable must be set'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using TW5_BUILD_OUTPUT as [$TW5_BUILD_OUTPUT]"
|
||||
|
||||
# Make the CNAME file that GitHub Pages requires
|
||||
|
||||
echo "tiddlywiki.com" > $TW5_BUILD_OUTPUT/CNAME
|
||||
|
||||
# The tw5.com wiki
|
||||
# index.html: the main file, including content
|
||||
|
||||
node ./tiddlywiki.js \
|
||||
./editions/de-AT-DE \
|
||||
--verbose \
|
||||
--rendertiddler $:/core/save/all $TW5_BUILD_OUTPUT/de-AT-DE.html text/plain \
|
||||
--savetiddler $:/favicon.ico $TW5_BUILD_OUTPUT/favicon.ico \
|
||||
|| exit 1
|
||||
|
||||
node ./tiddlywiki.js \
|
||||
./editions/zh-Hant \
|
||||
--verbose \
|
||||
--rendertiddler $:/core/save/all $TW5_BUILD_OUTPUT/zh-Hant.html text/plain \
|
||||
--savetiddler $:/favicon.ico $TW5_BUILD_OUTPUT/favicon.ico \
|
||||
|| exit 1
|
||||
|
||||
node ./tiddlywiki.js \
|
||||
./editions/zh-Hans \
|
||||
--verbose \
|
||||
--rendertiddler $:/core/save/all $TW5_BUILD_OUTPUT/zh-Hans.html text/plain \
|
||||
--savetiddler $:/favicon.ico $TW5_BUILD_OUTPUT/favicon.ico \
|
||||
|| exit 1
|
||||
|
||||
node ./tiddlywiki.js \
|
||||
./editions/fr-FR \
|
||||
--verbose \
|
||||
--rendertiddler $:/core/save/all $TW5_BUILD_OUTPUT/fr-FR.html text/plain \
|
||||
--savetiddler $:/favicon.ico $TW5_BUILD_OUTPUT/favicon.ico \
|
||||
|| exit 1
|
||||
|
||||
116
boot/boot.js
116
boot/boot.js
@@ -201,7 +201,7 @@ $tw.utils.deepDefaults = function(object /*, sourceObjectList */) {
|
||||
Convert "&" to &, " " to nbsp, "<" to <, ">" to > and """ to "
|
||||
*/
|
||||
$tw.utils.htmlDecode = function(s) {
|
||||
return s.toString().replace(/</mg,"<").replace(/ /mg,"\x40").replace(/>/mg,">").replace(/"/mg,"\"").replace(/&/mg,"&");
|
||||
return s.toString().replace(/</mg,"<").replace(/ /mg,"\xA0").replace(/>/mg,">").replace(/"/mg,"\"").replace(/&/mg,"&");
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -371,10 +371,11 @@ $tw.utils.checkVersions = function(versionStringA,versionStringB) {
|
||||
|
||||
/*
|
||||
Register file type information
|
||||
flags: "image" for image types
|
||||
*/
|
||||
$tw.utils.registerFileType = function(type,encoding,extension) {
|
||||
$tw.utils.registerFileType = function(type,encoding,extension,flags) {
|
||||
$tw.config.fileExtensionInfo[extension] = {type: type};
|
||||
$tw.config.contentTypeInfo[type] = {encoding: encoding, extension: extension};
|
||||
$tw.config.contentTypeInfo[type] = {encoding: encoding, extension: extension, flags: flags || []};
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -555,8 +556,12 @@ $tw.utils.Crypto = function() {
|
||||
this.updateCryptoStateTiddler();
|
||||
};
|
||||
this.updateCryptoStateTiddler = function() {
|
||||
if($tw.wiki && $tw.wiki.addTiddler) {
|
||||
$tw.wiki.addTiddler(new $tw.Tiddler({title: "$:/isEncrypted", text: currentPassword ? "yes" : "no"}));
|
||||
if($tw.wiki) {
|
||||
var state = currentPassword ? "yes" : "no",
|
||||
tiddler = $tw.wiki.getTiddler("$:/isEncrypted");
|
||||
if(!tiddler || tiddler.fields.text !== state) {
|
||||
$tw.wiki.addTiddler(new $tw.Tiddler({title: "$:/isEncrypted", text: state}));
|
||||
}
|
||||
}
|
||||
};
|
||||
this.hasPassword = function() {
|
||||
@@ -991,6 +996,34 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/tid","tiddlerdeserializer",{
|
||||
return [fields];
|
||||
}
|
||||
});
|
||||
$tw.modules.define("$:/boot/tiddlerdeserializer/tids","tiddlerdeserializer",{
|
||||
"application/x-tiddlers": function(text,fields) {
|
||||
var titles = [],
|
||||
tiddlers = [],
|
||||
match = /\r?\n\r?\n/mg.exec(text);
|
||||
if(match) {
|
||||
fields = $tw.utils.parseFields(text.substr(0,match.index),fields);
|
||||
var lines = text.substr(match.index + match[0].length).split(/\r?\n/mg);
|
||||
for(var t=0; t<lines.length; t++) {
|
||||
var line = lines[t];
|
||||
if(line.charAt(0) !== "#") {
|
||||
var colonPos= line.indexOf(": ");
|
||||
if(colonPos !== -1) {
|
||||
var tiddler = $tw.utils.extend({},fields);
|
||||
tiddler.title = (tiddler.title || "") + line.substr(0,colonPos);
|
||||
if(titles.indexOf(tiddler.title) !== -1) {
|
||||
console.log("Warning: .multids file contains multiple definitions for " + tiddler.title);
|
||||
}
|
||||
titles.push(tiddler.title);
|
||||
tiddler.text = line.substr(colonPos + 2);
|
||||
tiddlers.push(tiddler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tiddlers;
|
||||
}
|
||||
});
|
||||
$tw.modules.define("$:/boot/tiddlerdeserializer/txt","tiddlerdeserializer",{
|
||||
"text/plain": function(text,fields,type) {
|
||||
fields.text = text;
|
||||
@@ -1256,7 +1289,7 @@ $tw.loadPluginFolder = function(filepath,excludeRegExp) {
|
||||
}
|
||||
}
|
||||
// Give the plugin the same version number as the core if it doesn't have one
|
||||
if(!("version" in pluginInfo)) {
|
||||
if(pluginInfo && !("version" in pluginInfo)) {
|
||||
pluginInfo.version = $tw.packageInfo.version;
|
||||
}
|
||||
// Save the plugin tiddler
|
||||
@@ -1279,20 +1312,6 @@ $tw.loadPluginFolder = function(filepath,excludeRegExp) {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Fallback tiddlywiki.info content
|
||||
*/
|
||||
$tw.boot.defaultWikiInfo = {
|
||||
"plugins": [
|
||||
"tiddlywiki/tiddlyweb",
|
||||
"tiddlywiki/filesystem"
|
||||
],
|
||||
"themes": [
|
||||
"tiddlywiki/vanilla",
|
||||
"tiddlywiki/snowwhite"
|
||||
]
|
||||
};
|
||||
|
||||
/*
|
||||
path: path of wiki directory
|
||||
parentPaths: array of parent paths that we mustn't recurse into
|
||||
@@ -1306,7 +1325,7 @@ $tw.loadWikiTiddlers = function(wikiPath,parentPaths) {
|
||||
if(fs.existsSync(wikiInfoPath)) {
|
||||
wikiInfo = JSON.parse(fs.readFileSync(wikiInfoPath,"utf8"));
|
||||
} else {
|
||||
wikiInfo = $tw.boot.defaultWikiInfo;
|
||||
return null;
|
||||
}
|
||||
// Load any parent wikis
|
||||
if(wikiInfo.includeWikis) {
|
||||
@@ -1341,10 +1360,19 @@ $tw.loadWikiTiddlers = function(wikiPath,parentPaths) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Load any languages listed in the wiki info file
|
||||
if(wikiInfo.languages) {
|
||||
var languagesBasePath = path.resolve($tw.boot.corePath,$tw.config.languagesPath);
|
||||
for(var t=0; t<wikiInfo.languages.length; t++) {
|
||||
pluginFields = $tw.loadPluginFolder(path.resolve(languagesBasePath,"./" + wikiInfo.languages[t]));
|
||||
if(pluginFields) {
|
||||
$tw.wiki.addTiddler(pluginFields);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Load the wiki files, registering them as writable
|
||||
var resolvedWikiPath = path.resolve(wikiPath,$tw.config.wikiTiddlersSubDir);
|
||||
$tw.utils.each($tw.loadTiddlersFromPath(resolvedWikiPath),function(tiddlerFile) {
|
||||
$tw.wiki.addTiddlers(tiddlerFile.tiddlers);
|
||||
if(tiddlerFile.filepath) {
|
||||
$tw.utils.each(tiddlerFile.tiddlers,function(tiddler) {
|
||||
$tw.boot.files[tiddler.title] = {
|
||||
@@ -1354,7 +1382,16 @@ $tw.loadWikiTiddlers = function(wikiPath,parentPaths) {
|
||||
};
|
||||
});
|
||||
}
|
||||
$tw.wiki.addTiddlers(tiddlerFile.tiddlers);
|
||||
});
|
||||
// Save the original tiddler file locations if requested
|
||||
if(wikiInfo.config && wikiInfo.config["retain-original-tiddler-path"]) {
|
||||
var output = [];
|
||||
for(var title in $tw.boot.files) {
|
||||
output.push(title + ": " + path.relative(resolvedWikiPath,$tw.boot.files[title].filepath) + "\n");
|
||||
}
|
||||
$tw.wiki.addTiddler({title: "$:/config/OriginalTiddlerPaths", type: "application/x-tiddler-dictionary", text: output.join("")});
|
||||
}
|
||||
// Save the path to the tiddlers folder for the filesystemadaptor
|
||||
$tw.boot.wikiTiddlersPath = path.resolve($tw.boot.wikiPath,$tw.config.wikiTiddlersSubDir);
|
||||
// Load any plugins within the wiki folder
|
||||
@@ -1379,6 +1416,17 @@ $tw.loadWikiTiddlers = function(wikiPath,parentPaths) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Load any languages within the wiki folder
|
||||
var wikiLanguagesPath = path.resolve(wikiPath,$tw.config.wikiLanguagesSubDir);
|
||||
if(fs.existsSync(wikiLanguagesPath)) {
|
||||
var languageFolders = fs.readdirSync(wikiLanguagesPath);
|
||||
for(t=0; t<languageFolders.length; t++) {
|
||||
pluginFields = $tw.loadPluginFolder(path.resolve(wikiLanguagesPath,"./" + languageFolders[t]));
|
||||
if(pluginFields) {
|
||||
$tw.wiki.addTiddler(pluginFields);
|
||||
}
|
||||
}
|
||||
}
|
||||
return wikiInfo;
|
||||
};
|
||||
|
||||
@@ -1415,9 +1463,12 @@ $tw.boot.startup = function(options) {
|
||||
config: { // Configuration overridables
|
||||
pluginsPath: "../plugins/",
|
||||
themesPath: "../themes/",
|
||||
languagesPath: "../languages/",
|
||||
editionsPath: "../editions/",
|
||||
wikiInfo: "./tiddlywiki.info",
|
||||
wikiPluginsSubDir: "./plugins",
|
||||
wikiThemesSubDir: "./themes",
|
||||
wikiLanguagesSubDir: "./languages",
|
||||
wikiTiddlersSubDir: "./tiddlers",
|
||||
jsModuleHeaderRegExpString: "^\\/\\*\\\\(?:\\r?\\n)((?:^[^\\r\\n]*(?:\\r?\\n))+?)(^\\\\\\*\\/$(?:\\r?\\n)?)",
|
||||
fileExtensionInfo: {}, // Map file extension to {type:}
|
||||
@@ -1433,10 +1484,7 @@ $tw.boot.startup = function(options) {
|
||||
// If the first command line argument doesn't start with `--` then we
|
||||
// interpret it as the path to the wiki folder, which will otherwise default
|
||||
// to the current folder
|
||||
if($tw.boot.argv[0] === "*") {
|
||||
$tw.boot.wikiPath = undefined;
|
||||
$tw.boot.argv = $tw.boot.argv.slice(1);
|
||||
} else if($tw.boot.argv[0] && $tw.boot.argv[0].indexOf("--") !== 0) {
|
||||
if($tw.boot.argv[0] && $tw.boot.argv[0].indexOf("--") !== 0) {
|
||||
$tw.boot.wikiPath = $tw.boot.argv[0];
|
||||
$tw.boot.argv = $tw.boot.argv.slice(1);
|
||||
} else {
|
||||
@@ -1452,6 +1500,7 @@ $tw.boot.startup = function(options) {
|
||||
// Add file extension information
|
||||
$tw.utils.registerFileType("text/vnd.tiddlywiki","utf8",".tid");
|
||||
$tw.utils.registerFileType("application/x-tiddler","utf8",".tid");
|
||||
$tw.utils.registerFileType("application/x-tiddlers","utf8",".multids");
|
||||
$tw.utils.registerFileType("application/x-tiddler-html-div","utf8",".tiddler");
|
||||
$tw.utils.registerFileType("text/vnd.tiddlywiki2-recipe","utf8",".recipe");
|
||||
$tw.utils.registerFileType("text/plain","utf8",".txt");
|
||||
@@ -1459,12 +1508,12 @@ $tw.boot.startup = function(options) {
|
||||
$tw.utils.registerFileType("text/html","utf8",".html");
|
||||
$tw.utils.registerFileType("application/javascript","utf8",".js");
|
||||
$tw.utils.registerFileType("application/json","utf8",".json");
|
||||
$tw.utils.registerFileType("application/pdf","base64",".pdf");
|
||||
$tw.utils.registerFileType("image/jpeg","base64",".jpg");
|
||||
$tw.utils.registerFileType("image/png","base64",".png");
|
||||
$tw.utils.registerFileType("image/gif","base64",".gif");
|
||||
$tw.utils.registerFileType("image/svg+xml","utf8",".svg");
|
||||
$tw.utils.registerFileType("image/x-icon","base64",".ico");
|
||||
$tw.utils.registerFileType("application/pdf","base64",".pdf",["image"]);
|
||||
$tw.utils.registerFileType("image/jpeg","base64",".jpg",["image"]);
|
||||
$tw.utils.registerFileType("image/png","base64",".png",["image"]);
|
||||
$tw.utils.registerFileType("image/gif","base64",".gif",["image"]);
|
||||
$tw.utils.registerFileType("image/svg+xml","utf8",".svg",["image"]);
|
||||
$tw.utils.registerFileType("image/x-icon","base64",".ico",["image"]);
|
||||
$tw.utils.registerFileType("application/font-woff","base64",".woff");
|
||||
// Create the wiki store for the app
|
||||
$tw.wiki = new $tw.Wiki();
|
||||
@@ -1531,6 +1580,3 @@ if(typeof(exports) !== "undefined") {
|
||||
} else {
|
||||
_boot(window.$tw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/bag
|
||||
|
||||
The name of the bag from which a tiddler came
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/color
|
||||
|
||||
The CSS color value associated with a tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/created
|
||||
|
||||
The date a tiddler was created
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/creator
|
||||
|
||||
The name of the person who created a tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/description
|
||||
|
||||
The descriptive text for a wizard
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/draft.of
|
||||
|
||||
For draft tiddlers, contains the title of the tiddler of which this is a draft
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/draft.title
|
||||
|
||||
For draft tiddlers, contains the proposed new title of the tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/footer
|
||||
|
||||
The footer text for a wizard
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/icon
|
||||
|
||||
The title of the tiddler containing the icon associated with a tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/library
|
||||
|
||||
If set to "yes" indicates that a tiddler should be saved as a JavaScript library
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/list
|
||||
|
||||
An ordered list of tiddler titles associated with a tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/modified
|
||||
|
||||
The date and time at which a tiddler was last modified
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/modifier
|
||||
|
||||
The tiddler title associated with the person who last modified a tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/name
|
||||
|
||||
The human readable name associated with a plugin tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/plugin-priority
|
||||
|
||||
A numerical value indicating the priority of a plugin tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/plugin-type
|
||||
|
||||
The type of plugin in a plugin tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/revision
|
||||
|
||||
The revision of the tiddler held at the server
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/source
|
||||
|
||||
The source URL associated with a tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/subtitle
|
||||
|
||||
The subtitle text for a wizard
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/tags
|
||||
|
||||
A list of tags associated with a tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/text
|
||||
|
||||
The body text of a tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/title
|
||||
|
||||
The unique name of a tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/fields/type
|
||||
|
||||
The content type of a tiddler
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/moduletypes/animation
|
||||
|
||||
Animation modules contain animations that may be used with the RevealWidget.
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/types/application/json
|
||||
description: JSON data
|
||||
name: application/json
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/types/image/gif
|
||||
description: GIF image
|
||||
name: image/gif
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/docs/types/image/png
|
||||
description: PNG image
|
||||
name: image/png
|
||||
7
core/language/en-GB.tid
Normal file
7
core/language/en-GB.tid
Normal file
@@ -0,0 +1,7 @@
|
||||
title: $:/languages/en-GB
|
||||
name: en-GB
|
||||
description: English (British)
|
||||
author: JeremyRuston
|
||||
core-version: >=5.0.0"
|
||||
|
||||
Stub pseudo-plugin for the default language
|
||||
72
core/language/en-GB/ControlPanel.multids
Normal file
72
core/language/en-GB/ControlPanel.multids
Normal file
@@ -0,0 +1,72 @@
|
||||
title: $:/language/ControlPanel/
|
||||
|
||||
Advanced/Caption: Advanced
|
||||
Advanced/Hint: Internal information about this TiddlyWiki
|
||||
Advanced/LoadedModules/Caption: Loaded Modules
|
||||
Advanced/LoadedModules/Hint: These are the currently loaded tiddler modules linked to their source tiddlers. Any italicised modules lack a source tiddler, typically because they were setup during the boot process.
|
||||
Advanced/TiddlerFields/Caption: Tiddler Fields
|
||||
Advanced/TiddlerFields/Hint: This is the full set of TiddlerFields in use in this wiki (including system tiddlers but excluding shadow tiddlers).
|
||||
Appearance/Caption: Appearance
|
||||
Appearance/Hint: Ways to customise the appearance of your TiddlyWiki.
|
||||
Appearance/Palette/Caption: Palette
|
||||
Appearance/Palette/Editor/Clone/Caption: clone
|
||||
Appearance/Palette/Editor/Clone/Prompt: It is recommended that you clone this shadow palette before editing it
|
||||
Appearance/Palette/Editor/Prompt/Modified: This shadow palette has been modified
|
||||
Appearance/Palette/Editor/Prompt: Editing
|
||||
Appearance/Palette/Editor/Reset/Caption: reset
|
||||
Appearance/Palette/ShowEditor/Caption: show editor
|
||||
Appearance/Palette/HideEditor/Caption: hide editor
|
||||
Appearance/Palette/Prompt: Current palette:
|
||||
Appearance/StoryView/Caption: Story View
|
||||
Appearance/StoryView/Prompt: Current view:
|
||||
Appearance/Theme/Caption: Theme
|
||||
Appearance/Theme/Prompt: Current theme:
|
||||
Basics/AnimDuration/Prompt: Animation duration:
|
||||
Basics/Caption: Basics
|
||||
Basics/DefaultTiddlers/BottomHint: Use [[double square brackets]] for titles with spaces. Or you can choose to <$button set="$:/DefaultTiddlers" setTo="[list[$:/StoryList]]">retain story ordering</$button>
|
||||
Basics/DefaultTiddlers/Prompt: Default tiddlers:
|
||||
Basics/DefaultTiddlers/TopHint: Choose which tiddlers are displayed at startup:
|
||||
Basics/Language/Prompt: Hello! Current language:
|
||||
Basics/OverriddenShadowTiddlers/Prompt: Number of overridden shadow tiddlers:
|
||||
Basics/ShadowTiddlers/Prompt: Number of shadow tiddlers:
|
||||
Basics/Subtitle/Prompt: Subtitle:
|
||||
Basics/SystemTiddlers/Prompt: Number of system tiddlers:
|
||||
Basics/Tags/Prompt: Number of tags:
|
||||
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:
|
||||
Plugins/Caption: Plugins
|
||||
Plugins/Fields/Description: Description
|
||||
Plugins/Fields/Title: Title
|
||||
Plugins/Fields/Version: Version
|
||||
Saving/AutoSave/Disabled/Button: enable
|
||||
Saving/AutoSave/Disabled/Prompt: Autosave is currently disabled
|
||||
Saving/AutoSave/Enabled/Button: disable
|
||||
Saving/AutoSave/Enabled/Prompt: Autosave is currently enabled
|
||||
Saving/AutoSave: Autosave
|
||||
Saving/Caption: Saving
|
||||
Saving/Heading: Saving
|
||||
Saving/TiddlySpot/Advanced/Heading: Advanced Settings
|
||||
Saving/TiddlySpot/BackupDir: Backup Directory
|
||||
Saving/TiddlySpot/Backups: Backups
|
||||
Saving/TiddlySpot/Filename: Upload Filename
|
||||
Saving/TiddlySpot/Heading: ~TiddlySpot
|
||||
Saving/TiddlySpot/Hint: //The server URL defaults to `http://<wikiname>.tiddlyspot.com/store.cgi` and can be changed to use a custom server address//
|
||||
Saving/TiddlySpot/Password: Password
|
||||
Saving/TiddlySpot/ServerURL: Server URL
|
||||
Saving/TiddlySpot/UploadDir: Upload Directory
|
||||
Saving/TiddlySpot/UserName: Wiki Name
|
||||
Tools/Caption: Tools
|
||||
Tools/Download/Full/Caption: Download full wiki
|
||||
Tools/Encryption/ChangePassword/Button: change password
|
||||
Tools/Encryption/ClearPassword/Button: clear password
|
||||
Tools/Encryption/Disabled/Prompt: This wiki is not encrypted
|
||||
Tools/Encryption/Enabled/Prompt: This wiki is encrypted
|
||||
Tools/Encryption/Heading: Encryption
|
||||
Tools/Encryption/SetPassword/Button: set password
|
||||
Tools/Export/AllAsStaticHTML/Caption: Download all tiddlers as static HTML
|
||||
Tools/Export/Heading: Export
|
||||
Tools/Import/Heading: Import
|
||||
Tools/Import/Hint: Browse for files on your computer to import their contents (the individual tiddlers within TiddlyWiki HTML files are imported separately). You can also drag and drop files directly to the browser window.
|
||||
Tools/Import/Prompt: Import:
|
||||
22
core/language/en-GB/Docs/ModuleTypes.multids
Normal file
22
core/language/en-GB/Docs/ModuleTypes.multids
Normal file
@@ -0,0 +1,22 @@
|
||||
title: $:/language/Docs/ModuleTypes/
|
||||
|
||||
animation: Animations that may be used with the RevealWidget.
|
||||
browser-startup: Startup functions that are only executed in the browser.
|
||||
command: Commands that can be executed under Node.js.
|
||||
config: Data to be inserted into `$tw.config`.
|
||||
filteroperator: Individual filter operator methods.
|
||||
global: Global data to be inserted into `$tw`.
|
||||
isfilteroperator: Operands for the ''is'' filter operator.
|
||||
macro: JavaScript macro definitions.
|
||||
parser: Parsers for different content types.
|
||||
saver: Savers handle different methods for saving files from the browser.
|
||||
startup: Startup functions.
|
||||
storyview: Story views customise the animation and behaviour of list widgets.
|
||||
tiddlerdeserializer: Converts different content types into tiddlers.
|
||||
tiddlerfield: Defines the behaviour of an individual tiddler field.
|
||||
tiddlermethod: Adds methods to the `$tw.Tiddler` prototype.
|
||||
utils: Adds methods to `$tw.utils`.
|
||||
utils-node: Adds Node.js-specific methods to `$tw.utils`.
|
||||
widget: Widgets encapsulate DOM rendering and refreshing.
|
||||
wikimethod: Adds methods to `$tw.Wiki`.
|
||||
wikirule: Individual parser rules for the main WikiText parser.
|
||||
14
core/language/en-GB/EditTemplate.multids
Normal file
14
core/language/en-GB/EditTemplate.multids
Normal file
@@ -0,0 +1,14 @@
|
||||
title: $:/language/EditTemplate/
|
||||
|
||||
Body/Hint: Use WikiText to add formatting, images, and dynamic features
|
||||
Body/Placeholder: Type the text for this tiddler
|
||||
Body/Preview/Button/Hide: hide preview
|
||||
Body/Preview/Button/Show: show preview
|
||||
Fields/Add/Button: add
|
||||
Fields/Add/Name/Placeholder: field name
|
||||
Fields/Add/Prompt: Add a new field:
|
||||
Fields/Add/Value/Placeholder: field value
|
||||
Tags/Add/Button: add
|
||||
Tags/Add/Placeholder: tag name
|
||||
Type/Placeholder: content type
|
||||
Type/Prompt: Type:
|
||||
32
core/language/en-GB/Fields.multids
Normal file
32
core/language/en-GB/Fields.multids
Normal file
@@ -0,0 +1,32 @@
|
||||
title: $:/language/Docs/Fields/
|
||||
|
||||
bag: The name of the bag from which a tiddler came
|
||||
caption: The text to be displayed on a tab or button
|
||||
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]]
|
||||
created: The date a tiddler was created
|
||||
creator: The name of the person who created a tiddler
|
||||
dependents: For a plugin, lists the dependent plugin titles
|
||||
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
|
||||
hack-to-give-us-something-to-compare-against: A temporary storage field used in [[$:/core/templates/static.content]]
|
||||
icon: The title of the tiddler containing the icon associated with a tiddler
|
||||
library: If set to "yes" indicates that a tiddler should be saved as a JavaScript library
|
||||
list: An ordered list of tiddler titles associated with a tiddler
|
||||
modified: The date and time at which a tiddler was last modified
|
||||
modifier: The tiddler title associated with the person who last modified a tiddler
|
||||
name: The human readable name associated with a plugin tiddler
|
||||
plugin-priority: A numerical value indicating the priority of a plugin tiddler
|
||||
plugin-type: The type of plugin in a plugin tiddler
|
||||
revision: The revision of the tiddler held at the server
|
||||
released: Date of a TiddlyWiki release
|
||||
source: The source URL associated with a tiddler
|
||||
subtitle: The subtitle text for a wizard
|
||||
tags: A list of tags associated with a tiddler
|
||||
text: The body text of a tiddler
|
||||
title: The unique name of a tiddler
|
||||
type: The content type of a tiddler
|
||||
version: Version information for a plugin
|
||||
22
core/language/en-GB/Help/default.tid
Normal file
22
core/language/en-GB/Help/default.tid
Normal file
@@ -0,0 +1,22 @@
|
||||
title: $:/language/Help/default
|
||||
|
||||
\define commandTitle()
|
||||
$:/language/Help/$(command)$
|
||||
\end
|
||||
```
|
||||
usage: tiddlywiki [<wikifolder>] [--<command> [<args>...]...]
|
||||
```
|
||||
|
||||
Available commands:
|
||||
|
||||
<ul>
|
||||
<$list filter="[commands[]sort[title]]" variable="command">
|
||||
<li><$link to=<<commandTitle>>><$macrocall $name="command" $type="text/plain" $output="text/plain"/></$link>: <$transclude tiddler=<<commandTitle>> field="description"/></li>
|
||||
</$list>
|
||||
</ul>
|
||||
|
||||
To get detailed help on a command:
|
||||
|
||||
```
|
||||
tiddlywiki --help <command>
|
||||
```
|
||||
10
core/language/en-GB/Help/help.tid
Normal file
10
core/language/en-GB/Help/help.tid
Normal file
@@ -0,0 +1,10 @@
|
||||
title: $:/language/Help/help
|
||||
description: Display help for TiddlyWiki commands
|
||||
|
||||
Displays help text for a command:
|
||||
|
||||
```
|
||||
--help [<command>]
|
||||
```
|
||||
|
||||
If the command name is omitted then a list of available commands is displayed.
|
||||
23
core/language/en-GB/Help/init.tid
Normal file
23
core/language/en-GB/Help/init.tid
Normal file
@@ -0,0 +1,23 @@
|
||||
title: $:/language/Help/init
|
||||
description: Initialise a new wiki folder
|
||||
|
||||
Initialise an empty [[WikiFolder|WikiFolders]] with a copy of the specified edition.
|
||||
|
||||
```
|
||||
--init <edition> [<edition> ...]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
tiddlywiki ./MyWikiFolder --init empty
|
||||
```
|
||||
|
||||
Note:
|
||||
|
||||
* The wiki folder directory will be created if necessary
|
||||
* The "edition" defaults to ''empty''
|
||||
* The init command will fail if the wiki folder is not empty
|
||||
* The init command removes any `includeWikis` definitions in the edition's `tiddlywiki.info` file
|
||||
* When multiple editions are specified, editions initialised later will overwrite any files shared with earlier editions (so, the final `tiddlywiki.info` file will be copied from the last edition)
|
||||
* `--help editions` returns a list of available editions
|
||||
14
core/language/en-GB/Help/load.tid
Normal file
14
core/language/en-GB/Help/load.tid
Normal file
@@ -0,0 +1,14 @@
|
||||
title: $:/language/Help/load
|
||||
description: Load tiddlers from a file
|
||||
|
||||
Load tiddlers from 2.x.x TiddlyWiki files (`.html`), `.tiddler`, `.tid`, `.json` or other files
|
||||
|
||||
```
|
||||
--load <filepath>
|
||||
```
|
||||
|
||||
To load tiddlers from an encrypted TiddlyWiki file you should first specify the password with the PasswordCommand. For example:
|
||||
|
||||
```
|
||||
tiddlywiki ./MyWiki --password pa55w0rd --load my_encrypted_wiki.html
|
||||
```
|
||||
3
core/language/en-GB/Help/notfound.tid
Normal file
3
core/language/en-GB/Help/notfound.tid
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/language/Help/notfound
|
||||
|
||||
No such help item
|
||||
9
core/language/en-GB/Help/password.tid
Normal file
9
core/language/en-GB/Help/password.tid
Normal file
@@ -0,0 +1,9 @@
|
||||
title: $:/language/Help/password
|
||||
description: Set a password for subsequent crypto operations
|
||||
|
||||
Set a password for subsequent crypto operations
|
||||
|
||||
```
|
||||
--password <password>
|
||||
```
|
||||
|
||||
8
core/language/en-GB/Help/rendertiddler.tid
Normal file
8
core/language/en-GB/Help/rendertiddler.tid
Normal file
@@ -0,0 +1,8 @@
|
||||
title: $:/language/Help/rendertiddler
|
||||
description: Render an individual tiddler as a specified ContentType
|
||||
|
||||
Render an individual tiddler as a specified ContentType, defaults to `text/html` and save it to the specified filename:
|
||||
|
||||
```
|
||||
--rendertiddler <title> <filename> [<type>]
|
||||
```
|
||||
14
core/language/en-GB/Help/rendertiddlers.tid
Normal file
14
core/language/en-GB/Help/rendertiddlers.tid
Normal file
@@ -0,0 +1,14 @@
|
||||
title: $:/language/Help/rendertiddlers
|
||||
description: Render tiddlers matching a filter to a specified ContentType
|
||||
|
||||
Render a set of tiddlers matching a filter to separate files of a specified ContentType (defaults to `text/html`) and extension (defaults to `.html`).
|
||||
|
||||
```
|
||||
--rendertiddlers <filter> <template> <pathname> [<type>] [<extension>]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
--rendertiddlers [!is[system]] $:/core/templates/static.tiddler.html ./static text/plain
|
||||
```
|
||||
8
core/language/en-GB/Help/savetiddler.tid
Normal file
8
core/language/en-GB/Help/savetiddler.tid
Normal file
@@ -0,0 +1,8 @@
|
||||
title: $:/language/Help/savetiddler
|
||||
description: Saves a raw tiddler to a file
|
||||
|
||||
Saves an individual tiddler in its raw text or binary format to the specified filename.
|
||||
|
||||
```
|
||||
--savetiddler <title> <filename>
|
||||
```
|
||||
30
core/language/en-GB/Help/server.tid
Normal file
30
core/language/en-GB/Help/server.tid
Normal file
@@ -0,0 +1,30 @@
|
||||
title: $:/language/Help/server
|
||||
description: Provides an HTTP server interface to TiddlyWiki
|
||||
|
||||
The server built in to TiddlyWiki5 is very simple. Although compatible with TiddlyWeb it doesn't support many of the features needed for robust Internet-facing usage.
|
||||
|
||||
At the root, it serves a rendering of a specified tiddler. Away from the root, it serves individual tiddlers encoded in JSON, and supports the basic HTTP operations for `GET`, `PUT` and `DELETE`.
|
||||
|
||||
```
|
||||
--server <port> <roottiddler> <rendertype> <servetype> <username> <password> <host>
|
||||
```
|
||||
|
||||
The parameters are:
|
||||
|
||||
* ''port'' - port number to serve from (defaults to "8080")
|
||||
* ''roottiddler'' - the tiddler to serve at the root (defaults to "$:/core/save/all")
|
||||
* ''rendertype'' - the content type to which the root tiddler should be rendered (defaults to "text/plain")
|
||||
* ''servetype'' - the content type with which the root tiddler should be served (defaults to "text/html")
|
||||
* ''username'' - the default username for signing edits
|
||||
* ''password'' - optional password for basic authentication
|
||||
* ''host'' - optional hostname to serve from (defaults to "127.0.0.1" aka "localhost")
|
||||
|
||||
If the password parameter is specified then the browser will prompt the user for the username and password. Note that the password is transmitted in plain text so this implementation isn't suitable for general use.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
--server 8080 $:/core/save/all text/plain text/html MyUserName passw0rd
|
||||
```
|
||||
|
||||
To run multiple TiddlyWiki servers at the same time you'll need to put each one on a different port.
|
||||
8
core/language/en-GB/Help/verbose.tid
Normal file
8
core/language/en-GB/Help/verbose.tid
Normal file
@@ -0,0 +1,8 @@
|
||||
title: $:/language/Help/verbose
|
||||
description: Triggers verbose output mode
|
||||
|
||||
Triggers verbose output, useful for debugging
|
||||
|
||||
```
|
||||
--verbose
|
||||
```
|
||||
8
core/language/en-GB/Help/version.tid
Normal file
8
core/language/en-GB/Help/version.tid
Normal file
@@ -0,0 +1,8 @@
|
||||
title: $:/language/Help/version
|
||||
description: Displays the version number of TiddlyWiki
|
||||
|
||||
Displays the version number of TiddlyWiki.
|
||||
|
||||
```
|
||||
--version
|
||||
```
|
||||
4
core/language/en-GB/Misc.multids
Normal file
4
core/language/en-GB/Misc.multids
Normal file
@@ -0,0 +1,4 @@
|
||||
title: $:/language/
|
||||
|
||||
RecentChanges/DateFormat: DDth MMM YYYY
|
||||
CloseAll/Button: close all
|
||||
@@ -1,8 +1,8 @@
|
||||
title: $:/messages/Download
|
||||
title: $:/language/Modals/Download
|
||||
type: text/vnd.tiddlywiki
|
||||
subtitle: Download changes
|
||||
footer: <$button message="tw-close-tiddler" class="btn btn-primary">Close</$button>
|
||||
help: http://five.tiddlywiki.com/static/DownloadingChanges.html
|
||||
help: http://tiddlywiki.com/static/DownloadingChanges.html
|
||||
|
||||
Your browser only supports manual saving.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
title: $:/messages/SaveInstructions
|
||||
title: $:/language/Modals/SaveInstructions
|
||||
type: text/vnd.tiddlywiki
|
||||
subtitle: Save your work
|
||||
footer: <$button message="tw-close-tiddler" class="btn btn-primary">Close</$button>
|
||||
help: http://five.tiddlywiki.com/static/SavingChanges
|
||||
help: http://tiddlywiki.com/static/SavingChanges.html
|
||||
|
||||
Your changes to this wiki need to be saved as a ~TiddlyWiki HTML file.
|
||||
|
||||
4
core/language/en-GB/Notifications.multids
Normal file
4
core/language/en-GB/Notifications.multids
Normal file
@@ -0,0 +1,4 @@
|
||||
title: $:/language/Notifications/
|
||||
|
||||
Save/Done: Saved wiki
|
||||
Save/Starting: Starting to save wiki
|
||||
10
core/language/en-GB/Search.multids
Normal file
10
core/language/en-GB/Search.multids
Normal file
@@ -0,0 +1,10 @@
|
||||
title: $:/language/Search/
|
||||
|
||||
Advanced/Matches: //<small><$count filter={{$:/temp/advancedsearch}}/> matches</small>//
|
||||
Filter/Caption: Filter
|
||||
Filter/Hint: Search via a [[filter expression|http://tiddlywiki.com/static/TiddlerFilters.html]]
|
||||
Matches: //<small><$count filter="[!is[system]search{$:/temp/search}]"/> matches</small>//
|
||||
Shadows/Caption: Shadows
|
||||
Shadows/Hint: Search for shadow tiddlers
|
||||
System/Caption: System
|
||||
System/Hint: Search for system tiddlers
|
||||
17
core/language/en-GB/SideBar.multids
Normal file
17
core/language/en-GB/SideBar.multids
Normal file
@@ -0,0 +1,17 @@
|
||||
title: $:/language/SideBar/
|
||||
|
||||
All/Caption: All
|
||||
Drafts/Caption: Drafts
|
||||
Missing/Caption: Missing
|
||||
More/Caption: More
|
||||
Open/Caption: Open
|
||||
Orphans/Caption: Orphans
|
||||
Recent/Caption: Recent
|
||||
Shadows/Caption: Shadows
|
||||
System/Caption: System
|
||||
Tags/Caption: Tags
|
||||
Tags/TagManager/Caption: Tag Manager
|
||||
Tags/Untagged/Caption: untagged
|
||||
Tools/Caption: Tools
|
||||
Types/Caption: Types
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
title: SiteSubtitle
|
||||
title: $:/SiteSubtitle
|
||||
|
||||
a non-linear personal web notebook
|
||||
3
core/language/en-GB/SiteTitle.tid
Normal file
3
core/language/en-GB/SiteTitle.tid
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/SiteTitle
|
||||
|
||||
My ~TiddlyWiki
|
||||
11
core/language/en-GB/TiddlerInfo.multids
Normal file
11
core/language/en-GB/TiddlerInfo.multids
Normal file
@@ -0,0 +1,11 @@
|
||||
title: $:/language/TiddlerInfo/
|
||||
|
||||
Fields/Caption: Fields
|
||||
List/Caption: List
|
||||
List/Empty: This tiddler does not have a list
|
||||
Listed/Caption: Listed
|
||||
Listed/Empty: This tiddler is not listed by any others
|
||||
References/Caption: References
|
||||
References/Empty: No tiddlers link to this one
|
||||
Tagging/Caption: Tagging
|
||||
Tagging/Empty: No tiddlers are tagged with this one
|
||||
3
core/language/en-GB/Types/application_json.tid
Normal file
3
core/language/en-GB/Types/application_json.tid
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/language/Docs/Types/application/json
|
||||
description: JSON data
|
||||
name: application/json
|
||||
@@ -1,3 +1,3 @@
|
||||
title: $:/docs/types/application/x-tiddler-dictionary
|
||||
title: $:/language/Docs/Types/application/x-tiddler-dictionary
|
||||
description: Data dictionary
|
||||
name: application/x-tiddler-dictionary
|
||||
3
core/language/en-GB/Types/image_gif.tid
Normal file
3
core/language/en-GB/Types/image_gif.tid
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/language/Docs/Types/image/gif
|
||||
description: GIF image
|
||||
name: image/gif
|
||||
@@ -1,3 +1,3 @@
|
||||
title: $:/docs/types/image/jpeg
|
||||
title: $:/language/Docs/Types/image/jpeg
|
||||
description: JPEG image
|
||||
name: image/jpeg
|
||||
3
core/language/en-GB/Types/image_png.tid
Normal file
3
core/language/en-GB/Types/image_png.tid
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/language/Docs/Types/image/png
|
||||
description: PNG image
|
||||
name: image/png
|
||||
@@ -1,3 +1,3 @@
|
||||
title: $:/docs/types/image/svg+xml
|
||||
title: $:/language/Docs/Types/image/svg+xml
|
||||
description: Structured Vector Graphics image
|
||||
name: image/svg+xml
|
||||
@@ -1,3 +1,3 @@
|
||||
title: $:/docs/types/image/x-icon
|
||||
title: $:/language/Docs/Types/image/x-icon
|
||||
description: ICO format icon file
|
||||
name: image/x-icon
|
||||
3
core/language/en-GB/Types/text_css.tid
Normal file
3
core/language/en-GB/Types/text_css.tid
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/language/Docs/Types/text/css
|
||||
description: Static stylesheet
|
||||
name: text/css
|
||||
@@ -1,3 +1,3 @@
|
||||
title: $:/docs/types/text/plain
|
||||
title: $:/language/Docs/Types/text/plain
|
||||
description: Plain text
|
||||
name: text/plain
|
||||
@@ -1,3 +1,3 @@
|
||||
title: $:/docs/types/text/vnd.tiddlywiki
|
||||
title: $:/language/Docs/Types/text/vnd.tiddlywiki
|
||||
description: TiddlyWiki version 5 wikitext
|
||||
name: text/vnd.tiddlywiki
|
||||
@@ -1,3 +1,3 @@
|
||||
title: $:/docs/types/text/x-tiddlywiki
|
||||
title: $:/language/Docs/Types/text/x-tiddlywiki
|
||||
description: TiddlyWiki Classic wikitext
|
||||
name: text/x-tiddlywiki
|
||||
@@ -1,16 +0,0 @@
|
||||
title: $:/messages/EnterEditMode
|
||||
type: text/vnd.tiddlywiki
|
||||
subtitle: Editing this wiki
|
||||
footer: <<button close class:"btn btn-primary"><Close>>
|
||||
help: http://five.tiddlywiki.com/static/EditMode
|
||||
|
||||
You can edit this wiki and save your changes. You are strongly advised to verify that saving is working properly before trusting ~TiddlyWiki with your data.
|
||||
|
||||
The following methods of saving changes are available:
|
||||
|
||||
* Using Firefox's built-in file system access
|
||||
* Uploading to a simple server script
|
||||
* Using HTML5's data URI and download attribute
|
||||
|
||||
|
||||
[x] Don't show this message again
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/messages/Saved
|
||||
|
||||
Saved wiki
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/messages/StartingSave
|
||||
|
||||
Starting to save wiki
|
||||
41
core/modules/commands/help.js
Normal file
41
core/modules/commands/help.js
Normal file
@@ -0,0 +1,41 @@
|
||||
/*\
|
||||
title: $:/core/modules/commands/help.js
|
||||
type: application/javascript
|
||||
module-type: command
|
||||
|
||||
Help command
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jshint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.info = {
|
||||
name: "help",
|
||||
synchronous: true
|
||||
};
|
||||
|
||||
var Command = function(params,commander) {
|
||||
this.params = params;
|
||||
this.commander = commander;
|
||||
};
|
||||
|
||||
Command.prototype.execute = function() {
|
||||
var subhelp = this.params[0] || "default",
|
||||
helpBase = "$:/language/Help/",
|
||||
text;
|
||||
if(!this.commander.wiki.getTiddler(helpBase + subhelp)) {
|
||||
subhelp = "notfound";
|
||||
}
|
||||
// Wikify the help as formatted text (ie block elements generate newlines)
|
||||
text = this.commander.wiki.renderTiddler("text/plain-formatted",helpBase + subhelp);
|
||||
// Remove any leading linebreaks
|
||||
text = text.replace(/^(\r?\n)*/g,"");
|
||||
this.commander.streams.output.write(text);
|
||||
};
|
||||
|
||||
exports.Command = Command;
|
||||
|
||||
})();
|
||||
59
core/modules/commands/init.js
Normal file
59
core/modules/commands/init.js
Normal file
@@ -0,0 +1,59 @@
|
||||
/*\
|
||||
title: $:/core/modules/commands/init.js
|
||||
type: application/javascript
|
||||
module-type: command
|
||||
|
||||
Command to initialise an empty wiki folder
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.info = {
|
||||
name: "init",
|
||||
synchronous: true
|
||||
};
|
||||
|
||||
var Command = function(params,commander) {
|
||||
this.params = params;
|
||||
this.commander = commander;
|
||||
};
|
||||
|
||||
Command.prototype.execute = function() {
|
||||
var fs = require("fs"),
|
||||
path = require("path");
|
||||
// Check that we don't already have a valid wiki folder
|
||||
if($tw.boot.wikiTiddlersPath) {
|
||||
return "Wiki folder is not empty";
|
||||
}
|
||||
// Loop through each of the specified editions
|
||||
var editions = this.params.length > 0 ? this.params : ["empty"];
|
||||
for(var editionIndex=0; editionIndex<editions.length; editionIndex++) {
|
||||
var editionName = editions[editionIndex];
|
||||
// Check the edition exists
|
||||
var editionPath = path.resolve($tw.boot.corePath,$tw.config.editionsPath) + "/" + editionName;
|
||||
if(!$tw.utils.isDirectory(editionPath)) {
|
||||
return "Edition '" + editionName + "' not found";
|
||||
}
|
||||
// Copy the edition content
|
||||
var err = $tw.utils.copyDirectory(editionPath,$tw.boot.wikiPath);
|
||||
if(!err) {
|
||||
this.commander.streams.output.write("Copied edition '" + editionName + "' to " + $tw.boot.wikiPath + "\n");
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
// Tweak the tiddlywiki.info to remove any included wikis
|
||||
var packagePath = $tw.boot.wikiPath + "/tiddlywiki.info",
|
||||
packageJson = JSON.parse(fs.readFileSync(packagePath));
|
||||
delete packageJson.includeWikis;
|
||||
fs.writeFileSync(packagePath,JSON.stringify(packageJson,null,$tw.config.preferences.jsonSpaces));
|
||||
return null;
|
||||
};
|
||||
|
||||
exports.Command = Command;
|
||||
|
||||
})();
|
||||
@@ -1,114 +0,0 @@
|
||||
/*\
|
||||
title: $:/core/modules/commands/print.js
|
||||
type: application/javascript
|
||||
module-type: command
|
||||
|
||||
Print command for inspecting TiddlyWiki internals
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jshint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.info = {
|
||||
name: "print",
|
||||
synchronous: true
|
||||
};
|
||||
|
||||
var Command = function(params,commander) {
|
||||
this.params = params;
|
||||
this.commander = commander;
|
||||
this.output = commander.streams.output;
|
||||
};
|
||||
|
||||
Command.prototype.execute = function() {
|
||||
if(this.params.length < 1) {
|
||||
return "Too few parameters for print command";
|
||||
}
|
||||
var subcommand = this.subcommands[this.params[0]];
|
||||
if(subcommand) {
|
||||
return subcommand.call(this);
|
||||
} else {
|
||||
return "Unknown subcommand (" + this.params[0] + ") for print command";
|
||||
}
|
||||
};
|
||||
|
||||
Command.prototype.subcommands = {};
|
||||
|
||||
Command.prototype.subcommands.tiddler = function() {
|
||||
if(this.params.length < 2) {
|
||||
return "Too few parameters for print tiddler command";
|
||||
}
|
||||
var tiddler = this.commander.wiki.getTiddler(this.params[1]);
|
||||
if(!tiddler) {
|
||||
return "No such tiddler as '" + this.params[1] + "'";
|
||||
}
|
||||
this.output.write("Tiddler '" + this.params[1] + "' contains these fields:\n");
|
||||
for(var t in tiddler.fields) {
|
||||
this.output.write(" " + t + ": " + tiddler.getFieldString(t) + "\n");
|
||||
}
|
||||
return null; // No error
|
||||
};
|
||||
|
||||
Command.prototype.subcommands.tiddlers = function() {
|
||||
var tiddlers = this.commander.wiki.getTiddlers();
|
||||
this.output.write("Wiki contains these tiddlers:\n");
|
||||
for(var t=0; t<tiddlers.length; t++) {
|
||||
this.output.write(tiddlers[t] + "\n");
|
||||
}
|
||||
return null; // No error
|
||||
};
|
||||
|
||||
Command.prototype.subcommands.system = function() {
|
||||
var tiddlers = this.commander.wiki.getSystemTitles();
|
||||
this.output.write("Wiki contains these system tiddlers:\n");
|
||||
for(var t=0; t<tiddlers.length; t++) {
|
||||
this.output.write(tiddlers[t] + "\n");
|
||||
}
|
||||
return null; // No error
|
||||
};
|
||||
|
||||
Command.prototype.subcommands.config = function() {
|
||||
var self = this;
|
||||
var quotePropertyName = function(p) {
|
||||
var unquotedPattern = /^[A-Za-z0-9_]*$/mg;
|
||||
if(unquotedPattern.test(p)) {
|
||||
return p;
|
||||
} else {
|
||||
return "[\"" + $tw.utils.stringify(p) + "\"]";
|
||||
}
|
||||
},
|
||||
printConfig = function(object,prefix) {
|
||||
for(var n in object) {
|
||||
var v = object[n];
|
||||
if(typeof v === "object") {
|
||||
printConfig(v,prefix + "." + quotePropertyName(n));
|
||||
} else if(typeof v === "string") {
|
||||
self.output.write(prefix + "." + quotePropertyName(n) + ": \"" + $tw.utils.stringify(v) + "\"\n");
|
||||
} else {
|
||||
self.output.write(prefix + "." + quotePropertyName(n) + ": " + v.toString() + "\n");
|
||||
}
|
||||
}
|
||||
},
|
||||
printObject = function(heading,object) {
|
||||
self.output.write(heading +"\n");
|
||||
for(var n in object) {
|
||||
self.output.write(" " + n + "\n");
|
||||
}
|
||||
};
|
||||
this.output.write("Configuration:\n");
|
||||
printConfig($tw.config," $tw.config");
|
||||
printObject("Tiddler field modules:",$tw.Tiddler.fieldModules);
|
||||
printObject("Loaded modules:",$tw.modules.titles);
|
||||
printObject("Command modules:",$tw.commands);
|
||||
printObject("Parser modules:",$tw.wiki.parsers);
|
||||
printObject("Macro modules:",$tw.wiki.macros);
|
||||
printObject("Deserializer modules:",$tw.Wiki.tiddlerDeserializerModules);
|
||||
return null; // No error
|
||||
};
|
||||
|
||||
exports.Command = Command;
|
||||
|
||||
})();
|
||||
@@ -108,6 +108,9 @@ SimpleServer.prototype.listen = function(port,host) {
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
// Set the encoding for the incoming request
|
||||
// TODO: Presumably this would need tweaking if we supported PUTting binary tiddlers
|
||||
request.setEncoding("utf8");
|
||||
// Dispatch the appropriate method
|
||||
switch(request.method) {
|
||||
case "GET": // Intentional fall-through
|
||||
@@ -157,7 +160,7 @@ var Command = function(params,commander,callback) {
|
||||
state.wiki.addTiddler(new $tw.Tiddler(state.wiki.getCreationFields(),fields,{title: title}));
|
||||
var changeCount = state.wiki.getChangeCount(title).toString();
|
||||
response.writeHead(204, "OK",{
|
||||
Etag: "\"default/" + title + "/" + changeCount + ":\""
|
||||
Etag: "\"default/" + encodeURIComponent(title) + "/" + changeCount + ":\""
|
||||
});
|
||||
response.end();
|
||||
}
|
||||
|
||||
@@ -35,5 +35,6 @@ exports.htmlEntities = {quot:34, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:
|
||||
|
||||
exports.htmlVoidElements = "area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",");
|
||||
|
||||
exports.htmlBlockElements = "address,article,aside,audio,blockquote,canvas,dd,div,dl,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,li,noscript,ol,output,p,pre,section,table,tfoot,ul,video".split(",");
|
||||
|
||||
})();
|
||||
|
||||
@@ -62,7 +62,7 @@ function parseFilterOperation(operators,filterString,p) {
|
||||
nextBracketPos = filterString.indexOf(']',p);
|
||||
break;
|
||||
case '/': // regexp brackets
|
||||
var rex = /^((?:[^\\\/]*|\\.))*\/(?:\(([mygi]+)\))?/g,
|
||||
var rex = /^((?:[^\\\/]*|\\.)*)\/(?:\(([mygi]+)\))?/g,
|
||||
rexMatch = rex.exec(filterString.substring(p));
|
||||
if(rexMatch) {
|
||||
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
|
||||
@@ -219,6 +219,7 @@ exports.compileFilter = function(filterString) {
|
||||
});
|
||||
// Return a function that applies the operations to a source array/hashmap of tiddler titles
|
||||
return function(source,currTiddlerTitle) {
|
||||
source = source || self.tiddlers;
|
||||
var results = [];
|
||||
$tw.utils.each(operationFunctions,function(operationFunction) {
|
||||
operationFunction(results,source,currTiddlerTitle);
|
||||
|
||||
27
core/modules/filters/commands.js
Normal file
27
core/modules/filters/commands.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/commands.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operator for returning the names of the commands available in this wiki
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.commands = function(source,operator,options) {
|
||||
var results = [];
|
||||
$tw.utils.each($tw.commands,function(commandInfo,name) {
|
||||
results.push(name);
|
||||
});
|
||||
results.sort();
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -17,13 +17,14 @@ Export our filter function
|
||||
*/
|
||||
exports.field = function(source,operator,options) {
|
||||
var results = [],
|
||||
fieldname = (operator.suffix || operator.operator).toLowerCase();
|
||||
fieldname = (operator.suffix || operator.operator).toLowerCase(),
|
||||
isTitle = fieldname === "title";
|
||||
// Function to check an individual title
|
||||
function checkTiddler(title) {
|
||||
var tiddler = options.wiki.getTiddler(title);
|
||||
if(tiddler) {
|
||||
var match,
|
||||
text = tiddler.getFieldString(fieldname);
|
||||
var tiddler = options.wiki.getTiddler(title),
|
||||
text = tiddler ? tiddler.getFieldString(fieldname) : (isTitle ? title : null),
|
||||
match;
|
||||
if(text !== null) {
|
||||
if(operator.regexp) {
|
||||
match = !!operator.regexp.exec(text);
|
||||
} else {
|
||||
|
||||
43
core/modules/filters/indexes.js
Normal file
43
core/modules/filters/indexes.js
Normal file
@@ -0,0 +1,43 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/indexes.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operator for returning the indexes of a data tiddler
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.indexes = function(source,operator,options) {
|
||||
var self = this,
|
||||
results = [];
|
||||
// Function to check an individual title
|
||||
function checkTiddler(title) {
|
||||
// Return the fields on the specified tiddler
|
||||
var data = options.wiki.getTiddlerData(title,{});
|
||||
if(data) {
|
||||
$tw.utils.pushTop(results,Object.keys(data));
|
||||
}
|
||||
}
|
||||
// Iterate through the source tiddlers
|
||||
if($tw.utils.isArray(source)) {
|
||||
$tw.utils.each(source,function(title) {
|
||||
checkTiddler(title);
|
||||
});
|
||||
} else {
|
||||
$tw.utils.each(source,function(element,title) {
|
||||
checkTiddler(title);
|
||||
});
|
||||
}
|
||||
results.sort();
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
43
core/modules/filters/is/image.js
Normal file
43
core/modules/filters/is/image.js
Normal file
@@ -0,0 +1,43 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/is/image.js
|
||||
type: application/javascript
|
||||
module-type: isfilteroperator
|
||||
|
||||
Filter function for [is[image]]
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.image = function(source,prefix,options) {
|
||||
var results = [];
|
||||
// Function to check a tiddler
|
||||
function checkTiddler(title) {
|
||||
var match = options.wiki.isImageTiddler(title);
|
||||
if(prefix === "!") {
|
||||
match = !match;
|
||||
}
|
||||
if(match) {
|
||||
results.push(title);
|
||||
}
|
||||
};
|
||||
// Iterate through the source tiddlers
|
||||
if($tw.utils.isArray(source)) {
|
||||
$tw.utils.each(source,function(title) {
|
||||
checkTiddler(title);
|
||||
});
|
||||
} else {
|
||||
$tw.utils.each(source,function(element,title) {
|
||||
checkTiddler(title);
|
||||
});
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -18,7 +18,7 @@ Export our filter function
|
||||
exports.list = function(source,operator,options) {
|
||||
var results = [],
|
||||
tr = $tw.utils.parseTextReference(operator.operand),
|
||||
list = options.wiki.getTiddlerList(tr.title,tr.field,tr.index);
|
||||
list = options.wiki.getTiddlerList(tr.title || options.currTiddlerTitle,tr.field,tr.index);
|
||||
function checkTiddler(title) {
|
||||
var match = list.indexOf(title) !== -1;
|
||||
if(operator.prefix === "!") {
|
||||
|
||||
@@ -13,23 +13,23 @@ The image parser parses an image into an embeddable HTML element
|
||||
"use strict";
|
||||
|
||||
var ImageParser = function(type,text,options) {
|
||||
var element = "img",
|
||||
var element = {
|
||||
type: "element",
|
||||
tag: "img",
|
||||
attributes: {}
|
||||
},
|
||||
src;
|
||||
if(type === "application/pdf" || type === ".pdf") {
|
||||
src = "data:application/pdf;base64," + text;
|
||||
element = "embed";
|
||||
} else if(type === "image/svg+xml" || type === ".svg") {
|
||||
src = "data:image/svg+xml," + encodeURIComponent(text);
|
||||
} else {
|
||||
src = "data:" + type + ";base64," + text;
|
||||
}
|
||||
this.tree = [{
|
||||
type: "element",
|
||||
tag: element,
|
||||
attributes: {
|
||||
"src": {type: "string", value: src}
|
||||
if(text) {
|
||||
if(type === "application/pdf" || type === ".pdf") {
|
||||
element.attributes.src = {type: "string", value: "data:application/pdf;base64," + text};
|
||||
element.tag = "embed";
|
||||
} else if(type === "image/svg+xml" || type === ".svg") {
|
||||
element.attributes.src = {type: "string", value: "data:image/svg+xml," + encodeURIComponent(text)};
|
||||
} else {
|
||||
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
||||
}
|
||||
}];
|
||||
}
|
||||
this.tree = [element];
|
||||
};
|
||||
|
||||
exports["image/svg+xml"] = ImageParser;
|
||||
|
||||
@@ -9,6 +9,8 @@ Wiki text block rule for HTML comments. For example:
|
||||
<!-- This is a comment -->
|
||||
```
|
||||
|
||||
Note that the syntax for comments is simplified to an opening "<!--" sequence and a closing "-->" sequence -- HTML itself implements a more complex format (see http://ostermiller.org/findhtmlcomment.html)
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
@@ -21,13 +23,26 @@ exports.types = {block: true};
|
||||
|
||||
exports.init = function(parser) {
|
||||
this.parser = parser;
|
||||
// Regexp to match - HTML comment regexp by Stephen Ostermiller, http://ostermiller.org/findhtmlcomment.html
|
||||
this.matchRegExp = /\<![ \r\n\t]*(?:--(?:[^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>\r?\n/mg;
|
||||
this.matchRegExp = /\<!--/mg;
|
||||
this.endMatchRegExp = /--\>/mg;
|
||||
};
|
||||
|
||||
exports.findNextMatch = function(startPos) {
|
||||
this.matchRegExp.lastIndex = startPos;
|
||||
this.match = this.matchRegExp.exec(this.parser.source);
|
||||
if(this.match) {
|
||||
this.endMatchRegExp.lastIndex = startPos + this.match[0].length;
|
||||
this.endMatch = this.endMatchRegExp.exec(this.parser.source);
|
||||
if(this.endMatch) {
|
||||
return this.match.index;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
exports.parse = function() {
|
||||
// Move past the match
|
||||
this.parser.pos = this.matchRegExp.lastIndex;
|
||||
this.parser.pos = this.endMatchRegExp.lastIndex;
|
||||
// Don't return any elements
|
||||
return [];
|
||||
};
|
||||
|
||||
@@ -9,6 +9,8 @@ Wiki text inline rule for HTML comments. For example:
|
||||
<!-- This is a comment -->
|
||||
```
|
||||
|
||||
Note that the syntax for comments is simplified to an opening "<!--" sequence and a closing "-->" sequence -- HTML itself implements a more complex format (see http://ostermiller.org/findhtmlcomment.html)
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
@@ -21,13 +23,26 @@ exports.types = {inline: true};
|
||||
|
||||
exports.init = function(parser) {
|
||||
this.parser = parser;
|
||||
// Regexp to match - HTML comment regexp by Stephen Ostermiller, http://ostermiller.org/findhtmlcomment.html
|
||||
this.matchRegExp = /\<![ \r\n\t]*(?:--(?:[^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/mg;
|
||||
this.matchRegExp = /\<!--/mg;
|
||||
this.endMatchRegExp = /--\>/mg;
|
||||
};
|
||||
|
||||
exports.findNextMatch = function(startPos) {
|
||||
this.matchRegExp.lastIndex = startPos;
|
||||
this.match = this.matchRegExp.exec(this.parser.source);
|
||||
if(this.match) {
|
||||
this.endMatchRegExp.lastIndex = startPos + this.match[0].length;
|
||||
this.endMatch = this.endMatchRegExp.exec(this.parser.source);
|
||||
if(this.endMatch) {
|
||||
return this.match.index;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
exports.parse = function() {
|
||||
// Move past the match
|
||||
this.parser.pos = this.matchRegExp.lastIndex;
|
||||
this.parser.pos = this.endMatchRegExp.lastIndex;
|
||||
// Don't return any elements
|
||||
return [];
|
||||
};
|
||||
|
||||
@@ -47,8 +47,8 @@ exports.parse = function() {
|
||||
this.nextTag = null;
|
||||
// Advance the parser position to past the tag
|
||||
this.parser.pos = tag.end;
|
||||
// Check for a following linebreak
|
||||
var hasLineBreak = !tag.isSelfClosing && !!this.parseTokenRegExp(this.parser.source,this.parser.pos,/(\r?\n)/g);
|
||||
// Check for an immediately following double linebreak
|
||||
var hasLineBreak = !tag.isSelfClosing && !!this.parseTokenRegExp(this.parser.source,this.parser.pos,/(\r?\n(?:\r?\n|$))/g);
|
||||
// Set whether we're in block mode
|
||||
tag.isBlock = this.is.block || hasLineBreak;
|
||||
// Parse the body if we need to
|
||||
@@ -359,7 +359,7 @@ exports.parseTag = function(source,pos,options) {
|
||||
pos = token.end;
|
||||
// Check for a required line break
|
||||
if(options.requireLineBreak) {
|
||||
token = this.parseTokenRegExp(source,pos,/(\r?\n)/g);
|
||||
token = this.parseTokenRegExp(source,pos,/(\r?\n(?:\r?\n|$))/g);
|
||||
if(!token) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*\
|
||||
title: $:/core/modules/themes.js
|
||||
title: $:/core/modules/pluginswitcher.js
|
||||
type: application/javascript
|
||||
module-type: global
|
||||
|
||||
Manages themes and styling.
|
||||
Manages switching plugins for themes and languages.
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
@@ -12,42 +12,44 @@ Manages themes and styling.
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var THEME_PLUGIN_TITLE = "$:/theme", // This tiddler contains the title of the current theme plugin
|
||||
DEFAULT_THEME_PLUGINS = [
|
||||
"$:/themes/tiddlywiki/snowwhite",
|
||||
"$:/themes/tiddlywiki/vanilla"
|
||||
];
|
||||
|
||||
function ThemeManager(wiki) {
|
||||
this.wiki = wiki;
|
||||
// There's no theme to start with
|
||||
this.currentThemeTitle = undefined;
|
||||
// Switch to the current theme
|
||||
this.switchTheme();
|
||||
// Listen for changes to the theme
|
||||
/*
|
||||
options:
|
||||
wiki: wiki store to be used
|
||||
pluginType: type of plugin to be switched
|
||||
controllerTitle: title of tiddler used to control switching of this resource
|
||||
defaultPlugins: array of default plugins to be used if nominated plugin isn't found
|
||||
*/
|
||||
function PluginSwitcher(options) {
|
||||
this.wiki = options.wiki;
|
||||
this.pluginType = options.pluginType;
|
||||
this.controllerTitle = options.controllerTitle;
|
||||
this.defaultPlugins = options.defaultPlugins || [];
|
||||
// Switch to the current plugin
|
||||
this.switchPlugins();
|
||||
// Listen for changes to the selected plugin
|
||||
var self = this;
|
||||
this.wiki.addEventListener("change",function(changes) {
|
||||
if($tw.utils.hop(changes,THEME_PLUGIN_TITLE)) {
|
||||
self.switchTheme();
|
||||
if($tw.utils.hop(changes,self.controllerTitle)) {
|
||||
self.switchPlugins();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ThemeManager.prototype.switchTheme = function() {
|
||||
PluginSwitcher.prototype.switchPlugins = function() {
|
||||
// Get the name of the current theme
|
||||
var themePluginTitle = this.wiki.getTiddlerText(THEME_PLUGIN_TITLE);
|
||||
var selectedPluginTitle = this.wiki.getTiddlerText(this.controllerTitle);
|
||||
// If it doesn't exist, then fallback to one of the default themes
|
||||
var index = 0;
|
||||
while(!this.wiki.getTiddler(themePluginTitle) && index < DEFAULT_THEME_PLUGINS.length) {
|
||||
themePluginTitle = DEFAULT_THEME_PLUGINS[index++];
|
||||
while(!this.wiki.getTiddler(selectedPluginTitle) && index < this.defaultPlugins.length) {
|
||||
selectedPluginTitle = this.defaultPlugins[index++];
|
||||
}
|
||||
// Accumulate the titles of the plugins that we need to load
|
||||
var themePlugins = [],
|
||||
var plugins = [],
|
||||
self = this,
|
||||
accumulatePlugin = function(title) {
|
||||
var tiddler = self.wiki.getTiddler(title);
|
||||
if(tiddler && tiddler.isPlugin() && themePlugins.indexOf(title) === -1) {
|
||||
themePlugins.push(title);
|
||||
if(tiddler && tiddler.isPlugin() && plugins.indexOf(title) === -1) {
|
||||
plugins.push(title);
|
||||
var pluginInfo = JSON.parse(self.wiki.getTiddlerText(title)),
|
||||
dependents = $tw.utils.parseStringArray(tiddler.fields.dependents || "");
|
||||
$tw.utils.each(dependents,function(title) {
|
||||
@@ -55,23 +57,23 @@ ThemeManager.prototype.switchTheme = function() {
|
||||
});
|
||||
}
|
||||
};
|
||||
accumulatePlugin(themePluginTitle);
|
||||
accumulatePlugin(selectedPluginTitle);
|
||||
// Unregister any existing theme tiddlers
|
||||
var unregisteredThemeTiddlers = $tw.wiki.unregisterPluginTiddlers("theme");
|
||||
var unregisteredTiddlers = $tw.wiki.unregisterPluginTiddlers(this.pluginType);
|
||||
// Accumulate the titles of shadow tiddlers that have changed as a result of this switch
|
||||
var changedTiddlers = {};
|
||||
$tw.utils.each(this.wiki.shadowTiddlers,function(shadowInfo,title) {
|
||||
if(unregisteredThemeTiddlers.indexOf(shadowInfo.source) !== -1) {
|
||||
if(unregisteredTiddlers.indexOf(shadowInfo.source) !== -1) {
|
||||
changedTiddlers[title] = true; // isDeleted?
|
||||
}
|
||||
});
|
||||
// Register any new theme tiddlers
|
||||
var registeredThemeTiddlers = $tw.wiki.registerPluginTiddlers("theme",themePlugins);
|
||||
var registeredTiddlers = $tw.wiki.registerPluginTiddlers(this.pluginType,plugins);
|
||||
// Unpack the current theme tiddlers
|
||||
$tw.wiki.unpackPluginTiddlers();
|
||||
// Accumulate the affected shadow tiddlers
|
||||
$tw.utils.each(this.wiki.shadowTiddlers,function(shadowInfo,title) {
|
||||
if(registeredThemeTiddlers.indexOf(shadowInfo.source) !== -1) {
|
||||
if(registeredTiddlers.indexOf(shadowInfo.source) !== -1) {
|
||||
changedTiddlers[title] = false; // isDeleted?
|
||||
}
|
||||
});
|
||||
@@ -81,6 +83,6 @@ ThemeManager.prototype.switchTheme = function() {
|
||||
});
|
||||
};
|
||||
|
||||
exports.ThemeManager = ThemeManager;
|
||||
exports.PluginSwitcher = PluginSwitcher;
|
||||
|
||||
})();
|
||||
@@ -16,10 +16,6 @@ var AndTidWiki = function(wiki) {
|
||||
};
|
||||
|
||||
AndTidWiki.prototype.save = function(text,method,callback) {
|
||||
// Bail out unless this is a save (rather than a download)
|
||||
if(method !== "save") {
|
||||
return false;
|
||||
}
|
||||
// Get the pathname of this document
|
||||
var pathname = decodeURIComponent(document.location.toString());
|
||||
// Strip the file://
|
||||
@@ -47,7 +43,8 @@ Information about this saver
|
||||
*/
|
||||
AndTidWiki.prototype.info = {
|
||||
name: "andtidwiki",
|
||||
priority: 1600
|
||||
priority: 1600,
|
||||
capabilities: ["save", "autosave"]
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -46,7 +46,8 @@ Information about this saver
|
||||
*/
|
||||
DownloadSaver.prototype.info = {
|
||||
name: "download",
|
||||
priority: 100
|
||||
priority: 100,
|
||||
capabilities: ["save", "download"]
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -22,10 +22,6 @@ var FSOSaver = function(wiki) {
|
||||
};
|
||||
|
||||
FSOSaver.prototype.save = function(text,method,callback) {
|
||||
// Bail out unless this is a save (rather than a download)
|
||||
if(method !== "save") {
|
||||
return false;
|
||||
}
|
||||
// Get the pathname of this document
|
||||
var pathname = unescape(document.location.pathname);
|
||||
// Test for a Windows path of the form /x:\blah...
|
||||
@@ -53,7 +49,8 @@ Information about this saver
|
||||
*/
|
||||
FSOSaver.prototype.info = {
|
||||
name: "FSOSaver",
|
||||
priority: 120
|
||||
priority: 120,
|
||||
capabilities: ["save", "autosave"]
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -13,7 +13,7 @@ Handles saving changes via HTML5's download APIs
|
||||
"use strict";
|
||||
|
||||
// Title of the tiddler containing the download message
|
||||
var downloadInstructionsTitle = "$:/messages/Download"
|
||||
var downloadInstructionsTitle = "$:/language/Modals/Download";
|
||||
|
||||
/*
|
||||
Select the appropriate saver module and set it up
|
||||
@@ -33,7 +33,8 @@ Information about this saver
|
||||
*/
|
||||
ManualDownloadSaver.prototype.info = {
|
||||
name: "manualdownload",
|
||||
priority: 0
|
||||
priority: 0,
|
||||
capabilities: ["save", "download"]
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -36,7 +36,8 @@ Information about this saver
|
||||
*/
|
||||
MsDownloadSaver.prototype.info = {
|
||||
name: "msdownload",
|
||||
priority: 110
|
||||
priority: 110,
|
||||
capabilities: ["save", "download"]
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -16,10 +16,6 @@ var TiddlyFoxSaver = function(wiki) {
|
||||
};
|
||||
|
||||
TiddlyFoxSaver.prototype.save = function(text,method,callback) {
|
||||
// Bail out unless this is a save (rather than a download)
|
||||
if(method !== "save") {
|
||||
return false;
|
||||
}
|
||||
var messageBox = document.getElementById("tiddlyfox-message-box");
|
||||
if(messageBox) {
|
||||
// Get the pathname of this document
|
||||
@@ -55,7 +51,8 @@ Information about this saver
|
||||
*/
|
||||
TiddlyFoxSaver.prototype.info = {
|
||||
name: "tiddlyfox",
|
||||
priority: 1500
|
||||
priority: 1500,
|
||||
capabilities: ["save", "autosave"]
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -19,11 +19,7 @@ var TiddlyIESaver = function(wiki) {
|
||||
};
|
||||
|
||||
TiddlyIESaver.prototype.save = function(text,method,callback) {
|
||||
// Bail out unless this is a save (rather than a download)
|
||||
if(method !== "save") {
|
||||
return false;
|
||||
}
|
||||
// check existence of TiddlyIE BHO extension (note: only works after document is complete)
|
||||
// Check existence of TiddlyIE BHO extension (note: only works after document is complete)
|
||||
if(typeof(window.TiddlyIE) != "undefined") {
|
||||
// Get the pathname of this document
|
||||
var pathname = unescape(document.location.pathname);
|
||||
@@ -53,7 +49,8 @@ Information about this saver
|
||||
*/
|
||||
TiddlyIESaver.prototype.info = {
|
||||
name: "tiddlyiesaver",
|
||||
priority: 1500
|
||||
priority: 1500,
|
||||
capabilities: ["save"]
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -16,10 +16,6 @@ var TWEditSaver = function(wiki) {
|
||||
};
|
||||
|
||||
TWEditSaver.prototype.save = function(text,method,callback) {
|
||||
// Bail out unless this is a save (rather than a download)
|
||||
if(method !== "save") {
|
||||
return false;
|
||||
}
|
||||
// Bail if we're not running under TWEdit
|
||||
if(typeof DeviceInfo !== "object") {
|
||||
return false;
|
||||
@@ -68,7 +64,8 @@ Information about this saver
|
||||
*/
|
||||
TWEditSaver.prototype.info = {
|
||||
name: "twedit",
|
||||
priority: 1600
|
||||
priority: 1600,
|
||||
capabilities: ["save", "autosave"]
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -22,10 +22,6 @@ var UploadSaver = function(wiki) {
|
||||
};
|
||||
|
||||
UploadSaver.prototype.save = function(text,method,callback) {
|
||||
// Bail out unless this is a save (rather than a download)
|
||||
if(method !== "save") {
|
||||
return false;
|
||||
}
|
||||
// Get the various parameters we need
|
||||
var backupDir = this.wiki.getTextReference("$:/UploadBackupDir") || ".",
|
||||
username = this.wiki.getTextReference("$:/UploadName"),
|
||||
@@ -69,7 +65,7 @@ UploadSaver.prototype.save = function(text,method,callback) {
|
||||
}
|
||||
};
|
||||
http.send(data);
|
||||
$tw.notifier.display("$:/messages/StartingSave");
|
||||
$tw.notifier.display("$:/language/Notifications/Save/Starting");
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -78,7 +74,8 @@ Information about this saver
|
||||
*/
|
||||
UploadSaver.prototype.info = {
|
||||
name: "upload",
|
||||
priority: 2000
|
||||
priority: 2000,
|
||||
capabilities: ["save", "autosave"]
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -16,11 +16,11 @@ var widget = require("$:/core/modules/widgets/widget.js");
|
||||
|
||||
exports.startup = function() {
|
||||
var modules,n,m,f,commander;
|
||||
// Load utility modules and initialise the logger
|
||||
// Load modules
|
||||
$tw.modules.applyMethods("utils",$tw.utils);
|
||||
$tw.logger = new $tw.utils.Logger();
|
||||
$tw.log = $tw.logger.log;
|
||||
// Load other modules
|
||||
if($tw.node) {
|
||||
$tw.modules.applyMethods("utils-node",$tw.utils);
|
||||
}
|
||||
$tw.modules.applyMethods("global",$tw);
|
||||
$tw.modules.applyMethods("config",$tw.config);
|
||||
if($tw.browser) {
|
||||
@@ -38,8 +38,25 @@ exports.startup = function() {
|
||||
$tw.syncer = new $tw.Syncer({wiki: $tw.wiki});
|
||||
// Set up the command modules
|
||||
$tw.Commander.initCommands();
|
||||
// Kick off the language manager
|
||||
$tw.languageManager = new $tw.PluginSwitcher({
|
||||
wiki: $tw.wiki,
|
||||
pluginType: "language",
|
||||
controllerTitle: "$:/language",
|
||||
defaultPlugins: [
|
||||
"$:/languages/en-US"
|
||||
]
|
||||
});
|
||||
// Kick off the theme manager
|
||||
$tw.themeManager = new $tw.ThemeManager($tw.wiki);
|
||||
$tw.themeManager = new $tw.PluginSwitcher({
|
||||
wiki: $tw.wiki,
|
||||
pluginType: "theme",
|
||||
controllerTitle: "$:/theme",
|
||||
defaultPlugins: [
|
||||
"$:/themes/tiddlywiki/snowwhite",
|
||||
"$:/themes/tiddlywiki/vanilla"
|
||||
]
|
||||
});
|
||||
// Get the default tiddlers
|
||||
var defaultTiddlersTitle = "$:/DefaultTiddlers",
|
||||
defaultTiddlersTiddler = $tw.wiki.getTiddler(defaultTiddlersTitle),
|
||||
@@ -56,6 +73,15 @@ exports.startup = function() {
|
||||
$tw.wiki.addTiddler({title: storyTitle, text: "", list: story},$tw.wiki.getModificationFields());
|
||||
// Host-specific startup
|
||||
if($tw.browser) {
|
||||
// Set up our beforeunload handler
|
||||
window.addEventListener("beforeunload",function(event) {
|
||||
var confirmationMessage = null;
|
||||
if($tw.syncer.isDirty()) {
|
||||
confirmationMessage = "You have unsaved changes in TiddlyWiki";
|
||||
event.returnValue = confirmationMessage; // Gecko
|
||||
}
|
||||
return confirmationMessage;
|
||||
});
|
||||
// Install the popup manager
|
||||
$tw.popup = new $tw.utils.Popup({
|
||||
rootElement: document.body
|
||||
@@ -85,21 +111,37 @@ exports.startup = function() {
|
||||
$tw.rootWidget.addEventListener("tw-scroll",function(event) {
|
||||
$tw.pageScroller.handleEvent(event);
|
||||
});
|
||||
// Install the save action handler
|
||||
$tw.wiki.initSavers();
|
||||
// Install the save action handlers
|
||||
$tw.rootWidget.addEventListener("tw-save-wiki",function(event) {
|
||||
$tw.wiki.saveWiki({
|
||||
$tw.syncer.saveWiki({
|
||||
template: event.param,
|
||||
downloadType: "text/plain"
|
||||
});
|
||||
});
|
||||
$tw.rootWidget.addEventListener("tw-auto-save-wiki",function(event) {
|
||||
$tw.syncer.saveWiki({
|
||||
method: "autosave",
|
||||
template: event.param,
|
||||
downloadType: "text/plain"
|
||||
});
|
||||
});
|
||||
$tw.rootWidget.addEventListener("tw-download-file",function(event) {
|
||||
$tw.wiki.saveWiki({
|
||||
$tw.syncer.saveWiki({
|
||||
method: "download",
|
||||
template: event.param,
|
||||
downloadType: "text/plain"
|
||||
});
|
||||
});
|
||||
// Listen out for login/logout/refresh events in the browser
|
||||
$tw.rootWidget.addEventListener("tw-login",function() {
|
||||
$tw.syncer.handleLoginEvent();
|
||||
});
|
||||
$tw.rootWidget.addEventListener("tw-logout",function() {
|
||||
$tw.syncer.handleLogoutEvent();
|
||||
});
|
||||
$tw.rootWidget.addEventListener("tw-server-refresh",function() {
|
||||
$tw.syncer.handleRefreshEvent();
|
||||
});
|
||||
// Install the crypto event handlers
|
||||
$tw.rootWidget.addEventListener("tw-set-password",function(event) {
|
||||
$tw.passwordPrompt.createPrompt({
|
||||
@@ -118,6 +160,12 @@ exports.startup = function() {
|
||||
$tw.rootWidget.addEventListener("tw-clear-password",function(event) {
|
||||
$tw.crypto.setPassword(null);
|
||||
});
|
||||
// Ensure that $:/isEncrypted is maintained properly
|
||||
$tw.wiki.addEventListener("change",function(changes) {
|
||||
if($tw.utils.hop(changes,"$:/isEncrypted")) {
|
||||
$tw.crypto.updateCryptoStateTiddler();
|
||||
}
|
||||
});
|
||||
// Set up the favicon
|
||||
var faviconTitle = "$:/favicon.ico",
|
||||
faviconLink = document.getElementById("faviconLink"),
|
||||
@@ -164,7 +212,7 @@ exports.startup = function() {
|
||||
// If we're being viewed on a data: URI then give instructions for how to save
|
||||
if(document.location.protocol === "data:") {
|
||||
$tw.utils.dispatchCustomEvent(document,"tw-modal",{
|
||||
param: "$:/messages/SaveInstructions"
|
||||
param: "$:/language/Modals/SaveInstructions"
|
||||
});
|
||||
}
|
||||
// Call browser startup modules
|
||||
|
||||
@@ -3,7 +3,7 @@ title: $:/core/modules/syncer.js
|
||||
type: application/javascript
|
||||
module-type: global
|
||||
|
||||
The syncer transfers content to and from data sources using syncadaptor modules.
|
||||
The syncer tracks changes to the store. If a syncadaptor is used then individual tiddlers are synchronised through it. If there is no syncadaptor then the entire wiki is saved via saver modules.
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
@@ -20,7 +20,7 @@ function Syncer(options) {
|
||||
var self = this;
|
||||
this.wiki = options.wiki;
|
||||
// Make a logger
|
||||
this.log = $tw.logger.makeLog("syncer");
|
||||
this.logger = new $tw.utils.Logger("syncer" + ($tw.browser ? "-browser" : "") + ($tw.node ? "-server" : ""));
|
||||
// Find a working syncadaptor
|
||||
this.syncadaptor = undefined;
|
||||
$tw.modules.forEachModuleOfType("syncadaptor",function(title,module) {
|
||||
@@ -28,46 +28,16 @@ function Syncer(options) {
|
||||
self.syncadaptor = new module.adaptorClass(self);
|
||||
}
|
||||
});
|
||||
// Only do anything if we've got a syncadaptor
|
||||
if(this.syncadaptor) {
|
||||
this.init();
|
||||
// Initialise our savers
|
||||
if($tw.browser) {
|
||||
this.initSavers();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Error handling
|
||||
*/
|
||||
Syncer.prototype.showError = function(error) {
|
||||
this.log("Error: " + error);
|
||||
};
|
||||
|
||||
/*
|
||||
Constants
|
||||
*/
|
||||
Syncer.prototype.titleIsLoggedIn = "$:/status/IsLoggedIn";
|
||||
Syncer.prototype.titleUserName = "$:/status/UserName";
|
||||
Syncer.prototype.taskTimerInterval = 1 * 1000; // Interval for sync timer
|
||||
Syncer.prototype.throttleInterval = 1 * 1000; // Defer saving tiddlers if they've changed in the last 1s...
|
||||
Syncer.prototype.fallbackInterval = 10 * 1000; // Unless the task is older than 10s
|
||||
Syncer.prototype.pollTimerInterval = 60 * 1000; // Interval for polling for changes from the adaptor
|
||||
|
||||
/*
|
||||
Initialise the syncer
|
||||
*/
|
||||
Syncer.prototype.init = function() {
|
||||
var self = this;
|
||||
// Hashmap by title of {revision:,changeCount:,adaptorInfo:}
|
||||
this.tiddlerInfo = {};
|
||||
// Compile the dirty tiddler filter
|
||||
this.filterFn = this.wiki.compileFilter(this.wiki.getTiddlerText(this.titleSyncFilter));
|
||||
// Record information for known tiddlers
|
||||
this.wiki.forEachTiddler({includeSystem: true},function(title,tiddler) {
|
||||
self.tiddlerInfo[title] = {
|
||||
revision: tiddler.fields["revision"],
|
||||
adaptorInfo: self.syncadaptor.getTiddlerInfo(tiddler),
|
||||
changeCount: self.wiki.getChangeCount(title)
|
||||
}
|
||||
});
|
||||
this.readTiddlerInfo();
|
||||
// Tasks are {type: "load"/"save"/"delete", title:, queueTime:, lastModificationTime:}
|
||||
this.taskQueue = {}; // Hashmap of tasks to be performed
|
||||
this.taskQueue = {}; // Hashmap of tasks yet to be performed
|
||||
this.taskInProgress = {}; // Hash of tasks in progress
|
||||
this.taskTimerId = null; // Timer for task dispatch
|
||||
this.pollTimerId = null; // Timer for polling server
|
||||
@@ -76,30 +46,129 @@ Syncer.prototype.init = function() {
|
||||
self.syncToServer(changes);
|
||||
});
|
||||
// Listen out for lazyLoad events
|
||||
this.wiki.addEventListener("lazyLoad",function(title) {
|
||||
self.handleLazyLoadEvent(title);
|
||||
});
|
||||
// Listen out for login/logout/refresh events in the browser
|
||||
if($tw.browser) {
|
||||
document.addEventListener("tw-login",function(event) {
|
||||
self.handleLoginEvent(event);
|
||||
},false);
|
||||
document.addEventListener("tw-logout",function(event) {
|
||||
self.handleLogoutEvent(event);
|
||||
},false);
|
||||
document.addEventListener("tw-server-refresh",function(event) {
|
||||
self.handleRefreshEvent(event);
|
||||
},false);
|
||||
if(this.syncadaptor) {
|
||||
this.wiki.addEventListener("lazyLoad",function(title) {
|
||||
self.handleLazyLoadEvent(title);
|
||||
});
|
||||
}
|
||||
// Get the login status
|
||||
this.getStatus(function (err,isLoggedIn) {
|
||||
if(isLoggedIn) {
|
||||
// Do a sync from the server
|
||||
self.syncFromServer();
|
||||
// Do a sync from the server
|
||||
self.syncFromServer();
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
Constants
|
||||
*/
|
||||
Syncer.prototype.titleIsLoggedIn = "$:/status/IsLoggedIn";
|
||||
Syncer.prototype.titleUserName = "$:/status/UserName";
|
||||
Syncer.prototype.titleSyncFilter = "$:/config/SyncFilter";
|
||||
Syncer.prototype.titleAutoSave = "$:/config/AutoSave";
|
||||
Syncer.prototype.titleSavedNotification = "$:/language/Notifications/Save/Done";
|
||||
Syncer.prototype.taskTimerInterval = 1 * 1000; // Interval for sync timer
|
||||
Syncer.prototype.throttleInterval = 1 * 1000; // Defer saving tiddlers if they've changed in the last 1s...
|
||||
Syncer.prototype.fallbackInterval = 10 * 1000; // Unless the task is older than 10s
|
||||
Syncer.prototype.pollTimerInterval = 60 * 1000; // Interval for polling for changes from the adaptor
|
||||
|
||||
/*
|
||||
Read (or re-read) the latest tiddler info from the store
|
||||
*/
|
||||
Syncer.prototype.readTiddlerInfo = function() {
|
||||
// Hashmap by title of {revision:,changeCount:,adaptorInfo:}
|
||||
this.tiddlerInfo = {};
|
||||
// Record information for known tiddlers
|
||||
var self = this,
|
||||
tiddlers = this.filterFn.call(this.wiki);
|
||||
$tw.utils.each(tiddlers,function(title) {
|
||||
var tiddler = self.wiki.getTiddler(title);
|
||||
self.tiddlerInfo[title] = {
|
||||
revision: tiddler.fields["revision"],
|
||||
adaptorInfo: self.syncadaptor && self.syncadaptor.getTiddlerInfo(tiddler),
|
||||
changeCount: self.wiki.getChangeCount(title)
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
Select the appropriate saver modules and set them up
|
||||
*/
|
||||
Syncer.prototype.initSavers = function(moduleType) {
|
||||
moduleType = moduleType || "saver";
|
||||
// Instantiate the available savers
|
||||
this.savers = [];
|
||||
var self = this;
|
||||
$tw.modules.forEachModuleOfType(moduleType,function(title,module) {
|
||||
if(module.canSave(self)) {
|
||||
self.savers.push(module.create(self.wiki));
|
||||
}
|
||||
});
|
||||
// Sort the savers into priority order
|
||||
this.savers.sort(function(a,b) {
|
||||
if(a.info.priority < b.info.priority) {
|
||||
return -1;
|
||||
} else {
|
||||
if(a.info.priority > b.info.priority) {
|
||||
return +1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
Save the wiki contents. Options are:
|
||||
method: "save" or "download"
|
||||
template: the tiddler containing the template to save
|
||||
downloadType: the content type for the saved file
|
||||
*/
|
||||
Syncer.prototype.saveWiki = function(options) {
|
||||
options = options || {};
|
||||
var self = this,
|
||||
method = options.method || "save",
|
||||
template = options.template || "$:/core/save/all",
|
||||
downloadType = options.downloadType || "text/plain",
|
||||
text = this.wiki.renderTiddler(downloadType,template),
|
||||
callback = function(err) {
|
||||
if(err) {
|
||||
alert("Error while saving:\n\n" + err);
|
||||
} else {
|
||||
$tw.notifier.display(self.titleSavedNotification);
|
||||
if(options.callback) {
|
||||
options.callback();
|
||||
}
|
||||
}
|
||||
};
|
||||
// Ignore autosave if we've got a syncadaptor or autosave is disabled
|
||||
if(method === "autosave") {
|
||||
if(this.syncadaptor || this.wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Call the highest priority saver that supports this method
|
||||
for(var t=this.savers.length-1; t>=0; t--) {
|
||||
var saver = this.savers[t];
|
||||
if(saver.info.capabilities.indexOf(method) !== -1 && saver.save(text,method,callback)) {
|
||||
this.logger.log("Saving wiki with method",method,"through saver",saver.info.name);
|
||||
// Clear the task queue if we're saving (rather than downloading)
|
||||
if(method !== "download") {
|
||||
this.readTiddlerInfo();
|
||||
this.taskQueue = {};
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/*
|
||||
Checks whether the wiki is dirty (ie the window shouldn't be closed)
|
||||
*/
|
||||
Syncer.prototype.isDirty = function() {
|
||||
return (this.numTasksInQueue() > 0) || (this.numTasksInProgress() > 0);
|
||||
};
|
||||
|
||||
/*
|
||||
Save an incoming tiddler in the store, and updates the associated tiddlerInfo
|
||||
*/
|
||||
@@ -118,19 +187,19 @@ Syncer.prototype.storeTiddler = function(tiddlerFields) {
|
||||
Syncer.prototype.getStatus = function(callback) {
|
||||
var self = this;
|
||||
// Check if the adaptor supports getStatus()
|
||||
if(this.syncadaptor.getStatus) {
|
||||
if(this.syncadaptor && this.syncadaptor.getStatus) {
|
||||
// Mark us as not logged in
|
||||
this.wiki.addTiddler({title: this.titleIsLoggedIn,text: "no"});
|
||||
// Get login status
|
||||
this.syncadaptor.getStatus(function(err,isLoggedIn,username) {
|
||||
if(err) {
|
||||
self.showError(err);
|
||||
self.logger.alert(err);
|
||||
return;
|
||||
}
|
||||
// Set the various status tiddlers
|
||||
self.wiki.addTiddler({title: self.titleIsLoggedIn,text: isLoggedIn ? "yes" : "no"});
|
||||
if(isLoggedIn) {
|
||||
self.wiki.addTiddler({title: self.titleUserName,text: username});
|
||||
self.wiki.addTiddler({title: self.titleUserName,text: username || ""});
|
||||
} else {
|
||||
self.wiki.deleteTiddler(self.titleUserName);
|
||||
}
|
||||
@@ -148,8 +217,8 @@ Syncer.prototype.getStatus = function(callback) {
|
||||
Synchronise from the server by reading the skinny tiddler list and queuing up loads for any tiddlers that we don't already have up to date
|
||||
*/
|
||||
Syncer.prototype.syncFromServer = function() {
|
||||
if(this.syncadaptor.getSkinnyTiddlers) {
|
||||
this.log("Retrieving skinny tiddler list");
|
||||
if(this.syncadaptor && this.syncadaptor.getSkinnyTiddlers) {
|
||||
this.logger.log("Retrieving skinny tiddler list");
|
||||
var self = this;
|
||||
if(this.pollTimerId) {
|
||||
clearTimeout(this.pollTimerId);
|
||||
@@ -163,7 +232,7 @@ Syncer.prototype.syncFromServer = function() {
|
||||
},self.pollTimerInterval);
|
||||
// Check for errors
|
||||
if(err) {
|
||||
self.log("Error retrieving skinny tiddler list:",err);
|
||||
self.logger.alert("Error retrieving skinny tiddler list:",err);
|
||||
return;
|
||||
}
|
||||
// Process each incoming tiddler
|
||||
@@ -198,10 +267,11 @@ Synchronise a set of changes to the server
|
||||
*/
|
||||
Syncer.prototype.syncToServer = function(changes) {
|
||||
var self = this,
|
||||
now = new Date();
|
||||
now = new Date(),
|
||||
filteredChanges = this.filterFn.call(this.wiki,changes);
|
||||
$tw.utils.each(changes,function(change,title,object) {
|
||||
// Ignore the change if it is a shadow tiddler
|
||||
if((change.deleted && $tw.utils.hop(self.tiddlerInfo,title)) || (!change.deleted && self.wiki.tiddlerExists(title))) {
|
||||
// Process the change if it is a deletion of a tiddler we're already syncing, or is on the filtered change list
|
||||
if((change.deleted && $tw.utils.hop(self.tiddlerInfo,title)) || filteredChanges.indexOf(title) !== -1) {
|
||||
// Queue a task to sync this tiddler
|
||||
self.enqueueSyncTask({
|
||||
type: change.deleted ? "delete" : "save",
|
||||
@@ -249,7 +319,7 @@ Attempt to login to TiddlyWeb.
|
||||
callback: invoked with arguments (err,isLoggedIn)
|
||||
*/
|
||||
Syncer.prototype.login = function(username,password,callback) {
|
||||
this.log("Attempting to login as",username);
|
||||
this.logger.log("Attempting to login as",username);
|
||||
var self = this;
|
||||
if(this.syncadaptor.login) {
|
||||
this.syncadaptor.login(username,password,function(err) {
|
||||
@@ -271,12 +341,12 @@ Syncer.prototype.login = function(username,password,callback) {
|
||||
Attempt to log out of TiddlyWeb
|
||||
*/
|
||||
Syncer.prototype.handleLogoutEvent = function() {
|
||||
this.log("Attempting to logout");
|
||||
this.logger.log("Attempting to logout");
|
||||
var self = this;
|
||||
if(this.syncadaptor.logout) {
|
||||
this.syncadaptor.logout(function(err) {
|
||||
if(err) {
|
||||
self.showError(err);
|
||||
self.logger.alert(err);
|
||||
} else {
|
||||
self.getStatus();
|
||||
}
|
||||
@@ -314,7 +384,7 @@ Syncer.prototype.enqueueSyncTask = function(task) {
|
||||
}
|
||||
// Check if this tiddler is already in the queue
|
||||
if($tw.utils.hop(this.taskQueue,task.title)) {
|
||||
this.log("Re-queueing up sync task with type:",task.type,"title:",task.title);
|
||||
// this.logger.log("Re-queueing up sync task with type:",task.type,"title:",task.title);
|
||||
var existingTask = this.taskQueue[task.title];
|
||||
// If so, just update the last modification time
|
||||
existingTask.lastModificationTime = task.lastModificationTime;
|
||||
@@ -323,12 +393,14 @@ Syncer.prototype.enqueueSyncTask = function(task) {
|
||||
existingTask.type = task.type;
|
||||
}
|
||||
} else {
|
||||
this.log("Queuing up sync task with type:",task.type,"title:",task.title);
|
||||
// this.logger.log("Queuing up sync task with type:",task.type,"title:",task.title);
|
||||
// If it is not in the queue, insert it
|
||||
this.taskQueue[task.title] = task;
|
||||
}
|
||||
// Process the queue
|
||||
$tw.utils.nextTick(function() {self.processTaskQueue.call(self);});
|
||||
if(this.syncadaptor) {
|
||||
$tw.utils.nextTick(function() {self.processTaskQueue.call(self);});
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -375,7 +447,7 @@ Syncer.prototype.processTaskQueue = function() {
|
||||
// Dispatch the task
|
||||
this.dispatchTask(task,function(err) {
|
||||
if(err) {
|
||||
self.showError("Sync error while processing '" + task.title + "':\n" + err);
|
||||
self.logger.alert("Sync error while processing '" + task.title + "':\n" + err);
|
||||
}
|
||||
// Mark that this task is no longer in progress
|
||||
delete self.taskInProgress[task.title];
|
||||
@@ -427,7 +499,7 @@ Syncer.prototype.dispatchTask = function(task,callback) {
|
||||
if(task.type === "save") {
|
||||
var changeCount = this.wiki.getChangeCount(task.title),
|
||||
tiddler = this.wiki.getTiddler(task.title);
|
||||
this.log("Dispatching 'save' task:",task.title);
|
||||
this.logger.log("Dispatching 'save' task:",task.title);
|
||||
if(tiddler) {
|
||||
this.syncadaptor.saveTiddler(tiddler,function(err,adaptorInfo,revision) {
|
||||
if(err) {
|
||||
@@ -445,7 +517,7 @@ Syncer.prototype.dispatchTask = function(task,callback) {
|
||||
}
|
||||
} else if(task.type === "load") {
|
||||
// Load the tiddler
|
||||
this.log("Dispatching 'load' task:",task.title);
|
||||
this.logger.log("Dispatching 'load' task:",task.title);
|
||||
this.syncadaptor.loadTiddler(task.title,function(err,tiddlerFields) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
@@ -459,7 +531,7 @@ Syncer.prototype.dispatchTask = function(task,callback) {
|
||||
});
|
||||
} else if(task.type === "delete") {
|
||||
// Delete the tiddler
|
||||
this.log("Dispatching 'delete' task:",task.title);
|
||||
this.logger.log("Dispatching 'delete' task:",task.title);
|
||||
this.syncadaptor.deleteTiddler(task.title,function(err) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
|
||||
@@ -60,27 +60,6 @@ exports.toggleClass = function(el,className,status) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.applyStyleSheet = function(id,css) {
|
||||
var el = document.getElementById(id);
|
||||
if(document.createStyleSheet) { // Older versions of IE
|
||||
if(el) {
|
||||
el.parentNode.removeChild(el);
|
||||
}
|
||||
document.getElementsByTagName("head")[0].insertAdjacentHTML("beforeEnd",
|
||||
' <style id="' + id + '" type="text/css">' + css + '</style>'); // fails without
|
||||
} else { // Modern browsers
|
||||
if(el) {
|
||||
el.replaceChild(document.createTextNode(css), el.firstChild);
|
||||
} else {
|
||||
el = document.createElement("style");
|
||||
el.type = "text/css";
|
||||
el.id = id;
|
||||
el.appendChild(document.createTextNode(css));
|
||||
document.getElementsByTagName("head")[0].appendChild(el);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Get the scroll position of the viewport
|
||||
Returns:
|
||||
|
||||
@@ -45,7 +45,7 @@ exports.httpRequest = function(options) {
|
||||
return;
|
||||
}
|
||||
// Something went wrong
|
||||
options.callback(new Error("XMLHttpRequest error: " + this.status));
|
||||
options.callback("XMLHttpRequest error code: " + this.status);
|
||||
}
|
||||
};
|
||||
// Make the request
|
||||
|
||||
60
core/modules/utils/dom/keyboard.js
Normal file
60
core/modules/utils/dom/keyboard.js
Normal file
@@ -0,0 +1,60 @@
|
||||
/*\
|
||||
title: $:/core/modules/utils/dom/keyboard.js
|
||||
type: application/javascript
|
||||
module-type: utils
|
||||
|
||||
Keyboard utilities
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var namedKeys = {
|
||||
"backspace": 8,
|
||||
"tab": 9,
|
||||
"enter": 13,
|
||||
"escape": 27
|
||||
};
|
||||
|
||||
/*
|
||||
Parses a key descriptor into the structure:
|
||||
{
|
||||
keyCode: numeric keycode
|
||||
shiftKey: boolean
|
||||
altKey: boolean
|
||||
ctrlKey: boolean
|
||||
}
|
||||
Key descriptors have the following format:
|
||||
ctrl+enter
|
||||
ctrl+shift+alt+A
|
||||
*/
|
||||
exports.parseKeyDescriptor = function(keyDescriptor) {
|
||||
var components = keyDescriptor.split("+"),
|
||||
info = {
|
||||
keyCode: 0,
|
||||
shiftKey: false,
|
||||
altKey: false,
|
||||
ctrlKey: false
|
||||
};
|
||||
for(var t=0; t<components.length; t++) {
|
||||
var s = components[t].toLowerCase();
|
||||
// Look for modifier keys
|
||||
if(s === "ctrl") {
|
||||
info.ctrlKey = true;
|
||||
} else if(s === "shift") {
|
||||
info.shiftKey = true;
|
||||
} else if(s === "alt") {
|
||||
info.altKey = true;
|
||||
}
|
||||
// Replace named keys with their code
|
||||
if(namedKeys[s]) {
|
||||
info.keyCode = namedKeys[s];
|
||||
}
|
||||
}
|
||||
return info;
|
||||
};
|
||||
|
||||
})();
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user