diff --git a/core/modules/widgets/navigator.js b/core/modules/widgets/navigator.js index 4c554a70e..2dda2b34f 100755 --- a/core/modules/widgets/navigator.js +++ b/core/modules/widgets/navigator.js @@ -177,12 +177,7 @@ NavigatorWidget.prototype.handleCloseOtherTiddlersEvent = function(event) { NavigatorWidget.prototype.handleEditTiddlerEvent = function(event) { var self = this; function isUnmodifiedShadow(title) { - // jshint eqnull:true - var tiddler = self.wiki.getTiddler(title); - return ( - self.wiki.isShadowTiddler(title) && - tiddler.fields.modified == null - ); + return self.wiki.isShadowTiddler(title) && !self.wiki.tiddlerExists(title); } function confirmEditShadow(title) { return confirm($tw.language.getString( @@ -253,19 +248,14 @@ Create/reuse the draft tiddler for a given title */ NavigatorWidget.prototype.makeDraftTiddler = function(targetTitle) { // See if there is already a draft tiddler for this tiddler - var drafts = []; - this.wiki.forEachTiddler({includeSystem: true},function(title,tiddler) { - if(tiddler.fields["draft.title"] && tiddler.fields["draft.of"] === targetTitle) { - drafts.push(tiddler); - } - }); - if(drafts.length > 0) { - return drafts[0]; + var draftTitle = this.wiki.findDraft(targetTitle); + if(draftTitle) { + return draftTitle; } // Get the current value of the tiddler we're editing - var tiddler = this.wiki.getTiddler(targetTitle), - draftTitle = this.generateDraftTitle(targetTitle); + var tiddler = this.wiki.getTiddler(targetTitle); // Save the initial value of the draft tiddler + draftTitle = this.generateDraftTitle(targetTitle); var draftTiddler = new $tw.Tiddler( tiddler, { @@ -372,37 +362,62 @@ NavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) { }; // Create a new draft tiddler +// event.param can either be the title of a template tiddler, or a hashmap of fields. +// +// The title of the newly created tiddler follows these rules: +// * If a hashmap was used and a title field was specified, use that title +// * If a hashmap was used without a title field, use a default title, if necessary making it unique with a numeric suffix +// * If a template tiddler was used, use the title of the template, if necessary making it unique with a numeric suffix +// +// If a draft of the target tiddler already exists then it is reused NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) { // Get the story details var storyList = this.getStoryList(), - templateTiddler,originalTitle; + existingTiddler, templateTiddler, + title; // Get the template if(typeof event.param === "object") { + // If we got a hashmap use it as the template templateTiddler = event.param; - originalTitle = templateTiddler.title; + if(templateTiddler.title) { + // Pull in any existing tiddler + existingTiddler = this.wiki.getTiddler(templateTiddler.title); + if(existingTiddler && existingTiddler.fields.tags && templateTiddler.tags) { + // Merge tags + templateTiddler.tags = $tw.utils.pushTop($tw.utils.parseStringArray(templateTiddler.tags),existingTiddler.fields.tags); + } + // Use the provided title + title = templateTiddler.title + } } else { - templateTiddler = this.wiki.getTiddler(event.param); - originalTitle = templateTiddler && templateTiddler.fields.title; + existingTiddler = this.wiki.getTiddler(event.param); + title = this.wiki.generateNewTitle(event.param); + } + title = title || this.wiki.generateNewTitle($tw.language.getString("DefaultNewTiddlerTitle")); + // Try to reuse any existing draft of the tiddler + var draftTitle = this.wiki.findDraft(title); + if(!draftTitle) { + // Otherwise, create a new draft of the tiddler + draftTitle = this.generateDraftTitle(title); + var draftTiddler = new $tw.Tiddler({ + text: "" + },existingTiddler,templateTiddler, + this.wiki.getCreationFields(), + { + title: draftTitle, + "draft.title": title, + "draft.of": title + },this.wiki.getModificationFields()); + this.wiki.addTiddler(draftTiddler); + } + // Update the story to insert the new draft at the top and remove any existing tiddler + if(storyList.indexOf(draftTitle) === -1) { + var slot = storyList.indexOf(event.navigateFromTitle); + storyList.splice(slot + 1,0,draftTitle); + } + if(storyList.indexOf(title) !== -1) { + storyList.splice(storyList.indexOf(title),1); } - originalTitle = originalTitle || $tw.language.getString("DefaultNewTiddlerTitle"); - // Title the new tiddler - var title = this.wiki.generateNewTitle(originalTitle); - // Create the draft tiddler - var draftTitle = this.generateDraftTitle(title), - draftTiddler = new $tw.Tiddler({ - text: "" - },templateTiddler, - this.wiki.getCreationFields(), - { - title: draftTitle, - "draft.title": title, - "draft.of": title - },this.wiki.getModificationFields()); - this.wiki.addTiddler(draftTiddler); - // Update the story to insert the new draft at the top - var slot = storyList.indexOf(event.navigateFromTitle); - storyList.splice(slot + 1,0,draftTitle); - // Save the updated story this.saveStoryList(storyList); // Add a new record to the top of the history stack this.addToHistory(draftTitle); diff --git a/core/modules/wiki.js b/core/modules/wiki.js index e9df6b68c..9cb34601b 100755 --- a/core/modules/wiki.js +++ b/core/modules/wiki.js @@ -1132,6 +1132,19 @@ exports.readFile = function(file,callback) { } }; +/* +Find any existing draft of a specified tiddler +*/ +exports.findDraft = function(targetTitle) { + var draftTitle = undefined; + this.forEachTiddler({includeSystem: true},function(title,tiddler) { + if(tiddler.fields["draft.title"] && tiddler.fields["draft.of"] === targetTitle) { + draftTitle = title; + } + }); + return draftTitle; +} + /* Check whether the specified draft tiddler has been modified */ diff --git a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-new-tiddler.tid b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-new-tiddler.tid index 9085c9a8a..2c3dfa41f 100644 --- a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-new-tiddler.tid +++ b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-new-tiddler.tid @@ -11,6 +11,12 @@ The new tiddler message creates a new draft tiddler and adds it to the current s |param |Either the title of a tiddler to use as a template for the new tiddler or a hashmap of tiddler fields | |navigateFromTitle |Title of the tiddler from which the navigation to the new tiddler was initiated | +The title for the draft tiddler is chosen according to these rules: + +* If a hashmap was used and a title field was specified, use that title +* If a hashmap was used without a title field, use a default title, if necessary making it unique with a numeric suffix +* If a template tiddler was used, use the title of the template tiddler, if necessary making it unique with a numeric suffix + The new tiddler message is usually generated with the LinkWidget, ButtonWidget or ActionSendMessageWidget and is handled by the NavigatorWidget. ! Example