Commit 26639b48 authored by François Billioud's avatar François Billioud

Merge branch 'jio'

parents 455f7a5c ef1fced9
......@@ -5,7 +5,7 @@
<title></title>
<script type="text/javascript"> function reloc(url) {window.location = url;}</script>
</head>
<body onload="reloc('ung.html');">
<body onload="reloc('mail.html');">
</body>
</html>
/**
*
* Base64 encode / decode
* http://www.webtoolkit.info/
*
**/
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="jio.js" />
<script type="text/javascript">
nextField = function(event) {
if(event.keyCode==13) {
if(document.getElementById("userName")==document.activeElement) {document.getElementById("password").focus();return;}
if(document.getElementById("password")==document.activeElement) {login();document.getElementById("submit").focus();return;}
}
}
document.onload;
</script>
</head>
<body>
<form action="https://dav-storage/login.php" method="post">
<div style="border: solid 1px #000; width:auto; float:left;">
<label >user name</label>
<input id="userName" type="text" name="userName" onkeypress="nextField(event)" /><br/>
<label>password</label>
<input id="password" type="password" name="password" onkeypress="nextField(event)"/><br/>
<input id="submit" type="submit" value="send" />
</div>
</form>
</body>
</html>
NoSSLStorage = function(user, location) {
this.rsa = null;
this.userName = user;
this.storageLocation = location;
}
NoSSLStorage.prototype = {
initIO: function() {
this.rsa = new RSA();
},
maintenance: function() {//maintains the ssh key in life
var ID = {user:this.userName, key:this.rsa.getPublicKey()}
send(ID,this.storageLocation);
setTimeout(maintenance(),3000);
},
loadDocument: function(applicationDomain, repository, file) {
},
saveDocument: function(applicationDomain, data, repository, file, overwrite) {
},
deleteDocument: function(applicationDomain, repository, file) {
}
}
DAVStorage = function(user, location, passwdCrypto) {
this.passwordCrypto = passwdCrypto;
this.userName = user;
this.storageLocation = location;
}
DAVStorage.prototype = {
initIO: function() {
//récupérer le password crypto
},
loadDocument: function(applicationDomain, repository, file, instruction, errorHandler) {
$.ajax({
url: repository+file,
type: "GET",
dataType: type,
headers: { Authorization: "Basic "+btoa("smik:asdf")},
fields: { withCredentials: "true" },
success: instruction,
error: errorHandler || function(type) {alert("Error "+type.status+" : fail while trying to load "+address);}
});
},
saveDocument: function(applicationDomain, newData, repository, file, overwrite, instruction, oldData) {
var save = function() {
$.ajax({
url: repository+file,
type: "PUT",
dataType: "json",
data: JSON.stringify(newData),
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...
}
});
}
var merge = function(serverData) {
if(overwrite) {
//if(diff(oldData,serverData)) {merge(newData, serverData);}
save();
}
}
//check if already exists and for diffs
loadDocument(applicationDomain, repository, file,
function(serverData) {
merge(serverData);
},
function(type) {
if(type.status==404) {
save();
} else {
if(type.status==201 || type.status==204) {instruction();}
}
}
);
},
deleteDocument: function(applicationDomain, repository, file) {
$.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...
}
});
}
}
login = function() {
var user = $("#userName").value;
var storageLocation = $("#storageLocation").value;
currentStorage = new NoSSLStorage(user,storageLocation);
var password = CryptoSym.encrypt({
userName: user,
publicKey:currentStorage.rsa.getPublicKey(),
password:$("#password").value
});
$("#password").value = "";
$("#code").value = password;
$("#connection").action = "https://"+storageLocation;
maintenance();
}
loadFile = function(address, type, instruction) {
$.ajax({
url: address,
type: "GET",
dataType: type,
success: instruction,
error: function(type) {alert("Error "+type.status+" : fail while trying to load "+address);}
});
}
loadServerDescription = function(address) {
loadFile(address+"/server.json", "JSON", function() {})
}
CryptoSym = {
encrypt: function(obj, key) {return JSON.stringify(obj)+"key";},
decrypt: function(obj, key) {return JSON.parse(obj.split("key")[0])}
}
RSA = function(publicKey) {
if(publicKey) {
this.publicKey = publicKey;
} else {
this.publicKey = null;
this.privateKey = null;
this.generate();
}
}
RSA.prototype = {
getPublicKey: function() {return this.publicKey;},
getPrivateKey: function() {return this.privateKey;},
generate: function() {
this.privateKey = Date.now();
this.publicKey = this.privateKey;
},
encrypt: function(text,key) {return text+key;},
decrypt: function(text) {return text.split(this.privateKey)[0]}
}
<?php
function filesList($dirname) {
$dir = opendir($dirname);
$filesArray = array();
while($file = readdir($dir)) {
if($file != '.' && $file != '..' && !is_dir($dirname.$file))
{
$filesArray[] = $file;
}
}
closedir($dir);
$jsonList = json_encode($filesArray);
return $jsonList;
}
echo filesList(".");
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="jio.js" />
<script type="text/javascript">
nextField = function(event) {
if(event.keyCode==13) {
if(document.getElementById("userName")==document.activeElement) {document.getElementById("storageLocation").focus();return;}
if(document.getElementById("storageLocation")==document.activeElement) {document.getElementById("password").focus();return;}
if(document.getElementById("password")==document.activeElement) {login();document.getElementById("submit").focus();return;}
}
}
document.onload;
</script>
</head>
<body>
<div style="border: solid 1px #000; width:auto; float:left;">
<label >user name</label>
<input id="userName" type="text" name="userName" onkeypress="nextField(event)" /><br/>
<label>storage location</label>
<input id="storageLocation" type="text" name="storageLocation" onkeypress="nextField(event)"/><br/>
<label>password</label>
<input id="password" type="password" name="password" onkeypress="nextField(event)"/><br/>
</div>
<div style="border: solid 1px #000; width:auto; float:left;">
<form id="connection" action="" method="post" >
<input id="code" type="text" name="code"/>
<input id="submit" type="submit" value="send" />
</form>
</div>
</body>
</html>
......@@ -6,320 +6,320 @@
JIO Namespace. Everything related to JIO happens over here
*/
var JIO = (function () {
/* Function returns us a JIOStorage, a basic stensil for other kind of storage*/
var JIOStorage = function (store_info) {
var J = {}; // dummy object. We will augment it and return it
J = {
"initialize": function(server,path,username,password) {
/*
Basic initilization or pre-rituals
*/
},
"loadDocument": function (doc_id, handler ) {
/*
Calls handler with an object associated with requested document of the `doc_id`
The first argument of handler is error object or null depending on if error occured or not.(Like NodeJS)
Second argmuent is the object literal containing
.hash of the object is the MD5 hash of the data
.data of the object is the data itself
Signature of Handler:
handler = function (err, dataobject) {
if(err===null) {
console.log(dataobject.hash);
console.log(dataobject.data);
}
else{
console.log(err.status);
}
};
*/
},
/* Function returns us a JIOStorage, a basic stensil for other kind of storage*/
var JIOStorage = function (store_info) {
var J = {}; // dummy object. We will augment it and return it
J = {
"initialize": function(server,path,username,password) {
/*
Basic initilization or pre-rituals
*/
},
"loadDocument": function (doc_id, handler ) {
/*
Calls handler with an object associated with requested document of the `doc_id`
The first argument of handler is error object or null depending on if error occured or not.(Like NodeJS)
Second argmuent is the object literal containing
.hash of the object is the MD5 hash of the data
.data of the object is the data itself
Signature of Handler:
handler = function (err, dataobject) {
if(err===null) {
console.log(dataobject.hash);
console.log(dataobject.data);
}
else{
console.log(err.status);
}
};
"saveDocument": function (doc_id, data, handler, hash, conflict_func, overwrite) {
/*
Saves the document with a particular `doc_id`
`hash` is used to check if the document was last changed by someone else,
If it was, it will call the conflict_func with all other parameters passed.
If `hash` is not supplied, no validation would be performed and conflit_func won't be called and document would be saved directly.
Setting `overwrite` to false, will prevent overwriting the document in anycase if a document with doc_id already exists
`handler` workes sames way as in loadDocument
*/
},
"getDocumentList": function (storage_id, query, order_by, metadata) {
/*
Storage implementation should provide this function which will
return the list of documents which are stored on the storage
beased on `query`.
TODO Define how `query` is specified
`ordered_by` how the results should be sorted
*/
},
"hashdata": function(data) {
if(typeof hex_sha1 !== 'function') {
//this means that the hashing library is not load it. Load it now
$.ajax({
async:false,
type: "GET",
url: "js/sha1-min.js",
dataType: "script"
});
}
//now we can use hex_sha1(hopefully)
return hex_sha1(data);
}
};
return J;
}; //JIOStorage
*/
},
/* DAVStorage : Does JIO on a WebDAV server*/
var DAVStorage = function (store_info) {
if(!store_info.server)
throw Error("No server specified for DAVStorage");
store_info.path = store_info.path || '';
var auth=false;
if(store_info.user) {
if(store_info.pass===undefined)
throw Error("No password specified of user for DAVStorage");
auth=true;
}
//server,path should all be in correct format http://foo.com/ some/dir/
var complete_path = store_info.server + store_info.path;
var add_auth_headers = function (ajaxsetting) {
ajaxsetting.headers={'Authorization':"Basic "+btoa(store_info.user+":"+store_info.pass)};
ajaxsetting.fields={'withCredentials': "true"};
return ajaxsetting;
};
var J = JIOStorage(store_info); // we will return this object at the end
J.loadDocument = function (doc_id,handler) {
var ajaxsetting={
'url': complete_path+doc_id,
'type':'GET',
'cache':false,
'success': function (fetched_data, textStatus, jqXHR) {
var hashed_data=J.hashdata(fetched_data);
handler(null,{'hash':hashed_data,'data':fetched_data});
},
'error': function(jqXHR, textStatus, errorThrown) {
console.log("Error while doing ajax request for loadDocument. Return code:"+jqXHR.status+"["+errorThrown+"]");
handler(jqXHR);
}
};
if (auth) {
ajaxsetting = add_auth_headers(ajaxsetting);
}
$.ajax(ajaxsetting);
};
J.saveDocument = function(doc_id, data, handler, hash, conflict_func, overwrite){
var document_url=complete_path+doc_id;
var ajaxsetting={
'url':document_url,
'cache':false,
'type':'PUT',
'data':data,
'success' : function (fetched_data, textStatus, jqXHR) {
var hashed_data= J.hashdata(data);
handler(null,{'hash':hashed_data,'data':data});
},
'error' : function(jqXHR, textStatus, errorThrown) {
console.log("Error while doing ajax request for loadDocument. Return code:"+jqXHR.status+"["+errorThrown+"]");
handler(jqXHR);
}
};
if (auth) {
ajaxsetting = add_auth_headers(ajaxsetting);
}
"saveDocument": function (doc_id, data, handler, hash, conflict_func, overwrite) {
/*
Saves the document with a particular `doc_id`
`hash` is used to check if the document was last changed by someone else,
If it was, it will call the conflict_func with all other parameters passed.
If `hash` is not supplied, no validation would be performed and conflit_func won't be called and document would be saved directly.
Setting `overwrite` to false, will prevent overwriting the document in anycase if a document with doc_id already exists
`handler` workes sames way as in loadDocument
*/
},
"getDocumentList": function (storage_id, query, order_by, metadata) {
/*
Storage implementation should provide this function which will
return the list of documents which are stored on the storage
beased on `query`.
TODO Define how `query` is specified
`ordered_by` how the results should be sorted
*/
},
"hashdata": function(data) {
if(typeof hex_sha1 !== 'function') {
//this means that the hashing library is not load it. Load it now
$.ajax({
async:false,
type: "GET",
url: "js/sha1-min.js",
dataType: "script"
});
//The logic:
if(hash){
//hash is provided, we will now have to get the document first.
J.loadDocument(doc_id, function(err, dataobject){
if(err!==null){
//error occured, check if it is 404
if(err.status===404){
//the document doesn't exist, just do the save
$.ajax(ajaxsetting);
}
else{
//some other strange error,just call the user's error handler
handler(err);
}
}
else{
//we got back a document, check for hash
if(dataobject.hash===hash){
//hash matched, now check for overwrite value
if(overwrite!==false){
$.ajax(ajaxsetting);
}
}
//now we can use hex_sha1(hopefully)
return hex_sha1(data);
}
};
return J;
}; //JIOStorage
}
else{
//hash didn't match, raise conflict_func
conflict_func(doc_id,data,handler,hash,overwrite);
}
}
});
}
else{
//user didn't provide hash.
if(overwrite!==false){
//user doesn't care if document get's overwriten,
//save the document
$.ajax(ajaxsetting);
}
else{
//user doesn't wants to overwrite the document, now check if the document exists
J.loadDocument(doc_id,function(err,dataobject){
if(err!==null) {
//error occured while trying to fetch the doc, check if error was 404
if(err.status===404) {
//document doesn't exist, just do the save
$.ajax(ajaxsetting);
}
//now if any other error occurs, we don't care. (this is bad habbit)
}
});
}
}
};
J.getDocumentList = function(){};
//All methods are defined, now return J as the newly cooked object
return J;
};//DAVStorage
/*ObjStorage: JIO on javscript objects*/
var ObjStorage = function (store_info){
/*
* store_info.memobject must be either an empty object or must be a
* collection object indicated by it's .content to be an array.
*/
var memobject=store_info.memobject || {};
if(memobject.data===undefined){
// The object doesn't have a .data, we have to create a blank one
// Most probably the object was blank or wasn't passed
memobject.data=[];//blank array to hold all the object
}
if(memobject.doc_id===undefined){
/*
* We can have doc_id of the parent node as an empty string
* But remember if we are binding this object to a children of another
* We will have to ask user about the name as which has to be mounted
*/
memobject.doc_id="";
}
/*
* after this line, the memobeject will have
* .data as either an empty array [] or the original data as string
* .doc_id as either the original doc_id or blank string
*/
var J = JIOStorage(store_info);
J.hashObject = function(object,hashfunction){
if(hashfunction)
{
return hashfunction(JSON.stringify(object));
}
else{
return J.hashdata(JSON.stringify(object));
}
};
J.loadDocument = function (doc_id, handler) {
/*
* Handler is optional.
* Returns dataobject = {hash,data}
* If the requested doc_id is a 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.
*
* Since all operation are done on Memory, asyncronous request doesn't
* have a meaning, handler is provided just to give a uniform interface.
* Users are advised to call loadDocument without a handler
* TODO: write how to handle error in case not
* using handlers
* TODO: Make it compatible with handler
*
* Internal representation: Each object is
* {doc_id,meta_data,content}. content can be
* array which represents the collection or
* simple data representing document.
*/
var dataobject = {}; //to be returned
if(memobject.data instanceof Array){
/*
* Check for any of the children have given doc_id
*/
for (var i=0; i < memobject.data.length;i++){
var ith_child=memobject.data[i];
if(ith_child.doc_id===doc_id){
if(ith_child instanceof Array){
//found match is a collection
dataobject.data=[];
for(var j=0; j < ith_child.data.length; j++){
dataobject.data.push(ith_child.data[j]);
}
}
else{
//it was a document
dataobject.data=ith_child.data;
}
dataobject.hash=J.hashObject(ith_child);
break;
}
}
if(dataobject.data===undefined){
// there are is no child of doc_id in current collection
return null; //not found
}
/* DAVStorage : Does JIO on a WebDAV server*/
var DAVStorage = function (store_info) {
if(!store_info.server)
throw Error("No server specified for DAVStorage");
store_info.path = store_info.path || '';
var auth=false;
if(store_info.user) {
if(store_info.pass===undefined)
throw Error("No password specified of user for DAVStorage");
auth=true;
}
}
else{
// the memobject is a datablob, check if doc_id matches and return
if(memobject.doc_id===doc_id){
dataobject.data=memobject.data;
dataobject.hash=J.hashObject(memobject);
}
else{
// the doc_id neither matched with any child or the object itself
// return null
return null;//return null
}
}
return dataobject;
};
J.saveDocument = function (doc_id, data, handler, hash, conflict_func,overwrite){
/*
* if data is null (not undefined but null) the save function will make a collection (directory) instead.
*/
};
return J;
};
//server,path should all be in correct format http://foo.com/ some/dir/
var complete_path = store_info.server + store_info.path;
var add_auth_headers = function (ajaxsetting) {
ajaxsetting.headers={'Authorization':"Basic "+btoa(store_info.user+":"+store_info.pass)};
ajaxsetting.fields={'withCredentials': "true"};
return ajaxsetting;
};
//defined all classes, now return the interface of JIO which has all these classes
return {
'JIOStorage':JIOStorage,
'DAVStorage':DAVStorage,
'ObjStorage':ObjStorage
};
})();
var J = JIOStorage(store_info); // we will return this object at the end
J.loadDocument = function (doc_id,handler) {
var ajaxsetting={
'url': complete_path+doc_id,
'type':'GET',
'cache':false,
'success': function (fetched_data, textStatus, jqXHR) {
var hashed_data=J.hashdata(fetched_data);
handler(null,{'hash':hashed_data,'data':fetched_data});
},
'error': function(jqXHR, textStatus, errorThrown) {
console.log("Error while doing ajax request for loadDocument. Return code:"+jqXHR.status+"["+errorThrown+"]");
handler(jqXHR);
}
};
if (auth) {
ajaxsetting = add_auth_headers(ajaxsetting);
}
$.ajax(ajaxsetting);
};
J.saveDocument = function(doc_id, data, handler, hash, conflict_func, overwrite){
var document_url=complete_path+doc_id;
var ajaxsetting={
'url':document_url,
'cache':false,
'type':'PUT',
'data':data,
'success' : function (fetched_data, textStatus, jqXHR) {
var hashed_data= J.hashdata(data);
handler(null,{'hash':hashed_data,'data':data});
},
'error' : function(jqXHR, textStatus, errorThrown) {
console.log("Error while doing ajax request for loadDocument. Return code:"+jqXHR.status+"["+errorThrown+"]");
handler(jqXHR);
}
};
if (auth) {
ajaxsetting = add_auth_headers(ajaxsetting);
}
//The logic:
if(hash){
//hash is provided, we will now have to get the document first.
J.loadDocument(doc_id, function(err, dataobject){
if(err!==null){
//error occured, check if it is 404
if(err.status===404){
//the document doesn't exist, just do the save
$.ajax(ajaxsetting);
}
else{
//some other strange error,just call the user's error handler
handler(err);
}
}
else{
//we got back a document, check for hash
if(dataobject.hash===hash){
//hash matched, now check for overwrite value
if(overwrite!==false){
$.ajax(ajaxsetting);
}
}
else{
//hash didn't match, raise conflict_func
conflict_func(doc_id,data,handler,hash,overwrite);
}
}
});
}
else{
//user didn't provide hash.
if(overwrite!==false){
//user doesn't care if document get's overwriten,
//save the document
$.ajax(ajaxsetting);
}
else{
//user doesn't wants to overwrite the document, now check if the document exists
J.loadDocument(doc_id,function(err,dataobject){
if(err!==null) {
//error occured while trying to fetch the doc, check if error was 404
if(err.status===404) {
//document doesn't exist, just do the save
$.ajax(ajaxsetting);
}
//now if any other error occurs, we don't care. (this is bad habbit)
}
});
}
}
};
J.getDocumentList = function(){};
//All methods are defined, now return J as the newly cooked object
return J;
};//DAVStorage
/*ObjStorage: JIO on javscript objects*/
var ObjStorage = function (store_info){
/*
* store_info.memobject must be either an empty object or must be a
* collection object indicated by it's .content to be an array.
*/
var memobject=store_info.memobject || {};
if(memobject.data===undefined){
// The object doesn't have a .data, we have to create a blank one
// Most probably the object was blank or wasn't passed
memobject.data=[];//blank array to hold all the object
}
if(memobject.doc_id===undefined){
/*
* We can have doc_id of the parent node as an empty string
* But remember if we are binding this object to a children of another
* We will have to ask user about the name as which has to be mounted
*/
memobject.doc_id="";
}
/*
* after this line, the memobeject will have
* .data as either an empty array [] or the original data as string
* .doc_id as either the original doc_id or blank string
*/
var J = JIOStorage(store_info);
J.hashObject = function(object,hashfunction){
if(hashfunction)
{
return hashfunction(JSON.stringify(object));
}
else{
return J.hashdata(JSON.stringify(object));
}
};
J.loadDocument = function (doc_id, handler) {
/*
* Handler is optional.
* Returns dataobject = {hash,data}
* If the requested doc_id is a 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.
*
* Since all operation are done on Memory, asyncronous request doesn't
* have a meaning, handler is provided just to give a uniform interface.
* Users are advised to call loadDocument without a handler
* TODO: write how to handle error in case not
* using handlers
* TODO: Make it compatible with handler
*
* Internal representation: Each object is
* {doc_id,meta_data,content}. content can be
* array which represents the collection or
* simple data representing document.
*/
var dataobject = {}; //to be returned
if(memobject.data instanceof Array){
/*
* Check for any of the children have given doc_id
*/
for (var i=0; i < memobject.data.length;i++){
var ith_child=memobject.data[i];
if(ith_child.doc_id===doc_id){
if(ith_child instanceof Array){
//found match is a collection
dataobject.data=[];
for(var j=0; j < ith_child.data.length; j++){
dataobject.data.push(ith_child.data[j]);
}
}
else{
//it was a document
dataobject.data=ith_child.data;
}
dataobject.hash=J.hashObject(ith_child);
break;
}
}
if(dataobject.data===undefined){
// there are is no child of doc_id in current collection
return null; //not found
}
}
else{
// the memobject is a datablob, check if doc_id matches and return
if(memobject.doc_id===doc_id){
dataobject.data=memobject.data;
dataobject.hash=J.hashObject(memobject);
}
else{
// the doc_id neither matched with any child or the object itself
// return null
return null;//return null
}
}
return dataobject;
};
J.saveDocument = function (doc_id, data, handler, hash, conflict_func,overwrite){
/*
* if data is null (not undefined but null) the save function will make a collection (directory) instead.
*/
};
return J;
};
//defined all classes, now return the interface of JIO which has all these classes
return {
'JIOStorage':JIOStorage,
'DAVStorage':DAVStorage,
'ObjStorage':ObjStorage
};
})();
/**
* This file provides classes needed by the mail editor
*/
/**
* Editors
* editors must implement the following methods :
* load : load the editor in the current page
* saveEdition : save the edition made by this editor to the current document
* loadContentFromDocument : display the content of the specified document in the editor
*/
var Xinha = function() {
this.name = "Xinha";
this.load = function() {
_editor_url = "xinha/";
getCurrentPage().include("xinha/XinhaCore.js","script");
getCurrentPage().include("xinha/config.js","script");
xinha_init();
}
this.saveEdition = function() {
getCurrentDocument().saveEdition(xinha_editors.input_area.getEditorContent());
}
this.loadContentFromDocument = function(doc) {
var setText = function() {xinha_editors.input_area.setEditorContent(doc.getContent());}
tryUntilSucceed(setText);
}
this.load();
}
/**
* Text documents
*
* editable documents must implements the following arguments and methods
* 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 JSONEMail
* @param arg : a json JSONEMail object to load
*/
var JSONEMail = function(arg) {
if(arg) {this.load(arg);}
else {
this.senders = {};
this.cc = {};
this.bcc = {};
this.object = "";
this.recipients = {};
this.date = currentTime();
this.content = "";
this.attachment = {};
}
}
JSONEMail.prototype = new UngObject();//inherits methods from JSONDocument
JSONEMail.prototype.load({
//setters,getters
getSenders: function() {return this.senders;},
getCC: function() {return this.cc;},
getBCC: function() {return this.bcc;},
getObject: function() {return this.object},
getRecipients: function() {return this.recipients;},
getDate: function() {return this.date;},
setSenders: function(senderList) {this.senders = senderList;},
setCC: function(ccList) {this.cc = ccList;},
setBCC: function(bccList) {this.bcc = bccList;},
setObject: function(object) {this.object = object;},
setRecipients: function(recipientList) {this.recipients = recipientList;},
setDate: function(date) {this.date = date;}
});
/**
* This file provides the javascript used to display the list of user's documents
*/
/* global variable */
/* the last modified document */
getCurrentDocumentID = function() {return localStorage.getItem("currentDocumentID");}
setCurrentDocumentID = function(ID) {return localStorage.setItem("currentDocumentID",ID);}
/**
* class EMailList
* This class provides methods to manipulate the list of emails of the current user
* @param arg : an eMailList json object to load
*/
var EMailList = function(arg) {
//List.call(this);
if(arg) {
this.load(arg);
this.load(new List(arg,JSONEMail));
this.selectionList = new List(arg.selectionList);//load methods of selectionList
} else {
List.call(this);
this.displayInformation = {};
this.displayInformation.page = 1;
this.selectionList = new List();
}
}
EMailList.prototype = new List();
EMailList.prototype.load({
removeEMail: function(doc) {
var i = this.find(doc);
this.get(i).remove()//delete the file
this.remove(i);//remove from the list
getCurrentStorage().save();//save changes
},
getSelectionList: function() {return this.selectionList;},
resetSelectionList: function() {
this.selectionList = new List();
//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
}
$("span#selected_row_number a").html(0);//display the selected row number
},
checkAll: function() {
this.selectionList = new List();
for(var i=0; i<this.size(); i++) {
this.getSelectionList().add(this.get(i));
}
//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
},
applyToSelection: function(action,location) {
var selection = this.getSelectionList();
var toApply;
switch(action) {
case "moveTo": toApply = getCurrentEMailList().label=="bin" ? function(mail) {this.removeEMail(mail)} : function(mail) {};break;
case "read": toApply=function(mail) {};break;
case "unread": toApply=function(mail) {};break;
}
while(!selection.isEmpty()) {
var mail = selection.pop();
toApply(mail);
}
this.resetSelectionList();
this.display();
},
getDisplayInformation: function() {return this.displayInformation;},
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 */
displayContent: function() {
$("table.listbox tbody").html("");//empty the previous displayed list
for(var i=this.getDisplayInformation().first-1;i<this.getDisplayInformation().last;i++) {
var doc = this.get(i);
var ligne = new Line(doc,i);
ligne.updateHTML();
ligne.display();
if(this.getSelectionList().contains(doc)) {ligne.setSelected(true);}//check the box if selected
}
},
displayListInformation: function() {
if(this.size()>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());
}
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() {
this.updateDisplayInformation();
this.displayContent();
this.displayListInformation();
this.displayNavigationElements();
},
/* 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();
}
});
getEMailList = function() {
return getCurrentUser().getEMailList();
}
/**
* create a line representing a document in the main table
* @param mail : email to represent
* @param i : ID of the line (number)
*/
var Line = function(mail, i) {
this.email = mail;
this.ID = i;
this.html = Line.getOriginalHTML();
}
Line.prototype = {
getEMail: function() {return this.email;},
getID: function() {return this.ID;},
getType: function() {return this.document.getType() || "other";},
getHTML: function() {return this.html;},
setHTML: function(newHTML) {this.html = newHTML;},
setSelected: function(bool) {$("tr td.listbox-table-select-cell input#"+this.getID()).attr("checked",bool)},
isSelected: function() {
return $("tr td.listbox-table-select-cell input#"+this.getID()).attr("checked");
},
/* add the document of this line to the list of selected documents */
addToSelection: function() {
getDocumentList().getSelectionList().add(this.getDocument());
},
/* remove the document of this line from the list of selected documents */
removeFromSelection: function() {
getDocumentList().getSelectionList().removeElement(this.getDocument());
},
/* check or uncheck the line */
changeState: function() {
this.isSelected() ? this.addToSelection() : this.removeFromSelection();
$("span#selected_row_number a").html(getDocumentList().getSelectionList().size());//display the selected row number
},
/* load the document information in the html of a default line */
updateHTML: function() {
var line = this;
this.setHTML($(this.getHTML()).attr("class",this.getType())
.find("td.listbox-table-select-cell input")
.attr("id",this.getID())//ID
.click(function() {line.changeState();})//clic on a checkbox
.end()
.find("td.listbox-table-data-cell")
.click(function() {//clic on a line
setCurrentEMailID(line.getID());
startEMailEdition(line.getEMail())
})
.find("a.listbox-email-sender").html(this.getEMail().getSenders()).end()
.find("a.listbox-email-object").html(this.getEMail().getObject()[getCurrentUser().getSetting("language")]).end()
.find("a.listbox-email-date").html(this.getEMail().getLastModification()).end()
.end());
if(getEmail().getAttachment()) {
this.setHTML($("<img>",{src:"images/icons/attachment.png", css:{height:"1em"}}).appendTo(this.getHTML().find("a.listbox-email-attachment")));
}
},
/* 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("email table tbody").html();});
return Line.originalHTML;
}
/* return the html code of a default line */
Line.getOriginalHTML = function() {return Line.originalHTML;}
/**
* create a new email and start an editor to edit it
*/
var createNewEMail = function() {
var newEMail = new EMail();
newEMail.save(function() {
getMailList().add(newEMail);
getCurrentStorage().save();
startEMailEdition(newEMail);
});
}
createMoveToMenu = function(labelList) {
$("div#move_to_list").html("");
for(var label in labelList) {
var span = JQuery("<span>",{text:label});
var div = $("<div>",{click: function() {getMailList().applyToSelection('moveTo',label)}});
$("<li>", {}).html(div.html(span)).appendTo("div#move_to_list");
}
}
/**
* Class IMAPStorage
* this class provides usual API to save/load/delete emails with imap
*/
var IMAPStorage = function(userName) {
getCurrentStorage().load({
loadEmail: function(ID) {},
saveEmail: function(mail,ID) {},
deleteEmail: function(ID) {}
});
}
/**
* Class Label
* used to load the methods of emails
*/
var Label = function(arg) {
this.load(arg ? new List(arg,JSONEMail) : new List());
}
/**
* Class MailBox
* this class provides API to send/receive and manipulate emails
*/
var initMailBox = function(user, mailProvider) {
getCurrentStorage().load({
userName: user,
provider: mailProvider,
saveEmail: function(mail,ID) {},
deleteEmail: function(ID) {},
sendEMail: function(mail) {},
loadEMail: function(ID) {}
});
}
if(arg) {
} else {
this.provider = "";
this.userName = "";
this.labelList = new List();
}
}
MailBox.prototype = new UNGProject();
MailBox.prototype.load({
getLabelList: function() {return this.labelList;},
getLabelList: function() {return this.labelList;},
getLabelList: function() {return this.labelList;},
getLabelList: function() {return this.labelList;},
});
getCurrentEMail = function() {
if(!currentEMail) {
currentEMail = new JSONEMail(JSON.parse(localStorage.getItem("currentEMail")));
}
return currentEMail;
}
setCurrentEMail = function(mail) {
currentEMail = mail;
localStorage.setItem("currentEMail",JSON.stringify(mail));
}
\ No newline at end of file
......@@ -30,13 +30,17 @@ var Xinha = function() {
var AlohaInterface = function() {
this.name = "Aloha";
this.load = function() {
includeJS("aloha/aloha/plugins/com.gentics.aloha.plugins.Format/plugin.js");
includeJS("aloha/aloha/plugins/com.gentics.aloha.plugins.Table/plugin.js");
includeJS("aloha/aloha/plugins/com.gentics.aloha.plugins.List/plugin.js");
includeJS("aloha/aloha/plugins/com.gentics.aloha.plugins.Link/plugin.js");
$("div#page_content div.input").html("<div id='aloha_editable'>test</div>");
$("#aloha_editable").css("min-height","15em").css("border","5px solid #3399FF").css("overflow","auto");
$("#aloha_editable").aloha();
GENTICS_Aloha_base="aloha/aloha/";
loadFile("aloha/aloha/aloha.js", "script", function(data) {
eval(data);
includeJS("aloha/aloha/plugins/com.gentics.aloha.plugins.Format/plugin.js");
includeJS("aloha/aloha/plugins/com.gentics.aloha.plugins.Table/plugin.js");
includeJS("aloha/aloha/plugins/com.gentics.aloha.plugins.List/plugin.js");
includeJS("aloha/aloha/plugins/com.gentics.aloha.plugins.Link/plugin.js");
$("div#page_content div.input").html("<div id='aloha_editable'>test</div>");
$("#aloha_editable").css("min-height","15em").css("border","5px solid #3399FF").css("overflow","auto");
$("#aloha_editable").aloha();
});
}
this.saveEdition = function() {
getCurrentDocument().saveEdition(GENTICS.Aloha.editables[0].getContents());
......@@ -48,6 +52,65 @@ var AlohaInterface = function() {
this.load();
}
var NicEdit = function() {
this.name = "NicEdit";
this.instance = null;
this.load = function() {
var nic = this;
loadFile("nicEdit/nicEdit.js","script",function(data) {
eval(data);
nic.instance = new nicEditor({iconsPath : 'nicEdit/nicEditorIcons.gif',fullPanel : true}).panelInstance('input_area');
});
}
this.saveEdition = function() {
getCurrentDocument().saveEdition($("div.input div.nicEdit-main").html());
}
this.loadContentFromDocument = function(doc) {
if(this.instance) {this.instance.removeInstance('input_area');this.instance=null}
$("#input_area").attr("value",doc.getContent());
this.instance = new nicEditor({iconsPath : 'nicEdit/nicEditorIcons.gif',fullPanel : true}).panelInstance('input_area');
}
this.load();
}
var TinyEdit = function() {
this.name = "TinyEdit";
this.load = function() {
loadFile("tinyEdit/tinyEdit.js","script",function(data) {
eval(data);
new TINY.editor.edit('editor',{
id:'input_area', // (required) ID of the textarea
width:584, // (optional) width of the editor
height:175, // (optional) heightof the editor
cssclass:'te', // (optional) CSS class of the editor
controlclass:'tecontrol', // (optional) CSS class of the buttons
rowclass:'teheader', // (optional) CSS class of the button rows
dividerclass:'tedivider', // (optional) CSS class of the button diviers
controls:['bold', 'italic', 'underline', 'strikethrough', '|', 'subscript', 'superscript', '|', 'orderedlist', 'unorderedlist', '|' ,'outdent' ,'indent', '|', 'leftalign', 'centeralign', 'rightalign', 'blockjustify', '|', 'unformat', '|', 'undo', 'redo', 'n', 'font', 'size', 'style', '|', 'image', 'hr', 'link', 'unlink', '|', 'cut', 'copy', 'paste', 'print'], // (required) options you want available, a '|' represents a divider and an 'n' represents a new row
footer:true, // (optional) show the footer
fonts:['Verdana','Arial','Georgia','Trebuchet MS'], // (optional) array of fonts to display
xhtml:true, // (optional) generate XHTML vs HTML
//cssfile:'style.css', // (optional) attach an external CSS file to the editor
content:'starting content', // (optional) set the starting content else it will default to the textarea content
css:'body{background-color:#ccc}', // (optional) attach CSS to the editor
bodyid:'editor', // (optional) attach an ID to the editor body
footerclass:'tefooter', // (optional) CSS class of the footer
toggle:{text:'source',activetext:'wysiwyg',cssclass:'toggle'}, // (optional) toggle to markup view options
resize:{cssclass:'resize'} // (optional) display options for the editor resize
});
});
}
this.saveEdition = function() {
getCurrentDocument().saveEdition($("#input").attr("value"));
}
this.loadContentFromDocument = function(doc) {
$("#input").attr("value",doc.getContent());
}
this.load();
}
/**
* Text documents
*
......
......@@ -61,7 +61,7 @@ Page.prototype = {
/* load the editor to work with and a new document to work on */
switch(this.name) {
case "text-editor":
editor = new AlohaInterface();
editor = new NicEdit();
doc=new JSONTextDocument();
break;
case "table-editor":
......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta name="generator" content="ERP5 - Copyright (C) 2001 - 2008. All rights reserved." />
<meta name="description"
content="ERP5 Free Open Source ERP and CRM" />
<meta name="keywords" content="" />
<meta name="robots" content="index, follow" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<title>ERP5 | ERP5</title>
<link type="text/css" rel="stylesheet" href="css/ung.css" />
<link type="text/css" rel="stylesheet" href="css/jquery-ui.css" />
<link type="text/css" rel="stylesheet" href="css/gadget.css" />
<script type="text/javascript" src="js/jquery/jquery.js"></script>
<script type="text/javascript" src="js/jquery/jquery-ui.js"></script>
<script type="text/javascript" src="js/tools.js"></script>
<script type="text/javascript" src="js/theme.js"></script>
<script type="text/javascript" src="js/mail.js"></script>
<link rel="icon" type="image/x-icon"
href="images/ung/favicon.ico" />
<link rel="shortcut icon" type="image/x-icon"
href="images/ung/favicon.ico" />
<script type="text/javascript">
var init = function() {
//delete localStorage.documentList;//delete the list for tests
setCurrentPage(new Page("mail"));//provide methods on the page
getCurrentStorage().getUser().setAsCurrentUser();//initialize the user
if(getCurrentDocumentID()&&getDocumentList().get(getCurrentDocumentID())) {
/* update the list with the modifications of the last edited document
* (this method has to been rewritten if using multi users) */
getDocumentList().updateDocumentInformation(getCurrentDocumentID());
delete localStorage.currentDocumentID;
getCurrentStorage().save();
}
waitBeforeSucceed(//display the list of documents
function(){return Line.loadHTML()},function() {
getDocumentList().resetSelectionList();
getDocumentList().updateDisplayInformation();
getDocumentList().display();
resize();}//hack for a bug with firefox
);
}
$(window).resize(resize);
$(document).ready(init);
</script>
</head>
<body>
<div class="container">
<div class="navigation">
<!-- Each aggregate of groups is a div wrapper -->
<div class="wrapper" id="wrapper_navigation">
<div class=" navigation-left">
<fieldset class="widget">
<legend class="group_title"></legend>
<div class="field" title="">
<label> navigation_box </label>
<div class="input"><div >
<a class="email" href="/ung/mail">Email</a>
<a class="document" href="mail.html">Documents</a>
<a class="calendar" href="/ung/calendar">Calendar</a>
</div></div>
</div>
</fieldset>
</div>
<div class=" navigation-right">
<fieldset class="widget">
<legend class="group_title"></legend>
<div class="field" title="">
<label> your_language </label>
<div class="input"><div >
<div id="select_language">
<ul><li>
<span id="current_language">en</span>
<img src="images/ung/arrow_20C.png"/>
<ul id="available_languages">
<li></li>
</ul>
</li></ul>
</div>
</div></div>
</div>
<div class="field" title="">
<label> user_login_box </label>
<div class="input"><div >
<a id="right_message">Not Implemented yet</a>
<div id="preference_dialog" title="UNG Preferences"></div>
<a id="userName">Unknown</a>
| <a id="settings" href="">Settings</a>
| <a id="help" href="">Help</a>
| <a id="sign_out" href="login.html" onclick="signOut()">Sign out</a>
</div></div>
</div>
</fieldset>
</div>
</div>
</div>
<div class="header">
<!-- Each aggregate of groups is a div wrapper -->
<div class="wrapper" id="wrapper_header">
<div class=" header-left">
<fieldset class="widget">
<legend class="group_title"></legend>
<div class="field" title="">
<label> search_bar </label>
<div class="input"><div >
<a class="ung_docs" href="mail.html">
<img src="images/ung/ung-logo.gif"/>
</a>
<a id="loading_message">Loading...</a>
<form>
<input type="text" name="field_your_search_text" class="field" onkeyup="submitFormOnEnter(event, this.form, 'WebSection_viewSearchResultList')" />
<input type="submit" value="Search Mail" name="WebSection_viewSearchResultList:method" />
</form>
</div></div>
</div>
</fieldset>
</div>
</div>
</div>
<div class="main">
<!-- Each aggregate of groups is a div wrapper -->
<div class="wrapper" id="wrapper_main">
<!--<td class=" main-left">-->
<div class=" main-left">
<fieldset class="widget">
<legend class="group_title"></legend>
<div class="field" title="">
<label> user_menu_box </label>
<div class="input"><div >
<div class="gadget-column">
<div class="gadget-action">
<input type="button" id="compose_mail" class="ung_button" name="Compose Mail" value="Compose Mail" />
<div class="file-selection">
<div class="file-quick-search">
<div class="listbox-tree">
<!-- Domain Report Tree mode -->
<div class="listbox-domain-tree-container">
<!-- Domain node contents -->
<table cellpadding="0"
summary="This table contains the domain tree"
class="your_listbox-table-domain-tree">
<tr>
<td colspan="1" class="listbox-table-domain-tree-cell">
<button type="submit"
id="inbox"
name="unfoldDomain:method"
class="tree-closed current_folder"
value="ung_domain/all_documents.0">Inbox</button>
</td>
</tr>
<tr>
<td colspan="1" class="listbox-table-domain-tree-cell">
<button type="submit"
name="unfoldDomain:method"
class="tree-closed"
value="ung_domain/by_subject.0">Sent Mail</button>
</td>
</tr>
<tr>
<td colspan="1" class="listbox-table-domain-tree-cell">
<button type="submit"
name="unfoldDomain:method"
class="tree-closed"
value="ung_domain/hidden.0">Drafts</button>
</td>
</tr>
<tr>
<td colspan="1" class="listbox-table-domain-tree-cell">
<button type="submit"
name="unfoldDomain:method"
class="tree-closed"
value="ung_domain/owner.0">Spam</button>
</td>
</tr>
<tr>
<td colspan="1" class="listbox-table-domain-tree-cell">
<button type="submit"
name="unfoldDomain:method"
class="tree-closed"
value="ung_domain/recent.0">Bin</button>
</td>
</tr>
<tr>
<td colspan="1" class="listbox-table-domain-tree-cell">
<button type="submit"
name="unfoldDomain:method"
class="tree-open"
value="ung_domain/shared.0">Labels :</button>
<ul>
<li class="label">
test1
</li>
<li class="label">
test2
</li>
</ul>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div></div>
</div>
</fieldset>
</div>
<div class=" main-right">
<fieldset class="widget">
<legend class="group_title"></legend>
<div class="field" title="">
<label> favorite_box </label>
<div class="input"><div >
<div class="favorite">
<a class="domain_selected"></a>
<a href="mail.html">Refresh</a>
</div>
</div></div>
</div>
<div class="field" title="">
<label> Toolbar </label>
<div class="input"><div >
<div class="toolbar">
<button class="delete ung_button"
onclick="getMailList().applyToSelection('delete')">Delete
</button>
<button name="#" class="change_state ung_button">Change State</button>
<div id="change_state" class="change_state option_menu">
<ul><li>
<div class="fix ung_button">
<span>Change State</span>
<img src="images/ung/arrow.png"/>
</div>
<ul>
<li>
<div onclick="getMailList().applyToSelection('read')">
<span>Mark as read</span>
</div>
</li>
<li>
<div onclick="getMailList().applyToSelection('unread')">
<span>Mark as unread</span>
</div>
</li>
<li>
<div onclick="getMailList().applyToSelection('moveTo','spam')">
<span>Spam</span>
</div>
</li>
<li>
<div onclick="getMailList().applyToSelection('moveTo','bin')">
<span>Delete</span>
</div>
</li>
</ul>
</li></ul>
</div>
<div id="move_to" class="move_to option_menu">
<ul><li>
<div class="fix ung_button">
<span>Move to</span>
<img src="images/ung/arrow.png"/>
</div>
<ul id="move_to_list">
<li>
<div onclick="getEMailList().applyToSelection('moveTo','inbox')">
<span>Inbox</span>
</div>
</li>
<li>
<div onclick="getEMailList().applyToSelection('moveTo','send')">
<span>Sent Mail</span>
</div>
</li>
<li>
<div onclick="getEMailList().applyToSelection('moveTo','spam')">
<span>Spam</span>
</div>
</li>
<li>
<div onclick="getEMailList().applyToSelection('moveTo','bin')">
<span>Delete</span>
</div>
</li>
</ul>
</li></ul>
</div>
<div class="listbox-navigation">
<button class="listbox_first_page your_listbox_first_page ung_button" onclick="getDocumentList().changePage(event)">
<span class="image"> </span>
</button>
<button class="listbox_previous_page your_listbox_previous_page ung_button" 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 ung_button" onclick="getDocumentList().changePage(event)">
<span class="image"> </span>
</button>
<button class="listbox_last_page your_listbox_last_page ung_button" onclick="getDocumentList().changePage(event)">
<span class="image"> </span>
</button>
</div>
<div class="listbox-head">
<div class="listbox-head-spacer"></div>
<div class="listbox-head-content">
<!-- Listbox head (in left) -->
<div class="listbox-head-title">
<!-- 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>
<!-- Listbox nagivation (in right) -->
<div class="listbox-head-navigation">
<!--Show search result in web mode-->
<div class="listbox-header-box">
<div class="listbox-number-of-records">
<!-- 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>
<!-- 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 selected rows number -->
<span id="selected_row_number" class="your_listbox-current-item-number">
- <a>0</a> items selected
</span>
</div>
</div>
<!--Page navigation -->
</div>
</div>
</div>
</div>
</div></div>
</div>
<div class="field" title="">
<label> Document List </label>
<div class="input">
<div class="listbox-container">
<div class="listbox-content listbox-content-fixed-width">
<div class="listbox-body">
<table class="listbox your_listbox your_listbox-table">
<thead>
<!--Column title -->
<tr class="listbox-label-line">
<!--Report tree-->
<!-- Anchor cell -->
<!-- Select cell -->
<th class="listbox-table-select-cell">
<input class="listbox-check-all" type="image"
name="your_listbox_checkAll:method"
value="1" alt="Check All"
title="Check All"
onclick="getDocumentList().checkAll()"
src="images/icons/checkall.png" />
&nbsp;
<input class="listbox-uncheck-all"
type="image"
name="your_listbox_uncheckAll:method"
value="1" alt="Uncheck All"
title="Uncheck All"
onclick="getDocumentList().resetSelectionList()"
src="images/icons/decheckall.png" />
</th>
<!-- Label column row -->
<th class="listbox-table-header-cell"></th>
<th class="listbox-table-header-cell">
<!-- Button in normal view -->
<!-- Button in gadget mode -->
<button type="button" class="sort-button"
onclick=""
title="Title">
<span>Title</span>
</button>
<!-- Icon showing sort order -->
<img src="images/ung/transparent-image.gif"
alt="Sort" class="sort-button"
title="Sort" />
</th>
<th class="listbox-table-header-cell">
<!-- Button in normal view -->
<!-- Button in gadget mode -->
<button type="button"
class="sort-button"
onclick=""
title="Sharing">
<span>Sharing</span>
</button>
<!-- Icon showing sort order -->
<img src="images/ung/transparent-image.gif"
alt="Sort" class="sort-button"
title="Sort" />
</th>
<th class="listbox-table-header-cell">
<!-- Button in normal view -->
<!-- Button in gadget mode -->
<button type="button"
class="sort-button"
onclick=""
title="Date">
<span>Date</span>
</button>
<!-- Icon showing sort order -->
<img src="images/ung/transparent-image.gif"
alt="Sort" class="sort-button"
title="Sort" />
</th>
</tr>
<!--Search column input -->
</thead>
<!-- Stats -->
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</fieldset>
</div>
</div>
</div></div>
</body>
</html>
\ No newline at end of file
......@@ -28,13 +28,6 @@
<script type="text/javascript" src="js/theme-mobile.js"></script>
<script type="text/javascript">//hack for aloha
if(supportedDocuments[getCurrentDocument().getType()].editorPage=="text-editor") {
GENTICS_Aloha_base="aloha/aloha/"
includeJS("aloha/aloha/aloha.js");
}
</script>
<script type="text/javascript">
// initialize
var initPage = function() {
......@@ -49,11 +42,6 @@
var init = function() {
initPage();
waitBeforeSucceed(function() {return getCurrentPage().getXML();},initUser);
//$("script#jquery_loader").remove();
//$("script#jquery_loader2").remove();
//$("#author").aloha();
}
$(document).ready(init);
</script>
......@@ -129,7 +117,7 @@
<label>search_bar</label>
<div class="input"><div >
<a class="ung_docs" onclick="stopDocumentEdition()">
<a class="ung_docs" href="ung-mobile.html" onclick="stopDocumentEdition()">
<img src="images/ung/ung-logo.gif" alt="logo"/>
</a>
......@@ -179,11 +167,9 @@
<fieldset class="bottom editable">
<div id="page_content" class="field page"
title="Contenu de la page web.">
<div id="page_content" class="field page">
</div>
<div id="document_content" class="field hidden"
title="The content of the document considered as a text string">
<div id="document_content" class="field hidden">
</div>
</fieldset>
......
......@@ -229,11 +229,9 @@
<fieldset class="bottom editable">
<div id="page_content" class="field page"
title="Contenu de la page web.">
<div id="page_content" class="field page">
</div>
<div id="document_content" class="field hidden"
title="The content of the document considered as a text string">
<div id="document_content" class="field hidden">
</div>
</fieldset>
......
......@@ -80,22 +80,48 @@
</td>
<td class="listbox-table-data-cell">
<a class="listbox-document-icon">
<img src="images/icons/document.png"/>
<img src=""/>
</a>
</td>
<td class='listbox-table-data-cell'>
<a class="listbox-document-title">Web Page</a>
<a class="listbox-document-title"></a>
</td>
<td class="listbox-table-data-cell">
<a class="listbox-document-state">Deleted</a>
<a class="listbox-document-state"></a>
</td>
<td class="listbox-table-data-cell">
<a class="listbox-document-date">2011/05/31&nbsp;&nbsp;&nbsp;11:44</a>
<a class="listbox-document-date"></a>
</td>
</tr>
</tbody>
</table>
</line>
<mail>
<table>
<tbody>
<tr>
<td class="listbox-table-select-cell">
<input type="checkbox"/>
</td>
<td class="listbox-table-data-cell">
<a class="listbox-email-attachment">
</a>
</td>
<td class='listbox-table-data-cell'>
<a class="listbox-email-sender"></a>
</td>
<td class="listbox-table-data-cell">
<a class="listbox-email-object"></a>
</td>
<td class="listbox-table-data-cell">
<a class="listbox-email-date"></a>
</td>
</tr>
</tbody>
</table>
</mail>
</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