/** | |
* 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&replace=false&" 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©&filename="+escape(entry.key), | |
null, | |
function(json) { | |
var newentry = eval('(' + json + ')'); | |
asyncCallback(true, newentry); | |
}, | |
function(json) { | |
var newentry = eval('(' + json + ')'); | |
asyncCallback(false, newentry); | |
}); | |
} | |
})(); |