mirror of
https://github.com/YunoHost-Apps/rocketchat_ynh.git
synced 2024-09-03 20:16:25 +02:00
241 lines
19 KiB
JavaScript
241 lines
19 KiB
JavaScript
(function () {
|
|
|
|
/* Imports */
|
|
var Meteor = Package.meteor.Meteor;
|
|
var _ = Package.underscore._;
|
|
|
|
/* Package-scope variables */
|
|
var OrderedDict;
|
|
|
|
(function(){
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/ordered-dict/ordered_dict.js //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// This file defines an ordered dictionary abstraction that is useful for // 1
|
|
// maintaining a dataset backed by observeChanges. It supports ordering items // 2
|
|
// by specifying the item they now come before. // 3
|
|
// 4
|
|
// The implementation is a dictionary that contains nodes of a doubly-linked // 5
|
|
// list as its values. // 6
|
|
// 7
|
|
// constructs a new element struct // 8
|
|
// next and prev are whole elements, not keys. // 9
|
|
var element = function (key, value, next, prev) { // 10
|
|
return { // 11
|
|
key: key, // 12
|
|
value: value, // 13
|
|
next: next, // 14
|
|
prev: prev // 15
|
|
}; // 16
|
|
}; // 17
|
|
OrderedDict = function (/* ... */) { // 18
|
|
var self = this; // 19
|
|
self._dict = {}; // 20
|
|
self._first = null; // 21
|
|
self._last = null; // 22
|
|
self._size = 0; // 23
|
|
var args = _.toArray(arguments); // 24
|
|
self._stringify = function (x) { return x; }; // 25
|
|
if (typeof args[0] === 'function') // 26
|
|
self._stringify = args.shift(); // 27
|
|
_.each(args, function (kv) { // 28
|
|
self.putBefore(kv[0], kv[1], null); // 29
|
|
}); // 30
|
|
}; // 31
|
|
// 32
|
|
_.extend(OrderedDict.prototype, { // 33
|
|
// the "prefix keys with a space" thing comes from here // 34
|
|
// https://github.com/documentcloud/underscore/issues/376#issuecomment-2815649
|
|
_k: function (key) { return " " + this._stringify(key); }, // 36
|
|
// 37
|
|
empty: function () { // 38
|
|
var self = this; // 39
|
|
return !self._first; // 40
|
|
}, // 41
|
|
size: function () { // 42
|
|
var self = this; // 43
|
|
return self._size; // 44
|
|
}, // 45
|
|
_linkEltIn: function (elt) { // 46
|
|
var self = this; // 47
|
|
if (!elt.next) { // 48
|
|
elt.prev = self._last; // 49
|
|
if (self._last) // 50
|
|
self._last.next = elt; // 51
|
|
self._last = elt; // 52
|
|
} else { // 53
|
|
elt.prev = elt.next.prev; // 54
|
|
elt.next.prev = elt; // 55
|
|
if (elt.prev) // 56
|
|
elt.prev.next = elt; // 57
|
|
} // 58
|
|
if (self._first === null || self._first === elt.next) // 59
|
|
self._first = elt; // 60
|
|
}, // 61
|
|
_linkEltOut: function (elt) { // 62
|
|
var self = this; // 63
|
|
if (elt.next) // 64
|
|
elt.next.prev = elt.prev; // 65
|
|
if (elt.prev) // 66
|
|
elt.prev.next = elt.next; // 67
|
|
if (elt === self._last) // 68
|
|
self._last = elt.prev; // 69
|
|
if (elt === self._first) // 70
|
|
self._first = elt.next; // 71
|
|
}, // 72
|
|
putBefore: function (key, item, before) { // 73
|
|
var self = this; // 74
|
|
if (self._dict[self._k(key)]) // 75
|
|
throw new Error("Item " + key + " already present in OrderedDict"); // 76
|
|
var elt = before ? // 77
|
|
element(key, item, self._dict[self._k(before)]) : // 78
|
|
element(key, item, null); // 79
|
|
if (elt.next === undefined) // 80
|
|
throw new Error("could not find item to put this one before"); // 81
|
|
self._linkEltIn(elt); // 82
|
|
self._dict[self._k(key)] = elt; // 83
|
|
self._size++; // 84
|
|
}, // 85
|
|
append: function (key, item) { // 86
|
|
var self = this; // 87
|
|
self.putBefore(key, item, null); // 88
|
|
}, // 89
|
|
remove: function (key) { // 90
|
|
var self = this; // 91
|
|
var elt = self._dict[self._k(key)]; // 92
|
|
if (elt === undefined) // 93
|
|
throw new Error("Item " + key + " not present in OrderedDict"); // 94
|
|
self._linkEltOut(elt); // 95
|
|
self._size--; // 96
|
|
delete self._dict[self._k(key)]; // 97
|
|
return elt.value; // 98
|
|
}, // 99
|
|
get: function (key) { // 100
|
|
var self = this; // 101
|
|
if (self.has(key)) // 102
|
|
return self._dict[self._k(key)].value; // 103
|
|
return undefined; // 104
|
|
}, // 105
|
|
has: function (key) { // 106
|
|
var self = this; // 107
|
|
return _.has(self._dict, self._k(key)); // 108
|
|
}, // 109
|
|
// Iterate through the items in this dictionary in order, calling // 110
|
|
// iter(value, key, index) on each one. // 111
|
|
// 112
|
|
// Stops whenever iter returns OrderedDict.BREAK, or after the last element. // 113
|
|
forEach: function (iter) { // 114
|
|
var self = this; // 115
|
|
var i = 0; // 116
|
|
var elt = self._first; // 117
|
|
while (elt !== null) { // 118
|
|
var b = iter(elt.value, elt.key, i); // 119
|
|
if (b === OrderedDict.BREAK) // 120
|
|
return; // 121
|
|
elt = elt.next; // 122
|
|
i++; // 123
|
|
} // 124
|
|
}, // 125
|
|
first: function () { // 126
|
|
var self = this; // 127
|
|
if (self.empty()) // 128
|
|
return undefined; // 129
|
|
return self._first.key; // 130
|
|
}, // 131
|
|
firstValue: function () { // 132
|
|
var self = this; // 133
|
|
if (self.empty()) // 134
|
|
return undefined; // 135
|
|
return self._first.value; // 136
|
|
}, // 137
|
|
last: function () { // 138
|
|
var self = this; // 139
|
|
if (self.empty()) // 140
|
|
return undefined; // 141
|
|
return self._last.key; // 142
|
|
}, // 143
|
|
lastValue: function () { // 144
|
|
var self = this; // 145
|
|
if (self.empty()) // 146
|
|
return undefined; // 147
|
|
return self._last.value; // 148
|
|
}, // 149
|
|
prev: function (key) { // 150
|
|
var self = this; // 151
|
|
if (self.has(key)) { // 152
|
|
var elt = self._dict[self._k(key)]; // 153
|
|
if (elt.prev) // 154
|
|
return elt.prev.key; // 155
|
|
} // 156
|
|
return null; // 157
|
|
}, // 158
|
|
next: function (key) { // 159
|
|
var self = this; // 160
|
|
if (self.has(key)) { // 161
|
|
var elt = self._dict[self._k(key)]; // 162
|
|
if (elt.next) // 163
|
|
return elt.next.key; // 164
|
|
} // 165
|
|
return null; // 166
|
|
}, // 167
|
|
moveBefore: function (key, before) { // 168
|
|
var self = this; // 169
|
|
var elt = self._dict[self._k(key)]; // 170
|
|
var eltBefore = before ? self._dict[self._k(before)] : null; // 171
|
|
if (elt === undefined) // 172
|
|
throw new Error("Item to move is not present"); // 173
|
|
if (eltBefore === undefined) { // 174
|
|
throw new Error("Could not find element to move this one before"); // 175
|
|
} // 176
|
|
if (eltBefore === elt.next) // no moving necessary // 177
|
|
return; // 178
|
|
// remove from its old place // 179
|
|
self._linkEltOut(elt); // 180
|
|
// patch into its new place // 181
|
|
elt.next = eltBefore; // 182
|
|
self._linkEltIn(elt); // 183
|
|
}, // 184
|
|
// Linear, sadly. // 185
|
|
indexOf: function (key) { // 186
|
|
var self = this; // 187
|
|
var ret = null; // 188
|
|
self.forEach(function (v, k, i) { // 189
|
|
if (self._k(k) === self._k(key)) { // 190
|
|
ret = i; // 191
|
|
return OrderedDict.BREAK; // 192
|
|
} // 193
|
|
return undefined; // 194
|
|
}); // 195
|
|
return ret; // 196
|
|
}, // 197
|
|
_checkRep: function () { // 198
|
|
var self = this; // 199
|
|
_.each(self._dict, function (k, v) { // 200
|
|
if (v.next === v) // 201
|
|
throw new Error("Next is a loop"); // 202
|
|
if (v.prev === v) // 203
|
|
throw new Error("Prev is a loop"); // 204
|
|
}); // 205
|
|
} // 206
|
|
// 207
|
|
}); // 208
|
|
OrderedDict.BREAK = {"break": true}; // 209
|
|
// 210
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
/* Exports */
|
|
if (typeof Package === 'undefined') Package = {};
|
|
Package['ordered-dict'] = {
|
|
OrderedDict: OrderedDict
|
|
};
|
|
|
|
})();
|
|
|
|
//# sourceMappingURL=ordered-dict.js.map
|