1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-07-04 03:03:18 +00:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Bram Chen 2014-08-31 09:23:34 +08:00
commit 61fca88df5
85 changed files with 427 additions and 354 deletions

7
.jshintignore Normal file
View File

@ -0,0 +1,7 @@
plugins/tiddlywiki/browser-sniff/files
plugins/tiddlywiki/codemirror/files/
plugins/tiddlywiki/d3/files/
plugins/tiddlywiki/highlight/files/
plugins/tiddlywiki/jasmine/files/
plugins/tiddlywiki/markdown/files/
plugins/tiddlywiki/markdown/files/

View File

@ -26,7 +26,7 @@ Command.prototype.execute = function() {
// Get the build targets defined in the wiki // Get the build targets defined in the wiki
var buildTargets = $tw.boot.wikiInfo.build; var buildTargets = $tw.boot.wikiInfo.build;
if(!buildTargets) { if(!buildTargets) {
return "No build targets defined" return "No build targets defined";
} }
// Loop through each of the specified targets // Loop through each of the specified targets
var targets; var targets;

View File

@ -78,7 +78,7 @@ SimpleServer.prototype.findMatchingRoute = function(request,state) {
}; };
SimpleServer.prototype.checkCredentials = function(request,incomingUsername,incomingPassword) { SimpleServer.prototype.checkCredentials = function(request,incomingUsername,incomingPassword) {
var header = request.headers["authorization"] || "", var header = request.headers.authorization || "",
token = header.split(/\s+/).pop() || "", token = header.split(/\s+/).pop() || "",
auth = $tw.utils.base64Decode(token), auth = $tw.utils.base64Decode(token),
parts = auth.split(/:/), parts = auth.split(/:/),
@ -89,7 +89,7 @@ SimpleServer.prototype.checkCredentials = function(request,incomingUsername,inco
} else { } else {
return "DENIED"; return "DENIED";
} }
} };
SimpleServer.prototype.listen = function(port,host) { SimpleServer.prototype.listen = function(port,host) {
var self = this; var self = this;
@ -167,8 +167,8 @@ var Command = function(params,commander,callback) {
delete fields.fields; delete fields.fields;
} }
// Remove any revision field // Remove any revision field
if(fields["revision"]) { if(fields.revision) {
delete fields["revision"]; delete fields.revision;
} }
state.wiki.addTiddler(new $tw.Tiddler(state.wiki.getCreationFields(),fields,{title: title})); state.wiki.addTiddler(new $tw.Tiddler(state.wiki.getCreationFields(),fields,{title: title}));
var changeCount = state.wiki.getChangeCount(title).toString(); var changeCount = state.wiki.getChangeCount(title).toString();
@ -237,7 +237,7 @@ var Command = function(params,commander,callback) {
tiddlerFields[name] = tiddler.getFieldString(name); tiddlerFields[name] = tiddler.getFieldString(name);
} }
}); });
tiddlerFields["revision"] = state.wiki.getChangeCount(title); tiddlerFields.revision = state.wiki.getChangeCount(title);
tiddlerFields.type = tiddlerFields.type || "text/vnd.tiddlywiki"; tiddlerFields.type = tiddlerFields.type || "text/vnd.tiddlywiki";
tiddlers.push(tiddlerFields); tiddlers.push(tiddlerFields);
}); });
@ -265,7 +265,7 @@ var Command = function(params,commander,callback) {
tiddlerFields.fields[name] = value; tiddlerFields.fields[name] = value;
} }
}); });
tiddlerFields["revision"] = state.wiki.getChangeCount(title); tiddlerFields.revision = state.wiki.getChangeCount(title);
tiddlerFields.type = tiddlerFields.type || "text/vnd.tiddlywiki"; tiddlerFields.type = tiddlerFields.type || "text/vnd.tiddlywiki";
response.writeHead(200, {"Content-Type": "application/json"}); response.writeHead(200, {"Content-Type": "application/json"});
response.end(JSON.stringify(tiddlerFields),"utf8"); response.end(JSON.stringify(tiddlerFields),"utf8");

View File

@ -109,7 +109,7 @@ exports["text/html"] = function(text,fields) {
if(sysMatch) { if(sysMatch) {
results.push.apply(results,deserializeTiddlyWikiFile(text,systemAreaMarkerRegExp.lastIndex,!!sysMatch[1],fields)); results.push.apply(results,deserializeTiddlyWikiFile(text,systemAreaMarkerRegExp.lastIndex,!!sysMatch[1],fields));
} }
return results return results;
} else { } else {
// Check whether we've got an encrypted file // Check whether we've got an encrypted file
var encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text); var encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text);

View File

@ -34,7 +34,9 @@ exports.all = function(source,operator,options) {
var results = [], var results = [],
subops = operator.operand.split("+"); subops = operator.operand.split("+");
// Check for common optimisations // Check for common optimisations
if(subops.length === 1 && subops[0] === "tiddlers") { if(subops.length === 1 && subops[0] === "") {
return source;
} else if(subops.length === 1 && subops[0] === "tiddlers") {
return options.wiki.each; return options.wiki.each;
} else if(subops.length === 1 && subops[0] === "shadows") { } else if(subops.length === 1 && subops[0] === "shadows") {
return options.wiki.eachShadow; return options.wiki.eachShadow;

View File

@ -20,7 +20,7 @@ function getIsFilterOperators() {
$tw.modules.applyMethods("isfilteroperator",isFilterOperators); $tw.modules.applyMethods("isfilteroperator",isFilterOperators);
} }
return isFilterOperators; return isFilterOperators;
}; }
/* /*
Export our filter function Export our filter function

View File

@ -18,12 +18,12 @@ Export our filter function
exports.plugintiddlers = function(source,operator,options) { exports.plugintiddlers = function(source,operator,options) {
var results = []; var results = [];
source(function(tiddler,title) { source(function(tiddler,title) {
var pluginInfo = options.wiki.getPluginInfo(title) || options.wiki.getTiddlerData(title,{tiddlers:[]}); var pluginInfo = options.wiki.getPluginInfo(title) || options.wiki.getTiddlerData(title,{tiddlers:[]});
if(pluginInfo) { if(pluginInfo) {
$tw.utils.each(pluginInfo.tiddlers,function(fields,title) { $tw.utils.each(pluginInfo.tiddlers,function(fields,title) {
results.push(title); results.push(title);
}); });
} }
}); });
results.sort(); results.sort();
return results; return results;

View File

@ -19,9 +19,9 @@ exports.shadowsource = function(source,operator,options) {
var results = []; var results = [];
source(function(tiddler,title) { source(function(tiddler,title) {
var source = options.wiki.getShadowSource(title); var source = options.wiki.getShadowSource(title);
if(source) { if(source) {
$tw.utils.pushTop(results,source); $tw.utils.pushTop(results,source);
} }
}); });
results.sort(); results.sort();
return results; return results;

View File

@ -45,6 +45,6 @@ var prepare_results = function (source) {
results.push(title); results.push(title);
}); });
return results; return results;
} };
})(); })();

View File

@ -13,7 +13,7 @@ Initialise basic platform $:/info/ tiddlers
"use strict"; "use strict";
exports.getInfoTiddlerFields = function() { exports.getInfoTiddlerFields = function() {
var mapBoolean = function(value) {return value ? "yes" : "no"}, var mapBoolean = function(value) {return value ? "yes" : "no";},
infoTiddlerFields = []; infoTiddlerFields = [];
// Basics // Basics
infoTiddlerFields.push({title: "$:/info/browser", text: mapBoolean(!!$tw.browser)}); infoTiddlerFields.push({title: "$:/info/browser", text: mapBoolean(!!$tw.browser)});

View File

@ -23,8 +23,8 @@ exports.types = {block: true};
exports.init = function(parser) { exports.init = function(parser) {
this.parser = parser; this.parser = parser;
this.matchRegExp = /\<!--/mg; this.matchRegExp = /<!--/mg;
this.endMatchRegExp = /--\>/mg; this.endMatchRegExp = /-->/mg;
}; };
exports.findNextMatch = function(startPos) { exports.findNextMatch = function(startPos) {

View File

@ -23,8 +23,8 @@ exports.types = {inline: true};
exports.init = function(parser) { exports.init = function(parser) {
this.parser = parser; this.parser = parser;
this.matchRegExp = /\<!--/mg; this.matchRegExp = /<!--/mg;
this.endMatchRegExp = /--\>/mg; this.endMatchRegExp = /-->/mg;
}; };
exports.findNextMatch = function(startPos) { exports.findNextMatch = function(startPos) {

View File

@ -56,7 +56,7 @@ exports.parse = function() {
node.attributes.style = {type: "string", value: style}; node.attributes.style = {type: "string", value: style};
} }
if(classes) { if(classes) {
node.attributes["itemClass"] = {type: "string", value: classes.split(".").join(" ")}; node.attributes.itemClass = {type: "string", value: classes.split(".").join(" ")};
} }
return [node]; return [node];
}; };

View File

@ -55,7 +55,7 @@ exports.parse = function() {
node.attributes.style = {type: "string", value: style}; node.attributes.style = {type: "string", value: style};
} }
if(classes) { if(classes) {
node.attributes["itemClass"] = {type: "string", value: classes.split(".").join(" ")}; node.attributes.itemClass = {type: "string", value: classes.split(".").join(" ")};
} }
return [node]; return [node];
}; };

View File

@ -34,7 +34,8 @@ exports.init = function(parser) {
exports.parse = function() { exports.parse = function() {
var reEnd = /(""")|(\r?\n)/mg, var reEnd = /(""")|(\r?\n)/mg,
tree = []; tree = [],
match;
// Move past the match // Move past the match
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
do { do {
@ -42,7 +43,7 @@ exports.parse = function() {
tree.push.apply(tree,this.parser.parseInlineRun(reEnd,{eatTerminator: false})); tree.push.apply(tree,this.parser.parseInlineRun(reEnd,{eatTerminator: false}));
// Redo the terminator match // Redo the terminator match
reEnd.lastIndex = this.parser.pos; reEnd.lastIndex = this.parser.pos;
var match = reEnd.exec(this.parser.source); match = reEnd.exec(this.parser.source);
if(match) { if(match) {
this.parser.pos = reEnd.lastIndex; this.parser.pos = reEnd.lastIndex;
// Add a line break if the terminator was a line break // Add a line break if the terminator was a line break

View File

@ -55,7 +55,6 @@ exports.parse = function() {
classes.push.apply(classes, this.parser.parseClasses()); classes.push.apply(classes, this.parser.parseClasses());
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true}); this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
var cite = this.parser.parseInlineRun(/(\r?\n)/mg); var cite = this.parser.parseInlineRun(/(\r?\n)/mg);
// before handling the cite, parse the body of the quote // before handling the cite, parse the body of the quote
var tree= this.parser.parseBlocks(reEndString); var tree= this.parser.parseBlocks(reEndString);
// If we got a cite, put it before the text // If we got a cite, put it before the text
@ -66,10 +65,9 @@ exports.parse = function() {
children: cite children: cite
}); });
} }
// Parse any optional cite // Parse any optional cite
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true}); this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
var cite = this.parser.parseInlineRun(/(\r?\n)/mg); cite = this.parser.parseInlineRun(/(\r?\n)/mg);
// If we got a cite, push it // If we got a cite, push it
if(cite.length > 0) { if(cite.length > 0) {
tree.push({ tree.push({
@ -78,7 +76,6 @@ exports.parse = function() {
children: cite children: cite
}); });
} }
// Return the blockquote element // Return the blockquote element
return [{ return [{
type: "element", type: "element",

View File

@ -27,7 +27,8 @@ var processRow = function(prevColumns) {
tree = [], tree = [],
col = 0, col = 0,
colSpanCount = 1, colSpanCount = 1,
prevCell; prevCell,
vAlign;
// Match a single cell // Match a single cell
cellRegExp.lastIndex = this.parser.pos; cellRegExp.lastIndex = this.parser.pos;
var cellMatch = cellRegExp.exec(this.parser.source); var cellMatch = cellRegExp.exec(this.parser.source);
@ -38,7 +39,7 @@ var processRow = function(prevColumns) {
if(last) { if(last) {
last.rowSpanCount++; last.rowSpanCount++;
$tw.utils.addAttributeToParseTreeNode(last.element,"rowspan",last.rowSpanCount); $tw.utils.addAttributeToParseTreeNode(last.element,"rowspan",last.rowSpanCount);
var vAlign = $tw.utils.getAttributeValueFromParseTreeNode(last.element,"valign","center"); vAlign = $tw.utils.getAttributeValueFromParseTreeNode(last.element,"valign","center");
$tw.utils.addAttributeToParseTreeNode(last.element,"valign",vAlign); $tw.utils.addAttributeToParseTreeNode(last.element,"valign",vAlign);
if(colSpanCount > 1) { if(colSpanCount > 1) {
$tw.utils.addAttributeToParseTreeNode(last.element,"colspan",colSpanCount); $tw.utils.addAttributeToParseTreeNode(last.element,"colspan",colSpanCount);
@ -74,8 +75,8 @@ var processRow = function(prevColumns) {
// For ordinary cells, step beyond the opening `|` // For ordinary cells, step beyond the opening `|`
this.parser.pos++; this.parser.pos++;
// Look for a space at the start of the cell // Look for a space at the start of the cell
var spaceLeft = false, var spaceLeft = false;
vAlign = null; vAlign = null;
if(this.parser.source.substr(this.parser.pos).search(/^\^([^\^]|\^\^)/) === 0) { if(this.parser.source.substr(this.parser.pos).search(/^\^([^\^]|\^\^)/) === 0) {
vAlign = "top"; vAlign = "top";
} else if(this.parser.source.substr(this.parser.pos).search(/^,([^,]|,,)/) === 0) { } else if(this.parser.source.substr(this.parser.pos).search(/^,([^,]|,,)/) === 0) {

View File

@ -41,19 +41,20 @@ exports.parse = function() {
isBlock: true isBlock: true
}; };
// Prepare the tiddler widget // Prepare the tiddler widget
var tr, targetTitle, targetField, targetIndex, tiddlerNode;
if(textRef) { if(textRef) {
var tr = $tw.utils.parseTextReference(textRef), tr = $tw.utils.parseTextReference(textRef);
targetTitle = tr.title, targetTitle = tr.title;
targetField = tr.field, targetField = tr.field;
targetIndex = tr.index, targetIndex = tr.index;
tiddlerNode = { tiddlerNode = {
type: "tiddler", type: "tiddler",
attributes: { attributes: {
tiddler: {type: "string", value: targetTitle} tiddler: {type: "string", value: targetTitle}
}, },
isBlock: true, isBlock: true,
children: [transcludeNode] children: [transcludeNode]
}; };
} }
if(template) { if(template) {
transcludeNode.attributes.tiddler = {type: "string", value: template}; transcludeNode.attributes.tiddler = {type: "string", value: template};

View File

@ -38,18 +38,19 @@ exports.parse = function() {
attributes: {} attributes: {}
}; };
// Prepare the tiddler widget // Prepare the tiddler widget
var tr, targetTitle, targetField, targetIndex, tiddlerNode;
if(textRef) { if(textRef) {
var tr = $tw.utils.parseTextReference(textRef), tr = $tw.utils.parseTextReference(textRef);
targetTitle = tr.title, targetTitle = tr.title;
targetField = tr.field, targetField = tr.field;
targetIndex = tr.index, targetIndex = tr.index;
tiddlerNode = { tiddlerNode = {
type: "tiddler", type: "tiddler",
attributes: { attributes: {
tiddler: {type: "string", value: targetTitle} tiddler: {type: "string", value: targetTitle}
}, },
children: [transcludeNode] children: [transcludeNode]
}; };
} }
if(template) { if(template) {
transcludeNode.attributes.tiddler = {type: "string", value: template}; transcludeNode.attributes.tiddler = {type: "string", value: template};

View File

@ -68,7 +68,7 @@ exports.parse = function() {
var widgetNode = this.parser.wiki.makeWidget(parser), var widgetNode = this.parser.wiki.makeWidget(parser),
container = $tw.fakeDocument.createElement("div"); container = $tw.fakeDocument.createElement("div");
widgetNode.render(container,null); widgetNode.render(container,null);
var text = renderType === "text/html" ? container.innerHTML : container.textContent; text = renderType === "text/html" ? container.innerHTML : container.textContent;
return [{ return [{
type: "element", type: "element",
tag: "pre", tag: "pre",

View File

@ -27,7 +27,7 @@ var textPrimitives = {
upperLetter: "[A-Z\u00c0-\u00d6\u00d8-\u00de\u0150\u0170]", upperLetter: "[A-Z\u00c0-\u00d6\u00d8-\u00de\u0150\u0170]",
lowerLetter: "[a-z0-9\u00df-\u00f6\u00f8-\u00ff\u0151\u0171]", lowerLetter: "[a-z0-9\u00df-\u00f6\u00f8-\u00ff\u0151\u0171]",
anyLetter: "[A-Za-z0-9\u00c0-\u00d6\u00d8-\u00de\u00df-\u00f6\u00f8-\u00ff\u0150\u0170\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]" blockPrefixLetters: "[A-Za-z0-9-_\u00c0-\u00d6\u00d8-\u00de\u00df-\u00f6\u00f8-\u00ff\u0150\u0170\u0151\u0171]"
}; };
textPrimitives.unWikiLink = "~"; textPrimitives.unWikiLink = "~";

View File

@ -100,7 +100,7 @@ Get the next match out of an array of parse rule instances
*/ */
WikiParser.prototype.findNextMatch = function(rules,startPos) { WikiParser.prototype.findNextMatch = function(rules,startPos) {
// Find the best matching rule by finding the closest match position // Find the best matching rule by finding the closest match position
var matchingRule = undefined, var matchingRule,
matchingRulePos = this.sourceLength; matchingRulePos = this.sourceLength;
// Step through each rule // Step through each rule
for(var t=0; t<rules.length; t++) { for(var t=0; t<rules.length; t++) {
@ -308,7 +308,7 @@ WikiParser.prototype.parseClasses = function() {
while(match && match.index === this.pos) { while(match && match.index === this.pos) {
this.pos = match.index + match[0].length; this.pos = match.index + match[0].length;
classNames.push(match[1]); classNames.push(match[1]);
var match = classRegExp.exec(this.source); match = classRegExp.exec(this.source);
} }
return classNames; return classNames;
}; };
@ -345,7 +345,7 @@ WikiParser.prototype.amendRules = function(type,names) {
processRuleArray(this.pragmaRules); processRuleArray(this.pragmaRules);
processRuleArray(this.blockRules); processRuleArray(this.blockRules);
processRuleArray(this.inlineRules); processRuleArray(this.inlineRules);
} };
exports["text/vnd.tiddlywiki"] = WikiParser; exports["text/vnd.tiddlywiki"] = WikiParser;

View File

@ -18,64 +18,86 @@ wiki: wiki to be synced
dirtyTracking: true if dirty tracking should be performed dirtyTracking: true if dirty tracking should be performed
*/ */
function SaverHandler(options) { function SaverHandler(options) {
var self = this; var self = this;
this.wiki = options.wiki; this.wiki = options.wiki;
this.dirtyTracking = options.dirtyTracking; this.dirtyTracking = options.dirtyTracking;
// Make a logger this.pendingAutoSave = false;
this.logger = new $tw.utils.Logger("saver-handler"); // Make a logger
// Initialise our savers this.logger = new $tw.utils.Logger("saver-handler");
if($tw.browser) { // Initialise our savers
this.initSavers(); if($tw.browser) {
} this.initSavers();
// Only do dirty tracking if required }
if($tw.browser && this.dirtyTracking) { // Only do dirty tracking if required
// Compile the dirty tiddler filter if($tw.browser && this.dirtyTracking) {
this.filterFn = this.wiki.compileFilter(this.wiki.getTiddlerText(this.titleSyncFilter)); // Compile the dirty tiddler filter
// Count of tiddlers that have been changed but not yet saved this.filterFn = this.wiki.compileFilter(this.wiki.getTiddlerText(this.titleSyncFilter));
this.numTasksInQueue = 0; // Count of tiddlers that have been changed but not yet saved
// Listen out for changes to tiddlers this.numTasksInQueue = 0;
this.wiki.addEventListener("change",function(changes) { // Listen out for changes to tiddlers
var filteredChanges = self.filterFn.call(self.wiki,function(callback) { this.wiki.addEventListener("change",function(changes) {
$tw.utils.each(changes,function(change,title) { var filteredChanges = self.filterFn.call(self.wiki,function(callback) {
var tiddler = self.wiki.getTiddler(title); $tw.utils.each(changes,function(change,title) {
callback(tiddler,title); var tiddler = self.wiki.getTiddler(title);
}); callback(tiddler,title);
}); });
self.numTasksInQueue += filteredChanges.length; });
self.updateDirtyStatus(); self.numTasksInQueue += filteredChanges.length;
if(self.numTasksInQueue > 0) { self.updateDirtyStatus();
self.saveWiki({method: "autosave"}); // Do any autosave if one is pending and there's no more change events
} if(self.pendingAutoSave && self.wiki.getSizeOfTiddlerEventQueue() === 0) {
}); // Check if we're dirty
// Browser event handlers if(self.numTasksInQueue > 0) {
if($tw.browser) { self.saveWiki({
// Set up our beforeunload handler method: "autosave",
window.addEventListener("beforeunload",function(event) { downloadType: "text/plain"
var confirmationMessage = undefined; });
if(self.isDirty()) { }
confirmationMessage = $tw.language.getString("UnsavedChangesWarning"); self.pendingAutoSave = false;
event.returnValue = confirmationMessage; // Gecko }
} });
return confirmationMessage; // Listen for the autosave event
}); $tw.rootWidget.addEventListener("tw-auto-save-wiki",function(event) {
} // Do the autosave unless there are outstanding tiddler change events
} if(self.wiki.getSizeOfTiddlerEventQueue() === 0) {
// Install the save action handlers // Check if we're dirty
if($tw.browser) { if(self.numTasksInQueue > 0) {
$tw.rootWidget.addEventListener("tm-save-wiki",function(event) { self.saveWiki({
self.saveWiki({ method: "autosave",
template: event.param, downloadType: "text/plain"
downloadType: "text/plain" });
}); }
}); } else {
$tw.rootWidget.addEventListener("tm-download-file",function(event) { // Otherwise put ourselves in the "pending autosave" state and wait for the change event before we do the autosave
self.saveWiki({ self.pendingAutoSave = true;
method: "download", }
template: event.param, });
downloadType: "text/plain" // Set up our beforeunload handler
}); window.addEventListener("beforeunload",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) {
$tw.rootWidget.addEventListener("tm-save-wiki",function(event) {
self.saveWiki({
template: event.param,
downloadType: "text/plain"
});
});
$tw.rootWidget.addEventListener("tm-download-file",function(event) {
self.saveWiki({
method: "download",
template: event.param,
downloadType: "text/plain"
});
});
}
} }
SaverHandler.prototype.titleSyncFilter = "$:/config/SaverFilter"; SaverHandler.prototype.titleSyncFilter = "$:/config/SaverFilter";
@ -86,86 +108,86 @@ SaverHandler.prototype.titleSavedNotification = "$:/language/Notifications/Save/
Select the appropriate saver modules and set them up Select the appropriate saver modules and set them up
*/ */
SaverHandler.prototype.initSavers = function(moduleType) { SaverHandler.prototype.initSavers = function(moduleType) {
moduleType = moduleType || "saver"; moduleType = moduleType || "saver";
// Instantiate the available savers // Instantiate the available savers
this.savers = []; this.savers = [];
var self = this; var self = this;
$tw.modules.forEachModuleOfType(moduleType,function(title,module) { $tw.modules.forEachModuleOfType(moduleType,function(title,module) {
if(module.canSave(self)) { if(module.canSave(self)) {
self.savers.push(module.create(self.wiki)); self.savers.push(module.create(self.wiki));
} }
}); });
// Sort the savers into priority order // Sort the savers into priority order
this.savers.sort(function(a,b) { this.savers.sort(function(a,b) {
if(a.info.priority < b.info.priority) { if(a.info.priority < b.info.priority) {
return -1; return -1;
} else { } else {
if(a.info.priority > b.info.priority) { if(a.info.priority > b.info.priority) {
return +1; return +1;
} else { } else {
return 0; return 0;
} }
} }
}); });
}; };
/* /*
Save the wiki contents. Options are: Save the wiki contents. Options are:
method: "save", "autosave" or "download" method: "save", "autosave" or "download"
template: the tiddler containing the template to save template: the tiddler containing the template to save
downloadType: the content type for the saved file downloadType: the content type for the saved file
*/ */
SaverHandler.prototype.saveWiki = function(options) { SaverHandler.prototype.saveWiki = function(options) {
options = options || {}; options = options || {};
var self = this, var self = this,
method = options.method || "save", method = options.method || "save",
template = options.template || "$:/core/save/all", template = options.template || "$:/core/save/all",
downloadType = options.downloadType || "text/plain", downloadType = options.downloadType || "text/plain",
text = this.wiki.renderTiddler(downloadType,template), text = this.wiki.renderTiddler(downloadType,template),
callback = function(err) { callback = function(err) {
if(err) { if(err) {
alert("Error while saving:\n\n" + err); alert("Error while saving:\n\n" + err);
} else { } else {
// Clear the task queue if we're saving (rather than downloading) // Clear the task queue if we're saving (rather than downloading)
if(method !== "download") { if(method !== "download") {
self.numTasksInQueue = 0; self.numTasksInQueue = 0;
self.updateDirtyStatus(); self.updateDirtyStatus();
} }
$tw.notifier.display(self.titleSavedNotification); $tw.notifier.display(self.titleSavedNotification);
if(options.callback) { if(options.callback) {
options.callback(); options.callback();
} }
} }
}; };
// Ignore autosave if disabled // Ignore autosave if disabled
if(method === "autosave" && this.wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes") { if(method === "autosave" && this.wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes") {
return false; return false;
} }
// Call the highest priority saver that supports this method // Call the highest priority saver that supports this method
for(var t=this.savers.length-1; t>=0; t--) { for(var t=this.savers.length-1; t>=0; t--) {
var saver = this.savers[t]; var saver = this.savers[t];
if(saver.info.capabilities.indexOf(method) !== -1 && saver.save(text,method,callback)) { 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); this.logger.log("Saving wiki with method",method,"through saver",saver.info.name);
return true; return true;
} }
} }
return false; return false;
}; };
/* /*
Checks whether the wiki is dirty (ie the window shouldn't be closed) Checks whether the wiki is dirty (ie the window shouldn't be closed)
*/ */
SaverHandler.prototype.isDirty = function() { SaverHandler.prototype.isDirty = function() {
return this.numTasksInQueue > 0; return this.numTasksInQueue > 0;
}; };
/* /*
Update the document body with the class "tc-dirty" if the wiki has unsaved/unsynced changes Update the document body with the class "tc-dirty" if the wiki has unsaved/unsynced changes
*/ */
SaverHandler.prototype.updateDirtyStatus = function() { SaverHandler.prototype.updateDirtyStatus = function() {
if($tw.browser) { if($tw.browser) {
$tw.utils.toggleClass(document.body,"tc-dirty",this.isDirty()); $tw.utils.toggleClass(document.body,"tc-dirty",this.isDirty());
} }
}; };
exports.SaverHandler = SaverHandler; exports.SaverHandler = SaverHandler;

View File

@ -32,7 +32,7 @@ AndTidWiki.prototype.save = function(text,method,callback) {
pathname = pathname.substr(0,p); pathname = pathname.substr(0,p);
} }
// Save the file // Save the file
window.twi.saveFile(pathname,text) window.twi.saveFile(pathname,text);
// Call the callback // Call the callback
callback(null); callback(null);
return true; return true;

View File

@ -21,7 +21,7 @@ TiddlyFoxSaver.prototype.save = function(text,method,callback) {
// Get the pathname of this document // Get the pathname of this document
var pathname = document.location.toString().split("#")[0]; var pathname = document.location.toString().split("#")[0];
// Replace file://localhost/ with file:/// // Replace file://localhost/ with file:///
if(pathname.indexOf("file://localhost/") == 0) { if(pathname.indexOf("file://localhost/") === 0) {
pathname = "file://" + pathname.substr(16); pathname = "file://" + pathname.substr(16);
} }
// Windows path file:///x:/blah/blah --> x:\blah\blah // Windows path file:///x:/blah/blah --> x:\blah\blah
@ -32,10 +32,10 @@ TiddlyFoxSaver.prototype.save = function(text,method,callback) {
} else if(pathname.indexOf("file://///") === 0) { } else if(pathname.indexOf("file://///") === 0) {
pathname = "\\\\" + unescape(pathname.substr(10)).replace(/\//g,"\\"); pathname = "\\\\" + unescape(pathname.substr(10)).replace(/\//g,"\\");
// Mac/Unix local path file:///path/path --> /path/path // Mac/Unix local path file:///path/path --> /path/path
} else if(pathname.indexOf("file:///") == 0) { } else if(pathname.indexOf("file:///") === 0) {
pathname = unescape(pathname.substr(7)); pathname = unescape(pathname.substr(7));
// Mac/Unix local path file:/path/path --> /path/path // Mac/Unix local path file:/path/path --> /path/path
} else if(pathname.indexOf("file:/") == 0) { } else if(pathname.indexOf("file:/") === 0) {
pathname = unescape(pathname.substr(5)); pathname = unescape(pathname.substr(5));
// Otherwise Windows networth path file://server/share/path/path --> \\server\share\path\path // Otherwise Windows networth path file://server/share/path/path --> \\server\share\path\path
} else { } else {

View File

@ -38,25 +38,25 @@ TWEditSaver.prototype.save = function(text,method,callback) {
} }
// Error handler // Error handler
var errorHandler = function(event) { var errorHandler = function(event) {
// Error // Error
callback("Error saving to TWEdit: " + event.target.error.code); callback("Error saving to TWEdit: " + event.target.error.code);
}; };
// Get the file system // Get the file system
window.requestFileSystem(LocalFileSystem.PERSISTENT,0,function(fileSystem) { window.requestFileSystem(LocalFileSystem.PERSISTENT,0,function(fileSystem) {
// Now we've got the filesystem, get the fileEntry // Now we've got the filesystem, get the fileEntry
fileSystem.root.getFile(pathname, {create: true}, function(fileEntry) { fileSystem.root.getFile(pathname, {create: true}, function(fileEntry) {
// Now we've got the fileEntry, create the writer // Now we've got the fileEntry, create the writer
fileEntry.createWriter(function(writer) { fileEntry.createWriter(function(writer) {
writer.onerror = errorHandler; writer.onerror = errorHandler;
writer.onwrite = function() { writer.onwrite = function() {
callback(null); callback(null);
}; };
writer.position = 0; writer.position = 0;
writer.write(text); writer.write(text);
},errorHandler); },errorHandler);
}, errorHandler); }, errorHandler);
}, errorHandler); }, errorHandler);
return true; return true;
}; };
/* /*

View File

@ -38,6 +38,6 @@ function setFavicon() {
var faviconLink = document.getElementById("faviconLink"); var faviconLink = document.getElementById("faviconLink");
faviconLink.setAttribute("href","data:" + tiddler.fields.type + ";base64," + tiddler.fields.text); faviconLink.setAttribute("href","data:" + tiddler.fields.type + ";base64," + tiddler.fields.text);
} }
}; }
})(); })();

View File

@ -19,7 +19,7 @@ exports.after = ["story"];
exports.synchronous = true; exports.synchronous = true;
// Default story and history lists // Default story and history lists
var PAGE_TITLE_TITLE = "$:/core/wiki/title" var PAGE_TITLE_TITLE = "$:/core/wiki/title";
var PAGE_STYLESHEET_TITLE = "$:/core/ui/PageStylesheet"; var PAGE_STYLESHEET_TITLE = "$:/core/ui/PageStylesheet";
var PAGE_TEMPLATE_TITLE = "$:/core/ui/PageTemplate"; var PAGE_TEMPLATE_TITLE = "$:/core/ui/PageTemplate";

View File

@ -48,7 +48,7 @@ exports.startup = function() {
$tw.locationHash = hash; $tw.locationHash = hash;
openStartupTiddlers({defaultToCurrentStory: true}); openStartupTiddlers({defaultToCurrentStory: true});
} }
},false) },false);
// Listen for the tm-browser-refresh message // Listen for the tm-browser-refresh message
$tw.rootWidget.addEventListener("tm-browser-refresh",function(event) { $tw.rootWidget.addEventListener("tm-browser-refresh",function(event) {
window.location.reload(true); window.location.reload(true);
@ -157,7 +157,7 @@ function updateLocationHash(options) {
} }
// Assemble the location hash // Assemble the location hash
if(options.updateAddressBar === "permalink") { if(options.updateAddressBar === "permalink") {
$tw.locationHash = "#" + encodeURIComponent(targetTiddler) $tw.locationHash = "#" + encodeURIComponent(targetTiddler);
} else { } else {
$tw.locationHash = "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList)); $tw.locationHash = "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList));
} }

View File

@ -16,7 +16,7 @@ var easing = "cubic-bezier(0.645, 0.045, 0.355, 1)"; // From http://easings.net/
var ClassicStoryView = function(listWidget) { var ClassicStoryView = function(listWidget) {
this.listWidget = listWidget; this.listWidget = listWidget;
} };
ClassicStoryView.prototype.navigateTo = function(historyInfo) { ClassicStoryView.prototype.navigateTo = function(historyInfo) {
var listElementIndex = this.listWidget.findListItem(0,historyInfo.title); var listElementIndex = this.listWidget.findListItem(0,historyInfo.title);

View File

@ -14,7 +14,7 @@ Animates list insertions and removals
var PopStoryView = function(listWidget) { var PopStoryView = function(listWidget) {
this.listWidget = listWidget; this.listWidget = listWidget;
} };
PopStoryView.prototype.navigateTo = function(historyInfo) { PopStoryView.prototype.navigateTo = function(historyInfo) {
var listElementIndex = this.listWidget.findListItem(0,historyInfo.title); var listElementIndex = this.listWidget.findListItem(0,historyInfo.title);

View File

@ -86,7 +86,7 @@ ZoominListView.prototype.navigateTo = function(historyInfo) {
]); ]);
// Transform the previous tiddler out of the way and then hide it // Transform the previous tiddler out of the way and then hide it
if(prevCurrentTiddler && prevCurrentTiddler !== targetElement) { if(prevCurrentTiddler && prevCurrentTiddler !== targetElement) {
var scale = zoomBounds.width / sourceBounds.width; scale = zoomBounds.width / sourceBounds.width;
x = zoomBounds.left - targetBounds.left - (sourceBounds.left - targetBounds.left) * scale; x = zoomBounds.left - targetBounds.left - (sourceBounds.left - targetBounds.left) * scale;
y = zoomBounds.top - targetBounds.top - (sourceBounds.top - targetBounds.top) * scale; y = zoomBounds.top - targetBounds.top - (sourceBounds.top - targetBounds.top) * scale;
$tw.utils.setStyle(prevCurrentTiddler,[ $tw.utils.setStyle(prevCurrentTiddler,[

View File

@ -20,7 +20,7 @@ wiki: wiki to be synced
function Syncer(options) { function Syncer(options) {
var self = this; var self = this;
this.wiki = options.wiki; this.wiki = options.wiki;
this.syncadaptor = options.syncadaptor this.syncadaptor = options.syncadaptor;
// Make a logger // Make a logger
this.logger = new $tw.utils.Logger("syncer" + ($tw.browser ? "-browser" : "") + ($tw.node ? "-server" : "")); this.logger = new $tw.utils.Logger("syncer" + ($tw.browser ? "-browser" : "") + ($tw.node ? "-server" : ""));
// Compile the dirty tiddler filter // Compile the dirty tiddler filter
@ -40,7 +40,7 @@ function Syncer(options) {
if($tw.browser) { if($tw.browser) {
// Set up our beforeunload handler // Set up our beforeunload handler
window.addEventListener("beforeunload",function(event) { window.addEventListener("beforeunload",function(event) {
var confirmationMessage = undefined; var confirmationMessage;
if(self.isDirty()) { if(self.isDirty()) {
confirmationMessage = $tw.language.getString("UnsavedChangesWarning"); confirmationMessage = $tw.language.getString("UnsavedChangesWarning");
event.returnValue = confirmationMessage; // Gecko event.returnValue = confirmationMessage; // Gecko
@ -94,10 +94,10 @@ Syncer.prototype.readTiddlerInfo = function() {
$tw.utils.each(tiddlers,function(title) { $tw.utils.each(tiddlers,function(title) {
var tiddler = self.wiki.getTiddler(title); var tiddler = self.wiki.getTiddler(title);
self.tiddlerInfo[title] = { self.tiddlerInfo[title] = {
revision: tiddler.fields["revision"], revision: tiddler.fields.revision,
adaptorInfo: self.syncadaptor && self.syncadaptor.getTiddlerInfo(tiddler), adaptorInfo: self.syncadaptor && self.syncadaptor.getTiddlerInfo(tiddler),
changeCount: self.wiki.getChangeCount(title) changeCount: self.wiki.getChangeCount(title)
} };
}); });
}; };
@ -329,7 +329,7 @@ Syncer.prototype.enqueueSyncTask = function(task) {
revision: null, revision: null,
adaptorInfo: {}, adaptorInfo: {},
changeCount: -1 changeCount: -1
} };
} }
// Bail if this is a save and the tiddler is already at the changeCount that the server has // Bail if this is a save and the tiddler is already at the changeCount that the server has
if(task.type === "save" && this.wiki.getChangeCount(task.title) <= this.tiddlerInfo[task.title].changeCount) { if(task.type === "save" && this.wiki.getChangeCount(task.title) <= this.tiddlerInfo[task.title].changeCount) {

View File

@ -36,10 +36,10 @@ exports.upgrade = function(wiki,titles,tiddlers) {
$tw.utils.each(titles,function(title) { $tw.utils.each(titles,function(title) {
var incomingTiddler = tiddlers[title]; var incomingTiddler = tiddlers[title];
// Check if we're dealing with a plugin // Check if we're dealing with a plugin
if(incomingTiddler && incomingTiddler["plugin-type"] && incomingTiddler["version"]) { if(incomingTiddler && incomingTiddler["plugin-type"] && incomingTiddler.version) {
// Upgrade the incoming plugin if we've got a newer version in the upgrade library // Upgrade the incoming plugin if we've got a newer version in the upgrade library
var libraryTiddler = getLibraryTiddler(title); var libraryTiddler = getLibraryTiddler(title);
if(libraryTiddler && libraryTiddler["plugin-type"] && libraryTiddler["version"]) { if(libraryTiddler && libraryTiddler["plugin-type"] && libraryTiddler.version) {
if($tw.utils.checkVersions(libraryTiddler.version,incomingTiddler.version)) { if($tw.utils.checkVersions(libraryTiddler.version,incomingTiddler.version)) {
tiddlers[title] = libraryTiddler; tiddlers[title] = libraryTiddler;
messages[title] = $tw.language.getString("Import/Upgrader/Plugins/Upgraded",{variables: {incoming: incomingTiddler.version, upgraded: libraryTiddler.version}}); messages[title] = $tw.language.getString("Import/Upgrader/Plugins/Upgraded",{variables: {incoming: incomingTiddler.version, upgraded: libraryTiddler.version}});

View File

@ -51,10 +51,10 @@ exports.upgrade = function(wiki,titles,tiddlers) {
tiddlers[mappedTitle] = { tiddlers[mappedTitle] = {
title: mappedTitle, title: mappedTitle,
text: tiddlerData[index] text: tiddlerData[index]
} };
messages[mappedTitle] = $tw.language.getString("Import/Upgrader/ThemeTweaks/Created",{variables: { messages[mappedTitle] = $tw.language.getString("Import/Upgrader/ThemeTweaks/Created",{variables: {
from: title + "##" + index from: title + "##" + index
}}) }});
} }
} }
} }

View File

@ -93,7 +93,7 @@ Modal.prototype.display = function(title,options) {
}); });
// Setup the link if present // Setup the link if present
if(options.downloadLink) { if(options.downloadLink) {
modalLink.href = options.downloadLink modalLink.href = options.downloadLink;
modalLink.appendChild(document.createTextNode("Right-click to save changes")); modalLink.appendChild(document.createTextNode("Right-click to save changes"));
modalBody.appendChild(modalLink); modalBody.appendChild(modalLink);
} }

View File

@ -19,7 +19,7 @@ var bumpSequenceNumber = function(object) {
if(sequenceNumber !== null) { if(sequenceNumber !== null) {
object.sequenceNumber = sequenceNumber++; object.sequenceNumber = sequenceNumber++;
} }
} };
var TW_TextNode = function(text) { var TW_TextNode = function(text) {
bumpSequenceNumber(this); bumpSequenceNumber(this);
@ -79,7 +79,7 @@ TW_Element.prototype.insertBefore = function(node,nextSibling) {
} else { } else {
this.appendChild(node); this.appendChild(node);
} }
} };
TW_Element.prototype.removeChild = function(node) { TW_Element.prototype.removeChild = function(node) {
var p = this.children.indexOf(node); var p = this.children.indexOf(node);
@ -93,9 +93,9 @@ TW_Element.prototype.hasChildNodes = function() {
}; };
Object.defineProperty(TW_Element.prototype, "firstChild", { Object.defineProperty(TW_Element.prototype, "firstChild", {
get: function() { get: function() {
return this.children[0]; return this.children[0];
} }
}); });
TW_Element.prototype.addEventListener = function(type,listener,useCapture) { TW_Element.prototype.addEventListener = function(type,listener,useCapture) {
@ -106,22 +106,22 @@ Object.defineProperty(TW_Element.prototype, "className", {
get: function() { get: function() {
return this.attributes["class"] || ""; return this.attributes["class"] || "";
}, },
set: function(value) { set: function(value) {
this.attributes["class"] = value; this.attributes["class"] = value;
} }
}); });
Object.defineProperty(TW_Element.prototype, "value", { Object.defineProperty(TW_Element.prototype, "value", {
get: function() { get: function() {
return this.attributes["value"] || ""; return this.attributes.value || "";
}, },
set: function(value) { set: function(value) {
this.attributes["value"] = value; this.attributes.value = value;
} }
}); });
Object.defineProperty(TW_Element.prototype, "outerHTML", { Object.defineProperty(TW_Element.prototype, "outerHTML", {
get: function() { get: function() {
var output = [],attr,a,v; var output = [],attr,a,v;
output.push("<",this.tag); output.push("<",this.tag);
if(this.attributes) { if(this.attributes) {
@ -143,7 +143,7 @@ Object.defineProperty(TW_Element.prototype, "outerHTML", {
output.push("</",this.tag,">"); output.push("</",this.tag,">");
} }
return output.join(""); return output.join("");
} }
}); });
Object.defineProperty(TW_Element.prototype, "innerHTML", { Object.defineProperty(TW_Element.prototype, "innerHTML", {
@ -162,10 +162,10 @@ Object.defineProperty(TW_Element.prototype, "innerHTML", {
return b.join(""); return b.join("");
} }
}, },
set: function(value) { set: function(value) {
this.isRaw = true; this.isRaw = true;
this.rawHTML = value; this.rawHTML = value;
} }
}); });
Object.defineProperty(TW_Element.prototype, "textContent", { Object.defineProperty(TW_Element.prototype, "textContent", {
@ -193,7 +193,7 @@ Object.defineProperty(TW_Element.prototype, "formattedTextContent", {
b.push("\n"); b.push("\n");
} }
if(this.tag === "li") { if(this.tag === "li") {
b.push("* ") b.push("* ");
} }
$tw.utils.each(this.children,function(node) { $tw.utils.each(this.children,function(node) {
b.push(node.formattedTextContent); b.push(node.formattedTextContent);

View File

@ -41,7 +41,7 @@ exports.copyDirectory = function(srcPath,dstPath) {
if(err) { if(err) {
return err; return err;
} }
}; }
} }
}; };
copy(srcPath,dstPath); copy(srcPath,dstPath);
@ -70,7 +70,7 @@ exports.copyFile = function(srcPath,dstPath) {
fs.closeSync(srcFile); fs.closeSync(srcFile);
fs.closeSync(dstFile); fs.closeSync(dstFile);
return null; return null;
} };
/* /*
Remove trailing path separator Remove trailing path separator

View File

@ -41,9 +41,9 @@ exports.addClassToParseTreeNode = function(node,classString) {
exports.addStyleToParseTreeNode = function(node,name,value) { exports.addStyleToParseTreeNode = function(node,name,value) {
node.attributes = node.attributes || {}; node.attributes = node.attributes || {};
node.attributes["style"] = node.attributes["style"] || {type: "string", value: ""}; node.attributes.style = node.attributes.style || {type: "string", value: ""};
if(node.attributes["style"].type === "string") { if(node.attributes.style.type === "string") {
node.attributes["style"].value += name + ":" + value + ";"; node.attributes.style.value += name + ":" + value + ";";
} }
}; };

View File

@ -24,15 +24,16 @@ exports.repackPlugin = function(title,additionalTiddlers,excludeTiddlers) {
throw "No such tiddler as " + title; throw "No such tiddler as " + title;
} }
// Extract the JSON // Extract the JSON
var jsonPluginTiddler;
try { try {
var jsonPluginTiddler = JSON.parse(pluginTiddler.fields.text); jsonPluginTiddler = JSON.parse(pluginTiddler.fields.text);
} catch(e) { } catch(e) {
throw "Cannot parse plugin tiddler " + title + "\nError: " + e; throw "Cannot parse plugin tiddler " + title + "\nError: " + e;
} }
// Get the list of tiddlers // Get the list of tiddlers
var tiddlers = Object.keys(jsonPluginTiddler.tiddlers); var tiddlers = Object.keys(jsonPluginTiddler.tiddlers);
// Add the additional tiddlers // Add the additional tiddlers
$tw.utils.pushTop(tiddlers,additionalTiddlers) $tw.utils.pushTop(tiddlers,additionalTiddlers);
// Remove any excluded tiddlers // Remove any excluded tiddlers
for(var t=tiddlers.length-1; t>=0; t--) { for(var t=tiddlers.length-1; t>=0; t--) {
if(excludeTiddlers.indexOf(tiddlers[t]) !== -1) { if(excludeTiddlers.indexOf(tiddlers[t]) !== -1) {
@ -71,8 +72,10 @@ exports.repackPlugin = function(title,additionalTiddlers,excludeTiddlers) {
$tw.wiki.deleteTiddler(title); $tw.wiki.deleteTiddler(title);
} }
}); });
// Trigger an autosave
$tw.rootWidget.dispatchEvent({type: "tw-auto-save-wiki"});
// Return a heartwarming confirmation // Return a heartwarming confirmation
return "Plugin " + title + " successfully saved"; return "Plugin " + title + " successfully saved";
} };
})(); })();

View File

@ -126,7 +126,7 @@ DropZoneWidget.prototype.importData = function(dataTransfer) {
return; return;
} }
} }
}; }
}; };
DropZoneWidget.prototype.importDataTypes = [ DropZoneWidget.prototype.importDataTypes = [

View File

@ -120,7 +120,7 @@ EditBitmapWidget.prototype.loadCanvas = function() {
self.initCanvas(self.currCanvas,DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT); self.initCanvas(self.currCanvas,DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT);
// Set the width and height input boxes // Set the width and height input boxes
self.updateSize(); self.updateSize();
} };
// Get the current bitmap into an image object // Get the current bitmap into an image object
currImage.src = "data:" + tiddler.fields.type + ";base64," + tiddler.fields.text; currImage.src = "data:" + tiddler.fields.type + ";base64," + tiddler.fields.text;
}; };
@ -135,7 +135,7 @@ EditBitmapWidget.prototype.initCanvas = function(canvas,width,height,image) {
ctx.fillStyle = "#fff"; ctx.fillStyle = "#fff";
ctx.fillRect(0,0,canvas.width,canvas.height); ctx.fillRect(0,0,canvas.width,canvas.height);
} }
} };
/* /*
** Update the input boxes with the actual size of the canvas ** Update the input boxes with the actual size of the canvas

View File

@ -78,7 +78,7 @@ FieldsWidget.prototype.execute = function() {
row = row.replace("$name$",fieldName); row = row.replace("$name$",fieldName);
row = row.replace("$value$",value); row = row.replace("$value$",value);
row = row.replace("$encoded_value$",$tw.utils.htmlEncode(value)); row = row.replace("$encoded_value$",$tw.utils.htmlEncode(value));
text.push(row) text.push(row);
} }
} }
} }

View File

@ -35,7 +35,7 @@ LinkWidget.prototype.render = function(parent,nextSibling) {
this.execute(); this.execute();
// Get the value of the tv-wikilinks configuration macro // Get the value of the tv-wikilinks configuration macro
var wikiLinksMacro = this.getVariable("tv-wikilinks"), var wikiLinksMacro = this.getVariable("tv-wikilinks"),
useWikiLinks = wikiLinksMacro ? !(wikiLinksMacro.trim() === "no") : true; useWikiLinks = wikiLinksMacro ? (wikiLinksMacro.trim() !== "no") : true;
// Render the link if required // Render the link if required
if(useWikiLinks) { if(useWikiLinks) {
this.renderLink(parent,nextSibling); this.renderLink(parent,nextSibling);

View File

@ -44,7 +44,7 @@ ListWidget.prototype.render = function(parent,nextSibling) {
// Construct the storyview // Construct the storyview
var StoryView = this.storyViews[this.storyViewName]; var StoryView = this.storyViews[this.storyViewName];
if(StoryView && !this.document.isTiddlyWikiFakeDom) { if(StoryView && !this.document.isTiddlyWikiFakeDom) {
this.storyview = new StoryView(this) this.storyview = new StoryView(this);
} else { } else {
this.storyview = null; this.storyview = null;
} }

View File

@ -243,6 +243,8 @@ NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {
// Remove the closed tiddler from the story // Remove the closed tiddler from the story
this.removeTitleFromStory(storyList,title); this.removeTitleFromStory(storyList,title);
this.saveStoryList(storyList); this.saveStoryList(storyList);
// Trigger an autosave
$tw.rootWidget.dispatchEvent({type: "tw-auto-save-wiki"});
return false; return false;
}; };
@ -281,9 +283,10 @@ NavigatorWidget.prototype.makeDraftTiddler = function(targetTitle) {
Generate a title for the draft of a given tiddler Generate a title for the draft of a given tiddler
*/ */
NavigatorWidget.prototype.generateDraftTitle = function(title) { NavigatorWidget.prototype.generateDraftTitle = function(title) {
var c = 0; var c = 0,
draftTitle;
do { do {
var draftTitle = "Draft " + (c ? (c + 1) + " " : "") + "of '" + title + "'"; draftTitle = "Draft " + (c ? (c + 1) + " " : "") + "of '" + title + "'";
c++; c++;
} while(this.wiki.tiddlerExists(draftTitle)); } while(this.wiki.tiddlerExists(draftTitle));
return draftTitle; return draftTitle;
@ -331,6 +334,8 @@ NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {
if(draftTitle !== this.storyTitle) { if(draftTitle !== this.storyTitle) {
this.saveStoryList(storyList); this.saveStoryList(storyList);
} }
// Trigger an autosave
$tw.rootWidget.dispatchEvent({type: "tw-auto-save-wiki"});
} }
} }
} }
@ -478,6 +483,8 @@ NavigatorWidget.prototype.handlePerformImportEvent = function(event) {
})); }));
// Navigate to the $:/Import tiddler // Navigate to the $:/Import tiddler
this.addToHistory([IMPORT_TITLE]); this.addToHistory([IMPORT_TITLE]);
// Trigger an autosave
$tw.rootWidget.dispatchEvent({type: "tw-auto-save-wiki"});
}; };
exports.navigator = NavigatorWidget; exports.navigator = NavigatorWidget;

View File

@ -41,7 +41,7 @@ RevealWidget.prototype.render = function(parent,nextSibling) {
$tw.utils.addClass(domNode,"tc-popup"); // Make sure that clicks don't dismiss popups within the revealed content $tw.utils.addClass(domNode,"tc-popup"); // Make sure that clicks don't dismiss popups within the revealed content
} }
if(!this.isOpen) { if(!this.isOpen) {
domNode.setAttribute("hidden","true") domNode.setAttribute("hidden","true");
} }
this.domNodes.push(domNode); this.domNodes.push(domNode);
}; };

View File

@ -44,7 +44,7 @@ TiddlerWidget.prototype.execute = function() {
this.setVariable("missingTiddlerClass",(this.wiki.tiddlerExists(this.tiddlerTitle) || this.wiki.isShadowTiddler(this.tiddlerTitle)) ? "tc-tiddler-exists" : "tc-tiddler-missing"); this.setVariable("missingTiddlerClass",(this.wiki.tiddlerExists(this.tiddlerTitle) || this.wiki.isShadowTiddler(this.tiddlerTitle)) ? "tc-tiddler-exists" : "tc-tiddler-missing");
this.setVariable("shadowTiddlerClass",this.wiki.isShadowTiddler(this.tiddlerTitle) ? "tc-tiddler-shadow" : ""); this.setVariable("shadowTiddlerClass",this.wiki.isShadowTiddler(this.tiddlerTitle) ? "tc-tiddler-shadow" : "");
this.setVariable("systemTiddlerClass",this.wiki.isSystemTiddler(this.tiddlerTitle) ? "tc-tiddler-system" : ""); this.setVariable("systemTiddlerClass",this.wiki.isSystemTiddler(this.tiddlerTitle) ? "tc-tiddler-system" : "");
this.setVariable("tiddlerTagClasses",this.getTagClasses()) this.setVariable("tiddlerTagClasses",this.getTagClasses());
// Construct the child widgets // Construct the child widgets
this.makeChildWidgets(); this.makeChildWidgets();
}; };

View File

@ -171,7 +171,7 @@ Widget.prototype.evaluateMacroModule = function(name,actualParams,defaultValue)
else for(var i=0; i<actualParams.length; ++i) { else for(var i=0; i<actualParams.length; ++i) {
args.push(actualParams[i].value); args.push(actualParams[i].value);
} }
return macro.run.apply(this,args) return macro.run.apply(this,args);
} else { } else {
return defaultValue; return defaultValue;
} }
@ -263,9 +263,14 @@ Widget.prototype.assignAttributes = function(domNode,options) {
v = undefined; v = undefined;
} }
if(v !== undefined) { if(v !== undefined) {
var b = a.split(":");
// Setting certain attributes can cause a DOM error (eg xmlns on the svg element) // Setting certain attributes can cause a DOM error (eg xmlns on the svg element)
try { try {
domNode.setAttributeNS(null,a,v); if (b.length == 2 && b[0] == "xlink"){
domNode.setAttributeNS("http://www.w3.org/1999/xlink",b[1],v);
} else {
domNode.setAttributeNS(null,a,v);
}
} catch(e) { } catch(e) {
} }
} }
@ -289,7 +294,7 @@ Construct the widget object for a parse tree node
Widget.prototype.makeChildWidget = function(parseTreeNode) { Widget.prototype.makeChildWidget = function(parseTreeNode) {
var WidgetClass = this.widgetClasses[parseTreeNode.type]; var WidgetClass = this.widgetClasses[parseTreeNode.type];
if(!WidgetClass) { if(!WidgetClass) {
WidgetClass = this.widgetClasses["text"]; WidgetClass = this.widgetClasses.text;
parseTreeNode = {type: "text", text: "Undefined widget '" + parseTreeNode.type + "'"}; parseTreeNode = {type: "text", text: "Undefined widget '" + parseTreeNode.type + "'"};
} }
return new WidgetClass(parseTreeNode,{ return new WidgetClass(parseTreeNode,{
@ -357,8 +362,7 @@ Widget.prototype.addEventListener = function(type,handler) {
} else { // The handler is a function } else { // The handler is a function
this.eventListeners[type] = function(event) { this.eventListeners[type] = function(event) {
return handler.call(self,event); return handler.call(self,event);
} };
} }
}; };

View File

@ -152,9 +152,13 @@ exports.enqueueTiddlerEvent = function(title,isDeleted) {
} }
}; };
exports.getSizeOfTiddlerEventQueue = function() {
return $tw.utils.count(this.changedTiddlers);
};
exports.clearTiddlerEventQueue = function() { exports.clearTiddlerEventQueue = function() {
this.changedTiddlers = Object.create(null); this.changedTiddlers = Object.create(null);
this.changeCount = Object.create(null) this.changeCount = Object.create(null);
}; };
exports.getChangeCount = function(title) { exports.getChangeCount = function(title) {
@ -172,12 +176,12 @@ Generate an unused title from the specified base
exports.generateNewTitle = function(baseTitle,options) { exports.generateNewTitle = function(baseTitle,options) {
options = options || {}; options = options || {};
var c = 0, var c = 0,
title = baseTitle; title = baseTitle;
while(this.tiddlerExists(title) || this.isShadowTiddler(title)) { while(this.tiddlerExists(title) || this.isShadowTiddler(title)) {
title = baseTitle + title = baseTitle +
(options.prefix || " ") + (options.prefix || " ") +
(++c); (++c);
}; }
return title; return title;
}; };
@ -457,7 +461,7 @@ exports.getTagMap = function() {
for(var index=0; index<tagArray.length; index++) { for(var index=0; index<tagArray.length; index++) {
var tag = tagArray[index]; var tag = tagArray[index];
if($tw.utils.hop(tags,tag)) { if($tw.utils.hop(tags,tag)) {
tags[tag].push(title) tags[tag].push(title);
} else { } else {
tags[tag] = [title]; tags[tag] = [title];
} }
@ -596,7 +600,7 @@ exports.getTiddlerData = function(titleOrTiddler,defaultData) {
var tiddler = titleOrTiddler, var tiddler = titleOrTiddler,
data; data;
if(!(tiddler instanceof $tw.Tiddler)) { if(!(tiddler instanceof $tw.Tiddler)) {
tiddler = this.getTiddler(tiddler) tiddler = this.getTiddler(tiddler);
} }
if(tiddler && tiddler.fields.text) { if(tiddler && tiddler.fields.text) {
switch(tiddler.fields.type) { switch(tiddler.fields.type) {
@ -679,7 +683,7 @@ exports.getGlobalCache = function(cacheName,initializer) {
exports.clearGlobalCache = function() { exports.clearGlobalCache = function() {
this.globalCache = Object.create(null); this.globalCache = Object.create(null);
} };
// Return the named cache object for a tiddler. If the cache doesn't exist then the initializer function is invoked to create it // Return the named cache object for a tiddler. If the cache doesn't exist then the initializer function is invoked to create it
exports.getCacheForTiddler = function(title,cacheName,initializer) { exports.getCacheForTiddler = function(title,cacheName,initializer) {
@ -687,18 +691,18 @@ exports.getCacheForTiddler = function(title,cacheName,initializer) {
// Temporarily disable caching so that tweakParseTreeNode() works // Temporarily disable caching so that tweakParseTreeNode() works
return initializer(); return initializer();
this.caches = this.caches || Object.create(null); // this.caches = this.caches || Object.create(null);
var caches = this.caches[title]; // var caches = this.caches[title];
if(caches && caches[cacheName]) { // if(caches && caches[cacheName]) {
return caches[cacheName]; // return caches[cacheName];
} else { // } else {
if(!caches) { // if(!caches) {
caches = Object.create(null); // caches = Object.create(null);
this.caches[title] = caches; // this.caches[title] = caches;
} // }
caches[cacheName] = initializer(); // caches[cacheName] = initializer();
return caches[cacheName]; // return caches[cacheName];
} // }
}; };
// Clear all caches associated with a particular tiddler // Clear all caches associated with a particular tiddler
@ -789,16 +793,16 @@ var tweakParser = function(parser) {
exports.parseText = function(type,text,options) { exports.parseText = function(type,text,options) {
var parser = this.old_parseText(type,text,options); var parser = this.old_parseText(type,text,options);
if(parser) { if(parser) {
tweakParser(parser) tweakParser(parser);
}; }
return parser; return parser;
}; };
exports.parseTiddler = function(title,options) { exports.parseTiddler = function(title,options) {
var parser = this.old_parseTiddler(title,options); var parser = this.old_parseTiddler(title,options);
if(parser) { if(parser) {
tweakParser(parser) tweakParser(parser);
}; }
return parser; return parser;
}; };
@ -957,7 +961,9 @@ Options available:
*/ */
exports.search = function(text,options) { exports.search = function(text,options) {
options = options || {}; options = options || {};
var self = this,t; var self = this,
t,
invert = !!options.invert;
// Convert the search string into a regexp for each term // Convert the search string into a regexp for each term
var terms, searchTermsRegExps, var terms, searchTermsRegExps,
flags = options.caseSensitive ? "" : "i"; flags = options.caseSensitive ? "" : "i";
@ -1007,7 +1013,7 @@ exports.search = function(text,options) {
var results = [], var results = [],
source = options.source || this.each; source = options.source || this.each;
source(function(tiddler,title) { source(function(tiddler,title) {
if(!!searchTiddler(title) === !options.invert) { if(searchTiddler(title) !== options.invert) {
results.push(title); results.push(title);
} }
}); });
@ -1056,7 +1062,7 @@ exports.readFiles = function(files,callback) {
callback(result); callback(result);
} }
}); });
}; }
return files.length; return files.length;
}; };

View File

@ -1,3 +1,3 @@
title: $:/config/SaverFilter title: $:/config/SaverFilter
[!is[shadow]] -[[$:/HistoryList]] -[[$:/StoryList]] -[[$:/Import]] -[[$:/isEncrypted]] -[[$:/UploadName]] -[prefix[$:/status]] -[prefix[$:/state]] -[prefix[$:/temp]] -[has[draft.of]] [all[]] -[[$:/HistoryList]] -[[$:/StoryList]] -[[$:/Import]] -[[$:/isEncrypted]] -[[$:/UploadName]] -[prefix[$:/state]] -[prefix[$:/temp]] -[has[draft.of]]

View File

@ -1,3 +1,3 @@
title: $:/config/SyncFilter title: $:/config/SyncFilter
[is[tiddler]] -[[$:/HistoryList]] -[[$:/StoryList]] -[[$:/Import]] -[[$:/isEncrypted]] -[prefix[$:/status]] -[prefix[$:/state]] -[prefix[$:/temp]] [all[]] -[[$:/HistoryList]] -[[$:/StoryList]] -[[$:/Import]] -[[$:/isEncrypted]] -[prefix[$:/status]] -[prefix[$:/state]] -[prefix[$:/temp]]

View File

@ -1,6 +1,6 @@
caption: 5.0.16-beta caption: 5.0.16-beta
created: 20140826131615798 created: 20140830131615798
modified: 20140826131615798 modified: 20140830131615798
tags: releasenote tags: releasenote
title: Release 5.0.16-beta title: Release 5.0.16-beta
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
@ -9,16 +9,22 @@ type: text/vnd.tiddlywiki
!! Incompatible Changes !! Incompatible Changes
These changes have the potential to break existing tiddlers. 5.0.16-beta brings more incompatible changes than any previous release. These changes are likely to break almost all plugins written for previous releases of TiddlyWiki 5, and will break many customisations.
* [[Changed|https://github.com/Jermolene/TiddlyWiki5/issues/764]] all CSS class prefixes from `tw-` to `tc-` (eg `tw-tiddler-frame` has become `tc-tiddler-frame`; missing prefixes have also been added, so `btn-invisible` has become `tc-btn-invisible`)
* [[Changed|https://github.com/Jermolene/TiddlyWiki5/commit/2f69ea362cd673f59b9fadbe11f1f95549a59813]] all message prefixes from `tw-` to `tm-` (eg `tw-close-tiddler` has become `tm-close-tiddler`)
* [[Changed|https://github.com/Jermolene/TiddlyWiki5/commit/89fd5379dd78887fc21746d792072bf5a25f0c56]] all variable prefixes from `tw-` to `tv-` (eg `tw-config-toolbar-icons` has become `tv-config-toolbar-icons`)
* [[Changed|https://github.com/Jermolene/TiddlyWiki5/commit/112a9a95d95e9f62f110c97a4faaf537c5c100b1]] prefix/removeprefix filter operators to be case-sensitive * [[Changed|https://github.com/Jermolene/TiddlyWiki5/commit/112a9a95d95e9f62f110c97a4faaf537c5c100b1]] prefix/removeprefix filter operators to be case-sensitive
!! Usability Improvements !! Usability Improvements
* [[Amended|https://github.com/Jermolene/TiddlyWiki5/commit/e47852cb141b384ad2a9097eca795545cb5b2494]] behaviour of the [[tw-browser-refresh|WidgetMessage: tw-browser-refresh]] message so that it no longer clears the location hash * [[Amended|https://github.com/Jermolene/TiddlyWiki5/commit/e47852cb141b384ad2a9097eca795545cb5b2494]] behaviour of the [[tw-browser-refresh|WidgetMessage: tw-browser-refresh]] message so that it no longer clears the location hash
* [[Hide|https://github.com/Jermolene/TiddlyWiki5/commit/88c9c0c3ee115917b8c1a9126452bb0574061857]] toolbar buttons from static renderings
!! Hackability Improvements !! Hackability Improvements
* [[Extend|https://github.com/Jermolene/TiddlyWiki5/commit/48312272adb17610db96d50758e6af947cab7b1d]] the [FilterOperator: all]] to be able to select all the source tiddlers
* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/43aeb47fc34f1ba424030c4f78ee907fe7b1d5d8]] problem with single line macro definitions incorrectly including whitespace in the value. (For example, `\define mymacro() yes` would set the macro value to " yes", with a leading space)
* [[Extend|https://github.com/Jermolene/TiddlyWiki5/commit/d2a5a12f2d6b6ccc36dd22a70ac2def08d1d3722]] TableOfContentsMacro to use the caption field if present * [[Extend|https://github.com/Jermolene/TiddlyWiki5/commit/d2a5a12f2d6b6ccc36dd22a70ac2def08d1d3722]] TableOfContentsMacro to use the caption field if present
* [[Configurability|https://github.com/Jermolene/TiddlyWiki5/commit/b437f1b450f5f2a3104a9086f7c674299b53b9bc]] for the default tab shown in the tiddler info panel (see [[Configuring the default TiddlerInfo tab]]) * [[Configurability|https://github.com/Jermolene/TiddlyWiki5/commit/b437f1b450f5f2a3104a9086f7c674299b53b9bc]] for the default tab shown in the tiddler info panel (see [[Configuring the default TiddlerInfo tab]])
* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/dcf4e93a3283e3e93cc14e50366f9b0252870835]] [[suffix|FilterOperator: suffix]] and [[removesuffix|FilterOperator: removesuffix]] filter operators * [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/dcf4e93a3283e3e93cc14e50366f9b0252870835]] [[suffix|FilterOperator: suffix]] and [[removesuffix|FilterOperator: removesuffix]] filter operators
@ -32,4 +38,5 @@ These changes have the potential to break existing tiddlers.
[[@Jermolene|https://github.com/Jermolene]] would like to thank the contributors to this release who have generously given their time to help improve TiddlyWiki: [[@Jermolene|https://github.com/Jermolene]] would like to thank the contributors to this release who have generously given their time to help improve TiddlyWiki:
* [[@BramChen|https://github.com/BramChen]] * [[@BramChen|https://github.com/BramChen]]
* [[@pmario|https://github.com/pmario]]
* [[@xcazin|https://github.com/xcazin]] * [[@xcazin|https://github.com/xcazin]]

View File

@ -17,4 +17,5 @@ For example:
|`[all[current]]` |Selects the current tiddler | |`[all[current]]` |Selects the current tiddler |
|`[all[missing]]` |Selects all MissingTiddlers | |`[all[missing]]` |Selects all MissingTiddlers |
|`[all[orphans]]` |Selects all OrphanTiddlers | |`[all[orphans]]` |Selects all OrphanTiddlers |
|`[all[]]` |Selects all the source tiddlers available to the filter |

View File

@ -1,7 +1,7 @@
title: Improving TiddlyWiki Documentation title: Improving TiddlyWiki Documentation
tags: howto tags: howto
created: 20140820151051019 created: 20140820151051019
modified: 20140820151051019 modified: 20140830151051019
Anyone can submit improvements to the TiddlyWiki documentation that appears on http://tiddlywiki.com. Anyone can submit improvements to the TiddlyWiki documentation that appears on http://tiddlywiki.com.
@ -9,6 +9,7 @@ Anyone can submit improvements to the TiddlyWiki documentation that appears on h
# On http://tiddlywiki.com, click "edit" on the tiddler you want to improve # On http://tiddlywiki.com, click "edit" on the tiddler you want to improve
# You should see a pink banner with the text: //Can you help us improve this documentation? Find out how to edit this tiddler on ~GitHub// # You should see a pink banner with the text: //Can you help us improve this documentation? Find out how to edit this tiddler on ~GitHub//
# Click on the external link ...''this tiddler on ~GitHub'' # Click on the external link ...''this tiddler on ~GitHub''
## You will be prompted that "you need to fork this repository to propose changes". A "fork" is your own copy of the repository that incorporates the changes you are proposing
# A new browser tab should open ready to edit the tiddler on github.com # A new browser tab should open ready to edit the tiddler on github.com
# Below the edit box for the tiddler text you should see a box labelled ''Propose file change'' # Below the edit box for the tiddler text you should see a box labelled ''Propose file change''
# Enter a brief title to explain the change (eg, "Clarify attribute syntax instability") # Enter a brief title to explain the change (eg, "Clarify attribute syntax instability")
@ -17,3 +18,5 @@ Anyone can submit improvements to the TiddlyWiki documentation that appears on h
# On the following screen, click the green button labelled ''Create pull request'' # On the following screen, click the green button labelled ''Create pull request''
[[Jermolene|https://github.com/Jermolene]] or one of the other core developers will then have the opportunity to merge your pull request so that it is incorporated into the next build of http://tiddlywiki.com. [[Jermolene|https://github.com/Jermolene]] or one of the other core developers will then have the opportunity to merge your pull request so that it is incorporated into the next build of http://tiddlywiki.com.
There will be a short video soon!

View File

@ -0,0 +1,11 @@
created: 20140830112325641
modified: 20140830115149288
tags: message
title: WidgetMessage: tm-auto-save-wiki
type: text/vnd.tiddlywiki
The autosave wiki message causes the current saver module to perform a background save if it is required.
The autosave wiki message should be generated whenever changes are made to the store. For example, the navigator widget generates the autosave wiki message as part of its handling of the [[WidgetMessage: tw-save-tiddler]], [[WidgetMessage: tw-delete-tiddler]] and [[WidgetMessage: tw-perform-import]].
The autosave wiki message is handled by the TiddlyWiki core SyncMechanism which invokes the current [[SaverModule|SaverModules]]. Not all SaverModules can handle autosaving.

View File

@ -13,7 +13,7 @@ Initialise $:/info/browser tiddlers
"use strict"; "use strict";
exports.getInfoTiddlerFields = function() { exports.getInfoTiddlerFields = function() {
var mapBoolean = function(value) {return value ? "yes" : "no"}, var mapBoolean = function(value) {return value ? "yes" : "no";},
infoTiddlerFields = []; infoTiddlerFields = [];
// Basics // Basics
if($tw.browser) { if($tw.browser) {

View File

@ -113,7 +113,7 @@ CecilyStoryView.prototype.lookupTiddlerInMap = function(title,domNode) {
if(tiddler) { if(tiddler) {
var draftOf = tiddler.fields["draft.of"]; var draftOf = tiddler.fields["draft.of"];
if(draftOf && this.map.positions[draftOf]) { if(draftOf && this.map.positions[draftOf]) {
return this.map.positions[draftOf] return this.map.positions[draftOf];
} }
} }
// Try looking the target tiddler up in the map // Try looking the target tiddler up in the map

View File

@ -25,14 +25,14 @@ Config options "$:/config/CodeMirror" e.g. to allow vim key bindings
/*global $tw: false */ /*global $tw: false */
"use strict"; "use strict";
var CODEMIRROR_OPTIONS = "$:/config/CodeMirror" var CODEMIRROR_OPTIONS = "$:/config/CodeMirror";
// Install CodeMirror // Install CodeMirror
if($tw.browser && !window.CodeMirror) { if($tw.browser && !window.CodeMirror) {
window.CodeMirror = require("$:/plugins/tiddlywiki/codemirror/lib/codemirror.js"); window.CodeMirror = require("$:/plugins/tiddlywiki/codemirror/lib/codemirror.js");
// Install required CodeMirror plugins // Install required CodeMirror plugins
var configOptions = $tw.wiki.getTiddlerData(CODEMIRROR_OPTIONS,{}), var configOptions = $tw.wiki.getTiddlerData(CODEMIRROR_OPTIONS,{}),
req = configOptions["require"]; req = configOptions.require;
if(req) { if(req) {
if($tw.utils.isArray(req)) { if($tw.utils.isArray(req)) {
for(var index=0; index<req.length; index++) { for(var index=0; index<req.length; index++) {

View File

@ -57,7 +57,7 @@ BarWidget.prototype.createChart = function(parent,nextSibling) {
n = 4; // number of layers n = 4; // number of layers
m = 58; // number of samples per layer m = 58; // number of samples per layer
stack = d3.layout.stack(); stack = d3.layout.stack();
layers = stack(d3.range(n).map(function() { return bumpLayer(m, .1); })); layers = stack(d3.range(n).map(function() { return bumpLayer(m, 0.1); }));
} }
// Calculate the maximum data values // Calculate the maximum data values
var yGroupMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y; }); }), var yGroupMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y; }); }),
@ -69,7 +69,7 @@ BarWidget.prototype.createChart = function(parent,nextSibling) {
// x-scale // x-scale
var x = d3.scale.ordinal() var x = d3.scale.ordinal()
.domain(d3.range(m)) .domain(d3.range(m))
.rangeRoundBands([0, width], .08); .rangeRoundBands([0, width], 0.08);
// y-scale // y-scale
var y = d3.scale.linear() var y = d3.scale.linear()
.domain([0, yStackMax]) .domain([0, yStackMax])
@ -96,13 +96,13 @@ BarWidget.prototype.createChart = function(parent,nextSibling) {
// Create the layers // Create the layers
var layer = mainGroup.selectAll(".layer") var layer = mainGroup.selectAll(".layer")
.data(layers) .data(layers)
.enter().append("g") .enter().append("g")
.attr("class", "layer") .attr("class", "layer")
.style("fill", function(d, i) { return color(i); }); .style("fill", function(d, i) { return color(i); });
// Create the rectangles in each layer // Create the rectangles in each layer
var rect = layer.selectAll("rect") var rect = layer.selectAll("rect")
.data(function(d) { return d; }) .data(function(d) { return d; })
.enter().append("rect") .enter().append("rect")
.attr("x", function(d) { return x(d.x); }) .attr("x", function(d) { return x(d.x); })
.attr("y", height) .attr("y", height)
.attr("width", x.rangeBand()) .attr("width", x.rangeBand())
@ -131,44 +131,44 @@ BarWidget.prototype.createChart = function(parent,nextSibling) {
}; };
function transitionGrouped() { function transitionGrouped() {
y.domain([0, yGroupMax]); y.domain([0, yGroupMax]);
rect.transition() rect.transition()
.duration(500) .duration(500)
.delay(function(d, i) { return i * 10; }) .delay(function(d, i) { return i * 10; })
.attr("x", function(d, i, j) { return x(d.x) + x.rangeBand() / n * j; }) .attr("x", function(d, i, j) { return x(d.x) + x.rangeBand() / n * j; })
.attr("width", x.rangeBand() / n) .attr("width", x.rangeBand() / n)
.transition() .transition()
.attr("y", function(d) { return y(d.y); }) .attr("y", function(d) { return y(d.y); })
.attr("height", function(d) { return height - y(d.y); }); .attr("height", function(d) { return height - y(d.y); });
} }
function transitionStacked() { function transitionStacked() {
y.domain([0, yStackMax]); y.domain([0, yStackMax]);
rect.transition() rect.transition()
.duration(500) .duration(500)
.delay(function(d, i) { return i * 10; }) .delay(function(d, i) { return i * 10; })
.attr("y", function(d) { return y(d.y0 + d.y); }) .attr("y", function(d) { return y(d.y0 + d.y); })
.attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); }) .attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); })
.transition() .transition()
.attr("x", function(d) { return x(d.x); }) .attr("x", function(d) { return x(d.x); })
.attr("width", x.rangeBand()); .attr("width", x.rangeBand());
} }
// Inspired by Lee Byron's test data generator. // Inspired by Lee Byron's test data generator.
function bumpLayer(n, o) { function bumpLayer(n, o) {
function bump(a) { function bump(a) {
var x = 1 / (.1 + Math.random()), var x = 1 / (0.1 + Math.random()),
y = 2 * Math.random() - .5, y = 2 * Math.random() - 0.5,
z = 10 / (.1 + Math.random()); z = 10 / (0.1 + Math.random());
for (var i = 0; i < n; i++) { for (var i = 0; i < n; i++) {
var w = (i / n - y) * z; var w = (i / n - y) * z;
a[i] += x * Math.exp(-w * w); a[i] += x * Math.exp(-w * w);
}
} }
} var a = [], i;
var a = [], i; for (i = 0; i < n; ++i) a[i] = o + o * Math.random();
for (i = 0; i < n; ++i) a[i] = o + o * Math.random(); for (i = 0; i < 5; ++i) bump(a);
for (i = 0; i < 5; ++i) bump(a); return a.map(function(d, i) { return {x: i, y: Math.max(0, d)}; });
return a.map(function(d, i) { return {x: i, y: Math.max(0, d)}; });
} }
}; };

View File

@ -24,20 +24,19 @@ function FileSystemAdaptor(options) {
this.logger = new $tw.utils.Logger("FileSystem"); this.logger = new $tw.utils.Logger("FileSystem");
this.setwatcher = function(filename, title) { this.setwatcher = function(filename, title) {
return undefined; return undefined;
return this.watchers[filename] = this.watchers[filename] || //return this.watchers[filename] = this.watchers[filename] ||
fs.watch(filename, {persistent: false}, function(e) { // fs.watch(filename, {persistent: false}, function(e) {
self.logger.log("Error:",e,filename); // self.logger.log("Error:",e,filename);
if(e === "change") { // if(e === "change") {
var tiddlers = $tw.loadTiddlersFromFile(filename).tiddlers; // var tiddlers = $tw.loadTiddlersFromFile(filename).tiddlers;
for(var t in tiddlers) { // for(var t in tiddlers) {
if(tiddlers[t].title) { // if(tiddlers[t].title) {
self.wiki.addTiddler(tiddlers[t]); // self.wiki.addTiddler(tiddlers[t]);
} // }
} // }
} // }
}); // });
} };
for(var f in $tw.boot.files) { for(var f in $tw.boot.files) {
var fileInfo = $tw.boot.files[f]; var fileInfo = $tw.boot.files[f];
this.setwatcher(fileInfo.filepath, f); this.setwatcher(fileInfo.filepath, f);
@ -108,7 +107,7 @@ Given a tiddler title and an array of existing filenames, generate a new legal f
*/ */
FileSystemAdaptor.prototype.generateTiddlerFilename = function(title,extension,existingFilenames) { FileSystemAdaptor.prototype.generateTiddlerFilename = function(title,extension,existingFilenames) {
// First remove any of the characters that are illegal in Windows filenames // First remove any of the characters that are illegal in Windows filenames
var baseFilename = title.replace(/\<|\>|\:|\"|\/|\\|\||\?|\*|\^/g,"_"); var baseFilename = title.replace(/<|>|\:|\"|\/|\\|\||\?|\*|\^/g,"_");
// Truncate the filename if it is too long // Truncate the filename if it is too long
if(baseFilename.length > 200) { if(baseFilename.length > 200) {
baseFilename = baseFilename.substr(0,200) + extension; baseFilename = baseFilename.substr(0,200) + extension;

View File

@ -51,7 +51,7 @@ exports.startup = function() {
// The HTMLReporter links itself into the jasmine object automatically, but we have to manually add the node reporter // The HTMLReporter links itself into the jasmine object automatically, but we have to manually add the node reporter
jasmine.jasmine.TerminalVerboseReporter = reporterExports.jasmineNode.TerminalVerboseReporter; jasmine.jasmine.TerminalVerboseReporter = reporterExports.jasmineNode.TerminalVerboseReporter;
jasmine.jasmine.TerminalReporter = reporterExports.jasmineNode.TerminalReporter; jasmine.jasmine.TerminalReporter = reporterExports.jasmineNode.TerminalReporter;
jasmineEnv.addReporter(new jasmine.jasmine.TerminalVerboseReporter({ jasmineEnv.addReporter(new jasmine.jasmine.TerminalVerboseReporter({
print: require("util").print, print: require("util").print,
color: true, color: true,
includeStackTrace: true includeStackTrace: true

View File

@ -48,7 +48,7 @@ Static method that returns true if this saver is capable of working
*/ */
exports.canSave = function(wiki) { exports.canSave = function(wiki) {
// Check if we're running under node-webkit // Check if we're running under node-webkit
return (typeof process == "object") return (typeof process == "object");
}; };
/* /*

View File

@ -37,7 +37,7 @@ TiddlyWebAdaptor.prototype.getHost = function() {
TiddlyWebAdaptor.prototype.getTiddlerInfo = function(tiddler) { TiddlyWebAdaptor.prototype.getTiddlerInfo = function(tiddler) {
return { return {
bag: tiddler.fields["bag"] bag: tiddler.fields.bag
}; };
}; };
@ -248,7 +248,7 @@ TiddlyWebAdaptor.prototype.convertTiddlerToTiddlyWebFormat = function(tiddler) {
// Default the content type and convert the type "text/x-tiddlywiki" into null // Default the content type and convert the type "text/x-tiddlywiki" into null
if(result.type === "text/x-tiddlywiki") { if(result.type === "text/x-tiddlywiki") {
result.type = null; result.type = null;
}; }
result.type = result.type || "text/vnd.tiddlywiki"; result.type = result.type || "text/vnd.tiddlywiki";
return JSON.stringify(result,null,$tw.config.preferences.jsonSpaces); return JSON.stringify(result,null,$tw.config.preferences.jsonSpaces);
}; };

File diff suppressed because one or more lines are too long