Commit 77ddcfa2 authored by François Billioud's avatar François Billioud

Try to rewrite bad coded elements and fix asynchronism problem.

There is an infinity loop in with the user profile load and save. It should be fixed
parent 6e643eb0
......@@ -10,7 +10,8 @@
* loadContentFromDocument : display the content of the specified document in the editor
*/
SVGEditor = function() {
this.name = "svg-editor";
this.name = "svg-edit"; // name to use in dialog boxes
this.objectName = "SVGEditor" // name of the object reference
this.load = function() {$("#svgframe").attr("src", "svg-edit/svg-editor.html");}
this.saveEdition = function() {
......@@ -26,39 +27,20 @@ SVGEditor = function() {
/**
* SVG documents
*
* editable documents must implements the following arguments and methods
* editable documents must override the following arguments and methods of JSONDocument prototype
* type : a unique type ID
* saveEdition : set the argument as the new content of the document. Change last modification time and display the changes
* setAsCurrentDocument : set the document as currentDocument in the local storage and display its properties in the current page
*
* @param arg : a json JSONTextDocument object to load
*/
var JSONIllustrationDocument = function(arg) {
JSONDocument.call(this,arg);//inherits properties from JSONDocument
if(arg) {this.load(arg);}
else {
this.type = "illustration";
}
}
JSONIllustrationDocument.prototype = new JSONDocument();//inherits methods from JSONDocument
JSONIllustrationDocument.prototype.saveEdition = function(content) {
JSONDocument.prototype.type = "text";
JSONDocument.prototype.saveEdition = function(content) {
this.setLastUser(getCurrentUser().getName());
this.setContent(content);
this.setLastModification(getCurrentTime());
this.setAsCurrentDocument();
}
JSONIllustrationDocument.prototype.setAsCurrentDocument = function() {
getCurrentPage().displayDocumentTitle(this);
getCurrentPage().displayDocumentState(this);
getCurrentPage().displayDocumentContent(this);
getCurrentPage().displayLastUserName(this);
getCurrentPage().displayLastModification(this);
JSONDocument.prototype.setAsCurrentDocument = function() {
getCurrentPage().displayDocumentInformation(this);
setCurrentDocument(this);
}
getCurrentDocument = function() {
return new JSONIllustrationDocument(JSON.parse(localStorage.getItem("currentDocument")));
}
......@@ -21,9 +21,9 @@ function logIntoDav(wallet) {
function initStorage(wallet) {
if(!wallet.provider) {//local storage
setCurrentStorage(new LocalStorage(wallet.userName));
Storage.currentStorage = new LocalStorage(wallet.userName);
} else {
setCurrentStorage(new JIOStorage(wallet));
Storage.currentStorage = new JIOStorage(wallet);
}
}
......
......@@ -10,7 +10,8 @@
* loadContentFromDocument : display the content of the specified document in the editor
*/
var Xinha = function() {
this.name = "Xinha";
this.name = "Xinha"; // name to use in dialog boxes
this.objectName = "Xinha" // name of the object reference
this.load = function() {
_editor_url = "xinha/";
getCurrentPage().include("xinha/XinhaCore.js","script");
......@@ -28,7 +29,8 @@ var Xinha = function() {
}
var AlohaInterface = function() {
this.name = "Aloha";
this.name = "Aloha"; // name to use in dialog boxes
this.objectName = "AlohaInterface" // name of the object reference
this.load = function() {
GENTICS_Aloha_base="aloha/aloha/";
loadFile("aloha/aloha/aloha.js", "script", function(data) {
......@@ -53,7 +55,8 @@ var AlohaInterface = function() {
}
var NicEdit = function() {
this.name = "NicEdit";
this.name = "NicEdit"; // name to use in dialog boxes
this.objectName = "NicEdit" // name of the object reference
this.instance = null;
this.load = function() {
var nic = this;
......@@ -75,7 +78,8 @@ var NicEdit = function() {
var TinyEdit = function() {
this.name = "TinyEdit";
this.name = "Tiny"; // name to use in dialog boxes
this.objectName = "TinyEdit" // name of the object reference
this.load = function() {
loadFile("tinyEdit/tinyEdit.js","script",function(data) {
eval(data);
......@@ -114,41 +118,20 @@ var TinyEdit = function() {
/**
* Text documents
*
* editable documents must implements the following arguments and methods
* editable documents must override the following arguments and methods of JSONDocument prototype
* type : a unique type ID
* saveEdition : set the argument as the new content of the document. Change last modification time and display the changes
* setAsCurrentDocument : set the document as currentDocument in the local storage and display its properties in the current page
/**
* class JSONTextDocument
* @param arg : a json JSONTextDocument object to load
*/
var JSONTextDocument = function(arg) {
JSONDocument.call(this,arg);//inherits properties from JSONDocument
if(arg) {this.load(arg);}
else {
this.type = "text";
}
}
JSONTextDocument.prototype = new JSONDocument();//inherits methods from JSONDocument
JSONTextDocument.prototype.saveEdition = function(content) {
JSONDocument.prototype.type = "text";
JSONDocument.prototype.saveEdition = function(content) {
this.setLastUser(getCurrentUser().getName());
this.setContent(content);
this.setLastModification(getCurrentTime());
this.setAsCurrentDocument();
}
JSONTextDocument.prototype.setAsCurrentDocument = function() {
getCurrentPage().displayDocumentTitle(this);
getCurrentPage().displayDocumentState(this);
getCurrentPage().displayDocumentContent(this);
getCurrentPage().displayLastUserName(this);
getCurrentPage().displayLastModification(this);
JSONDocument.prototype.setAsCurrentDocument = function() {
getCurrentPage().displayDocumentInformation(this);
setCurrentDocument(this);
}
getCurrentDocument = function() {
return new JSONTextDocument(JSON.parse(localStorage.getItem("currentDocument")));
}
......@@ -5,85 +5,68 @@
/*
* global variables
*/
applicationID = window.location.href.split("://")[1].split("/")[0];
languages = ["fr","en"];
var availableLanguages = $("#available_languages");
currentPage = null;
currentDocument = null;
currentStorage = null;
applicationID = window.location.href.split("://")[1].split("/")[0]; //should be removed and better implemented
LANGUAGES = ["fr","en"];
/*
* Page Class
* used to decompose the page and give access to useful elements
* @param page : name of the page to be created
* Page
* used to decompose the page and give access to useful elements.
* initialize with Page.initialize(pageName)
* @param pageName : name of the page to be created
*/
var Page = function(page) {
this.name = page;
this.html = window.document;
this.xml = null;
this.editor = null;
//define as current page
currentPage = this;
if(page!="ung" &&page!="mail" && page !=undefined) {this.loadXML("xml/"+page+".xml");}
}
Page.prototype = {
setXML: function(data) {
this.xml = data;
this.loadPage();
var Page = {
initialize: function(page) {
this.name = page;
this.xml = null; //will contain some html elements
this.editor = null; //will contain the editor
//load and include editors to the page
//(could be written better)
if(page!="ung" &&page!="mail" && page !=undefined) {
this.loadXML("xml/"+page+".xml");
} else {
//load the user and the documentList in the page (wait for the storage being ready)
getCurrentStorage().addWaiter(function() {
getCurrentUser().setAsCurrentUser();
getCurrentDocumentList()
},Storage.USER_READY);
}
},
//getters
getName: function() {return this.name;},
getXML: function() {return this.xml;},
getHTML: function() {return this.html;},
getHTML: function() {return window.document;},
getTitle: function() {return $(this.getXML()).find("title").text();},
getContent: function() {return $(this.getXML()).find("content").html();},
getDependencies: function() {return $(this.getXML()).find("dependencies");},
getEditor: function() {return this.editor;},
setEditor: function(editor) {this.editor = editor;},
loadEditor: function() { //load the favourite editor of the user
this.editor = new (getCurrentUser().getSetting("favouriteEditor")[this.getName()])();
},
//loaders
/* load the xml document which contains the web page information */
/* load the xml document which contains the web page information
* and display this information */
loadXML: function(source) {
loadFile(source,"html",function(data) {getCurrentPage().setXML(data);});
var page = this;
loadFile(source,"html",function(data) {
page.xml = data;
this.displayPageinformation();
var dependencies = this.getDependencies();
$(dependencies).find("linkfile").each(function() {page.include($(this).text(),"link");});//includes css
$(dependencies).find("scriptfile").each(function() {page.include($(this).text(),"script");});//includes js
// load the user, the editor and the document in the page (wait for the storage being ready)
getCurrentStorage().addWaiter(function() {
getCurrentUser().setAsCurrentUser();
this.loadEditor();
getCurrentDocument().setAsCurrentDocument();
},Storage.USER_READY);
});
},
/* update the HTML page from the XML document */
loadPage: function() {
//Page content
this.displayPageTitle();
this.displayPageContent();
var dependencies = this.getDependencies();
$(dependencies).find("linkfile").each(function() {currentPage.include($(this).text(),"link");});//includes css
$(dependencies).find("scriptfile").each(function() {currentPage.include($(this).text(),"script");});//includes js
var doc = null;
var editor = null;
/* load the editor to work with and a new document to work on */
switch(this.name) {
case "text-editor":
editor = new Xinha();
doc=new JSONTextDocument();
break;
case "table-editor":
editor = new SheetEditor();
doc=new JSONSheetDocument();
break;
case "image-editor":
editor = new SVGEditor();
doc=new JSONIllustrationDocument();
break;
default://renvoie à la page d'accueil
window.location.href = "ung.html";
return;
break;
}
if(getCurrentDocument()) {doc.load(getCurrentDocument());}
this.setEditor(editor);
doc.setAsCurrentDocument();
},
/* include a javascript or a css file */
include: function(file,type) {
var object = null;
......@@ -101,7 +84,6 @@ Page.prototype = {
object.type = "text/css";
break;
}
var head = $(this.getHTML()).find("head").append(object);
},
......@@ -109,13 +91,29 @@ Page.prototype = {
/* these methods display dynamically information about the page, user or current document
* at the right place on the web page
*/
displayPageInformation: function () {
this.displayPageTitle();
this.displayPageContent();
},
displayUserInformation: function (user) {
this.displayUserName(user);
this.displayLanguages(user);
},
displayDocumentInformation: function (doc) {
this.displayDocumentTitle(doc);
this.displayDocumentState(doc);
this.displayDocumentContent(doc);
this.displayLastModification(doc);
this.displayLastUserName(doc);
},
//user information
/* display the list of availaible languages */
displayLanguages: function(user) {
var avLang = "";
for (var i = 0; i<languages.length; i++) {
var l = languages[i];
for (var i = 0; i<LANGUAGES.length; i++) {
var l = LANGUAGES[i];
if(l==user.getSetting("language")) {$("span#current_language").html(l);}
else {
avLang = avLang + "<li><span onclick='changeLanguage($(this).html())' id='" +l+ "'>"+l+"</span></li>\n"
......@@ -139,8 +137,7 @@ Page.prototype = {
displayPageTitle: function() {$("title#page_title").html(this.getTitle());},
displayPageContent: function() {$("div#page_content").html(this.getContent());}
}
function getCurrentPage() {return currentPage;}
function setCurrentPage(page) {currentPage = page;}
function getCurrentPage() {return Page;}
/*
* User Class
......@@ -159,9 +156,13 @@ var User = function(arg) {
this.settings = {
language: "en",
displayPreferences: 15,//number of displayed document in the list
checkAllMethod: "page"//check only the displayed page
checkAllMethod: "page",//check only the displayed page
favouriteEditor: {
"text-editor": "Xinha",
"table-editor": "SheetEditor",
"image-editor": "SVGEditor"
}
}
this.documents = {};
}
}
User.prototype = new UngObject();//inherits from UngObject
......@@ -177,14 +178,13 @@ User.prototype.load({//add methods thanks to the UngObject.load method
getStorageLocation: function() {return this.storageLocation;},
setAsCurrentUser: function() {
getCurrentPage().displayUserName(this);
getCurrentPage().displayLanguages(this);
getCurrentPage().displayUserInformation(this);
getCurrentStorage().setUser(this);
if(getCurrentPage().getName()=="ung") getDocumentList().setAsCurrentDocumentList();
if(getCurrentPage().getName()=="ung") this.getDocumentList().setAsCurrentDocumentList();
}
});
function getCurrentUser() {
getCurrentUser = function () {
return getCurrentStorage().getUser();
}
......@@ -198,19 +198,59 @@ function getCurrentUser() {
* @param type : "local" to save in localStorage, or "JIO" for remote storage
*/
var Storage = function(type) {
Storage.currentStorage = this;
this.type = type;
this.pendingList = [];
//(re)initialize events
this.userReady = false;
}
Storage.prototype = new UngObject();
Storage.prototype.load({
getType: function() {return this.type;},
getUser: function() {return this.user;},
setUser: function(user) {this.user = user;this.save();},
updateUser: function() {localStorage[this.user.name] = JSON.stringify(this.user);},
setUser: function(user) {
this.user = user;
user.setAsCurrentUser();
this.userName = user.name;
fireEvent(Storage.userReady);
this.save();
},
updateUser: function() {localStorage[this.getUser().getName()] = JSON.stringify(this.getUser());},
save: function() {
this.updateUser();
localStorage.setItem("currentStorage", JSON.stringify(this));
},
addWaiter: function(action, expectedEvent) {
this[expectedEvent] ? action() : this.pendingList.push({action:action,expectedEvent:expectedEvent});
},
fireEvent: function(event) {
for (var i=0; i<this.pendingList.length; i++) {
var waiter = this.pendingList[i];
if(waiter.expectedEvent===event) {
waiter.action.apply(this, waiter.argument);
this.pendingList(i,1);
i--;
}
}
}
});
Storage.initialize = function () {
var dataStorage = JSON.parse(localStorage.getItem("currentStorage"));
if(!dataStorage) {window.location.href = "login.html";}//if it's the first connexion
if(dataStorage.type == "local") {
Storage.currentStorage = new LocalStorage(dataStorage.userName);
} else {
Storage.currentStorage = new JIOStorage(dataStorage);
}
}
Storage.USER_READY = "userReady"; // value of the USER_READY event
getCurrentStorage = function () {
return Storage.currentStorage;
}
/**
* Class LocalStorage
......@@ -223,6 +263,7 @@ var LocalStorage = function(userName) {
if(!loaded) {//create a new user if there was no such one
var user = new User();
user.setName(userName);
user.documents = {};
this.setUser(user);
}
}
......@@ -237,7 +278,7 @@ LocalStorage.prototype.load({
loadUser: function(userName) {
try{
if(!localStorage[userName]) {throw "noSuchUser";}
this.user = new User(JSON.parse(localStorage[userName]));
this.setUser(new User(JSON.parse(localStorage[userName])));
return true;
} catch(e) {
if(e!="noSuchUser") {alert(e);}
......@@ -245,10 +286,13 @@ LocalStorage.prototype.load({
}
},
getDocument: function(file, instruction) {
var doc = new JSONDocument(this.user.documents[file]);
var doc = new JSONDocument(this.getUser().documents[file]);
if(instruction) instruction(doc);
return doc;
},
getDocumentList: function() {
return this.getUser().getDocumentList();
},
saveDocument: function(doc, file, instruction) {
this.user.documents[file] = doc;
this.save();
......@@ -270,20 +314,22 @@ var JIOStorage = function(arg) {
Storage.call(this,"JIO");
if(arg.jio && arg.jio.jioFileContent) {
//recreate the storage from the localStorage (arg = localStorage.currentStorage)
this.jio = JIO.initialize(arg.jio.jioFileContent, {"ID":"www.ungproject.com"});
this.user = new User(arg.user);
this.setUser(new User(arg.user));
waitBeforeSucceed(JIO.isReady,this.save);
} else {
//load jio from the dav storage
this.jio = initializeFromDav(arg.userName, arg.storageLocation, {"ID":"www.ungproject.com", "password":arg.applicationPassword});
//try to load user parameters
var storage = this;
JIO.loadDocument(arg.userName+".profile","text",
function(data) {//success
var option = {
success: function(data) {//success
storage.setUser(new User(JSON.parse(data)));
storage.user.storageLocation = arg.storageLocation;
storage.save()
storage.save();
},
function(errorEvent) {//fail
errorHandler: 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);
......@@ -291,12 +337,15 @@ var JIOStorage = function(arg) {
storage.user.storageLocation = arg.storageLocation;
storage.save();
}
}
,false);
},
asynchronous: false
}
JIO.loadDocument(arg.userName+".profile", option);
}
/**
* load JIO file from a DAV and create and return the JIO object
* This function will be replaced. The aim is to load JIO in more various ways, and use JIO.initialize after
* @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)
......@@ -318,59 +367,51 @@ var JIOStorage = function(arg) {
});
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){}}
);
var storage = this;
var option = {
success: function(data) {storage.setUser(new User(JSON.parse(data)));},
errorHandler: function(errorEvent) {if(errorEvent.status==404){}}
}
JIO.loadDocument(userName+".profile", option);
},
getDocument: function(file, instruction) {
JIO.loadDocument(file, "text", function(content) {
getDocument: function(fileName, instruction) {
var option = {
success:function(content) {
var doc = new JSONDocument(JSON.parse(content));
if(instruction) instruction(doc);
});
}
};
JIO.loadDocument(fileName, option);
},
saveDocument: function(doc, file, instruction) {
JIO.saveDocument(JSON.stringify(doc), file, "text", true, instruction)
saveDocument: function(doc, fileName, instruction) {
var metaData = doc.copy();
delete metaData.content;
var option = {
success: instruction,
metaData: metaData
};
JIO.saveDocument(JSON.stringify(doc), fileName, option);
},
deleteDocument: function(file, instruction) {
JIO.deleteDocument(file, instruction)
},
getDocumentList: function(instruction) {
var list = JIO.getDocumentList(instruction, undefined, false);//synchrone operation. Could be asynchronised
delete list[this.userName+".profile"];
return list;
var option = {option: {success: instruction}};
JIO.deleteDocument(file, option);
},
save: function() {
this.updateUser();
this.saveDocument(this.user,this.user.getName()+".profile",function() {});
localStorage.setItem("currentStorage",JSON.stringify(this));
this.saveDocument(this.user,this.user.getName()+".profile",function() {
localStorage.setItem("currentStorage",JSON.stringify(this));
});
}
});
function getCurrentStorage() {
if(currentStorage) {return currentStorage;}
var dataStorage = JSON.parse(localStorage.getItem("currentStorage"));
});
if(!dataStorage) {window.location.href = "login.html";return null;}//if it's the first connexion
if(dataStorage.type == "local") {
currentStorage = new LocalStorage(dataStorage.userName);
} else {
if(!JIO.jioFileContent) {JIO.initialize(dataStorage.jio.jioFileContent, {"ID":"www.ungproject.com"})}
currentStorage = new JIOStorage(dataStorage);
}
return currentStorage;
}
function setCurrentStorage(storage) {
currentStorage = storage;
localStorage.setItem("currentStorage", JSON.stringify(storage));
}
......@@ -384,6 +425,65 @@ function setCurrentStorage(storage) {
* to manipulate these elements.
*/
var Document = {
/**
* save document modification
*/
saveCurrentDocument: function() {
getCurrentPage().getEditor().saveEdition();
getCurrentDocument().save();
},
/**
* start an editor to edit the document
* @param doc : the document to edit
*/
startDocumentEdition: function(doc) {
getCurrentStorage().getDocument(doc.fileName, function(data) {
this.setCurrentDocument(data);
if(Document.supportedDocuments[data.getType()].editorPage) {window.location.href = "theme.html";}
else alert("no editor available for this document");
});
},
/**
* save document modification and go back to the documentList
*/
stopDocumentEdition: function() {
this.saveCurrentDocument();
window.location.href = "ung.html";
return false;
},
/**
* list of supported document types and the editor and icon linked to each type
*/
supportedDocuments: {
"text":{editorPage:"text-editor",icon:"images/icons/document.png"},
"illustration":{editorPage:"image-editor",icon:"images/icons/svg.png"},
"table":{editorPage:"table-editor",icon:"images/icons/table.png"},
"other":{editorPage:null,icon:"images/icons/other.gif"},
undefined:{editorPage:null,icon:"images/icons/other.gif"}
},
/**
* generate a unique name for the document
*/
getAddress: function(doc) {
return doc.getCreation();
}
}
getCurrentDocument = function() {
if(!Document.currentDocument) {
Document.currentDocument = new JSONDocument(JSON.parse(localStorage.getItem("currentDocument")));
}
return Document.currentDocument;
}
setCurrentDocument = function(doc) {
localStorage.setItem("currentDocument",JSON.stringify(doc));
this.currentDocument = doc;
}
/**
* JSON document
* @param arg : a json JSONDocument object to load
......@@ -453,10 +553,10 @@ JSONDocument.prototype.load({//add methods thanks to the UngObject.load method
},
save: function(instruction) {//save the document
var doc = this;
getCurrentStorage().saveDocument(doc, getDocumentAddress(this), instruction);
getCurrentStorage().saveDocument(doc, Document.getAddress(this), instruction);
},
remove: function(instruction) {//remove the document
getCurrentStorage().deleteDocument(getDocumentAddress(this), instruction);
getCurrentStorage().deleteDocument(Document.getAddress(this), instruction);
}
});
JSONDocument.prototype.states = {
......@@ -464,12 +564,7 @@ JSONDocument.prototype.states = {
saved:{"fr":"Enregistré","en":"Saved"},
deleted:{"fr":"Supprimé","en":"Deleted"}
}
getCurrentDocument = function() {
if(!currentDocument) {
currentDocument = new JSONDocument(JSON.parse(localStorage.getItem("currentDocument")));
}
return currentDocument;
}
setCurrentDocument = function(doc) {
currentDocument = doc;
localStorage.setItem("currentDocument",JSON.stringify(doc));
......@@ -480,24 +575,42 @@ setCurrentDocument = function(doc) {
supportedDocuments = {"text":{editorPage:"text-editor",icon:"images/icons/document.png"},
"illustration":{editorPage:"image-editor",icon:"images/icons/svg.png"},
"table":{editorPage:"table-editor",icon:"images/icons/table.png"},
"other":{editorPage:null,icon:"images/icons/other.gif"},
undefined:{editorPage:null,icon:"images/icons/other.gif"}
}
getDocumentAddress = function(doc) {
return doc.getCreation();
}
/*************************************************
****************** actions ******************
*************************************************/
/**
* change the language of the user and reload the web page
* @param language : the new language
*/
var changeLanguage = function(language) {
getCurrentUser().setSetting("language",language);
getCurrentStorage().save();
getCurrentPage().displayLanguages(getCurrentUser());
window.location.reload();
}
var signOut = function() {
delete localStorage.currentStorage;
delete localStorage.currentDocumentID;
delete localStorage.wallet;
delete sessionStorage.documentList;
window.location.href = "login.html";
return false
}
cancel_sharing = function() {alert("cancel");}
translate = function() {alert("translate");}
submit = function() {alert("submit");}
share = function() {alert("share");}
/**
* open a dialog box to edit document information
*/
editDocumentSettings = function() {
saveCurrentDocument();
Document.saveCurrentDocument();
loadFile("xml/xmlElements.xml", "html", function(data) {
$("rename", data).dialog({
autoOpen: true,
......@@ -510,7 +623,7 @@ editDocumentSettings = function() {
doc.setTitle($(this).find("#name").attr("value"));
doc.setLanguage($(getCurrentDocument()).find("#language").attr("value"));
doc.setVersion($(getCurrentDocument()).find("#version").attr("value"));
saveCurrentDocument();
Document.saveCurrentDocument();
doc.setAsCurrentDocument();//diplay modifications
$(this).dialog("close");
},
......@@ -550,7 +663,7 @@ editDocumentSettings = function() {
* open a dialog box to upload a document
*/
uploadDocument = function() {
loadFile("xml/xmlElements.xml", "html", function(data) {
loadFile("xml/xmlElements.xml", "html", function(data) { //load the upload form
$("upload", data).dialog({
autoOpen: false,
height: 116,
......@@ -614,52 +727,4 @@ editUserSettings = function() {
}
}
});
}
saveCurrentDocument = function() {
getCurrentPage().getEditor().saveEdition();
getCurrentDocument().save();
}
/**
* start an editor to edit the document
* @param doc : the document to edit
*/
var startDocumentEdition = function(doc) {
getCurrentStorage().getDocument(doc.fileName, function(data) {
setCurrentDocument(data);
if(supportedDocuments[data.getType()].editorPage) {window.location.href = "theme.html";}
else alert("no editor available for this document");
});
}
var stopDocumentEdition = function() {
saveCurrentDocument();
window.location.href = "ung.html";
return false;
}
/**
* change the language of the user and reload the web page
* @param language : the new language
*/
var changeLanguage = function(language) {
getCurrentUser().setSetting("language",language);
getCurrentStorage().save();
getCurrentPage().displayLanguages(getCurrentUser());
window.location.reload();
}
var signOut = function() {
delete localStorage.currentStorage;
delete localStorage.currentDocumentID;
delete localStorage.wallet;
delete sessionStorage.documentList;
window.location.href = "login.html";
return false
}
cancel_sharing = function() {alert("cancel");}
translate = function() {alert("translate");}
submit = function() {alert("submit");}
share = function() {alert("share");}
}
\ No newline at end of file
......@@ -29,7 +29,8 @@ UngObject.prototype.load = function(data) {
};
/* Load methods from a class to another class */
UngObject.prototype.inherits = function(superClass) {
UngObject.prototype.inherits = function(superClass,arg) {
superClass.call(this,arg);//or this.load(new superClass(arg));
this.prototype.load(superClass.prototype);
}
......@@ -44,7 +45,7 @@ UngObject.prototype.equals = function(object) {
return true;
}
/* return a copy of the current object */
/* return a deep copy of the current object */
UngObject.prototype.copy = function() {
var copied = new Object();
for (var property in this) {
......@@ -53,123 +54,17 @@ UngObject.prototype.copy = function() {
return copied;
}
/**
* Class List
* this class provides usual API to manipulate list structure
* @param arg : a json list object
* @param contentType : the type of the elements of the list
* convert an object into an array easier to manipulate
* @param object : the object to convert
*/
var List = function(arg, contentType) {
if(arg && arg.headElement) {
if(contentType) {
this.headElement=new contentType(arg.headElement);
} else {
this.headElement = arg.headElement;
}
this.length = arg.length;
this.previous = new List(arg.previous, contentType);
}
else {
this.nullElement();
toArray = function(object) {
var array = [];
for(var element in object) {
if(typeof element != "function") array.push(object[element]);
}
return array
}
List.prototype = new UngObject();
List.prototype.load({
nullElement: function() {
this.headElement = null;
this.previous = undefined;
this.length = 0;
},
size: function() {return this.length;},
head: function() {return this.headElement;},
tail: function() {return this.previous;},
isEmpty: function() {return this.head()===null;},
equals: function(list) {
return this.head().equals(list.head()) && this.tail().equals(list.tail());
},
add: function(value) {
var t = new List();
t.load(this);
this.headElement = value;
this.previous = t;
this.length = t.size()+1;
},
get: function(i) {
if(i>=this.size()) {return null;}
if(i==0) {return this.head();}
return this.tail().get(i-1);
},
set: function(i,element) {
if(i>=this.size()) {errorMessage("set out of bounds, "+i+" : "+this.size(),this);return}
if(i==0) {
this.headElement=element;
} else {
this.tail().set(i-1,element);
}
},
remove: function(i) {
if(i>=this.size()) {errorMessage("remove out of bounds, "+i+" : "+this.size(),this);return}//particular case
if(i==0) {this.pop();return}//particular case
if(i==1) {//init
this.previous = this.tail().tail();
} else {//recursion
this.tail().remove(i-1);
}
this.length--;
},
pop: function() {
if(this.isEmpty()) {errorMessage("pop on empty list",this);return null;}
var h = this.head();
this.load(this.tail())
return h;
},
find: function(object) {
if(this.isEmpty()) {return -1}//init-false
var elt = this.head();
if(object.equals) {//init-true
if(object.equals(this.head())) {return 0;}//with an adapted comparator
} else {
if(object===this.head()) {return 0;}//with usual comparator
}
var recursiveResult = this.tail().find(object);//recursion
return recursiveResult>=0 ? this.tail().find(object)+1 : recursiveResult;
},
contains: function(object) {if(this.isEmpty()) {return false} else {return object===this.head() ? true : this.tail().contains(object)}},
insert: function(element,i) {
if(i>this.size()) {errorMessage("insert out of bounds, "+i+" : "+this.size(),this);return}//particular case
if(i==0) {//init
this.add(element);
} else {//recursion
this.tail().insert(element,i-1);
this.length++;
}
},
replace: function(oldElement,newElement) {
if(this.isEmpty()) {errorMessage("<<element not found>> when trying to replace",this);return}//init-false
if(oldElement===this.head()) {
this.set(0,newElement);//init-true
} else {
this.tail().replace(oldElement,newElement);//recursion
}
},
removeElement: function(element) {//remove each occurence of the element in this list
if(this.isEmpty()) {return}
this.tail().removeElement(element);
if(element.equals) {//init-true
if(element.equals(this.head())) {this.pop();}//with an adapted comparator
} else {
if(element===this.head()) {this.pop();}//with usual comparator
}
},
concat: function(list) {
if(list.size()==0) {return this}
var l1 = this.copy();
var l2 = list.copy();
l1.add(l2.get(l2.size()-1));
return l2;
}
});
/**
* load a public file with a basic ajax request
......@@ -184,7 +79,6 @@ loadFile = function(address, type, instruction) {
dataType: type,
success: instruction,
error: function(type) {alert("Error "+type.status+" : fail while trying to load "+address);}
});
}
......@@ -195,14 +89,16 @@ loadFile = function(address, type, instruction) {
*/
waitBeforeSucceed = function(required, func) {
var nb = 2;//avoid to test too much times
var execute = function() {
(function execute() {
try {
if(!required.call()) {throw 0;}
func.call();}
catch(e) {console.log(e);if(nb<100) {setTimeout(execute,nb*100);}}
catch(e) {
if(console) {console.log(e)}
if(nb<100) {setTimeout(execute,nb*100);}
}
nb*=nb;
}
execute();
})()
}
/*
......@@ -211,12 +107,27 @@ waitBeforeSucceed = function(required, func) {
*/
tryUntilSucceed = function(func) {
var nb = 2;//avoid to test too much times
var execute = function() {
(function execute() {
try {func.call();}
catch(e) {if(nb<100) {setTimeout(execute,nb*200);}console.log(e);}
catch(e) {
if(console) {console.log(e)}
if(nb<100) {setTimeout(execute,nb*200);}
}
nb*=nb;
}
execute();
})()
}
/**
* call a function periodically. Usefull for checking some stuff regularly
* @param task : function to execute each period
* @param period : time to wait before next execution
* @param firstExecution : (optional) if set to false, the task will not be executed at first call
*/
recursiveTask = function(task,period,firstExecution) {
if(firstExecution!==false) {task.call()}
(function recursion() {
setTimeout(function() {task.call();recursion()},period);
})();
}
/**
......@@ -232,7 +143,7 @@ var resize = function() {
*/
errorMessage = function(message,object) {
errorObject = object;
console.log(message);
if(console) {console.log(message)}
}
/**
......@@ -241,7 +152,15 @@ errorMessage = function(message,object) {
function getCurrentTime() {return Date.now();}
/**
* Paste a toolkit at the mouse position
* Paste a toolkit at the mouse position.
* Just add a common css class to your element needing a tooltip, and initialize with :
tooltip = new Tooltip();
$(".myTooltipClass")
.mouseover(function() {tooltip.show("my tooltip text")})
.mouseout(function() {tooltip.hide();})
.mousemove(function(event) {tooltip.move(event);});
*/
Tooltip = function() {
this.visible=false;
......
......@@ -15,32 +15,38 @@ setCurrentDocumentID = function(ID) {return localStorage.setItem("currentDocumen
* @param documentList : documents information loaded from the storage
*/
var DocumentList = function(documentList) {
if(sessionStorage.documentList) {//load from sessionStorage
this.load(JSON.parse(sessionStorage.documentList));
this.detailedList = {}
if(documentList) {
for(var doc in documentList) {
this.detailedList[doc] = new JSONDocument(documentList[doc]);
}
}
else {
if(documentList) {
for(var doc in documentList) {
this.documentList[doc] = new JSONDocument(documentList[doc]);
this.displayInformation = {};
this.displayInformation.page = 1;
this.selectionList = [];
//check the user document list on the remote storage every 10 seconds
var list = this;
var updateDocumentList = function () {
JIO.getDocumentList({
success: function(data) {
list.detailedList = data;
}
} else {this.documentList = {}}
this.list = getCurrentStorage().getDocumentList();
this.displayInformation = {};
this.displayInformation.page = 1;
this.selectionList = [];
});
}
recursiveTask(function() {if(JIO.isReady()){updateDocumentList()}},10000);
}
DocumentList.prototype = new UngObject();
DocumentList.prototype.load({
removeDocument: function(fileName) {
getCurrentStorage().remove(fileName)//delete the file
delete this.list[fileName];//remove from the list
delete this.detailedList[fileName];//
this.save();//save changes
},
getList: function() {return this.list},
get: function(fileName) {return this.getDetailedList()[fileName]},
getList: function() {return getCurrentStorage().getDocumentList();},
getDetailedList: function() {return this.detailedList},
getSelectionList: function() {return this.selectionList;},
resetSelectionList: function() {
......@@ -70,7 +76,7 @@ DocumentList.prototype.load({
for(i=this.getDisplayInformation().first-1; i<this.getDisplayInformation().last; i++) {
$("tr td.listbox-table-select-cell input#"+i).attr("checked",true);//check
}
$("span#selected_row_number a").html(this.size());//display the selected row number
$("span#selected_row_number a").html(list.length);//display the selected row number
},
addToSelection: function(fileName) {
this.getSelectionList().push(fileName);
......@@ -108,27 +114,35 @@ DocumentList.prototype.load({
},
/* display the list of documents in the web page */
displayContent: function() {//display the list of document itself
displayContent: function(list) {//display the list of document itself
$("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++) {
var fileName = list[i].fileName;
if(!detailedList[fileName] || new Date(detailedList[fileName].lastModification+1000)<new Date(list[i].lastModify)) {updateDocumentInformation(fileName)}
var line = new Line(doc,i);
line.updateHTML();
line.display();
if(this.getSelectionList().indexOf(doc.fileName)) {line.setSelected(true);}//check the box if selected
var doc = detailedList[fileName];
var documentList = this;
(function tryToDisplay(j) {//update document information before displaying
if(!doc || new Date(detailedList[fileName].lastModification+1000)<new Date(list[j].lastModify)) {
documentList.updateDocumentInformation(fileName);
setTimeout(function(){tryToDisplay.call(this,j)},500);
} else {
var line = new Line(doc,j);
line.updateHTML();
line.display();
if(this.getSelectionList().indexOf(doc.fileName)) {line.setSelected(true);}//check the box if selected
}
})(i)
}
},
displayListInformation: function() {//display number of records, first displayed document, last displayed document...
if(this.size()>0) {
displayListInformation: function(list) {//display number of records, first displayed document, last displayed document...
if(list.length>0) {
$("div.listbox-number-of-records").css("display","inline");
$("span#page_start_number").html(this.getDisplayInformation().first);
$("span#page_stop_number").html(this.getDisplayInformation().last);
$("span#total_row_number a").html(this.size());
$("span#selected_row_number a").html(this.getSelectionList().size());
$("span#total_row_number a").html(list.length);
$("span#selected_row_number a").html(this.getSelectionList().length);
}
else {$("div.listbox-number-of-records").css("display","none");}
},
......@@ -141,7 +155,7 @@ DocumentList.prototype.load({
if(lastPage>1) {
$("div.listbox-navigation input.listbox_set_page").attr("value",this.getDisplayedPage());
$("div.listbox-navigation span.listbox_last_page").html(lastPage);
disp("div.listbox-navigation button.listbox_first_page",this.getDisplayedPage()>1);
disp("div.listbox-navigation button.listbox_previous_page",this.getDisplayedPage()>1);
disp("div.listbox-navigation button.listbox_next_page",this.getDisplayedPage()<lastPage);
......@@ -149,9 +163,10 @@ DocumentList.prototype.load({
}
},
display: function() {
this.updateDisplayInformation();
this.displayContent();
this.displayListInformation();
var list = toArray(this.getList());
this.updateDisplayInformation(list);
this.displayContent(list);
this.displayListInformation(list);
this.displayNavigationElements();
},
......@@ -165,12 +180,12 @@ DocumentList.prototype.load({
});
},
/* update the document to be displayed */
updateDisplayInformation: function() {
updateDisplayInformation: function(list) {
var infos = this.getDisplayInformation();
infos.step = getCurrentUser().getSetting("displayPreferences"),//documents per page
infos.first = (infos.page-1)*infos.step + 1,//number of the first displayed document
infos.last = (this.size()<(infos.first+infos.step)) ? this.size() : infos.first+infos.step-1//number of the last displayed document
infos.lastPage = Math.ceil(this.size()/infos.step);
infos.last = list.length<(infos.first+infos.step) ? list.length : (infos.first+infos.step-1);//number of the last displayed document
infos.lastPage = Math.ceil(list.length/infos.step);
},
setAsCurrentDocumentList: function() {
......@@ -182,6 +197,8 @@ getDocumentList = function() {
}
/**
* create a line representing a document in the main table
* @param doc : document to represent
......@@ -228,11 +245,11 @@ Line.prototype = {
.find("td.listbox-table-data-cell")
.click(function() {//clic on a line
setCurrentDocumentID(line.getID());
startDocumentEdition(line.getDocument())
Document.startDocumentEdition(line.getDocument())
})
.find("a.listbox-document-icon")
.find("img")
.attr("src",supportedDocuments[this.getType()].icon)//icon
.attr("src",Document.supportedDocuments[this.getType()].icon)//icon
.end()
.end()
.find("a.listbox-document-title").html(this.getDocument().getTitle()).end()
......@@ -243,9 +260,12 @@ Line.prototype = {
/* add the line in the table */
display: function() {$("table.listbox tbody").append($(this.getHTML()));}
}
/* load the html code of a default line */
Line.loadHTML = function() {
loadFile("xml/xmlElements.xml", "html", function(data) {Line.originalHTML = $(data).find("line table tbody").html();});
/* load the html code of a default line and execute the callback */
Line.loadHTML = function(callback) {
loadFile("xml/xmlElements.xml", "html", function(data) {
Line.originalHTML = $(data).find("line table tbody").html();
callback(Line.getOriginalHTML());
});
return Line.originalHTML;
}
/* return the html code of a default line */
......@@ -262,10 +282,11 @@ Line.getOriginalHTML = function() {return Line.originalHTML;}
var createNewDocument = function(type) {
var newDocument = new JSONDocument();
newDocument.setType(type);
var fileName = DOcument.getAddress(newDocument);
newDocument.save(function() {
getDocumentList().add(newDocument);
getDocumentList()[fileName]=newDocument;
getCurrentStorage().save();
startDocumentEdition(newDocument);
Document.startDocumentEdition(newDocument);
});
}
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