Commit 380a62c2 authored by Tristan Cavelier's avatar Tristan Cavelier

First Commit!

parents
This diff is collapsed.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jIO Complex Example</title>
</head>
<body>
<script type="text/javascript">
<!--
var logcolor = 'cyan';
var logGetColor = function () {
if (logcolor === 'white') {
logcolor = 'cyan';
} else {
logcolor = 'white';
}
return logcolor;
};
var log = function (o) {
var node = document.createElement ('div');
node.setAttribute('style','background-color:'+logGetColor()+';');
if (typeof o === 'string') {
node.textContent = o;
} else {
node.textContent = JSON.stringify (o);
}
document.getElementById('log').appendChild(node);
};
var error = function (o) {
var node = document.createElement ('div');
node.setAttribute('style','background-color:'+logGetColor()+
';color:red;font-weight:bold');
if (typeof o === 'string') {
node.textContent = o;
} else {
node.textContent = JSON.stringify (o);
}
document.getElementById('log').appendChild(node);
};
var clearlog = function () {
document.getElementById('log').innerHTML = '';
};
//-->
</script>
<div id="main">
<table>
<tr style="font-style:italic;">
<th>simple storage</th><th>multi storage</th><th>distant storage</th>
<th>conflict managing</th><th>custom storage description</th>
</tr>
<tr>
<th>local</th><th>crypt & local</th><th>dav</th>
<th>conflictmanager & local</th><th>custom</th>
</tr>
<tr>
<th>
<input type="text" id="localuser" value="localuser" placeholder="username" /><br />
<input type="text" id="localapp" value="localapp" placeholder="applicationname" /><br />
</th>
<th>
<input type="text" id="cryptuser" value="cryptuser" placeholder="username" /><br />
<input type="text" id="cryptapp" value="cryptapp" placeholder="applicationname" /><br />
<input type="password" id="cryptpassword" value="pwd" placeholder="password" /><br />
</th>
<th>
<input type="text" id="davuser" value="" placeholder="username" /><br />
<input type="text" id="davapp" value="" placeholder="applicationname" /><br />
<input type="password" id="davpassword" value="" placeholder="password" /><br />
<input type="text" id="davurl" value="" placeholder="url" /><br />
</th>
<th>
<input type="text" id="conflictuser" value="localuser" placeholder="username" /><br />
<input type="text" id="conflictapp" value="localapp" placeholder="applicationname" /><br />
</th>
<th style="width:100%;">
<textarea id="customstorage" style="width:100%;">{&quot;type&quot;:&quot;local&quot;,&quot;username&quot;:&quot;customuser&quot;,&quot;applicationname&quot;:&quot;customapp&quot;,&quot;customkey&quot;:&quot;customvalue&quot;}</textarea>
</th>
</tr>
<tr>
<th><button onclick="newLocalJio()">Create New jIO</button></th>
<th><button onclick="newCryptJio()">Create New jIO</button></th>
<th><button onclick="newDavJio()">Create New jIO</button></th>
<th><button onclick="newConflictJio()">Create New jIO</button></th>
<th><button onclick="newCustomJio()">Create New jIO</button></th>
</tr>
</table>
</div>
<hr />
<input type="text" id="filepath" value="" placeholder="filepath" />
<input type="text" id="content" value="" placeholder="content" />
<input type="text" id="prev_rev" value="" placeholder="previous revision" />
<br />
<label for="show_conflicts">Show Conflicts</label>
<input type="checkbox" id="show_conflicts" />,
<label for="show_revision_history">Show Revision History</label>
<input type="checkbox" id="show_revision_history" />,
<label for="show_revision_info">Show Revision Info</label>
<input type="checkbox" id="show_revision_info" />,
<label for="last_revision">Remove Last Revision</label>
<input type="checkbox" id="last_revision" />,<br />
<label for="max_retry">Max Retry</label>
<input type="number" id="max_retry" value="0" style="width:30px;"/>
(0 = infinite),
<label for="metadata_only">Metadata Only</label>
<input type="checkbox" id="metadata_only" />
<hr />
<button onclick="post()">post</button>
<button onclick="put()">put</button>
<button onclick="get()">get</button>
<button onclick="remove()">remove</button>
<button onclick="allDocs()">allDocs</button><br />
<button onclick="printLocalStorage()">print localStorage</button>
<button onclick="localStorage.clear()">clear localStorage</button><br />
<button onclick="clearlog()">Clear Log</button>
<hr />
<div id="log">
</div>
<script type="text/javascript" src="../localorcookiestorage.js"></script>
<script type="text/javascript" src="../jio.js"></script>
<script type="text/javascript" src="../lib/jquery/jquery.min.js"></script>
<script type="text/javascript" src="../lib/base64/base64.js"></script>
<script type="text/javascript" src="../lib/sjcl/sjcl.min.js"></script>
<script type="text/javascript" src="../lib/jsSha2/sha2.js"></script>
<script type="text/javascript" src="../jio.storage.js"></script>
<script type="text/javascript">
<!--
var my_jio = null;
var newLocalJio = function () {
var localuser, localapp;
localuser = $('#localuser').attr('value');
localapp = $('#localapp').attr('value');
var spec = {type: 'local', username: localuser, applicationname: localapp};
if (my_jio) { log('closing older jio'); my_jio.close(); }
log ('local storage description object: ' + JSON.stringify (spec));
my_jio = jIO.newJio(spec);
};
var newCryptJio = function () {
var user, app, pwd;
user = $('#cryptuser').attr('value');
app = $('#cryptapp').attr('value');
pwd = $('#cryptpassword').attr('value');
var spec = {type: 'crypt', username: user, password: pwd, storage:{
type: 'local', username: user, applicationname: app
}};
if (my_jio) { log('closing older jio'); my_jio.close(); }
log ('crypt storage description object: ' + JSON.stringify (spec));
my_jio = jIO.newJio(spec);
};
var newDavJio = function () {
var user, app, pwd, url;
user = $('#davuser').attr('value');
app = $('#davapp').attr('value');
pwd = $('#davpassword').attr('value');
url = $('#davurl').attr('value');
var spec = {
type: 'dav', username: user, applicationname: app,
password: pwd, url: url
};
if (my_jio) { log('closing older jio'); my_jio.close(); }
log ('dav storage description object: ' + JSON.stringify (spec));
my_jio = jIO.newJio(spec);
};
var newConflictJio = function () {
var user, app;
user = $('#conflictuser').attr('value');
app = $('#conflictapp').attr('value');
var spec = {
type: 'conflictmanager', storage: {
type: 'local', username: user, applicationname: app
}
};
if (my_jio) { log('closing older jio'); my_jio.close(); }
log ('conflict manager storage description object: '+JSON.stringify (spec));
my_jio = jIO.newJio(spec);
};
var newCustomJio = function () {
var spec = JSON.parse ($('#customstorage').text());
if (my_jio) { log('closing older jio'); my_jio.close(); }
log ('custom storage description object: '+JSON.stringify (spec));
my_jio = jIO.newJio(spec);
};
var printLocalStorage = function () {
var i;
log ('LOCALSTORAGE');
for (i in localStorage) {
log ('- '+ i +': '+localStorage[i]);
}
log ('------------------------------');
};
var callback = function (err,val,begin_date) {
log ('time : ' + (Date.now() - begin_date));
if (err) {
return error ('return :' + JSON.stringify (err));
}
log ('return : ' + JSON.stringify (val));
};
var command = function (method) {
var begin_date = Date.now(), doc = {}, opts = {};
log (method);
if (!my_jio) {
return error ('no jio set');
}
opts.conflicts = $('#show_conflicts').attr('checked')?true:false;
opts.revs = $('#show_revision_history').attr('checked')?true:false;
opts.revs_info = $('#show_revision_info').attr('checked')?true:false;
opts.max_retry = parseInt($('#max_retry').attr('value') || '0');
opts.metadata_only = $('#metadata_only').attr('checked')?true:false;
switch (method) {
case 'post':
case 'put':
doc.content = $('#content').attr('value');
doc._id = $('#filepath').attr('value');
doc._rev = $('#prev_rev').attr('value') || undefined;
break;
case 'remove':
doc._id = $('#filepath').attr('value');
opts.rev = ($('#last_revision').attr('checked')?'last':undefined) ||
$('#prev_rev').attr('value') || undefined;
break;
case 'get':
doc = $('#filepath').attr('value');
case 'allDocs':
break;
}
log ('doc: ' + JSON.stringify (doc));
log ('opts: ' + JSON.stringify (opts));
switch (method) {
case 'remove':
case 'post':
case 'put':
case 'get':
my_jio[method](doc,opts,function (err,val) {
callback(err,val,begin_date);
});
break;
case 'allDocs':
my_jio[method](opts,function (err,val) {
callback(err,val,begin_date);
});
break;
}
};
var post = function () {
command('post');
};
var put = function () {
command('put');
};
var get = function () {
command('get');
};
var remove = function () {
command('remove');
};
var allDocs = function () {
command('allDocs');
}
//-->
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jIO Example</title>
</head>
<body>
<script type="text/javascript">
<!--
var log = function (o) {
var node = document.createElement ('div');
node.textContent = o;
document.getElementById('log').appendChild(node);
};
//-->
</script>
<div id="log">
</div>
<script type="text/javascript" src="../localorcookiestorage.js"></script>
<script type="text/javascript" src="../jio.js"></script>
<script type="text/javascript" src="../lib/jquery/jquery.min.js"></script>
<script type="text/javascript" src="../lib/base64/base64.js"></script>
<script type="text/javascript" src="../lib/sjcl/sjcl.min.js"></script>
<script type="text/javascript" src="../lib/jsSha2/sha2.js"></script>
<script type="text/javascript" src="../jio.storage.js"></script>
<script type="text/javascript">
<!--
var my_jio = null;
log ('Welcome to the jIO example.html!')
log ('--> Create jIO instance');
my_jio = jIO.newJio({
type: 'local', username: 'jIOtest', applicationname: 'example'
});
log ('--> put "hello" document to localStorage');
// careful ! asynchronous method
my_jio.put({_id:'hello',content:'world'},function (val) {
log ('done');
}, function (err) {
log ('error!');
});
setTimeout ( function () {
log ('--> get "hello" document from localStorage');
my_jio.get('hello',function (val) {
log ('done, content: ' + val.content);
}, function (err) {
log ('error!');
});
}, 500);
//-->
</script>
</body>
</html>
/*global module:false*/
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: '<json:package.json>',
meta: {
banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - '+
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
'<%= pkg.homepage ? "* " + pkg.homepage + "\n" : "" %>' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> Nexedi;' +
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */'
},
concat: {
dist: {
src: ['<banner:meta.banner>',
'<file_strip_banner:../../src/<%= pkg.name %>.js>'],
dest: '../../<%= pkg.name %>.js'
}
},
min: {
dist: {
src: ['<banner:meta.banner>', '<config:concat.dist.dest>'],
dest: '../../<%= pkg.name %>.min.js'
}
},
qunit: {
files: []
},
lint: {
files: ['grunt.js','../../src/<%= pkg.name %>.js']
},
watch: {
files: '<config:lint.files>',
tasks: 'lint'
},
jshint: {
options: {
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
boss: true,
eqnull: true,
browser: true
},
globals: {
jQuery: true,
LocalOrCookieStorage: true,
Base64: true,
JIO: true,
console: true,
unescape: true,
// Needed to avoid "not defined error" with requireJs
define: true,
require: true,
// Needed to avoid "not defined error" with sinonJs
sinon: true,
module: true,
test: true,
ok: true,
deepEqual: true,
expect: true,
stop: true,
start: true,
equal: true
}
},
uglify: {}
});
// Default task.
grunt.registerTask('default', 'lint concat min');
};
{
"name": "localorcookiestorage",
"title": "Local Or Cookie Storage",
"description": "A small API which can manipulate data into local persistent storage.",
"version": "0.1.0",
"homepage": "",
"author": {
"name": "Tristan Cavelier",
"email": "tristan.cavelier@tiolive.com"
},
"repository": {
"type": "git",
"url": "http://git.erp5.org/repos/ung.git"
},
"bugs": {
"url": ""
},
"licenses": [
],
"dependencies": {
},
"keywords": []
}
auto: grunt
grunt:
grunt
/*global module:false*/
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: '<json:package.json>',
meta: {
banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - '+
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
'<%= pkg.homepage ? "* " + pkg.homepage + "\n" : "" %>' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> Nexedi;' +
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */'
},
concat: {
dist: {
src: ['<banner:meta.banner>',
'<file_strip_banner:../../src/<%= pkg.name %>/intro.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/localstorage.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/davstorage.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/replicatestorage.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/indexstorage.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/cryptstorage.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/conflictmanagerstorage.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/outro.js>'],
dest: '../../<%= pkg.name %>.js'
}
},
min: {
dist: {
src: ['<banner:meta.banner>', '<config:concat.dist.dest>'],
dest: '../../<%= pkg.name %>.min.js'
}
},
qunit: {
files: []
},
lint: {
files: ['grunt.js','../../<%= pkg.name %>.js']
},
watch: {
files: '<config:lint.files>',
tasks: 'lint'
},
jshint: {
options: {
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
boss: true,
eqnull: true,
browser: true
},
globals: {
jQuery: true,
sjcl: true,
LocalOrCookieStorage: true,
Base64: true,
MD5: true,
hex_sha256: true,
jIO: true,
console: true,
unescape: true,
// Needed to avoid "not defined error" with requireJs
define: true,
require: true,
// Needed to avoid "not defined error" with sinonJs
sinon: true,
module: true,
test: true,
ok: true,
deepEqual: true,
expect: true,
stop: true,
start: true,
equal: true
}
},
uglify: {}
});
// Default task.
grunt.registerTask('default', 'concat lint min');
};
{
"name": "jio.storage",
"title": "JIO Storage",
"description": "Javascript Input Output Storage",
"version": "0.1.0",
"homepage": "",
"author": {
"name": "Tristan Cavelier",
"email": "tristan.cavelier@tiolive.com"
},
"repository": {
"type": "git",
"url": "http://git.erp5.org/repos/ung.git"
},
"bugs": {
"url": ""
},
"licenses": [
],
"dependencies": {
"jquery": "~1.7"
},
"keywords": []
}
auto: grunt
grunt:
grunt
/*global module:false*/
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: '<json:package.json>',
meta: {
banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - '+
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
'<%= pkg.homepage ? "* " + pkg.homepage + "\n" : "" %>' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> Nexedi;' +
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */'
},
concat: {
dist: {
src: ['<banner:meta.banner>',
// Wrapper top
'<file_strip_banner:../../src/<%= pkg.name %>/intro.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/exceptions.js>',
// Jio wrapper top
'<file_strip_banner:../../src/<%= pkg.name %>/jio.intro.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/storages/storage.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/commands/command.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/commands/allDocsCommand.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/commands/getCommand.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/commands/removeCommand.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/commands/putCommand.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/commands/postCommand.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/jobs/status/jobStatus.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/jobs/status/doneStatus.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/jobs/status/failStatus.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/jobs/status/initialStatus.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/jobs/status/onGoingStatus.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/jobs/status/waitStatus.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/jobs/job.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/announcements/announcement.js>',
// Singletons
'<file_strip_banner:../../src/<%= pkg.name %>/activityUpdater.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/announcements/announcer.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/jobs/jobIdHandler.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/jobs/jobManager.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/jobs/jobRules.js>',
// Jio wrappor bottem
'<file_strip_banner:../../src/<%= pkg.name %>/jio.outro.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/jioNamespace.js>',
// Wrapper bottom
'<file_strip_banner:../../src/<%= pkg.name %>/outro.js>'],
dest: '../../<%= pkg.name %>.js'
}
},
min: {
dist: {
src: ['<banner:meta.banner>', '<config:concat.dist.dest>'],
dest: '../../<%= pkg.name %>.min.js'
}
},
qunit: {
files: [// '../../test/jiotests.html',
'../../test/jiotests_withoutrequirejs.html']
},
lint: {
files: ['grunt.js',
'../../<%= pkg.name %>.js']
// '../../js/base64.requirejs_module.js',
// '../../src/jio.dummystorages.js',
// '../../js/jquery.requirejs_module.js',
// '../../test/jiotests.js',
// '../../test/jiotests.loader.js']
},
watch: {
files: '<config:lint.files>',
tasks: 'lint qunit'
},
jshint: {
options: {
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
boss: true,
eqnull: true,
browser: true
},
globals: {
LocalOrCookieStorage: true,
console: true,
unescape: true,
// Needed to avoid "not defined error" with requireJs
define: true,
require: true,
// Needed to avoid "not defined error" with sinonJs
sinon: true,
module: true,
test: true,
ok: true,
deepEqual: true,
expect: true,
stop: true,
start: true,
equal: true
}
},
uglify: {}
});
// Default task.
grunt.registerTask('default', 'concat lint min');
};
{
"name": "jio",
"title": "JIO",
"description": "Javascript Input Output",
"version": "0.1.0",
"homepage": "",
"author": {
"name": "Tristan Cavelier",
"email": "tristan.cavelier@tiolive.com"
},
"repository": {
"type": "git",
"url": "http://git.erp5.org/repos/ung.git"
},
"bugs": {
"url": ""
},
"licenses": [
],
"dependencies": {
"jquery": "~1.7"
},
"keywords": []
}
#!/bin/bash
for node in `ls -1` ; do
if [ -d "$node" ] ; then
printf "\n\033[1m\033[36mmake -C %s\033[0m\n" "$node"
make -C "$node"
fi
done
/**
*
* 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;
}
}
This diff is collapsed.
12/21/2004 - version 0.3
- Fixed copyright notice
- Included license.txt file
- Added readme.txt
- Released to the public
04/09/2003 - version 0.2
- sha256 rewritten ussing some code and ideas
from Paul Johnston's sha1.js
- Now is possible to get the hash as a string,
base 64 encoded or hex encoded.
- It can now calculate the hash from unicode
strings.
- Hexadecimal hash can be lowercase (default)
or uppercase.
- Optimized the rest of the code.
- Written the test page with the test vectors from
nist paper.
- Tested on OE 6.0 and OE 6.0SP1.
04/08/2003 - version 0.1
- First sha256 implementation. It's a dirty one, but works.
- Tested on OE 6.0SP1
\ No newline at end of file
jsSHA2 - OpenSource JavaScript implementation of the Secure Hash Algorithms,
SHA-256-384-512 - http://anmar.eu.org/projects/jssha2/
Introduction
--------------------------------
jsSHA2 is an OpenSource JavaScript implementation of the Secure Hash Algorithm,
SHA-256-384-512. As defined by NIST:
'All of the algorithms are iterative, one-way hash functions that can process a
message to produce a condensed representation called a message digest. These
algorithms enable the determination of a message’s integrity: any change to the
message will, with a very high probability, result in a different message digest.
This property is useful in the generation and verification of digital signatures
and message authentication codes, and in the generation of random numbers (bits)'
File description
--------------------------------
sha2.js:
Full implementation, it gives the hash as a string, base64 encoded or hex encoded.
sha256.js:
Is a stripped down version for using only SHA-256 in web based apps. It only gives
hex output.
Features
--------------------------------
There is a working implementation of SHA-256.
Instructions
--------------------------------
Reference the appropriate file from your page:
<script type="text/javascript" src="sha256.js"></script>
Then, use it:
<script language="JavaScript">
hash = hex_sha256("test string");
</script>
Authors
--------------------------------
- Angel Marin <anmar at gmx.net> - http://anmar.eu.org/
License
--------------------------------
- Read the included license.txt
--------------------------------
Angel Marin 2003 - 2004 - http://anmar.eu.org/
Copyright (c) 2003-2004, Angel Marin
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
/* A JavaScript implementation of the Secure Hash Standard
* Version 0.3 Copyright Angel Marin 2003-2004 - http://anmar.eu.org/
* Distributed under the BSD License
* Some bits taken from Paul Johnston's SHA-1 implementation
*/
(function () {
var chrsz = 8;/* bits per input character. 8 - ASCII; 16 - Unicode */
var hexcase = 0;/* hex output format. 0 - lowercase; 1 - uppercase */
function safe_add (x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
function S (X, n) {return ( X >>> n ) | (X << (32 - n));}
function R (X, n) {return ( X >>> n );}
function Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
function Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
function Sigma0256(x) {return (S(x, 2) ^ S(x, 13) ^ S(x, 22));}
function Sigma1256(x) {return (S(x, 6) ^ S(x, 11) ^ S(x, 25));}
function Gamma0256(x) {return (S(x, 7) ^ S(x, 18) ^ R(x, 3));}
function Gamma1256(x) {return (S(x, 17) ^ S(x, 19) ^ R(x, 10));}
function Sigma0512(x) {return (S(x, 28) ^ S(x, 34) ^ S(x, 39));}
function Sigma1512(x) {return (S(x, 14) ^ S(x, 18) ^ S(x, 41));}
function Gamma0512(x) {return (S(x, 1) ^ S(x, 8) ^ R(x, 7));}
function Gamma1512(x) {return (S(x, 19) ^ S(x, 61) ^ R(x, 6));}
function newArray (n) {
var a = [];
for (;n>0;n--) {
a.push(undefined);
}
return a;
}
function core_sha256 (m, l) {
var K = [0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2];
var HASH = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19];
var W = newArray(64);
var a, b, c, d, e, f, g, h, i, j;
var T1, T2;
/* append padding */
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >> 9) << 4) + 15] = l;
for ( var i = 0; i<m.length; i+=16 ) {
a = HASH[0];
b = HASH[1];
c = HASH[2];
d = HASH[3];
e = HASH[4];
f = HASH[5];
g = HASH[6];
h = HASH[7];
for ( var j = 0; j<64; j++) {
if (j < 16) {
W[j] = m[j + i];
} else {
W[j] = safe_add(safe_add(safe_add(Gamma1256(
W[j - 2]),W[j - 7]),Gamma0256(W[j - 15])), W[j - 16]);
}
T1 = safe_add(safe_add(safe_add(safe_add(
h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
T2 = safe_add(Sigma0256(a), Maj(a, b, c));
h = g;
g = f;
f = e;
e = safe_add(d, T1);
d = c;
c = b;
b = a;
a = safe_add(T1, T2);
}
HASH[0] = safe_add(a, HASH[0]);
HASH[1] = safe_add(b, HASH[1]);
HASH[2] = safe_add(c, HASH[2]);
HASH[3] = safe_add(d, HASH[3]);
HASH[4] = safe_add(e, HASH[4]);
HASH[5] = safe_add(f, HASH[5]);
HASH[6] = safe_add(g, HASH[6]);
HASH[7] = safe_add(h, HASH[7]);
}
return HASH;
}
function core_sha512 (m, l) {
var K = [0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817];
var HASH = [0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179];
var W = newArray(80);
var a, b, c, d, e, f, g, h, i, j;
var T1, T2;
}
function str2binb (str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for(var i = 0; i < str.length * chrsz; i += chrsz)
bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32);
return bin;
}
function binb2str (bin) {
var str = "";
var mask = (1 << chrsz) - 1;
for(var i = 0; i < bin.length * 32; i += chrsz)
str += String.fromCharCode((bin[i>>5] >>> (24 - i%32)) & mask);
return str;
}
function binb2hex (binarray) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for(var i = 0; i < binarray.length * 4; i++)
{
str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
}
return str;
}
function binb2b64 (binarray) {
var tab =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var str = "";
for(var i = 0; i < binarray.length * 4; i += 3) {
var triplet = (((binarray[i >> 2] >> 8 * (3- i %4)) & 0xFF) << 16) |
(((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) |
((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
for(var j = 0; j < 4; j++) {
if(i * 8 + j * 6 > binarray.length * 32) { str += b64pad; }
else {str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);}
}
}
return str;
}
function hex_sha256(s){
return binb2hex(core_sha256(str2binb(s),s.length * chrsz));
}
function b64_sha256(s){
return binb2b64(core_sha256(str2binb(s),s.length * chrsz));
}
function str_sha256(s){
return binb2str(core_sha256(str2binb(s),s.length * chrsz));
}
window.hex_sha256 = hex_sha256;
window.b64_sha256 = b64_sha256;
window.str_sha256 = str_sha256;
}());
/* A JavaScript implementation of the Secure Hash Algorithm, SHA-256
* Version 0.3 Copyright Angel Marin 2003-2004 - http://anmar.eu.org/
* Distributed under the BSD License
* Some bits taken from Paul Johnston's SHA-1 implementation
*/
(function () {
var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
function safe_add (x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
function S (X, n) {return ( X >>> n ) | (X << (32 - n));}
function R (X, n) {return ( X >>> n );}
function Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
function Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
function Sigma0256(x) {return (S(x, 2) ^ S(x, 13) ^ S(x, 22));}
function Sigma1256(x) {return (S(x, 6) ^ S(x, 11) ^ S(x, 25));}
function Gamma0256(x) {return (S(x, 7) ^ S(x, 18) ^ R(x, 3));}
function Gamma1256(x) {return (S(x, 17) ^ S(x, 19) ^ R(x, 10));}
function newArray (n) {
var a = [];
for (;n>0;n--) {
a.push(undefined);
}
return a;
}
function core_sha256 (m, l) {
var K = [0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2];
var HASH = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19];
var W = newArray(64);
var a, b, c, d, e, f, g, h, i, j;
var T1, T2;
/* append padding */
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >> 9) << 4) + 15] = l;
for ( var i = 0; i<m.length; i+=16 ) {
a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3];
e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7];
for ( var j = 0; j<64; j++) {
if (j < 16) {
W[j] = m[j + i];
} else {
W[j] = safe_add(safe_add(safe_add(Gamma1256(
W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
}
T1 = safe_add(safe_add(safe_add(
safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
T2 = safe_add(Sigma0256(a), Maj(a, b, c));
h = g; g = f; f = e; e = safe_add(d, T1);
d = c; c = b; b = a; a = safe_add(T1, T2);
}
HASH[0] = safe_add(a, HASH[0]); HASH[1] = safe_add(b, HASH[1]);
HASH[2] = safe_add(c, HASH[2]); HASH[3] = safe_add(d, HASH[3]);
HASH[4] = safe_add(e, HASH[4]); HASH[5] = safe_add(f, HASH[5]);
HASH[6] = safe_add(g, HASH[6]); HASH[7] = safe_add(h, HASH[7]);
}
return HASH;
}
function str2binb (str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for(var i = 0; i < str.length * chrsz; i += chrsz)
bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32);
return bin;
}
function binb2hex (binarray) {
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for (var i = 0; i < binarray.length * 4; i++) {
str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
}
return str;
}
function hex_sha256(s){
return binb2hex(core_sha256(str2binb(s),s.length * chrsz));
}
window.hex_sha256 = hex_sha256;
}());
<html>
<head>
<title>anmar.eu.org - CTNjsSha2: sha2 test page</title>
<script language="JavaScript" src="../sha2.js"></script>
</head>
<body onload="testSHA2()">
<form name="testform256">
<input type="text" name="orig256" size="75" value="abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" onchange="testSHA256()"><br>
<input type="text" name="calc256" size="75" value="" disabled="true"><br>
<input type="text" name="control256" size="75" value="248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" onchange="testSHA256()"><br>
<input type="text" name="result256" size="15" value="Testing...">
</form>
<script language="JavaScript">
function testSHA2 () {
testSHA256();
}
function testSHA256 () {
document.testform256.calc256.value = hex_sha256 (document.testform256.orig256.value);
if (document.testform256.calc256.value == document.testform256.control256.value) {
document.testform256.result256.value="OK";
} else {
document.testform256.result256.value="Error";
}
}
</script>
</body>
</html>
/**
* QUnit v1.5.0 - A JavaScript Unit Testing Framework
*
* http://docs.jquery.com/QUnit
*
* Copyright (c) 2012 John Resig, Jörn Zaefferer
* Dual licensed under the MIT (MIT-LICENSE.txt)
* or GPL (GPL-LICENSE.txt) licenses.
*/
/** Font Family and Sizes */
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
}
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
#qunit-tests { font-size: smaller; }
/** Resets */
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
margin: 0;
padding: 0;
}
/** Header */
#qunit-header {
padding: 0.5em 0 0.5em 1em;
color: #8699a4;
background-color: #0d3349;
font-size: 1.5em;
line-height: 1em;
font-weight: normal;
border-radius: 15px 15px 0 0;
-moz-border-radius: 15px 15px 0 0;
-webkit-border-top-right-radius: 15px;
-webkit-border-top-left-radius: 15px;
}
#qunit-header a {
text-decoration: none;
color: #c2ccd1;
}
#qunit-header a:hover,
#qunit-header a:focus {
color: #fff;
}
#qunit-header label {
display: inline-block;
}
#qunit-banner {
height: 5px;
}
#qunit-testrunner-toolbar {
padding: 0.5em 0 0.5em 2em;
color: #5E740B;
background-color: #eee;
}
#qunit-userAgent {
padding: 0.5em 0 0.5em 2.5em;
background-color: #2b81af;
color: #fff;
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
}
/** Tests: Pass/Fail */
#qunit-tests {
list-style-position: inside;
}
#qunit-tests li {
padding: 0.4em 0.5em 0.4em 2.5em;
border-bottom: 1px solid #fff;
list-style-position: inside;
}
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
display: none;
}
#qunit-tests li strong {
cursor: pointer;
}
#qunit-tests li a {
padding: 0.5em;
color: #c2ccd1;
text-decoration: none;
}
#qunit-tests li a:hover,
#qunit-tests li a:focus {
color: #000;
}
#qunit-tests ol {
margin-top: 0.5em;
padding: 0.5em;
background-color: #fff;
border-radius: 15px;
-moz-border-radius: 15px;
-webkit-border-radius: 15px;
box-shadow: inset 0px 2px 13px #999;
-moz-box-shadow: inset 0px 2px 13px #999;
-webkit-box-shadow: inset 0px 2px 13px #999;
}
#qunit-tests table {
border-collapse: collapse;
margin-top: .2em;
}
#qunit-tests th {
text-align: right;
vertical-align: top;
padding: 0 .5em 0 0;
}
#qunit-tests td {
vertical-align: top;
}
#qunit-tests pre {
margin: 0;
white-space: pre-wrap;
word-wrap: break-word;
}
#qunit-tests del {
background-color: #e0f2be;
color: #374e0c;
text-decoration: none;
}
#qunit-tests ins {
background-color: #ffcaca;
color: #500;
text-decoration: none;
}
/*** Test Counts */
#qunit-tests b.counts { color: black; }
#qunit-tests b.passed { color: #5E740B; }
#qunit-tests b.failed { color: #710909; }
#qunit-tests li li {
margin: 0.5em;
padding: 0.4em 0.5em 0.4em 0.5em;
background-color: #fff;
border-bottom: none;
list-style-position: inside;
}
/*** Passing Styles */
#qunit-tests li li.pass {
color: #5E740B;
background-color: #fff;
border-left: 26px solid #C6E746;
}
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
#qunit-tests .pass .test-name { color: #366097; }
#qunit-tests .pass .test-actual,
#qunit-tests .pass .test-expected { color: #999999; }
#qunit-banner.qunit-pass { background-color: #C6E746; }
/*** Failing Styles */
#qunit-tests li li.fail {
color: #710909;
background-color: #fff;
border-left: 26px solid #EE5757;
white-space: pre;
}
#qunit-tests > li:last-child {
border-radius: 0 0 15px 15px;
-moz-border-radius: 0 0 15px 15px;
-webkit-border-bottom-right-radius: 15px;
-webkit-border-bottom-left-radius: 15px;
}
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
#qunit-tests .fail .test-name,
#qunit-tests .fail .module-name { color: #000000; }
#qunit-tests .fail .test-actual { color: #EE5757; }
#qunit-tests .fail .test-expected { color: green; }
#qunit-banner.qunit-fail { background-color: #EE5757; }
/** Result */
#qunit-testresult {
padding: 0.5em 0.5em 0.5em 2.5em;
color: #2b81af;
background-color: #D2E0E6;
border-bottom: 1px solid white;
}
#qunit-testresult .module-name {
font-weight: bold;
}
/** Fixture */
#qunit-fixture {
position: absolute;
top: -10000px;
left: -10000px;
width: 1000px;
height: 1000px;
}
This diff is collapsed.
This diff is collapsed.
/**
* sinon-qunit 1.0.0, 2010/12/09
*
* @author Christian Johansen (christian@cjohansen.no)
*
* (The BSD License)
*
* Copyright (c) 2010-2011, Christian Johansen, christian@cjohansen.no
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Christian Johansen nor the names of his contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*global sinon, QUnit, test*/
sinon.assert.fail = function (msg) {
QUnit.ok(false, msg);
};
sinon.assert.pass = function (assertion) {
QUnit.ok(true, assertion);
};
sinon.config = {
injectIntoThis: true,
injectInto: null,
properties: ["spy", "stub", "mock", "clock", "sandbox"],
useFakeTimers: true,
useFakeServer: false
};
(function (global) {
var qTest = QUnit.test;
QUnit.test = global.test = function (testName, expected, callback, async) {
if (arguments.length === 2) {
callback = expected;
expected = null;
}
return qTest(testName, expected, sinon.test(callback), async);
};
}(this));
This diff is collapsed.
This diff is collapsed.
// Adds 3 dummy storages to JIO
// type:
// - dummyallok
// - dummyallfail
// - dummyallnotfound
// - dummyall3tries
(function () { var jioDummyStorageLoader = function ( jIO ) {
////////////////////////////////////////////////////////////////////////////
// Dummy Storage 1 : all ok
var newDummyStorageAllOk = function ( spec, my ) {
var that = my.basicStorage( spec, my );
var super_serialized = that.serialized;
that.serialized = function () {
var o = super_serialized();
o.username = spec.username;
return o;
};
that.post = function (command) {
setTimeout (function () {
that.success ({
ok:true,
id:command.getDocId()
});
}, 100);
}; // end post
that.put = function (command) {
setTimeout (function () {
that.success ({
ok:true,
id:command.getDocId()
});
}, 100); // 100 ms, for jiotests simple job waiting
}; // end put
that.get = function (command) {
setTimeout(function () {
that.success ({
_id:command.getDocId(),
content:'content',
_creation_date: 10000,
_last_modified: 15000
});
}, 100);
}; // end get
that.allDocs = function (command) {
setTimeout(function () {
var o = {
total_rows: 2,
rows: [{
id:'file',
key:'file',
value: {
content:'filecontent',
_creation_date:10000,
_last_modified:15000
}
},{
id:'memo',
key:'memo',
value: {
content:'memocontent',
_creation_date:20000,
_last_modified:25000
}
}]
};
if (command.getOption('metadata_only')) {
delete o.rows[0].value.content;
delete o.rows[1].value.content;
}
that.success (o);
}, 100);
}; // end allDocs
that.remove = function (command) {
setTimeout (function () {
that.success ({ok:true,id:command.getDocId()});
}, 100);
}; // end remove
return that;
},
// end Dummy Storage All Ok
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Dummy Storage 2 : all fail
newDummyStorageAllFail = function ( spec, my ) {
var that = my.basicStorage( spec, my ), priv = {};
priv.error = function () {
setTimeout (function () {
that.error ({status:0,statusText:'Unknown Error',
error:'unknown_error',
message:'Execution encountred an error.',
reason:'Execution encountred an error'});
});
};
that.post = function (command) {
priv.error();
}; // end post
that.put = function (command) {
priv.error();
}; // end put
that.get = function (command) {
priv.error();
}; // end get
that.allDocs = function (command) {
priv.error();
}; // end allDocs
that.remove = function (command) {
priv.error();
}; // end remove
return that;
},
// end Dummy Storage All Fail
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Dummy Storage 3 : all not found
newDummyStorageAllNotFound = function ( spec, my ) {
var that = my.basicStorage( spec, my );
that.post = function (command) {
setTimeout (function () {
that.success ({
ok:true,
id:command.getDocId()
});
}, 100);
}; // end post
that.put = function (command) {
setTimeout (function () {
that.success ({
ok:true,
id:command.getDocId()
});
}, 100);
}; // end put
that.get = function (command) {
setTimeout(function () {
that.error ({status:404,statusText:'Not Found',
error:'not_found',
message:'Document "'+ command.getDocId() +
'" not found.',
reason:'Document "'+ command.getDocId() +
'" not found'});
}, 100);
}; // end get
that.allDocs = function (command) {
setTimeout(function () {
that.error ({status:404,statusText:'Not Found',
error:'not_found',
message:'User list not found.',
reason:'User list not found'});
}, 100);
}; // end allDocs
that.remove = function (command) {
setTimeout (function () {
that.success ({
ok:true,
id:command.getDocId()
});
}, 100);
}; // end remove
return that;
},
// end Dummy Storage All Not Found
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Dummy Storage 4 : all 3 tries
newDummyStorageAll3Tries = function ( spec, my ) {
var that = my.basicStorage( spec, my ), priv = {};
// this serialized method is used to make simple difference between
// two dummyall3tries storages:
// so {type:'dummyall3tries',a:'b'} differs from
// {type:'dummyall3tries',c:'d'}.
var super_serialized = that.serialized;
that.serialized = function () {
var o = super_serialized();
o.applicationname = spec.applicationname;
return o;
};
priv.doJob = function (command,if_ok_return) {
// wait a little in order to simulate asynchronous operation
setTimeout(function () {
priv.Try3OKElseFail (command.getTried(),if_ok_return);
}, 100);
};
priv.Try3OKElseFail = function (tries,if_ok_return) {
if ( typeof tries === 'undefined' ) {
return that.error ({status:0,statusText:'Unknown Error',
error:'unknown_error',
message:'Cannot get tried.',
reason:'Cannot get tried'});
}
if ( tries < 3 ) {
return that.retry (
{message:'' + (3 - tries) + ' tries left.'});
}
if ( tries === 3 ) {
return that.success (if_ok_return);
}
if ( tries > 3 ) {
return that.error ({status:1,statusText:'Too Much Tries',
error:'too_much_tries',
message:'Too much tries.',
reason:'Too much tries'});
}
};
that.post = function (command) {
priv.doJob (command,{ok:true,id:command.getDocId()});
}; // end post
that.put = function (command) {
priv.doJob (command,{ok:true,id:command.getDocId()});
}; // end put
that.get = function (command) {
priv.doJob (command,{
_id: command.getDocId(),
content: 'content '+command.getDocId(),
_creation_date: 11000,
_last_modified: 17000
});
}; // end get
that.allDocs = function (command) {
priv.doJob(command,{
total_rows:2,
rows:[{
id:'file',key:'file',
value:{
_creation_date:10000,
_last_modified:15000
}
},{
id:'memo',key:'memo',
value:{
_creation_date:20000,
_last_modified:25000
}
}]});
}; // end allDocs
that.remove = function (command) {
priv.doJob(command,{ok:true,id:command.getDocId()});
}; // end remove
return that;
};
// end Dummy Storage All 3 Tries
////////////////////////////////////////////////////////////////////////////
// add key to storageObjectType of global jio
jIO.addStorageType('dummyallok', newDummyStorageAllOk);
jIO.addStorageType('dummyallfail', newDummyStorageAllFail);
jIO.addStorageType('dummyallnotfound', newDummyStorageAllNotFound);
jIO.addStorageType('dummyall3tries', newDummyStorageAll3Tries);
};
if (window.requirejs) {
define ('JIODummyStorages',['jIO'], jioDummyStorageLoader);
} else {
jioDummyStorageLoader ( jIO );
}
}());
auto: grunt
check-syntax: grunt
grunt:
make -C ../../grunt/*_gruntJIOStorage > /dev/null 2>&1
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/**
* Adds 6 storages to JIO.
* - LocalStorage ('local')
* - DAVStorage ('dav')
* - ReplicateStorage ('replicate')
* - IndexedStorage ('indexed')
* - CryptedStorage ('crypted')
* - ConflictManagerStorage ('conflictmanager')
*
* @module JIOStorages
*/
(function(LocalOrCookieStorage, $, Base64, sjcl, hex_sha256, jIO) {
This diff is collapsed.
}( LocalOrCookieStorage, jQuery, Base64, sjcl, hex_sha256, jIO ));
var newReplicateStorage = function ( spec, my ) {
spec = spec || {};
var that = my.basicStorage( spec, my ), priv = {};
priv.return_value_array = [];
priv.storagelist = spec.storagelist || [];
priv.nb_storage = priv.storagelist.length;
var super_serialized = that.serialized;
that.serialized = function () {
var o = super_serialized();
o.storagelist = priv.storagelist;
return o;
};
that.validateState = function () {
if (priv.storagelist.length === 0) {
return 'Need at least one parameter: "storagelist" '+
'containing at least one storage.';
}
return '';
};
priv.isTheLast = function (error_array) {
return (error_array.length === priv.nb_storage);
};
priv.doJob = function (command,errormessage,nodocid) {
var done = false, error_array = [], i,
error = function (err) {
if (!done) {
error_array.push(err);
if (priv.isTheLast(error_array)) {
that.error ({
status:207,
statusText:'Multi-Status',
error:'multi_status',
message:'All '+errormessage+
(!nodocid?' "'+command.getDocId()+'"':' ') +
' requests have failed.',
reason:'requests fail',
array:error_array
});
}
}
},
success = function (val) {
if (!done) {
done = true;
that.success (val);
}
};
for (i = 0; i < priv.nb_storage; i+= 1) {
var cloned_option = command.cloneOption();
that.addJob (command.getLabel(),priv.storagelist[i],
command.cloneDoc(),cloned_option,success,error);
}
};
that.post = function (command) {
priv.doJob (command,'post');
that.end();
};
/**
* Save a document in several storages.
* @method put
*/
that.put = function (command) {
priv.doJob (command,'put');
that.end();
};
/**
* Load a document from several storages, and send the first retreived
* document.
* @method get
*/
that.get = function (command) {
priv.doJob (command,'get');
that.end();
};
/**
* Get a document list from several storages, and returns the first
* retreived document list.
* @method allDocs
*/
that.allDocs = function (command) {
priv.doJob (command,'allDocs',true);
that.end();
};
/**
* Remove a document from several storages.
* @method remove
*/
that.remove = function (command) {
priv.doJob (command,'remove');
that.end();
};
return that;
};
jIO.addStorageType('replicate', newReplicateStorage);
This diff is collapsed.
auto: grunt
check-syntax: grunt
grunt:
make -C ../../grunt/*_gruntJIO > /dev/null 2>&1
This diff is collapsed.
This diff is collapsed.
var announcer = (function(spec, my) {
var that = {};
spec = spec || {};
my = my || {};
// Attributes //
var announcement_o = {};
// Methods //
that.register = function(name) {
if(!announcement_o[name]) {
announcement_o[name] = announcement();
}
};
that.unregister = function(name) {
if (announcement_o[name]) {
delete announcement_o[name];
}
};
that.at = function(name) {
return announcement_o[name];
};
that.on = function(name, callback) {
that.register(name);
that.at(name).add(callback);
};
that.trigger = function(name, args) {
that.at(name).trigger(args);
};
return that;
}());
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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