1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-06-16 10:29:54 +00:00

Merge pull request #1 from Jermolene/master

Update my fork.
This commit is contained in:
Roma 2015-02-05 18:30:54 -06:00
commit a11264ebb0
1085 changed files with 15869 additions and 2563 deletions

View File

@ -62,14 +62,22 @@ $tw.utils.isDate = function(value) {
Iterate through all the own properties of an object or array. Callback is invoked with (element,title,object)
*/
$tw.utils.each = function(object,callback) {
var f;
var next,f;
if(object) {
if(Object.prototype.toString.call(object) == "[object Array]") {
object.forEach(callback);
for (f=0; f<object.length; f++) {
next = callback(object[f],f,object);
if(next === false) {
break;
}
}
} else {
for(f in object) {
if(Object.prototype.hasOwnProperty.call(object,f)) {
callback(object[f],f,object);
next = callback(object[f],f,object);
if(next === false) {
break;
}
}
}
}
@ -354,21 +362,20 @@ Returns true if the version string A is greater than the version string B. Retur
*/
$tw.utils.checkVersions = function(versionStringA,versionStringB) {
var defaultVersion = {
major: 0,
minor: 0,
patch: 0
},
versionA = $tw.utils.parseVersion(versionStringA) || defaultVersion,
versionB = $tw.utils.parseVersion(versionStringB) || defaultVersion,
diff = [
versionA.major - versionB.major,
versionA.minor - versionB.minor,
versionA.patch - versionB.patch
];
major: 0,
minor: 0,
patch: 0
},
versionA = $tw.utils.parseVersion(versionStringA) || defaultVersion,
versionB = $tw.utils.parseVersion(versionStringB) || defaultVersion,
diff = [
versionA.major - versionB.major,
versionA.minor - versionB.minor,
versionA.patch - versionB.patch
];
return (diff[0] > 0) ||
(diff[0] === 0 && diff[1] > 0) ||
(diff[0] === 0 && diff[1] === 0 && diff[2] > 0) ||
(diff[0] === 0 && diff[1] === 0 && diff[2] === 0);
(diff[0] === 0 && diff[1] === 0 && diff[2] > 0);
};
/*
@ -390,12 +397,20 @@ $tw.utils.registerFileType = function(type,encoding,extension,options) {
$tw.config.contentTypeInfo[type] = {encoding: encoding, extension: extension, flags: options.flags || [], deserializerType: options.deserializerType || type};
};
/*
Given an extension, always access the $tw.config.fileExtensionInfo
using a lowercase extension only.
*/
$tw.utils.getFileExtensionInfo = function(ext) {
return ext ? $tw.config.fileExtensionInfo[ext.toLowerCase()] : null;
}
/*
Given an extension, get the correct encoding for that file.
defaults to utf8
*/
$tw.utils.getTypeEncoding = function(ext) {
var extensionInfo = $tw.config.fileExtensionInfo[ext],
var extensionInfo = $tw.util.getFileExtensionInfo(ext),
type = extensionInfo ? extensionInfo.type : null,
typeInfo = type ? $tw.config.contentTypeInfo[type] : null;
return typeInfo ? typeInfo.encoding : "utf8";
@ -413,7 +428,7 @@ $tw.utils.evalGlobal = function(code,context,filename) {
contextValues.push(value);
});
// Add the code prologue and epilogue
code = "(function(" + contextNames.join(",") + ") {(function(){\n" + code + ";})();\nreturn exports;\n})\n";
code = "(function(" + contextNames.join(",") + ") {(function(){\n" + code + "\n;})();\nreturn exports;\n})\n";
// Compile the code into a function
var fn;
if($tw.browser) {
@ -930,7 +945,7 @@ $tw.Wiki = function(options) {
};
// Test for the existence of a tiddler
// Test for the existence of a tiddler (excludes shadow tiddlers)
this.tiddlerExists = function(title) {
return !!$tw.utils.hop(tiddlers,title);
};
@ -1130,9 +1145,9 @@ $tw.Wiki.prototype.deserializeTiddlers = function(type,text,srcFields) {
srcFields = srcFields || Object.create(null);
var deserializer = $tw.Wiki.tiddlerDeserializerModules[type],
fields = Object.create(null);
if(!deserializer && $tw.config.fileExtensionInfo[type]) {
if(!deserializer && $tw.utils.getFileExtensionInfo(type)) {
// If we didn't find the serializer, try converting it from an extension to a content type
type = $tw.config.fileExtensionInfo[type].type;
type = $tw.utils.getFileExtensionInfo(type).type;
deserializer = $tw.Wiki.tiddlerDeserializerModules[type];
}
if(!deserializer && $tw.config.contentTypeInfo[type]) {
@ -1379,7 +1394,7 @@ Load the tiddlers contained in a particular file (and optionally extract fields
*/
$tw.loadTiddlersFromFile = function(filepath,fields) {
var ext = path.extname(filepath),
extensionInfo = $tw.config.fileExtensionInfo[ext],
extensionInfo = $tw.utils.getFileExtensionInfo(ext),
type = extensionInfo ? extensionInfo.type : null,
typeInfo = type ? $tw.config.contentTypeInfo[type] : null,
data = fs.readFileSync(filepath,typeInfo ? typeInfo.encoding : "utf8"),
@ -1529,7 +1544,7 @@ $tw.getLibraryItemSearchPaths = function(libraryPath,envVar) {
var pluginPaths = [path.resolve($tw.boot.corePath,libraryPath)],
env = process.env[envVar];
if(env) {
Array.prototype.push.apply(pluginPaths,env.split(":"));
Array.prototype.push.apply(pluginPaths,env.split(path.delimiter));
}
return pluginPaths;
};
@ -1899,6 +1914,35 @@ $tw.boot.isStartupTaskEligible = function(taskModule) {
return true;
};
/*
Global Hooks mechanism which allows plugins to modify default functionality
*/
$tw.hooks = $tw.hooks || { names: {}};
/*
Add hooks to the hashmap
*/
$tw.hooks.addHook = function(hookName,definition) {
if($tw.utils.hop($tw.hooks.names,hookName)) {
$tw.hooks.names[hookName].push(definition);
}
else {
$tw.hooks.names[hookName] = [definition];
}
};
/*
Invoke the hook by key
*/
$tw.hooks.invokeHook = function(hookName, value) {
if($tw.utils.hop($tw.hooks.names,hookName)) {
for (var i = 0; i < $tw.hooks.names[hookName].length; i++) {
value = $tw.hooks.names[hookName][i](value);
}
}
return value;
};
/////////////////////////// Main boot function to decrypt tiddlers and then startup
$tw.boot.boot = function() {

View File

@ -20,9 +20,15 @@ $tw = $tw || Object.create(null);
$tw.boot = $tw.boot || Object.create(null);
// Detect platforms
$tw.browser = typeof(window) !== "undefined" ? {} : null;
$tw.node = typeof(process) === "object" ? {} : null;
$tw.nodeWebKit = $tw.node && global.window && global.window.nwDispatcher ? {} : null;
if(!("browser" in $tw)) {
$tw.browser = typeof(window) !== "undefined" ? {} : null;
}
if(!("node" in $tw)) {
$tw.node = typeof(process) === "object" ? {} : null;
}
if(!("nodeWebKit" in $tw)) {
$tw.nodeWebKit = $tw.node && global.window && global.window.nwDispatcher ? {} : null;
}
// Set default boot tasks
$tw.boot.tasks = {

View File

@ -3,7 +3,7 @@ title: $:/language/Buttons/
AdvancedSearch/Caption: advanced search
AdvancedSearch/Hint: Advanced search
Cancel/Caption: cancel
Cancel/Hint: Cancel editing this tiddler
Cancel/Hint: Discard changes to this tiddler
Clone/Caption: clone
Clone/Hint: Clone this tiddler
Close/Caption: close
@ -56,8 +56,8 @@ Permaview/Caption: permaview
Permaview/Hint: Set browser address bar to a direct link to all the tiddlers in this story
Refresh/Caption: refresh
Refresh/Hint: Perform a full refresh of the wiki
Save/Caption: save
Save/Hint: Save this tiddler
Save/Caption: ok
Save/Hint: Store changes to this tiddler
SaveWiki/Caption: save changes
SaveWiki/Hint: Save changes
StoryView/Caption: storyview

View File

@ -56,7 +56,7 @@ Saving/TiddlySpot/Backups: Backups
Saving/TiddlySpot/Description: These settings are only used when saving to http://tiddlyspot.com or a compatible remote server
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/Hint: //The server URL defaults to `http://<wikiname>.tiddlyspot.com/store.cgi` and can be changed to use a custom server address, e.g. `http://me.com/store.php`.//
Saving/TiddlySpot/Password: Password
Saving/TiddlySpot/ServerURL: Server URL
Saving/TiddlySpot/UploadDir: Upload Directory
@ -94,3 +94,5 @@ Toolbars/PageControls/Caption: Page Toolbar
Toolbars/PageControls/Hint: Choose which buttons are displayed on the main page toolbar
Toolbars/ViewToolbar/Caption: View Toolbar
Toolbars/ViewToolbar/Hint: Choose which buttons are displayed for tiddlers in view mode
Tools/Download/Full/Caption: Download full wiki

View File

@ -11,3 +11,4 @@ SystemTiddlers: System tiddlers
ShadowTiddlers: Shadow tiddlers
OverriddenShadowTiddlers: Overridden shadow tiddlers
SystemTags: System tags
TypedTiddlers: Non wiki-text tiddlers

View File

@ -1,13 +1,14 @@
title: GettingStarted
Welcome to TiddlyWiki, the non-linear personal web notebook.
\define lingo-base() $:/language/ControlPanel/Basics/
Welcome to ~TiddlyWiki and the ~TiddlyWiki community
To get started, first verify that you can save changes successfully - see http://tiddlywiki.com/ for detailed instructions.
Before you start storing important information in ~TiddlyWiki it is important to make sure that you can reliably save changes. See http://tiddlywiki.com/#GettingStarted for details
Then you can:
!! Set up this ~TiddlyWiki
* Create new tiddlers using the 'plus' button in the sidebar
* Visit the [[control panel|$:/ControlPanel]] using the 'cog' button in the sidebar to customise your wiki
** Stop this message appearing by changing the default tiddlers under the ''Basics'' tab
* Save changes using the 'download' button in the sidebar
* Learn more about [[WikiText|http://tiddlywiki.com/static/WikiText.html]]
|<$link to="$:/SiteTitle"><<lingo Title/Prompt>></$link> |<$edit-text tiddler="$:/SiteTitle" default="" tag="input"/> |
|<$link to="$:/SiteSubtitle"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler="$:/SiteSubtitle" default="" tag="input"/> |
|<$link to="$:/DefaultTiddlers"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit-text tag="textarea" tiddler="$:/DefaultTiddlers"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |
See the [[control panel|$:/ControlPanel]] for more options.

View File

@ -4,7 +4,7 @@ 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>]
--rendertiddlers <filter> <template> <pathname> [<type>] [<extension>] ["noclean"]
```
For example:
@ -15,4 +15,4 @@ For example:
By default, the pathname is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.
Any files in the target directory are deleted. The target directory is recursively created if it is missing.
Any files in the target directory are deleted unless the "noclean" parameter is specified. The target directory is recursively created if it is missing.

View File

@ -9,7 +9,7 @@ ConfirmDeleteTiddler: Do you wish to delete the tiddler "<$text text=<<title>>/>
ConfirmOverwriteTiddler: Do you wish to overwrite the tiddler "<$text text=<<title>>/>"?
ConfirmEditShadowTiddler: You are about to edit a ShadowTiddler. Any changes will override the default system making future upgrades non-trivial. Are you sure you want to edit "<$text text=<<title>>/>"?
DefaultNewTiddlerTitle: New Tiddler
DropMessage: Drop here (or click escape to cancel)
DropMessage: Drop here (or use the 'Escape' key to cancel)
Encryption/ConfirmClearPassword: Do you wish to clear the password? This will remove the encryption applied when saving this wiki
Encryption/PromptSetPassword: Set a new password for this TiddlyWiki
InvalidFieldName: Illegal characters in field name "<$text text=<<fieldName>>/>". Fields can only contain lowercase letters, digits and the characters underscore (`_`), hyphen (`-`) and period (`.`)

View File

@ -23,35 +23,12 @@ var Command = function(params,commander) {
};
Command.prototype.execute = function() {
var fs = require("fs"),
path = require("path"),
self = this;
// Enumerate the edition paths
var editionPaths = $tw.getLibraryItemSearchPaths($tw.config.editionsPath,$tw.config.editionsEnvVar),
editions = {};
for(var editionIndex=0; editionIndex<editionPaths.length; editionIndex++) {
var editionPath = editionPaths[editionIndex];
// Enumerate the folders
var entries = fs.readdirSync(editionPath);
for(var entryIndex=0; entryIndex<entries.length; entryIndex++) {
var entry = entries[entryIndex];
// Check if directories have a valid tiddlywiki.info
if(!editions[entry] && $tw.utils.isDirectory(path.resolve(editionPath,entry))) {
var info;
try {
info = JSON.parse(fs.readFileSync(path.resolve(editionPath,entry,"tiddlywiki.info"),"utf8"));
} catch(ex) {
}
if(info) {
editions[entry] = info.description || "";
}
}
}
}
var self = this;
// Output the list
this.commander.streams.output.write("Available editions:\n\n");
$tw.utils.each(editions,function(description,name) {
self.commander.streams.output.write(" " + name + ": " + description + "\n");
var editionInfo = $tw.utils.getEditionInfo();
$tw.utils.each(editionInfo,function(info,name) {
self.commander.streams.output.write(" " + name + ": " + info.description + "\n");
});
this.commander.streams.output.write("\n");
return null;

View File

@ -26,7 +26,7 @@ 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) {
if($tw.boot.wikiTiddlersPath || ($tw.utils.isDirectory($tw.boot.wikiPath) && !$tw.utils.isDirectoryEmpty($tw.boot.wikiPath))) {
return "Wiki folder is not empty";
}
// Loop through each of the specified editions

View File

@ -38,8 +38,11 @@ Command.prototype.execute = function() {
pathname = path.resolve(this.commander.outputPath,this.params[2]),
type = this.params[3] || "text/html",
extension = this.params[4] || ".html",
deleteDirectory = (this.params[5] || "") != "noclean",
tiddlers = wiki.filterTiddlers(filter);
$tw.utils.deleteDirectory(pathname);
if(deleteDirectory){
$tw.utils.deleteDirectory(pathname);
}
$tw.utils.createDirectory(pathname);
$tw.utils.each(tiddlers,function(title) {
var parser = wiki.parseTiddler(template),

View File

@ -17,6 +17,19 @@ exports.preferences = {};
exports.preferences.notificationDuration = 3 * 1000;
exports.preferences.jsonSpaces = 4;
exports.textPrimitives = {
upperLetter: "[A-Z\u00c0-\u00d6\u00d8-\u00de\u0150\u0170]",
lowerLetter: "[a-z\u00df-\u00f6\u00f8-\u00ff\u0151\u0171]",
anyLetter: "[A-Za-z0-9\u00c0-\u00d6\u00d8-\u00de\u00df-\u00f6\u00f8-\u00ff\u0150\u0170\u0151\u0171]",
blockPrefixLetters: "[A-Za-z0-9-_\u00c0-\u00d6\u00d8-\u00de\u00df-\u00f6\u00f8-\u00ff\u0150\u0170\u0151\u0171]"
};
exports.textPrimitives.unWikiLink = "~";
exports.textPrimitives.wikiLink = exports.textPrimitives.upperLetter + "+" +
exports.textPrimitives.lowerLetter + "+" +
exports.textPrimitives.upperLetter +
exports.textPrimitives.anyLetter + "*";
exports.htmlEntities = {quot:34, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 };
exports.htmlVoidElements = "area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",");

View File

@ -13,8 +13,8 @@ Adds tiddler filtering methods to the $tw.Wiki object.
"use strict";
/*
Parses an operation within a filter string
results: Array of array of operator nodes into which results should be inserted
Parses an operation (i.e. a run) within a filter string
operators: Array of array of operator nodes into which results should be inserted
filterString: filter string
p: start position within the string
Returns the new start position, after the parsed operation
@ -108,7 +108,7 @@ exports.parseFilter = function(filterString) {
p = 0, // Current position in the filter string
match;
var whitespaceRegExp = /(\s+)/mg,
operandRegExp = /((?:\+|\-)?)(?:(\[)|("(?:[^"])*")|('(?:[^'])*')|([^\s\[\]]+))/mg;
operandRegExp = /((?:\+|\-)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
while(p < filterString.length) {
// Skip any whitespace
whitespaceRegExp.lastIndex = p;
@ -202,6 +202,7 @@ exports.compileFilter = function(filterString) {
if(operator.variable) {
operand = widget.getVariable(operator.operand,{defaultValue: ""});
}
// Invoke the appropriate filteroperator module
results = operatorFunction(accumulator,{
operator: operator.operator,
operand: operand,

View File

@ -0,0 +1,31 @@
/*\
title: $:/core/modules/filters/editiondescription.js
type: application/javascript
module-type: filteroperator
Filter operator for returning the descriptions of the specified edition names
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.editiondescription = function(source,operator,options) {
var results = [],
editionInfo = $tw.utils.getEditionInfo();
if(editionInfo) {
source(function(tiddler,title) {
if($tw.utils.hop(editionInfo,title)) {
results.push(editionInfo[title].description || "");
}
});
}
return results;
};
})();

View File

@ -0,0 +1,30 @@
/*\
title: $:/core/modules/filters/editions.js
type: application/javascript
module-type: filteroperator
Filter operator for returning the names of the available editions in this wiki
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.editions = function(source,operator,options) {
var results = [],
editionInfo = $tw.utils.getEditionInfo();
if(editionInfo) {
$tw.utils.each(editionInfo,function(info,name) {
results.push(name);
});
}
results.sort();
return results;
};
})();

View File

@ -26,6 +26,8 @@ exports.field = function(source,operator,options) {
if(text !== null && !operator.regexp.exec(text)) {
results.push(title);
}
} else {
results.push(title);
}
});
} else {
@ -35,6 +37,8 @@ exports.field = function(source,operator,options) {
if(text !== null && text !== operator.operand) {
results.push(title);
}
} else {
results.push(title);
}
});
}

View File

@ -19,7 +19,7 @@ exports.has = function(source,operator,options) {
var results = [];
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(tiddler && (!$tw.utils.hop(tiddler.fields,operator.operand) || tiddler.fields[operator.operand] === "")) {
if(!tiddler || (tiddler && (!$tw.utils.hop(tiddler.fields,operator.operand) || tiddler.fields[operator.operand] === ""))) {
results.push(title);
}
});

View File

@ -41,7 +41,11 @@ exports.regexp = function(source,operator,options) {
regexpString = regexpString.substr(0,regexpString.length - match[0].length);
}
}
regexp = new RegExp(regexpString,flags);
try {
regexp = new RegExp(regexpString,flags);
} catch(e) {
return ["" + e];
}
// Process the incoming tiddlers
if(operator.prefix === "!") {
source(function(tiddler,title) {

View File

@ -0,0 +1,31 @@
/*\
title: $:/core/modules/filters/splitbefore.js
type: application/javascript
module-type: filteroperator
Filter operator that splits each result on the first occurance of the specified separator and returns the unique values.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.splitbefore = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var parts = title.split(operator.operand);
if(parts.length === 1) {
$tw.utils.pushTop(results,parts[0]);
} else {
$tw.utils.pushTop(results,parts[0] + operator.operand);
}
});
return results;
};
})();

View File

@ -0,0 +1,29 @@
/*\
title: $:/core/modules/macros/resolvepath.js
type: application/javascript
module-type: macro
Resolves a relative path for an absolute rootpath.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.name = "resolvepath";
exports.params = [
{name: "source"},
{name: "root"}
];
/*
Run the macro
*/
exports.run = function(source, root) {
return $tw.utils.resolvePath(source, root);
};
})();

View File

@ -23,7 +23,8 @@ var HtmlParser = function(type,text,options) {
type: "element",
tag: "iframe",
attributes: {
src: {type: "string", value: src}
src: {type: "string", value: src},
sandbox: {type: "string", value: "sandbox"}
}
}];
};

View File

@ -58,7 +58,7 @@ exports.parse = function() {
var reEnd;
if(this.match[3]) {
// If so, the end of the body is marked with \end
reEnd = /(\r?\n\\end(?:$|\r?\n))/mg;
reEnd = /(\r?\n\\end[^\S\n\r]*(?:$|\r?\n))/mg;
} else {
// Otherwise, the end of the definition is marked by the end of the line
reEnd = /(\r?\n)/mg;

View File

@ -27,18 +27,13 @@ exports.init = function(parser) {
this.matchRegExp = /\[\[(.*?)(?:\|(.*?))?\]\]/mg;
};
var isLinkExternal = function(to) {
var externalRegExp = /(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\s<>{}\[\]`|'"\\^~]+(?:\/|\b)/i;
return externalRegExp.test(to);
};
exports.parse = function() {
// Move past the match
this.parser.pos = this.matchRegExp.lastIndex;
// Process the link
var text = this.match[1],
link = this.match[2] || text;
if(isLinkExternal(link)) {
if($tw.utils.isLinkExternal(link)) {
return [{
type: "element",
tag: "a",

View File

@ -0,0 +1,45 @@
/*\
title: $:/core/modules/parsers/wikiparser/rules/syslink.js
type: application/javascript
module-type: wikirule
Wiki text inline rule for system tiddler links.
Can be suppressed preceding them with `~`.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.name = "syslink";
exports.types = {inline: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /~?\$:[^\s<|]+(?:[^\s<|])/mg;
};
exports.parse = function() {
var match = this.match[0];
// Move past the match
this.parser.pos = this.matchRegExp.lastIndex;
// Create the link unless it is suppressed
if(match.substr(0,1) === "~") {
return [{type: "text", text: match.substr(1)}];
} else {
return [{
type: "link",
attributes: {
to: {type: "string", value: match}
},
children: [{
type: "text",
text: match
}]
}];
}
};
})();

View File

@ -23,23 +23,10 @@ Precede a camel case word with `~` to prevent it from being recognised as a link
exports.name = "wikilink";
exports.types = {inline: true};
var textPrimitives = {
upperLetter: "[A-Z\u00c0-\u00d6\u00d8-\u00de\u0150\u0170]",
lowerLetter: "[a-z\u00df-\u00f6\u00f8-\u00ff\u0151\u0171]",
anyLetter: "[A-Za-z0-9\u00c0-\u00d6\u00d8-\u00de\u00df-\u00f6\u00f8-\u00ff\u0150\u0170\u0151\u0171]",
blockPrefixLetters: "[A-Za-z0-9-_\u00c0-\u00d6\u00d8-\u00de\u00df-\u00f6\u00f8-\u00ff\u0150\u0170\u0151\u0171]"
};
textPrimitives.unWikiLink = "~";
textPrimitives.wikiLink = textPrimitives.upperLetter + "+" +
textPrimitives.lowerLetter + "+" +
textPrimitives.upperLetter +
textPrimitives.anyLetter + "*";
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = new RegExp(textPrimitives.unWikiLink + "?" + textPrimitives.wikiLink,"mg");
this.matchRegExp = new RegExp($tw.config.textPrimitives.unWikiLink + "?" + $tw.config.textPrimitives.wikiLink,"mg");
};
/*
@ -51,12 +38,12 @@ exports.parse = function() {
// Move past the macro call
this.parser.pos = this.matchRegExp.lastIndex;
// If the link starts with the unwikilink character then just output it as plain text
if(linkText.substr(0,1) === textPrimitives.unWikiLink) {
if(linkText.substr(0,1) === $tw.config.textPrimitives.unWikiLink) {
return [{type: "text", text: linkText.substr(1)}];
}
// If the link has been preceded with a blocked letter then don't treat it as a link
if(this.match.index > 0) {
var preRegExp = new RegExp(textPrimitives.blockPrefixLetters,"mg");
var preRegExp = new RegExp($tw.config.textPrimitives.blockPrefixLetters,"mg");
preRegExp.lastIndex = this.match.index-1;
var preMatch = preRegExp.exec(this.parser.source);
if(preMatch && preMatch.index === this.match.index-1) {

View File

@ -75,14 +75,14 @@ function SaverHandler(options) {
}
});
// Set up our beforeunload handler
window.addEventListener("beforeunload",function(event) {
window.onbeforeunload = function(event) {
var confirmationMessage;
if(self.isDirty()) {
confirmationMessage = $tw.language.getString("UnsavedChangesWarning");
event.returnValue = confirmationMessage; // Gecko
}
return confirmationMessage;
});
};
}
// Install the save action handlers
if($tw.browser) {

View File

@ -26,10 +26,11 @@ DownloadSaver.prototype.save = function(text,method,callback,options) {
var p = document.location.pathname.lastIndexOf("/");
if(p !== -1) {
filename = document.location.pathname.substr(p+1);
} else {
filename = "tiddlywiki.html";
}
}
if(!filename) {
filename = "tiddlywiki.html";
}
// Set up the link
var link = document.createElement("a");
link.setAttribute("target","_blank");

View File

@ -19,7 +19,7 @@ exports.synchronous = true;
exports.startup = function() {
// Load modules
$tw.modules.applyMethods("utils",$tw.utils);
if($tw.node && !$tw.browser) {
if($tw.node) {
$tw.modules.applyMethods("utils-node",$tw.utils);
}
$tw.modules.applyMethods("global",$tw);

View File

@ -62,7 +62,7 @@ exports.startup = function() {
timerId;
function refresh() {
// Process the refresh
$tw.pageWidgetNode.refresh(deferredChanges,$tw.pageContainer,null);
$tw.pageWidgetNode.refresh(deferredChanges);
deferredChanges = Object.create(null);
}
// Add the change event handler

View File

@ -78,9 +78,7 @@ exports.startup = function() {
// Host-specific startup
if($tw.browser) {
// Install the popup manager
$tw.popup = new $tw.utils.Popup({
rootElement: document.body
});
$tw.popup = new $tw.utils.Popup();
// Install the animator
$tw.anim = new $tw.utils.Animator();
}

View File

@ -58,6 +58,8 @@ exports.startup = function() {
window.location.hash = "";
var storyFilter = $tw.wiki.getTiddlerText(DEFAULT_TIDDLERS_TITLE),
storyList = $tw.wiki.filterTiddlers(storyFilter);
//invoke any hooks that might change the default story list
storyList = $tw.hooks.invokeHook("th-opening-default-tiddlers-list",storyList);
$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: "", list: storyList},$tw.wiki.getModificationFields());
if(storyList[0]) {
$tw.wiki.addToHistory(storyList[0]);
@ -116,6 +118,8 @@ function openStartupTiddlers(options) {
}
// Process the story filter to get the story list
var storyList = $tw.wiki.filterTiddlers(storyFilter);
//invoke any hooks that might change the default story list
storyList = $tw.hooks.invokeHook("th-opening-default-tiddlers-list",storyList);
// If the target tiddler isn't included then splice it in at the top
if(target && storyList.indexOf(target) === -1) {
storyList.unshift(target);

View File

@ -39,14 +39,14 @@ function Syncer(options) {
// Browser event handlers
if($tw.browser) {
// Set up our beforeunload handler
window.addEventListener("beforeunload",function(event) {
window.onbeforeunload = function(event) {
var confirmationMessage;
if(self.isDirty()) {
confirmationMessage = $tw.language.getString("UnsavedChangesWarning");
event.returnValue = confirmationMessage; // Gecko
}
return confirmationMessage;
});
};
// Listen out for login/logout/refresh events in the browser
$tw.rootWidget.addEventListener("tm-login",function() {
self.handleLoginEvent();

View File

@ -15,6 +15,9 @@ Upgrader module that checks that plugins are newer than any already installed ve
var UPGRADE_LIBRARY_TITLE = "$:/UpgradeLibrary";
var BLOCKED_PLUGINS = {
"$:/themes/tiddlywiki/stickytitles": {
versions: ["*"]
},
"$:/plugins/tiddlywiki/fullscreen": {
versions: ["*"]
}

View File

@ -148,9 +148,13 @@ exports.getFullScreenApis = function() {
"_fullscreenElement": d.webkitFullscreenElement !== undefined ? "webkitFullscreenElement" :
d.mozFullScreenElement !== undefined ? "mozFullScreenElement" :
d.msFullscreenElement !== undefined ? "msFullscreenElement" :
d.fullscreenElement !== undefined ? "fullscreenElement" : ""
d.fullscreenElement !== undefined ? "fullscreenElement" : "",
"_fullscreenChange": d.webkitFullscreenElement !== undefined ? "webkitfullscreenchange" :
d.mozFullScreenElement !== undefined ? "mozfullscreenchange" :
d.msFullscreenElement !== undefined ? "MSFullscreenChange" :
d.fullscreenElement !== undefined ? "fullscreenchange" : ""
};
if(!result._requestFullscreen || !result._exitFullscreen || !result._fullscreenElement) {
if(!result._requestFullscreen || !result._exitFullscreen || !result._fullscreenElement || !result._fullscreenChange) {
return null;
} else {
return result;

View File

@ -18,41 +18,8 @@ Creates a Popup object with these options:
*/
var Popup = function(options) {
options = options || {};
this.rootElement = options.rootElement || document.body;
};
Popup.prototype.show = function(options) {
this.cancel();
this.title = options.title;
this.wiki = options.wiki;
this.anchorDomNode = options.domNode;
$tw.utils.addClass(this.anchorDomNode,"tc-popup");
this.rootElement.addEventListener("click",this,false);
};
Popup.prototype.handleEvent = function(event) {
// Dismiss the popup if we get a click on an element that doesn't have .tc-popup class
if(event.type === "click") {
var node = event.target;
while(node && !$tw.utils.hasClass(node,"tc-popup")) {
node = node.parentNode;
}
if(!node) {
this.cancel();
}
}
};
Popup.prototype.cancel = function() {
if(this.anchorDomNode) {
$tw.utils.removeClass(this.anchorDomNode,"tc-popup");
this.anchorDomNode = null;
}
this.rootElement.removeEventListener("click",this,false);
if(this.title) {
this.wiki.deleteTiddler(this.title);
this.title = null;
}
this.rootElement = options.rootElement || document.documentElement;
this.popups = []; // Array of {title:,wiki:,domNode:} objects
};
/*
@ -60,38 +27,126 @@ Trigger a popup open or closed. Parameters are in a hashmap:
title: title of the tiddler where the popup details are stored
domNode: dom node to which the popup will be positioned
wiki: wiki
force: if specified, forces the popup state to true or false
force: if specified, forces the popup state to true or false (instead of toggling it)
*/
Popup.prototype.triggerPopup = function(options) {
// Get the current popup state tiddler
var value = options.wiki.getTextReference(options.title,"");
// Check if the popup is open by checking whether it matches "(<x>,<y>)"
var state = !this.readPopupState(options.title,value);
if("force" in options) {
// Check if this popup is already active
var index = -1;
for(var t=0; t<this.popups.length; t++) {
if(this.popups[t].title === options.title) {
index = t;
}
}
// Compute the new state
var state = index === -1;
if(options.force !== undefined) {
state = options.force;
}
// Show or cancel the popup according to the new state
if(state) {
// Set the position if we're opening it
this.cancel();
options.wiki.setTextReference(options.title,
"(" + options.domNode.offsetLeft + "," + options.domNode.offsetTop + "," +
options.domNode.offsetWidth + "," + options.domNode.offsetHeight + ")");
this.show(options);
} else {
this.cancel();
this.cancel(index);
}
};
Popup.prototype.handleEvent = function(event) {
if(event.type === "click") {
// Find out what was clicked on
var info = this.popupInfo(event.target),
cancelLevel = info.popupLevel - 1;
// Don't remove the level that was clicked on if we clicked on a handle
if(info.isHandle) {
cancelLevel++;
}
// Cancel
this.cancel(cancelLevel);
}
};
/*
Find the popup level containing a DOM node. Returns:
popupLevel: count of the number of nested popups containing the specified element
isHandle: true if the specified element is within a popup handle
*/
Popup.prototype.popupInfo = function(domNode) {
var isHandle = false,
popupCount = 0,
node = domNode;
// First check ancestors to see if we're within a popup handle
while(node) {
if($tw.utils.hasClass(node,"tc-popup-handle")) {
isHandle = true;
popupCount++;
}
if($tw.utils.hasClass(node,"tc-popup-keep")) {
isHandle = true;
}
node = node.parentNode;
}
// Then count the number of ancestor popups
node = domNode;
while(node) {
if($tw.utils.hasClass(node,"tc-popup")) {
popupCount++;
}
node = node.parentNode;
}
var info = {
popupLevel: popupCount,
isHandle: isHandle
};
return info;
};
/*
Display a popup by adding it to the stack
*/
Popup.prototype.show = function(options) {
// Find out what was clicked on
var info = this.popupInfo(options.domNode);
// Cancel any higher level popups
this.cancel(info.popupLevel);
// Store the popup details
this.popups.push({
title: options.title,
wiki: options.wiki,
domNode: options.domNode
});
// Set the state tiddler
options.wiki.setTextReference(options.title,
"(" + options.domNode.offsetLeft + "," + options.domNode.offsetTop + "," +
options.domNode.offsetWidth + "," + options.domNode.offsetHeight + ")");
// Add the click handler if we have any popups
if(this.popups.length > 0) {
this.rootElement.addEventListener("click",this,true);
}
};
/*
Cancel all popups at or above a specified level or DOM node
level: popup level to cancel (0 cancels all popups)
*/
Popup.prototype.cancel = function(level) {
var numPopups = this.popups.length;
level = Math.max(0,Math.min(level,numPopups));
for(var t=level; t<numPopups; t++) {
var popup = this.popups.pop();
if(popup.title) {
popup.wiki.deleteTiddler(popup.title);
}
}
if(this.popups.length === 0) {
this.rootElement.removeEventListener("click",this,false);
}
};
/*
Returns true if the specified title and text identifies an active popup
*/
Popup.prototype.readPopupState = function(title,text) {
var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/,
result = false;
if(this.title === title) {
result = popupLocationRegExp.test(text);
}
return result;
Popup.prototype.readPopupState = function(text) {
var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/;
return popupLocationRegExp.test(text);
};
exports.Popup = Popup;

View File

@ -0,0 +1,48 @@
/*\
title: $:/core/modules/utils/edition-info.js
type: application/javascript
module-type: utils-node
Information about the available editions
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var fs = require("fs"),
path = require("path");
var editionInfo;
exports.getEditionInfo = function() {
if(!editionInfo) {
// Enumerate the edition paths
var editionPaths = $tw.getLibraryItemSearchPaths($tw.config.editionsPath,$tw.config.editionsEnvVar);
editionInfo = {};
for(var editionIndex=0; editionIndex<editionPaths.length; editionIndex++) {
var editionPath = editionPaths[editionIndex];
// Enumerate the folders
var entries = fs.readdirSync(editionPath);
for(var entryIndex=0; entryIndex<entries.length; entryIndex++) {
var entry = entries[entryIndex];
// Check if directories have a valid tiddlywiki.info
if(!editionInfo[entry] && $tw.utils.isDirectory(path.resolve(editionPath,entry))) {
var info;
try {
info = JSON.parse(fs.readFileSync(path.resolve(editionPath,entry,"tiddlywiki.info"),"utf8"));
} catch(ex) {
}
if(info) {
editionInfo[entry] = info;
}
}
}
}
}
return editionInfo;
};
})();

View File

@ -52,9 +52,13 @@ exports.copyDirectory = function(srcPath,dstPath) {
Copy a file
*/
var FILE_BUFFER_LENGTH = 64 * 1024,
fileBuffer = $tw.node && new Buffer(FILE_BUFFER_LENGTH);
fileBuffer;
exports.copyFile = function(srcPath,dstPath) {
// Create buffer if required
if(!fileBuffer) {
fileBuffer = new Buffer(FILE_BUFFER_LENGTH);
}
// Create any directories in the destination
$tw.utils.createDirectory(path.dirname(dstPath));
// Copy the file
@ -139,4 +143,21 @@ exports.isDirectory = function(dirPath) {
return fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();
};
/*
Check if a path identifies a directory that is empty
*/
exports.isDirectoryEmpty = function(dirPath) {
if(!$tw.utils.isDirectory(dirPath)) {
return false;
}
var files = fs.readdirSync(dirPath),
empty = true;
$tw.utils.each(files,function(file,index) {
if(file.charAt(0) !== ".") {
empty = false;
}
});
return empty;
};
})();

View File

@ -176,89 +176,109 @@ exports.slowInSlowOut = function(t) {
};
exports.formatDateString = function(date,template) {
var t = template;
t = t.replace(/0hh12/g,function() {
return $tw.utils.pad($tw.utils.getHours12(date));
});
t = t.replace(/hh12/g,function() {
return $tw.utils.getHours12(date);
});
t = t.replace(/0hh/g,function() {
return $tw.utils.pad(date.getHours());
});
t = t.replace(/hh/g,function() {
return date.getHours();
});
t = t.replace(/mmm/g,function() {
return $tw.language.getString("Date/Short/Month/" + (date.getMonth() + 1));
});
t = t.replace(/0mm/g,function() {
return $tw.utils.pad(date.getMinutes());
});
t = t.replace(/mm/g,function() {
return date.getMinutes();
});
t = t.replace(/0ss/g,function() {
return $tw.utils.pad(date.getSeconds());
});
t = t.replace(/ss/g,function() {
return date.getSeconds();
});
t = t.replace(/[ap]m/g,function() {
return $tw.utils.getAmPm(date).toLowerCase();
});
t = t.replace(/[AP]M/g,function() {
return $tw.utils.getAmPm(date).toUpperCase();
});
t = t.replace(/wYYYY/g,function() {
return $tw.utils.getYearForWeekNo(date);
});
t = t.replace(/wYY/g,function() {
return $tw.utils.pad($tw.utils.getYearForWeekNo(date)-2000);
});
t = t.replace(/YYYY/g,function() {
return date.getFullYear();
});
t = t.replace(/YY/g,function() {
return $tw.utils.pad(date.getFullYear()-2000);
});
t = t.replace(/MMM/g,function() {
return $tw.language.getString("Date/Long/Month/" + (date.getMonth() + 1));
});
t = t.replace(/0MM/g,function() {
return $tw.utils.pad(date.getMonth()+1);
});
t = t.replace(/MM/g,function() {
return date.getMonth() + 1;
});
t = t.replace(/0WW/g,function() {
return $tw.utils.pad($tw.utils.getWeek(date));
});
t = t.replace(/WW/g,function() {
return $tw.utils.getWeek(date);
});
t = t.replace(/DDD/g,function() {
return $tw.language.getString("Date/Long/Day/" + date.getDay());
});
t = t.replace(/ddd/g,function() {
return $tw.language.getString("Date/Short/Day/" + date.getDay());
});
t = t.replace(/0DD/g,function() {
return $tw.utils.pad(date.getDate());
});
t = t.replace(/DDth/g,function() {
return date.getDate() + $tw.utils.getDaySuffix(date);
});
t = t.replace(/DD/g,function() {
return date.getDate();
});
t = t.replace(/TZD/g,function() {
var tz = date.getTimezoneOffset(),
atz = Math.abs(tz);
return (tz < 0 ? '+' : '-') + $tw.utils.pad(Math.floor(atz / 60)) + ':' + $tw.utils.pad(atz % 60);
});
t = t.replace(/\\(.)/g,"$1");
return t;
var result = "",
t = template,
matches = [
[/^0hh12/, function() {
return $tw.utils.pad($tw.utils.getHours12(date));
}],
[/^wYYYY/, function() {
return $tw.utils.getYearForWeekNo(date);
}],
[/^hh12/, function() {
return $tw.utils.getHours12(date);
}],
[/^DDth/, function() {
return date.getDate() + $tw.utils.getDaySuffix(date);
}],
[/^YYYY/, function() {
return date.getFullYear();
}],
[/^0hh/, function() {
return $tw.utils.pad(date.getHours());
}],
[/^0mm/, function() {
return $tw.utils.pad(date.getMinutes());
}],
[/^0ss/, function() {
return $tw.utils.pad(date.getSeconds());
}],
[/^0DD/, function() {
return $tw.utils.pad(date.getDate());
}],
[/^0MM/, function() {
return $tw.utils.pad(date.getMonth()+1);
}],
[/^0WW/, function() {
return $tw.utils.pad($tw.utils.getWeek(date));
}],
[/^ddd/, function() {
return $tw.language.getString("Date/Short/Day/" + date.getDay());
}],
[/^mmm/, function() {
return $tw.language.getString("Date/Short/Month/" + (date.getMonth() + 1));
}],
[/^DDD/, function() {
return $tw.language.getString("Date/Long/Day/" + date.getDay());
}],
[/^MMM/, function() {
return $tw.language.getString("Date/Long/Month/" + (date.getMonth() + 1));
}],
[/^TZD/, function() {
var tz = date.getTimezoneOffset(),
atz = Math.abs(tz);
return (tz < 0 ? '+' : '-') + $tw.utils.pad(Math.floor(atz / 60)) + ':' + $tw.utils.pad(atz % 60);
}],
[/^wYY/, function() {
return $tw.utils.pad($tw.utils.getYearForWeekNo(date) - 2000);
}],
[/^[ap]m/, function() {
return $tw.utils.getAmPm(date).toLowerCase();
}],
[/^hh/, function() {
return date.getHours();
}],
[/^mm/, function() {
return date.getMinutes();
}],
[/^ss/, function() {
return date.getSeconds();
}],
[/^[AP]M/, function() {
return $tw.utils.getAmPm(date).toUpperCase();
}],
[/^DD/, function() {
return date.getDate();
}],
[/^MM/, function() {
return date.getMonth() + 1;
}],
[/^WW/, function() {
return $tw.utils.getWeek(date);
}],
[/^YY/, function() {
return $tw.utils.pad(date.getFullYear() - 2000);
}]
];
while(t.length){
var matchString = "";
$tw.utils.each(matches, function(m) {
var match = m[0].exec(t);
if(match) {
matchString = m[1].call();
t = t.substr(match[0].length);
return false;
}
});
if(matchString) {
result += matchString;
} else {
result += t.charAt(0);
t = t.substr(1);
}
}
result = result.replace(/\\(.)/g,"$1");
return result;
};
exports.getAmPm = function(date) {
@ -419,9 +439,15 @@ exports.escapeRegExp = function(s) {
return s.replace(/[\-\/\\\^\$\*\+\?\.\(\)\|\[\]\{\}]/g, '\\$&');
};
// Checks whether a link target is external, i.e. not a tiddler title
exports.isLinkExternal = function(to) {
var externalRegExp = /(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\s<>{}\[\]`|'"\\^~]+(?:\/|\b)/i;
return externalRegExp.test(to);
};
exports.nextTick = function(fn) {
/*global window: false */
if(typeof window !== "undefined") {
if(typeof process === "undefined") {
// Apparently it would be faster to use postMessage - http://dbaron.org/log/20100309-faster-timeouts
window.setTimeout(fn,4);
} else {
@ -461,21 +487,31 @@ Returns an object with the following fields, all optional:
*/
exports.parseTextReference = function(textRef) {
// Separate out the title, field name and/or JSON indices
var reTextRef = /^\s*([^!#]+)?(?:(?:!!([^\s]+))|(?:##(.+)))?\s*/mg,
match = reTextRef.exec(textRef);
var reTextRef = /(?:(.*?)!!(.+))|(?:(.*?)##(.+))|(.*)/mg,
match = reTextRef.exec(textRef),
result = {};
if(match && reTextRef.lastIndex === textRef.length) {
// Return the parts
return {
title: match[1],
field: match[2],
index: match[3]
};
if(match[1]) {
result.title = match[1];
}
if(match[2]) {
result.field = match[2];
}
if(match[3]) {
result.title = match[3];
}
if(match[4]) {
result.index = match[4];
}
if(match[5]) {
result.title = match[5];
}
} else {
// If we couldn't parse it (eg it started with a)
return {
title: textRef
};
// If we couldn't parse it
result.title = textRef
}
return result;
};
/*
@ -494,29 +530,22 @@ exports.isValidFieldName = function(name) {
Extract the version number from the meta tag or from the boot file
*/
if($tw.browser) {
// Browser version
exports.extractVersionInfo = function() {
var metatags = document.getElementsByTagName("meta");
for(var t=0; t<metatags.length; t++) {
var m = metatags[t];
if(m.name === "tiddlywiki-version") {
return m.content;
if($tw.packageInfo) {
return $tw.packageInfo.version;
} else {
var metatags = document.getElementsByTagName("meta");
for(var t=0; t<metatags.length; t++) {
var m = metatags[t];
if(m.name === "tiddlywiki-version") {
return m.content;
}
}
}
return null;
};
} else {
// Server version
exports.extractVersionInfo = function() {
return $tw.packageInfo.version;
};
}
/*
Get the animation duration in ms
*/
@ -577,4 +606,4 @@ exports.timer = function(base) {
return m;
};
})();
})();

View File

@ -58,7 +58,7 @@ Invoke the action associated with this widget
*/
SetFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {
var self = this;
if(this.actionValue) {
if(typeof this.actionValue === "string") {
this.wiki.setText(this.actionTiddler,this.actionField,this.actionIndex,this.actionValue);
}
$tw.utils.each(this.attributes,function(attribute,name) {

View File

@ -39,10 +39,16 @@ BrowseWidget.prototype.render = function(parent,nextSibling) {
if(this.browseMultiple) {
domNode.setAttribute("multiple","multiple");
}
if(this.tooltip) {
domNode.setAttribute("title",this.tooltip);
}
if(this.nwsaveas) {
domNode.setAttribute("nwsaveas",this.nwsaveas);
}
// Add a click event handler
domNode.addEventListener("change",function (event) {
if(self.message) {
self.dispatchEvent({type: self.message, param: event.target.files});
self.dispatchEvent({type: self.message, param: self.param, files: event.target.files});
} else {
self.wiki.readFiles(event.target.files,function(tiddlerFieldsArray) {
self.dispatchEvent({type: "tm-import-tiddlers", param: JSON.stringify(tiddlerFieldsArray)});
@ -62,6 +68,9 @@ Compute the internal state of the widget
BrowseWidget.prototype.execute = function() {
this.browseMultiple = this.getAttribute("multiple");
this.message = this.getAttribute("message");
this.param = this.getAttribute("param");
this.tooltip = this.getAttribute("tooltip");
this.nwsaveas = this.getAttribute("nwsaveas");
};
/*

View File

@ -36,15 +36,19 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
// Create element
var domNode = this.document.createElement("button");
// Assign classes
var classes = this["class"].split(" ") || [];
var classes = this["class"].split(" ") || [],
isPoppedUp = this.popup && this.isPoppedUp();
if(this.selectedClass) {
if(this.set && this.setTo && this.isSelected()) {
$tw.utils.pushTop(classes,this.selectedClass.split(" "));
}
if(this.popup && this.isPoppedUp()) {
if(isPoppedUp) {
$tw.utils.pushTop(classes,this.selectedClass.split(" "));
}
}
if(isPoppedUp) {
$tw.utils.pushTop(classes,"tc-popup-handle");
}
domNode.className = classes.join(" ");
// Assign other attributes
if(this.style) {
@ -101,7 +105,7 @@ ButtonWidget.prototype.isSelected = function() {
ButtonWidget.prototype.isPoppedUp = function() {
var tiddler = this.wiki.getTiddler(this.popup);
var result = tiddler && tiddler.fields.text ? $tw.popup.readPopupState(this.popup,tiddler.fields.text) : false;
var result = tiddler && tiddler.fields.text ? $tw.popup.readPopupState(tiddler.fields.text) : false;
return result;
};

View File

@ -80,7 +80,9 @@ EditBitmapWidget.prototype.render = function(parent,nextSibling) {
parent.insertBefore(this.heightDomNode,nextSibling);
this.domNodes.push(this.canvasDomNode,this.widthDomNode,this.heightDomNode);
// Load the image into the canvas
this.loadCanvas();
if($tw.browser) {
this.loadCanvas();
}
};
/*

View File

@ -71,6 +71,13 @@ EditTextWidget.prototype.render = function(parent,nextSibling) {
}
// Fix height
this.fixHeight();
// Focus field
if(this.editFocus === "true") {
if(domNode.focus && domNode.select) {
domNode.focus();
domNode.select();
}
}
};
/*
@ -140,6 +147,7 @@ EditTextWidget.prototype.execute = function() {
this.editAutoHeight = this.getAttribute("autoHeight","yes") === "yes";
this.editMinHeight = this.getAttribute("minHeight",DEFAULT_MIN_TEXT_AREA_HEIGHT);
this.editFocusPopup = this.getAttribute("focusPopup");
this.editFocus = this.getAttribute("focus");
// Get the editor element tag and type
var tag,type;
if(this.editField === "text") {

View File

@ -71,24 +71,40 @@ FieldManglerWidget.prototype.handleRemoveFieldEvent = function(event) {
};
FieldManglerWidget.prototype.handleAddFieldEvent = function(event) {
var tiddler = this.wiki.getTiddler(this.mangleTitle);
if(tiddler && typeof event.param === "string") {
var name = event.param.toLowerCase().trim();
if(name !== "" && !$tw.utils.hop(tiddler.fields,name)) {
if(!$tw.utils.isValidFieldName(name)) {
alert($tw.language.getString(
"InvalidFieldName",
{variables:
{fieldName: name}
}
));
return true;
var tiddler = this.wiki.getTiddler(this.mangleTitle),
addition = this.wiki.getModificationFields(),
hadInvalidFieldName = false,
addField = function(name,value) {
var trimmedName = name.toLowerCase().trim();
if(!$tw.utils.isValidFieldName(trimmedName)) {
if(!hadInvalidFieldName) {
alert($tw.language.getString(
"InvalidFieldName",
{variables:
{fieldName: trimmedName}
}
));
hadInvalidFieldName = true;
return;
}
} else {
if(!value && tiddler) {
value = tiddler.fields[trimmedName];
}
addition[trimmedName] = value || "";
}
var addition = this.wiki.getModificationFields();
addition[name] = "";
this.wiki.addTiddler(new $tw.Tiddler(tiddler,addition));
return;
};
addition.title = this.mangleTitle;
if(typeof event.param === "string") {
addField(event.param,"");
}
if(typeof event.paramObject === "object") {
for(var name in event.paramObject) {
addField(name,event.paramObject[name]);
}
}
this.wiki.addTiddler(new $tw.Tiddler(tiddler,addition));
return true;
};

View File

@ -106,8 +106,8 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
this.domNodes.push(domNode);
};
LinkWidget.prototype.handleClickEvent = function (event) {
// Send the click on it's way as a navigate event
LinkWidget.prototype.handleClickEvent = function(event) {
// Send the click on its way as a navigate event
var bounds = this.domNodes[0].getBoundingClientRect();
this.dispatchEvent({
type: "tm-navigate",
@ -155,7 +155,7 @@ LinkWidget.prototype.handleDragStartEvent = function(event) {
dataTransfer.clearData();
var jsonData = this.wiki.getTiddlerAsJson(this.to),
textData = this.wiki.getTiddlerText(this.to,""),
title = this.to.indexOf(" ") === -1 ? this.to : "[[" + this.to + "]]";
title = (new RegExp("^" + $tw.config.textPrimitives.wikiLink + "$","mg")).exec(this.to) ? this.to : "[[" + this.to + "]]";
// IE doesn't like these content types
if(!$tw.browser.isIE) {
dataTransfer.setData("text/vnd.tiddler",jsonData);

View File

@ -60,16 +60,18 @@ ListWidget.prototype.execute = function() {
this.variableName = this.getAttribute("variable","currentTiddler");
this.storyViewName = this.getAttribute("storyview");
this.historyTitle = this.getAttribute("history");
this.iterator = this.getAttribute("iterator","iterator");
// Compose the list elements
this.list = this.getTiddlerList();
var members = [],
self = this;
self = this,
count = self.list.length;
// Check for an empty list
if(this.list.length === 0) {
if(0 === count) {
members = this.getEmptyMessage();
} else {
$tw.utils.each(this.list,function(title,index) {
members.push(self.makeItemTemplate(title));
members.push(self.makeItemTemplate(title,index,count,self.iterator));
});
}
// Construct the child widgets
@ -96,7 +98,7 @@ ListWidget.prototype.getEmptyMessage = function() {
/*
Compose the template for a list item
*/
ListWidget.prototype.makeItemTemplate = function(title) {
ListWidget.prototype.makeItemTemplate = function(title,index,count,iterator) {
// Check if the tiddler is a draft
var tiddler = this.wiki.getTiddler(title),
isDraft = tiddler && tiddler.hasField("draft.of"),
@ -119,7 +121,15 @@ ListWidget.prototype.makeItemTemplate = function(title) {
}
}
// Return the list item
return {type: "listitem", itemTitle: title, variableName: this.variableName, children: templateTree};
return {
type: "listitem",
itemTitle: title,
variableName: this.variableName,
children: templateTree,
index: index,
count: count,
iterator: iterator
};
};
/*
@ -291,8 +301,12 @@ ListItemWidget.prototype.render = function(parent,nextSibling) {
Compute the internal state of the widget
*/
ListItemWidget.prototype.execute = function() {
var item = this.parseTreeNode;
// Set the current list item title
this.setVariable(this.parseTreeNode.variableName,this.parseTreeNode.itemTitle);
this.setVariable(item.variableName,item.itemTitle);
this.setVariable(item.iterator,(item.index + 1).toString());
this.setVariable(item.iterator + "-even",item.index % 2 == 1 ? "true" : "false");
this.setVariable(item.iterator + "-last",item.index + 1 == item.count ? "true" : "false");
// Construct the child widgets
this.makeChildWidgets();
};

View File

@ -333,12 +333,12 @@ NavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) {
// Flip the specified tiddler from draft back to the original
var draftTitle = event.param || event.tiddlerTitle,
draftTiddler = this.wiki.getTiddler(draftTitle),
originalTitle = draftTiddler.fields["draft.of"],
originalTiddler = this.wiki.getTiddler(originalTitle),
storyList = this.getStoryList();
originalTitle = draftTiddler && draftTiddler.fields["draft.of"];
if(draftTiddler && originalTitle) {
// Ask for confirmation if the tiddler text has changed
var isConfirmed = true;
var isConfirmed = true,
originalTiddler = this.wiki.getTiddler(originalTitle),
storyList = this.getStoryList();
if(this.wiki.isDraftModified(draftTitle)) {
isConfirmed = confirm($tw.language.getString(
"ConfirmCancelTiddler",
@ -376,7 +376,7 @@ NavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) {
NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {
// Get the story details
var storyList = this.getStoryList(),
templateTiddler, additionalFields, title, draftTitle, existingTiddler, mergedTags;
templateTiddler, additionalFields, title, draftTitle, existingTiddler;
// Get the template tiddler (if any)
if(typeof event.param === "string") {
// Get the template tiddler
@ -406,13 +406,17 @@ NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {
existingTiddler = this.wiki.getTiddler(title);
}
// Merge the tags
if(existingTiddler && existingTiddler.fields.tags && additionalFields && additionalFields.tags) {
var mergedTags = [];
if(existingTiddler && existingTiddler.fields.tags) {
$tw.utils.pushTop(mergedTags,existingTiddler.fields.tags)
}
if(additionalFields && additionalFields.tags) {
// Merge tags
mergedTags = $tw.utils.pushTop($tw.utils.parseStringArray(additionalFields.tags),existingTiddler.fields.tags);
} else if(existingTiddler && existingTiddler.fields.tags) {
mergedTags = existingTiddler.fields.tags;
} else if(additionalFields && additionalFields.tags) {
mergedTags = additionalFields.tags;
mergedTags = $tw.utils.pushTop(mergedTags,$tw.utils.parseStringArray(additionalFields.tags));
}
if(templateTiddler && templateTiddler.fields.tags) {
// Merge tags
mergedTags = $tw.utils.pushTop(mergedTags,templateTiddler.fields.tags);
}
// Save the draft tiddler
var draftTiddler = new $tw.Tiddler({

View File

@ -106,20 +106,18 @@ Read the state tiddler
*/
RevealWidget.prototype.readState = function() {
// Read the information from the state tiddler
if(this.stateTitle) {
var state = this.wiki.getTextReference(this.stateTitle,this["default"],this.getVariable("currentTiddler"));
switch(this.type) {
case "popup":
this.readPopupState(state);
break;
case "match":
this.readMatchState(state);
break;
case "nomatch":
this.readMatchState(state);
this.isOpen = !this.isOpen;
break;
}
var state = this.stateTitle ? this.wiki.getTextReference(this.stateTitle,this["default"],this.getVariable("currentTiddler")) : this["default"];
switch(this.type) {
case "popup":
this.readPopupState(state);
break;
case "match":
this.readMatchState(state);
break;
case "nomatch":
this.readMatchState(state);
this.isOpen = !this.isOpen;
break;
}
};

View File

@ -171,7 +171,7 @@ Widget.prototype.evaluateMacroModule = function(name,actualParams,defaultValue)
else for(var i=0; i<actualParams.length; ++i) {
args.push(actualParams[i].value);
}
return macro.run.apply(this,args).toString();
return (macro.run.apply(this,args) || "").toString();
} else {
return defaultValue;
}
@ -476,15 +476,25 @@ Widget.prototype.removeChildDomNodes = function() {
};
/*
Invoke any action widgets that are immediate children of this widget
Invoke any action widgets that are descendants of this widget.
*/
Widget.prototype.invokeActions = function(event) {
return this.invokeActionCall(this, event);
};
/*
Recursively search through descendants, invoking all actions encountered.
*/
Widget.prototype.invokeActionCall = function(here, event) {
var handled = false;
for(var t=0; t<this.children.length; t++) {
var child = this.children[t];
for(var t=0; t<here.children.length; t++) {
var child = here.children[t];
if(child.invokeAction && child.invokeAction(this,event)) {
handled = true;
}
if(this.invokeActionCall(child, event)) {
handled = true;
}
}
return handled;
};

View File

@ -316,6 +316,14 @@ Sort an array of tiddler titles by a specified field
exports.sortTiddlers = function(titles,sortField,isDescending,isCaseSensitive,isNumeric) {
var self = this;
titles.sort(function(a,b) {
var x,y,
compareNumbers = function(x,y) {
var result =
isNaN(x) && !isNaN(y) ? (isDescending ? -1 : 1) :
!isNaN(x) && isNaN(y) ? (isDescending ? 1 : -1) :
(isDescending ? y - x : x - y);
return result;
};
if(sortField !== "title") {
var tiddlerA = self.getTiddler(a),
tiddlerB = self.getTiddler(b);
@ -330,10 +338,10 @@ exports.sortTiddlers = function(titles,sortField,isDescending,isCaseSensitive,is
b = "";
}
}
if(isNumeric) {
a = Number(a);
b = Number(b);
return isDescending ? b - a : a - b;
x = Number(a);
y = Number(b);
if(isNumeric && (!isNaN(x) || !isNaN(y))) {
return compareNumbers(x,y);
} else if($tw.utils.isDate(a) && $tw.utils.isDate(b)) {
return isDescending ? b - a : a - b;
} else {
@ -516,7 +524,7 @@ exports.sortByList = function(array,listTitle) {
if(!array || array.length === 0) {
return [];
} else {
var titles = [], t, title;
var t, title, titles = [], unlisted = [];
// First place any entries that are present in the list
for(t=0; t<list.length; t++) {
title = list[t];
@ -524,13 +532,17 @@ exports.sortByList = function(array,listTitle) {
titles.push(title);
}
}
// Then place any remaining entries
// Add remaining entries to unlisted
for(t=0; t<array.length; t++) {
title = array[t];
if(list.indexOf(title) === -1) {
titles.push(title);
unlisted.push(title);
}
}
//sort unlisted
$tw.wiki.sortTiddlers(unlisted,"title",false,false);
//concat listed with unlisted
titles = titles.concat(unlisted);
// Finally obey the list-before and list-after fields of each tiddler in turn
var sortedTitles = titles.slice(0);
for(t=0; t<sortedTitles.length; t++) {
@ -662,7 +674,7 @@ exports.setTiddlerData = function(title,data,fields) {
newFields.type = "application/json";
newFields.text = JSON.stringify(data,null,$tw.config.preferences.jsonSpaces);
}
this.addTiddler(new $tw.Tiddler(existingTiddler,fields,newFields,this.getModificationFields()));
this.addTiddler(new $tw.Tiddler(this.getCreationFields(),existingTiddler,fields,newFields,this.getModificationFields()));
};
/*
@ -749,8 +761,8 @@ exports.old_parseText = function(type,text,options) {
options = options || {};
// Select a parser
var Parser = $tw.Wiki.parsers[type];
if(!Parser && $tw.config.fileExtensionInfo[type]) {
Parser = $tw.Wiki.parsers[$tw.config.fileExtensionInfo[type].type];
if(!Parser && $tw.utils.getFileExtensionInfo(type)) {
Parser = $tw.Wiki.parsers[$tw.utils.getFileExtensionInfo(type).type];
}
if(!Parser) {
Parser = $tw.Wiki.parsers[options.defaultType || "text/vnd.tiddlywiki"];
@ -1092,7 +1104,7 @@ exports.readFile = function(file,callback) {
if(type === "" || !type) {
var dotPos = file.name.lastIndexOf(".");
if(dotPos !== -1) {
var fileExtensionInfo = $tw.config.fileExtensionInfo[file.name.substr(dotPos)];
var fileExtensionInfo = $tw.utils.getFileExtensionInfo(file.name.substr(dotPos));
if(fileExtensionInfo) {
type = fileExtensionInfo.type;
}

View File

@ -73,7 +73,7 @@ tab-foreground: #666666
table-border: #dddddd
table-footer-background: #a8a8a8
table-header-background: #f0f0f0
tag-background: #d5ad34
tag-background: #ec6
tag-foreground: #ffffff
tiddler-background: <<colour background>>
tiddler-border: <<colour background>>

View File

@ -3,4 +3,8 @@ type: text/vnd.tiddlywiki-html
<!-- This template is provided for backwards compatibility with older versions of TiddlyWiki -->
<$set name="exportFilter" value="[!is[system]sort[title]]">
{{$:/core/templates/exporters/StaticRiver}}
</$set>

View File

@ -1,7 +1,7 @@
title: $:/core/templates/exporters/CsvFile
tags: $:/tags/Exporter
description: {{$:/language/Exporters/CsvFile}}
filename: tiddlers.csv
extension: .csv
\define renderContent()
<$text text=<<csvtiddlers filter:"""$(exportFilter)$""" format:"quoted-comma-sep">>/>

View File

@ -1,7 +1,7 @@
title: $:/core/templates/exporters/JsonFile
tags: $:/tags/Exporter
description: {{$:/language/Exporters/JsonFile}}
filename: tiddlers.json
extension: .json
\define renderContent()
<$text text=<<jsontiddlers filter:"""$(exportFilter)$""">>/>

View File

@ -1,7 +1,7 @@
title: $:/core/templates/exporters/StaticRiver
tags: $:/tags/Exporter
description: {{$:/language/Exporters/StaticRiver}}
filename: static.tiddlers.html
extension: .html
\define tv-wikilink-template() #$uri_encoded$
\define tv-config-toolbar-icons() no

View File

@ -1,7 +1,7 @@
title: $:/core/templates/exporters/TidFile
tags: $:/tags/Exporter
description: {{$:/language/Exporters/TidFile}}
filename: tiddler.tid
extension: .tid
\define renderContent()
{{{ $(exportFilter)$ +[limit[1]] ||$:/core/templates/tid-tiddler}}}

View File

@ -12,6 +12,9 @@ type: text/vnd.tiddlywiki-html
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="generator" content="TiddlyWiki" />
<meta name="tiddlywiki-version" content="{{$:/core/templates/version}}" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="format-detection" content="telephone=no">
<link id="faviconLink" rel="shortcut icon" href="favicon.ico">
<title>{{$:/core/wiki/title}}</title>

View File

@ -10,6 +10,9 @@ title: $:/core/templates/static.tiddler.html
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="generator" content="TiddlyWiki" />
<meta name="tiddlywiki-version" content="`{{$:/core/templates/version}}`" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="format-detection" content="telephone=no">
<link id="faviconLink" rel="shortcut icon" href="favicon.ico">
<link rel="stylesheet" href="static.css">

View File

@ -1,4 +1,5 @@
title: $:/AdvancedSearch
icon: $:/core/images/advanced-search-button
<div class="tc-advanced-search">
<<tabs "[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch]!has[draft.of]]" "$:/core/ui/AdvancedSearch/System">>

View File

@ -7,7 +7,15 @@ caption: {{$:/language/Search/Shadows/Caption}}
<<lingo Shadows/Hint>>
<div class="tc-search"><$edit-text tiddler="$:/temp/advancedsearch" type="search" tag="input"/><$reveal state="$:/temp/advancedsearch" type="nomatch" text=""> <$link to="" class="tc-btn-invisible">{{$:/core/images/close-button}}</$link></$reveal></div>
<div class="tc-search">
<$edit-text tiddler="$:/temp/advancedsearch" type="search" tag="input"/>
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
<$button class="tc-btn-invisible">
<$action-setfield $tiddler="$:/temp/advancedsearch" $field="text" $value=""/>
{{$:/core/images/close-button}}
</$button>
</$reveal>
</div>
</$linkcatcher>

View File

@ -7,7 +7,15 @@ caption: {{$:/language/Search/Standard/Caption}}
<<lingo Standard/Hint>>
<div class="tc-search"><$edit-text tiddler="$:/temp/advancedsearch" type="search" tag="input"/><$reveal state="$:/temp/advancedsearch" type="nomatch" text=""> <$link to="" class="tc-btn-invisible">{{$:/core/images/close-button}}</$link></$reveal></div>
<div class="tc-search">
<$edit-text tiddler="$:/temp/advancedsearch" type="search" tag="input"/>
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
<$button class="tc-btn-invisible">
<$action-setfield $tiddler="$:/temp/advancedsearch" $field="text" $value=""/>
{{$:/core/images/close-button}}
</$button>
</$reveal>
</div>
</$linkcatcher>

View File

@ -7,7 +7,15 @@ caption: {{$:/language/Search/System/Caption}}
<<lingo System/Hint>>
<div class="tc-search"><$edit-text tiddler="$:/temp/advancedsearch" type="search" tag="input"/><$reveal state="$:/temp/advancedsearch" type="nomatch" text=""> <$link to="" class="tc-btn-invisible">{{$:/core/images/close-button}}</$link></$reveal></div>
<div class="tc-search">
<$edit-text tiddler="$:/temp/advancedsearch" type="search" tag="input"/>
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
<$button class="tc-btn-invisible">
<$action-setfield $tiddler="$:/temp/advancedsearch" $field="text" $value=""/>
{{$:/core/images/close-button}}
</$button>
</$reveal>
</div>
</$linkcatcher>

View File

@ -0,0 +1,9 @@
title: $:/core/ui/Components/tag-link
<$link>
<$set name="backgroundColor" value={{!!color}}>
<span style=<<tag-styles>> class="tc-tag-label">
<$view field="title" format="text"/>
</span>
</$set>
</$link>

View File

@ -1,4 +1,5 @@
title: $:/ControlPanel
icon: $:/core/images/options-button
<div class="tc-control-panel">
<<tabs "[all[shadows+tiddlers]tag[$:/tags/ControlPanel]!has[draft.of]]" "$:/core/ui/ControlPanel/Info">>

View File

@ -9,7 +9,12 @@ http://$(userName)$.tiddlyspot.com/backup/
\define backupLink()
<$reveal type="nomatch" state="$:/UploadName" text="">
<$set name="userName" value={{$:/UploadName}}>
<a href=<<backupURL>>><$macrocall $name="backupURL" $type="text/plain" $output="text/plain"/></a>
<$reveal type="match" state="$:/UploadURL" text="">
<<backupURL>>
</$reveal>
<$reveal type="nomatch" state="$:/UploadURL" text="">
<$macrocall $name=resolvePath source={{$:/UploadBackupDir}} root={{$:/UploadURL}}>>
</$reveal>
</$set>
</$reveal>
\end
@ -28,5 +33,4 @@ http://$(userName)$.tiddlyspot.com/backup/
|<<lingo TiddlySpot/UploadDir>> |<$edit-text tiddler="$:/UploadDir" default="." tag="input"/> |
|<<lingo TiddlySpot/BackupDir>> |<$edit-text tiddler="$:/UploadBackupDir" default="." tag="input"/> |
<<lingo TiddlySpot/Hint>>
<<lingo TiddlySpot/Hint>>

View File

@ -5,9 +5,27 @@ tags: $:/tags/EditTemplate
\define config-title()
$:/config/EditTemplateFields/Visibility/$(currentField)$
\end
\define config-filter()
[[hide]] -[title{$(config-title)$}]
\end
\define new-field(name,value)
<$reveal type="nomatch" text="" default="""$name$""">
<$button>
<$action-sendmessage $message="tm-add-field" $name$="""$value$"""/>
<$action-deletetiddler $tiddler="$:/temp/newfieldname"/>
<$action-deletetiddler $tiddler="$:/temp/newfieldvalue"/>
<<lingo Fields/Add/Button>>
</$button>
</$reveal>
<$reveal type="match" text="" default="""$name$""">
<$button>
<<lingo Fields/Add/Button>>
</$button>
</$reveal>
\end
<div class="tc-edit-fields">
<table class="tc-edit-fields">
<tbody>
@ -32,6 +50,7 @@ $:/config/EditTemplateFields/Visibility/$(currentField)$
</table>
</div>
<$fieldmangler>
<div class="tc-edit-field-add">
<em class="tc-edit">
<<lingo Fields/Add/Prompt>>
@ -43,11 +62,8 @@ $:/config/EditTemplateFields/Visibility/$(currentField)$
<$edit-text tiddler="$:/temp/newfieldvalue" tag="input" default="" placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}} class="tc-edit-texteditor"/>
</span>
<span class="tc-edit-field-add-button">
<$button>
<$action-setfield $field={{$:/temp/newfieldname}} $value={{$:/temp/newfieldvalue}}/>
<$action-deletetiddler $tiddler="$:/temp/newfieldname"/>
<$action-deletetiddler $tiddler="$:/temp/newfieldvalue"/>
<<lingo Fields/Add/Button>>
</$button>
<$macrocall $name="new-field" name={{$:/temp/newfieldname}} value={{$:/temp/newfieldvalue}}/>
</span>
</div>
</$fieldmangler>

View File

@ -15,7 +15,7 @@ background-color:$(backgroundColor)$;
<div class="tc-edit-add-tag">
<span class="tc-add-tag-name">
<$edit-text tiddler="$:/temp/NewTagName" tag="input" default="" placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}} focusPopup=<<qualify "$:/state/popup/tags-auto-complete">> class="tc-edit-texteditor"/>
<$edit-text tiddler="$:/temp/NewTagName" tag="input" default="" placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}} focusPopup=<<qualify "$:/state/popup/tags-auto-complete">> class="tc-edit-texteditor tc-popup-handle"/>
</span> <$button popup=<<qualify "$:/state/popup/tags-auto-complete">> class="tc-btn-invisible tc-btn-dropdown" tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button> <span class="tc-add-tag-button">
<$button message="tm-add-tag" param={{$:/temp/NewTagName}} set="$:/temp/NewTagName" setTo="" class="">
<<lingo Tags/Add/Button>>
@ -27,14 +27,12 @@ background-color:$(backgroundColor)$;
<$reveal state=<<qualify "$:/state/popup/tags-auto-complete">> type="nomatch" text="" default="">
<div class="tc-block-dropdown">
<$linkcatcher set="$:/temp/NewTagName" setTo="" message="tm-add-tag">
<$list filter="[!is[shadow]tags[]search{$:/temp/NewTagName}sort[title]]">
<$link>
<$set name="backgroundColor" value={{!!color}}>
<span style=<<tag-styles>> class="tc-tag-label">
<$view field="title" format="text"/>
</span>
</$set>
</$link>
<$list filter="[tags[]search:title{$:/temp/NewTagName}sort[]]">
{{||$:/core/ui/Components/tag-link}}
</$list>
<hr>
<$list filter="[!is[system]search:title{$:/temp/NewTagName}sort[]]">
{{||$:/core/ui/Components/tag-link}}
</$list>
</$linkcatcher>
</div>

View File

@ -1,4 +1,4 @@
title: $:/core/ui/EditTemplate/title
tags: $:/tags/EditTemplate
<$edit-text field="draft.title" class="tc-titlebar tc-edit-texteditor"/>
<$edit-text field="draft.title" class="tc-titlebar tc-edit-texteditor" focus="true"/>

View File

@ -3,7 +3,7 @@ tags: $:/tags/EditTemplate
\define lingo-base() $:/language/EditTemplate/
<div class="tc-type-selector"><$fieldmangler>
<em class="tc-edit"><<lingo Type/Prompt>></em> <$edit-text field="type" tag="input" default="" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<<qualify "$:/state/popup/type-dropdown">> class="tc-edit-typeeditor"/> <$button popup=<<qualify "$:/state/popup/type-dropdown">> class="tc-btn-invisible tc-btn-dropdown" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button> <$button message="tm-remove-field" param="type" class="tc-btn-invisible tc-btn-icon" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}</$button>
<em class="tc-edit"><<lingo Type/Prompt>></em> <$edit-text field="type" tag="input" default="" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<<qualify "$:/state/popup/type-dropdown">> class="tc-edit-typeeditor tc-popup-handle"/> <$button popup=<<qualify "$:/state/popup/type-dropdown">> class="tc-btn-invisible tc-btn-dropdown" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button> <$button message="tm-remove-field" param="type" class="tc-btn-invisible tc-btn-icon" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}</$button>
</$fieldmangler></div>
<div class="tc-block-dropdown-wrapper">

View File

@ -0,0 +1,5 @@
title: $:/core/Filters/TypedTiddlers
tags: $:/tags/Filter
filter: [!is[system]has[type]each[type]sort[type]] -[type[text/vnd.tiddlywiki]]
description: {{$:/language/Filters/TypedTiddlers}}

View File

@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/All
tags: $:/tags/MoreSideBar
caption: {{$:/language/SideBar/All/Caption}}
<$list filter="[!is[system]sort[title]]" template="$:/core/ui/ListItemTemplate"/>
<$list filter={{$:/core/Filters/AllTiddlers!!filter}} template="$:/core/ui/ListItemTemplate"/>

View File

@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/Drafts
tags: $:/tags/MoreSideBar
caption: {{$:/language/SideBar/Drafts/Caption}}
<$list filter="[has[draft.of]sort[title]]" template="$:/core/ui/ListItemTemplate"/>
<$list filter={{$:/core/Filters/Drafts!!filter}} template="$:/core/ui/ListItemTemplate"/>

View File

@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/Missing
tags: $:/tags/MoreSideBar
caption: {{$:/language/SideBar/Missing/Caption}}
<$list filter="[all[missing]sort[title]]" template="$:/core/ui/MissingTemplate"/>
<$list filter={{$:/core/Filters/Missing!!filter}} template="$:/core/ui/MissingTemplate"/>

View File

@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/Orphans
tags: $:/tags/MoreSideBar
caption: {{$:/language/SideBar/Orphans/Caption}}
<$list filter="[all[orphans]sort[title]]" template="$:/core/ui/ListItemTemplate"/>
<$list filter={{$:/core/Filters/Orphans!!filter}} template="$:/core/ui/ListItemTemplate"/>

View File

@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/Shadows
tags: $:/tags/MoreSideBar
caption: {{$:/language/SideBar/Shadows/Caption}}
<$list filter="[all[shadows]sort[title]]" template="$:/core/ui/ListItemTemplate"/>
<$list filter={{$:/core/Filters/ShadowTiddlers!!filter}} template="$:/core/ui/ListItemTemplate"/>

View File

@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/System
tags: $:/tags/MoreSideBar
caption: {{$:/language/SideBar/System/Caption}}
<$list filter="[is[system]sort[title]]" template="$:/core/ui/ListItemTemplate"/>
<$list filter={{$:/core/Filters/SystemTiddlers!!filter}} template="$:/core/ui/ListItemTemplate"/>

View File

@ -16,7 +16,7 @@ caption: {{$:/language/SideBar/Tags/Caption}}
</$set>
<$list filter="[tags[]!is[system]sort[title]]">
<$list filter={{$:/core/Filters/AllTags!!filter}}>
<$transclude tiddler="$:/core/ui/TagTemplate"/> <small class="tc-menu-list-count"><$count filter="[all[current]tagging[]]"/></small>

View File

@ -2,7 +2,7 @@ title: $:/core/ui/MoreSideBar/Types
tags: $:/tags/MoreSideBar
caption: {{$:/language/SideBar/Types/Caption}}
<$list filter="[!is[system]has[type]each[type]sort[type]] -[type[text/vnd.tiddlywiki]]">
<$list filter={{$:/core/Filters/TypedTiddlers!!filter}}>
<div class="tc-menu-list-item">
<$view field="type"/>
<$list filter="[type{!!type}!is[system]sort[title]]">

View File

@ -10,4 +10,4 @@ description: {{$:/language/Buttons/AdvancedSearch/Hint}}
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/AdvancedSearch/Caption}}/></span>
</$list>
</$button>
</$button>

View File

@ -10,4 +10,4 @@ description: {{$:/language/Buttons/CloseAll/Hint}}
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/CloseAll/Caption}}/></span>
</$list>
</$button>
</$button>

View File

@ -10,4 +10,4 @@ description: {{$:/language/Buttons/ControlPanel/Hint}}
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/ControlPanel/Caption}}/></span>
</$list>
</$button>
</$button>

View File

@ -22,4 +22,4 @@ description: {{$:/language/Buttons/Encryption/Hint}}
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Encryption/SetPassword/Caption}}/></span>
</$list>
</$button>
</$reveal>
</$reveal>

View File

@ -3,4 +3,4 @@ tags: $:/tags/PageControls
caption: {{$:/core/images/export-button}} {{$:/language/Buttons/ExportPage/Caption}}
description: {{$:/language/Buttons/ExportPage/Hint}}
<$macrocall $name="exportButton" exportFilter="[!is[system]sort[title]]" lingoBase="$:/language/Buttons/ExportPage/"/>
<$macrocall $name="exportButton" exportFilter="[!is[system]sort[title]]" lingoBase="$:/language/Buttons/ExportPage/"/>

View File

@ -10,4 +10,4 @@ description: {{$:/language/Buttons/FullScreen/Hint}}
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/FullScreen/Caption}}/></span>
</$list>
</$button>
</$button>

View File

@ -10,4 +10,4 @@ description: {{$:/language/Buttons/Home/Hint}}
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Home/Caption}}/></span>
</$list>
</$button>
</$button>

View File

@ -12,5 +12,5 @@ description: {{$:/language/Buttons/Import/Hint}}
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Import/Caption}}/></span>
</$list>
</$button>
<$browse/>
</div>
<$browse tooltip={{$:/language/Buttons/Import/Hint}}/>
</div>

View File

@ -6,6 +6,7 @@ description: {{$:/language/Buttons/Language/Hint}}
\define flag-title()
$(languagePluginTitle)$/icon
\end
<span class="tc-popup-keep">
<$button popup=<<qualify "$:/state/popup/language">> tooltip={{$:/language/Buttons/Language/Hint}} aria-label={{$:/language/Buttons/Language/Caption}} class=<<tv-config-toolbar-class>> selectedClass="tc-selected">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
<span class="tc-image-button">
@ -18,10 +19,11 @@ $(languagePluginTitle)$/icon
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Language/Caption}}/></span>
</$list>
</$button>
</span>
<$reveal state=<<qualify "$:/state/popup/language">> type="popup" position="below" animate="yes">
<div class="tc-drop-down tc-drop-down-language-chooser">
<$linkcatcher to="$:/language">
<$list filter="[[$:/languages/en-GB]] [plugin-type[language]sort[title]]">
<$list filter="[[$:/languages/en-GB]] [plugin-type[language]sort[description]]">
<$link>
<span class="tc-drop-down-bullet">
<$reveal type="match" state="$:/language" text=<<currentTiddler>>>
@ -49,4 +51,4 @@ $(languagePluginTitle)$/icon
</$list>
</$linkcatcher>
</div>
</$reveal>
</$reveal>

View File

@ -42,5 +42,4 @@ $:/config/PageControlButtons/Visibility/$(listItem)$
</div>
</$reveal>
</$reveal>

View File

@ -17,4 +17,4 @@ description: {{$:/language/Buttons/NewJournal/Hint}}
<$set name="journalTitleTemplate" value={{$:/config/NewJournal/Title}}>
<$set name="journalTags" value={{$:/config/NewJournal/Tags}}>
<<journalButton>>
</$set></$set>
</$set></$set>

View File

@ -10,4 +10,4 @@ description: {{$:/language/Buttons/NewTiddler/Hint}}
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/NewTiddler/Caption}}/></span>
</$list>
</$button>
</$button>

View File

@ -10,4 +10,4 @@ description: {{$:/language/Buttons/Refresh/Hint}}
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Refresh/Caption}}/></span>
</$list>
</$button>
</$button>

View File

@ -6,6 +6,7 @@ description: {{$:/language/Buttons/StoryView/Hint}}
\define icon()
$:/core/images/storyview-$(storyview)$
\end
<span class="tc-popup-keep">
<$button popup=<<qualify "$:/state/popup/storyview">> tooltip={{$:/language/Buttons/StoryView/Hint}} aria-label={{$:/language/Buttons/StoryView/Caption}} class=<<tv-config-toolbar-class>> selectedClass="tc-selected">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
<$set name="storyview" value={{$:/view}}>
@ -16,6 +17,7 @@ $:/core/images/storyview-$(storyview)$
<span class="tc-btn-text"><$text text={{$:/language/Buttons/StoryView/Caption}}/></span>
</$list>
</$button>
</span>
<$reveal state=<<qualify "$:/state/popup/storyview">> type="popup" position="below" animate="yes">
<div class="tc-drop-down">
<$linkcatcher to="$:/view">
@ -34,4 +36,4 @@ $:/core/images/storyview-$(storyview)$
</$list>
</$linkcatcher>
</div>
</$reveal>
</$reveal>

View File

@ -10,4 +10,4 @@ description: {{$:/language/Buttons/TagManager/Hint}}
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/TagManager/Caption}}/></span>
</$list>
</$button>
</$button>

View File

@ -3,6 +3,7 @@ tags: $:/tags/PageControls
caption: {{$:/core/images/theme-button}} {{$:/language/Buttons/Theme/Caption}}
description: {{$:/language/Buttons/Theme/Hint}}
<span class="tc-popup-keep">
<$button popup=<<qualify "$:/state/popup/theme">> tooltip={{$:/language/Buttons/Theme/Hint}} aria-label={{$:/language/Buttons/Theme/Caption}} class=<<tv-config-toolbar-class>> selectedClass="tc-selected">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/theme-button}}
@ -11,6 +12,7 @@ description: {{$:/language/Buttons/Theme/Hint}}
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Theme/Caption}}/></span>
</$list>
</$button>
</span>
<$reveal state=<<qualify "$:/state/popup/theme">> type="popup" position="below" animate="yes">
<div class="tc-drop-down">
<$linkcatcher to="$:/theme">
@ -29,4 +31,4 @@ description: {{$:/language/Buttons/Theme/Hint}}
</$list>
</$linkcatcher>
</div>
</$reveal>
</$reveal>

View File

@ -19,7 +19,7 @@ tags: $:/tags/PageTemplate
</div>
{{$:/core/ui/PageTemplate/pagecontrols}}
{{||$:/core/ui/PageTemplate/pagecontrols}}
<$transclude tiddler="$:/core/ui/SideBarLists" mode="inline"/>

View File

@ -3,7 +3,7 @@ title: $:/core/ui/SideBarLists
<div class="tc-sidebar-lists">
<div class="tc-search">
<$edit-text tiddler="$:/temp/search" type="search" tag="input"/>
<$edit-text tiddler="$:/temp/search" type="search" tag="input" focus="true"/>
<$reveal state="$:/temp/search" type="nomatch" text="">
<$button tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class="tc-btn-invisible">
<$action-setfield $tiddler="$:/temp/advancedsearch" text={{$:/temp/search}}/>

View File

@ -1,4 +1,5 @@
title: $:/TagManager
icon: $:/core/images/tag-button
\define lingo-base() $:/language/TagManager/
\define iconEditorTab(type)
@ -37,7 +38,7 @@ $title$$(currentTiddler)$
</$button>
</$reveal>
\end
<table>
<table class="tc-tag-manager-table">
<tbody>
<tr>
<th><<lingo Colour/Heading>></th>

View File

@ -13,7 +13,7 @@ $:/config/ViewToolbarButtons/Visibility/$(listItem)$
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]" variable="listItem"><$reveal type="nomatch" state=<<config-title>> text="hide"><$transclude tiddler=<<listItem>>/></$reveal></$list>
</span>
<$set name="foregroundColor" value={{!!color}}>
<span style=<<title-styles>>>
<span class="tc-tiddler-title-icon" style=<<title-styles>>>
<$transclude tiddler={{!!icon}}/>
</span>
</$set>
@ -29,7 +29,7 @@ $:/config/ViewToolbarButtons/Visibility/$(listItem)$
</$list>
</div>
<$reveal type="nomatch" text="" default="" state=<<tiddlerInfoState>> class="tc-tiddler-info tc-popup" animate="yes" retain="yes">
<$reveal type="nomatch" text="" default="" state=<<tiddlerInfoState>> class="tc-tiddler-info tc-popup-handle" animate="yes" retain="yes">
<$transclude tiddler="$:/core/ui/TiddlerInfo"/>

View File

@ -10,4 +10,4 @@ description: {{$:/language/Buttons/Clone/Hint}}
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Clone/Caption}}/></span>
</$list>
</$button>
</$button>

View File

@ -10,4 +10,4 @@ description: {{$:/language/Buttons/CloseOthers/Hint}}
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/CloseOthers/Caption}}/></span>
</$list>
</$button>
</$button>

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