wuira 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/README.md +62 -792
- package/data/icons/forever.json +90051 -0
- package/docs/icons.md +28 -0
- package/docs/source-converters.md +34 -0
- package/lib/datasources/DataSource.d.ts +8 -0
- package/lib/datasources/DataSource.lua +7 -0
- package/lib/datasources/GroupMembers.d.ts +6 -0
- package/lib/datasources/GroupMembers.lua +332 -0
- package/lib/datasources/GroupRoster.d.ts +28 -0
- package/lib/datasources/GroupRoster.lua +611 -0
- package/lib/datasources/MathConverter.d.ts +6 -0
- package/lib/datasources/MathConverter.lua +61 -0
- package/lib/datasources/MathExpression.d.ts +16 -0
- package/lib/datasources/MathExpression.lua +281 -0
- package/lib/datasources/Resources.d.ts +3 -2
- package/lib/datasources/Resources.lua +57 -48
- package/lib/datasources/SourceConverter.d.ts +39 -0
- package/lib/datasources/SourceConverter.lua +568 -0
- package/lib/datasources/UnitInfo.d.ts +6 -0
- package/lib/datasources/UnitInfo.lua +347 -15
- package/lib/datasources/UnitSource.d.ts +8 -3
- package/lib/datasources/UnitSource.lua +318 -5
- package/lib/datasources/index.d.ts +7 -1
- package/lib/datasources/index.lua +15 -0
- package/lib/icons/index.d.ts +45634 -0
- package/lib/icons/index.lua +3 -0
- package/lib/index.d.ts +1 -0
- package/lib/store/index.lua +20 -18
- package/lib/ui/Cell.d.ts +2 -0
- package/lib/ui/ForEach.d.ts +18 -4
- package/lib/ui/ForEach.lua +763 -13
- package/lib/ui/index.d.ts +1 -1
- package/package.json +20 -4
- package/tools/build-library.mjs +1 -1
- package/tools/generate-icons.mjs +10 -0
- package/tools/icon-data.mjs +59 -0
- package/tools/update-icons.mjs +36 -0
package/lib/ui/ForEach.lua
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
|
|
2
2
|
-- Lua Library inline imports
|
|
3
|
+
local function __TS__ObjectRest(target, usedProperties)
|
|
4
|
+
local result = {}
|
|
5
|
+
for property in pairs(target) do
|
|
6
|
+
if not usedProperties[property] then
|
|
7
|
+
result[property] = target[property]
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
return result
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
local function __TS__ArrayIsArray(value)
|
|
14
|
+
return type(value) == "table" and (value[1] ~= nil or next(value) == nil)
|
|
15
|
+
end
|
|
16
|
+
|
|
3
17
|
local function __TS__ArrayMap(self, callbackfn, thisArg)
|
|
4
18
|
local result = {}
|
|
5
19
|
for i = 1, #self do
|
|
@@ -7,24 +21,760 @@ local function __TS__ArrayMap(self, callbackfn, thisArg)
|
|
|
7
21
|
end
|
|
8
22
|
return result
|
|
9
23
|
end
|
|
24
|
+
|
|
25
|
+
local function __TS__NumberIsFinite(value)
|
|
26
|
+
return type(value) == "number" and value == value and value ~= math.huge and value ~= -math.huge
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
local function __TS__NumberIsInteger(value)
|
|
30
|
+
return __TS__NumberIsFinite(value) and math.floor(value) == value
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
local function __TS__Class(self)
|
|
34
|
+
local c = {prototype = {}}
|
|
35
|
+
c.prototype.__index = c.prototype
|
|
36
|
+
c.prototype.constructor = c
|
|
37
|
+
return c
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
local __TS__Symbol, Symbol
|
|
41
|
+
do
|
|
42
|
+
local symbolMetatable = {__tostring = function(self)
|
|
43
|
+
return ("Symbol(" .. (self.description or "")) .. ")"
|
|
44
|
+
end}
|
|
45
|
+
function __TS__Symbol(description)
|
|
46
|
+
return setmetatable({description = description}, symbolMetatable)
|
|
47
|
+
end
|
|
48
|
+
Symbol = {
|
|
49
|
+
asyncDispose = __TS__Symbol("Symbol.asyncDispose"),
|
|
50
|
+
dispose = __TS__Symbol("Symbol.dispose"),
|
|
51
|
+
iterator = __TS__Symbol("Symbol.iterator"),
|
|
52
|
+
hasInstance = __TS__Symbol("Symbol.hasInstance"),
|
|
53
|
+
species = __TS__Symbol("Symbol.species"),
|
|
54
|
+
toStringTag = __TS__Symbol("Symbol.toStringTag")
|
|
55
|
+
}
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
local __TS__Iterator
|
|
59
|
+
do
|
|
60
|
+
local function iteratorGeneratorStep(self)
|
|
61
|
+
local co = self.____coroutine
|
|
62
|
+
local status, value = coroutine.resume(co)
|
|
63
|
+
if not status then
|
|
64
|
+
error(value, 0)
|
|
65
|
+
end
|
|
66
|
+
if coroutine.status(co) == "dead" then
|
|
67
|
+
return
|
|
68
|
+
end
|
|
69
|
+
return true, value
|
|
70
|
+
end
|
|
71
|
+
local function iteratorIteratorStep(self)
|
|
72
|
+
local result = self:next()
|
|
73
|
+
if result.done then
|
|
74
|
+
return
|
|
75
|
+
end
|
|
76
|
+
return true, result.value
|
|
77
|
+
end
|
|
78
|
+
local function iteratorStringStep(self, index)
|
|
79
|
+
index = index + 1
|
|
80
|
+
if index > #self then
|
|
81
|
+
return
|
|
82
|
+
end
|
|
83
|
+
return index, string.sub(self, index, index)
|
|
84
|
+
end
|
|
85
|
+
function __TS__Iterator(iterable)
|
|
86
|
+
if type(iterable) == "string" then
|
|
87
|
+
return iteratorStringStep, iterable, 0
|
|
88
|
+
elseif iterable.____coroutine ~= nil then
|
|
89
|
+
return iteratorGeneratorStep, iterable
|
|
90
|
+
elseif iterable[Symbol.iterator] then
|
|
91
|
+
local iterator = iterable[Symbol.iterator](iterable)
|
|
92
|
+
return iteratorIteratorStep, iterator
|
|
93
|
+
else
|
|
94
|
+
return ipairs(iterable)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
local Map
|
|
100
|
+
do
|
|
101
|
+
Map = __TS__Class()
|
|
102
|
+
Map.name = "Map"
|
|
103
|
+
function Map.prototype.____constructor(self, entries)
|
|
104
|
+
self[Symbol.toStringTag] = "Map"
|
|
105
|
+
self.items = {}
|
|
106
|
+
self.size = 0
|
|
107
|
+
self.nextKey = {}
|
|
108
|
+
self.previousKey = {}
|
|
109
|
+
if entries == nil then
|
|
110
|
+
return
|
|
111
|
+
end
|
|
112
|
+
local iterable = entries
|
|
113
|
+
if iterable[Symbol.iterator] then
|
|
114
|
+
local iterator = iterable[Symbol.iterator](iterable)
|
|
115
|
+
while true do
|
|
116
|
+
local result = iterator:next()
|
|
117
|
+
if result.done then
|
|
118
|
+
break
|
|
119
|
+
end
|
|
120
|
+
local value = result.value
|
|
121
|
+
self:set(value[1], value[2])
|
|
122
|
+
end
|
|
123
|
+
else
|
|
124
|
+
local array = entries
|
|
125
|
+
for ____, kvp in ipairs(array) do
|
|
126
|
+
self:set(kvp[1], kvp[2])
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
function Map.prototype.clear(self)
|
|
131
|
+
self.items = {}
|
|
132
|
+
self.nextKey = {}
|
|
133
|
+
self.previousKey = {}
|
|
134
|
+
self.firstKey = nil
|
|
135
|
+
self.lastKey = nil
|
|
136
|
+
self.size = 0
|
|
137
|
+
end
|
|
138
|
+
function Map.prototype.delete(self, key)
|
|
139
|
+
local contains = self:has(key)
|
|
140
|
+
if contains then
|
|
141
|
+
self.size = self.size - 1
|
|
142
|
+
local next = self.nextKey[key]
|
|
143
|
+
local previous = self.previousKey[key]
|
|
144
|
+
if next ~= nil and previous ~= nil then
|
|
145
|
+
self.nextKey[previous] = next
|
|
146
|
+
self.previousKey[next] = previous
|
|
147
|
+
elseif next ~= nil then
|
|
148
|
+
self.firstKey = next
|
|
149
|
+
self.previousKey[next] = nil
|
|
150
|
+
elseif previous ~= nil then
|
|
151
|
+
self.lastKey = previous
|
|
152
|
+
self.nextKey[previous] = nil
|
|
153
|
+
else
|
|
154
|
+
self.firstKey = nil
|
|
155
|
+
self.lastKey = nil
|
|
156
|
+
end
|
|
157
|
+
self.nextKey[key] = nil
|
|
158
|
+
self.previousKey[key] = nil
|
|
159
|
+
end
|
|
160
|
+
self.items[key] = nil
|
|
161
|
+
return contains
|
|
162
|
+
end
|
|
163
|
+
function Map.prototype.forEach(self, callback)
|
|
164
|
+
for ____, key in __TS__Iterator(self:keys()) do
|
|
165
|
+
callback(nil, self.items[key], key, self)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
function Map.prototype.get(self, key)
|
|
169
|
+
return self.items[key]
|
|
170
|
+
end
|
|
171
|
+
function Map.prototype.has(self, key)
|
|
172
|
+
return self.nextKey[key] ~= nil or self.lastKey == key
|
|
173
|
+
end
|
|
174
|
+
function Map.prototype.set(self, key, value)
|
|
175
|
+
local isNewValue = not self:has(key)
|
|
176
|
+
if isNewValue then
|
|
177
|
+
self.size = self.size + 1
|
|
178
|
+
end
|
|
179
|
+
self.items[key] = value
|
|
180
|
+
if self.firstKey == nil then
|
|
181
|
+
self.firstKey = key
|
|
182
|
+
self.lastKey = key
|
|
183
|
+
elseif isNewValue then
|
|
184
|
+
self.nextKey[self.lastKey] = key
|
|
185
|
+
self.previousKey[key] = self.lastKey
|
|
186
|
+
self.lastKey = key
|
|
187
|
+
end
|
|
188
|
+
return self
|
|
189
|
+
end
|
|
190
|
+
Map.prototype[Symbol.iterator] = function(self)
|
|
191
|
+
return self:entries()
|
|
192
|
+
end
|
|
193
|
+
function Map.prototype.entries(self)
|
|
194
|
+
local function getFirstKey()
|
|
195
|
+
return self.firstKey
|
|
196
|
+
end
|
|
197
|
+
local items = self.items
|
|
198
|
+
local nextKey = self.nextKey
|
|
199
|
+
local key
|
|
200
|
+
local started = false
|
|
201
|
+
return {
|
|
202
|
+
[Symbol.iterator] = function(self)
|
|
203
|
+
return self
|
|
204
|
+
end,
|
|
205
|
+
next = function(self)
|
|
206
|
+
if not started then
|
|
207
|
+
started = true
|
|
208
|
+
key = getFirstKey(nil)
|
|
209
|
+
else
|
|
210
|
+
key = nextKey[key]
|
|
211
|
+
end
|
|
212
|
+
return {done = not key, value = {key, items[key]}}
|
|
213
|
+
end
|
|
214
|
+
}
|
|
215
|
+
end
|
|
216
|
+
function Map.prototype.keys(self)
|
|
217
|
+
local function getFirstKey()
|
|
218
|
+
return self.firstKey
|
|
219
|
+
end
|
|
220
|
+
local nextKey = self.nextKey
|
|
221
|
+
local key
|
|
222
|
+
local started = false
|
|
223
|
+
return {
|
|
224
|
+
[Symbol.iterator] = function(self)
|
|
225
|
+
return self
|
|
226
|
+
end,
|
|
227
|
+
next = function(self)
|
|
228
|
+
if not started then
|
|
229
|
+
started = true
|
|
230
|
+
key = getFirstKey(nil)
|
|
231
|
+
else
|
|
232
|
+
key = nextKey[key]
|
|
233
|
+
end
|
|
234
|
+
return {done = not key, value = key}
|
|
235
|
+
end
|
|
236
|
+
}
|
|
237
|
+
end
|
|
238
|
+
function Map.prototype.values(self)
|
|
239
|
+
local function getFirstKey()
|
|
240
|
+
return self.firstKey
|
|
241
|
+
end
|
|
242
|
+
local items = self.items
|
|
243
|
+
local nextKey = self.nextKey
|
|
244
|
+
local key
|
|
245
|
+
local started = false
|
|
246
|
+
return {
|
|
247
|
+
[Symbol.iterator] = function(self)
|
|
248
|
+
return self
|
|
249
|
+
end,
|
|
250
|
+
next = function(self)
|
|
251
|
+
if not started then
|
|
252
|
+
started = true
|
|
253
|
+
key = getFirstKey(nil)
|
|
254
|
+
else
|
|
255
|
+
key = nextKey[key]
|
|
256
|
+
end
|
|
257
|
+
return {done = not key, value = items[key]}
|
|
258
|
+
end
|
|
259
|
+
}
|
|
260
|
+
end
|
|
261
|
+
Map[Symbol.species] = Map
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
local function __TS__New(target, ...)
|
|
265
|
+
local instance = setmetatable({}, target.prototype)
|
|
266
|
+
instance:____constructor(...)
|
|
267
|
+
return instance
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
local Set
|
|
271
|
+
do
|
|
272
|
+
Set = __TS__Class()
|
|
273
|
+
Set.name = "Set"
|
|
274
|
+
function Set.prototype.____constructor(self, values)
|
|
275
|
+
self[Symbol.toStringTag] = "Set"
|
|
276
|
+
self.size = 0
|
|
277
|
+
self.nextKey = {}
|
|
278
|
+
self.previousKey = {}
|
|
279
|
+
if values == nil then
|
|
280
|
+
return
|
|
281
|
+
end
|
|
282
|
+
local iterable = values
|
|
283
|
+
if iterable[Symbol.iterator] then
|
|
284
|
+
local iterator = iterable[Symbol.iterator](iterable)
|
|
285
|
+
while true do
|
|
286
|
+
local result = iterator:next()
|
|
287
|
+
if result.done then
|
|
288
|
+
break
|
|
289
|
+
end
|
|
290
|
+
self:add(result.value)
|
|
291
|
+
end
|
|
292
|
+
else
|
|
293
|
+
local array = values
|
|
294
|
+
for ____, value in ipairs(array) do
|
|
295
|
+
self:add(value)
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
function Set.prototype.add(self, value)
|
|
300
|
+
local isNewValue = not self:has(value)
|
|
301
|
+
if isNewValue then
|
|
302
|
+
self.size = self.size + 1
|
|
303
|
+
end
|
|
304
|
+
if self.firstKey == nil then
|
|
305
|
+
self.firstKey = value
|
|
306
|
+
self.lastKey = value
|
|
307
|
+
elseif isNewValue then
|
|
308
|
+
self.nextKey[self.lastKey] = value
|
|
309
|
+
self.previousKey[value] = self.lastKey
|
|
310
|
+
self.lastKey = value
|
|
311
|
+
end
|
|
312
|
+
return self
|
|
313
|
+
end
|
|
314
|
+
function Set.prototype.clear(self)
|
|
315
|
+
self.nextKey = {}
|
|
316
|
+
self.previousKey = {}
|
|
317
|
+
self.firstKey = nil
|
|
318
|
+
self.lastKey = nil
|
|
319
|
+
self.size = 0
|
|
320
|
+
end
|
|
321
|
+
function Set.prototype.delete(self, value)
|
|
322
|
+
local contains = self:has(value)
|
|
323
|
+
if contains then
|
|
324
|
+
self.size = self.size - 1
|
|
325
|
+
local next = self.nextKey[value]
|
|
326
|
+
local previous = self.previousKey[value]
|
|
327
|
+
if next ~= nil and previous ~= nil then
|
|
328
|
+
self.nextKey[previous] = next
|
|
329
|
+
self.previousKey[next] = previous
|
|
330
|
+
elseif next ~= nil then
|
|
331
|
+
self.firstKey = next
|
|
332
|
+
self.previousKey[next] = nil
|
|
333
|
+
elseif previous ~= nil then
|
|
334
|
+
self.lastKey = previous
|
|
335
|
+
self.nextKey[previous] = nil
|
|
336
|
+
else
|
|
337
|
+
self.firstKey = nil
|
|
338
|
+
self.lastKey = nil
|
|
339
|
+
end
|
|
340
|
+
self.nextKey[value] = nil
|
|
341
|
+
self.previousKey[value] = nil
|
|
342
|
+
end
|
|
343
|
+
return contains
|
|
344
|
+
end
|
|
345
|
+
function Set.prototype.forEach(self, callback)
|
|
346
|
+
for ____, key in __TS__Iterator(self:keys()) do
|
|
347
|
+
callback(nil, key, key, self)
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
function Set.prototype.has(self, value)
|
|
351
|
+
return self.nextKey[value] ~= nil or self.lastKey == value
|
|
352
|
+
end
|
|
353
|
+
Set.prototype[Symbol.iterator] = function(self)
|
|
354
|
+
return self:values()
|
|
355
|
+
end
|
|
356
|
+
function Set.prototype.entries(self)
|
|
357
|
+
local function getFirstKey()
|
|
358
|
+
return self.firstKey
|
|
359
|
+
end
|
|
360
|
+
local nextKey = self.nextKey
|
|
361
|
+
local key
|
|
362
|
+
local started = false
|
|
363
|
+
return {
|
|
364
|
+
[Symbol.iterator] = function(self)
|
|
365
|
+
return self
|
|
366
|
+
end,
|
|
367
|
+
next = function(self)
|
|
368
|
+
if not started then
|
|
369
|
+
started = true
|
|
370
|
+
key = getFirstKey(nil)
|
|
371
|
+
else
|
|
372
|
+
key = nextKey[key]
|
|
373
|
+
end
|
|
374
|
+
return {done = not key, value = {key, key}}
|
|
375
|
+
end
|
|
376
|
+
}
|
|
377
|
+
end
|
|
378
|
+
function Set.prototype.keys(self)
|
|
379
|
+
local function getFirstKey()
|
|
380
|
+
return self.firstKey
|
|
381
|
+
end
|
|
382
|
+
local nextKey = self.nextKey
|
|
383
|
+
local key
|
|
384
|
+
local started = false
|
|
385
|
+
return {
|
|
386
|
+
[Symbol.iterator] = function(self)
|
|
387
|
+
return self
|
|
388
|
+
end,
|
|
389
|
+
next = function(self)
|
|
390
|
+
if not started then
|
|
391
|
+
started = true
|
|
392
|
+
key = getFirstKey(nil)
|
|
393
|
+
else
|
|
394
|
+
key = nextKey[key]
|
|
395
|
+
end
|
|
396
|
+
return {done = not key, value = key}
|
|
397
|
+
end
|
|
398
|
+
}
|
|
399
|
+
end
|
|
400
|
+
function Set.prototype.values(self)
|
|
401
|
+
local function getFirstKey()
|
|
402
|
+
return self.firstKey
|
|
403
|
+
end
|
|
404
|
+
local nextKey = self.nextKey
|
|
405
|
+
local key
|
|
406
|
+
local started = false
|
|
407
|
+
return {
|
|
408
|
+
[Symbol.iterator] = function(self)
|
|
409
|
+
return self
|
|
410
|
+
end,
|
|
411
|
+
next = function(self)
|
|
412
|
+
if not started then
|
|
413
|
+
started = true
|
|
414
|
+
key = getFirstKey(nil)
|
|
415
|
+
else
|
|
416
|
+
key = nextKey[key]
|
|
417
|
+
end
|
|
418
|
+
return {done = not key, value = key}
|
|
419
|
+
end
|
|
420
|
+
}
|
|
421
|
+
end
|
|
422
|
+
function Set.prototype.union(self, other)
|
|
423
|
+
local result = __TS__New(Set, self)
|
|
424
|
+
for ____, item in __TS__Iterator(other) do
|
|
425
|
+
result:add(item)
|
|
426
|
+
end
|
|
427
|
+
return result
|
|
428
|
+
end
|
|
429
|
+
function Set.prototype.intersection(self, other)
|
|
430
|
+
local result = __TS__New(Set)
|
|
431
|
+
for ____, item in __TS__Iterator(self) do
|
|
432
|
+
if other:has(item) then
|
|
433
|
+
result:add(item)
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
return result
|
|
437
|
+
end
|
|
438
|
+
function Set.prototype.difference(self, other)
|
|
439
|
+
local result = __TS__New(Set, self)
|
|
440
|
+
for ____, item in __TS__Iterator(other) do
|
|
441
|
+
result:delete(item)
|
|
442
|
+
end
|
|
443
|
+
return result
|
|
444
|
+
end
|
|
445
|
+
function Set.prototype.symmetricDifference(self, other)
|
|
446
|
+
local result = __TS__New(Set, self)
|
|
447
|
+
for ____, item in __TS__Iterator(other) do
|
|
448
|
+
if self:has(item) then
|
|
449
|
+
result:delete(item)
|
|
450
|
+
else
|
|
451
|
+
result:add(item)
|
|
452
|
+
end
|
|
453
|
+
end
|
|
454
|
+
return result
|
|
455
|
+
end
|
|
456
|
+
function Set.prototype.isSubsetOf(self, other)
|
|
457
|
+
for ____, item in __TS__Iterator(self) do
|
|
458
|
+
if not other:has(item) then
|
|
459
|
+
return false
|
|
460
|
+
end
|
|
461
|
+
end
|
|
462
|
+
return true
|
|
463
|
+
end
|
|
464
|
+
function Set.prototype.isSupersetOf(self, other)
|
|
465
|
+
for ____, item in __TS__Iterator(other) do
|
|
466
|
+
if not self:has(item) then
|
|
467
|
+
return false
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
return true
|
|
471
|
+
end
|
|
472
|
+
function Set.prototype.isDisjointFrom(self, other)
|
|
473
|
+
for ____, item in __TS__Iterator(self) do
|
|
474
|
+
if other:has(item) then
|
|
475
|
+
return false
|
|
476
|
+
end
|
|
477
|
+
end
|
|
478
|
+
return true
|
|
479
|
+
end
|
|
480
|
+
Set[Symbol.species] = Set
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
local function __TS__ObjectAssign(target, ...)
|
|
484
|
+
local sources = {...}
|
|
485
|
+
for i = 1, #sources do
|
|
486
|
+
local source = sources[i]
|
|
487
|
+
if type(source) == "table" then
|
|
488
|
+
for key in pairs(source) do
|
|
489
|
+
target[key] = source[key]
|
|
490
|
+
end
|
|
491
|
+
end
|
|
492
|
+
end
|
|
493
|
+
return target
|
|
494
|
+
end
|
|
10
495
|
-- End of Lua Library inline imports
|
|
11
496
|
local ____exports = {}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
497
|
+
local ____jsx = require("ui.primitives.jsx")
|
|
498
|
+
local UI = ____jsx.UI
|
|
499
|
+
local ____wuira = require("wuira")
|
|
500
|
+
local wuira = ____wuira.wuira
|
|
501
|
+
--- Arrays expand once; observable lists keep one mounted tree per stable key.
|
|
502
|
+
function ____exports.ForEach(self, props)
|
|
503
|
+
local ____props_0 = props
|
|
504
|
+
local items = ____props_0.items
|
|
505
|
+
local key = ____props_0.key
|
|
506
|
+
local child = ____props_0.child
|
|
507
|
+
local onUpdate = ____props_0.onUpdate
|
|
508
|
+
local onDispose = ____props_0.onDispose
|
|
509
|
+
local direction = ____props_0.direction
|
|
510
|
+
if direction == nil then
|
|
511
|
+
direction = "vertical"
|
|
512
|
+
end
|
|
513
|
+
local gap = ____props_0.gap
|
|
514
|
+
if gap == nil then
|
|
515
|
+
gap = 0
|
|
516
|
+
end
|
|
517
|
+
local lineGap = ____props_0.lineGap
|
|
518
|
+
if lineGap == nil then
|
|
519
|
+
lineGap = gap
|
|
520
|
+
end
|
|
521
|
+
local wrapAfter = ____props_0.wrapAfter
|
|
522
|
+
if wrapAfter == nil then
|
|
523
|
+
wrapAfter = math.huge
|
|
524
|
+
end
|
|
525
|
+
local groupBy = ____props_0.groupBy
|
|
526
|
+
local position = __TS__ObjectRest(____props_0, {
|
|
527
|
+
items = true,
|
|
528
|
+
key = true,
|
|
529
|
+
child = true,
|
|
530
|
+
onUpdate = true,
|
|
531
|
+
onDispose = true,
|
|
532
|
+
direction = true,
|
|
533
|
+
gap = true,
|
|
534
|
+
lineGap = true,
|
|
535
|
+
wrapAfter = true,
|
|
536
|
+
groupBy = true
|
|
537
|
+
})
|
|
18
538
|
if type(child) ~= "function" then
|
|
19
539
|
error("ForEach requires a render function as its child")
|
|
20
540
|
end
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
541
|
+
if __TS__ArrayIsArray(items) then
|
|
542
|
+
return {
|
|
543
|
+
kind = "group",
|
|
544
|
+
props = {},
|
|
545
|
+
children = __TS__ArrayMap(
|
|
546
|
+
items,
|
|
547
|
+
function(____, item, index)
|
|
548
|
+
local view = child(nil, item, index)
|
|
549
|
+
if key ~= nil then
|
|
550
|
+
view.props.key = key(nil, item)
|
|
551
|
+
end
|
|
552
|
+
return view
|
|
553
|
+
end
|
|
554
|
+
)
|
|
555
|
+
}
|
|
556
|
+
end
|
|
557
|
+
if key == nil then
|
|
558
|
+
error("An observable ForEach requires a stable key")
|
|
559
|
+
end
|
|
560
|
+
if wrapAfter ~= math.huge and (not __TS__NumberIsInteger(wrapAfter) or wrapAfter < 1) then
|
|
561
|
+
error("ForEach wrapAfter must be a positive integer")
|
|
562
|
+
end
|
|
563
|
+
if gap < 0 or lineGap < 0 then
|
|
564
|
+
error("ForEach gaps must be non-negative")
|
|
565
|
+
end
|
|
566
|
+
local source = items
|
|
567
|
+
return UI:createElement(
|
|
568
|
+
"cell",
|
|
569
|
+
__TS__ObjectAssign(
|
|
570
|
+
{},
|
|
571
|
+
position,
|
|
572
|
+
{
|
|
573
|
+
width = position.width or 0,
|
|
574
|
+
height = position.height or 0,
|
|
575
|
+
onMount = function(____, host)
|
|
576
|
+
local entries = __TS__New(Map)
|
|
577
|
+
local stopped = false
|
|
578
|
+
local dirty = true
|
|
579
|
+
local latest
|
|
580
|
+
local lastWidth = -1
|
|
581
|
+
local lastHeight = -1
|
|
582
|
+
local events = CreateFrame("Frame", nil, UIParent)
|
|
583
|
+
local function release(____, entry)
|
|
584
|
+
do
|
|
585
|
+
local ____try, ____error = pcall(function()
|
|
586
|
+
wuira:Unmount(entry.frame)
|
|
587
|
+
end)
|
|
588
|
+
do
|
|
589
|
+
if onDispose ~= nil then
|
|
590
|
+
onDispose(nil, entry.view, entry.item)
|
|
591
|
+
end
|
|
592
|
+
end
|
|
593
|
+
if not ____try then
|
|
594
|
+
error(____error, 0)
|
|
595
|
+
end
|
|
596
|
+
end
|
|
597
|
+
end
|
|
598
|
+
local function reconcile()
|
|
599
|
+
if stopped or not dirty or InCombatLockdown() then
|
|
600
|
+
return
|
|
601
|
+
end
|
|
602
|
+
local values = latest or source.Value
|
|
603
|
+
if #values > 1024 then
|
|
604
|
+
error("ForEach list exceeds its safety limit")
|
|
605
|
+
end
|
|
606
|
+
local next = __TS__New(Map)
|
|
607
|
+
local created = {}
|
|
608
|
+
local ordered = {}
|
|
609
|
+
do
|
|
610
|
+
local function ____catch(failure)
|
|
611
|
+
for ____, entry in ipairs(created) do
|
|
612
|
+
release(nil, entry)
|
|
613
|
+
end
|
|
614
|
+
error(failure, 0)
|
|
615
|
+
end
|
|
616
|
+
local ____try, ____hasReturned = pcall(function()
|
|
617
|
+
local keys = __TS__New(Set)
|
|
618
|
+
local identities = {}
|
|
619
|
+
for ____, item in ipairs(values) do
|
|
620
|
+
local identity = key(nil, item)
|
|
621
|
+
if issecretvalue(identity) or type(identity) ~= "string" and type(identity) ~= "number" or type(identity) == "number" and not __TS__NumberIsFinite(identity) or keys:has(identity) then
|
|
622
|
+
error("ForEach requires unique, public keys")
|
|
623
|
+
end
|
|
624
|
+
keys:add(identity)
|
|
625
|
+
identities[#identities + 1] = identity
|
|
626
|
+
end
|
|
627
|
+
do
|
|
628
|
+
local index = 0
|
|
629
|
+
while index < #values do
|
|
630
|
+
local item = values[index + 1]
|
|
631
|
+
local identity = identities[index + 1]
|
|
632
|
+
local entry = entries:get(identity)
|
|
633
|
+
if entry == nil then
|
|
634
|
+
local view = child(nil, item, index)
|
|
635
|
+
view.props.key = identity
|
|
636
|
+
local frame
|
|
637
|
+
do
|
|
638
|
+
local function ____catch(failure)
|
|
639
|
+
if onDispose ~= nil then
|
|
640
|
+
onDispose(nil, view, item)
|
|
641
|
+
end
|
|
642
|
+
error(failure, 0)
|
|
643
|
+
end
|
|
644
|
+
local ____try, ____hasReturned = pcall(function()
|
|
645
|
+
frame = wuira:Mount(view, nil, host)
|
|
646
|
+
if frame == nil then
|
|
647
|
+
error("Observable ForEach children must return a Cell")
|
|
648
|
+
end
|
|
649
|
+
end)
|
|
650
|
+
if not ____try then
|
|
651
|
+
____catch(____hasReturned)
|
|
652
|
+
end
|
|
653
|
+
end
|
|
654
|
+
entry = {item = item, view = view, frame = frame}
|
|
655
|
+
created[#created + 1] = entry
|
|
656
|
+
else
|
|
657
|
+
if onUpdate ~= nil then
|
|
658
|
+
onUpdate(nil, entry.view, item, entry.item)
|
|
659
|
+
end
|
|
660
|
+
entry.item = item
|
|
661
|
+
end
|
|
662
|
+
next:set(identity, entry)
|
|
663
|
+
ordered[#ordered + 1] = entry
|
|
664
|
+
index = index + 1
|
|
665
|
+
end
|
|
666
|
+
end
|
|
667
|
+
end)
|
|
668
|
+
if not ____try then
|
|
669
|
+
____catch(____hasReturned)
|
|
670
|
+
end
|
|
671
|
+
end
|
|
672
|
+
for ____, ____value in __TS__Iterator(entries) do
|
|
673
|
+
local identity = ____value[1]
|
|
674
|
+
local entry = ____value[2]
|
|
675
|
+
if not next:has(identity) then
|
|
676
|
+
release(nil, entry)
|
|
677
|
+
end
|
|
678
|
+
end
|
|
679
|
+
entries = next
|
|
680
|
+
local groups = __TS__New(Map)
|
|
681
|
+
do
|
|
682
|
+
local index = 0
|
|
683
|
+
while index < #ordered do
|
|
684
|
+
local entry = ordered[index + 1]
|
|
685
|
+
local group = groupBy and groupBy(nil, entry.item) or math.floor(index / wrapAfter)
|
|
686
|
+
local values = groups:get(group)
|
|
687
|
+
if values == nil then
|
|
688
|
+
values = {}
|
|
689
|
+
groups:set(group, values)
|
|
690
|
+
end
|
|
691
|
+
values[#values + 1] = entry
|
|
692
|
+
index = index + 1
|
|
693
|
+
end
|
|
694
|
+
end
|
|
695
|
+
local cross = 0
|
|
696
|
+
local width = 0
|
|
697
|
+
local height = 0
|
|
698
|
+
for ____, group in __TS__Iterator(groups:values()) do
|
|
699
|
+
local cursor = 0
|
|
700
|
+
local crossSize = 0
|
|
701
|
+
for ____, entry in ipairs(group) do
|
|
702
|
+
local w = entry.frame:GetWidth()
|
|
703
|
+
local h = entry.frame:GetHeight()
|
|
704
|
+
local x = direction == "vertical" and cross or cursor
|
|
705
|
+
local y = direction == "vertical" and -cursor or -cross
|
|
706
|
+
if x ~= entry.x or y ~= entry.y then
|
|
707
|
+
entry.frame:ClearAllPoints()
|
|
708
|
+
entry.frame:SetPoint(
|
|
709
|
+
"TOPLEFT",
|
|
710
|
+
host,
|
|
711
|
+
"TOPLEFT",
|
|
712
|
+
x,
|
|
713
|
+
y
|
|
714
|
+
)
|
|
715
|
+
entry.x = x
|
|
716
|
+
entry.y = y
|
|
717
|
+
end
|
|
718
|
+
width = math.max(width, (direction == "vertical" and cross or cursor) + w)
|
|
719
|
+
height = math.max(height, (direction == "vertical" and cursor or cross) + h)
|
|
720
|
+
cursor = cursor + ((direction == "vertical" and h or w) + gap)
|
|
721
|
+
crossSize = math.max(crossSize, direction == "vertical" and w or h)
|
|
722
|
+
end
|
|
723
|
+
cross = cross + (crossSize + lineGap)
|
|
724
|
+
end
|
|
725
|
+
if width ~= lastWidth or height ~= lastHeight then
|
|
726
|
+
host:SetSize(width, height)
|
|
727
|
+
lastWidth = width
|
|
728
|
+
lastHeight = height
|
|
729
|
+
end
|
|
730
|
+
latest = nil
|
|
731
|
+
dirty = false
|
|
732
|
+
end
|
|
733
|
+
local function refresh(____, values)
|
|
734
|
+
latest = values
|
|
735
|
+
dirty = true
|
|
736
|
+
reconcile(nil)
|
|
737
|
+
end
|
|
738
|
+
events:RegisterEvent("PLAYER_REGEN_ENABLED")
|
|
739
|
+
events:SetScript(
|
|
740
|
+
"OnEvent",
|
|
741
|
+
function()
|
|
742
|
+
latest = nil
|
|
743
|
+
reconcile(nil)
|
|
744
|
+
end
|
|
745
|
+
)
|
|
746
|
+
local unsubscribe = source:onChange(refresh)
|
|
747
|
+
do
|
|
748
|
+
local function ____catch(failure)
|
|
749
|
+
unsubscribe(nil)
|
|
750
|
+
events:UnregisterAllEvents()
|
|
751
|
+
events:SetScript("OnEvent", nil)
|
|
752
|
+
for ____, entry in __TS__Iterator(entries:values()) do
|
|
753
|
+
release(nil, entry)
|
|
754
|
+
end
|
|
755
|
+
error(failure, 0)
|
|
756
|
+
end
|
|
757
|
+
local ____try, ____hasReturned = pcall(function()
|
|
758
|
+
reconcile(nil)
|
|
759
|
+
end)
|
|
760
|
+
if not ____try then
|
|
761
|
+
____catch(____hasReturned)
|
|
762
|
+
end
|
|
763
|
+
end
|
|
764
|
+
return function()
|
|
765
|
+
stopped = true
|
|
766
|
+
unsubscribe(nil)
|
|
767
|
+
events:UnregisterAllEvents()
|
|
768
|
+
events:SetScript("OnEvent", nil)
|
|
769
|
+
events:Hide()
|
|
770
|
+
for ____, entry in __TS__Iterator(entries:values()) do
|
|
771
|
+
release(nil, entry)
|
|
772
|
+
end
|
|
773
|
+
entries:clear()
|
|
774
|
+
end
|
|
775
|
+
end
|
|
776
|
+
}
|
|
27
777
|
)
|
|
28
|
-
|
|
778
|
+
)
|
|
29
779
|
end
|
|
30
780
|
return ____exports
|