| /* |
| * 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; |
| |
| }); |
| |
| |