diff --git a/.jshintignore b/.jshintignore new file mode 100644 index 000000000..cca917270 --- /dev/null +++ b/.jshintignore @@ -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/ diff --git a/core/modules/commands/build.js b/core/modules/commands/build.js index 6d6e04548..8471119d7 100644 --- a/core/modules/commands/build.js +++ b/core/modules/commands/build.js @@ -26,7 +26,7 @@ Command.prototype.execute = function() { // Get the build targets defined in the wiki var buildTargets = $tw.boot.wikiInfo.build; if(!buildTargets) { - return "No build targets defined" + return "No build targets defined"; } // Loop through each of the specified targets var targets; diff --git a/core/modules/commands/server.js b/core/modules/commands/server.js index e724aa53f..edbb1f1ca 100644 --- a/core/modules/commands/server.js +++ b/core/modules/commands/server.js @@ -78,7 +78,7 @@ SimpleServer.prototype.findMatchingRoute = function(request,state) { }; SimpleServer.prototype.checkCredentials = function(request,incomingUsername,incomingPassword) { - var header = request.headers["authorization"] || "", + var header = request.headers.authorization || "", token = header.split(/\s+/).pop() || "", auth = $tw.utils.base64Decode(token), parts = auth.split(/:/), @@ -89,7 +89,7 @@ SimpleServer.prototype.checkCredentials = function(request,incomingUsername,inco } else { return "DENIED"; } -} +}; SimpleServer.prototype.listen = function(port,host) { var self = this; @@ -167,8 +167,8 @@ var Command = function(params,commander,callback) { delete fields.fields; } // Remove any revision field - if(fields["revision"]) { - delete fields["revision"]; + if(fields.revision) { + delete fields.revision; } state.wiki.addTiddler(new $tw.Tiddler(state.wiki.getCreationFields(),fields,{title: title})); var changeCount = state.wiki.getChangeCount(title).toString(); @@ -237,7 +237,7 @@ var Command = function(params,commander,callback) { tiddlerFields[name] = tiddler.getFieldString(name); } }); - tiddlerFields["revision"] = state.wiki.getChangeCount(title); + tiddlerFields.revision = state.wiki.getChangeCount(title); tiddlerFields.type = tiddlerFields.type || "text/vnd.tiddlywiki"; tiddlers.push(tiddlerFields); }); @@ -265,7 +265,7 @@ var Command = function(params,commander,callback) { tiddlerFields.fields[name] = value; } }); - tiddlerFields["revision"] = state.wiki.getChangeCount(title); + tiddlerFields.revision = state.wiki.getChangeCount(title); tiddlerFields.type = tiddlerFields.type || "text/vnd.tiddlywiki"; response.writeHead(200, {"Content-Type": "application/json"}); response.end(JSON.stringify(tiddlerFields),"utf8"); diff --git a/core/modules/deserializers.js b/core/modules/deserializers.js index 5e3fce42e..ba31c5314 100644 --- a/core/modules/deserializers.js +++ b/core/modules/deserializers.js @@ -109,7 +109,7 @@ exports["text/html"] = function(text,fields) { if(sysMatch) { results.push.apply(results,deserializeTiddlyWikiFile(text,systemAreaMarkerRegExp.lastIndex,!!sysMatch[1],fields)); } - return results + return results; } else { // Check whether we've got an encrypted file var encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text); diff --git a/core/modules/filters/all.js b/core/modules/filters/all.js index ee31f4abb..da9e949dc 100644 --- a/core/modules/filters/all.js +++ b/core/modules/filters/all.js @@ -34,7 +34,9 @@ exports.all = function(source,operator,options) { var results = [], subops = operator.operand.split("+"); // 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; } else if(subops.length === 1 && subops[0] === "shadows") { return options.wiki.eachShadow; diff --git a/core/modules/filters/is.js b/core/modules/filters/is.js index fc45a62f9..d27d00907 100644 --- a/core/modules/filters/is.js +++ b/core/modules/filters/is.js @@ -20,7 +20,7 @@ function getIsFilterOperators() { $tw.modules.applyMethods("isfilteroperator",isFilterOperators); } return isFilterOperators; -}; +} /* Export our filter function diff --git a/core/modules/filters/plugintiddlers.js b/core/modules/filters/plugintiddlers.js index 84d641587..9845e8ce8 100644 --- a/core/modules/filters/plugintiddlers.js +++ b/core/modules/filters/plugintiddlers.js @@ -18,12 +18,12 @@ Export our filter function exports.plugintiddlers = function(source,operator,options) { var results = []; source(function(tiddler,title) { - var pluginInfo = options.wiki.getPluginInfo(title) || options.wiki.getTiddlerData(title,{tiddlers:[]}); - if(pluginInfo) { - $tw.utils.each(pluginInfo.tiddlers,function(fields,title) { - results.push(title); - }); - } + var pluginInfo = options.wiki.getPluginInfo(title) || options.wiki.getTiddlerData(title,{tiddlers:[]}); + if(pluginInfo) { + $tw.utils.each(pluginInfo.tiddlers,function(fields,title) { + results.push(title); + }); + } }); results.sort(); return results; diff --git a/core/modules/filters/shadowsource.js b/core/modules/filters/shadowsource.js index 88ae4132e..f16e2bcc7 100644 --- a/core/modules/filters/shadowsource.js +++ b/core/modules/filters/shadowsource.js @@ -19,9 +19,9 @@ exports.shadowsource = function(source,operator,options) { var results = []; source(function(tiddler,title) { var source = options.wiki.getShadowSource(title); - if(source) { + if(source) { $tw.utils.pushTop(results,source); - } + } }); results.sort(); return results; diff --git a/core/modules/filters/sort.js b/core/modules/filters/sort.js index 408de81eb..f993825df 100644 --- a/core/modules/filters/sort.js +++ b/core/modules/filters/sort.js @@ -45,6 +45,6 @@ var prepare_results = function (source) { results.push(title); }); return results; -} +}; })(); diff --git a/core/modules/info/platform.js b/core/modules/info/platform.js index f084d6c00..9f6097f74 100644 --- a/core/modules/info/platform.js +++ b/core/modules/info/platform.js @@ -13,7 +13,7 @@ Initialise basic platform $:/info/ tiddlers "use strict"; exports.getInfoTiddlerFields = function() { - var mapBoolean = function(value) {return value ? "yes" : "no"}, + var mapBoolean = function(value) {return value ? "yes" : "no";}, infoTiddlerFields = []; // Basics infoTiddlerFields.push({title: "$:/info/browser", text: mapBoolean(!!$tw.browser)}); diff --git a/core/modules/parsers/wikiparser/rules/commentblock.js b/core/modules/parsers/wikiparser/rules/commentblock.js index cb1bd1a93..84ee897ba 100644 --- a/core/modules/parsers/wikiparser/rules/commentblock.js +++ b/core/modules/parsers/wikiparser/rules/commentblock.js @@ -23,8 +23,8 @@ exports.types = {block: true}; exports.init = function(parser) { this.parser = parser; - this.matchRegExp = /\/mg; }; exports.findNextMatch = function(startPos) { diff --git a/core/modules/parsers/wikiparser/rules/commentinline.js b/core/modules/parsers/wikiparser/rules/commentinline.js index fd9c6a10e..6e697e6c0 100644 --- a/core/modules/parsers/wikiparser/rules/commentinline.js +++ b/core/modules/parsers/wikiparser/rules/commentinline.js @@ -23,8 +23,8 @@ exports.types = {inline: true}; exports.init = function(parser) { this.parser = parser; - this.matchRegExp = /\/mg; }; exports.findNextMatch = function(startPos) { diff --git a/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js b/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js index 5a863a42a..7ab4801bf 100644 --- a/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js +++ b/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js @@ -56,7 +56,7 @@ exports.parse = function() { node.attributes.style = {type: "string", value: style}; } if(classes) { - node.attributes["itemClass"] = {type: "string", value: classes.split(".").join(" ")}; + node.attributes.itemClass = {type: "string", value: classes.split(".").join(" ")}; } return [node]; }; diff --git a/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js b/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js index abda75f95..029fd6802 100644 --- a/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js +++ b/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js @@ -55,7 +55,7 @@ exports.parse = function() { node.attributes.style = {type: "string", value: style}; } if(classes) { - node.attributes["itemClass"] = {type: "string", value: classes.split(".").join(" ")}; + node.attributes.itemClass = {type: "string", value: classes.split(".").join(" ")}; } return [node]; }; diff --git a/core/modules/parsers/wikiparser/rules/hardlinebreaks.js b/core/modules/parsers/wikiparser/rules/hardlinebreaks.js index 7573a5501..c278686b4 100644 --- a/core/modules/parsers/wikiparser/rules/hardlinebreaks.js +++ b/core/modules/parsers/wikiparser/rules/hardlinebreaks.js @@ -34,7 +34,8 @@ exports.init = function(parser) { exports.parse = function() { var reEnd = /(""")|(\r?\n)/mg, - tree = []; + tree = [], + match; // Move past the match this.parser.pos = this.matchRegExp.lastIndex; do { @@ -42,7 +43,7 @@ exports.parse = function() { tree.push.apply(tree,this.parser.parseInlineRun(reEnd,{eatTerminator: false})); // Redo the terminator match reEnd.lastIndex = this.parser.pos; - var match = reEnd.exec(this.parser.source); + match = reEnd.exec(this.parser.source); if(match) { this.parser.pos = reEnd.lastIndex; // Add a line break if the terminator was a line break diff --git a/core/modules/parsers/wikiparser/rules/quoteblock.js b/core/modules/parsers/wikiparser/rules/quoteblock.js index 8f83c57e8..71b689680 100644 --- a/core/modules/parsers/wikiparser/rules/quoteblock.js +++ b/core/modules/parsers/wikiparser/rules/quoteblock.js @@ -55,7 +55,6 @@ exports.parse = function() { classes.push.apply(classes, this.parser.parseClasses()); this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true}); var cite = this.parser.parseInlineRun(/(\r?\n)/mg); - // before handling the cite, parse the body of the quote var tree= this.parser.parseBlocks(reEndString); // If we got a cite, put it before the text @@ -66,10 +65,9 @@ exports.parse = function() { children: cite }); } - // Parse any optional cite 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(cite.length > 0) { tree.push({ @@ -78,7 +76,6 @@ exports.parse = function() { children: cite }); } - // Return the blockquote element return [{ type: "element", diff --git a/core/modules/parsers/wikiparser/rules/table.js b/core/modules/parsers/wikiparser/rules/table.js index eb830b855..fb72f6890 100644 --- a/core/modules/parsers/wikiparser/rules/table.js +++ b/core/modules/parsers/wikiparser/rules/table.js @@ -27,7 +27,8 @@ var processRow = function(prevColumns) { tree = [], col = 0, colSpanCount = 1, - prevCell; + prevCell, + vAlign; // Match a single cell cellRegExp.lastIndex = this.parser.pos; var cellMatch = cellRegExp.exec(this.parser.source); @@ -38,7 +39,7 @@ var processRow = function(prevColumns) { if(last) { 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); if(colSpanCount > 1) { $tw.utils.addAttributeToParseTreeNode(last.element,"colspan",colSpanCount); @@ -74,8 +75,8 @@ var processRow = function(prevColumns) { // For ordinary cells, step beyond the opening `|` this.parser.pos++; // Look for a space at the start of the cell - var spaceLeft = false, - vAlign = null; + var spaceLeft = false; + vAlign = null; if(this.parser.source.substr(this.parser.pos).search(/^\^([^\^]|\^\^)/) === 0) { vAlign = "top"; } else if(this.parser.source.substr(this.parser.pos).search(/^,([^,]|,,)/) === 0) { diff --git a/core/modules/parsers/wikiparser/rules/transcludeblock.js b/core/modules/parsers/wikiparser/rules/transcludeblock.js index 6cfb472fc..1a5df1e06 100644 --- a/core/modules/parsers/wikiparser/rules/transcludeblock.js +++ b/core/modules/parsers/wikiparser/rules/transcludeblock.js @@ -41,19 +41,20 @@ exports.parse = function() { isBlock: true }; // Prepare the tiddler widget + var tr, targetTitle, targetField, targetIndex, tiddlerNode; if(textRef) { - var tr = $tw.utils.parseTextReference(textRef), - targetTitle = tr.title, - targetField = tr.field, - targetIndex = tr.index, - tiddlerNode = { - type: "tiddler", - attributes: { - tiddler: {type: "string", value: targetTitle} - }, - isBlock: true, - children: [transcludeNode] - }; + tr = $tw.utils.parseTextReference(textRef); + targetTitle = tr.title; + targetField = tr.field; + targetIndex = tr.index; + tiddlerNode = { + type: "tiddler", + attributes: { + tiddler: {type: "string", value: targetTitle} + }, + isBlock: true, + children: [transcludeNode] + }; } if(template) { transcludeNode.attributes.tiddler = {type: "string", value: template}; diff --git a/core/modules/parsers/wikiparser/rules/transcludeinline.js b/core/modules/parsers/wikiparser/rules/transcludeinline.js index 66f16bb4b..dbf39bfb6 100644 --- a/core/modules/parsers/wikiparser/rules/transcludeinline.js +++ b/core/modules/parsers/wikiparser/rules/transcludeinline.js @@ -38,18 +38,19 @@ exports.parse = function() { attributes: {} }; // Prepare the tiddler widget + var tr, targetTitle, targetField, targetIndex, tiddlerNode; if(textRef) { - var tr = $tw.utils.parseTextReference(textRef), - targetTitle = tr.title, - targetField = tr.field, - targetIndex = tr.index, - tiddlerNode = { - type: "tiddler", - attributes: { - tiddler: {type: "string", value: targetTitle} - }, - children: [transcludeNode] - }; + tr = $tw.utils.parseTextReference(textRef); + targetTitle = tr.title; + targetField = tr.field; + targetIndex = tr.index; + tiddlerNode = { + type: "tiddler", + attributes: { + tiddler: {type: "string", value: targetTitle} + }, + children: [transcludeNode] + }; } if(template) { transcludeNode.attributes.tiddler = {type: "string", value: template}; diff --git a/core/modules/parsers/wikiparser/rules/typedblock.js b/core/modules/parsers/wikiparser/rules/typedblock.js index 561733b91..4195e57e5 100644 --- a/core/modules/parsers/wikiparser/rules/typedblock.js +++ b/core/modules/parsers/wikiparser/rules/typedblock.js @@ -68,7 +68,7 @@ exports.parse = function() { var widgetNode = this.parser.wiki.makeWidget(parser), container = $tw.fakeDocument.createElement("div"); widgetNode.render(container,null); - var text = renderType === "text/html" ? container.innerHTML : container.textContent; + text = renderType === "text/html" ? container.innerHTML : container.textContent; return [{ type: "element", tag: "pre", diff --git a/core/modules/parsers/wikiparser/rules/wikilink.js b/core/modules/parsers/wikiparser/rules/wikilink.js index f4b543896..886a42d4e 100644 --- a/core/modules/parsers/wikiparser/rules/wikilink.js +++ b/core/modules/parsers/wikiparser/rules/wikilink.js @@ -27,7 +27,7 @@ var textPrimitives = { upperLetter: "[A-Z\u00c0-\u00d6\u00d8-\u00de\u0150\u0170]", 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]", - 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 = "~"; diff --git a/core/modules/parsers/wikiparser/wikiparser.js b/core/modules/parsers/wikiparser/wikiparser.js index 6b23198c0..19a3522fa 100644 --- a/core/modules/parsers/wikiparser/wikiparser.js +++ b/core/modules/parsers/wikiparser/wikiparser.js @@ -100,7 +100,7 @@ Get the next match out of an array of parse rule instances */ WikiParser.prototype.findNextMatch = function(rules,startPos) { // Find the best matching rule by finding the closest match position - var matchingRule = undefined, + var matchingRule, matchingRulePos = this.sourceLength; // Step through each rule for(var t=0; t 0) { - self.saveWiki({method: "autosave"}); - } - }); - // Browser event handlers - if($tw.browser) { - // Set up our beforeunload handler - window.addEventListener("beforeunload",function(event) { - var confirmationMessage = undefined; - 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" - }); - }); - } + var self = this; + this.wiki = options.wiki; + this.dirtyTracking = options.dirtyTracking; + this.pendingAutoSave = false; + // Make a logger + this.logger = new $tw.utils.Logger("saver-handler"); + // Initialise our savers + if($tw.browser) { + this.initSavers(); + } + // Only do dirty tracking if required + if($tw.browser && this.dirtyTracking) { + // Compile the dirty tiddler filter + this.filterFn = this.wiki.compileFilter(this.wiki.getTiddlerText(this.titleSyncFilter)); + // Count of tiddlers that have been changed but not yet saved + this.numTasksInQueue = 0; + // Listen out for changes to tiddlers + this.wiki.addEventListener("change",function(changes) { + var filteredChanges = self.filterFn.call(self.wiki,function(callback) { + $tw.utils.each(changes,function(change,title) { + var tiddler = self.wiki.getTiddler(title); + callback(tiddler,title); + }); + }); + self.numTasksInQueue += filteredChanges.length; + self.updateDirtyStatus(); + // 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 + if(self.numTasksInQueue > 0) { + self.saveWiki({ + method: "autosave", + downloadType: "text/plain" + }); + } + self.pendingAutoSave = false; + } + }); + // 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) { + // Check if we're dirty + if(self.numTasksInQueue > 0) { + self.saveWiki({ + method: "autosave", + downloadType: "text/plain" + }); + } + } else { + // Otherwise put ourselves in the "pending autosave" state and wait for the change event before we do the autosave + self.pendingAutoSave = true; + } + }); + // 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"; @@ -86,86 +108,86 @@ SaverHandler.prototype.titleSavedNotification = "$:/language/Notifications/Save/ Select the appropriate saver modules and set them up */ SaverHandler.prototype.initSavers = function(moduleType) { - moduleType = moduleType || "saver"; - // Instantiate the available savers - this.savers = []; - var self = this; - $tw.modules.forEachModuleOfType(moduleType,function(title,module) { - if(module.canSave(self)) { - self.savers.push(module.create(self.wiki)); - } - }); - // Sort the savers into priority order - this.savers.sort(function(a,b) { - if(a.info.priority < b.info.priority) { - return -1; - } else { - if(a.info.priority > b.info.priority) { - return +1; - } else { - return 0; - } - } - }); + moduleType = moduleType || "saver"; + // Instantiate the available savers + this.savers = []; + var self = this; + $tw.modules.forEachModuleOfType(moduleType,function(title,module) { + if(module.canSave(self)) { + self.savers.push(module.create(self.wiki)); + } + }); + // Sort the savers into priority order + this.savers.sort(function(a,b) { + if(a.info.priority < b.info.priority) { + return -1; + } else { + if(a.info.priority > b.info.priority) { + return +1; + } else { + return 0; + } + } + }); }; /* Save the wiki contents. Options are: - method: "save", "autosave" or "download" - template: the tiddler containing the template to save - downloadType: the content type for the saved file + method: "save", "autosave" or "download" + template: the tiddler containing the template to save + downloadType: the content type for the saved file */ SaverHandler.prototype.saveWiki = function(options) { - options = options || {}; - var self = this, - method = options.method || "save", - template = options.template || "$:/core/save/all", - downloadType = options.downloadType || "text/plain", - text = this.wiki.renderTiddler(downloadType,template), - callback = function(err) { - if(err) { - alert("Error while saving:\n\n" + err); - } else { - // Clear the task queue if we're saving (rather than downloading) - if(method !== "download") { - self.numTasksInQueue = 0; - self.updateDirtyStatus(); - } - $tw.notifier.display(self.titleSavedNotification); - if(options.callback) { - options.callback(); - } - } - }; - // Ignore autosave if disabled - if(method === "autosave" && this.wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes") { - return false; - } - // Call the highest priority saver that supports this method - for(var t=this.savers.length-1; t>=0; t--) { - var saver = this.savers[t]; - if(saver.info.capabilities.indexOf(method) !== -1 && saver.save(text,method,callback)) { - this.logger.log("Saving wiki with method",method,"through saver",saver.info.name); - return true; - } - } - return false; + options = options || {}; + var self = this, + method = options.method || "save", + template = options.template || "$:/core/save/all", + downloadType = options.downloadType || "text/plain", + text = this.wiki.renderTiddler(downloadType,template), + callback = function(err) { + if(err) { + alert("Error while saving:\n\n" + err); + } else { + // Clear the task queue if we're saving (rather than downloading) + if(method !== "download") { + self.numTasksInQueue = 0; + self.updateDirtyStatus(); + } + $tw.notifier.display(self.titleSavedNotification); + if(options.callback) { + options.callback(); + } + } + }; + // Ignore autosave if disabled + if(method === "autosave" && this.wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes") { + return false; + } + // Call the highest priority saver that supports this method + for(var t=this.savers.length-1; t>=0; t--) { + var saver = this.savers[t]; + if(saver.info.capabilities.indexOf(method) !== -1 && saver.save(text,method,callback)) { + this.logger.log("Saving wiki with method",method,"through saver",saver.info.name); + return true; + } + } + return false; }; /* Checks whether the wiki is dirty (ie the window shouldn't be closed) */ 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 */ SaverHandler.prototype.updateDirtyStatus = function() { - if($tw.browser) { - $tw.utils.toggleClass(document.body,"tc-dirty",this.isDirty()); - } + if($tw.browser) { + $tw.utils.toggleClass(document.body,"tc-dirty",this.isDirty()); + } }; exports.SaverHandler = SaverHandler; diff --git a/core/modules/savers/andtidwiki.js b/core/modules/savers/andtidwiki.js index 584db5d62..33e776977 100644 --- a/core/modules/savers/andtidwiki.js +++ b/core/modules/savers/andtidwiki.js @@ -32,7 +32,7 @@ AndTidWiki.prototype.save = function(text,method,callback) { pathname = pathname.substr(0,p); } // Save the file - window.twi.saveFile(pathname,text) + window.twi.saveFile(pathname,text); // Call the callback callback(null); return true; diff --git a/core/modules/savers/tiddlyfox.js b/core/modules/savers/tiddlyfox.js index 6f06d72bf..a729e26e3 100644 --- a/core/modules/savers/tiddlyfox.js +++ b/core/modules/savers/tiddlyfox.js @@ -21,7 +21,7 @@ TiddlyFoxSaver.prototype.save = function(text,method,callback) { // Get the pathname of this document var pathname = document.location.toString().split("#")[0]; // Replace file://localhost/ with file:/// - if(pathname.indexOf("file://localhost/") == 0) { + if(pathname.indexOf("file://localhost/") === 0) { pathname = "file://" + pathname.substr(16); } // 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) { pathname = "\\\\" + unescape(pathname.substr(10)).replace(/\//g,"\\"); // 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)); // 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)); // Otherwise Windows networth path file://server/share/path/path --> \\server\share\path\path } else { diff --git a/core/modules/savers/twedit.js b/core/modules/savers/twedit.js index 48b3ffbbc..33d748f67 100644 --- a/core/modules/savers/twedit.js +++ b/core/modules/savers/twedit.js @@ -38,25 +38,25 @@ TWEditSaver.prototype.save = function(text,method,callback) { } // Error handler var errorHandler = function(event) { - // Error - callback("Error saving to TWEdit: " + event.target.error.code); - }; + // Error + callback("Error saving to TWEdit: " + event.target.error.code); + }; // Get the file system - window.requestFileSystem(LocalFileSystem.PERSISTENT,0,function(fileSystem) { - // Now we've got the filesystem, get the fileEntry - fileSystem.root.getFile(pathname, {create: true}, function(fileEntry) { - // Now we've got the fileEntry, create the writer - fileEntry.createWriter(function(writer) { - writer.onerror = errorHandler; - writer.onwrite = function() { - callback(null); - }; - writer.position = 0; - writer.write(text); - },errorHandler); - }, errorHandler); - }, errorHandler); - return true; + window.requestFileSystem(LocalFileSystem.PERSISTENT,0,function(fileSystem) { + // Now we've got the filesystem, get the fileEntry + fileSystem.root.getFile(pathname, {create: true}, function(fileEntry) { + // Now we've got the fileEntry, create the writer + fileEntry.createWriter(function(writer) { + writer.onerror = errorHandler; + writer.onwrite = function() { + callback(null); + }; + writer.position = 0; + writer.write(text); + },errorHandler); + }, errorHandler); + }, errorHandler); + return true; }; /* diff --git a/core/modules/startup/favicon.js b/core/modules/startup/favicon.js index 7794dec25..0d1792ea7 100644 --- a/core/modules/startup/favicon.js +++ b/core/modules/startup/favicon.js @@ -38,6 +38,6 @@ function setFavicon() { var faviconLink = document.getElementById("faviconLink"); faviconLink.setAttribute("href","data:" + tiddler.fields.type + ";base64," + tiddler.fields.text); } -}; +} })(); diff --git a/core/modules/startup/render.js b/core/modules/startup/render.js index 865c7f5d8..8e1dafd71 100644 --- a/core/modules/startup/render.js +++ b/core/modules/startup/render.js @@ -19,7 +19,7 @@ exports.after = ["story"]; exports.synchronous = true; // 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_TEMPLATE_TITLE = "$:/core/ui/PageTemplate"; diff --git a/core/modules/startup/story.js b/core/modules/startup/story.js index 90bb9003d..6c7258485 100644 --- a/core/modules/startup/story.js +++ b/core/modules/startup/story.js @@ -48,7 +48,7 @@ exports.startup = function() { $tw.locationHash = hash; openStartupTiddlers({defaultToCurrentStory: true}); } - },false) + },false); // Listen for the tm-browser-refresh message $tw.rootWidget.addEventListener("tm-browser-refresh",function(event) { window.location.reload(true); @@ -157,7 +157,7 @@ function updateLocationHash(options) { } // Assemble the location hash if(options.updateAddressBar === "permalink") { - $tw.locationHash = "#" + encodeURIComponent(targetTiddler) + $tw.locationHash = "#" + encodeURIComponent(targetTiddler); } else { $tw.locationHash = "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList)); } diff --git a/core/modules/storyviews/classic.js b/core/modules/storyviews/classic.js index ceb54ee47..a600fe326 100644 --- a/core/modules/storyviews/classic.js +++ b/core/modules/storyviews/classic.js @@ -16,7 +16,7 @@ var easing = "cubic-bezier(0.645, 0.045, 0.355, 1)"; // From http://easings.net/ var ClassicStoryView = function(listWidget) { this.listWidget = listWidget; -} +}; ClassicStoryView.prototype.navigateTo = function(historyInfo) { var listElementIndex = this.listWidget.findListItem(0,historyInfo.title); diff --git a/core/modules/storyviews/pop.js b/core/modules/storyviews/pop.js index 51c014da6..b94a23df2 100644 --- a/core/modules/storyviews/pop.js +++ b/core/modules/storyviews/pop.js @@ -14,7 +14,7 @@ Animates list insertions and removals var PopStoryView = function(listWidget) { this.listWidget = listWidget; -} +}; PopStoryView.prototype.navigateTo = function(historyInfo) { var listElementIndex = this.listWidget.findListItem(0,historyInfo.title); diff --git a/core/modules/storyviews/zoomin.js b/core/modules/storyviews/zoomin.js index 46afb354a..51463e83b 100644 --- a/core/modules/storyviews/zoomin.js +++ b/core/modules/storyviews/zoomin.js @@ -86,7 +86,7 @@ ZoominListView.prototype.navigateTo = function(historyInfo) { ]); // Transform the previous tiddler out of the way and then hide it 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; y = zoomBounds.top - targetBounds.top - (sourceBounds.top - targetBounds.top) * scale; $tw.utils.setStyle(prevCurrentTiddler,[ diff --git a/core/modules/syncer.js b/core/modules/syncer.js index ba736f677..7d5880d1e 100644 --- a/core/modules/syncer.js +++ b/core/modules/syncer.js @@ -20,7 +20,7 @@ wiki: wiki to be synced function Syncer(options) { var self = this; this.wiki = options.wiki; - this.syncadaptor = options.syncadaptor + this.syncadaptor = options.syncadaptor; // Make a logger this.logger = new $tw.utils.Logger("syncer" + ($tw.browser ? "-browser" : "") + ($tw.node ? "-server" : "")); // Compile the dirty tiddler filter @@ -40,7 +40,7 @@ function Syncer(options) { if($tw.browser) { // Set up our beforeunload handler window.addEventListener("beforeunload",function(event) { - var confirmationMessage = undefined; + var confirmationMessage; if(self.isDirty()) { confirmationMessage = $tw.language.getString("UnsavedChangesWarning"); event.returnValue = confirmationMessage; // Gecko @@ -94,10 +94,10 @@ Syncer.prototype.readTiddlerInfo = function() { $tw.utils.each(tiddlers,function(title) { var tiddler = self.wiki.getTiddler(title); self.tiddlerInfo[title] = { - revision: tiddler.fields["revision"], + revision: tiddler.fields.revision, adaptorInfo: self.syncadaptor && self.syncadaptor.getTiddlerInfo(tiddler), changeCount: self.wiki.getChangeCount(title) - } + }; }); }; @@ -329,7 +329,7 @@ Syncer.prototype.enqueueSyncTask = function(task) { revision: null, adaptorInfo: {}, changeCount: -1 - } + }; } // 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) { diff --git a/core/modules/upgraders/plugins.js b/core/modules/upgraders/plugins.js index 91948ff73..d770ea29a 100644 --- a/core/modules/upgraders/plugins.js +++ b/core/modules/upgraders/plugins.js @@ -36,10 +36,10 @@ exports.upgrade = function(wiki,titles,tiddlers) { $tw.utils.each(titles,function(title) { var incomingTiddler = tiddlers[title]; // 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 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)) { tiddlers[title] = libraryTiddler; messages[title] = $tw.language.getString("Import/Upgrader/Plugins/Upgraded",{variables: {incoming: incomingTiddler.version, upgraded: libraryTiddler.version}}); diff --git a/core/modules/upgraders/themetweaks.js b/core/modules/upgraders/themetweaks.js index 8a15271e4..86ddc0f7e 100644 --- a/core/modules/upgraders/themetweaks.js +++ b/core/modules/upgraders/themetweaks.js @@ -51,10 +51,10 @@ exports.upgrade = function(wiki,titles,tiddlers) { tiddlers[mappedTitle] = { title: mappedTitle, text: tiddlerData[index] - } + }; messages[mappedTitle] = $tw.language.getString("Import/Upgrader/ThemeTweaks/Created",{variables: { from: title + "##" + index - }}) + }}); } } } diff --git a/core/modules/utils/dom/modal.js b/core/modules/utils/dom/modal.js index a27f84024..1c4e30c1c 100644 --- a/core/modules/utils/dom/modal.js +++ b/core/modules/utils/dom/modal.js @@ -93,7 +93,7 @@ Modal.prototype.display = function(title,options) { }); // Setup the link if present if(options.downloadLink) { - modalLink.href = options.downloadLink + modalLink.href = options.downloadLink; modalLink.appendChild(document.createTextNode("Right-click to save changes")); modalBody.appendChild(modalLink); } diff --git a/core/modules/utils/fakedom.js b/core/modules/utils/fakedom.js index 3904f95b0..dd36369a2 100755 --- a/core/modules/utils/fakedom.js +++ b/core/modules/utils/fakedom.js @@ -19,7 +19,7 @@ var bumpSequenceNumber = function(object) { if(sequenceNumber !== null) { object.sequenceNumber = sequenceNumber++; } -} +}; var TW_TextNode = function(text) { bumpSequenceNumber(this); @@ -79,7 +79,7 @@ TW_Element.prototype.insertBefore = function(node,nextSibling) { } else { this.appendChild(node); } -} +}; TW_Element.prototype.removeChild = function(node) { var p = this.children.indexOf(node); @@ -93,9 +93,9 @@ TW_Element.prototype.hasChildNodes = function() { }; Object.defineProperty(TW_Element.prototype, "firstChild", { - get: function() { - return this.children[0]; - } + get: function() { + return this.children[0]; + } }); TW_Element.prototype.addEventListener = function(type,listener,useCapture) { @@ -106,22 +106,22 @@ Object.defineProperty(TW_Element.prototype, "className", { get: function() { return this.attributes["class"] || ""; }, - set: function(value) { - this.attributes["class"] = value; - } + set: function(value) { + this.attributes["class"] = value; + } }); Object.defineProperty(TW_Element.prototype, "value", { get: function() { - return this.attributes["value"] || ""; + return this.attributes.value || ""; }, - set: function(value) { - this.attributes["value"] = value; - } + set: function(value) { + this.attributes.value = value; + } }); Object.defineProperty(TW_Element.prototype, "outerHTML", { - get: function() { + get: function() { var output = [],attr,a,v; output.push("<",this.tag); if(this.attributes) { @@ -143,7 +143,7 @@ Object.defineProperty(TW_Element.prototype, "outerHTML", { output.push(""); } return output.join(""); - } + } }); Object.defineProperty(TW_Element.prototype, "innerHTML", { @@ -162,10 +162,10 @@ Object.defineProperty(TW_Element.prototype, "innerHTML", { return b.join(""); } }, - set: function(value) { - this.isRaw = true; - this.rawHTML = value; - } + set: function(value) { + this.isRaw = true; + this.rawHTML = value; + } }); Object.defineProperty(TW_Element.prototype, "textContent", { @@ -193,7 +193,7 @@ Object.defineProperty(TW_Element.prototype, "formattedTextContent", { b.push("\n"); } if(this.tag === "li") { - b.push("* ") + b.push("* "); } $tw.utils.each(this.children,function(node) { b.push(node.formattedTextContent); diff --git a/core/modules/utils/filesystem.js b/core/modules/utils/filesystem.js index db7e5e26a..d0fe34645 100644 --- a/core/modules/utils/filesystem.js +++ b/core/modules/utils/filesystem.js @@ -41,7 +41,7 @@ exports.copyDirectory = function(srcPath,dstPath) { if(err) { return err; } - }; + } } }; copy(srcPath,dstPath); @@ -70,7 +70,7 @@ exports.copyFile = function(srcPath,dstPath) { fs.closeSync(srcFile); fs.closeSync(dstFile); return null; -} +}; /* Remove trailing path separator diff --git a/core/modules/utils/parsetree.js b/core/modules/utils/parsetree.js index dc811c727..26c7f9a1b 100644 --- a/core/modules/utils/parsetree.js +++ b/core/modules/utils/parsetree.js @@ -41,9 +41,9 @@ exports.addClassToParseTreeNode = function(node,classString) { exports.addStyleToParseTreeNode = function(node,name,value) { node.attributes = node.attributes || {}; - node.attributes["style"] = node.attributes["style"] || {type: "string", value: ""}; - if(node.attributes["style"].type === "string") { - node.attributes["style"].value += name + ":" + value + ";"; + node.attributes.style = node.attributes.style || {type: "string", value: ""}; + if(node.attributes.style.type === "string") { + node.attributes.style.value += name + ":" + value + ";"; } }; diff --git a/core/modules/utils/pluginmaker.js b/core/modules/utils/pluginmaker.js index 5cce747a0..c3ef000b0 100644 --- a/core/modules/utils/pluginmaker.js +++ b/core/modules/utils/pluginmaker.js @@ -24,15 +24,16 @@ exports.repackPlugin = function(title,additionalTiddlers,excludeTiddlers) { throw "No such tiddler as " + title; } // Extract the JSON + var jsonPluginTiddler; try { - var jsonPluginTiddler = JSON.parse(pluginTiddler.fields.text); + jsonPluginTiddler = JSON.parse(pluginTiddler.fields.text); } catch(e) { throw "Cannot parse plugin tiddler " + title + "\nError: " + e; } // Get the list of tiddlers var tiddlers = Object.keys(jsonPluginTiddler.tiddlers); // Add the additional tiddlers - $tw.utils.pushTop(tiddlers,additionalTiddlers) + $tw.utils.pushTop(tiddlers,additionalTiddlers); // Remove any excluded tiddlers for(var t=tiddlers.length-1; t>=0; t--) { if(excludeTiddlers.indexOf(tiddlers[t]) !== -1) { @@ -71,8 +72,10 @@ exports.repackPlugin = function(title,additionalTiddlers,excludeTiddlers) { $tw.wiki.deleteTiddler(title); } }); + // Trigger an autosave + $tw.rootWidget.dispatchEvent({type: "tw-auto-save-wiki"}); // Return a heartwarming confirmation return "Plugin " + title + " successfully saved"; -} +}; })(); diff --git a/core/modules/widgets/dropzone.js b/core/modules/widgets/dropzone.js index 30f1ddb5c..edda8fa50 100644 --- a/core/modules/widgets/dropzone.js +++ b/core/modules/widgets/dropzone.js @@ -126,7 +126,7 @@ DropZoneWidget.prototype.importData = function(dataTransfer) { return; } } - }; + } }; DropZoneWidget.prototype.importDataTypes = [ diff --git a/core/modules/widgets/edit-bitmap.js b/core/modules/widgets/edit-bitmap.js index f73734cca..11728bea0 100644 --- a/core/modules/widgets/edit-bitmap.js +++ b/core/modules/widgets/edit-bitmap.js @@ -120,7 +120,7 @@ EditBitmapWidget.prototype.loadCanvas = function() { self.initCanvas(self.currCanvas,DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT); // Set the width and height input boxes self.updateSize(); - } + }; // Get the current bitmap into an image object 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.fillRect(0,0,canvas.width,canvas.height); } -} +}; /* ** Update the input boxes with the actual size of the canvas diff --git a/core/modules/widgets/fields.js b/core/modules/widgets/fields.js index aaa9761b6..511b6f7d5 100755 --- a/core/modules/widgets/fields.js +++ b/core/modules/widgets/fields.js @@ -78,7 +78,7 @@ FieldsWidget.prototype.execute = function() { row = row.replace("$name$",fieldName); row = row.replace("$value$",value); row = row.replace("$encoded_value$",$tw.utils.htmlEncode(value)); - text.push(row) + text.push(row); } } } diff --git a/core/modules/widgets/link.js b/core/modules/widgets/link.js index 0be1dbef0..60d3edd7d 100755 --- a/core/modules/widgets/link.js +++ b/core/modules/widgets/link.js @@ -35,7 +35,7 @@ LinkWidget.prototype.render = function(parent,nextSibling) { this.execute(); // Get the value of the tv-wikilinks configuration macro var wikiLinksMacro = this.getVariable("tv-wikilinks"), - useWikiLinks = wikiLinksMacro ? !(wikiLinksMacro.trim() === "no") : true; + useWikiLinks = wikiLinksMacro ? (wikiLinksMacro.trim() !== "no") : true; // Render the link if required if(useWikiLinks) { this.renderLink(parent,nextSibling); diff --git a/core/modules/widgets/list.js b/core/modules/widgets/list.js index fd3b26dd9..0138e0837 100755 --- a/core/modules/widgets/list.js +++ b/core/modules/widgets/list.js @@ -44,7 +44,7 @@ ListWidget.prototype.render = function(parent,nextSibling) { // Construct the storyview var StoryView = this.storyViews[this.storyViewName]; if(StoryView && !this.document.isTiddlyWikiFakeDom) { - this.storyview = new StoryView(this) + this.storyview = new StoryView(this); } else { this.storyview = null; } diff --git a/core/modules/widgets/navigator.js b/core/modules/widgets/navigator.js index 1ee5a42d3..dcc0b0594 100755 --- a/core/modules/widgets/navigator.js +++ b/core/modules/widgets/navigator.js @@ -243,6 +243,8 @@ NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) { // Remove the closed tiddler from the story this.removeTitleFromStory(storyList,title); this.saveStoryList(storyList); + // Trigger an autosave + $tw.rootWidget.dispatchEvent({type: "tw-auto-save-wiki"}); return false; }; @@ -281,9 +283,10 @@ NavigatorWidget.prototype.makeDraftTiddler = function(targetTitle) { Generate a title for the draft of a given tiddler */ NavigatorWidget.prototype.generateDraftTitle = function(title) { - var c = 0; + var c = 0, + draftTitle; do { - var draftTitle = "Draft " + (c ? (c + 1) + " " : "") + "of '" + title + "'"; + draftTitle = "Draft " + (c ? (c + 1) + " " : "") + "of '" + title + "'"; c++; } while(this.wiki.tiddlerExists(draftTitle)); return draftTitle; @@ -331,6 +334,8 @@ NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) { if(draftTitle !== this.storyTitle) { 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 this.addToHistory([IMPORT_TITLE]); + // Trigger an autosave + $tw.rootWidget.dispatchEvent({type: "tw-auto-save-wiki"}); }; exports.navigator = NavigatorWidget; diff --git a/core/modules/widgets/reveal.js b/core/modules/widgets/reveal.js index b2229631a..66a87f1af 100755 --- a/core/modules/widgets/reveal.js +++ b/core/modules/widgets/reveal.js @@ -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 } if(!this.isOpen) { - domNode.setAttribute("hidden","true") + domNode.setAttribute("hidden","true"); } this.domNodes.push(domNode); }; diff --git a/core/modules/widgets/tiddler.js b/core/modules/widgets/tiddler.js index fcc4fabf1..6a86940c0 100755 --- a/core/modules/widgets/tiddler.js +++ b/core/modules/widgets/tiddler.js @@ -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("shadowTiddlerClass",this.wiki.isShadowTiddler(this.tiddlerTitle) ? "tc-tiddler-shadow" : ""); 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 this.makeChildWidgets(); }; diff --git a/core/modules/widgets/widget.js b/core/modules/widgets/widget.js index 9424dd6d8..144f12fa2 100755 --- a/core/modules/widgets/widget.js +++ b/core/modules/widgets/widget.js @@ -171,7 +171,7 @@ Widget.prototype.evaluateMacroModule = function(name,actualParams,defaultValue) else for(var i=0; i|\:|\"|\/|\\|\||\?|\*|\^/g,"_"); + var baseFilename = title.replace(/<|>|\:|\"|\/|\\|\||\?|\*|\^/g,"_"); // Truncate the filename if it is too long if(baseFilename.length > 200) { baseFilename = baseFilename.substr(0,200) + extension; diff --git a/plugins/tiddlywiki/jasmine/jasmine-1.3.1/MIT.LICENSE b/plugins/tiddlywiki/jasmine/files/MIT.LICENSE similarity index 100% rename from plugins/tiddlywiki/jasmine/jasmine-1.3.1/MIT.LICENSE rename to plugins/tiddlywiki/jasmine/files/MIT.LICENSE diff --git a/plugins/tiddlywiki/jasmine/jasmine-1.3.1/jasmine-html.js b/plugins/tiddlywiki/jasmine/files/jasmine-html.js similarity index 100% rename from plugins/tiddlywiki/jasmine/jasmine-1.3.1/jasmine-html.js rename to plugins/tiddlywiki/jasmine/files/jasmine-html.js diff --git a/plugins/tiddlywiki/jasmine/jasmine-1.3.1/jasmine.css b/plugins/tiddlywiki/jasmine/files/jasmine.css similarity index 100% rename from plugins/tiddlywiki/jasmine/jasmine-1.3.1/jasmine.css rename to plugins/tiddlywiki/jasmine/files/jasmine.css diff --git a/plugins/tiddlywiki/jasmine/jasmine-1.3.1/jasmine.js b/plugins/tiddlywiki/jasmine/files/jasmine.js similarity index 100% rename from plugins/tiddlywiki/jasmine/jasmine-1.3.1/jasmine.js rename to plugins/tiddlywiki/jasmine/files/jasmine.js diff --git a/plugins/tiddlywiki/jasmine/jasmine-1.3.1/reporter.js b/plugins/tiddlywiki/jasmine/files/reporter.js similarity index 100% rename from plugins/tiddlywiki/jasmine/jasmine-1.3.1/reporter.js rename to plugins/tiddlywiki/jasmine/files/reporter.js diff --git a/plugins/tiddlywiki/jasmine/jasmine-1.3.1/tiddlywiki.files b/plugins/tiddlywiki/jasmine/files/tiddlywiki.files similarity index 100% rename from plugins/tiddlywiki/jasmine/jasmine-1.3.1/tiddlywiki.files rename to plugins/tiddlywiki/jasmine/files/tiddlywiki.files diff --git a/plugins/tiddlywiki/jasmine/jasmine-plugin.js b/plugins/tiddlywiki/jasmine/jasmine-plugin.js index 1ed39e186..07e19ffda 100644 --- a/plugins/tiddlywiki/jasmine/jasmine-plugin.js +++ b/plugins/tiddlywiki/jasmine/jasmine-plugin.js @@ -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 jasmine.jasmine.TerminalVerboseReporter = reporterExports.jasmineNode.TerminalVerboseReporter; jasmine.jasmine.TerminalReporter = reporterExports.jasmineNode.TerminalReporter; - jasmineEnv.addReporter(new jasmine.jasmine.TerminalVerboseReporter({ + jasmineEnv.addReporter(new jasmine.jasmine.TerminalVerboseReporter({ print: require("util").print, color: true, includeStackTrace: true diff --git a/plugins/tiddlywiki/nodewebkitsaver/nodewebkit.js b/plugins/tiddlywiki/nodewebkitsaver/nodewebkit.js index 81680f667..ae36dea1f 100644 --- a/plugins/tiddlywiki/nodewebkitsaver/nodewebkit.js +++ b/plugins/tiddlywiki/nodewebkitsaver/nodewebkit.js @@ -48,7 +48,7 @@ Static method that returns true if this saver is capable of working */ exports.canSave = function(wiki) { // Check if we're running under node-webkit - return (typeof process == "object") + return (typeof process == "object"); }; /* diff --git a/plugins/tiddlywiki/tiddlyweb/tiddlywebadaptor.js b/plugins/tiddlywiki/tiddlyweb/tiddlywebadaptor.js index e87db5b0b..69d92119d 100644 --- a/plugins/tiddlywiki/tiddlyweb/tiddlywebadaptor.js +++ b/plugins/tiddlywiki/tiddlyweb/tiddlywebadaptor.js @@ -37,7 +37,7 @@ TiddlyWebAdaptor.prototype.getHost = function() { TiddlyWebAdaptor.prototype.getTiddlerInfo = function(tiddler) { 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 if(result.type === "text/x-tiddlywiki") { result.type = null; - }; + } result.type = result.type || "text/vnd.tiddlywiki"; return JSON.stringify(result,null,$tw.config.preferences.jsonSpaces); }; diff --git a/readme.md b/readme.md index 7d04f5492..4f7c1563f 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -

Welcome to TiddlyWiki

Welcome to TiddlyWiki, a non-linear personal web notebook that anyone can use and keep forever, independently of any corporation.

TiddlyWiki is a complete interactive wiki in JavaScript. It can be used as a single HTML file in the browser or as a powerful Node.js application. It is highly customisable: the entire user interface is itself implemented in hackable WikiText.

This is version of TiddlyWiki, a major reboot designed for the next 25 years. It is currently in beta (see the detailed ReleaseHistory) with a RoadMap for moving to the full release. It is a great time to get involved and support the future development of TiddlyWiki.

TiddlyWiki is a free, open source project that depends on your love and support for its survival.

TiddlyWikiClassic

The original "Classic" version of TiddlyWiki is still available at http://classic.tiddlywiki.com. Note that it is not fully backwards compatible: existing content will need massaging, while plugins and themes will have to be completely rewritten. The upgrade path will get smoother as the new version matures. +

Welcome to TiddlyWiki

Welcome to TiddlyWiki, a non-linear personal web notebook that anyone can use and keep forever, independently of any corporation.

TiddlyWiki is a complete interactive wiki in JavaScript. It can be used as a single HTML file in the browser or as a powerful Node.js application. It is highly customisable: the entire user interface is itself implemented in hackable WikiText.

This is version of TiddlyWiki, a major reboot designed for the next 25 years. It is currently in beta (see the detailed ReleaseHistory) with a RoadMap for moving to the full release. It is a great time to get involved and support the future development of TiddlyWiki.

TiddlyWiki is a free, open source project that depends on your love and support for its survival.

TiddlyWikiClassic

The original "Classic" version of TiddlyWiki is still available at http://classic.tiddlywiki.com. Note that it is not fully backwards compatible: existing content will need massaging, while plugins and themes will have to be completely rewritten. The upgrade path will get smoother as the new version matures.

Getting started with TiddlyWiki under Node.js

Running TiddlyWiki on Node.js brings several important benefits over and above the single file version:

  • You can edit your content on any suitably compatible HTML5 browser, including smartphones and tablets
  • Individual tiddlers are stored in separate files, which you can organise as you wish
  • The ability to build multiple wikis that blend different combinations of shared and unique content

Installation

  1. Install Node.js from http://nodejs.org
  2. Open a command line terminal and type:

    npm install -g tiddlywiki

    If it fails with an error you may need to re-run the command as an administrator:

    npm install -g tiddlywiki (Windows)

    sudo npm install -g tiddlywiki (Mac/Linux)

  3. Check TiddlyWiki is installed by typing:

    tiddlywiki --version

  4. In response, you should see TiddlyWiki report its current version (eg 5.0.8-beta; you may also see other debugging information reported)
  5. Try it out:
    1. tiddlywiki mynewwiki --init server to create a folder for a new wiki that includes server-related components
    2. tiddlywiki mynewwiki --server to start TiddlyWiki
    3. Visit http://127.0.0.1:8080/ in your browser
    4. Try editing and creating tiddlers

The -g flag causes TiddlyWiki to be installed globally. Without it, TiddlyWiki will only be available in the directory where you installed it.

A slightly different method for installation is recommended if you plan on forking the source code in order to study it or contribute to it. See Working with the TiddlyWiki5 repository.

Usage

TiddlyWiki5 can be used on the command line to perform an extensive set of operations based on TiddlyWikiFolders, TiddlerFiles and TiddlyWikiFiles.

For example, the following command loads the tiddlers from a TiddlyWiki HTML file and then saves one of them in static HTML:

tiddlywiki --verbose --load mywiki.html --rendertiddler ReadMe ./readme.html

Running tiddlywiki from the command line boots the TiddlyWiki kernel, loads the core plugins and establishes an empty wiki store. It then sequentially processes the command line arguments from left to right. The arguments are separated with spaces.

The first argument is the optional path to the TiddlyWikiFolder to be loaded. If not present, then the current directory is used.

The commands and their individual arguments follow, each command being identified by the prefix --.

tiddlywiki [<wikipath>] [--<command> [<arg>[,<arg>]]]

The available commands are:

See also:

Upgrading

If you've installed TiddlyWiki on Node.js on the usual way, when a new version is released you can upgrade it with this command:

npm update -g tiddlywiki

On Mac or Linux you'll need to add sudo like this:

sudo npm update -g tiddlywiki

Working with the TiddlyWiki5 repository

Setting Up

If you plan on working with the TiddlyWiki5 source code then follow these steps:

  1. Fork the TiddlyWiki5 GitHub repository from https://github.com/Jermolene/TiddlyWiki5
  2. Clone a local copy of your fork
  3. Open a command line terminal and change the current working directory to the root of the repo
  4. Type npm link (Windows) or sudo npm link (Mac/Linux) to tell npm to use this copy of the repo as the globally installed one

After this procedure you can work with TiddlyWiki5 via npm as though it were installed in the usual way with npm install -g tiddlywiki.

See also Scripts for TiddlyWiki on Node.js.

This readme file was automatically generated by TiddlyWiki

\ No newline at end of file