/*** |''Name:''|Plugin: ZiddlyWiki| |''Description:''|Client-side component of the ZiddlyWiki server-side for TiddlyWiki| |''Version:''|1.0.0| |''Date:''|Sep 30, 2006| |''Source:''|http://ziddlywiki.com| |''Author:''|BobMcElrath| |''Email:''|my first name at my last name dot org| |''License:''|[[GPL open source license|http://www.gnu.org/licenses/gpl.html]]| |''~CoreVersion:''|2.1.0| !Description This plugin is useful only in conjunction with the ZiddlyWiki server-side for TiddlyWiki. This plugin is automatically added to any TiddlyWiki downloaded from a ZiddlyWiki server, and should not be added by hand to your TiddlyWiki. If you want to use the ZiddlyWiki server, install that first, and you will automatically get this plugin. !My Server This ZiddlyWiki lives at: {{{ }}} !API {{{ action=get }}} !Code ***/ //{{{ // Place to store my junk if(typeof zw == "undefined") var zw = {}; config.options.checkUnsavedChanges = false; config.options.confirmExit = false; //zw.ieurl = (navigator.appVersion.indexOf('MSIE') > -1) ? 'ie=1&' : ''; zw.editingTiddlers = {}; zw.dirty = false; // flag for when ZW was unable to save something zw.serverUrl = ""; config.messages.loginToEdit = 'You must be logged in to make changes. Viewing source instead.'; config.messages.errorDeleting = 'An error has occurred. Review your Zope error log for details.'; config.messages.errorSaving = 'An error has occurred. Review your Zope error log for details. If you navigate away from this page now, you will lose your changes.'; config.messages.protectedTiddler = 'You are not allowed to edit here. Click OK to view the source.'; config.messages.lockedTiddler = 'This tiddler is currently being edited by %s. Please try again in a few minutes.'; config.messages.lockedTiddlerYou = 'This tiddler is currently locked by you. Would you like to edit anyway?'; config.messages.viewRevisionTooltip = 'View this revision.'; config.messages.exportLinkLabel = 'export to file'; config.messages.exportLinkPrompt = 'Export to a TiddlyWiki file'; config.messages.importLinkLabel = 'import from file'; config.messages.importLinkPrompt = 'Import from a TiddlyWiki file'; config.messages.unsavedChangesWarning = 'Something has gone wrong and ZiddlyWiki was unable to save all changes to the server.\nIf you navigate away from this page, those changes will be lost.\nPress OK to save a backup to a local file.'; config.views.wikified.toolbarRevisions = {text: "revisions", tooltip: "View another revision of this tiddler", popupNone: "No revisions"}; // Shadow tiddlers that are protected config.protectedTiddlers = ['DefaultTiddlers', 'MainMenu']; config.replaceBodyCharacters = [ [/‘/g, "'"], [/’/g, "'"], [/“/g, '"'], [/”/g, '"'], [/…/g, '...'], [/–/g, ' -- '] ]; config.macros.login = { label: 'login', prompt: 'Log into the system', sizeTextbox: 15, // FIXME onmouseover, etc... do these cause a problem? Add (?!onmouseover|onmouseout...) innerHTMLSafe: /^[^<>]*<\/div>$/, handler: function(place) { if(zw.loggedIn) { var link = createTiddlyLink(place, zw.username, true); if(location.protocol == "file:") { link.innerHTML = zw.username + ' (offline)'; } else { link.innerHTML = zw.username + ' (logged in)'; createTiddlyButton(place, "logout", "Log out of the system", this.doLogout); } } else { // FIXME Only make login form if cookie-based login are enabled. var form = document.createElement("form"); form.action = "?action=get&title=ZiddlyStatus"; var u = createTiddlyElement(form, "input", "zw_username"); u.value = "YourName"; u.onclick = this.clearInput; u.size = this.sizeTextbox; u.onkeypress = this.enterSubmit; u.name = "__ac_name"; var p = createTiddlyElement(form, "input", "zw_password"); p.value = "password"; p.size = this.sizeTextbox; p.onclick = this.clearInput; p.onkeypress = this.enterSubmit; p.name = "__ac_password"; place.appendChild(form); createTiddlyButton(place,this.label,this.prompt,this.doLogin); } }, clearInput: function(e) { var u = document.getElementById("zw_username"); var p = document.getElementById("zw_password"); if((e.target == u || e.target == p) && p.type != "password") { u.value = ''; p.value=''; p.type = "password"; } }, enterSubmit: function(e) { if(e.keyCode == 13 || e.keyCode == 10) config.macros.login.doLogin(e); }, doLogin: function(e) { clearMessage(); displayMessage('Logging in...'); var u = document.getElementById("zw_username"); var p = document.getElementById("zw_password"); zw.loggingIn = true; ajax.post(zw.serverUrl.replace("http://","http://"+u.value+":"+p.value+"@") ,zw.addTiddler, "action=get&title=ZiddlyStatus&__ac_name="+u.value+"&__ac_password="+p.value); }, doLogout: function(e) { clearMessage(); displayMessage('Logging out...'); zw.loggingIn=false; // FIXME this will fail if " " is a valid username ajax.post(zw.serverUrl.replace("http://","http:// :@") ,zw.addTiddler, "action=get&title=ZiddlyStatus&__ac_name=&__ac_password="); }, statusChange: function() { var oldreadOnly = readOnly; config.options.chkHttpReadOnly = (zw.loggedIn || zw.anonEdit || location.protocol == "file:") ? false:true; readOnly = !zw.loggedIn; // Check for new tiddlers var numtofetch = 0; var missingtiddlers = ""; for(var t in zw.tiddlerList) { if(!store.fetchTiddler(t.htmlDecode())) { numtofetch++; missingtiddlers += "\n" + t; } } var fetched = 0; this.fetchlist = []; if(zw.tiddlerList.length == 0) { clearMessage(); } else for(var t in zw.tiddlerList) { if(!store.fetchTiddler(t.htmlDecode())) { var callback = zw.addTiddler; this.fetchlist.push(t); if(++fetched == numtofetch) callback = config.macros.login.addLastTiddler; ajax.get('?action=get&title=' + encodeURIComponent(t.htmlDecode()) + "&" + zw.no_cache(), callback) } } if(oldreadOnly != readOnly || numtofetch == 0) { refreshDisplay(["ViewTemplate", "EditTemplate"]); story.refreshAllTiddlers(); refreshAll(); } }, doneLoginout: function() { var evalme = store.fetchTiddler("ZiddlyStatus").text; window.eval(evalme); readOnly = !zw.loggedIn; store.notify(["ZiddlyStatus"], true); if(!zw.loggedIn && zw.loggingIn) { // still not logged in. clearMessage(); displayMessage("Authentication failed. Did you type your username and password correctly?"); } if(!zw.loggingIn || (zw.loggedIn && zw.loggingIn)) clearMessage(); return true; }, addLastTiddler: function(str,status) { zw.addTiddler(str,status); refreshAll(); // Just redraw everything. } }; // This causes our doneLogin method above to be called on startup. store.addNotification("ZiddlyStatus", config.macros.login.statusChange); // Dynamically load a tiddler zw.loadTiddler = function(t) { var str = ajax.gets('?action=get&title=' + encodeURIComponent(t.htmlDecode()) + "&" + zw.no_cache()); return zw.addTiddler(str, 200); } zw.addTiddler = function(str,status) { var tiddler = new Tiddler(); var d = document.createElement("div"); if(!str.match(config.macros.login.innerHTMLSafe)) { if(!confirm("This tiddler appears to contain HTML and may be dangerous\n\n"+str)) return tiddler; } d.innerHTML = str; // FIXME dangerous -- response could contain