blob: 8f158081916ce40c0989d7b4736644901fe25e4a [file] [log] [blame]
/*
* NOTE:
* This temporarily uses the PouchDB map reduce implementation
* These files are modified locally until we make a more general version and
* push it back upstream.
* Original file:
* https://github.com/daleharvey/pouchdb/blob/master/src/pouch.collate.js
*/
/*
(function() {
// a few hacks to get things in the right place for node.js
if (typeof module !== 'undefined' && module.exports) {
module.exports = Pouch;
}
*/
define([
"app",
"api",
// Modules
"addons/pouchdb/pouch.collate.js"
],
function(app, FauxtonAPI, Collate) {
var Pouch = {};
Pouch.collate = function(a, b) {
var ai = collationIndex(a);
var bi = collationIndex(b);
if ((ai - bi) !== 0) {
return ai - bi;
}
if (a === null) {
return 0;
}
if (typeof a === 'number') {
return a - b;
}
if (typeof a === 'boolean') {
return a < b ? -1 : 1;
}
if (typeof a === 'string') {
return stringCollate(a, b);
}
if (Array.isArray(a)) {
return arrayCollate(a, b);
}
if (typeof a === 'object') {
return objectCollate(a, b);
}
};
var stringCollate = function(a, b) {
// See: https://github.com/daleharvey/pouchdb/issues/40
// This is incompatible with the CouchDB implementation, but its the
// best we can do for now
return (a === b) ? 0 : ((a > b) ? 1 : -1);
};
var objectCollate = function(a, b) {
var ak = Object.keys(a), bk = Object.keys(b);
var len = Math.min(ak.length, bk.length);
for (var i = 0; i < len; i++) {
// First sort the keys
var sort = Pouch.collate(ak[i], bk[i]);
if (sort !== 0) {
return sort;
}
// if the keys are equal sort the values
sort = Pouch.collate(a[ak[i]], b[bk[i]]);
if (sort !== 0) {
return sort;
}
}
return (ak.length === bk.length) ? 0 :
(ak.length > bk.length) ? 1 : -1;
};
var arrayCollate = function(a, b) {
var len = Math.min(a.length, b.length);
for (var i = 0; i < len; i++) {
var sort = Pouch.collate(a[i], b[i]);
if (sort !== 0) {
return sort;
}
}
return (a.length === b.length) ? 0 :
(a.length > b.length) ? 1 : -1;
};
// The collation is defined by erlangs ordered terms
// the atoms null, true, false come first, then numbers, strings,
// arrays, then objects
var collationIndex = function(x) {
var id = ['boolean', 'number', 'string', 'object'];
if (id.indexOf(typeof x) !== -1) {
if (x === null) {
return 1;
}
return id.indexOf(typeof x) + 2;
}
if (Array.isArray(x)) {
return 4.5;
}
};
return Pouch;
});