| 'use strict'; |
| |
| function Sorter() { |
| } |
| |
| Sorter.prototype.sort = function(tokens, fromIndex) { |
| fromIndex = fromIndex || 0; |
| for (var i = 0, len = this.keys.length; i < len; i++) { |
| var key = this.keys[i]; |
| var token = key.slice(1); |
| var index = tokens.indexOf(token, fromIndex); |
| if (index !== -1) { |
| do { |
| if (index !== fromIndex) { |
| tokens.splice(index, 1); |
| tokens.splice(fromIndex, 0, token); |
| } |
| fromIndex++; |
| } while ((index = tokens.indexOf(token, fromIndex)) !== -1); |
| return this[key].sort(tokens, fromIndex); |
| } |
| } |
| return tokens; |
| }; |
| |
| function TokenChain() { |
| } |
| |
| TokenChain.prototype = { |
| add: function(tokens) { |
| var self = this; |
| tokens.forEach(function(token) { |
| var key = '$' + token; |
| if (!self[key]) { |
| self[key] = []; |
| self[key].processed = 0; |
| } |
| self[key].push(tokens); |
| }); |
| }, |
| createSorter: function() { |
| var self = this; |
| var sorter = new Sorter(); |
| sorter.keys = Object.keys(self).sort(function(j, k) { |
| var m = self[j].length; |
| var n = self[k].length; |
| return m < n ? 1 : m > n ? -1 : j < k ? -1 : j > k ? 1 : 0; |
| }).filter(function(key) { |
| if (self[key].processed < self[key].length) { |
| var token = key.slice(1); |
| var chain = new TokenChain(); |
| self[key].forEach(function(tokens) { |
| var index; |
| while ((index = tokens.indexOf(token)) !== -1) { |
| tokens.splice(index, 1); |
| } |
| tokens.forEach(function(token) { |
| self['$' + token].processed++; |
| }); |
| chain.add(tokens.slice(0)); |
| }); |
| sorter[key] = chain.createSorter(); |
| return true; |
| } |
| return false; |
| }); |
| return sorter; |
| } |
| }; |
| |
| module.exports = TokenChain; |