Commit b489e3c5 authored by François Billioud's avatar François Billioud

implement multi-user and multi-storage

parent 3f423885
...@@ -215,7 +215,7 @@ div.header-right div.input a { ...@@ -215,7 +215,7 @@ div.header-right div.input a {
border: 1px solid #D1D1D1; border: 1px solid #D1D1D1;
display: none; display: none;
} }
.action_menu ul li ul hover { .action_menu ul li ul:hover {
display: block; display: block;
} }
.action_menu ul li ul li:hover { .action_menu ul li ul li:hover {
...@@ -330,7 +330,7 @@ div.gadget-action input#upload { ...@@ -330,7 +330,7 @@ div.gadget-action input#upload {
border: 1px solid #BBBBBB; border: 1px solid #BBBBBB;
border-radius: 4px 4px 4px 4px; border-radius: 4px 4px 4px 4px;
color: #333333; color: #333333;
left: 1em; left: 0.5em;
position: relative; position: relative;
top: 0.1em; top: 0.1em;
} }
...@@ -409,12 +409,46 @@ button.delete { ...@@ -409,12 +409,46 @@ button.delete {
margin-left: 6px; margin-left: 6px;
margin-top: 6px; margin-top: 6px;
} }
/* navigation buttons */
div.listbox-navigation { div.listbox-navigation {
float: right; float: right;
font-size: 13px; font-size: 13px;
margin-right: 5px; margin-right: 5px;
margin-top: 6px; margin-top: 0;
min-width: 10%; min-width: 10%;
display: none;
}
div.listbox-navigation input {
margin-top: 0.3em;
height: 18px;
width: 20px;
}
div.listbox-navigation button.listbox_first_page {
background-image: url("../images/ung/first_page.png");
}
div.listbox-navigation button.listbox_previous_page {
background-image: url("../images/ung/previous_page.png");
}
div.listbox-navigation button.listbox_next_page {
background-image: url("../images/ung/next_page.png");
}
div.listbox-navigation button.listbox_last_page {
background-image: url("../images/ung/last_page.png");
}
div.listbox-navigation button.listbox_previous_page, div.listbox-navigation button.listbox_next_page {
margin: 0;
width: 12px;
}
div.listbox-navigation button {
position: relative;
top: -0.2em;
background-repeat: no-repeat;
border: 0 none;
height: 20px;
display: none;
}
div.listbox-navigation button:hover {
cursor: pointer;
} }
/* header */ /* header */
...@@ -558,6 +592,10 @@ div#advertisement img{ ...@@ -558,6 +592,10 @@ div#advertisement img{
height: 10em; height: 10em;
} }
/* login table */ /* login table */
span#id_provider_details {
font-size: 8px;
float: left;
}
table#field_table, table#new-account-table, table#create-new-user { table#field_table, table#new-account-table, table#create-new-user {
border: 1px solid #C3D9FF; border: 1px solid #C3D9FF;
width: 78%; width: 78%;
...@@ -606,6 +644,23 @@ div.footer a { ...@@ -606,6 +644,23 @@ div.footer a {
margin-right: 0.5em; margin-right: 0.5em;
} }
/**********************************************************
******************** tooltip area *********************/
span.tooltipElement {
cursor: pointer;
color: #0099CC;
}
div.toolLocation{
visibility: hidden;
position: absolute;
border-radius: 10px 10px 10px 10px;
border: 1px solid Black;
padding: 10px;
font-family: Verdana, Arial;
font-size: 10px;
background-color: #FFFFCC;
}
/********************************************************** /**********************************************************
******************* dialog box ************************/ ******************* dialog box ************************/
div.ui-dialog { div.ui-dialog {
...@@ -624,9 +679,6 @@ div.ui-dialog-titlebar { ...@@ -624,9 +679,6 @@ div.ui-dialog-titlebar {
border-radius: 1px 1px 1px 1px; border-radius: 1px 1px 1px 1px;
height: 15px; height: 15px;
} }
div.ui-dialog-titlebar {
height: 15px;
}
span#ui-dialog-title-edit_document, span#ui-dialog-title-upload_document, span#ui-dialog-title-gadget-listbox { span#ui-dialog-title-edit_document, span#ui-dialog-title-upload_document, span#ui-dialog-title-gadget-listbox {
color: #222222 !important; color: #222222 !important;
font: bold 12pt Arial,Sans-serif; font: bold 12pt Arial,Sans-serif;
...@@ -658,4 +710,4 @@ div#edit_document { ...@@ -658,4 +710,4 @@ div#edit_document {
} }
span.ui-button-text { span.ui-button-text {
font-size: 12px; font-size: 12px;
} }
\ No newline at end of file
* Decision of JS pattern used for Prototypical Inheritance
* Desicion: Why meta-data should be inside the data of the file
** I had two choices about meta data:
*** Let the meta-data stay inside the data itself i.e. your data on file will contain the meta data too.
**** Advantage is that the ability to store meta-data is not needed or is dependednt on the type of storage
**** We have more control over the meta data and how it is interfaced.
**** Thus, currently meta-data in DAV is stored along with data, this way the hash returns the sum of both meta-data and data
**** This might be desirable or undesirable but good thing is that decision is in our hand
**** Other software must know how JIO stores the meta-data
*** Let the meta-data be separate from the data so that the server can take care of meta-data in meaningful way
**** This way, meta-data interface has to be written for every backend separately
**** We just work on the data, the hash is returned for only the data part. encryption (or other transformations) are done for only the data part
**** Many backend like ObjStore won't have meta-data handling in an intutive way
**** server will handle the meta-data
**** This facilitates JIO interaction with other services (eg: in Google Doc, if you use its API to do the meta-data, even Google Doc can use that information)
*** Decision
Meta-data with file data for now. Since JIO is open standard, we will publish our meta-data storing syntax. This way JIO can be used uniformally on All backends
The consequence of this is that we don't see meta-data as a different data, it is part of the document
* Object based Storage
** The basic idea is to let a object represent the entire tree of the
virtual file system
** The such objects can be nested inside each other. Hence to create
an entire filesystem is possible.
** Each object can be either a document (as are files in Unix) or a
collection (as are directory in Unix)
** We can then encapsulate the entire filesystem tree in as a single
object.
** The good part is that we can run JSON stringify on this object to
convert it into pure string and thus serialize it.
** The design should be such that these objects must be pluggable
inside other objects.
** Should be able to store Metadata
** Design
*** Each Object contain two basic information : doc_id, content
*** doc_id is basically the name of the resource (resource is a general term used for a collection or a document)
*** In a given collection, all the containing collections and document should have unique doc_id (i.e. you can't have a collection and a document named `foo' inside on collection)
*** Identification of if the resource is a collection or document is done by noting the type of the content, if it is an array, then the given resource is a collection, document otherwise
*** Any resource is identified by it's doc_id and parent object (or parent's doc_id, which itself is identified by using its parents doc_id)
***
** If the loadDocument requests a directory, (aka collection), return the hash is the sum of all the content inside that collection and let the data be an array with the docid of all the child documents.
** Implementing
** Current implmentation doesn't enjoy much of code-reuse, I think I can use more inheritance core-reuse, will have to refactor the code. But the basic design of JIO will facilitate that
...@@ -9,6 +9,8 @@ languages = ["fr","en"]; ...@@ -9,6 +9,8 @@ languages = ["fr","en"];
var availableLanguages = $("#available_languages"); var availableLanguages = $("#available_languages");
currentPage = null; currentPage = null;
currentDocument = null;
currentStorage = null;
/* /*
...@@ -23,7 +25,7 @@ var Page = function(page) { ...@@ -23,7 +25,7 @@ var Page = function(page) {
this.editor = null; this.editor = null;
//define as current page //define as current page
currentPage = this; currentPage = this;
if(page!=undefined) {this.loadXML("xml/"+page+".xml");} if(page!="ung" && page !=undefined) {this.loadXML("xml/"+page+".xml");}
} }
Page.prototype = { Page.prototype = {
setXML: function(data) { setXML: function(data) {
...@@ -31,6 +33,7 @@ Page.prototype = { ...@@ -31,6 +33,7 @@ Page.prototype = {
this.loadPage(); this.loadPage();
}, },
//getters //getters
getName: function() {return this.name;},
getXML: function() {return this.xml;}, getXML: function() {return this.xml;},
getHTML: function() {return this.html;}, getHTML: function() {return this.html;},
getTitle: function() {return $(this.getXML()).find("title").text();}, getTitle: function() {return $(this.getXML()).find("title").text();},
...@@ -52,7 +55,7 @@ Page.prototype = { ...@@ -52,7 +55,7 @@ Page.prototype = {
var dependencies = this.getDependencies(); var dependencies = this.getDependencies();
$(dependencies).find("linkfile").each(function() {currentPage.include($(this).text(),"link");});//includes css $(dependencies).find("linkfile").each(function() {currentPage.include($(this).text(),"link");});//includes css
$(dependencies).find("scriptfile").each(function() {currentPage.include($(this).text(),"script");});//includes js $(dependencies).find("scriptfile").each(function() {currentPage.include($(this).text(),"script");});//includes js
var doc = null; var doc = null;
var editor = null; var editor = null;
/* load the editor to work with and a new document to work on */ /* load the editor to work with and a new document to work on */
...@@ -112,7 +115,7 @@ Page.prototype = { ...@@ -112,7 +115,7 @@ Page.prototype = {
for (var i = 0; i<languages.length; i++) { for (var i = 0; i<languages.length; i++) {
var l = languages[i]; var l = languages[i];
if(l==user.getLanguage()) {$("span#current_language").html(l);} if(l==user.getSetting("language")) {$("span#current_language").html(l);}
else { else {
avLang = avLang + "<li><span onclick='changeLanguage($(this).html())' id='" +l+ "'>"+l+"</span></li>\n" avLang = avLang + "<li><span onclick='changeLanguage($(this).html())' id='" +l+ "'>"+l+"</span></li>\n"
} }
...@@ -129,7 +132,7 @@ Page.prototype = { ...@@ -129,7 +132,7 @@ Page.prototype = {
$("a#document_title").html(title); $("a#document_title").html(title);
}, },
displayDocumentContent: function(doc) {this.getEditor().loadContentFromDocument(doc);}, displayDocumentContent: function(doc) {this.getEditor().loadContentFromDocument(doc);},
displayDocumentState: function(doc) {$("a#document_state").html(doc.getState()[getCurrentUser().getLanguage()]);}, displayDocumentState: function(doc) {$("a#document_state").html(doc.getState()[getCurrentUser().getSetting("language")]);},
//web page information //web page information
displayPageTitle: function() {$("title#page_title").html(this.getTitle());}, displayPageTitle: function() {$("title#page_title").html(this.getTitle());},
...@@ -144,39 +147,205 @@ setCurrentPage = function(page) {currentPage = page;} ...@@ -144,39 +147,205 @@ setCurrentPage = function(page) {currentPage = page;}
* @param arg : a json User object to load * @param arg : a json User object to load
*/ */
var User = function(arg) { var User = function(arg) {
if(arg) {this.load(arg);} if(arg) {
this.load(arg);
if(window.DocumentList) {this.documentList = new DocumentList(arg.documentList);}
}
else { else {
this.name = "unknown"; this.name = "UNG";//default name
this.language = "en"; this.settings = {
this.storage = "http://www.unhosted-dav.com"; language: "en",
this.identityProvider = "http://www.webfinger.com"; displayPreferences: 15//number of displayed document in the list
this.displayPreferences = 15;//number of displayed document in the list }
this.documentList = new DocumentList();
this.documents = {};
} }
} }
User.prototype = new UngObject();//inherits from UngObject User.prototype = new UngObject();//inherits from UngObject
User.prototype.load({//add methods thanks to the UngObject.load method 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;},
getLanguage: function() {return this.language;}, getSetting: function(key) {return this.settings[key];},
setLanguage:function(language) {this.language = language;}, setSetting: function(key,value) { this.settings[key] = value; },
getStorageLocation: function() {return this.storage;}, getSettings: function() {return this.settings;},
setStorageLocation: function(storage) {this.storage = storage;}, getDocumentList: function() {return this.documentList;},
getIdentityProvider: function() {return this.identityProvider;}, setDocumentList: function(list) {this.documentList = list;},
setIdentityProvider: function(IDProv) {this.identityProvider = IDProv;},
getDisplayPreferences: function() {return this.displayPreferences;},
setDisplayPreferences: function(n) {this.displayPreferences = n;},
setAsCurrentUser: function() { setAsCurrentUser: function() {
getCurrentPage().displayUserName(this); getCurrentPage().displayUserName(this);
getCurrentPage().displayLanguages(this); getCurrentPage().displayLanguages(this);
setCurrentUser(this); getCurrentStorage().setUser(this);
if(getCurrentPage().getName()=="ung") getDocumentList().setAsCurrentDocumentList();
} }
}); });
getCurrentUser = function() { getCurrentUser = function() {
return new User(JSON.parse(localStorage.getItem("currentUser"))); return getCurrentStorage().getUser();
}
/**
* Class Storage
* this class provides usual API to save/load/delete documents
* @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) {
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.load({
getType: function() {return this.type;},
getUser: function() {return this.user;},
loadUser: function(userName) {},
setUser: function(user) {this.user = user},
getDocument: function(address, instruction) {},
saveDocument: function(doc, address, instruction) {},
deleteDocument: function(address, instruction) {}
});
/**
* Class LocalStorage
* this class provides usual API to save/load/delete documents on the localStorage
*/
var LocalStorage = function(userName) {
Storage.call(this,"local", userName);
if(this.user) {
//this.user.documents = {}
//this.updateUser();
}
} }
setCurrentUser = function(user) {localStorage.setItem("currentUser", JSON.stringify(user));} LocalStorage.prototype = new Storage();
LocalStorage.prototype.load({
/* try to load the user information in the storage and save it in the
* storage instance.
* @param userName : the name of the user
* @return : true if the user existed and has been loaded, false otherwise
*/
loadUser: function(userName) {
try{
if(!localStorage[userName]) {throw "noSuchUser";}
this.user = new User(JSON.parse(localStorage[userName]));
return true;
} catch(e) {
if(e!="noSuchUser") {alert(e);}
return false
}
},
getUser: function() {return this.user;},
setUser: function(user) {
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);
return doc;
},
saveDocument: function(doc, address, instruction) {
this.user.documents[address] = doc;
this.updateUser();
if(instruction) instruction();
},
deleteDocument: function(address, instruction) {
delete this.user.documents[address];
this.updateUser();
if(instruction) instruction();
},
save: function() {
this.updateUser();
localStorage.setItem("currentStorage", JSON.stringify(this));
}
});
/**
* Class JIOStorage
* this class provides usual API to save/load/delete documents on a remote storage
*/
var JIOStorage = function(userName) {
Storage.call(this,"JIO", userName);
}
JIOStorage.prototype = new Storage();
JIOStorage.prototype.load({
loadUser: function(userName) {
//JIO : IDProvider
},
getDocument: function(address, instruction) {
$.ajax({
url: address,
type: "GET",
dataType: type,
success: instruction,
error: function(type) {alert("Error "+type.status+" : fail while trying to load "+address);}
});
},
saveDocument: function(content, address, instruction) {
this.user.documents[address] = doc;
$.ajax({
url: address,
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) {
delete this.user.documents[address];
$.ajax({
url: address,
type: "DELETE",
headers: {Authorization: "Basic "+btoa("smik:asdf")},
fields: {withCredentials: "true"},
success: instruction,
error: function(type) {
alert(type.status);//ajax thinks that 201 is an error...
}
});
}
});
getCurrentStorage = function() {
if(!currentStorage) {//if storage has not been loaded yet
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
case "local": currentStorage = new LocalStorage(); break;
case "JIO": currentStorage = new JIOStorage(); break;
}
currentStorage.loadUser(dataStorage.user.name);
currentStorage.type = dataStorage.type;
}
return currentStorage;
}
setCurrentStorage = function(storage) {
currentStorage = storage;
localStorage.setItem("currentStorage", JSON.stringify(storage));
}
...@@ -193,7 +362,7 @@ setCurrentUser = function(user) {localStorage.setItem("currentUser", JSON.string ...@@ -193,7 +362,7 @@ setCurrentUser = function(user) {localStorage.setItem("currentUser", JSON.string
var JSONDocument = function(arg) { var JSONDocument = function(arg) {
if(arg) {this.load(arg);} if(arg) {this.load(arg);}
else { else {
this.language = getCurrentUser().getLanguage(); this.language = getCurrentUser().getSetting("language");
this.version = null; this.version = null;
this.author=getCurrentUser().getName(); this.author=getCurrentUser().getName();
...@@ -211,7 +380,7 @@ JSONDocument.prototype.load({//add methods thanks to the UngObject.load method ...@@ -211,7 +380,7 @@ JSONDocument.prototype.load({//add methods thanks to the UngObject.load method
//type //type
getType: function() {return this.type;}, getType: function() {return this.type;},
setType: function(newType) {this.type = newType;}, setType: function(newType) {this.type = newType;},
//version //version
getVersion: function() {return this.version;}, getVersion: function() {return this.version;},
setVersion: function(version) {this.version = version;}, setVersion: function(version) {this.version = version;},
...@@ -249,9 +418,9 @@ JSONDocument.prototype.load({//add methods thanks to the UngObject.load method ...@@ -249,9 +418,9 @@ JSONDocument.prototype.load({//add methods thanks to the UngObject.load method
save: function(instruction) { save: function(instruction) {
var doc = this; var doc = this;
saveFile(getDocumentAddress(this), doc, instruction); getCurrentStorage().saveDocument(doc, getDocumentAddress(this), instruction);
}, },
remove: function(instruction) {deleteFile(getDocumentAddress(this), instruction);} remove: function(instruction) {getCurrentStorage().deleteDocument(getDocumentAddress(this), instruction);}
}); });
JSONDocument.prototype.states = { JSONDocument.prototype.states = {
draft:{"fr":"Brouillon","en":"Draft"}, draft:{"fr":"Brouillon","en":"Draft"},
...@@ -259,9 +428,20 @@ JSONDocument.prototype.states = { ...@@ -259,9 +428,20 @@ JSONDocument.prototype.states = {
deleted:{"fr":"Supprimé","en":"Deleted"} deleted:{"fr":"Supprimé","en":"Deleted"}
} }
getCurrentDocument = function() { getCurrentDocument = function() {
return new JSONDocument(JSON.parse(localStorage.getItem("currentDocument"))); if(!currentDocument) {
currentDocument = new JSONDocument(JSON.parse(localStorage.getItem("currentDocument")));
}
return currentDocument;
} }
setCurrentDocument = function(doc) {localStorage.setItem("currentDocument",JSON.stringify(doc));} setCurrentDocument = function(doc) {
currentDocument = doc;
localStorage.setItem("currentDocument",JSON.stringify(doc));
}
supportedDocuments = {"text":{editorPage:"text-editor",icon:"images/icons/document.png"}, supportedDocuments = {"text":{editorPage:"text-editor",icon:"images/icons/document.png"},
"illustration":{editorPage:"image-editor",icon:"images/icons/svg.png"}, "illustration":{editorPage:"image-editor",icon:"images/icons/svg.png"},
...@@ -269,7 +449,9 @@ supportedDocuments = {"text":{editorPage:"text-editor",icon:"images/icons/docume ...@@ -269,7 +449,9 @@ supportedDocuments = {"text":{editorPage:"text-editor",icon:"images/icons/docume
"other":{editorPage:null,icon:"images/icons/other.gif"}, "other":{editorPage:null,icon:"images/icons/other.gif"},
undefined:{editorPage:null,icon:"images/icons/other.gif"} undefined:{editorPage:null,icon:"images/icons/other.gif"}
} }
getDocumentAddress = function(doc) {return "dav/"+doc.getCreation();} getDocumentAddress = function(doc) {
return getCurrentStorage().getType()=="local" ? doc.getCreation() : "dav/"+doc.getCreation();
}
/************************************************* /*************************************************
****************** actions ****************** ****************** actions ******************
...@@ -300,6 +482,30 @@ editDocumentSettings = function() { ...@@ -300,6 +482,30 @@ editDocumentSettings = function() {
} }
} }
}); });
$("p#more_properties") .click(function(){
$("div#more_property").show();
$("p#hide_properties").show();
$("div#edit_document fieldset").animate({"height": "186px"}, "slow");
$("div.ui-dialog").animate({"top": "50px"}, "slow")
.animate({"height": "255px"}, "slow");
$("div#edit_document").animate({"height": "183px"}, "slow");
$("div#edit_document fieldset input").css("margin", "0")
.css("width", "60%");
$("div#edit_document fieldset label").css("float", "left")
.css("width", "35%");
$("div#more_property input").css("width", "47%");
$("p#more_properties").hide();
});
$("p#hide_properties") .click(function(){
$("div#more_property").hide();
$("p#more_properties").show();
$("p#hide_properties").hide();
$("div#edit_document fieldset input").css("width", "95%")
.css("margin-top", "14px");
$("div#edit_document fieldset").animate({"height": "69px"}, "slow");
$("div.ui-dialog").animate({"height": "148px"}, "slow");
$("div#edit_document").animate({"height": "78px"}, "slow");
});
} }
)} )}
...@@ -353,6 +559,26 @@ gadgetListBox = function() { ...@@ -353,6 +559,26 @@ gadgetListBox = function() {
}); });
} }
/**
* open a dialog box to propose settings
*/
editUserSettings = function() {
$("div#preference_dialog").dialog({
autoOpen: false,
height: 215,
width: 319,
modal:true,
buttons: {
"Save": function(){
},
Cancel: function() {
$(this).dialog("close");
}
}
});
}
saveCurrentDocument = function() { saveCurrentDocument = function() {
getCurrentPage().getEditor().saveEdition(); getCurrentPage().getEditor().saveEdition();
...@@ -364,7 +590,7 @@ saveCurrentDocument = function() { ...@@ -364,7 +590,7 @@ saveCurrentDocument = function() {
* @param doc : the document to edit * @param doc : the document to edit
*/ */
var startDocumentEdition = function(doc) { var startDocumentEdition = function(doc) {
loadFile(getDocumentAddress(doc),"json",function(data) { getCurrentStorage().getDocument(getDocumentAddress(doc), function(data) {
doc.load(data); doc.load(data);
setCurrentDocument(doc); setCurrentDocument(doc);
if(supportedDocuments[doc.getType()].editorPage) {window.location = "theme.html";} if(supportedDocuments[doc.getType()].editorPage) {window.location = "theme.html";}
...@@ -381,12 +607,18 @@ var stopDocumentEdition = function() { ...@@ -381,12 +607,18 @@ var stopDocumentEdition = function() {
* @param language : the new language * @param language : the new language
*/ */
var changeLanguage = function(language) { var changeLanguage = function(language) {
var user = getCurrentUser(); getCurrentUser().setSetting("language");
user.setLanguage(language); getCurrentStorage().save();
setCurrentUser(user);
getCurrentPage().displayLanguages(user); getCurrentPage().displayLanguages(user);
window.location.reload(); window.location.reload();
} }
var signOut = function() {
delete localStorage.currentStorage;
delete localStorage.currentDocumentID;
window.location = "login.html";
}
cancel_sharing = function() {alert("cancel");} cancel_sharing = function() {alert("cancel");}
translate = function() {alert("translate");} translate = function() {alert("translate");}
submit = function() {alert("submit");} submit = function() {alert("submit");}
......
...@@ -92,7 +92,7 @@ List.prototype.load({ ...@@ -92,7 +92,7 @@ List.prototype.load({
return this.tail().get(i-1); return this.tail().get(i-1);
}, },
set: function(i,element) { set: function(i,element) {
if(i>=this.size()) {error("set out of bounds, "+i+" : "+this.size(),this);return} if(i>=this.size()) {errorMessage("set out of bounds, "+i+" : "+this.size(),this);return}
if(i==0) { if(i==0) {
this.headElement=element; this.headElement=element;
} else { } else {
...@@ -100,7 +100,7 @@ List.prototype.load({ ...@@ -100,7 +100,7 @@ List.prototype.load({
} }
}, },
remove: function(i) { remove: function(i) {
if(i>=this.size()) {error("remove out of bounds, "+i+" : "+this.size(),this);return}//particular case 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==0) {this.pop();return}//particular case
if(i==1) {//init if(i==1) {//init
this.previous = this.tail().tail(); this.previous = this.tail().tail();
...@@ -110,7 +110,7 @@ List.prototype.load({ ...@@ -110,7 +110,7 @@ List.prototype.load({
this.length--; this.length--;
}, },
pop: function() { pop: function() {
if(this.isEmpty()) {error("pop on empty list",this);return null;} if(this.isEmpty()) {errorMessage("pop on empty list",this);return null;}
var h = this.head(); var h = this.head();
this.load(this.tail()) this.load(this.tail())
return h; return h;
...@@ -128,7 +128,7 @@ List.prototype.load({ ...@@ -128,7 +128,7 @@ List.prototype.load({
}, },
contains: function(object) {if(this.isEmpty()) {return false} else {return object===this.head() ? true : this.tail().contains(object)}}, contains: function(object) {if(this.isEmpty()) {return false} else {return object===this.head() ? true : this.tail().contains(object)}},
insert: function(element,i) { insert: function(element,i) {
if(i>this.size()) {error("insert out of bounds, "+i+" : "+this.size(),this);return}//particular case if(i>this.size()) {errorMessage("insert out of bounds, "+i+" : "+this.size(),this);return}//particular case
if(i==0) {//init if(i==0) {//init
this.add(element); this.add(element);
} else {//recursion } else {//recursion
...@@ -137,7 +137,7 @@ List.prototype.load({ ...@@ -137,7 +137,7 @@ List.prototype.load({
} }
}, },
replace: function(oldElement,newElement) { replace: function(oldElement,newElement) {
if(this.isEmpty()) {error("<<element not found>> when trying to replace",this);return}//init-false if(this.isEmpty()) {errorMessage("<<element not found>> when trying to replace",this);return}//init-false
if(oldElement===this.head()) { if(oldElement===this.head()) {
this.set(0,newElement);//init-true this.set(0,newElement);//init-true
} else { } else {
...@@ -155,34 +155,6 @@ List.prototype.load({ ...@@ -155,34 +155,6 @@ List.prototype.load({
} }
}); });
error: function(message,object) {
errorObject = object;
console.log(message);
}
/**
* returns the current date
*/
currentTime = function() {return (new Date()).toUTCString();}
// save
saveXHR = function(address) {
$.ajax({
url: address,
type: "PUT",
headers: {
Authorization: "Basic "+btoa("smik:asdf")},
fields: {
withCredentials: "true"
},
data: JSON.stringify(getCurrentDocument()),
success: function(){alert("saved");},
error: function(xhr) { alert("error while saving");}
});
};
/** /**
* load a public file with a basic ajax request * load a public file with a basic ajax request
* @param address : the address of the document * @param address : the address of the document
...@@ -199,55 +171,6 @@ loadFile = function(address, type, instruction) { ...@@ -199,55 +171,6 @@ loadFile = function(address, type, instruction) {
}); });
} }
// save
saveFile = function(address, content, instruction) {
$.ajax({
url: address,
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...
}
});
}
deleteFile = function(address, instruction) {
$.ajax({
url: address,
type: "DELETE",
headers: { Authorization: "Basic "+btoa("smik:asdf")},
fields: { withCredentials: "true" },
success: instruction,
error: function(type) {
alert(type.status);//ajax thinks that 201 is an error...
}
});
}
// load
loadXHR = function(address) {
$.ajax({
url: address,
type: "GET",
dataType: "json",
cache:false,
headers: {
Authorization: "Basic "+btoa("smik:asdf")},
fields: {
withCredentials: "true"
},
success: function(data){
var cDoc = getCurrentDocument();
cDoc.load(data);
cDoc.setAsCurrentDocument();
}
});
}
/* /*
* wait an event before execute an action * wait an event before execute an action
* @param required : function we are waiting for a result * @param required : function we are waiting for a result
...@@ -273,7 +196,7 @@ tryUntilSucceed = function(func) { ...@@ -273,7 +196,7 @@ tryUntilSucceed = function(func) {
var nb = 2;//avoid to test too much times var nb = 2;//avoid to test too much times
var execute = function() { var execute = function() {
try {func.call();} try {func.call();}
catch(e) {if(nb<100) {setTimeout(execute,nb*200);} console.log(e);} catch(e) {if(nb<100) {setTimeout(execute,nb*200);}console.log(e);}
nb*=nb; nb*=nb;
} }
execute(); execute();
...@@ -287,4 +210,43 @@ var resize = function() { ...@@ -287,4 +210,43 @@ var resize = function() {
$("div.main-right").width($(window).width()-$("div.main-left").width()); $("div.main-right").width($(window).width()-$("div.main-left").width());
} }
/**
* Used to debug
*/
errorMessage = function(message,object) {
errorObject = object;
console.log(message);
}
/**
* returns the current date
*/
currentTime = function() {return (new Date()).toUTCString();}
/**
* Paste a toolkit at the mouse position
*/
Tooltip = function() {
this.visible=false; // La variable i nous dit si la bulle est visible ou non
}
Tooltip.prototype = {
isVisible: function() {return this.visible;},
move: function(e) {$("div.toolLocation").css("left",e.pageX+5+"px").css("top",e.pageY + 10+"px");},
show: function(text) {
if(!this.isVisible()) {
$("div.toolLocation")
.css("display","inline")
.css("visibility","visible")
.html(text);
this.visible = true;
}
},
hide: function() {
if(this.isVisible()) {
$("div.toolLocation")
.css("display","none")
.css("visibility","hidden");
this.visible = false;
}
}
}
...@@ -10,8 +10,6 @@ setCurrentDocumentID = function(ID) {return localStorage.setItem("currentDocumen ...@@ -10,8 +10,6 @@ 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
* As the list is stored in the localStorage, we are obliged to call "setDocumentList" after
* any content modification
* @param arg : a documentList json object to load * @param arg : a documentList json object to load
*/ */
var DocumentList = function(arg) { var DocumentList = function(arg) {
...@@ -19,44 +17,45 @@ var DocumentList = function(arg) { ...@@ -19,44 +17,45 @@ var DocumentList = function(arg) {
if(arg) { if(arg) {
this.load(arg); this.load(arg);
this.load(new List(arg,JSONDocument)); this.load(new List(arg,JSONDocument));
this.selectionList = new List(arg.selectionList,JSONDocument);//load methods of selectionList this.selectionList = new List(arg.selectionList);//load methods of selectionList
} }
else { else {
this.displayedPage = 1; List.call(this);
this.displayInformation = {};
this.displayInformation.page = 1;
this.selectionList = new List(); this.selectionList = new List();
} }
} }
DocumentList.prototype = new List(); DocumentList.prototype = new List();
DocumentList.prototype.load({ DocumentList.prototype.load({
addDocument: function(doc) {
this.add(doc);
setDocumentList(this);
this.display();
},
removeDocument: function(doc) { removeDocument: function(doc) {
var i = this.find(doc); var i = this.find(doc);
this.get(i).remove()//delete the file this.get(i).remove()//delete the file
this.remove(i);//remove from the list this.remove(i);//remove from the list
setDocumentList(this); getCurrentStorage().save();//save changes
this.display();
}, },
getSelectionList: function() { return this.selectionList; }, getSelectionList: function() {return this.selectionList;},
resetSelectionList: function() { resetSelectionList: function() {
this.selectionList = new List(); this.selectionList = new List();
for(var i=0; i<this.size(); i++) {
//display consequences
for(var i=this.getDisplayInformation().first-1; i<this.getDisplayInformation().last; i++) {
$("tr td.listbox-table-select-cell input#"+i).attr("checked",false);//uncheck $("tr td.listbox-table-select-cell input#"+i).attr("checked",false);//uncheck
} }
setDocumentList(this);
$("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 = new List();
for(var i=0; i<this.size(); i++) { for(var i=0; i<this.size(); i++) {
this.getSelectionList().add(this.get(i)); this.getSelectionList().add(this.get(i));
$("tr td.listbox-table-select-cell input#"+i).attr("checked",true);
} }
setDocumentList(this);
//display consequences
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(this.size());//display the selected row number
}, },
...@@ -66,56 +65,97 @@ DocumentList.prototype.load({ ...@@ -66,56 +65,97 @@ DocumentList.prototype.load({
var doc = selection.pop(); var doc = selection.pop();
this.removeDocument(doc); this.removeDocument(doc);
} }
this.display();
}, },
getDisplayedPage: function() {return this.displayedPage;}, getDisplayInformation: function() {return this.displayInformation;},
setDisplayedPage: function(index) {this.displayedPage = index;}, getDisplayedPage: function() {return this.getDisplayInformation().page;},
setDisplayedPage: function(index) {
this.displayInformation.page = index;
this.display();
},
changePage: function(event) {
var newPage = this.getDisplayedPage();
switch(event.target.className.split(" ")[0]) {
case "listbox_set_page":newPage = event.target.value;break;
case "listbox_next_page":newPage++;break;
case "listbox_previous_page":newPage--;break;
case "listbox_last_page":newPage = this.getDisplayInformation().lastPage;break;
case "listbox_first_page":newPage = 1;break;
}
this.setDisplayedPage(newPage);
},
/* display the list of documents in the web page */ /* display the list of documents in the web page */
displayContent: function() { displayContent: function() {
$("table.listbox tbody").html("");//empty the previous displayed list $("table.listbox tbody").html("");//empty the previous displayed list
var n = this.size(); for(var i=this.getDisplayInformation().first-1;i<this.getDisplayInformation().last;i++) {
for(var i=0;i<n;i++) { var doc = this.get(i);
var ligne = new Line(this.get(i),i); var ligne = new Line(doc,i);
ligne.updateHTML(); ligne.updateHTML();
ligne.display(); ligne.display();
if(this.getSelectionList().contains(doc)) {ligne.setSelected(true);}//check the box if selected
} }
}, },
displayListInformation: function() { displayListInformation: function() {
if(this.size()>0) { if(this.size()>0) {
$("div.listbox-number-of-records").css("display","inline"); $("div.listbox-number-of-records").css("display","inline");
var step = getCurrentUser().getDisplayPreferences();
var first = (this.getDisplayedPage()-1)*step + 1; $("span#page_start_number").html(this.getDisplayInformation().first);
var last = (this.size()<first+step) ? this.size() : first+step-1; $("span#page_stop_number").html(this.getDisplayInformation().last);
$("span#page_start_number").html(first);
$("span#page_stop_number").html(last);
$("span#total_row_number a").html(this.size()); $("span#total_row_number a").html(this.size());
$("span#selected_row_number a").html(this.getSelectionList().size()); $("span#selected_row_number a").html(this.getSelectionList().size());
} }
else {$("div.listbox-number-of-records").css("display","none");} else {$("div.listbox-number-of-records").css("display","none");}
}, },
displayNavigationElements: function() {
var lastPage = this.getDisplayInformation().lastPage;
var disp = function(element,bool) {
bool ? $(element).css("display","inline") : $(element).css("display","none");
}
disp("div.listbox-navigation",this.getDisplayInformation().lastPage>1);
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);
disp("div.listbox-navigation button.listbox_last_page",this.getDisplayedPage()<lastPage);
}
},
display: function() { display: function() {
this.updateDisplayInformation();
this.displayContent(); this.displayContent();
this.displayListInformation(); this.displayListInformation();
this.displayNavigationElements();
}, },
/* update the ith document information */ /* update the ith document information */
update: function(i) { updateDocumentInformation: function(i) {
var list = this; var list = this;
var doc = list.get(i); var doc = list.get(i);
loadFile(getDocumentAddress(doc),"json",function(data) { getCurrentStorage().getDocument(getDocumentAddress(doc), function(data) {
doc.load(data);//todo : replace by data.header doc.load(data);//todo : replace by data.header
doc.setContent("");// doc.setContent("");//
list.set(i,doc); list.set(i,doc);
setDocumentList(list);
}); });
},
/* update the document to be displayed */
updateDisplayInformation: function() {
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);
},
setAsCurrentDocumentList: function() {
this.display();
} }
}); });
getDocumentList = function() { getDocumentList = function() {
return new DocumentList(JSON.parse(localStorage.getItem("documentList"))); return getCurrentUser().getDocumentList();
}
setDocumentList = function(list) {
localStorage.setItem("documentList",JSON.stringify(list));
} }
...@@ -135,21 +175,18 @@ Line.prototype = { ...@@ -135,21 +175,18 @@ Line.prototype = {
getType: function() {return this.document.getType() ? this.document.getType() : "other";}, getType: function() {return this.document.getType() ? 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)},
isSelected: function() { isSelected: function() {
return $("tr td.listbox-table-select-cell input#"+this.getID()).attr("checked"); return $("tr td.listbox-table-select-cell input#"+this.getID()).attr("checked");
}, },
/* 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() {
var list = getDocumentList(); getDocumentList().getSelectionList().add(this.getDocument());
list.getSelectionList().add(this.getDocument());
setDocumentList(list);
}, },
/* 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() {
var list = getDocumentList(); getDocumentList().getSelectionList().removeElement(this.getDocument());
list.getSelectionList().removeElement(this.getDocument());
setDocumentList(list);
}, },
/* check or uncheck the line */ /* check or uncheck the line */
changeState: function() { changeState: function() {
...@@ -176,7 +213,7 @@ Line.prototype = { ...@@ -176,7 +213,7 @@ Line.prototype = {
.end() .end()
.end() .end()
.find("a.listbox-document-title").html(this.getDocument().getTitle()).end() .find("a.listbox-document-title").html(this.getDocument().getTitle()).end()
.find("a.listbox-document-state").html(this.getDocument().getState()[getCurrentUser().getLanguage()]).end() .find("a.listbox-document-state").html(this.getDocument().getState()[getCurrentUser().getSetting("language")]).end()
.find("a.listbox-document-date").html(this.getDocument().getLastModification()).end() .find("a.listbox-document-date").html(this.getDocument().getLastModification()).end()
.end()); .end());
}, },
...@@ -192,6 +229,9 @@ Line.loadHTML = function() { ...@@ -192,6 +229,9 @@ Line.loadHTML = function() {
Line.getOriginalHTML = function() {return Line.originalHTML;} Line.getOriginalHTML = function() {return Line.originalHTML;}
/** /**
* create a new document and start an editor to edit it * create a new document and start an editor to edit it
* @param type : the type of the document to create * @param type : the type of the document to create
...@@ -201,7 +241,8 @@ var createNewDocument = function(type) { ...@@ -201,7 +241,8 @@ var createNewDocument = function(type) {
newDocument.setType(type); newDocument.setType(type);
newDocument.save(function() { newDocument.save(function() {
getDocumentList().addDocument(newDocument); getDocumentList().add(newDocument);
getCurrentStorage().save();
startDocumentEdition(newDocument); startDocumentEdition(newDocument);
}); });
} }
...@@ -30,26 +30,24 @@ ...@@ -30,26 +30,24 @@
href="images/ung/favicon.ico" /> href="images/ung/favicon.ico" />
<script type="text/javascript"> <script type="text/javascript">
var initUser = function() {
var user = getCurrentUser();
user.setAsCurrentUser();
}
var init = function() { var init = function() {
//delete localStorage.documentList;//delete the list for tests //delete localStorage.documentList;//delete the list for tests
setCurrentPage(new Page());//provide methods on the page setCurrentPage(new Page("ung"));//provide methods on the page
initUser();//initialize the user getCurrentStorage().getUser().setAsCurrentUser();//initialize the user
if(getCurrentDocumentID()&&getDocumentList().get(getCurrentDocumentID())) { if(getCurrentDocumentID()&&getDocumentList().get(getCurrentDocumentID())) {
/* update the list with the modifications of the last edited document /* update the list with the modifications of the last edited document
* (this method has to been rewritten if using multi users) */ * (this method has to been rewritten if using multi users) */
getDocumentList().update(getCurrentDocumentID()); getDocumentList().updateDocumentInformation(getCurrentDocumentID());
delete localStorage.currentDocumentID; delete localStorage.currentDocumentID;
} }
waitBeforeSucceed(//display the list of documents waitBeforeSucceed(//display the list of documents
function(){return Line.loadHTML()},function() { function(){return Line.loadHTML()},function() {
getDocumentList().resetSelectionList(); getDocumentList().resetSelectionList();
getDocumentList().display();} getDocumentList().updateDisplayInformation();
getDocumentList().display();
resize();}
); );
resize(); resize();
...@@ -124,9 +122,9 @@ ...@@ -124,9 +122,9 @@
<a id="right_message">Not Implemented yet</a> <a id="right_message">Not Implemented yet</a>
<div id="preference_dialog" title="UNG Preferences"></div> <div id="preference_dialog" title="UNG Preferences"></div>
<a id="userName">Unknown</a> <a id="userName">Unknown</a>
| <a id="settings" href="#">Settings</a> | <a id="settings" href="">Settings</a>
| <a id="help" href="#">Help</a> | <a id="help" href="">Help</a>
| <a href="..WebSite_logout">Sign out</a> | <a id="sign_out" href="" onclick="signOut()">Sign out</a>
</div></div> </div></div>
...@@ -174,8 +172,7 @@ ...@@ -174,8 +172,7 @@
<div class="main"> <div class="main">
<!-- Each aggregate of groups is a div wrapper -- <!-- Each aggregate of groups is a div wrapper -->
<table class="wrapper" id="wrapper_main"><tr>-->
<div class="wrapper" id="wrapper_main"> <div class="wrapper" id="wrapper_main">
<!--<td class=" main-left">--> <!--<td class=" main-left">-->
<div class=" main-left"> <div class=" main-left">
...@@ -465,73 +462,87 @@ ...@@ -465,73 +462,87 @@
onclick="getDocumentList().deleteSelectedDocuments()">Delete onclick="getDocumentList().deleteSelectedDocuments()">Delete
</button> </button>
<button name="#" class="change_state">Change State</button> <button name="#" class="change_state">Change State</button>
</div>
</div></div>
</div> <div class="listbox-navigation">
<button class="listbox_first_page your_listbox_first_page" onclick="getDocumentList().changePage(event)">
<span class="image"> </span>
</button>
<button class="listbox_previous_page your_listbox_previous_page" onclick="getDocumentList().changePage(event)">
<span class="image"> </span>
</button>
<input class="listbox_set_page your_listbox_set_page" value="1" size="1" onkeypress="if(event.keyCode==13){getDocumentList().changePage(event)}" />
/<span class="listbox_last_page">1</span>
<button class="listbox_next_page your_listbox_next_page" onclick="getDocumentList().changePage(event)">
<span class="image"> </span>
</button>
<button class="listbox_last_page your_listbox_last_page" onclick="getDocumentList().changePage(event)">
<span class="image"> </span>
</button>
</div>
<div class="field" title=""> <div class="listbox-head">
<div class="listbox-head-spacer"></div>
<div class="listbox-head-content">
<label> Document List </label> <!-- Listbox head (in left) -->
<div class="listbox-head-title">
<div class="input"> <!-- List tree mode choice -->
<!-- Listbox title -->
<div class="listbox-header-box">
<div class="listbox-title">
<a href="..." class="your_listbox_title">
<span>Document List</span></a>
</div>
</div>
</div>
<div class="listbox-container"> <!-- Listbox nagivation (in right) -->
<div class="listbox-head-navigation">
<div class="listbox-content listbox-content-fixed-width"> <!--Show search result in web mode-->
<div class="listbox-head"> <div class="listbox-header-box">
<div class="listbox-number-of-records">
<div class="listbox-head-spacer"></div> <!-- listbox start - stop number -->
<span id="page_start_number" class="listbox-current-page-start-number">1</span> -
<span id="page_stop_number" class="listbox-current-page-stop-number">...</span>
<span>of</span>
<div class="listbox-head-content"> <!-- listbox total rows number -->
<span id="total_row_number" class="listbox-current-page-total-number your_listbox-current-page-total-number">
<a>?</a> records
</span>
<!-- Listbox head (in left) --> <!-- listbox selected rows number -->
<div class="listbox-head-title"> <span id="selected_row_number" class="your_listbox-current-item-number">
- <a>0</a> items selected
</span>
<!-- List tree mode choice -->
<!-- Listbox title -->
<div class="listbox-header-box">
<div class="listbox-title">
<a href="..." class="your_listbox_title">
<span>Document List</span></a>
</div>
</div> </div>
</div>
<!-- Number of rows in ERP5 mode --> <!--Page navigation -->
<!-- List style display mode --> </div>
</div>
</div> </div>
<!-- Listbox nagivation (in right) --> </div>
<div class="listbox-head-navigation">
<!--Show search result in web mode--> </div></div>
<div class="listbox-header-box">
<div class="listbox-number-of-records">
<!-- listbox start - stop number --> </div>
<span id="page_start_number" class="listbox-current-page-start-number">1</span> -
<span id="page_stop_number" class="listbox-current-page-stop-number">...</span>
<span>of</span>
<!-- listbox total rows number --> <div class="field" title="">
<span id="total_row_number" class="listbox-current-page-total-number your_listbox-current-page-total-number">
<a>?</a> records
</span>
<!-- listbox selected rows number --> <label> Document List </label>
<span id="selected_row_number" class="your_listbox-current-item-number">
- <a>0</a> items selected
</span>
</div> <div class="input">
</div>
<!--Page navigation --> <div class="listbox-container">
</div>
</div>
</div> <div class="listbox-content listbox-content-fixed-width">
<div class="listbox-body"> <div class="listbox-body">
......
<?xml version="1.0" encoding="UTF-8"?>
<root>
<title> Welcome </title>
<content>
<fieldset class="widget">
<p></p>
<h2>Welcome to UNG Web Office</h2>
<div id="main-content">
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr>
<td valign="top">
<div id="advertisement">
<b>Sign in to edit documents, spreadsheets and drawing and share this document with other users</b>
<br/>
<img src="images/ung/ung-logo.png" alt=""/>
</div>
</td>
<td>
<table id="field_table" style="display: table; width: 78%;">
<tbody>
<tr>
<td align="center">
<table>
<tbody>
<tr>
<td align="center" colspan="2">
<font size="-1">Login in</font>
</td>
</tr>
<tr><td></td></tr>
<tr>
<td align="center">
<label for="name">Name</label>
</td>
<td align="center">
<input id="name" type="text" value="" name="name" />
</td>
</tr>
<tr>
<td align="center">
<label for="id_provider">ID provider</label>
</td>
<td>
<input id="id_provider" type="text" value="" name="id_provider" />
</td>
</tr>
<tr>
<td align="center" colspan="2">
<input class="submit" onclick="logUser()" type="submit" value="Login" name="logged_in:method" />
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td>
<br/>
</td>
<td>
<table id="create-new-user" style="width: 78%; display: none;">
<tbody>
<tr>
<td>
<form id="create-user" action="javascript:createNewUser()" method="post">
<table width="100%">
<tbody>
<tr>
<td align="center" colspan="2">
<b>Create an account</b>
</td>
</tr>
<tr>
<td id="form-message" align="center" colspan="2"></td>
</tr>
<tr>
<td>First Name</td>
<td>
<input type="text" name="firstname" />
</td>
</tr>
<tr>
<td>Last Name</td>
<td>
<input type="text" name="lastname" />
</td>
</tr>
<tr>
<td>Email</td>
<td>
<input type="text" name="email" />
</td>
</tr>
<tr>
<td>Login name</td>
<td>
<input type="text" name="login_name" />
</td>
</tr>
<tr>
<td>Password</td>
<td>
<input type="password" name="password" />
</td>
</tr>
<tr>
<td>Confirm Password</td>
<td>
<input type="password" name="confirm" />
</td>
</tr>
<tr>
<td align="center" colspan="2">
<input class="submit" type="submit" value="Create Account" name="logged_in:method" />
</td>
</tr>
<tr>
<td id="back-login" align="left" colspan="2">
<a onclick="displayNewAccountForm(false)">&lt;&lt;Back</a>
</td>
</tr>
</tbody>
</table>
</form>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr><td></td></tr>
<tr>
<td></td>
<td>
<table id="new-account-table" style="display: table; width: 78%;">
<tbody>
<tr>
<td>
<table width="100%">
<tbody>
<tr>
<td align="center" colspan="2">
<b>Don't have an UNG Account?</b>
</td>
</tr>
<tr>
<td id="new-account-form" align="center" colspan="2" onclick="displayNewAccountForm(true)">Create an account now</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<div class="footer">
<a href="http://www.freecloudalliance.org/">Free Cloud Alliance</a>
-
<a href="#">Help</a>
</div>
<p></p>
</fieldset>
</content>
<dependencies>
<scriptfile>js/login.js</scriptfile>
</dependencies>
</root>
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