Commit 518161fb authored by François Billioud's avatar François Billioud

add JIOStorage management

parent 594bdd07
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
/* /*
* global variables * global variables
*/ */
applicationID = window.location.href.split("://")[1].split("/")[0];
languages = ["fr","en"]; languages = ["fr","en"];
var availableLanguages = $("#available_languages"); var availableLanguages = $("#available_languages");
...@@ -73,7 +74,7 @@ Page.prototype = { ...@@ -73,7 +74,7 @@ Page.prototype = {
doc=new JSONIllustrationDocument(); doc=new JSONIllustrationDocument();
break; break;
default://renvoie à la page d'accueil default://renvoie à la page d'accueil
window.location = "ung.html"; window.location.href = "ung.html";
return; return;
break; break;
} }
...@@ -138,8 +139,8 @@ Page.prototype = { ...@@ -138,8 +139,8 @@ Page.prototype = {
displayPageTitle: function() {$("title#page_title").html(this.getTitle());}, displayPageTitle: function() {$("title#page_title").html(this.getTitle());},
displayPageContent: function() {$("div#page_content").html(this.getContent());} displayPageContent: function() {$("div#page_content").html(this.getContent());}
} }
getCurrentPage = function() {return currentPage;} function getCurrentPage() {return currentPage;}
setCurrentPage = function(page) {currentPage = page;} function setCurrentPage(page) {currentPage = page;}
/* /*
* User Class * User Class
...@@ -157,9 +158,9 @@ var User = function(arg) { ...@@ -157,9 +158,9 @@ var User = function(arg) {
this.name = "UNG";//default name this.name = "UNG";//default name
this.settings = { this.settings = {
language: "en", language: "en",
displayPreferences: 15//number of displayed document in the list displayPreferences: 15,//number of displayed document in the list
checkAllMethod: "page"//check only the displayed page
} }
this.documentList = new DocumentList();
this.documents = {}; this.documents = {};
} }
} }
...@@ -168,12 +169,12 @@ User.prototype.load({//add methods thanks to the UngObject.load method ...@@ -168,12 +169,12 @@ User.prototype.load({//add methods thanks to the UngObject.load method
getName: function() {return this.name;}, getName: function() {return this.name;},
setName: function(newName) {this.name = newName;}, setName: function(newName) {this.name = newName;},
getSetting: function(key) {return this.settings[key];}, getSetting: function(key) {return this.settings[key];},
setSetting: function(key,value) { this.settings[key] = value; }, setSetting: function(key,value) {this.settings[key] = value;},
getSettings: function() {return this.settings;}, getSettings: function() {return this.settings;},
getDocumentList: function() {return this.documentList;}, getDocumentList: function() {return this.documentList;},
setDocumentList: function(list) {this.documentList = list;}, setDocumentList: function(list) {this.documentList = list;},
getIDProvider: function() {return this.IDProvider;}, getStorageLocation: function() {return this.storageLocation;},
setAsCurrentUser: function() { setAsCurrentUser: function() {
getCurrentPage().displayUserName(this); getCurrentPage().displayUserName(this);
...@@ -183,7 +184,7 @@ User.prototype.load({//add methods thanks to the UngObject.load method ...@@ -183,7 +184,7 @@ User.prototype.load({//add methods thanks to the UngObject.load method
} }
}); });
getCurrentUser = function() { function getCurrentUser() {
return getCurrentStorage().getUser(); return getCurrentStorage().getUser();
} }
...@@ -195,26 +196,20 @@ getCurrentUser = function() { ...@@ -195,26 +196,20 @@ getCurrentUser = function() {
* Class Storage * Class Storage
* this class provides usual API to save/load/delete elements * this class provides usual API to save/load/delete elements
* @param type : "local" to save in localStorage, or "JIO" for remote storage * @param type : "local" to save in localStorage, or "JIO" for remote storage
* @param userName : the name of the user concerned by this storage
*/ */
var Storage = function(type, userName) { var Storage = function(type) {
this.type = type; this.type = type;
if(userName) {
var loaded = this.loadUser(userName)//load an existing user
if(!loaded) {//create a new user if there was no such one
var user = new User();
user.setName(userName);
this.setUser(user);
}
}
} }
Storage.prototype = new UngObject(); Storage.prototype = new UngObject();
Storage.prototype.load({ Storage.prototype.load({
getType: function() {return this.type;}, getType: function() {return this.type;},
getUser: function() {return this.user;}, getUser: function() {return this.user;},
setUser: function(user) {this.user = user;this.save();},
loadUser: function(userName) {}, updateUser: function() {localStorage[this.user.name] = JSON.stringify(this.user);},
setUser: function(user) {this.user = user} save: function() {
this.updateUser();
localStorage.setItem("currentStorage", JSON.stringify(this));
}
}); });
/** /**
...@@ -222,7 +217,15 @@ Storage.prototype.load({ ...@@ -222,7 +217,15 @@ Storage.prototype.load({
* this class provides usual API to save/load/delete documents on the localStorage * this class provides usual API to save/load/delete documents on the localStorage
*/ */
var LocalStorage = function(userName) { var LocalStorage = function(userName) {
Storage.call(this,"local", userName); Storage.call(this,"local");
if(userName) {
var loaded = this.loadUser(userName)//load an existing user
if(!loaded) {//create a new user if there was no such one
var user = new User();
user.setName(userName);
this.setUser(user);
}
}
} }
LocalStorage.prototype = new Storage(); LocalStorage.prototype = new Storage();
LocalStorage.prototype.load({ LocalStorage.prototype.load({
...@@ -241,104 +244,130 @@ LocalStorage.prototype.load({ ...@@ -241,104 +244,130 @@ LocalStorage.prototype.load({
return false return false
} }
}, },
getUser: function() {return this.user;}, getDocument: function(file, instruction) {
setUser: function(user) { var doc = new JSONDocument(this.user.documents[file]);
this.user = user;
localStorage[this.user.name] = JSON.stringify(user);
},
updateUser: function() {localStorage[this.user.name] = JSON.stringify(this.user);},
getDocument: function(address, instruction) {
var doc = new JSONDocument(this.user.documents[address]);
if(instruction) instruction(doc); if(instruction) instruction(doc);
return doc; return doc;
}, },
saveDocument: function(doc, address, instruction) { saveDocument: function(doc, file, instruction) {
this.user.documents[address] = doc; this.user.documents[file] = doc;
this.updateUser(); this.save();
if(instruction) instruction(); if(instruction) instruction();
}, },
deleteDocument: function(address, instruction) { deleteDocument: function(file, instruction) {
delete this.user.documents[address]; delete this.user.documents[file];
this.updateUser(); this.save();
if(instruction) instruction(); if(instruction) instruction();
},
save: function() {
this.updateUser();
localStorage.setItem("currentStorage", JSON.stringify(this));
} }
}); });
/** /**
* Class JIOStorage * Class JIO
* this class provides usual API to save/load/delete documents on a remote storage * this class provides usual API to save/load/delete documents on a remote storage
*/ */
var JIOStorage = function(userName, IDProvider) { var JIOStorage = function(arg) {
Storage.call(this,"JIO", userName); Storage.call(this,"JIO");
if(this.user) this.user.IDProvider = IDProvider;
} if(arg.jio && arg.jio.jioFileContent) {
JIOStorage.prototype = new Storage(); this.jio = JIO.initialize(arg.jio.jioFileContent, {"ID":"www.ungproject.com"});
JIOStorage.prototype.load({ this.user = new User(arg.user);
loadUser: function(userName) {
//JIO : IDProvider } else {
}, this.jio = initializeFromDav(arg.userName, arg.storageLocation, {"ID":"www.ungproject.com", "password":arg.applicationPassword});
getDocument: function(address, instruction) { //try to load user parameters
var storage = this;
JIO.loadDocument(arg.userName+".profile","text",
function(data) {//success
storage.setUser(new User(JSON.parse(data)));
storage.user.storageLocation = arg.storageLocation;
storage.save()
},
function(errorEvent) {//fail
if(errorEvent.status==404){//create a new user if there was no such one
var user = new User();
user.setName(arg.userName);
storage.setUser(user);
storage.user.storageLocation = arg.storageLocation;
storage.save();
}
}
,false);
}
/**
* load JIO file from a DAV and create and return the JIO object
* @param userName : name of the user
* @param location : server location
* @param applicant : (optional) information about the person/application needing this JIO object (allow limited access)
* @return JIO object
*/
function initializeFromDav(userName, location, applicant) {
//get the user personal JIO file
$.ajax({ $.ajax({
url: address, url: location+"/dav/"+userName+"/"+applicant.ID+"/"+"jio.json",//we could use userAdress instead...
type: "GET", type: "GET",
dataType: type, async: false,
headers: {Authorization: "Basic "+btoa("smik:asdf")}, dataType: "text",
headers: {Authorization: "Basic "+Base64.encode(userName+":"+applicant.password)},
fields: {withCredentials: "true"}, fields: {withCredentials: "true"},
success: instruction, success: function(jioContent){
error: function(type) {alert("Error "+type.status+" : fail while trying to load "+address);} JIO.initialize(jioContent,applicant);
},
error: function(type) {alert("Error "+type.status+" : fail while trying to load jio.json");}
}); });
return JIO;
}
}
JIOStorage.prototype = new Storage();
JIOStorage.prototype.load({
getJIO: function() {return this.jio;},
loadUser: function(userName) {//warning no return value
JIO.loadDocument(userName+".profile","text",
function(data) {setUser(new User(JSON.parse(data)));},
function(errorEvent) {if(errorEvent.status==404){}}
);
}, },
saveDocument: function(content, address, instruction) { getDocument: function(file, instruction) {
this.user.documents[address] = doc; JIO.loadDocument(file, "text", function(content) {
$.ajax({ var doc = new JSONDocument(JSON.parse(content));
url: address, if(instruction) instruction(doc);
type: "PUT",
dataType: "json",
data: JSON.stringify(content),
headers: {Authorization: "Basic "+btoa("smik:asdf")},
fields: {withCredentials: "true"},
success: instruction,
error: function(type) {
if(type.status==201 || type.status==204) {instruction();}//ajax thinks that 201 is an error...
}
}); });
}, },
deleteDocument: function(address, instruction) { saveDocument: function(doc, file, instruction) {
delete this.user.documents[address]; JIO.saveDocument(JSON.stringify(doc), file, "text", true, instruction)
$.ajax({ },
url: address, deleteDocument: function(file, instruction) {
type: "DELETE", JIO.deleteDocument(file, instruction)
headers: {Authorization: "Basic "+btoa("smik:asdf")}, },
fields: {withCredentials: "true"}, getDocumentList: function(instruction) {
success: instruction, var list = JIO.getDocumentList(instruction, undefined, false);//synchrone operation. Could be asynchronised
error: function(type) { delete list[this.userName+".profile"];
alert(type.status);//ajax thinks that 201 is an error... return list;
} },
}); save: function() {
this.updateUser();
this.saveDocument(this.user,this.user.getName()+".profile",function() {});
localStorage.setItem("currentStorage",JSON.stringify(this));
} }
}); });
getCurrentStorage = function() { function getCurrentStorage() {
if(!currentStorage) {//if storage has not been loaded yet if(currentStorage) {return currentStorage;}
var dataStorage = JSON.parse(localStorage.getItem("currentStorage"));
if(!dataStorage) {window.location = "login.html";return null;}//if it's the first connexion
switch(dataStorage.type) {//load the last storage used var dataStorage = JSON.parse(localStorage.getItem("currentStorage"));
case "local": currentStorage = new LocalStorage(); break;
case "JIO": currentStorage = new JIOStorage(); break; if(!dataStorage) {window.location.href = "login.html";return null;}//if it's the first connexion
} if(dataStorage.type == "local") {
currentStorage.loadUser(dataStorage.user.name); currentStorage = new LocalStorage(dataStorage.userName);
currentStorage.type = dataStorage.type; } else {
if(!JIO.jioFileContent) {JIO.initialize(dataStorage.jio.jioFileContent, {"ID":"www.ungproject.com"})}
currentStorage = new JIOStorage(dataStorage);
} }
return currentStorage; return currentStorage;
} }
setCurrentStorage = function(storage) { function setCurrentStorage(storage) {
currentStorage = storage; currentStorage = storage;
localStorage.setItem("currentStorage", JSON.stringify(storage)); localStorage.setItem("currentStorage", JSON.stringify(storage));
} }
...@@ -413,15 +442,22 @@ JSONDocument.prototype.load({//add methods thanks to the UngObject.load method ...@@ -413,15 +442,22 @@ JSONDocument.prototype.load({//add methods thanks to the UngObject.load method
getState:function() {return this.state;}, getState:function() {return this.state;},
setState:function(state) {this.state=state;}, setState:function(state) {this.state=state;},
setAsCurrentDocument: function() { //labels
getLabel:function() {return this.label},
isLabelised:function(label) {return this.label[label]},
addLabel:function(label) {this.label[label]=true;},
removeLabel:function(label) {delete this.label[label]},
setAsCurrentDocument: function() {//display informations about this document in the webPage
setCurrentDocument(this); setCurrentDocument(this);
}, },
save: function(instruction) {//save the document
save: function(instruction) {
var doc = this; var doc = this;
getCurrentStorage().saveDocument(doc, getDocumentAddress(this), instruction); getCurrentStorage().saveDocument(doc, getDocumentAddress(this), instruction);
}, },
remove: function(instruction) {getCurrentStorage().deleteDocument(getDocumentAddress(this), instruction);} remove: function(instruction) {//remove the document
getCurrentStorage().deleteDocument(getDocumentAddress(this), instruction);
}
}); });
JSONDocument.prototype.states = { JSONDocument.prototype.states = {
draft:{"fr":"Brouillon","en":"Draft"}, draft:{"fr":"Brouillon","en":"Draft"},
...@@ -591,16 +627,15 @@ saveCurrentDocument = function() { ...@@ -591,16 +627,15 @@ saveCurrentDocument = function() {
* @param doc : the document to edit * @param doc : the document to edit
*/ */
var startDocumentEdition = function(doc) { var startDocumentEdition = function(doc) {
getCurrentStorage().getDocument(getDocumentAddress(doc), function(data) { getCurrentStorage().getDocument(doc.fileName, function(data) {
doc.load(data); setCurrentDocument(data);
setCurrentDocument(doc); if(supportedDocuments[data.getType()].editorPage) {window.location.href = "theme.html";}
if(supportedDocuments[doc.getType()].editorPage) {window.location = "theme.html";}
else alert("no editor available for this document"); else alert("no editor available for this document");
}); });
} }
var stopDocumentEdition = function() { var stopDocumentEdition = function() {
saveCurrentDocument(); saveCurrentDocument();
window.location = "ung.html"; window.location.href = "ung.html";
return false; return false;
} }
...@@ -609,16 +644,18 @@ var stopDocumentEdition = function() { ...@@ -609,16 +644,18 @@ var stopDocumentEdition = function() {
* @param language : the new language * @param language : the new language
*/ */
var changeLanguage = function(language) { var changeLanguage = function(language) {
getCurrentUser().setSetting("language"); getCurrentUser().setSetting("language",language);
getCurrentStorage().save(); getCurrentStorage().save();
getCurrentPage().displayLanguages(user); getCurrentPage().displayLanguages(getCurrentUser());
window.location.reload(); window.location.reload();
} }
var signOut = function() { var signOut = function() {
delete localStorage.currentStorage; delete localStorage.currentStorage;
delete localStorage.currentDocumentID; delete localStorage.currentDocumentID;
window.location = "login.html"; delete localStorage.wallet;
delete sessionStorage.documentList;
window.location.href = "login.html";
return false return false
} }
......
...@@ -10,35 +10,41 @@ setCurrentDocumentID = function(ID) {return localStorage.setItem("currentDocumen ...@@ -10,35 +10,41 @@ setCurrentDocumentID = function(ID) {return localStorage.setItem("currentDocumen
/** /**
* class DocumentList * class DocumentList
* This class provides methods to manipulate the list of documents of the current user * This class provides methods to manipulate the list of documents of the current user
* @param arg : a documentList json object to load * the list object is the documentList returned by the storage.
* the detailedList object is the synchronized list containing more detailed information about documents
* @param documentList : documents information loaded from the storage
*/ */
var DocumentList = function(arg) { var DocumentList = function(documentList) {
//List.call(this); if(sessionStorage.documentList) {//load from sessionStorage
if(arg) { this.load(JSON.parse(sessionStorage.documentList));
this.load(arg);
this.load(new List(arg,JSONDocument));
this.selectionList = new List(arg.selectionList);//load methods of selectionList
} }
else { else {
List.call(this); if(documentList) {
for(var doc in documentList) {
this.documentList[doc] = new JSONDocument(documentList[doc]);
}
} else {this.documentList = {}}
this.list = getCurrentStorage().getDocumentList();
this.displayInformation = {}; this.displayInformation = {};
this.displayInformation.page = 1; this.displayInformation.page = 1;
this.selectionList = new List(); this.selectionList = [];
} }
} }
DocumentList.prototype = new List(); DocumentList.prototype = new UngObject();
DocumentList.prototype.load({ DocumentList.prototype.load({
removeDocument: function(doc) { removeDocument: function(fileName) {
var i = this.find(doc); getCurrentStorage().remove(fileName)//delete the file
this.get(i).remove()//delete the file delete this.list[fileName];//remove from the list
this.remove(i);//remove from the list delete this.detailedList[fileName];//
getCurrentStorage().save();//save changes this.save();//save changes
}, },
getList: function() {return this.list},
getDetailedList: function() {return this.detailedList},
getSelectionList: function() {return this.selectionList;}, getSelectionList: function() {return this.selectionList;},
resetSelectionList: function() { resetSelectionList: function() {
this.selectionList = new List(); this.selectionList = [];
//display consequences //display consequences
for(var i=this.getDisplayInformation().first-1; i<this.getDisplayInformation().last; i++) { for(var i=this.getDisplayInformation().first-1; i<this.getDisplayInformation().last; i++) {
...@@ -47,9 +53,17 @@ DocumentList.prototype.load({ ...@@ -47,9 +53,17 @@ DocumentList.prototype.load({
$("span#selected_row_number a").html(0);//display the selected row number $("span#selected_row_number a").html(0);//display the selected row number
}, },
checkAll: function() { checkAll: function() {
this.selectionList = new List(); this.selectionList = [];
for(var i=0; i<this.size(); i++) { var list = toArray(this.getList());
this.getSelectionList().add(this.get(i));
var begin = 0;
var end = list.length;
if(getCurrentUser().getSetting("checkAllMethod")=="page") {
begin = this.getDisplayInformation().first-1;
end = this.getDisplayInformation().last;
}
for(var i=begin; i<end; i++) {
this.addToSelection(list[i].fileName);
} }
//display consequences //display consequences
...@@ -58,12 +72,19 @@ DocumentList.prototype.load({ ...@@ -58,12 +72,19 @@ DocumentList.prototype.load({
} }
$("span#selected_row_number a").html(this.size());//display the selected row number $("span#selected_row_number a").html(this.size());//display the selected row number
}, },
addToSelection: function(fileName) {
this.getSelectionList().push(fileName);
},
removeFromSelection: function(fileName) {
var selection = getDocumentList().getSelectionList();
selection.splice(selection.indexOf(fileName),1);
},
deleteSelectedDocuments: function() { deleteSelectedDocuments: function() {
var selection = this.getSelectionList(); var selection = this.getSelectionList();
while(!selection.isEmpty()) { while(selection.length>0) {
var doc = selection.pop(); var fileName = selection.pop();
this.removeDocument(doc); this.removeDocument(fileName);
} }
this.display(); this.display();
}, },
...@@ -87,17 +108,20 @@ DocumentList.prototype.load({ ...@@ -87,17 +108,20 @@ DocumentList.prototype.load({
}, },
/* display the list of documents in the web page */ /* display the list of documents in the web page */
displayContent: function() { displayContent: function() {//display the list of document itself
$("table.listbox tbody").html("");//empty the previous displayed list $("table.listbox tbody").html("");//empty the previous displayed list
var list = toArray(this.getList());
var detailedList = this.getDetailedList();
for(var i=this.getDisplayInformation().first-1;i<this.getDisplayInformation().last;i++) { for(var i=this.getDisplayInformation().first-1;i<this.getDisplayInformation().last;i++) {
var doc = this.get(i); var fileName = list[i].fileName;
var ligne = new Line(doc,i); if(!detailedList[fileName] || new Date(detailedList[fileName].lastModification+1000)<new Date(list[i].lastModify)) {updateDocumentInformation(fileName)}
ligne.updateHTML(); var line = new Line(doc,i);
ligne.display(); line.updateHTML();
if(this.getSelectionList().contains(doc)) {ligne.setSelected(true);}//check the box if selected line.display();
if(this.getSelectionList().indexOf(doc.fileName)) {line.setSelected(true);}//check the box if selected
} }
}, },
displayListInformation: function() { displayListInformation: function() {//display number of records, first displayed document, last displayed document...
if(this.size()>0) { if(this.size()>0) {
$("div.listbox-number-of-records").css("display","inline"); $("div.listbox-number-of-records").css("display","inline");
...@@ -108,7 +132,7 @@ DocumentList.prototype.load({ ...@@ -108,7 +132,7 @@ DocumentList.prototype.load({
} }
else {$("div.listbox-number-of-records").css("display","none");} else {$("div.listbox-number-of-records").css("display","none");}
}, },
displayNavigationElements: function() { displayNavigationElements: function() {//display buttons first-page, previous, next, last-page
var lastPage = this.getDisplayInformation().lastPage; var lastPage = this.getDisplayInformation().lastPage;
var disp = function(element,bool) { var disp = function(element,bool) {
bool ? $(element).css("display","inline") : $(element).css("display","none"); bool ? $(element).css("display","inline") : $(element).css("display","none");
...@@ -132,13 +156,12 @@ DocumentList.prototype.load({ ...@@ -132,13 +156,12 @@ DocumentList.prototype.load({
}, },
/* update the ith document information */ /* update the ith document information */
updateDocumentInformation: function(i) { updateDocumentInformation: function(fileName) {
var list = this; var list = this.getDetailedList();
var doc = list.get(i); getCurrentStorage().getDocument(fileName, function(doc) {
getCurrentStorage().getDocument(getDocumentAddress(doc), function(data) { list[fileName]=doc;
doc.load(data);//todo : replace by data.header list[fileName].fileName = fileName;
doc.setContent("");// doc.setContent("");
list.set(i,doc);
}); });
}, },
/* update the document to be displayed */ /* update the document to be displayed */
...@@ -172,7 +195,7 @@ var Line = function(doc, i) { ...@@ -172,7 +195,7 @@ var Line = function(doc, i) {
Line.prototype = { Line.prototype = {
getDocument: function() {return this.document;}, getDocument: function() {return this.document;},
getID: function() {return this.ID;}, getID: function() {return this.ID;},
getType: function() {return this.document.getType() ? this.document.getType() : "other";}, getType: function() {return this.document.getType() || "other";},
getHTML: function() {return this.html;}, getHTML: function() {return this.html;},
setHTML: function(newHTML) {this.html = newHTML;}, setHTML: function(newHTML) {this.html = newHTML;},
setSelected: function(bool) {$("tr td.listbox-table-select-cell input#"+this.getID()).attr("checked",bool)}, setSelected: function(bool) {$("tr td.listbox-table-select-cell input#"+this.getID()).attr("checked",bool)},
...@@ -182,16 +205,16 @@ Line.prototype = { ...@@ -182,16 +205,16 @@ Line.prototype = {
/* add the document of this line to the list of selected documents */ /* add the document of this line to the list of selected documents */
addToSelection: function() { addToSelection: function() {
getDocumentList().getSelectionList().add(this.getDocument()); getDocumentList().addToSelection(this.getDocument().fileName);
}, },
/* remove the document of this line from the list of selected documents */ /* remove the document of this line from the list of selected documents */
removeFromSelection: function() { removeFromSelection: function() {
getDocumentList().getSelectionList().removeElement(this.getDocument()); getDocumentList().removeFromSelection(this.getDocument().fileName);
}, },
/* check or uncheck the line */ /* check or uncheck the line */
changeState: function() { changeState: function() {
this.isSelected() ? this.addToSelection() : this.removeFromSelection(); this.isSelected() ? this.addToSelection() : this.removeFromSelection();
$("span#selected_row_number a").html(getDocumentList().getSelectionList().size());//display the selected row number $("span#selected_row_number a").html(getDocumentList().getSelectionList().length);//display the selected row number
}, },
/* load the document information in the html of a default line */ /* load the document information in the html of a default line */
......
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