/* Copyright (c) 2006-2007, The Xooki project http://xooki.sourceforge.net/ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Some code is largely inspired by code found in the dojo toolkit, see http://dojotoolkit.org/ for more information. */ // this file is included only in edit mode xooki.url.include("tiddly/util.js"); if (typeof xooki.io == "undefined") { xooki.io = {}; } xooki.io.removeFile = function (filePath) { var r = null; if((r == null) || (r == false)) r = xooki.io.mozillaRemoveFile(filePath); if((r == null) || (r == false)) r = xooki.io.ieRemoveFile(filePath); return(r); } xooki.io.mozillaRemoveFile = function(filePath) { if(window.Components) 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()) return null; file.remove(false); return(true); } catch(e) { return(false); } return(null); } xooki.io.ieRemoveFile = function(filePath) { try { var fso = new ActiveXObject("Scripting.FileSystemObject"); } catch(e) { //alert("Exception while attempting to save\n\n" + e.toString()); return(null); } fso.DeleteFile(filePath, false); return(true); } // fix EOL characters in text to use native characters xooki.io.fixEOL = function(text) { var nativeEOL = navigator.platform.indexOf('Win') != -1 ? '\r\n' : '\n'; return text.replace(/\r?\n/g, nativeEOL); } if (typeof xooki.string == "undefined") { xooki.string = {}; } xooki.string.escapeString = function(str) { // borrowed from dojo //summary: // Adds escape sequences for non-visual characters, double quote and backslash // and surrounds with double quotes to form a valid string literal. return ('"' + str.replace(/(["\\])/g, '\\$1') + '"' ).replace(/[\f]/g, "\\f" ).replace(/[\b]/g, "\\b" ).replace(/[\n]/g, "\\n" ).replace(/[\t]/g, "\\t" ).replace(/[\r]/g, "\\r"); // string }; if (typeof xooki.json == "undefined") { xooki.json = {}; } xooki.json.serialize = function (o, indent) { // borrowed and adapted from dojo // summary: // Create a JSON serialization of the object. // return: // a String representing the serialized version of the passed object if (!indent) { indent = ""; } var objtype = typeof(o); if(objtype == "undefined"){ return "undefined"; }else if((objtype == "number")||(objtype == "boolean")){ return o + ""; }else if(o === null){ return "null"; } if (objtype == "string") { return xooki.string.escapeString(o); } if(objtype == "function"){ // do not encode functions return null; } // recurse var me = arguments.callee; // short-circuit for objects that support "json" serialization // if they return "self" then just pass-through... var newObj; // array if(objtype != "function" && typeof(o.length) == "number"){ var res = []; for(var i = 0; i < o.length; i++){ var val = me(o[i], indent+" "); if(typeof(val) != "string"){ val = "undefined"; } res.push(val); } return " [\n" + res.join(",\n") + "\n"+indent+"]\n"; } // generic object code path res = []; for (var k in o){ if ("meta" == k) { continue; } // let a chance to the object to define its transient keys, using a meta.isTransient function if (typeof o.meta != 'undefined' && typeof o.meta.isTransient == 'function' && o.meta.isTransient(k)) { continue; } var useKey; if (typeof(k) == "number"){ useKey = '"' + k + '"'; }else if (typeof(k) == "string"){ useKey = xooki.string.escapeString(k); }else{ // skip non-string or number keys continue; } val = o[k]; // let a chance to the object to define its serialized value if (typeof o.meta != 'undefined' && typeof o.meta.getSerializeValue == 'function') { val = o.meta.getSerializeValue(o, k); } val = me(val, indent+" "); if(typeof(val) != "string"){ // skip non-serializable values continue; } res.push(indent+" "+useKey + ":" + val); } return indent+"{\n" + res.join(",\n") + indent+"}"; }; xooki.component.toolbar = function () { return '
' + '' + '' + '' + '' + '' + '' + (xooki.c.debug?'':'') + '
'; }; xooki.component.editZone = function () { return ''; } xooki.url.reload = function() { window.location = window.location; } if (typeof xooki.action == "undefined") { xooki.action = {}; } xooki.action.quitEdit = function () { xooki.input.applyChanges(); xooki.html.hide('xooki-edit'); xooki.html.show('xooki-content'); } xooki.action.edit = function () { xooki.html.hide('xooki-content'); xooki.html.show('xooki-edit'); } xooki.action.toggleEdit = function () { if (document.getElementById('xooki-edit').style.display == 'none') { xooki.action.edit(); } else { xooki.action.quitEdit(); } } xooki.action.remove = function () { if (confirm(t("The current page will be removed from the table of content, and deleted on file system.\nNote that all children will be removed from the table of content too, but not from the file system!\nAre you sure you want to delete the current page?"))) { // the page to which we'll be redirected... var nextPage; var index = xooki.page.meta.index; var parent = xooki.page.meta.parent; if (index > 0) { // ... will be the previous sibling if there is one ... nextPage = parent.children[index - 1]; } else if (parent.children.length > 1) { // ... or the next sibling if there is one ... nextPage = parent.children[index + 1]; } else if (parent != xooki.toc) { // ... or the parent if the parent is not the toc root ... nextPage = parent; } else { // ... otherwise it s a problem xooki.error(t("Cannot delete the sole page!")); return; } parent.children.splice(index, 1); // remove node from toc xooki.toc.save(); xooki.io.removeFile(xooki.io.getLocalPath(window.location.toString())); window.location = pu(nextPage.id); } } xooki.action.discardChanges = function () { xooki.url.reload(); } xooki.action.previewChanges = function () { xooki.action.quitEdit(); } xooki.action.saveChanges = function () { var originalPath = document.location.toString(); var localPath = xooki.io.getLocalPath(originalPath); // Load the original file var original = xooki.io.loadFile(localPath); if(original == null) { xooki.error(t("Impossible to load original file: ${0}", localPath)); return; } var startSaveArea = ''); xooki.page.title = document.getElementById('xooki-input-title').value; xooki.toc.save(); var save; try { // Save new file var revised = original.substr(0,posOpeningArea + startSaveArea.length) + "\n" + xooki.input.source() + original.substr(posClosingArea); save = xooki.io.saveFile(localPath,xooki.io.fixEOL(revised)); } catch (e) { xooki.error(e); } if(save) { xooki.info(t("saved to ${0}",localPath)); // TODO: see if we are able to apply title change without reloading setTimeout(function() {xooki.url.reload();}, 800); } else xooki.error(t("Impossible to save changes to ${0}", localPath)); } xooki.action.movePageUp = function () { xooki.action.movePage(-1); } xooki.action.movePageDown = function () { xooki.action.movePage(1); } xooki.action.movePage = function (delta) { var index = xooki.page.meta.index; var parent = xooki.page.meta.parent; // check if node can move if (index + delta < 0) { xooki.info(t("Can't move first page up")); return; } if (index + delta >= parent.children.length) { xooki.info(t("Can't move last page down")); return; } // move node in toc parent.children.splice(index, 1); parent.children.splice(index+delta, 0, xooki.page); xooki.toc.save(); xooki.url.reload(); } xooki.action.createChild = function () { titleToId = function (title) { return title.replace(/\s+/g, ''); } var title = prompt("Child page title?", ""); var id = prompt("Child page path?", titleToId(title)); xooki.action.createChildPage({"id": id, "title": title, "children": []}); } xooki.action.createChildPage = function (child) { if (typeof child.meta == 'undefined' || typeof child.meta.level == 'undefined') { if (typeof child.meta == 'undefined') child.meta = {}; child.meta.level = child.id.split('/').length - 1; } var pagetpl = xooki.url.loadURL(cu("blankPageTpl")); if (pagetpl != null) { var childURL = pu(child.id); var localPath = xooki.io.getLocalPath(childURL); var original = xooki.io.loadFile(localPath); if (original != null) { if (!window.confirm(t("File for child page:\n${0}\nalready exists.\nAre you sure you want to continue and overwrite it?", localPath))) return; } xooki.page.children.push(child); xooki.toc.save(); // usually used by templates if (typeof child.relroot == 'undefined') { child.relroot = ""; for (var i=0; i < child.meta.level; i++) { child.relroot += "../"; } } child.level = child.meta.level; var revised = xooki.string.processTemplate(pagetpl, child); var save; try { // Save new file save = xooki.io.saveFile(localPath,xooki.io.fixEOL(revised)); } catch (e) { xooki.error(e); } if(save) { // go to child page window.location = childURL; } else xooki.error(t("Impossible to save changes to ${0}", localPath)); } } xooki.toc.save = function (revised) { if (!revised) { revised = xooki.json.serialize({children: this.actualRoot.children}); } var save; var tocPath = xooki.io.getLocalPath(this.url); try { save = xooki.io.saveFile(tocPath, xooki.io.fixEOL(revised)); } catch (e) { xooki.error(e); } if(!save) xooki.error(t("Impossible to save changes to ${0}", tocPath)); } if (typeof xooki.util == 'undefined') xooki.util = {} xooki.util.copy = function(o) { var copy = {}; for (var k in o) { copy[k] = o[k]; } return copy; }