From 2a56c043d770b788a8249ce27a25a97466b9542f Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Mon, 27 Aug 2012 21:48:57 +0100 Subject: [PATCH] Basic, dumb saving in TiddlyFox now works It seems to work OK, but could do with more of a user interface for confirmations and so on... --- tiddlyfox/extension/content/inject.js | 45 ++++++++ tiddlyfox/extension/content/overlay.js | 102 ++++++++++++++++-- .../extension/content/tiddlyfox_32x32.png | Bin 5823 -> 3649 bytes tiddlyfox/extension/tiddlyfox.xpi | Bin 10788 -> 10748 bytes 4 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 tiddlyfox/extension/content/inject.js diff --git a/tiddlyfox/extension/content/inject.js b/tiddlyfox/extension/content/inject.js new file mode 100644 index 000000000..caa732290 --- /dev/null +++ b/tiddlyfox/extension/content/inject.js @@ -0,0 +1,45 @@ +/* +The JavaScript in this file is injected into each TiddlyWiki page that loads +*/ + +(function () { + + /* + Returns true if successful, false if failed, null if not available + */ + var injectedSaveFile = function(path,content) { + // Find the message box element + var messageBox = document.getElementById("tiddlyfox-message-box"); + if(messageBox) { + // Create the message element and put it in the message box + var message = document.createElement("div"); + message.setAttribute("tiddlyfox-path",path); + message.setAttribute("tiddlyfox-content",content); + messageBox.appendChild(message); + // Create and dispatch the custom event to the extension + var event = document.createEvent("Events"); + event.initEvent("tiddlyfox-save-file",true,false); + message.dispatchEvent(event); + } + return true; + }; + + /* + Returns text if successful, false if failed, null if not available + */ + var injectedLoadFile = function(path) { + try { + // Just the read the file synchronously + var xhReq = new XMLHttpRequest(); + xhReq.open("GET", "file://" + path, false); + xhReq.send(null); + return xhReq.responseText; + } catch(ex) { + return false; + } + }; + + window.mozillaSaveFile = injectedSaveFile; + window.mozillaLoadFile = injectedLoadFile; + +})(); \ No newline at end of file diff --git a/tiddlyfox/extension/content/overlay.js b/tiddlyfox/extension/content/overlay.js index 579e06383..d9d0bb4fe 100644 --- a/tiddlyfox/extension/content/overlay.js +++ b/tiddlyfox/extension/content/overlay.js @@ -1,12 +1,96 @@ -var TiddlyFox = { - onLoad: function() { - // initialization code - this.initialized = true; - }, +/* + +The JavaScript code in this file is executed via `overlay.xul` when Firefox starts up. + +*/ + +var TiddlyFox = { + + // Called when the main browser has loaded + onLoad: function(event) { + // Register a page load event + var appcontent = document.getElementById("appcontent"); + if(appcontent){ + appcontent.addEventListener("DOMContentLoaded",TiddlyFox.onPageLoad,true); + } + }, + + // Called each time a page loads + onPageLoad: function(event) { + // Get the document and window + var doc = event.originalTarget, + win = doc.defaultView; + // If it is a TiddlyWiki + if(TiddlyFox.isTiddlyWiki(doc,win)) { + alert("TiddlyFox: Enabling TiddlyWiki file saving"); + TiddlyFox.injectPage(doc); + } + }, + + injectPage: function(doc) { + // Inject the message box + var messageBox = doc.createElement("div"); + messageBox.id = "tiddlyfox-message-box"; + messageBox.style.display = "none"; + doc.body.appendChild(messageBox); + // Attach the event handler to the message box + messageBox.addEventListener("tiddlyfox-save-file",TiddlyFox.onSaveFile,false); + // Load the script text + var xhReq = new XMLHttpRequest(); + xhReq.open("GET","chrome://tiddlyfox/content/inject.js",false); + xhReq.send(null); + var injectCode = xhReq.responseText; + // Inject the script + var code = doc.createTextNode(injectCode); + var scr = doc.createElement("script"); + scr.type = "text/javascript"; + scr.appendChild(code); + doc.getElementsByTagName("head")[0].appendChild(scr) + }, + + saveFile: function(filePath,content) { + try { + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile); + file.initWithPath(filePath); + if(!file.exists()) + file.create(0,0x01B4);// 0x01B4 = 0664 + var out = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream); + out.init(file,0x22,0x04,null); + out.write(content,content.length); + out.flush(); + out.close(); + return true; + } catch(ex) { + return false; + } + }, + + onSaveFile: function(event) { + // Get the details from the message + var message = event.target, + path = message.getAttribute("tiddlyfox-path"), + content = message.getAttribute("tiddlyfox-content"); + // Save the file + TiddlyFox.saveFile(path,content); + // Remove the message element from the message box + message.parentNode.removeChild(message); + return false; + }, + + // Called via `overlay.xul` when the menu item is selected + onMenuItemCommand: function() { + window.open("chrome://tiddlyfox/content/hello.xul", "", "chrome"); + }, + + isTiddlyWiki: function(doc,win) { + // Test whether the document is a TiddlyWiki (we don't have access to JS objects in it) + return (doc.scripts[0].id === "versionArea"); + } - onMenuItemCommand: function() { - window.open("chrome://tiddlyfox/content/hello.xul", "", "chrome"); - } }; -window.addEventListener("load", function(e) { TiddlyFox.onLoad(e); }, false); +window.addEventListener("load",function load(event) { + window.removeEventListener("load",load,false); + TiddlyFox.onLoad(event); +},false); diff --git a/tiddlyfox/extension/content/tiddlyfox_32x32.png b/tiddlyfox/extension/content/tiddlyfox_32x32.png index 8ed46bd7ea52644a54c25d08a706887bed6d0cab..058cbf71a53514258bb66e8d94f6b29abfc804f6 100644 GIT binary patch delta 971 zcmdn5dr)RWD_1@9GEW!BkO?d|P%Zr?ubQh(&|;lnjGHEU|l zxW7F5Fwt=W^WFRRKmY!1J$WCiT-uw54;z2~{w?a_>e~A4?%lgJg@p^H3~fugUdt~}Ise=!(JZxNHr)AqKuE#GgKHzY6}^7r>wi4JK^ zd}IBj{EzQSidkr>de{tg_Pn@%3I`917VrAM>xTKYr)ly{wM?(i0an zuPE1iAYh$bd6?%|K}}K7qNXr?#kDOw{~w(VNh>Uz_~eG#leL>SPmYR?e);0XiD#!T z-M@R+_14#KmDSbO{yshh-rn7xRFv+`$xxH?K63TgrAw2h$XVZ)(>K*Pm9%li*#}MG ze4nN_-z@JEt^Y00YpEm7VKMFU^*_~ni~AM?oZjetX14CS)vHfO_|3QYp7hpR`Wxqq z7cU;Xew}^r$hoZtEicGasMc*vmXH5(?3i1xO@&*%`!UVn{wd0)j~_pNrMQY^AJ6Ix zwMiS39p35Hl$AYO%F4{Rs!pIc1OA1Ch)PX%knhTlZ}5-n}O>rkE)0 zkh$${Br);Ut*E&8_;7)Ly8@2QcYoAzW7?G4VyFMQ=D#g1Ev=e3?LOzcIdh)G=zZ7Z z@KIw+T6w^K#>JN}HQ&E^V^F2+{IlVf!6to9fh9?$rJ>=i@d5S+4~8o!%;)HM+t%2~ qSXWaMlKf0!s{ngLqnW~fhQv8LK3JHZn#RDuz~JfX=d#Wzp$PzN{^#8Q delta 3162 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 Dom=Zp diff --git a/tiddlyfox/extension/tiddlyfox.xpi b/tiddlyfox/extension/tiddlyfox.xpi index b84c2103c8589f2b6d4d6eed800983238d1429ba..377b133b3dff3a0e4d92a1de3cebee12fbe24f31 100644 GIT binary patch delta 4916 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 a$;HKR3;te|hC23=9m$j0_Ay3^EMK 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