1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-12-28 02:50:27 +00:00
TiddlyWiki5/tw2/source/tiddlywiki/js/Saving.js
Jeremy Ruston a1c8ac624f Added first pass at support for building TiddlyWiki 2.6.x with TW5
There are still some whitespace and attribute ordering issues, but the
result runs correctly.
2012-05-29 22:02:38 +01:00

249 lines
8.1 KiB
JavaScript
Executable File

//--
//-- Saving
//--
var saveUsingSafari = false;
var startSaveArea = '<div id="' + 'storeArea">'; // Split up into two so that indexOf() of this source doesn't find it
var startSaveAreaRE = /<((div)|(DIV)) ((id)|(ID))=["']?storeArea['"]?>/; // Used for IE6
var endSaveArea = '</d' + 'iv>';
var endSaveAreaCaps = '</D' + 'IV>';
// If there are unsaved changes, force the user to confirm before exitting
function confirmExit()
{
hadConfirmExit = true;
if((store && store.isDirty && store.isDirty()) || (story && story.areAnyDirty && story.areAnyDirty()))
return config.messages.confirmExit;
}
// Give the user a chance to save changes before exitting
function checkUnsavedChanges()
{
if(store && store.isDirty && store.isDirty() && window.hadConfirmExit === false) {
if(confirm(config.messages.unsavedChangesWarning))
saveChanges();
}
}
function updateLanguageAttribute(s)
{
if(config.locale) {
var mRE = /(<html(?:.*?)?)(?: xml:lang\="([a-z]+)")?(?: lang\="([a-z]+)")?>/;
var m = mRE.exec(s);
if(m) {
var t = m[1];
if(m[2])
t += ' xml:lang="' + config.locale + '"';
if(m[3])
t += ' lang="' + config.locale + '"';
t += ">";
s = s.substr(0,m.index) + t + s.substr(m.index+m[0].length);
}
}
return s;
}
function updateMarkupBlock(s,blockName,tiddlerName)
{
return s.replaceChunk(
"<!--%0-START-->".format([blockName]),
"<!--%0-END-->".format([blockName]),
"\n" + convertUnicodeToFileFormat(store.getRecursiveTiddlerText(tiddlerName,"")) + "\n");
}
function updateOriginal(original,posDiv,localPath)
{
if(!posDiv)
posDiv = locateStoreArea(original);
if(!posDiv) {
alert(config.messages.invalidFileError.format([localPath]));
return null;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
convertUnicodeToFileFormat(store.allTiddlersAsHtml()) + "\n" +
original.substr(posDiv[1]);
var newSiteTitle = convertUnicodeToFileFormat(getPageTitle()).htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised = updateLanguageAttribute(revised);
revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
return revised;
}
function locateStoreArea(original)
{
// Locate the storeArea divs
if(!original)
return null;
var posOpeningDiv = original.search(startSaveAreaRE);
var limitClosingDiv = original.indexOf("<"+"!--POST-STOREAREA--"+">");
if(limitClosingDiv == -1)
limitClosingDiv = original.indexOf("<"+"!--POST-BODY-START--"+">");
var start = limitClosingDiv == -1 ? original.length : limitClosingDiv;
var posClosingDiv = original.lastIndexOf(endSaveArea,start);
if(posClosingDiv == -1)
posClosingDiv = original.lastIndexOf(endSaveAreaCaps,start);
return (posOpeningDiv != -1 && posClosingDiv != -1) ? [posOpeningDiv,posClosingDiv] : null;
}
function autoSaveChanges(onlyIfDirty,tiddlers)
{
if(config.options.chkAutoSave)
saveChanges(onlyIfDirty,tiddlers);
}
function loadOriginal(localPath)
{
return loadFile(localPath);
}
// Save this tiddlywiki with the pending changes
function saveChanges(onlyIfDirty,tiddlers)
{
if(onlyIfDirty && !store.isDirty())
return;
clearMessage();
var t0 = new Date();
var msg = config.messages;
//# Get the URL of the document
var originalPath = document.location.toString();
//# Check we were loaded from a file URL
if(originalPath.substr(0,5) != "file:") {
alert(msg.notFileUrlError);
if(store.tiddlerExists(msg.saveInstructions))
story.displayTiddler(null,msg.saveInstructions);
return;
}
var localPath = getLocalPath(originalPath);
//# Load the original file
var original = loadOriginal(localPath);
if(original == null) {
alert(msg.cantSaveError);
if(store.tiddlerExists(msg.saveInstructions))
story.displayTiddler(null,msg.saveInstructions);
return;
}
//# Locate the storeArea div's
var posDiv = locateStoreArea(original);
if(!posDiv) {
alert(msg.invalidFileError.format([localPath]));
return;
}
saveMain(localPath,original,posDiv);
if(config.options.chkSaveBackups)
saveBackup(localPath,original);
if(config.options.chkSaveEmptyTemplate)
saveEmpty(localPath,original,posDiv);
if(config.options.chkGenerateAnRssFeed && saveRss instanceof Function)
saveRss(localPath);
if(config.options.chkDisplayInstrumentation)
displayMessage("saveChanges " + (new Date()-t0) + " ms");
}
function saveMain(localPath,original,posDiv)
{
var save;
try {
//# Save new file
var revised = updateOriginal(original,posDiv,localPath);
save = saveFile(localPath,revised);
} catch (ex) {
showException(ex);
}
if(save) {
displayMessage(config.messages.mainSaved,"file://" + localPath);
store.setDirty(false);
} else {
alert(config.messages.mainFailed);
}
}
function saveBackup(localPath,original)
{
//# Save the backup
var backupPath = getBackupPath(localPath);
var backup = copyFile(backupPath,localPath);
//# Browser does not support copy, so use save instead
if(!backup)
backup = saveFile(backupPath,original);
if(backup)
displayMessage(config.messages.backupSaved,"file://" + backupPath);
else
alert(config.messages.backupFailed);
}
function saveEmpty(localPath,original,posDiv)
{
//# Save empty template
var emptyPath,p;
if((p = localPath.lastIndexOf("/")) != -1)
emptyPath = localPath.substr(0,p) + "/";
else if((p = localPath.lastIndexOf("\\")) != -1)
emptyPath = localPath.substr(0,p) + "\\";
else
emptyPath = localPath + ".";
emptyPath += "empty.html";
var empty = original.substr(0,posDiv[0] + startSaveArea.length) + original.substr(posDiv[1]);
var emptySave = saveFile(emptyPath,empty);
if(emptySave)
displayMessage(config.messages.emptySaved,"file://" + emptyPath);
else
alert(config.messages.emptyFailed);
}
function getLocalPath(origPath)
{
var originalPath = convertUriToUTF8(origPath,config.options.txtFileSystemCharSet);
// Remove any location or query part of the URL
var argPos = originalPath.indexOf("?");
if(argPos != -1)
originalPath = originalPath.substr(0,argPos);
var hashPos = originalPath.indexOf("#");
if(hashPos != -1)
originalPath = originalPath.substr(0,hashPos);
// Convert file://localhost/ to file:///
if(originalPath.indexOf("file://localhost/") == 0)
originalPath = "file://" + originalPath.substr(16);
// Convert to a native file format
//# "file:///x:/path/path/path..." - pc local file --> "x:\path\path\path..."
//# "file://///server/share/path/path/path..." - FireFox pc network file --> "\\server\share\path\path\path..."
//# "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."
//# "file://server/share/path/path/path..." - pc network file --> "\\server\share\path\path\path..."
var localPath;
if(originalPath.charAt(9) == ":") // pc local file
localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
else if(originalPath.indexOf("file://///") == 0) // FireFox pc network file
localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
else if(originalPath.indexOf("file:///") == 0) // mac/unix local file
localPath = unescape(originalPath.substr(7));
else if(originalPath.indexOf("file:/") == 0) // mac/unix local file
localPath = unescape(originalPath.substr(5));
else // pc network file
localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\");
return localPath;
}
function getBackupPath(localPath,title,extension)
{
var slash = "\\";
var dirPathPos = localPath.lastIndexOf("\\");
if(dirPathPos == -1) {
dirPathPos = localPath.lastIndexOf("/");
slash = "/";
}
var backupFolder = config.options.txtBackupFolder;
if(!backupFolder || backupFolder == "")
backupFolder = ".";
var backupPath = localPath.substr(0,dirPathPos) + slash + backupFolder + localPath.substr(dirPathPos);
backupPath = backupPath.substr(0,backupPath.lastIndexOf(".")) + ".";
//# replace illegal filename characters(// \/:*?"<>|) and space with underscore
if(title)
backupPath += title.replace(/[\\\/\*\?\":<> ]/g,"_") + ".";
backupPath += (new Date()).convertToYYYYMMDDHHMMSSMMM() + "." + (extension || "html");
return backupPath;
}