upgrade TiddlyWiki to v2.8.1
Notably TiddlyWiki provides now a fallback mechanism in case the saving to a local file fails due to security restrictions. When this happens, TiddlyWiki generates a download link pointing to the current content; this way one is at least able to "save as" through the browser context menu. Due to some controversial policy changes in recent Firefox versions the support for saving to local files was removed. The rationale given by the Firefox developers was that this is a rarely used and generally outdated concept; preferrably people shall use extensions and save to cloud services (!) Anyway, Jeremy Ruston, the original author of TiddlyWiki, wrote a Firefox plugin called "TiddlyFox" to work around these arcane limitations.
This commit is contained in:
parent
1f1d478da2
commit
fada231a6b
2 changed files with 264 additions and 28 deletions
144
wiki/empty.html
144
wiki/empty.html
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<script id="versionArea" type="text/javascript">
|
<script id="versionArea" type="text/javascript">
|
||||||
//<![CDATA[
|
//<![CDATA[
|
||||||
var version = {title: "TiddlyWiki", major: 2, minor: 7, revision: 2, date: new Date("May 15, 2013"), extensions: {}};
|
var version = {title: "TiddlyWiki", major: 2, minor: 8, revision: 1, date: new Date("June 23, 2013"), extensions: {}};
|
||||||
|
|
||||||
//]]>
|
//]]>
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -46,7 +46,7 @@ DAMAGE.
|
||||||
<!--}}}-->
|
<!--}}}-->
|
||||||
|
|
||||||
<!--PRE-HEAD-END-->
|
<!--PRE-HEAD-END-->
|
||||||
<title> Empty TiddlyWiki 2.7.2 - a local web scrapbook in a single HTML page </title>
|
<title> Empty TiddlyWiki 2.8.1 - a local web scrapbook in a single HTML page </title>
|
||||||
<style id="styleArea" type="text/css">
|
<style id="styleArea" type="text/css">
|
||||||
#saveTest {display:none;}
|
#saveTest {display:none;}
|
||||||
#messageArea {display:none;}
|
#messageArea {display:none;}
|
||||||
|
|
@ -862,6 +862,8 @@ merge(config.messages,{
|
||||||
emptySaved: "Empty template saved",
|
emptySaved: "Empty template saved",
|
||||||
emptyFailed: "Failed to save empty template file",
|
emptyFailed: "Failed to save empty template file",
|
||||||
mainSaved: "Main TiddlyWiki file saved",
|
mainSaved: "Main TiddlyWiki file saved",
|
||||||
|
mainDownload: "Downloading/saving main TiddlyWiki file",
|
||||||
|
mainDownloadManual: "RIGHT CLICK HERE to download/save main TiddlyWiki file",
|
||||||
mainFailed: "Failed to save main TiddlyWiki file. Your changes have not been saved",
|
mainFailed: "Failed to save main TiddlyWiki file. Your changes have not been saved",
|
||||||
macroError: "Error in macro <<%0>>",
|
macroError: "Error in macro <<%0>>",
|
||||||
macroErrorDetails: "Error while executing macro <<%0>>:\n%1",
|
macroErrorDetails: "Error while executing macro <<%0>>:\n%1",
|
||||||
|
|
@ -1274,12 +1276,18 @@ var pluginInfo,tiddler; // Used to pass information to plugins in loadPlugins()
|
||||||
|
|
||||||
// Whether this file can be saved back to the same location [Preemption]
|
// Whether this file can be saved back to the same location [Preemption]
|
||||||
window.allowSave = window.allowSave || function(l)
|
window.allowSave = window.allowSave || function(l)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Whether this file is being viewed locally
|
||||||
|
window.isLocal = function()
|
||||||
{
|
{
|
||||||
return (document.location.protocol == "file:");
|
return (document.location.protocol == "file:");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether to use the JavaSaver applet
|
// Whether to use the JavaSaver applet
|
||||||
var useJavaSaver = window.allowSave() && (config.browser.isSafari || config.browser.isOpera);
|
var useJavaSaver = window.isLocal() && (config.browser.isSafari || config.browser.isOpera);
|
||||||
|
|
||||||
// Allow preemption code a chance to tweak config and useJavaSaver [Preemption]
|
// Allow preemption code a chance to tweak config and useJavaSaver [Preemption]
|
||||||
if (window.tweakConfig) window.tweakConfig();
|
if (window.tweakConfig) window.tweakConfig();
|
||||||
|
|
@ -1291,6 +1299,7 @@ if(!window || !window.console) {
|
||||||
// Starting up
|
// Starting up
|
||||||
function main()
|
function main()
|
||||||
{
|
{
|
||||||
|
window.originalHTML=recreateOriginal();
|
||||||
|
|
||||||
var t10,t9,t8,t7,t6,t5,t4,t3,t2,t1,t0 = new Date();
|
var t10,t9,t8,t7,t6,t5,t4,t3,t2,t1,t0 = new Date();
|
||||||
startingUp = true;
|
startingUp = true;
|
||||||
|
|
@ -1318,7 +1327,7 @@ function main()
|
||||||
t3 = new Date();
|
t3 = new Date();
|
||||||
invokeParamifier(params,"onload");
|
invokeParamifier(params,"onload");
|
||||||
t4 = new Date();
|
t4 = new Date();
|
||||||
readOnly = window.allowSave() ? false : config.options.chkHttpReadOnly;
|
readOnly = window.isLocal() ? false : config.options.chkHttpReadOnly;
|
||||||
var pluginProblem = loadPlugins("systemConfig");
|
var pluginProblem = loadPlugins("systemConfig");
|
||||||
doc.trigger("loadPlugins");
|
doc.trigger("loadPlugins");
|
||||||
t5 = new Date();
|
t5 = new Date();
|
||||||
|
|
@ -6605,9 +6614,40 @@ function autoSaveChanges(onlyIfDirty,tiddlers)
|
||||||
function loadOriginal(localPath)
|
function loadOriginal(localPath)
|
||||||
{
|
{
|
||||||
var content=loadFile(localPath);
|
var content=loadFile(localPath);
|
||||||
|
if (!content) content=window.originalHTML||recreateOriginal();
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function recreateOriginal()
|
||||||
|
{
|
||||||
|
// construct doctype
|
||||||
|
var content = "<!DOCTYPE ";
|
||||||
|
var t=document.doctype;
|
||||||
|
if (!t)
|
||||||
|
content+="html"
|
||||||
|
else {
|
||||||
|
content+=t.name;
|
||||||
|
if (t.publicId) content+=' PUBLIC "'+t.publicId+'"';
|
||||||
|
else if (t.systemId) content+=' SYSTEM "'+t.systemId+'"';
|
||||||
|
}
|
||||||
|
content+=' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"';
|
||||||
|
content+='>\n';
|
||||||
|
|
||||||
|
// append current document content
|
||||||
|
content+=document.documentElement.outerHTML;
|
||||||
|
|
||||||
|
content=content.replace(/<div id="saveTest">savetest<\/div>/,'<div id="saveTest"></div>');
|
||||||
|
content=content.replace(/script><applet [^\>]*><\/applet>/g,'script>');
|
||||||
|
content=content.replace(/><head>/,'>\n<head>');
|
||||||
|
content=content.replace(/\n\n<\/body><\/html>$/,'</body>\n</html>\n');
|
||||||
|
content=content.replace(/(<(meta) [^\>]*[^\/])>/g,'$1 />');
|
||||||
|
content=content.replace(/<noscript>[^\<]*<\/noscript>/,
|
||||||
|
function(m){return m.replace(/</g,'<').replace(/>/g,'>');});
|
||||||
|
content=content.replace(/<div id="copyright">[^\<]*<\/div>/,
|
||||||
|
function(m){return m.replace(/\xA9/g,'©');});
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
// Save this tiddlywiki with the pending changes
|
// Save this tiddlywiki with the pending changes
|
||||||
function saveChanges(onlyIfDirty,tiddlers)
|
function saveChanges(onlyIfDirty,tiddlers)
|
||||||
|
|
@ -6637,17 +6677,23 @@ function saveChanges(onlyIfDirty,tiddlers)
|
||||||
alert(msg.invalidFileError.format([localPath]));
|
alert(msg.invalidFileError.format([localPath]));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var co=config.options; //# abbreviation
|
||||||
|
config.saveByDownload=false;
|
||||||
|
config.saveByManualDownload=false;
|
||||||
saveMain(localPath,original,posDiv);
|
saveMain(localPath,original,posDiv);
|
||||||
if(config.options.chkSaveBackups)
|
if (!config.saveByDownload && !config.saveByManualDownload) {
|
||||||
saveBackup(localPath,original);
|
if(co.chkSaveBackups)
|
||||||
if(config.options.chkSaveEmptyTemplate)
|
saveBackup(localPath,original);
|
||||||
saveEmpty(localPath,original,posDiv);
|
if(co.chkSaveEmptyTemplate)
|
||||||
if(config.options.chkGenerateAnRssFeed && saveRss instanceof Function)
|
saveEmpty(localPath,original,posDiv);
|
||||||
saveRss(localPath);
|
if(co.chkGenerateAnRssFeed && saveRss instanceof Function)
|
||||||
if(config.options.chkDisplayInstrumentation)
|
saveRss(localPath);
|
||||||
|
}
|
||||||
|
if(co.chkDisplayInstrumentation)
|
||||||
displayMessage("saveChanges " + (new Date()-t0) + " ms");
|
displayMessage("saveChanges " + (new Date()-t0) + " ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function saveMain(localPath,original,posDiv)
|
function saveMain(localPath,original,posDiv)
|
||||||
{
|
{
|
||||||
var save;
|
var save;
|
||||||
|
|
@ -6658,7 +6704,16 @@ function saveMain(localPath,original,posDiv)
|
||||||
showException(ex);
|
showException(ex);
|
||||||
}
|
}
|
||||||
if(save) {
|
if(save) {
|
||||||
displayMessage(config.messages.mainSaved,"file://" + localPath);
|
if (!config.saveByManualDownload) {
|
||||||
|
if (config.saveByDownload) { //# set by HTML5DownloadSaveFile()
|
||||||
|
var link = getDataURI(revised);
|
||||||
|
var msg = config.messages.mainDownload;
|
||||||
|
} else {
|
||||||
|
var link = "file://" + localPath;
|
||||||
|
var msg = config.messages.mainSaved;
|
||||||
|
}
|
||||||
|
displayMessage(msg,link);
|
||||||
|
}
|
||||||
store.setDirty(false);
|
store.setDirty(false);
|
||||||
} else {
|
} else {
|
||||||
alert(config.messages.mainFailed);
|
alert(config.messages.mainFailed);
|
||||||
|
|
@ -6819,6 +6874,10 @@ window.saveFile = window.saveFile || function(fileUrl,content)
|
||||||
r = ieSaveFile(fileUrl,content);
|
r = ieSaveFile(fileUrl,content);
|
||||||
if(!r)
|
if(!r)
|
||||||
r = javaSaveFile(fileUrl,content);
|
r = javaSaveFile(fileUrl,content);
|
||||||
|
if(!r)
|
||||||
|
r = HTML5DownloadSaveFile(fileUrl,content);
|
||||||
|
if(!r)
|
||||||
|
r = manualSaveFile(fileUrl,content);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7048,7 +7107,66 @@ function javaLoadFile(filePath)
|
||||||
return content.join("\n");
|
return content.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//--
|
function HTML5DownloadSaveFile(filePath,content)
|
||||||
|
{
|
||||||
|
if(document.createElement("a").download !== undefined) {
|
||||||
|
config.saveByDownload=true;
|
||||||
|
var slashpos=filePath.lastIndexOf("/");
|
||||||
|
if (slashpos==-1) slashpos=filePath.lastIndexOf("\\");
|
||||||
|
var filename=filePath.substr(slashpos+1);
|
||||||
|
var uri = getDataURI(content);
|
||||||
|
var link = document.createElement("a");
|
||||||
|
link.setAttribute("target","_blank");
|
||||||
|
link.setAttribute("href",uri);
|
||||||
|
link.setAttribute("download",filename);
|
||||||
|
document.body.appendChild(link); link.click(); document.body.removeChild(link);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns null if it can't do it, false if there's an error, true if it saved OK
|
||||||
|
function manualSaveFile(filePath,content)
|
||||||
|
{
|
||||||
|
// FALLBACK for showing a link to data: URI
|
||||||
|
config.saveByManualDownload=true;
|
||||||
|
var slashpos=filePath.lastIndexOf("/");
|
||||||
|
if (slashpos==-1) slashpos=filePath.lastIndexOf("\\");
|
||||||
|
var filename=filePath.substr(slashpos+1);
|
||||||
|
var uri = getDataURI(content);
|
||||||
|
displayMessage(config.messages.mainDownloadManual,uri);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct data URI (using base64 encoding to preserve multi-byte encodings)
|
||||||
|
function getDataURI(data) {
|
||||||
|
if (config.browser.isIE)
|
||||||
|
return "data:text/html,"+encodeURIComponent(data);
|
||||||
|
else
|
||||||
|
return "data:text/html;base64,"+encodeBase64(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function encodeBase64(data) {
|
||||||
|
if (!data) return "";
|
||||||
|
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||||
|
var out = "";
|
||||||
|
var chr1,chr2,chr3="";
|
||||||
|
var enc1,enc2,enc3,enc4="";
|
||||||
|
for (var count=0,i=0; i<data.length; ) {
|
||||||
|
chr1=data.charCodeAt(i++);
|
||||||
|
chr2=data.charCodeAt(i++);
|
||||||
|
chr3=data.charCodeAt(i++);
|
||||||
|
enc1=chr1 >> 2;
|
||||||
|
enc2=((chr1 & 3) << 4) | (chr2 >> 4);
|
||||||
|
enc3=((chr2 & 15) << 2) | (chr3 >> 6);
|
||||||
|
enc4=chr3 & 63;
|
||||||
|
if (isNaN(chr2)) enc3=enc4=64;
|
||||||
|
else if (isNaN(chr3)) enc4=64;
|
||||||
|
out+=keyStr.charAt(enc1)+keyStr.charAt(enc2)+keyStr.charAt(enc3)+keyStr.charAt(enc4);
|
||||||
|
chr1=chr2=chr3=enc1=enc2=enc3=enc4="";
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}//--
|
||||||
//-- Filesystem utilities
|
//-- Filesystem utilities
|
||||||
//--
|
//--
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<script id="versionArea" type="text/javascript">
|
<script id="versionArea" type="text/javascript">
|
||||||
//<![CDATA[
|
//<![CDATA[
|
||||||
var version = {title: "TiddlyWiki", major: 2, minor: 7, revision: 2, date: new Date("May 15, 2013"), extensions: {}};
|
var version = {title: "TiddlyWiki", major: 2, minor: 8, revision: 1, date: new Date("June 23, 2013"), extensions: {}};
|
||||||
|
|
||||||
//]]>
|
//]]>
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -1795,7 +1795,7 @@ The main tool used to implement this separation is the [[Builder Pattern|http://
|
||||||
Another pertinent theme is to make the basic building blocks simpler, while on the other hand gaining much more flexibility for combining these building blocks. For example we try to unfold any "internal-multi" effects into separate instances (e.g. the possibility of having an arbitrary number of single masks at any point of the pipeline instead of having one special masking facility encompassing multiple sub-masks. Similarly, we treat the Objects in the Session in a more uniform manner and gain the possibility to [[place|Placement]] them in various ways.
|
Another pertinent theme is to make the basic building blocks simpler, while on the other hand gaining much more flexibility for combining these building blocks. For example we try to unfold any "internal-multi" effects into separate instances (e.g. the possibility of having an arbitrary number of single masks at any point of the pipeline instead of having one special masking facility encompassing multiple sub-masks. Similarly, we treat the Objects in the Session in a more uniform manner and gain the possibility to [[place|Placement]] them in various ways.
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<div title="DesignPlayerSubsystem" modifier="Ichthyostega" created="201105220216" modified="201305220140" tags="Player design draft" changecount="1">
|
<div title="DesignPlayerSubsystem" modifier="Ichthyostega" created="201105220216" modified="201305220140" tags="Player design draft">
|
||||||
<pre>//Currently (5/2011) this page is used to collect and build up a coherent design for the player subsystem of Lumiera..//
|
<pre>//Currently (5/2011) this page is used to collect and build up a coherent design for the player subsystem of Lumiera..//
|
||||||
|
|
||||||
!Starting point
|
!Starting point
|
||||||
|
|
@ -5706,10 +5706,10 @@ And last but not least: the difficult part of this whole concept is encapsulated
|
||||||
<div title="SideBarOptions" modifier="CehTeh" created="200706200048">
|
<div title="SideBarOptions" modifier="CehTeh" created="200706200048">
|
||||||
<pre><<search>><<closeAll>><<permaview>><<newTiddler>><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options »" "Change TiddlyWiki advanced options">></pre>
|
<pre><<search>><<closeAll>><<permaview>><<newTiddler>><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options »" "Change TiddlyWiki advanced options">></pre>
|
||||||
</div>
|
</div>
|
||||||
<div title="SiteSubtitle" modifier="Ichthyostega" created="200706190044" modified="200802030406">
|
<div title="SiteSubtitle" creator="Lumiera.org" modifier="Ichthyostega" created="200706190044" modified="200802030406">
|
||||||
<pre>Building a Render Nodes Network from Objects in the Session</pre>
|
<pre>Building a Render Nodes Network from Objects in the Session</pre>
|
||||||
</div>
|
</div>
|
||||||
<div title="SiteTitle" modifier="Ichthyostega" created="200706190042" modified="200708080212">
|
<div title="SiteTitle" creator="Ichthyostega" modifier="Ichthyostega" created="200706190042" modified="200708080212">
|
||||||
<pre>Engine</pre>
|
<pre>Engine</pre>
|
||||||
</div>
|
</div>
|
||||||
<div title="SplashScreen" modifier="just me" created="200706220430">
|
<div title="SplashScreen" modifier="just me" created="200706220430">
|
||||||
|
|
@ -8233,6 +8233,8 @@ merge(config.messages,{
|
||||||
emptySaved: "Empty template saved",
|
emptySaved: "Empty template saved",
|
||||||
emptyFailed: "Failed to save empty template file",
|
emptyFailed: "Failed to save empty template file",
|
||||||
mainSaved: "Main TiddlyWiki file saved",
|
mainSaved: "Main TiddlyWiki file saved",
|
||||||
|
mainDownload: "Downloading/saving main TiddlyWiki file",
|
||||||
|
mainDownloadManual: "RIGHT CLICK HERE to download/save main TiddlyWiki file",
|
||||||
mainFailed: "Failed to save main TiddlyWiki file. Your changes have not been saved",
|
mainFailed: "Failed to save main TiddlyWiki file. Your changes have not been saved",
|
||||||
macroError: "Error in macro <<%0>>",
|
macroError: "Error in macro <<%0>>",
|
||||||
macroErrorDetails: "Error while executing macro <<%0>>:\n%1",
|
macroErrorDetails: "Error while executing macro <<%0>>:\n%1",
|
||||||
|
|
@ -8645,12 +8647,18 @@ var pluginInfo,tiddler; // Used to pass information to plugins in loadPlugins()
|
||||||
|
|
||||||
// Whether this file can be saved back to the same location [Preemption]
|
// Whether this file can be saved back to the same location [Preemption]
|
||||||
window.allowSave = window.allowSave || function(l)
|
window.allowSave = window.allowSave || function(l)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Whether this file is being viewed locally
|
||||||
|
window.isLocal = function()
|
||||||
{
|
{
|
||||||
return (document.location.protocol == "file:");
|
return (document.location.protocol == "file:");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether to use the JavaSaver applet
|
// Whether to use the JavaSaver applet
|
||||||
var useJavaSaver = window.allowSave() && (config.browser.isSafari || config.browser.isOpera);
|
var useJavaSaver = window.isLocal() && (config.browser.isSafari || config.browser.isOpera);
|
||||||
|
|
||||||
// Allow preemption code a chance to tweak config and useJavaSaver [Preemption]
|
// Allow preemption code a chance to tweak config and useJavaSaver [Preemption]
|
||||||
if (window.tweakConfig) window.tweakConfig();
|
if (window.tweakConfig) window.tweakConfig();
|
||||||
|
|
@ -8662,6 +8670,7 @@ if(!window || !window.console) {
|
||||||
// Starting up
|
// Starting up
|
||||||
function main()
|
function main()
|
||||||
{
|
{
|
||||||
|
window.originalHTML=recreateOriginal();
|
||||||
|
|
||||||
var t10,t9,t8,t7,t6,t5,t4,t3,t2,t1,t0 = new Date();
|
var t10,t9,t8,t7,t6,t5,t4,t3,t2,t1,t0 = new Date();
|
||||||
startingUp = true;
|
startingUp = true;
|
||||||
|
|
@ -8689,7 +8698,7 @@ function main()
|
||||||
t3 = new Date();
|
t3 = new Date();
|
||||||
invokeParamifier(params,"onload");
|
invokeParamifier(params,"onload");
|
||||||
t4 = new Date();
|
t4 = new Date();
|
||||||
readOnly = window.allowSave() ? false : config.options.chkHttpReadOnly;
|
readOnly = window.isLocal() ? false : config.options.chkHttpReadOnly;
|
||||||
var pluginProblem = loadPlugins("systemConfig");
|
var pluginProblem = loadPlugins("systemConfig");
|
||||||
doc.trigger("loadPlugins");
|
doc.trigger("loadPlugins");
|
||||||
t5 = new Date();
|
t5 = new Date();
|
||||||
|
|
@ -13976,9 +13985,40 @@ function autoSaveChanges(onlyIfDirty,tiddlers)
|
||||||
function loadOriginal(localPath)
|
function loadOriginal(localPath)
|
||||||
{
|
{
|
||||||
var content=loadFile(localPath);
|
var content=loadFile(localPath);
|
||||||
|
if (!content) content=window.originalHTML||recreateOriginal();
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function recreateOriginal()
|
||||||
|
{
|
||||||
|
// construct doctype
|
||||||
|
var content = "<!DOCTYPE ";
|
||||||
|
var t=document.doctype;
|
||||||
|
if (!t)
|
||||||
|
content+="html"
|
||||||
|
else {
|
||||||
|
content+=t.name;
|
||||||
|
if (t.publicId) content+=' PUBLIC "'+t.publicId+'"';
|
||||||
|
else if (t.systemId) content+=' SYSTEM "'+t.systemId+'"';
|
||||||
|
}
|
||||||
|
content+=' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"';
|
||||||
|
content+='>\n';
|
||||||
|
|
||||||
|
// append current document content
|
||||||
|
content+=document.documentElement.outerHTML;
|
||||||
|
|
||||||
|
content=content.replace(/<div id="saveTest">savetest<\/div>/,'<div id="saveTest"></div>');
|
||||||
|
content=content.replace(/script><applet [^\>]*><\/applet>/g,'script>');
|
||||||
|
content=content.replace(/><head>/,'>\n<head>');
|
||||||
|
content=content.replace(/\n\n<\/body><\/html>$/,'</body>\n</html>\n');
|
||||||
|
content=content.replace(/(<(meta) [^\>]*[^\/])>/g,'$1 />');
|
||||||
|
content=content.replace(/<noscript>[^\<]*<\/noscript>/,
|
||||||
|
function(m){return m.replace(/</g,'<').replace(/>/g,'>');});
|
||||||
|
content=content.replace(/<div id="copyright">[^\<]*<\/div>/,
|
||||||
|
function(m){return m.replace(/\xA9/g,'©');});
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
// Save this tiddlywiki with the pending changes
|
// Save this tiddlywiki with the pending changes
|
||||||
function saveChanges(onlyIfDirty,tiddlers)
|
function saveChanges(onlyIfDirty,tiddlers)
|
||||||
|
|
@ -14008,17 +14048,23 @@ function saveChanges(onlyIfDirty,tiddlers)
|
||||||
alert(msg.invalidFileError.format([localPath]));
|
alert(msg.invalidFileError.format([localPath]));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var co=config.options; //# abbreviation
|
||||||
|
config.saveByDownload=false;
|
||||||
|
config.saveByManualDownload=false;
|
||||||
saveMain(localPath,original,posDiv);
|
saveMain(localPath,original,posDiv);
|
||||||
if(config.options.chkSaveBackups)
|
if (!config.saveByDownload && !config.saveByManualDownload) {
|
||||||
saveBackup(localPath,original);
|
if(co.chkSaveBackups)
|
||||||
if(config.options.chkSaveEmptyTemplate)
|
saveBackup(localPath,original);
|
||||||
saveEmpty(localPath,original,posDiv);
|
if(co.chkSaveEmptyTemplate)
|
||||||
if(config.options.chkGenerateAnRssFeed && saveRss instanceof Function)
|
saveEmpty(localPath,original,posDiv);
|
||||||
saveRss(localPath);
|
if(co.chkGenerateAnRssFeed && saveRss instanceof Function)
|
||||||
if(config.options.chkDisplayInstrumentation)
|
saveRss(localPath);
|
||||||
|
}
|
||||||
|
if(co.chkDisplayInstrumentation)
|
||||||
displayMessage("saveChanges " + (new Date()-t0) + " ms");
|
displayMessage("saveChanges " + (new Date()-t0) + " ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function saveMain(localPath,original,posDiv)
|
function saveMain(localPath,original,posDiv)
|
||||||
{
|
{
|
||||||
var save;
|
var save;
|
||||||
|
|
@ -14029,7 +14075,16 @@ function saveMain(localPath,original,posDiv)
|
||||||
showException(ex);
|
showException(ex);
|
||||||
}
|
}
|
||||||
if(save) {
|
if(save) {
|
||||||
displayMessage(config.messages.mainSaved,"file://" + localPath);
|
if (!config.saveByManualDownload) {
|
||||||
|
if (config.saveByDownload) { //# set by HTML5DownloadSaveFile()
|
||||||
|
var link = getDataURI(revised);
|
||||||
|
var msg = config.messages.mainDownload;
|
||||||
|
} else {
|
||||||
|
var link = "file://" + localPath;
|
||||||
|
var msg = config.messages.mainSaved;
|
||||||
|
}
|
||||||
|
displayMessage(msg,link);
|
||||||
|
}
|
||||||
store.setDirty(false);
|
store.setDirty(false);
|
||||||
} else {
|
} else {
|
||||||
alert(config.messages.mainFailed);
|
alert(config.messages.mainFailed);
|
||||||
|
|
@ -14190,6 +14245,10 @@ window.saveFile = window.saveFile || function(fileUrl,content)
|
||||||
r = ieSaveFile(fileUrl,content);
|
r = ieSaveFile(fileUrl,content);
|
||||||
if(!r)
|
if(!r)
|
||||||
r = javaSaveFile(fileUrl,content);
|
r = javaSaveFile(fileUrl,content);
|
||||||
|
if(!r)
|
||||||
|
r = HTML5DownloadSaveFile(fileUrl,content);
|
||||||
|
if(!r)
|
||||||
|
r = manualSaveFile(fileUrl,content);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -14419,7 +14478,66 @@ function javaLoadFile(filePath)
|
||||||
return content.join("\n");
|
return content.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//--
|
function HTML5DownloadSaveFile(filePath,content)
|
||||||
|
{
|
||||||
|
if(document.createElement("a").download !== undefined) {
|
||||||
|
config.saveByDownload=true;
|
||||||
|
var slashpos=filePath.lastIndexOf("/");
|
||||||
|
if (slashpos==-1) slashpos=filePath.lastIndexOf("\\");
|
||||||
|
var filename=filePath.substr(slashpos+1);
|
||||||
|
var uri = getDataURI(content);
|
||||||
|
var link = document.createElement("a");
|
||||||
|
link.setAttribute("target","_blank");
|
||||||
|
link.setAttribute("href",uri);
|
||||||
|
link.setAttribute("download",filename);
|
||||||
|
document.body.appendChild(link); link.click(); document.body.removeChild(link);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns null if it can't do it, false if there's an error, true if it saved OK
|
||||||
|
function manualSaveFile(filePath,content)
|
||||||
|
{
|
||||||
|
// FALLBACK for showing a link to data: URI
|
||||||
|
config.saveByManualDownload=true;
|
||||||
|
var slashpos=filePath.lastIndexOf("/");
|
||||||
|
if (slashpos==-1) slashpos=filePath.lastIndexOf("\\");
|
||||||
|
var filename=filePath.substr(slashpos+1);
|
||||||
|
var uri = getDataURI(content);
|
||||||
|
displayMessage(config.messages.mainDownloadManual,uri);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct data URI (using base64 encoding to preserve multi-byte encodings)
|
||||||
|
function getDataURI(data) {
|
||||||
|
if (config.browser.isIE)
|
||||||
|
return "data:text/html,"+encodeURIComponent(data);
|
||||||
|
else
|
||||||
|
return "data:text/html;base64,"+encodeBase64(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function encodeBase64(data) {
|
||||||
|
if (!data) return "";
|
||||||
|
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||||
|
var out = "";
|
||||||
|
var chr1,chr2,chr3="";
|
||||||
|
var enc1,enc2,enc3,enc4="";
|
||||||
|
for (var count=0,i=0; i<data.length; ) {
|
||||||
|
chr1=data.charCodeAt(i++);
|
||||||
|
chr2=data.charCodeAt(i++);
|
||||||
|
chr3=data.charCodeAt(i++);
|
||||||
|
enc1=chr1 >> 2;
|
||||||
|
enc2=((chr1 & 3) << 4) | (chr2 >> 4);
|
||||||
|
enc3=((chr2 & 15) << 2) | (chr3 >> 6);
|
||||||
|
enc4=chr3 & 63;
|
||||||
|
if (isNaN(chr2)) enc3=enc4=64;
|
||||||
|
else if (isNaN(chr3)) enc4=64;
|
||||||
|
out+=keyStr.charAt(enc1)+keyStr.charAt(enc2)+keyStr.charAt(enc3)+keyStr.charAt(enc4);
|
||||||
|
chr1=chr2=chr3=enc1=enc2=enc3=enc4="";
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}//--
|
||||||
//-- Filesystem utilities
|
//-- Filesystem utilities
|
||||||
//--
|
//--
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue