/*\ title: $:/core/modules/widgets/navigator.js type: application/javascript module-type: widget Navigator widget \*/ (function(){ /*jslint node: true, browser: true */ /*global $tw: false */ "use strict"; var Widget = require("$:/core/modules/widgets/widget.js").widget; var NavigatorWidget = function(parseTreeNode,options) { this.initialise(parseTreeNode,options); this.addEventListeners([ {type: "tw-navigate", handler: "handleNavigateEvent"}, {type: "tw-edit-tiddler", handler: "handleEditTiddlerEvent"}, {type: "tw-delete-tiddler", handler: "handleDeleteTiddlerEvent"}, {type: "tw-save-tiddler", handler: "handleSaveTiddlerEvent"}, {type: "tw-cancel-tiddler", handler: "handleCancelTiddlerEvent"}, {type: "tw-close-tiddler", handler: "handleCloseTiddlerEvent"}, {type: "tw-close-all-tiddlers", handler: "handleCloseAllTiddlersEvent"}, {type: "tw-close-other-tiddlers", handler: "handleCloseOtherTiddlersEvent"}, {type: "tw-new-tiddler", handler: "handleNewTiddlerEvent"}, {type: "tw-import-tiddlers", handler: "handleImportTiddlersEvent"}, ]); }; /* Inherit from the base widget class */ NavigatorWidget.prototype = new Widget(); /* Render this widget into the DOM */ NavigatorWidget.prototype.render = function(parent,nextSibling) { this.parentDomNode = parent; this.computeAttributes(); this.execute(); this.renderChildren(parent,nextSibling); }; /* Compute the internal state of the widget */ NavigatorWidget.prototype.execute = function() { // Get our parameters this.storyTitle = this.getAttribute("story"); this.historyTitle = this.getAttribute("history"); // Construct the child widgets this.makeChildWidgets(); }; /* Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering */ NavigatorWidget.prototype.refresh = function(changedTiddlers) { var changedAttributes = this.computeAttributes(); if(changedAttributes.story || changedAttributes.history) { this.refreshSelf(); return true; } else { return this.refreshChildren(changedTiddlers); } }; NavigatorWidget.prototype.getStoryList = function() { this.storyList = this.wiki.getTiddlerList(this.storyTitle); }; NavigatorWidget.prototype.saveStoryList = function() { var storyTiddler = this.wiki.getTiddler(this.storyTitle); this.wiki.addTiddler(new $tw.Tiddler({ title: this.storyTitle },storyTiddler,{list: this.storyList})); }; NavigatorWidget.prototype.findTitleInStory = function(title,defaultIndex) { for(var t=0; t=0; t--) { // Replace the first story instance of the original tiddler name with the draft title if(this.storyList[t] === title) { if(!gotOne) { this.storyList[t] = draftTiddler.fields.title; gotOne = true; } else { this.storyList.splice(t,1); } } else if(this.storyList[t] === draftTiddler.fields.title) { // Remove any existing references to the draft this.storyList.splice(t,1); } } this.addToHistory(draftTiddler.fields.title,event.navigateFromClientRect); this.saveStoryList(); return false; }; // Delete a tiddler NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) { // Get the tiddler we're deleting var title = event.param || event.tiddlerTitle, tiddler = this.wiki.getTiddler(title); // Check if the tiddler we're deleting is in draft mode if(tiddler.hasField("draft.title")) { // Delete the original tiddler this.wiki.deleteTiddler(tiddler.fields["draft.of"]); } // Delete this tiddler this.wiki.deleteTiddler(title); // Remove the closed tiddler from the story this.getStoryList(); // Look for tiddler with this title to close var slot = this.findTitleInStory(title,-1); if(slot !== -1) { this.storyList.splice(slot,1); this.saveStoryList(); } return false; }; /* Create/reuse the draft tiddler for a given title */ NavigatorWidget.prototype.getDraftTiddler = function(targetTitle) { // See if there is already a draft tiddler for this tiddler var drafts = []; this.wiki.forEachTiddler(function(title,tiddler) { if(tiddler.fields["draft.title"] && tiddler.fields["draft.of"] === targetTitle) { drafts.push(tiddler); } }); if(drafts.length > 0) { return drafts[0]; } // Get the current value of the tiddler we're editing var tiddler = this.wiki.getTiddler(targetTitle), draftTitle = this.generateDraftTitle(targetTitle); // Save the initial value of the draft tiddler var draftTiddler = new $tw.Tiddler( {text: "Type the text for the tiddler '" + targetTitle + "'"}, tiddler, { title: draftTitle, "draft.title": targetTitle, "draft.of": targetTitle }, this.wiki.getModificationFields() ); this.wiki.addTiddler(draftTiddler); return draftTiddler; }; /* Generate a title for the draft of a given tiddler */ NavigatorWidget.prototype.generateDraftTitle = function(title) { var c = 0; do { var draftTitle = "Draft " + (c ? (c + 1) + " " : "") + "of '" + title + "'"; c++; } while(this.wiki.tiddlerExists(draftTitle)); return draftTitle; }; // Take a tiddler out of edit mode, saving the changes NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) { this.getStoryList(); var title = event.param || event.tiddlerTitle, storyTiddlerModified = false; // We have to special case saving the story tiddler itself for(var t=0; t