1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-01-12 10:20:26 +00:00

Major refactoring of the navigator widget

Cleans things up, and hopefully fixes #267
This commit is contained in:
Jermolene 2013-12-12 15:17:12 +00:00
parent 49b3165fbd
commit ae6d1b1685

View File

@ -70,33 +70,76 @@ NavigatorWidget.prototype.refresh = function(changedTiddlers) {
}; };
NavigatorWidget.prototype.getStoryList = function() { NavigatorWidget.prototype.getStoryList = function() {
this.storyList = this.wiki.getTiddlerList(this.storyTitle); return this.storyTitle ? this.wiki.getTiddlerList(this.storyTitle) : null;
}; };
NavigatorWidget.prototype.saveStoryList = function() { NavigatorWidget.prototype.saveStoryList = function(storyList) {
var storyTiddler = this.wiki.getTiddler(this.storyTitle); var storyTiddler = this.wiki.getTiddler(this.storyTitle);
this.wiki.addTiddler(new $tw.Tiddler({ this.wiki.addTiddler(new $tw.Tiddler(
title: this.storyTitle {title: this.storyTitle},
},storyTiddler,{list: this.storyList})); storyTiddler,
{list: storyList}
));
}; };
NavigatorWidget.prototype.findTitleInStory = function(title,defaultIndex) { NavigatorWidget.prototype.findTitleInStory = function(storyList,title,defaultIndex) {
for(var t=0; t<this.storyList.length; t++) { var p = storyList.indexOf(title);
if(this.storyList[t] === title) { return p === -1 ? defaultIndex : p;
return t; };
NavigatorWidget.prototype.removeTitleFromStory = function(storyList,title) {
var p = storyList.indexOf(title);
while(p !== -1) {
storyList.splice(p,1);
p = storyList.indexOf(title);
}
};
NavigatorWidget.prototype.replaceFirstTitleInStory = function(storyList,oldTitle,newTitle) {
var pos = storyList.indexOf(oldTitle);
if(pos !== -1) {
storyList[pos] = newTitle;
do {
pos = storyList.indexOf(oldTitle,pos + 1);
if(pos !== -1) {
storyList.splice(pos,1);
}
} while(pos !== -1);
} else {
storyList.splice(0,0,newTitle);
}
};
NavigatorWidget.prototype.addToStory = function(title,fromTitle) {
var storyList = this.getStoryList();
if(storyList) {
// See if the tiddler is already there
var slot = this.findTitleInStory(storyList,title,-1);
// If not we need to add it
if(slot === -1) {
// First we try to find the position of the story element we navigated from
slot = this.findTitleInStory(storyList,fromTitle,-1) + 1;
// Add the tiddler
storyList.splice(slot,0,title);
// Save the story
this.saveStoryList(storyList);
} }
} }
return defaultIndex;
}; };
/* /*
Add a new record to the top of the history stack Add a new record to the top of the history stack
title: a title string or an array of title strings
fromPageRect: page coordinates of the origin of the navigation
*/ */
NavigatorWidget.prototype.addToHistory = function(title,fromPageRect) { NavigatorWidget.prototype.addToHistory = function(title,fromPageRect) {
var titles = $tw.utils.isArray(title) ? title : [title];
// Add a new record to the top of the history stack // Add a new record to the top of the history stack
if(this.historyTitle) { if(this.historyTitle) {
var historyList = this.wiki.getTiddlerData(this.historyTitle,[]); var historyList = this.wiki.getTiddlerData(this.historyTitle,[]);
historyList.push({title: title, fromPageRect: fromPageRect}); $tw.utils.each(titles,function(title) {
historyList.push({title: title, fromPageRect: fromPageRect});
});
this.wiki.setTiddlerData(this.historyTitle,historyList); this.wiki.setTiddlerData(this.historyTitle,historyList);
} }
}; };
@ -105,73 +148,45 @@ NavigatorWidget.prototype.addToHistory = function(title,fromPageRect) {
Handle a tw-navigate event Handle a tw-navigate event
*/ */
NavigatorWidget.prototype.handleNavigateEvent = function(event) { NavigatorWidget.prototype.handleNavigateEvent = function(event) {
if(this.storyTitle) { this.addToStory(event.navigateTo,event.navigateFromTitle);
// Update the story tiddler if specified
this.getStoryList();
// See if the tiddler is already there
var slot = this.findTitleInStory(event.navigateTo,-1);
// If not we need to add it
if(slot === -1) {
// First we try to find the position of the story element we navigated from
slot = this.findTitleInStory(event.navigateFromTitle,-1) + 1;
// Add the tiddler
this.storyList.splice(slot,0,event.navigateTo);
// Save the story
this.saveStoryList();
}
}
this.addToHistory(event.navigateTo,event.navigateFromClientRect); this.addToHistory(event.navigateTo,event.navigateFromClientRect);
return false; return false;
}; };
// Close a specified tiddler // Close a specified tiddler
NavigatorWidget.prototype.handleCloseTiddlerEvent = function(event) { NavigatorWidget.prototype.handleCloseTiddlerEvent = function(event) {
this.getStoryList(); var title = event.param || event.tiddlerTitle,
storyList = this.getStoryList();
// Look for tiddlers with this title to close // Look for tiddlers with this title to close
var slot = this.findTitleInStory(event.tiddlerTitle,-1); this.removeTitleFromStory(storyList,title);
if(slot !== -1) { this.saveStoryList(storyList);
this.storyList.splice(slot,1);
this.saveStoryList();
}
return false; return false;
}; };
// Close all tiddlers // Close all tiddlers
NavigatorWidget.prototype.handleCloseAllTiddlersEvent = function(event) { NavigatorWidget.prototype.handleCloseAllTiddlersEvent = function(event) {
this.storyList = []; this.saveStoryList([]);
this.saveStoryList();
return false; return false;
}; };
// Close other tiddlers // Close other tiddlers
NavigatorWidget.prototype.handleCloseOtherTiddlersEvent = function(event) { NavigatorWidget.prototype.handleCloseOtherTiddlersEvent = function(event) {
this.storyList = [event.tiddlerTitle]; var title = event.param || event.tiddlerTitle;
this.saveStoryList(); this.saveStoryList([title]);
return false; return false;
}; };
// Place a tiddler in edit mode // Place a tiddler in edit mode
NavigatorWidget.prototype.handleEditTiddlerEvent = function(event) { NavigatorWidget.prototype.handleEditTiddlerEvent = function(event) {
this.getStoryList();
// Replace the specified tiddler with a draft in edit mode // Replace the specified tiddler with a draft in edit mode
var title = event.param || event.tiddlerTitle, var title = event.param || event.tiddlerTitle,
draftTiddler = this.getDraftTiddler(title), draftTiddler = this.makeDraftTiddler(title),
gotOne = false; draftTitle = draftTiddler.fields.title,
for(var t=this.storyList.length-1; t>=0; t--) { storyList = this.getStoryList();
// Replace the first story instance of the original tiddler name with the draft title this.removeTitleFromStory(storyList,draftTitle);
if(this.storyList[t] === title) { this.replaceFirstTitleInStory(storyList,title,draftTitle);
if(!gotOne) { this.addToHistory(draftTitle,event.navigateFromClientRect);
this.storyList[t] = draftTiddler.fields.title; this.saveStoryList(storyList);
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; return false;
}; };
@ -179,32 +194,30 @@ NavigatorWidget.prototype.handleEditTiddlerEvent = function(event) {
NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) { NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {
// Get the tiddler we're deleting // Get the tiddler we're deleting
var title = event.param || event.tiddlerTitle, var title = event.param || event.tiddlerTitle,
tiddler = this.wiki.getTiddler(title); tiddler = this.wiki.getTiddler(title),
storyList = this.getStoryList();
// Check if the tiddler we're deleting is in draft mode // Check if the tiddler we're deleting is in draft mode
if(tiddler.hasField("draft.title")) { if(tiddler.hasField("draft.title")) {
// Delete the original tiddler // Delete the original tiddler
this.wiki.deleteTiddler(tiddler.fields["draft.of"]); var originalTitle = tiddler.fields["draft.of"];
this.wiki.deleteTiddler(originalTitle);
this.removeTitleFromStory(storyList,originalTitle);
} }
// Delete this tiddler // Delete this tiddler
this.wiki.deleteTiddler(title); this.wiki.deleteTiddler(title);
// Remove the closed tiddler from the story // Remove the closed tiddler from the story
this.getStoryList(); this.removeTitleFromStory(storyList,title);
// Look for tiddler with this title to close this.saveStoryList(storyList);
var slot = this.findTitleInStory(title,-1);
if(slot !== -1) {
this.storyList.splice(slot,1);
this.saveStoryList();
}
return false; return false;
}; };
/* /*
Create/reuse the draft tiddler for a given title Create/reuse the draft tiddler for a given title
*/ */
NavigatorWidget.prototype.getDraftTiddler = function(targetTitle) { NavigatorWidget.prototype.makeDraftTiddler = function(targetTitle) {
// See if there is already a draft tiddler for this tiddler // See if there is already a draft tiddler for this tiddler
var drafts = []; var drafts = [];
this.wiki.forEachTiddler(function(title,tiddler) { this.wiki.forEachTiddler({includeSystem: true},function(title,tiddler) {
if(tiddler.fields["draft.title"] && tiddler.fields["draft.of"] === targetTitle) { if(tiddler.fields["draft.title"] && tiddler.fields["draft.of"] === targetTitle) {
drafts.push(tiddler); drafts.push(tiddler);
} }
@ -244,75 +257,58 @@ NavigatorWidget.prototype.generateDraftTitle = function(title) {
// Take a tiddler out of edit mode, saving the changes // Take a tiddler out of edit mode, saving the changes
NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) { NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {
this.getStoryList();
var title = event.param || event.tiddlerTitle, var title = event.param || event.tiddlerTitle,
tiddler = this.wiki.getTiddler(title),
storyList = this.getStoryList(),
storyTiddlerModified = false; // We have to special case saving the story tiddler itself storyTiddlerModified = false; // We have to special case saving the story tiddler itself
for(var t=0; t<this.storyList.length; t++) { // Replace the original tiddler with the draft
if(this.storyList[t] === title) { if(tiddler) {
var tiddler = this.wiki.getTiddler(title); var draftTitle = (tiddler.fields["draft.title"] || "").trim(),
if(tiddler) { draftOf = (tiddler.fields["draft.of"] || "").trim();
var draftTitle = (tiddler.fields["draft.title"] || "").trim(), if(draftTitle) {
draftOf = (tiddler.fields["draft.of"] || "").trim(); var isRename = draftOf !== draftTitle,
if(draftTitle) { isConfirmed = true;
var isRename = draftOf !== draftTitle, if(isRename && this.wiki.tiddlerExists(draftTitle)) {
isConfirmed = true; isConfirmed = confirm("Do you wish to overwrite the tiddler '" + draftTitle + "'?");
if(isRename && this.wiki.tiddlerExists(draftTitle)) { }
isConfirmed = confirm("Do you wish to overwrite the tiddler '" + draftTitle + "'?"); if(isConfirmed) {
} // Save the draft tiddler as the real tiddler
if(isConfirmed) { this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,{
// Save the draft tiddler as the real tiddler title: draftTitle,
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,{ "draft.title": undefined,
title: draftTitle, "draft.of": undefined
"draft.title": undefined, },this.wiki.getModificationFields()));
"draft.of": undefined // Remove the draft tiddler
},this.wiki.getModificationFields())); this.wiki.deleteTiddler(title);
// Remove the draft tiddler // Remove the original tiddler if we're renaming it
this.wiki.deleteTiddler(title); if(isRename) {
// Remove the original tiddler if we're renaming it this.wiki.deleteTiddler(draftOf);
if(isRename) { }
this.wiki.deleteTiddler(draftOf); // Replace the draft in the story with the original
} this.replaceFirstTitleInStory(storyList,title,draftTitle);
// Make the story record point to the newly saved tiddler this.addToHistory(draftTitle,event.navigateFromClientRect);
this.storyList[t] = draftTitle; if(draftTitle !== this.storyTitle) {
// Check if we're modifying the story tiddler itself this.saveStoryList(storyList);
if(draftTitle === this.storyTitle) {
storyTiddlerModified = true;
}
this.addToHistory(draftTitle,event.navigateFromClientRect);
}
} }
} }
} }
} }
if(!storyTiddlerModified) {
this.saveStoryList();
}
return false; return false;
}; };
// Take a tiddler out of edit mode without saving the changes // Take a tiddler out of edit mode without saving the changes
NavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) { NavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) {
this.getStoryList();
var storyTiddlerModified = false;
// Flip the specified tiddler from draft back to the original // Flip the specified tiddler from draft back to the original
var draftTitle = event.param || event.tiddlerTitle, var draftTitle = event.param || event.tiddlerTitle,
draftTiddler = this.wiki.getTiddler(draftTitle); draftTiddler = this.wiki.getTiddler(draftTitle),
if(draftTiddler && draftTiddler.hasField("draft.of")) { originalTitle = draftTiddler.fields["draft.of"],
var originalTitle = draftTiddler.fields["draft.of"]; storyList = this.getStoryList();
if(draftTiddler && originalTitle) {
// Remove the draft tiddler // Remove the draft tiddler
this.wiki.deleteTiddler(draftTitle); this.wiki.deleteTiddler(draftTitle);
// Swap the draft for the original in the story this.replaceFirstTitleInStory(storyList,draftTitle,originalTitle);
for(var t=0; t<this.storyList.length; t++) {
if(this.storyList[t] === draftTitle) {
// Make the story record point to the original tiddler
this.storyList[t] = originalTitle;
storyTiddlerModified = true;
}
}
this.addToHistory(originalTitle,event.navigateFromClientRect); this.addToHistory(originalTitle,event.navigateFromClientRect);
} this.saveStoryList(storyList);
if(storyTiddlerModified) {
this.saveStoryList();
} }
return false; return false;
}; };
@ -320,7 +316,7 @@ NavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) {
// Create a new draft tiddler // Create a new draft tiddler
NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) { NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {
// Get the story details // Get the story details
this.getStoryList(); var storyList = this.getStoryList();
// Get the template tiddler if there is one // Get the template tiddler if there is one
var templateTiddler = this.wiki.getTiddler(event.param); var templateTiddler = this.wiki.getTiddler(event.param);
// Create the new tiddler // Create the new tiddler
@ -348,10 +344,10 @@ NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {
},this.wiki.getModificationFields()); },this.wiki.getModificationFields());
this.wiki.addTiddler(draftTiddler); this.wiki.addTiddler(draftTiddler);
// Update the story to insert the new draft at the top // Update the story to insert the new draft at the top
var slot = this.findTitleInStory(event.navigateFromTitle,-1) + 1; var slot = storyList.indexOf(event.navigateFromTitle);
this.storyList.splice(slot,0,draftTitle); storyList.splice(slot + 1,0,draftTitle);
// Save the updated story // Save the updated story
this.saveStoryList(); this.saveStoryList(storyList);
// Add a new record to the top of the history stack // Add a new record to the top of the history stack
this.addToHistory(draftTitle); this.addToHistory(draftTitle);
return false; return false;
@ -361,8 +357,8 @@ NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {
NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) { NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
var self = this; var self = this;
// Get the story and history details // Get the story and history details
this.getStoryList(); var storyList = this.getStoryList();
var history = this.wiki.getTiddlerData(this.historyTitle,[]); var history = [];
// Get the tiddlers // Get the tiddlers
var tiddlers = []; var tiddlers = [];
try { try {
@ -380,16 +376,16 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
)); ));
if(imported) { if(imported) {
// Add it to the story // Add it to the story
if(self.storyList.indexOf(title) === -1) { if(storyList.indexOf(title) === -1) {
self.storyList.unshift(title); storyList.unshift(title);
} }
// And to history // And to history
history.push({title: title}); history.push(title);
} }
}); });
// Save the updated story and history // Save the updated story and history
this.saveStoryList(); this.saveStoryList(storyList);
this.wiki.setTiddlerData(this.historyTitle,history); this.addToHistory(history);
return false; return false;
}; };