Commit 3c5348b8 authored by Tristan Cavelier's avatar Tristan Cavelier Committed by Sebastien Robin

Add localStorage or Cookie support.

localStorage job list is a rescue job list now.
job list and LocalStorage are inserted to localStorage differently.
...
parent a1f3c2e9
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
<title>JIO</title> <title>JIO</title>
<script type="text/javascript" src="js/jquery/jquery.js"></script> <script type="text/javascript" src="js/jquery/jquery.js"></script>
<script type="text/javascript" src="unhosted/jio.js"></script> <script type="text/javascript" src="unhosted/jio.js"></script>
<script type="text/javascript" src="unhosted/jquery.storage.js"></script>
<script type="text/javascript" src="unhosted/base64.js"></script> <script type="text/javascript" src="unhosted/base64.js"></script>
<script type="text/javascript" src="unhosted/jio.storage.js"></script> <script type="text/javascript" src="unhosted/jio.storage.js"></script>
<!-- <script type="text/javascript" src="unhosted/sjcl.js"></script> --> <!-- <script type="text/javascript" src="unhosted/sjcl.js"></script> -->
...@@ -70,25 +72,30 @@ $.jio('subscribe',{'event':'start_gettingList', 'func': function ( o ) { ...@@ -70,25 +72,30 @@ $.jio('subscribe',{'event':'start_gettingList', 'func': function ( o ) {
}}); }});
$.jio('subscribe',{'event':'stop_gettingList', 'func': function ( o ) { $.jio('subscribe',{'event':'stop_gettingList', 'func': function ( o ) {
$('#divmessage').html($('#divmessage').html() + '<br />' + $('#divmessage').html($('#divmessage').html() + '<br />' +
'Getting list ended: ' + toString(o.job.list) ); 'Getting list ended: ' + toString(o) );
}}); }});
// $.jio({'storage':{'type':'local','userName':'tristan'}, $.jio({'storage':{'type':'local','userName':'tristan'},
// 'applicant':{'ID':'www.ungproject.org'}});
$.jio({'storage':{'type':'dav','userName':'tristan','password':'test',
'location':'https://ca-davstorage:8080','provider':'Unknown'},
'applicant':{'ID':'www.ungproject.org'}}); 'applicant':{'ID':'www.ungproject.org'}});
// $.jio({'storage':{'type':'dav','userName':'tristan','password':'test',
// 'location':'https://ca-davstorage:8080','provider':'Unknown'},
// 'applicant':{'ID':'www.ungproject.org'}});
// TODO
// doc string
// localStorage.status
// $.jio('isAvailable',{'userName':'toto'}); // $.jio('isAvailable',{'userName':'toto'});
// $.jio('isAvailable',{'userName':'tristan'}); // $.jio('isAvailable',{'userName':'tristan'});
// $.jio('save',{'fileName':'SonNom','fileContent':'SonContenu'}); // $.jio('saveDocument',{'fileName':'SonNom','fileContent':'SonContenu'});
// $.jio({'fileName':'SonNom','fileContent':'SonContenu','method':'save'}); // $.jio({'fileName':'SonNom','fileContent':'SonContenu','method':'saveDocument'});
// $.jio({'fileName':'SonNom2','fileContent':'SonContenu2','method':'save'}); // $.jio({'fileName':'SonNom2','fileContent':'SonContenu2','method':'saveDocument'});
// $.jio('load',{'fileName':'SonNom'}); // $.jio('loadDocument',{'fileName':'SonNom'});
$.jio('getList'); // $.jio('removeDocument',{'fileName':'SonNom'});
// $.jio('getDocumentList');
......
;(function ( $ ) { ;(function ( $ ) {
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// private vars // private vars
var attr = { var jioAttributeObject = {
'jobMethodObject': { 'jobMethodObject': {
'isAvailable': { 'isAvailable': {
'start_event':'start_checkingNameAvailability', 'start_event':'start_checkingNameAvailability',
'stop_event':'stop_checkingNameAvailability', 'stop_event':'stop_checkingNameAvailability',
'func':'checkNameAvailability', 'func':'checkNameAvailability',
'retvalue':'isAvailable' }, // returns 'boolean' 'retvalue':'isAvailable' }, // returns 'boolean'
'save': { 'saveDocument': {
'start_event':'start_saving', 'start_event':'start_saving',
'stop_event':'stop_saving', 'stop_event':'stop_saving',
'func':'saveDocument',
'retvalue':'isSaved' }, // returns 'boolean' 'retvalue':'isSaved' }, // returns 'boolean'
'load': { 'loadDocument': {
'start_event':'start_loading', 'start_event':'start_loading',
'stop_event':'stop_loading', 'stop_event':'stop_loading',
'func':'loadDocument',
'retvalue':'fileContent' }, // returns the file content 'string' 'retvalue':'fileContent' }, // returns the file content 'string'
'getList': { 'getDocumentList': {
'start_event':'start_gettingList', 'start_event':'start_gettingList',
'stop_event':'stop_gettingList', 'stop_event':'stop_gettingList',
'func':'getDocumentList',
'retvalue':'list' }, // returns the document list 'array' 'retvalue':'list' }, // returns the document list 'array'
'remove': { 'removeDocument': {
'start_event':'start_removing', 'start_event':'start_removing',
'stop_event':'stop_removing', 'stop_event':'stop_removing',
'func':'removeDocument',
'retvalue':'isRemoved' } // returns 'boolean' 'retvalue':'isRemoved' } // returns 'boolean'
}, },
'localStorage': null,
'tabid': 0,
'queue': null, // the job manager 'queue': null, // the job manager
'storage': null, // the storage given at init 'storage': null, // the storage given at init
'applicant': null, // the applicant given at init 'applicant': null, // the applicant given at init
...@@ -43,64 +42,89 @@ ...@@ -43,64 +42,89 @@
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Tools // cookies & localStorage
var objectDump = function (o) { var myLocalStorage = function () {
// TODO DEBUG we can remove this function
console.log (JSON.stringify(o));
}; };
var toString = function (o) { myLocalStorage.prototype = {
// TODO DEBUG we can remove this function getItem: function (name) {
return (JSON.stringify(o)); return JSON.parse(localStorage.getItem(name));
},
setItem: function (name,value) {
if (name)
return localStorage.setItem(name,JSON.stringify(value));
},
getAll: function() {
return localStorage;
},
deleteItem: function (name) {
if (name)
delete localStorage[name];
}
}; };
var supportLocalStorage = function () { var cookieStorage = function () {
// Modernizr function
try { return !!localStorage.getItem; }
catch (e) { return false; }
}; };
var ifRemainingJobs = function(method) { cookieStorage.prototype = {
// check if it remains [method] jobs (save,load,...) getItem: function (name) {
// method : can me 'string' or 'undefined' var cookies = document.cookie.split(';');
// undefined -> test if there is at least one job for (var i in cookies) {
// string -> test if there is at least one [method] job var x = cookies[i].substr(0, cookies[i].indexOf('='));
var y = cookies[i].substr(cookies[i].indexOf('=')+1);
if (!method) return (localStorage.joblist !== '[]'); x = x.replace(/^\s+|\s+$/g,"");
var joba = getJobArrayFromLocalStorage(); if( x == name ) return unescape(y);
for (var k in joba) { }
if (joba[k].method === method && return null;
joba[k].status !== 'fail') return true; },
setItem: function (name,value) {
// function to store into cookies
if (value != undefined) {
document.cookie = name+'='+JSON.stringify(value)+';domain='+
window.location.hostname+
';path='+window.location.pathname;
return true;
} }
return false; return false;
},
getAll: function() {
var retObject = {};
var cookies = document.cookie.split(':');
for (var i in cookies) {
var x = cookies[i].substr(0, cookies[i].indexOf('='));
var y = cookies[i].substr(cookies[i].indexOf('=')+1);
x = x.replace(/^\s+|\s+$/g,"");
retObject[x] = unescape(y);
}
return retObject;
},
deleteItem: function (name) {
document.cookie = name+'=null;domain='+window.location.hostname+
';path='+window.location.pathname+
';expires=Thu, 01-Jan-1970 00:00:01 GMT';
}
}; };
var getStatusObjectFromLocalStorage = function () { // set good localStorage
var tmp = {}; try {
if (localStorage.status) { if (localStorage.getItem) {
tmp = JSON.parse (localStorage.status); jioAttributeObject.localStorage = new myLocalStorage();
} else { // if it does not exists, create it } else {
for (var method in attr.jobMethodObject) { jioAttributeObject.localStorage = new cookieStorage();
tmp[method] = 'done';
} }
} }
return tmp; catch (e) {
}; jioAttributeObject.localStorage = new cookieStorage();
var setStatusObjectToLocalStorage = function (statusobject) { }
localStorage.status = JSON.stringify(statusobject); // end cookies & localStorages
}; ////////////////////////////////////////////////////////////////////////////
var getJobArrayFromLocalStorage = function () {
var localjoblist = []; ////////////////////////////////////////////////////////////////////////////
if (localStorage.joblist) // Tools
localjoblist = JSON.parse(localStorage.joblist);
return localjoblist;
};
var setJobArrayToLocalStorage = function (jobarray) {
localStorage.joblist = JSON.stringify(jobarray);
};
var createStorageObject = function ( options ) { var createStorageObject = function ( options ) {
// create a storage thanks to attr.storageTypeObject // create a storage thanks to jioAttributeObject.storageTypeObject
if (!attr.storageTypeObject[ options.storage.type]) if (!jioAttributeObject.storageTypeObject[ options.storage.type ])
return null; // error! return null; // error!
return attr.storageTypeObject[ options.storage.type ](options); return jioAttributeObject.storageTypeObject[
} options.storage.type ](options);
};
// end Tools // end Tools
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
...@@ -138,7 +162,7 @@ ...@@ -138,7 +162,7 @@
$.jiopubsub(eventname).unsubscribe(); $.jiopubsub(eventname).unsubscribe();
} }
}; };
attr.pubsub = new PubSub(); jioAttributeObject.pubsub = new PubSub();
// end Publisher Subcriber // end Publisher Subcriber
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
...@@ -154,34 +178,43 @@ ...@@ -154,34 +178,43 @@
}; };
var JobQueue = function () { var JobQueue = function () {
// restore job list from local storage, if it exists
this.jobObject = jioAttributeObject.localStorage.getItem(
'jio/jobObject/' + jioAttributeObject.tabid);
if (!this.jobObject) this.jobObject = {};
//// set first job ID //// set first job ID
console.log ('Queue'); console.log ('Queue');
this.jobid = 1; this.jobid = 1;
var localjoblist = getJobArrayFromLocalStorage(); for (var id in this.jobObject) {
if (localjoblist.length > 0) { if ( this.jobObject[id].id > this.jobid ) {
this.jobid = localjoblist[localjoblist.length - 1].id + 1; this.jobid = this.jobObject[id].id;
}; }
localjoblist = undefined; // it is not necessary to fill memory with }
this.jobid++;
// reset all jobs' status to initial // reset all jobs' status to initial
this.resetAll(); this.resetAll();
var t = this;
var returnedJobAnalyse = function ( job ) { var returnedJobAnalyse = function ( job ) {
// analyse the [o.job] // analyse the [job]
//// analysing job method // if the job method does not exists, return false
if (!attr.jobMethodObject[job.method]) if (!jioAttributeObject.jobMethodObject[job.method])
return false; return false;
if (!ifRemainingJobs(job.method)) { // if there isn't some job to do, then send stop event
var statusobject = getStatusObjectFromLocalStorage(); if (!t.isThereJobsWhere(function(testjob){
statusobject[job.method] = 'done'; return (testjob.method === job.method &&
setStatusObjectToLocalStorage(statusobject); testjob.status !== 'fail');
})) {
switch (job.method) { switch (job.method) {
// TODO merging is done with jio? or by the user's scripts? // TODO merging is done with jio? or by the user's scripts?
case 'isAvailable': case 'isAvailable':
// TODO merge name availability between storages // TODO merge name availability between storages
// TODO send job ? // TODO send job ?
$.jio('publish',{'event': attr.jobMethodObject[ $.jio('publish',{'event':
jioAttributeObject.jobMethodObject[
job.method].stop_event, 'job':job}); job.method].stop_event, 'job':job});
return; return;
case 'getList': case 'getList':
...@@ -189,58 +222,83 @@ ...@@ -189,58 +222,83 @@
// this.getList, deleted after sending the event, // this.getList, deleted after sending the event,
// filled with done event) -> merge here or show // filled with done event) -> merge here or show
// possible actions (manually, auto, ...) // possible actions (manually, auto, ...)
$.jio('publish',{'event': attr.jobMethodObject[ $.jio('publish',{'event':
jioAttributeObject.jobMethodObject[
job.method].stop_event , 'job':job}); job.method].stop_event , 'job':job});
///*, 'retvalue': merged list */}); ///*, 'retvalue': merged list */});
// delete list // delete list
return; return;
default: default:
$.jio('publish',{'event': attr.jobMethodObject[ $.jio('publish',{'event':
jioAttributeObject.jobMethodObject[
job.method].stop_event}); job.method].stop_event});
return; return;
} }
} }
//// end analyse }; // end returnedJobAnalyse
};
//// sebscribe an event //// sebscribe an event
var t = this; var t = this;
$.jio('subscribe',{'event':'job_done','func':function (o) { $.jio('subscribe',{'event':'job_done','func':function (o) {
setTimeout (function () {
if (methods.isReady()) { if (methods.isReady()) {
t.done(o.job); t.done(o.job);
returnedJobAnalyse (o.job); returnedJobAnalyse (o.job);
t.setJobObjectToLocalStorage();
} }
},50);
}}); }});
$.jio('subscribe',{'event':'job_fail','func':function (o) { $.jio('subscribe',{'event':'job_fail','func':function (o) {
setTimeout (function () {
if (methods.isReady()) { if (methods.isReady()) {
t.fail(o.job); t.fail(o.job);
returnedJobAnalyse (o.job); returnedJobAnalyse (o.job);
t.setJobObjectToLocalStorage();
} }
},50);
}}); }});
//// end subscribing //// end subscribing
}; };
JobQueue.prototype = { JobQueue.prototype = {
addJob: function ( o ) { isThereJobsWhere: function( func ) {
// check if there is jobs where [func](job) == true
if (!func)
return true;
for (var id in this.jobObject) {
if (func(this.jobObject[id]))
return true;
}
return false;
},
setJobObjectToLocalStorage: function () {
// set the jobs to the local storage
return jioAttributeObject.localStorage.setItem(
'jio/jobObject/' + jioAttributeObject.tabid,
this.jobObject);
},
addJob: function ( options ) {
// Add a job to the Job list // Add a job to the Job list
// o.storage : the storage object // options.storage : the storage object
// o.job : the job object (may be a 'string') // options.job : the job object (may be a 'string')
console.log ('addJob'); console.log ('addJob');
//// Adding job to the list in localStorage
// transforming job/storage to an object // transforming job/storage to an object
try { o.job = JSON.parse(o.job); } catch (e) {}; if (typeof options.job === 'string')
try { o.storage = JSON.parse(o.storage); } catch (e) {}; options.job = JSON.parse(options.job);
// create joblist in local storage if unset if (typeof options.storage === 'string')
if (!localStorage.joblist) localStorage.joblist = "[]"; options.storage=JSON.parse(options.storage);
// set job id // set job id
o.job.id = this.jobid; options.job.id = this.jobid;
this.jobid ++; this.jobid ++;
// save the new job // save the new job
var localjoblist = getJobArrayFromLocalStorage(); this.jobObject[this.jobid] = options.job;
localjoblist.push(o.job); // save into localStorage
setJobArrayToLocalStorage (localjoblist); this.setJobObjectToLocalStorage();
//// job added
}, // end addJob }, // end addJob
removeJob: function ( options ) { removeJob: function ( options ) {
...@@ -250,34 +308,30 @@ ...@@ -250,34 +308,30 @@
console.log ('removeJob'); console.log ('removeJob');
//// set tests functions //// set tests functions
var settings = $.extend ({'where':function (j) {return true;}}, var settings = $.extend ({'where':function (job) {return true;}},
options); options);
var andwhere ; var andwhere ;
if (settings.job) { if (settings.job) {
andwhere = function (j) {return (j.id === settings.job.id);}; andwhere = function (job) {return (job.id===settings.job.id);};
} else { } else {
andwhere = function (j) {return true;}; andwhere = function (job) {return true;};
} }
//// end set tests functions //// end set tests functions
//// modify the job list //// modify the job list
var jobarray = getJobArrayFromLocalStorage();
var newjobarray = [];
var found = false; var found = false;
// fill now jobarray with the for (var k in this.jobObject) {
for (var k in jobarray) { if (settings.where(this.jobObject[k]) &&
if ( settings.where(jobarray[k]) && andwhere(jobarray[k]) ) { andwhere(this.jobObject[k]) ) {
delete this.jobObject[k];
found = true; found = true;
} else {
newjobarray.push ( jobarray[k] );
} }
} }
if (found) { if (!found) {
setJobArrayToLocalStorage (newjobarray); $.error ('No jobs was found, when trying to remove some.');
} else {
$.error ('Job not found, when trying to remove one.');
} }
//// end modifying //// end modifying
this.setJobObjectToLocalStorage();
console.log ('end removeJob'); console.log ('end removeJob');
}, },
...@@ -285,27 +339,21 @@ ...@@ -285,27 +339,21 @@
resetAll: function () { resetAll: function () {
// reset All job to 'initial' // reset All job to 'initial'
console.log ('resetAll'); for (var id in this.jobObject) {
var jobarray = getJobArrayFromLocalStorage(); this.jobObject[id].status = 'initial';
for (var i in jobarray) {
jobarray[i].status = 'initial';
} }
setJobArrayToLocalStorage(jobarray); this.setJobObjectToLocalStorage();
console.log ('end resetAll');
}, },
invokeAll: function () { invokeAll: function () {
// Do all jobs in the list // Do all jobs in the list
//// do All jobs //// do All jobs
var jobarray = getJobArrayFromLocalStorage(); for (var i in this.jobObject) {
for (var i in jobarray) { if (this.jobObject[i].status === 'initial') {
if (jobarray[i].status === 'initial') { this.invoke(this.jobObject[i]);
jobarray[i].status = 'ongoing';
this.invoke(jobarray[i]);
} }
} }
setJobArrayToLocalStorage(jobarray); this.setJobObjectToLocalStorage();
//// end, continue doing jobs asynchronously //// end, continue doing jobs asynchronously
}, },
...@@ -315,22 +363,26 @@ ...@@ -315,22 +363,26 @@
console.log ('invoke'); console.log ('invoke');
//// analysing job method //// analysing job method
// browsing methods // browsing methods
if (!attr.jobMethodObject[job.method]) if (!jioAttributeObject.jobMethodObject[job.method])
// TODO do an appropriate error reaction ? unknown job method // TODO do an appropriate error reaction ? unknown job method
return false; return false;
var statusobject = getStatusObjectFromLocalStorage (); if (!this.isThereJobsWhere(function (testjob){
if (statusobject[job.method] === 'done') { return (testjob.method === job.method &&
statusobject[job.method] = 'ongoing'; testjob.method === 'ongoing');
setStatusObjectToLocalStorage(statusobject); })) {
job.status = 'ongoing';
$.jio('publish', $.jio('publish',
{'event':attr.jobMethodObject[job.method].start_event, {'event':
jioAttributeObject.jobMethodObject[
job.method].start_event,
'job':job}); 'job':job});
} else {
job.status = 'ongoing';
} }
// create an object and use it to save,load,...! // create an object and use it to save,load,...!
createStorageObject({'storage':job.storage, createStorageObject(
'applicant':attr.applicant})[ {'storage':job.storage,
attr.jobMethodObject[job.method].func 'applicant':jioAttributeObject.applicant})[job.method](job);
](job);
//// end method analyse //// end method analyse
console.log ('end invoke'); console.log ('end invoke');
}, },
...@@ -344,26 +396,17 @@ ...@@ -344,26 +396,17 @@
fail: function (job) { fail: function (job) {
// This job cannot be done, change its status into localStorage. // This job cannot be done, change its status into localStorage.
var jobarray = getJobArrayFromLocalStorage (); this.jobObject[job.id] = job;
//// find this unique job inside the list
for (var i in jobarray) {
if (jobarray[i].id === job.id) {
jobarray[i] = job;
break;
}
}
// save to local storage // save to local storage
setJobArrayToLocalStorage (jobarray); this.setJobObjectToLocalStorage ();
}, },
clean: function () { clean: function () {
// Clean the job list, removing all jobs that have failed. // Clean the job list, removing all jobs that have failed.
// It also change the localStorage Job list // It also change the localStorage Job list
this.removeJob (undefined, this.removeJob (undefined,
{'where': {'where':function (job) {
function (j) { return (job.status === 'fail');
return (j.status === 'fail');
} }); } });
} }
}; };
...@@ -389,9 +432,10 @@ ...@@ -389,9 +432,10 @@
if (!this.id) { if (!this.id) {
this.id = setInterval (function () { this.id = setInterval (function () {
// if there are jobs // if there are jobs
if (localStorage.joblist && if (jioAttributeObject.localStorage.getItem(
localStorage.joblist !== '[]') { 'jio/jobObject/'+jioAttributeObject.tabid) &&
attr.queue.invokeAll(); localStorage.joblist !== '{}') {
jioAttributeObject.queue.invokeAll();
} }
},this.interval); },this.interval);
console.log ('listener started'); console.log ('listener started');
...@@ -422,13 +466,6 @@ ...@@ -422,13 +466,6 @@
return false; return false;
} }
console.log ('initializing'); console.log ('initializing');
// check dependencies
if (!supportLocalStorage()) {
alert ('Your browser does not support local storage. '+
'$.jio cannot be initialized.');
$.error ('localStorage not supported');
return false;
}
// check settings // check settings
if (!settings.storage || if (!settings.storage ||
!settings.applicant) { !settings.applicant) {
...@@ -436,18 +473,19 @@ ...@@ -436,18 +473,19 @@
return false; return false;
} }
// objectify settings if there are strings // objectify settings if there are strings
try { attr.storage = JSON.parse(settings.storage); } try {jioAttributeObject.storage=JSON.parse(settings.storage);}
catch (e) { attr.storage = settings.storage; } catch(e){jioAttributeObject.storage=settings.storage;}
try { attr.applicant = JSON.parse(settings.applicant); } try{jioAttributeObject.applicant=JSON.parse(settings.applicant);}
catch (e) { attr.applicant = settings.applicant; } catch(e){jioAttributeObject.applicant=settings.applicant;}
// check if key exists in attr.storageTypeObject // check if key exists in jioAttributeObject.storageTypeObject
if (!settings.storage.type) { if (!settings.storage.type) {
$.error ('Storage incomplete.'); $.error ('Storage incomplete.');
return false; return false;
} }
if (!attr.storageTypeObject[settings.storage.type]) { if(!jioAttributeObject.storageTypeObject[settings.storage.type]) {
$.error ('Unknown storage type "' + settings.storage.type + '".'); $.error ('Unknown storage type "' +
settings.storage.type + '".');
return false; return false;
} }
...@@ -455,47 +493,61 @@ ...@@ -455,47 +493,61 @@
// set a tab id to every jobs ? // set a tab id to every jobs ?
// see todo from methods.close // see todo from methods.close
//attr.pubsub = new PubSub(); // set tab id
if (!attr.queue)
attr.queue = new JobQueue(); var localStor = jioAttributeObject.localStorage.getAll();
if (!attr.listener) for (var key in localStor) {
attr.listener = new JobListener(); var splitedkey = key.split('/');
attr.listener.start(); if (splitedkey[0] === 'jio' && splitedkey[1] === 'tab' &&
attr.isReady = true; JSON.parse(splitedkey[2]) > jioAttributeObject.tabid) {
jioAttributeObject.tabid = JSON.parse(splitedkey[2]);
}
}
jioAttributeObject.tabid ++;
//jioAttributeObject.pubsub = new PubSub();
if (!jioAttributeObject.queue)
jioAttributeObject.queue = new JobQueue();
if (!jioAttributeObject.listener)
jioAttributeObject.listener = new JobListener();
jioAttributeObject.listener.start();
jioAttributeObject.isReady = true;
}, },
isReady: function () { isReady: function () {
// check if jio is ready // check if jio is ready
return attr.isReady; return jioAttributeObject.isReady;
}, },
addStorageType: function ( options ) { addStorageType: function ( options ) {
var settings = $.extend({},options); var settings = $.extend({},options);
// add LocalStorage to storage object // add LocalStorage to storage object
if (settings.type && settings.creator) { if (settings.type && settings.creator) {
attr.storageTypeObject [settings.type] = settings.creator; jioAttributeObject.storageTypeObject[
settings.type] = settings.creator;
return true; return true;
} }
return false; return false;
}, },
getApplicant: function () { getApplicant: function () {
// return applicant // return applicant
return attr.applicant; return jioAttributeObject.applicant;
}, },
publish: function ( options ) { publish: function ( options ) {
if (!methods.isReady()) return null; if (!methods.isReady()) return null;
console.log ('publish ' + options.event); console.log ('publish ' + options.event);
var tmp = $.extend({},options); var tmp = $.extend({},options);
tmp.event = undefined; tmp.event = undefined;
attr.pubsub.publish(options.event,tmp); jioAttributeObject.pubsub.publish(options.event,tmp);
}, },
subscribe: function ( options ) { subscribe: function ( options ) {
console.log ('subscribe'); console.log ('subscribe');
attr.pubsub.subscribe(options.event,options.func); jioAttributeObject.pubsub.subscribe(options.event,options.func);
}, },
unsubscribe: function ( options ) { unsubscribe: function ( options ) {
console.log ('unsubscribe'); console.log ('unsubscribe');
attr.pubsub.unsubscribe(options.event); jioAttributeObject.pubsub.unsubscribe(options.event);
}, },
doMethod: function ( options ) { doMethod: function ( options ) {
// $.jio({'fileName':'a','fileContent':'b','method':'save'} // $.jio({'fileName':'a','fileContent':'b','method':'save'}
if (options.method) { if (options.method) {
if (methods[options.method]) { if (methods[options.method]) {
...@@ -505,83 +557,88 @@ ...@@ -505,83 +557,88 @@
} }
} }
}, },
isAvailable: function ( options ) { checkUserNameAvailability: function ( options ) {
// $.jio('isAvailable',{'userName':'toto'});
// $.jio('checkUserNameAvailability',{'userName':'toto'});
console.log ('isAvailable'); console.log ('isAvailable');
if (!methods.isReady()) return null; if (!methods.isReady()) return null;
var settings = $.extend ({ var settings = $.extend ({
'userName': attr.storage.userName, 'userName': jioAttributeObject.storage.userName,
'storage': attr.storage, 'storage': jioAttributeObject.storage,
'applicant': attr.applicant, 'applicant': jioAttributeObject.applicant,
'method': 'isAvailable' 'method': 'checkUserNameAvailability'
},options); },options);
// check dependencies // check dependencies
if (settings.userName) { if (settings.userName) {
return attr.queue.addJob ( {'job':(new Job ( settings ))} ) ; return jioAttributeObject.queue.addJob (
{'job':(new Job ( settings ))} ) ;
} }
return null; return null;
}, },
save: function ( options ) { saveDocument: function ( options ) {
// $.jio('save',{'fileName':'a','fileContent':'b','options':{
// $.jio('saveDocument',{'fileName':'a','fileContent':'b','options':{
// 'overwrite':false}} // 'overwrite':false}}
console.log ('save'); console.log ('saveDocument');
if (!methods.isReady()) return null; if (!methods.isReady()) return null;
var settings = $.extend({ var settings = $.extend({
'storage': attr.storage, 'storage': jioAttributeObject.storage,
'applicant': attr.applicant, 'applicant': jioAttributeObject.applicant,
'lastModified': Date.now(), 'lastModified': Date.now(),
'method':'save' 'method':'saveDocument'
},options); },options);
// check dependencies // check dependencies
if (settings.fileName && settings.fileContent) { if (settings.fileName && settings.fileContent) {
return attr.queue.addJob ( {'job':(new Job ( settings ))} ) ; return jioAttributeObject.queue.addJob (
{'job':(new Job ( settings ))} ) ;
} }
return null; return null;
}, },
load: function ( options ) { loadDocument: function ( options ) {
// $.jio('load',{'fileName':'a'});
// $.jio('loadDocument',{'fileName':'a'});
console.log ('load'); console.log ('load');
if (!methods.isReady()) return null; if (!methods.isReady()) return null;
var settings = $.extend ({ var settings = $.extend ({
'storage':attr.storage, 'storage':jioAttributeObject.storage,
'applicant':attr.applicant, 'applicant':jioAttributeObject.applicant,
'method':'load' 'method':'loadDocument'
},options); },options);
// check dependencies // check dependencies
if ( settings.fileName ) { if ( settings.fileName ) {
return attr.queue.addJob ( {'job':(new Job ( settings ))} ) ; return jioAttributeObject.queue.addJob (
{'job':(new Job ( settings ))} ) ;
} }
return null; return null;
}, },
getList: function ( options ) { getDocumentList: function ( options ) {
// $.jio('getList');
// $.jio('getDocumentList');
console.log ('getList'); console.log ('getList');
if (!methods.isReady()) return null; if (!methods.isReady()) return null;
var settings = $.extend ({ var settings = $.extend ({
'storage': attr.storage, 'storage': jioAttributeObject.storage,
'applicant': attr.applicant, 'applicant': jioAttributeObject.applicant,
'method':'getList' 'method':'getDocumentList'
},options); },options);
return attr.queue.addJob ( {'job':(new Job ( settings ))} ); return jioAttributeObject.queue.addJob (
{'job':(new Job ( settings ))} );
}, },
remove: function ( options ) { removeDocument: function ( options ) {
// $.jio('remove',{'fileName':'a'}); // $.jio('removeDocument',{'fileName':'a'});
console.log ('remove'); console.log ('removeDocument');
if (!methods.isReady()) return null; if (!methods.isReady()) return null;
var settings = $.extend ({ var settings = $.extend ({
'storage': attr.storage, 'storage': jioAttributeObject.storage,
'applicant': attr.applicant, 'applicant': jioAttributeObject.applicant,
'method':'remove' 'method':'removeDocument'
},options); },options);
if ( settings.fileName ) { if ( settings.fileName ) {
return attr.queue.addJob ( {'job':(new Job( settings ))} ); return jioAttributeObject.queue.addJob (
{'job':(new Job( settings ))} );
} }
return null; return null;
}, },
clean: function ( options ) {
// clean the job, removing all job that have failed.
attr.queue.clean();
},
close: function ( options ) { close: function ( options ) {
// finish some job if possible and close jio. // finish some job if possible and close jio.
// it can be re-init later. // it can be re-init later.
...@@ -590,8 +647,11 @@ ...@@ -590,8 +647,11 @@
// page, $.jio('close') will close tab id (if any) to free its jobs, // page, $.jio('close') will close tab id (if any) to free its jobs,
// so that other tabs may do them. // so that other tabs may do them.
attr.listener.stop(); jioAttributeObject.listener.stop();
attr.isReady = false; jioAttributeObject.isReady = false;
},
getJioAttributes: function ( options ) {
return $.extend({},jioAttributeObject);
} }
}; };
// end JIO methods // end JIO methods
...@@ -610,183 +670,4 @@ ...@@ -610,183 +670,4 @@
// end JIO arguments manager // end JIO arguments manager
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Local Storage
var LocalStorage = function ( options ) {
this.userName = options.storage.userName;
// check user's localStorage
if(!localStorage[this.userName]) {
localStorage[this.userName] = '{}'; // create user
}
};
LocalStorage.prototype = {
readDocumentsFromLocalStorage: function () {
return JSON.parse (localStorage[this.userName]);
},
writeDocumentsToLocalStorage: function (documents) {
localStorage[this.userName] = JSON.stringify(documents);
},
checkNameAvailability: function ( job ) {
// wait a little in order to simulate asynchronous operation
setTimeout(function () {
if (localStorage[job.userName]) {
job.status = 'done';
job.message = ''+ job.userName + ' is not available.';
job.isAvailable = false;
$.jio('publish',{'event': 'job_done',
'job': job});
} else {
job.status = 'done';
job.message = ''+ job.userName + ' is available.';
job.isAvailable = true;
$.jio('publish',{'event': 'job_done',
'job': job});
}
}, 100);
}, // end userNameAvailable
saveDocument: function ( job ) {
// Save a document in the local storage
// job : the job object
// job.options : the save options
// job.options.overwrite : true -> overwrite
// job.options.force : true -> save even if jobdate < existingdate
// or overwrite: false
var settings = $.extend({'overwrite':true,
'force':false},job.options);
var t = this;
// wait a little in order to simulate asynchronous saving
setTimeout (function () {
var documents = t.readDocumentsFromLocalStorage();
if (!documents[job.fileName]) { // create document
documents[job.fileName] = {
'fileName': job.fileName,
'fileContent': job.fileContent,
'creationDate': Date.now (),
'lastModified': Date.now ()
}
t.writeDocumentsToLocalStorage(documents);
job.status = 'done';
job.message = 'Document saved.';
job.isSaved = true;
$.jio('publish',{'event':'job_done',
'job':job});
return true;
}
if ( settings.overwrite || settings.force ) { // overwrite
if ( ! settings.force ) { // force write
// checking modification date
if ( ! documents[
job.fileName].lastModified < job.lastModified ) {
// date problem!
job.status = 'fail';
job.message = 'Modification date is earlier than ' +
'existing modification date.';
job.isSaved = false;
$.jio('publish',{'event':'job_done',
'job':job});
return false;
}
}
documents[job.fileName].lastModified = Date.now();
documents[job.fileName].fileContent = job.fileContent;
t.writeDocumentsToLocalStorage(documents);
job.status = 'done';
job.message = 'Document saved';
job.isSaved = true;
$.jio('publish',{'event':'job_done',
'job':job});
return true;
}
// already exists
job.status = 'fail';
job.message = 'Document already exists.';
job.errno = 403;
job.isSaved = false;
$.jio('publish',{'event':'job_fail',
'job': job});
return false;
}, 100);
}, // end saveDocument
loadDocument: function ( job ) {
// load a document in the storage, copy the content into the job
// job : the job
var t = this;
// wait a little in order to simulate asynchronous operation
setTimeout(function () {
var documents = t.readDocumentsFromLocalStorage();
if (!documents[job.fileName]) {
job.status = 'fail';
job.errno = 404;
job.message = 'Document not found.';
$.jio('publish',{'event':'job_fail',
'job':job});
} else {
job.status = 'done';
job.message = 'Document loaded.';
job.fileContent = documents[job.fileName].fileContent;
$.jio('publish',{'event':'job_done',
'job':job});
}
}, 100);
}, // end loadDocument
getDocumentList: function (job) {
var t = this;
setTimeout(function () {
var documents = t.readDocumentsFromLocalStorage();
job.list = [];
for (var k in documents) {
job.list.push ({
'fileName':documents[k].fileName,
'creationDate':documents[k].creationDate,
'lastModified':documents[k].lastModified});
}
job.status = 'done';
job.message = 'List received.';
$.jio('publish',{'event':'job_done',
'job':job});
}, 100);
}, // end getDocumentList
removeDocument: function () {
var t = this;
setTimeout (function () {
var documents = t.readDocumentsFromLocalStorage();
if (!documents[job.fileName]) {
// job.status = 'fail';
// job.errno = 404;
// job.message = 'Document not found.';
// job.isRemoved = false;
// $.jio('publish',{'event':'job_fail',
// 'job':job});
job.status = 'done';
job.message = 'Document already removed.';
job.isRemoved = true;
$.jio('publish',{'event':'job_done',
'job':job});
} else {
delete documents[job.fileName];
t.writeToLocalStorage(documents);
job.status = 'done';
job.message = 'Document removed.';
job.isRemoved = true;
$.jio('publish',{'event':'job_done',
'job':job});
}
}, 100);
}
};
// add key to storageObject
methods.addStorageType({'type':'local','creator':function (o) {
return new LocalStorage(o);
}});
// end Local Storage
////////////////////////////////////////////////////////////////////////////
})( jQuery ); })( jQuery );
;(function ( $ ) { ;(function ( $ ) {
// TODO do we realy need to check dependencies ?
// test dependencies // test dependencies
try { try {
if (Base64) {} if ($.jio && Base64) {}
else {return false;} else {return false;}
} catch (e) { } catch (e) {
$.error('Base64 is required by jio.storage.js'); $.error('jio.js and base64.js '+
' are required by jio.storage.js');
return false; return false;
}; };
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// private vars // private vars
var attr = { var jioAttributeObject = $.jio('getJioAttributes');
'jobMethodObject': {
'available': {
'start_event':'start_testingNameAvailability',
'stop_event':'stop_testingNameAvailability',
'func':'checkNameAvailability',
'retvalue':'isAvailable' }, // returns 'boolean'
'save': {
'start_event':'start_saving',
'stop_event':'stop_saving',
'func':'saveDocument',
'retvalue':'isSaved' }, // returns 'boolean'
'load': {
'start_event':'start_loading',
'stop_event':'stop_loading',
'func':'loadDocument',
'retvalue':'fileContent' }, // returns the file content 'string'
'getList': {
'start_event':'start_gettingList',
'stop_event':'stop_gettingList',
'func':'getDocumentList',
'retvalue':'list' }, // returns the document list 'array'
'remove': {
'start_event':'start_removing',
'stop_event':'stop_removing',
'func':'removeDocument',
'retvalue':'isRemoved' } // returns 'boolean'
}
};
// end private vars // end private vars
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Tools // Tools
var objectDump = function (o) {
// TODO DEBUG we can remove this function // end Tools
console.log (JSON.stringify(o)); ////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Local Storage
var LocalStorage = function ( options ) {
// LocalStorage constructor
// initializes the local storage for jio and create user if necessary.
this.userName = options.storage.userName;
}; };
var toString = function (o) { LocalStorage.prototype = {
// TODO DEBUG we can remove this function checkNameAvailability: function ( job ) {
return (JSON.stringify(o)); // checks the availability of the [job.userName].
// if the name already exists, it is not available.
// job: the job object
// job.userName: the name we want to check.
// wait a little in order to simulate asynchronous operation
setTimeout(function () {
var available = true;
var localStor = jioAttributeObject.localStorage.getAll();
for (var k in localStor) {
var splitk = k.split('/');
if (splitk[0] === 'jio' && splitk[1] === job.userName) {
available = false;
break;
}
}
if (!available) {
job.status = 'done';
job.message = ''+ job.userName + ' is not available.';
job.isAvailable = false;
$.jio('publish',{'event': 'job_done',
'job': job});
} else {
job.status = 'done';
job.message = ''+ job.userName + ' is available.';
job.isAvailable = true;
$.jio('publish',{'event': 'job_done',
'job': job});
}
}, 100);
}, // end userNameAvailable
saveDocument: function ( job ) {
// Save a document in the local storage
// job : the job object
// job.options : the save options object
// job.options.overwrite : true -> overwrite
// job.options.force : true -> save even if jobdate < existingdate
// or overwrite: false
var settings = $.extend({'overwrite':true,
'force':false},job.options);
var t = this;
// wait a little in order to simulate asynchronous saving
setTimeout (function () {
// reading
var doc = jioAttributeObject.localStorage.getItem(
'jio/local/'+job.storage.userName+'/'+job.applicant.ID+'/'+
job.fileName);
if (!doc) { // create document
doc = {
'fileName': job.fileName,
'fileContent': job.fileContent,
'creationDate': Date.now (),
'lastModified': Date.now ()
}
// writing
jioAttributeObject.localStorage.setItem(
'jio/local/'+job.storage.userName+'/'+job.applicant.ID+'/'+
job.fileName, doc);
job.status = 'done';
job.message = 'Document saved.';
job.isSaved = true;
$.jio('publish',{'event':'job_done',
'job':job});
return true;
}
if ( settings.overwrite || settings.force ) { // overwrite
if ( ! settings.force ) { // force write
// checking modification date
if ( doc.lastModified >= job.lastModified ) {
// date problem!
job.status = 'fail';
job.message = 'Modification date is earlier than ' +
'existing modification date.';
job.isSaved = false;
$.jio('publish',{'event':'job_fail',
'job':job});
return false;
}
}
doc.lastModified = Date.now();
doc.fileContent = job.fileContent;
// writing
jioAttributeObject.localStorage.setItem(
'jio/local/'+job.storage.userName+'/'+job.applicant.ID+'/'+
job.fileName, doc);
job.status = 'done';
job.message = 'Document saved';
job.isSaved = true;
$.jio('publish',{'event':'job_done',
'job':job});
return true;
}
// already exists
job.status = 'fail';
job.message = 'Document already exists.';
job.errno = 403;
job.isSaved = false;
$.jio('publish',{'event':'job_fail',
'job': job});
return false;
}, 100);
}, // end saveDocument
loadDocument: function ( job ) {
// load a document in the storage, copy the content into the job
// job : the job
var t = this;
// wait a little in order to simulate asynchronous operation
setTimeout(function () {
var doc = jioAttributeObject.localStorage.getItem(
'jio/local/'+job.storage.userName+'/'+job.applicant.ID+'/'+
job.fileName);
if (!doc) {
job.status = 'fail';
job.errno = 404;
job.message = 'Document not found.';
$.jio('publish',{'event':'job_fail',
'job':job});
} else {
job.status = 'done';
job.message = 'Document loaded.';
job.fileContent = doc.fileContent;
$.jio('publish',{'event':'job_done',
'job':job});
}
}, 100);
}, // end loadDocument
getDocumentList: function (job) {
var t = this;
setTimeout(function () {
var localStor = jioAttributeObject.localStorage.getAll();
job.list = [];
for (var k in localStor) {
var splitk = k.split('/');
if (splitk[0] === 'jio' &&
splitk[1] === 'local' &&
splitk[2] === job.storage.userName &&
splitk[3] === job.applicant.ID) {
// TODO error here
console.log (JSON.stringify (localStor[k]));
job.list.push ({
'fileName':localStor[k].fileName,
'creationDate':localStor[k].creationDate,
'lastModified':localStor[k].lastModified});
}
}
console.log (JSON.stringify (job.list));
job.status = 'done';
job.message = 'List received.';
$.jio('publish',{'event':'job_done',
'job':job});
}, 100);
}, // end getDocumentList
removeDocument: function ( job ) {
var t = this;
setTimeout (function () {
var doc = jioAttributeObject.localStorage.getItem(
'jio/local/'+job.storage.userName+'/'+job.applicant.ID+'/'+
job.fileName);
if (!doc) {
// job.status = 'fail';
// job.errno = 404;
// job.message = 'Document not found.';
// job.isRemoved = false;
// $.jio('publish',{'event':'job_fail',
// 'job':job});
job.status = 'done';
job.message = 'Document already removed.';
job.isRemoved = true;
$.jio('publish',{'event':'job_done',
'job':job});
} else {
jioAttributeObject.localStorage.deleteItem(
'jio/local/'+
job.storage.userName+'/'+job.applicant.ID+'/'+
job.fileName);
job.status = 'done';
job.message = 'Document removed.';
job.isRemoved = true;
$.jio('publish',{'event':'job_done',
'job':job});
}
}, 100);
}
}; };
// end Tools
// add key to storageObject
$.jio('addStorageType',{'type':'local','creator':function (options) {
return new LocalStorage(options);
}});
// end Local Storage
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
...@@ -280,11 +456,11 @@ ...@@ -280,11 +456,11 @@
$("D\\:response",xmlData).each(function(i,data) { $("D\\:response",xmlData).each(function(i,data) {
if(i>0) { // exclude parent folder if(i>0) { // exclude parent folder
var file = {}; var file = {};
var nt = ($($("D\\:href", var pathArray = ($($("D\\:href",
xmlData).get(i)).text()).split('/'); xmlData).get(i)).text()).split('/');
file.fileName = (nt[nt.length-1] ? file.fileName = (pathArray[pathArray.length-1] ?
nt[nt.length-1] : pathArray[pathArray.length-1] :
nt[nt.length-2]+'/'); pathArray[pathArray.length-2]+'/');
if (file.fileName === '.htaccess' || if (file.fileName === '.htaccess' ||
file.fileName === '.htpasswd') file.fileName === '.htpasswd')
return; return;
...@@ -352,8 +528,8 @@ ...@@ -352,8 +528,8 @@
}; };
// add key to storageObject // add key to storageObject
$.jio('addStorageType',{'type':'dav','creator':function (o) { $.jio('addStorageType',{'type':'dav','creator':function (options) {
return new DAVStorage(o); return new DAVStorage(options);
}}); }});
// end DAVStorage // end DAVStorage
......
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