blob: 639cec88c1b74880c5ca16e20a0ff2aec28ddbcf [file] [log] [blame]
/**
* PSServer PSServer.js file.
* This plugin is a server based persistent storage backend.
*/
(function() {
var PSServer = window.PSServer = function PSServer(editor) {
this.editor = editor;
}
PSServer._pluginInfo = {
name : "PSServer",
version : "2.0",
developer : "Douglas Mayle",
developer_url : "http://xinha.org",
license : "MIT"
};
PSServer.prototype.onGenerateOnce = function () {
// We use _loadConfig to asynchronously load the config and then register the
// backend.
this._loadConfig();
};
PSServer.prototype._loadConfig = function() {
var self = this;
if (!this._serverConfig) {
Xinha._getback(Xinha.getPluginDir("PSServer") + "/config.inc.php",
function(config) {
self._serverConfig = eval('(' + config + ')');
self._serverConfig.user_affinity = 20;
self._serverConfig.displayName = 'Server';
self._loadConfig();
});
return;
}
this._registerBackend();
}
PSServer.prototype._registerBackend = function(timeWaited) {
var editor = this.editor;
var self = this;
if (!timeWaited) {
timeWaited = 0;
}
// Retry over a period of ten seconds to register. We back off exponentially
// to limit resouce usage in the case of misconfiguration.
var registerTimeout = 10000;
if (timeWaited > registerTimeout) {
// This is most likely a configuration error. We're loaded and
// PersistentStorage is not.
return;
}
if (!editor.plugins['PersistentStorage'] ||
!editor.plugins['PersistentStorage'].instance ||
!editor.plugins['PersistentStorage'].instance.ready) {
window.setTimeout(function() {self._registerBackend(timeWaited ? timeWaited*2 : 50);}, timeWaited ? timeWaited : 50);
return;
}
editor.plugins['PersistentStorage'].instance.registerBackend('PSServer', this, this._serverConfig);
}
PSServer.prototype.loadData = function (asyncCallback) {
var self = this;
Xinha._getback(Xinha.getPluginDir("PSServer") + "/backend.php?directory&listing",
function(json) {
self.dirTree = eval('(' + json + ')');
asyncCallback(self.dirTree);
});
}
var treeRecurse = function treeRecurse(tree, callback, root) {
if (typeof root == 'undefined') {
root = '/';
callback('/', '', tree);
}
for (var key in tree) {
callback(root, key, tree[key]);
if (tree[key].$type == 'folder') {
treeRecurse(tree[key], callback, root + key + '/');
}
}
};
PSServer.prototype.getFilters = function(dirTree) {
// Clear out the previous directory listing.
var filters = [];
treeRecurse(dirTree, function(path, key, value) {
if (value.$type != 'folder') {
return;
}
var filePath = key.length ? path + key + '/' : path;
var filePathDisplay = key.length ? path + key + '/' : path;
if (filePathDisplay.length > 1) {
filePathDisplay = filePathDisplay.substring(0, filePathDisplay.length-1);
}
filters.push({
value: filePath,
display: filePathDisplay
});
});
return filters;
}
PSServer.prototype.loadDocument = function(entry, asyncCallback) {
Xinha._getback(entry.URL,
function(documentSource) {
asyncCallback(documentSource);
});
}
PSServer.prototype.getMetadata = function(dirTree, pathFilter, typeFilter) {
var editor = this.editor;
var self = this;
var metadata = [];
var typeKeys = {};
for (var index=0; index<typeFilter.length; ++index) {
typeKeys[typeFilter[index]] = true;
}
treeRecurse(dirTree, function(path, key, value) {
if (!value.$type || !key) {
// This is a builtin property of objects, not one returned by the
// backend.
return;
}
if (path != pathFilter) {
return;
}
if (!(value.$type in typeKeys)) {
return;
}
if ((value.$type == 'folder') || (value.$type == 'html') ||
(value.$type == 'text') || (value.$type == 'document')) {
metadata.push({
name: key,
key: path + key,
$type: value.$type
});
} else {
metadata.push({
URL: Xinha.getPluginDir("PSServer") + '/demo_images' + path + key,
name: key,
key: path + key,
$type: value.$type
});
}
});
return metadata;
}
PSServer.prototype.loadDocument = function(entry, asyncCallback) {
var self = this;
Xinha._getback(Xinha.getPluginDir("PSServer") + '/demo_images' + entry.key,
function(documentSource) {
asyncCallback(documentSource);
});
}
PSServer.prototype.buildImportUI = function(dialog, element) {
// We receive an HTML element and are expected to build an HTML UI. We'll
// model it off of this HTML fragment:
// <form target="importFrame" action="../plugins/PSServer/backend.php?upload&amp;replace=false&amp;" id="importForm" method="post" enctype="multipart/form-data">
// File: <input type="file" name="filedata" /><input type="submit" value="_(Import)" />
// </form>
// <iframe id="importFrame" name="importFrame" src="#" style="display:none;"></iframe>
var iframeID = dialog.createId('importFrame');
var form = document.createElement('form');
form.setAttribute('enctype', 'multipart/form-data');
form.setAttribute('method', 'post');
form.setAttribute('action', Xinha.getPluginDir("PSServer") + "/backend.php?upload&replace=true&");
var fileentry = document.createElement('input');
fileentry.setAttribute('type', 'file');
fileentry.setAttribute('name', 'filedata');
var submitbutton = document.createElement('input');
submitbutton.setAttribute('type', 'submit');
submitbutton.setAttribute('value',Xinha._lc('Import', 'PSServer'));
var filetext = document.createTextNode(Xinha._lc('File: ', 'PSServer'));
filetext = form.appendChild(filetext);
fileentry = form.appendChild(fileentry);
submitbutton = form.appendChild(submitbutton);
form = element.appendChild(form);
form.setAttribute('target', iframeID);
// The iframe must be added to the document after the form has been, or the targeting fails.
var iframe = document.createElement('iframe');
iframe.setAttribute('src', 'about:blank');
iframe.style.display = 'none';
iframe.id = iframe.name = iframeID;
iframe.onload = function() {
var docCheck = iframe.contentDocument || iframe.contentWindow;
if (docCheck.location.href == 'about:blank') {
return;
}
// What to do on import? Add an entry to the UI, I guess...
alert('Add entry here');
}
iframe = element.appendChild(iframe);
}
PSServer.prototype.saveDocument = function(path, filename, documentSource, asyncCallback) {
Xinha._postback(Xinha.getPluginDir("PSServer") + "/backend.php?upload&replace=true&filedata=" + escape(documentSource)+"&filename="+escape(path + filename),
null,
function(response) {
asyncCallback(true);
},
function(response) {
asyncCallback(false);
});
}
PSServer.prototype.makeFolder = function(currentPath, folderName, asyncCallback) {
Xinha._postback(Xinha.getPluginDir("PSServer") + "/backend.php?directory&create&dirname="+escape(currentPath + '/' + folderName),
null,
function(response) {
asyncCallback(true);
},
function(response) {
asyncCallback(false);
});
}
PSServer.prototype.deleteEntry = function(entry, asyncCallback) {
Xinha._postback(Xinha.getPluginDir("PSServer") + "/backend.php?file&delete&filename="+escape(entry.key),
null,
function(response) {
asyncCallback(true);
},
function(response) {
asyncCallback(false);
});
}
PSServer.prototype.moveEntry = function(entry, container, asyncCallback) {
Xinha._postback(Xinha.getPluginDir("PSServer") + "/backend.php?file&rename&filename="+escape(entry.key)+'&newname='+escape(container.key + '/' + entry.name),
null,
function(json) {
asyncCallback(true);
},
function(json) {
asyncCallback(false);
});
}
PSServer.prototype.copyEntry = function(entry, asyncCallback) {
Xinha._postback(Xinha.getPluginDir("PSServer") + "/backend.php?file&copy&filename="+escape(entry.key),
null,
function(json) {
var newentry = eval('(' + json + ')');
asyncCallback(true, newentry);
},
function(json) {
var newentry = eval('(' + json + ')');
asyncCallback(false, newentry);
});
}
})();