Commit d24fe545 authored by Caleb James DeLisle's avatar Caleb James DeLisle

Fixed phantomjs test failures and conformed to c89 all-vars-at-beginning-of-function codestyle.

parent 58115408
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
maxlen: 80, maxlen: 80,
sloppy: true, sloppy: true,
nomen: true, nomen: true,
vars: true,
plusplus: true plusplus: true
*/ */
/*global /*global
define: true,
jIO: true, jIO: true,
$: true, jQuery: true,
XMLHttpRequest: true, XMLHttpRequest: true,
Blob: true, Blob: true,
FormData: true, FormData: true,
...@@ -17,678 +17,716 @@ ...@@ -17,678 +17,716 @@
* JIO XWiki Storage. Type = 'xwiki'. * JIO XWiki Storage. Type = 'xwiki'.
* XWiki Document/Attachment storage. * XWiki Document/Attachment storage.
*/ */
jIO.addStorageType('xwiki', function (spec, my) { (function () {
var $, store;
spec = spec || {}; store = function (spec, my) {
var that, priv, xwikistorage;
that = my.basicStorage(spec, my);
priv = {};
/**
* Get the Space and Page components of a documkent ID.
*
* @param id the document id.
* @return a map of { 'space':<Space>, 'page':<Page> }
*/
var getParts = function (id) {
if (id.indexOf('/') === -1) {
return {
space: 'Main',
page: id
};
}
return {
space: id.substring(0, id.indexOf('/')),
page: id.substring(id.indexOf('/') + 1)
};
};
/** spec = spec || {};
* Get the Anti-CSRF token and do something with it. var that, priv, xwikistorage;
*
* @param andThen function which is called with (formToken, err)
* as parameters.
*/
var doWithFormToken = function (andThen) {
$.ajax({
url: priv.formTokenPath,
type: "GET",
async: true,
dataType: 'text',
success: function (html) {
// this is unreliable
//var token = $('meta[name=form_token]', html).attr("content");
var m = html.match(/<meta name="form_token" content="(\w*)"\/>/);
var token = (m && m[1]) || null;
if (!token) {
andThen(null, {
"status": 404,
"statusText": "Not Found",
"error": "err_form_token_not_found",
"message": "Anti-CSRF form token was not found in page",
"reason": "XWiki main page did not contain expected " +
"Anti-CSRF form token"
});
} else {
andThen(token, null);
}
},
error: function (jqxhr, err, cause) {
andThen(null, {
"status": jqxhr.status,
"statusText": jqxhr.statusText,
"error": err,
"message": "Could not get Anti-CSRF form token from [" +
priv.xwikiurl + "]",
"reason": cause
});
},
});
};
/**
* Get the REST read URL for a document.
*
* @param docId the id of the document.
* @return the REST URL for accessing this document.
*/
var getDocRestURL = function (docId) {
var parts = getParts(docId);
return priv.xwikiurl + '/rest/wikis/'
+ priv.wiki + '/spaces/' + parts.space + '/pages/' + parts.page;
};
/** that = my.basicStorage(spec, my);
* Make an HTML5 Blob object. priv = {};
* Equivilant to the `new Blob()` constructor.
* Will fall back on deprecated BlobBuilder if necessary.
*/
var makeBlob = function (contentArray, options) {
var i, bb, BB;
try {
// use the constructor if possible.
return new Blob(contentArray, options);
} catch (err) {
// fall back on the blob builder.
BB = (window.MozBlobBuilder || window.WebKitBlobBuilder
|| window.BlobBuilder);
bb = new BB();
for (i = 0; i < contentArray.length; i++) {
bb.append(contentArray[i]);
}
return bb.getBlob(options ? options.type : undefined);
}
};
/*
* Wrapper for the xwikistorage based on localstorage JiO store.
*/
xwikistorage = {
/** /**
* Get content of an XWikiDocument. * Get the Space and Page components of a documkent ID.
* *
* @param docId the document ID. * @param id the document id.
* @param andThen a callback taking (doc, err), doc being the document * @return a map of { 'space':<Space>, 'page':<Page> }
* json object and err being the error if any.
*/ */
getItem: function (docId, andThen) { priv.getParts = function (id) {
if (id.indexOf('/') === -1) {
var success = function (jqxhr) { return {
var out = {}; space: 'Main',
try { page: id
var xd = $(jqxhr.responseText); };
xd.find('modified').each(function () { }
out._last_modified = Date.parse($(this).text()); return {
}); space: id.substring(0, id.indexOf('/')),
xd.find('created').each(function () { page: id.substring(id.indexOf('/') + 1)
out._creation_date = Date.parse($(this).text());
});
xd.find('title').each(function () { out.title = $(this).text(); });
xd.find('parent').each(function () { out.parent = $(this).text(); });
xd.find('syntax').each(function () { out.syntax = $(this).text(); });
xd.find('content').each(function () {
out.content = $(this).text();
});
out._id = docId;
andThen(out, null);
} catch (err) {
andThen(null, {
status: 500,
statusText: "internal error",
error: err,
message: err.message,
reason: ""
});
}
}; };
};
/**
* Get the Anti-CSRF token and do something with it.
*
* @param andThen function which is called with (formToken, err)
* as parameters.
*/
priv.doWithFormToken = function (andThen) {
$.ajax({ $.ajax({
url: getDocRestURL(docId), url: priv.formTokenPath,
type: "GET", type: "GET",
async: true, async: true,
dataType: 'xml', dataType: 'text',
success: function (html) {
// Use complete instead of success and error because phantomjs var m, token;
// sometimes causes error to be called with html return code 200. // this is unreliable
complete: function (jqxhr) { //var token = $('meta[name=form_token]', html).attr("content");
if (jqxhr.status === 404) { m = html.match(/<meta name="form_token" content="(\w*)"\/>/);
andThen(null, null); token = (m && m[1]) || null;
return; if (!token) {
}
if (jqxhr.status !== 200) {
andThen(null, { andThen(null, {
"status": jqxhr.status, "status": 404,
"statusText": jqxhr.statusText, "statusText": "Not Found",
"error": "", "error": "err_form_token_not_found",
"message": "Failed to get document [" + docId + "]", "message": "Anti-CSRF form token was not found in page",
"reason": "" "reason": "XWiki main page did not contain expected " +
"Anti-CSRF form token"
}); });
return; } else {
andThen(token, null);
} }
success(jqxhr); },
} error: function (jqxhr, err, cause) {
andThen(null, {
"status": jqxhr.status,
"statusText": jqxhr.statusText,
"error": err,
"message": "Could not get Anti-CSRF form token from [" +
priv.xwikiurl + "]",
"reason": cause
});
},
}); });
}, };
/** /**
* Get content of an XWikiAttachment. * Get the REST read URL for a document.
* *
* @param attachId the attachment ID. * @param docId the id of the document.
* @param andThen a callback taking (attach, err), attach being the * @return the REST URL for accessing this document.
* attachment blob and err being the error if any.
*/ */
getAttachment: function (docId, fileName, andThen) { priv.getDocRestURL = function (docId) {
// need to do this manually, jquery doesn't support returning blobs. var parts = priv.getParts(docId);
var xhr = new XMLHttpRequest(); return priv.xwikiurl + '/rest/wikis/'
var parts = getParts(docId); + priv.wiki + '/spaces/' + parts.space + '/pages/' + parts.page;
var url = priv.xwikiurl + '/bin/download/' + parts.space + };
"/" + parts.page + "/" + fileName;
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function (e) {
if (xhr.status === 200) {
var contentType = xhr.getResponseHeader("Content-Type");
if (contentType.indexOf(';') > -1) {
contentType = contentType.substring(0, contentType.indexOf(';'));
}
if (priv.useBlobs) {
andThen(makeBlob([xhr.response], {type: contentType}));
} else {
andThen(xhr.response);
}
} else {
andThen(null, {
"status": xhr.status,
"statusText": xhr.statusText,
"error": "err_network_error",
"message": "Failed to get attachment ["
+ docId + "/" + fileName + "]",
"reason": "Error getting data from network"
});
}
};
xhr.send();
},
/** /**
* Store an XWikiDocument. * Make an HTML5 Blob object.
* * Equivilant to the `new Blob()` constructor.
* @param id the document identifier. * Will fall back on deprecated BlobBuilder if necessary.
* @param doc the document JSON object containing
* "parent", "title", "content", and/or "syntax" keys.
* @param andThen a callback taking (err), err being the error if any.
*/ */
setItem: function (id, doc, andThen) { priv.makeBlob = function (contentArray, options) {
doWithFormToken(function (formToken, err) { var i, bb, BB;
if (err) { try {
that.error(err); // use the constructor if possible.
return; return new Blob(contentArray, options);
} catch (err) {
// fall back on the blob builder.
BB = (window.MozBlobBuilder || window.WebKitBlobBuilder
|| window.BlobBuilder);
bb = new BB();
for (i = 0; i < contentArray.length; i++) {
bb.append(contentArray[i]);
} }
var parts = getParts(id); return bb.getBlob(options ? options.type : undefined);
}
};
priv.isBlob = function (potentialBlob) {
return typeof (potentialBlob) !== 'undefined' &&
potentialBlob.toString() === "[object Blob]";
};
/*
* Wrapper for the xwikistorage based on localstorage JiO store.
*/
xwikistorage = {
/**
* Get content of an XWikiDocument.
*
* @param docId the document ID.
* @param andThen a callback taking (doc, err), doc being the document
* json object and err being the error if any.
*/
getItem: function (docId, andThen) {
var success = function (jqxhr) {
var out, xd;
out = {};
try {
xd = $(jqxhr.responseText);
xd.find('modified').each(function () {
out._last_modified = Date.parse($(this).text());
});
xd.find('created').each(function () {
out._creation_date = Date.parse($(this).text());
});
xd.find('title').each(function () { out.title = $(this).text(); });
xd.find('parent').each(function () {
out.parent = $(this).text();
});
xd.find('syntax').each(function () {
out.syntax = $(this).text();
});
xd.find('content').each(function () {
out.content = $(this).text();
});
out._id = docId;
andThen(out, null);
} catch (err) {
andThen(null, {
status: 500,
statusText: "internal error",
error: err,
message: err.message,
reason: ""
});
}
};
$.ajax({ $.ajax({
url: priv.xwikiurl + "/bin/preview/" + parts.space + '/' + parts.page, url: priv.getDocRestURL(docId),
type: "POST", type: "GET",
async: true, async: true,
dataType: 'text', dataType: 'xml',
data: {
parent: doc.parent || '', // Use complete instead of success and error because phantomjs
title: doc.title || '', // sometimes causes error to be called with html return code 200.
xredirect: '', complete: function (jqxhr) {
language: 'en', if (jqxhr.status === 404) {
// RequiresHTMLConversion: 'content', andThen(null, null);
// content_syntax: doc.syntax || 'xwiki/2.1', return;
content: doc.content || '', }
xeditaction: 'edit', if (jqxhr.status !== 200) {
comment: 'Saved by JiO', andThen(null, {
action_saveandcontinue: 'Save & Continue', "status": jqxhr.status,
syntaxId: doc.syntax || 'xwiki/2.1', "statusText": jqxhr.statusText,
xhidden: 0, "error": "",
minorEdit: 0, "message": "Failed to get document [" + docId + "]",
ajax: true, "reason": ""
form_token: formToken });
}, return;
success: function () { }
andThen(null); success(jqxhr);
},
error: function (jqxhr, err, cause) {
andThen({
"status": jqxhr.status,
"statusText": jqxhr.statusText,
"error": err,
"message": "Failed to store document [" + id + "]",
"reason": cause
});
} }
}); });
}); },
},
/** /**
* Store an XWikiAttachment. * Get content of an XWikiAttachment.
* *
* @param docId the ID of the document to attach to. * @param attachId the attachment ID.
* @param fileName the attachment file name. * @param andThen a callback taking (attach, err), attach being the
* @param mimeType the MIME type of the attachment content. * attachment blob and err being the error if any.
* @param content the attachment content. */
* @param andThen a callback taking one parameter which is the error if any. getAttachment: function (docId, fileName, andThen) {
*/ var xhr, parts, url;
setAttachment: function (docId, fileName, mimeType, content, andThen) { // need to do this manually, jquery doesn't support returning blobs.
doWithFormToken(function (formToken, err) { xhr = new XMLHttpRequest();
if (err) { parts = priv.getParts(docId);
that.error(err); url = priv.xwikiurl + '/bin/download/' + parts.space +
return; "/" + parts.page + "/" + fileName + '?cb=' + Math.random();
xhr.open('GET', url, true);
if (priv.useBlobs) {
xhr.responseType = 'blob';
} else {
xhr.responseType = 'text';
} }
var parts = getParts(docId);
var blob = (content.constructor === "function Blob() { [native code] }")
? content : makeBlob([content], {type: mimeType});
var fd = new FormData();
fd.append("filepath", blob, fileName);
fd.append("form_token", formToken);
var xhr = new XMLHttpRequest();
xhr.open('POST', priv.xwikiurl + "/bin/upload/" +
parts.space + '/' + parts.page, true);
xhr.onload = function (e) { xhr.onload = function (e) {
if (xhr.status === 302 || xhr.status === 200) { if (xhr.status === 200) {
andThen(null); var contentType = xhr.getResponseHeader("Content-Type");
if (contentType.indexOf(';') > -1) {
contentType = contentType.substring(0, contentType.indexOf(';'));
}
andThen(xhr.response);
} else { } else {
andThen({ andThen(null, {
"status": xhr.status, "status": xhr.status,
"statusText": xhr.statusText, "statusText": xhr.statusText,
"error": "err_network_error", "error": "err_network_error",
"message": "Failed to store attachment [" "message": "Failed to get attachment ["
+ docId + "/" + fileName + "]", + docId + "/" + fileName + "]",
"reason": "Error posting data" "reason": "Error getting data from network"
}); });
} }
}; };
xhr.send(fd);
});
},
removeItem: function (id, andThen) { xhr.send();
doWithFormToken(function (formToken, err) { },
if (err) {
that.error(err); /**
return; * Store an XWikiDocument.
} *
var parts = getParts(id); * @param id the document identifier.
$.ajax({ * @param doc the document JSON object containing
url: priv.xwikiurl + "/bin/delete/" + parts.space + '/' + parts.page, * "parent", "title", "content", and/or "syntax" keys.
type: "POST", * @param andThen a callback taking (err), err being the error if any.
async: true, */
dataType: 'text', setItem: function (id, doc, andThen) {
data: { priv.doWithFormToken(function (formToken, err) {
confirm: '1', if (err) {
form_token: formToken that.error(err);
}, return;
success: function () { }
andThen(null); var parts = priv.getParts(id);
}, $.ajax({
error: function (jqxhr, err, cause) { url: priv.xwikiurl + "/bin/preview/" +
andThen({ parts.space + '/' + parts.page,
"status": jqxhr.status, type: "POST",
"statusText": jqxhr.statusText, async: true,
"error": err, dataType: 'text',
"message": "Failed to delete document [" + id + "]", data: {
"reason": cause parent: doc.parent || '',
}); title: doc.title || '',
xredirect: '',
language: 'en',
// RequiresHTMLConversion: 'content',
// content_syntax: doc.syntax || 'xwiki/2.1',
content: doc.content || '',
xeditaction: 'edit',
comment: 'Saved by JiO',
action_saveandcontinue: 'Save & Continue',
syntaxId: doc.syntax || 'xwiki/2.1',
xhidden: 0,
minorEdit: 0,
ajax: true,
form_token: formToken
},
success: function () {
andThen(null);
},
error: function (jqxhr, err, cause) {
andThen({
"status": jqxhr.status,
"statusText": jqxhr.statusText,
"error": err,
"message": "Failed to store document [" + id + "]",
"reason": cause
});
}
});
});
},
/**
* Store an XWikiAttachment.
*
* @param docId the ID of the document to attach to.
* @param fileName the attachment file name.
* @param mimeType the MIME type of the attachment content.
* @param content the attachment content.
* @param andThen a callback taking one parameter, the error if any.
*/
setAttachment: function (docId, fileName, mimeType, content, andThen) {
priv.doWithFormToken(function (formToken, err) {
var parts, blob, fd, xhr;
if (err) {
that.error(err);
return;
} }
parts = priv.getParts(docId);
blob = priv.isBlob(content)
? content
: priv.makeBlob([content], {type: mimeType});
fd = new FormData();
fd.append("filepath", blob, fileName);
fd.append("form_token", formToken);
xhr = new XMLHttpRequest();
xhr.open('POST', priv.xwikiurl + "/bin/upload/" +
parts.space + '/' + parts.page, true);
xhr.onload = function (e) {
if (xhr.status === 302 || xhr.status === 200) {
andThen(null);
} else {
andThen({
"status": xhr.status,
"statusText": xhr.statusText,
"error": "err_network_error",
"message": "Failed to store attachment ["
+ docId + "/" + fileName + "]",
"reason": "Error posting data"
});
}
};
xhr.send(fd);
}); });
}); },
},
removeAttachment: function (docId, fileName, andThen) { removeItem: function (id, andThen) {
var parts = getParts(docId); priv.doWithFormToken(function (formToken, err) {
doWithFormToken(function (formToken, err) { if (err) {
if (err) { that.error(err);
that.error(err); return;
return;
}
$.ajax({
url: priv.xwikiurl + "/bin/delattachment/" + parts.space + '/' +
parts.page + '/' + fileName,
type: "POST",
async: true,
dataType: 'text',
data: {
ajax: '1',
form_token: formToken
},
success: function () {
andThen(null);
},
error: function (jqxhr, err, cause) {
andThen({
"status": jqxhr.status,
"statusText": jqxhr.statusText,
"error": err,
"message": "Failed to delete attachment ["
+ docId + '/' + fileName + "]",
"reason": cause
});
} }
var parts = priv.getParts(id);
$.ajax({
url: priv.xwikiurl + "/bin/delete/" +
parts.space + '/' + parts.page,
type: "POST",
async: true,
dataType: 'text',
data: {
confirm: '1',
form_token: formToken
},
success: function () {
andThen(null);
},
error: function (jqxhr, err, cause) {
andThen({
"status": jqxhr.status,
"statusText": jqxhr.statusText,
"error": err,
"message": "Failed to delete document [" + id + "]",
"reason": cause
});
}
});
}); });
}); },
}
};
// ==================== Tools ==================== removeAttachment: function (docId, fileName, andThen) {
/** var parts = priv.getParts(docId);
* Update [doc] the document object and remove [doc] keys priv.doWithFormToken(function (formToken, err) {
* which are not in [new_doc]. It only changes [doc] keys not starting if (err) {
* with an underscore. that.error(err);
* ex: doc: {key:value1,_key:value2} with return;
* new_doc: {key:value3,_key:value4} updates }
* doc: {key:value3,_key:value2}. $.ajax({
* @param {object} doc The original document object. url: priv.xwikiurl + "/bin/delattachment/" + parts.space + '/' +
* @param {object} new_doc The new document object parts.page + '/' + fileName,
*/ type: "POST",
priv.documentObjectUpdate = function (doc, new_doc) { async: true,
var k; dataType: 'text',
for (k in doc) { data: {
if (doc.hasOwnProperty(k)) { ajax: '1',
if (k[0] !== '_') { form_token: formToken
delete doc[k]; },
success: function () {
andThen(null);
},
error: function (jqxhr, err, cause) {
andThen({
"status": jqxhr.status,
"statusText": jqxhr.statusText,
"error": err,
"message": "Failed to delete attachment ["
+ docId + '/' + fileName + "]",
"reason": cause
});
}
});
});
}
};
// ==================== Tools ====================
/**
* Update [doc] the document object and remove [doc] keys
* which are not in [new_doc]. It only changes [doc] keys not starting
* with an underscore.
* ex: doc: {key:value1,_key:value2} with
* new_doc: {key:value3,_key:value4} updates
* doc: {key:value3,_key:value2}.
* @param {object} doc The original document object.
* @param {object} new_doc The new document object
*/
priv.documentObjectUpdate = function (doc, new_doc) {
var k;
for (k in doc) {
if (doc.hasOwnProperty(k)) {
if (k[0] !== '_') {
delete doc[k];
}
} }
} }
} for (k in new_doc) {
for (k in new_doc) { if (new_doc.hasOwnProperty(k)) {
if (new_doc.hasOwnProperty(k)) { if (k[0] !== '_') {
if (k[0] !== '_') { doc[k] = new_doc[k];
doc[k] = new_doc[k]; }
} }
} }
} };
};
/** /**
* Checks if an object has no enumerable keys * Checks if an object has no enumerable keys
* @method objectIsEmpty * @method objectIsEmpty
* @param {object} obj The object * @param {object} obj The object
* @return {boolean} true if empty, else false * @return {boolean} true if empty, else false
*/ */
priv.objectIsEmpty = function (obj) { priv.objectIsEmpty = function (obj) {
var k; var k;
for (k in obj) { for (k in obj) {
if (obj.hasOwnProperty(k)) { if (obj.hasOwnProperty(k)) {
return false; return false;
}
} }
} return true;
return true; };
};
// ==================== attributes ==================== // ==================== attributes ====================
// the wiki to store stuff in // the wiki to store stuff in
priv.wiki = spec.wiki || 'xwiki'; priv.wiki = spec.wiki || 'xwiki';
// unused // unused
priv.username = spec.username; priv.username = spec.username;
priv.language = spec.language; priv.language = spec.language;
// URL location of the wiki, unused since // URL location of the wiki, unused since
// XWiki doesn't currently allow cross-domain requests. // XWiki doesn't currently allow cross-domain requests.
priv.xwikiurl = spec.xwikiurl || priv.xwikiurl = spec.xwikiurl ||
window.location.href.replace(/\/xwiki\/bin\//, '/xwiki\n').split('\n')[0]; window.location.href.replace(/\/xwiki\/bin\//, '/xwiki\n')
// should be: s@/xwiki/bin/.*$@/xwiki@ .split('\n')[0];
// but jslint gets in the way. // should be: s@/xwiki/bin/.*$@/xwiki@
// but jslint gets in the way.
// Which URL to load for getting the Anti-CSRF form token, used for testing. // Which URL to load for getting the Anti-CSRF form token, used for testing.
priv.formTokenPath = spec.formTokenPath || priv.xwikiurl; priv.formTokenPath = spec.formTokenPath || priv.xwikiurl;
// If true then Blob objects will be returned by // If true then Blob objects will be returned by
// getAttachment() rather than strings. // getAttachment() rather than strings.
priv.useBlobs = spec.useBlobs || false; priv.useBlobs = spec.useBlobs || false;
that.specToStore = function () { that.specToStore = function () {
return { return {
"username": priv.username, "username": priv.username,
"language": priv.language, "language": priv.language,
"xwikiurl": priv.xwikiurl, "xwikiurl": priv.xwikiurl,
};
}; };
};
// can't fo wrong since no parameters are required. // can't fo wrong since no parameters are required.
that.validateState = function () { that.validateState = function () {
return ''; return '';
}; };
// ==================== commands ==================== // ==================== commands ====================
/** /**
* Create a document in local storage. * Create a document in local storage.
* @method post * @method post
* @param {object} command The JIO command * @param {object} command The JIO command
*/ */
that.post = function (command) { that.post = function (command) {
var docId = command.getDocId(); var docId = command.getDocId();
if (!(typeof docId === "string" && docId !== "")) { if (!(typeof docId === "string" && docId !== "")) {
setTimeout(function () { setTimeout(function () {
that.error({ that.error({
"status": 405, "status": 405,
"statusText": "Method Not Allowed", "statusText": "Method Not Allowed",
"error": "method_not_allowed", "error": "method_not_allowed",
"message": "Cannot create document which id is undefined", "message": "Cannot create document which id is undefined",
"reason": "Document id is undefined" "reason": "Document id is undefined"
});
});
return;
}
xwikistorage.getItem(docId, function (doc, err) {
if (err) {
that.error(err);
} else if (doc === null) {
// the document does not exist
xwikistorage.setItem(command.getDocId(),
command.cloneDoc(),
function (err) {
if (err) {
that.error(err);
} else {
that.success({
"ok": true,
"id": command.getDocId()
});
}
}); });
} else {
// the document already exists
that.error({
"status": 409,
"statusText": "Conflicts",
"error": "conflicts",
"message": "Cannot create a new document",
"reason": "Document already exists (use 'put' to modify it)"
}); });
return;
} }
}); xwikistorage.getItem(docId, function (doc, err) {
};
/**
* Create or update a document in local storage.
* @method put
* @param {object} command The JIO command
*/
that.put = function (command) {
xwikistorage.getItem(command.getDocId(), function (doc, err) {
if (err) {
that.error(err);
} else if (doc === null) {
doc = command.cloneDoc();
} else {
priv.documentObjectUpdate(doc, command.cloneDoc());
}
// write
xwikistorage.setItem(command.getDocId(), doc, function (err) {
if (err) { if (err) {
that.error(err); that.error(err);
} else if (doc === null) {
// the document does not exist
xwikistorage.setItem(command.getDocId(),
command.cloneDoc(),
function (err) {
if (err) {
that.error(err);
} else {
that.success({
"ok": true,
"id": command.getDocId()
});
}
});
} else { } else {
that.success({ // the document already exists
"ok": true, that.error({
"id": command.getDocId() "status": 409,
"statusText": "Conflicts",
"error": "conflicts",
"message": "Cannot create a new document",
"reason": "Document already exists (use 'put' to modify it)"
}); });
} }
}); });
}); };
};
/** /**
* Add an attachment to a document * Create or update a document in local storage.
* @method putAttachment * @method put
* @param {object} command The JIO command * @param {object} command The JIO command
*/ */
that.putAttachment = function (command) { that.put = function (command) {
xwikistorage.getItem(command.getDocId(), function (doc, err) { xwikistorage.getItem(command.getDocId(), function (doc, err) {
if (err) { if (err) {
that.error(err); that.error(err);
} else if (doc === null) { } else if (doc === null) {
// the document does not exist doc = command.cloneDoc();
that.error({ } else {
"status": 404, priv.documentObjectUpdate(doc, command.cloneDoc());
"statusText": "Not Found", }
"error": "not_found", // write
"message": "Impossible to add attachment", xwikistorage.setItem(command.getDocId(), doc, function (err) {
"reason": "Document not found" if (err) {
that.error(err);
} else {
that.success({
"ok": true,
"id": command.getDocId()
});
}
}); });
} else { });
// Document exists, upload attachment. };
xwikistorage.setAttachment(command.getDocId(),
/**
* Add an attachment to a document
* @method putAttachment
* @param {object} command The JIO command
*/
that.putAttachment = function (command) {
xwikistorage.getItem(command.getDocId(), function (doc, err) {
if (err) {
that.error(err);
} else if (doc === null) {
// the document does not exist
that.error({
"status": 404,
"statusText": "Not Found",
"error": "not_found",
"message": "Impossible to add attachment",
"reason": "Document not found"
});
} else {
// Document exists, upload attachment.
xwikistorage.setAttachment(command.getDocId(),
command.getAttachmentId(),
command.getAttachmentMimeType(),
command.getAttachmentData(),
function (err) {
if (err) {
that.error(err);
} else {
that.success({
"ok": true,
"id": command.getDocId() + "/" + command.getAttachmentId()
});
}
});
}
});
};
/**
* Get a document or attachment
* @method get
* @param {object} command The JIO command
*/
that.get = that.getAttachment = function (command) {
if (typeof command.getAttachmentId() === "string") {
// seeking for an attachment
xwikistorage.getAttachment(command.getDocId(),
command.getAttachmentId(), command.getAttachmentId(),
command.getAttachmentMimeType(), function (attach, err) {
command.getAttachmentData(),
function (err) {
if (err) { if (err) {
that.error(err); that.error(err);
} else if (attach !== null) {
that.success(attach);
} else { } else {
that.success({ that.error({
"ok": true, "status": 404,
"id": command.getDocId() + "/" + command.getAttachmentId() "statusText": "Not Found",
"error": "not_found",
"message": "Cannot find the attachment",
"reason": "Attachment does not exist"
}); });
} }
}); });
} } else {
}); // seeking for a document
}; xwikistorage.getItem(command.getDocId(), function (doc, err) {
/**
* Get a document or attachment
* @method get
* @param {object} command The JIO command
*/
that.get = that.getAttachment = function (command) {
if (typeof command.getAttachmentId() === "string") {
// seeking for an attachment
xwikistorage.getAttachment(command.getDocId(),
command.getAttachmentId(),
function (attach, err) {
if (err) { if (err) {
that.error(err); that.error(err);
} else if (attach !== null) { } else if (doc !== null) {
that.success(attach); that.success(doc);
} else { } else {
that.error({ that.error({
"status": 404, "status": 404,
"statusText": "Not Found", "statusText": "Not Found",
"error": "not_found", "error": "not_found",
"message": "Cannot find the attachment", "message": "Cannot find the document",
"reason": "Attachment does not exist" "reason": "Document does not exist"
}); });
} }
}); });
} else { }
// seeking for a document };
xwikistorage.getItem(command.getDocId(), function (doc, err) {
/**
* Remove a document or attachment
* @method remove
* @param {object} command The JIO command
*/
that.remove = that.removeAttachment = function (command) {
var notFoundError, objId, complete;
notFoundError = function (word) {
that.error({
"status": 404,
"statusText": "Not Found",
"error": "not_found",
"message": word + " not found",
"reason": "missing"
});
};
objId = command.getDocId();
complete = function (err) {
if (err) { if (err) {
that.error(err); that.error(err);
} else if (doc !== null) {
that.success(doc);
} else { } else {
that.error({ that.success({
"status": 404, "ok": true,
"statusText": "Not Found", "id": objId
"error": "not_found",
"message": "Cannot find the document",
"reason": "Document does not exist"
}); });
} }
}); };
} if (typeof command.getAttachmentId() === "string") {
}; objId += '/' + command.getAttachmentId();
xwikistorage.removeAttachment(command.getDocId(),
/** command.getAttachmentId(),
* Remove a document or attachment complete);
* @method remove } else {
* @param {object} command The JIO command xwikistorage.removeItem(objId, complete);
*/ }
that.remove = that.removeAttachment = function (command) {
var notFoundError = function (word) {
that.error({
"status": 404,
"statusText": "Not Found",
"error": "not_found",
"message": word + " not found",
"reason": "missing"
});
}; };
var objId = command.getDocId(); /**
var complete = function (err) { * Get all filenames belonging to a user from the document index
if (err) { * @method allDocs
that.error(err); * @param {object} command The JIO command
} else { */
that.success({ that.allDocs = function () {
"ok": true, setTimeout(function () {
"id": objId that.error({
"status": 405,
"statusText": "Method Not Allowed",
"error": "method_not_allowed",
"message": "Your are not allowed to use this command",
"reason": "xwikistorage forbids AllDocs command executions"
}); });
} });
}; };
if (typeof command.getAttachmentId() === "string") {
objId += '/' + command.getAttachmentId(); return that;
xwikistorage.removeAttachment(command.getDocId(),
command.getAttachmentId(),
complete);
} else {
xwikistorage.removeItem(objId, complete);
}
}; };
/** if (typeof (define) === 'function' && define.amd) {
* Get all filenames belonging to a user from the document index define(['jquery', 'jiobase', 'module'], function (jquery, j, mod) {
* @method allDocs $ = jquery;
* @param {object} command The JIO command jIO.addStorageType('xwiki', store);
*/
that.allDocs = function () { var conf = mod.config();
setTimeout(function () { conf.type = 'xwiki';
that.error({
"status": 405, return jIO.newJio(conf);
"statusText": "Method Not Allowed",
"error": "method_not_allowed",
"message": "Your are not allowed to use this command",
"reason": "xwikistorage forbids AllDocs command executions"
});
}); });
}; } else {
jIO.addStorageType('xwiki', store);
$ = jQuery;
}
return that; }());
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment