@oscarpalmer/tabela 0.9.0 → 0.11.0
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/dist/components/body.component.js +3 -15
- package/dist/components/footer.component.js +3 -3
- package/dist/components/header.component.js +2 -2
- package/dist/components/row.component.js +19 -7
- package/dist/helpers/dom.helpers.js +5 -10
- package/dist/helpers/misc.helpers.js +7 -0
- package/dist/helpers/style.helper.js +6 -0
- package/dist/managers/column.manager.js +10 -9
- package/dist/managers/data.manager.js +26 -22
- package/dist/managers/event.manager.js +39 -19
- package/dist/managers/filter.manager.js +11 -10
- package/dist/managers/navigation.manager.js +73 -0
- package/dist/managers/render.manager.js +110 -0
- package/dist/managers/row.manager.js +7 -7
- package/dist/managers/selection.manager.js +189 -0
- package/dist/managers/sort.manager.js +9 -8
- package/dist/tabela.full.js +1096 -433
- package/dist/tabela.js +34 -11
- package/package.json +1 -1
- package/src/components/body.component.ts +5 -20
- package/src/components/footer.component.ts +3 -3
- package/src/components/header.component.ts +2 -2
- package/src/components/row.component.ts +30 -10
- package/src/helpers/dom.helpers.ts +3 -10
- package/src/helpers/misc.helpers.ts +15 -0
- package/src/helpers/style.helper.ts +6 -0
- package/src/managers/column.manager.ts +12 -14
- package/src/managers/data.manager.ts +31 -27
- package/src/managers/event.manager.ts +67 -37
- package/src/managers/filter.manager.ts +12 -11
- package/src/managers/navigation.manager.ts +145 -0
- package/src/managers/render.manager.ts +184 -0
- package/src/managers/row.manager.ts +9 -14
- package/src/managers/selection.manager.ts +332 -0
- package/src/managers/sort.manager.ts +14 -14
- package/src/models/render.model.ts +16 -0
- package/src/models/tabela.model.ts +23 -2
- package/src/tabela.ts +42 -10
- package/types/components/row.component.d.ts +4 -4
- package/types/helpers/dom.helpers.d.ts +1 -1
- package/types/helpers/misc.helpers.d.ts +2 -0
- package/types/helpers/style.helper.d.ts +1 -0
- package/types/managers/column.manager.d.ts +4 -5
- package/types/managers/data.manager.d.ts +5 -6
- package/types/managers/event.manager.d.ts +3 -6
- package/types/managers/filter.manager.d.ts +3 -3
- package/types/managers/navigation.manager.d.ts +10 -0
- package/types/managers/render.manager.d.ts +16 -0
- package/types/managers/row.manager.d.ts +4 -5
- package/types/managers/selection.manager.d.ts +18 -0
- package/types/managers/sort.manager.d.ts +4 -4
- package/types/models/render.model.d.ts +13 -0
- package/types/models/tabela.model.d.ts +21 -2
- package/types/tabela.d.ts +2 -1
- package/dist/managers/virtualization.manager.js +0 -101
- package/src/managers/virtualization.manager.ts +0 -176
- package/src/models/virtualization.model.ts +0 -14
- package/types/managers/virtualization.manager.d.ts +0 -18
- package/types/models/virtualization.model.d.ts +0 -12
- /package/dist/models/{virtualization.model.js → render.model.js} +0 -0
package/dist/tabela.full.js
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
function compact$1(array, strict) {
|
|
2
|
+
if (!Array.isArray(array)) return [];
|
|
3
|
+
if (strict === true) return array.filter(Boolean);
|
|
4
|
+
const { length } = array;
|
|
5
|
+
const compacted = [];
|
|
6
|
+
for (let index = 0; index < length; index += 1) {
|
|
7
|
+
const item = array[index];
|
|
8
|
+
if (item != null) compacted.push(item);
|
|
9
|
+
}
|
|
10
|
+
return compacted;
|
|
11
|
+
}
|
|
1
12
|
/**
|
|
2
13
|
* Get the string value from any value
|
|
3
14
|
* @param value Original value
|
|
@@ -12,6 +23,32 @@ function getString$1(value) {
|
|
|
12
23
|
return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
|
|
13
24
|
}
|
|
14
25
|
/**
|
|
26
|
+
* Join an array of values into a string
|
|
27
|
+
* @param value Array of values
|
|
28
|
+
* @param delimiter Delimiter to use between values
|
|
29
|
+
* @returns Joined string
|
|
30
|
+
*/
|
|
31
|
+
function join$1(value, delimiter) {
|
|
32
|
+
return compact$1(value).map(getString$1).join(typeof delimiter === "string" ? delimiter : "");
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Split a string into words _(and other readable parts)_
|
|
36
|
+
* @param value Original string
|
|
37
|
+
* @returns Array of words found in the string
|
|
38
|
+
*/
|
|
39
|
+
function words$1(value) {
|
|
40
|
+
return typeof value === "string" ? value.match(EXPRESSION_WORDS$1) ?? [] : [];
|
|
41
|
+
}
|
|
42
|
+
var EXPRESSION_WORDS$1 = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
|
43
|
+
/**
|
|
44
|
+
* Is the value a number?
|
|
45
|
+
* @param value Value to check
|
|
46
|
+
* @returns `true` if the value is a `number`, otherwise `false`
|
|
47
|
+
*/
|
|
48
|
+
function isNumber$1(value) {
|
|
49
|
+
return typeof value === "number" && !Number.isNaN(value);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
15
52
|
* Is the value a plain object?
|
|
16
53
|
* @param value Value to check
|
|
17
54
|
* @returns `true` if the value is a plain object, otherwise `false`
|
|
@@ -22,9 +59,237 @@ function isPlainObject$1(value) {
|
|
|
22
59
|
const prototype = Object.getPrototypeOf(value);
|
|
23
60
|
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
24
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Clamp a number between a minimum and maximum value
|
|
64
|
+
* @param value Value to clamp
|
|
65
|
+
* @param minimum Minimum value
|
|
66
|
+
* @param maximum Maximum value
|
|
67
|
+
* @param loop If `true`, the value will loop around when smaller than the minimum or larger than the maximum _(defaults to `false`)_
|
|
68
|
+
* @returns Clamped value
|
|
69
|
+
*/
|
|
70
|
+
function clamp$1(value, minimum, maximum, loop) {
|
|
71
|
+
if (![
|
|
72
|
+
value,
|
|
73
|
+
minimum,
|
|
74
|
+
maximum
|
|
75
|
+
].every(isNumber$1)) return NaN;
|
|
76
|
+
if (value < minimum) return loop === true ? maximum : minimum;
|
|
77
|
+
return value > maximum ? loop === true ? minimum : maximum : value;
|
|
78
|
+
}
|
|
79
|
+
function getSizedMaximum$1(first, second) {
|
|
80
|
+
let actual;
|
|
81
|
+
if (typeof first === "number") actual = first;
|
|
82
|
+
else actual = typeof second === "number" ? second : MAXIMUM_DEFAULT$1;
|
|
83
|
+
return clamp$1(actual, 1, MAXIMUM_ABSOLUTE$1);
|
|
84
|
+
}
|
|
85
|
+
var MAXIMUM_ABSOLUTE$1 = 16777216;
|
|
86
|
+
var MAXIMUM_DEFAULT$1 = 1048576;
|
|
87
|
+
/**
|
|
88
|
+
* A Map with a maximum size
|
|
89
|
+
*
|
|
90
|
+
* Behavior is similar to a _LRU_-cache, where the least recently used entries are removed
|
|
91
|
+
*/
|
|
92
|
+
var SizedMap$1 = class extends Map {
|
|
93
|
+
/**
|
|
94
|
+
* The maximum size of the Map
|
|
95
|
+
*/
|
|
96
|
+
#maximumSize;
|
|
97
|
+
/**
|
|
98
|
+
* Is the Map full?
|
|
99
|
+
*/
|
|
100
|
+
get full() {
|
|
101
|
+
return this.size >= this.#maximumSize;
|
|
102
|
+
}
|
|
103
|
+
get maximum() {
|
|
104
|
+
return this.#maximumSize;
|
|
105
|
+
}
|
|
106
|
+
constructor(first, second) {
|
|
107
|
+
const maximum = getSizedMaximum$1(first, second);
|
|
108
|
+
super();
|
|
109
|
+
this.#maximumSize = maximum;
|
|
110
|
+
if (Array.isArray(first)) {
|
|
111
|
+
const { length } = first;
|
|
112
|
+
if (length <= maximum) for (let index = 0; index < length; index += 1) this.set(...first[index]);
|
|
113
|
+
else for (let index = 0; index < maximum; index += 1) this.set(...first[length - maximum + index]);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* @inheritdoc
|
|
118
|
+
*/
|
|
119
|
+
get(key) {
|
|
120
|
+
const value = super.get(key);
|
|
121
|
+
if (value !== void 0 || this.has(key)) this.set(key, value);
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* @inheritdoc
|
|
126
|
+
*/
|
|
127
|
+
set(key, value) {
|
|
128
|
+
if (this.has(key)) this.delete(key);
|
|
129
|
+
else if (this.size >= this.#maximumSize) this.delete(this.keys().next().value);
|
|
130
|
+
return super.set(key, value);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
var Memoized$1 = class {
|
|
134
|
+
#state;
|
|
135
|
+
/**
|
|
136
|
+
* Maximum cache size
|
|
137
|
+
*/
|
|
138
|
+
get maximum() {
|
|
139
|
+
return this.#state.cache?.maximum ?? NaN;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Current cache size
|
|
143
|
+
*/
|
|
144
|
+
get size() {
|
|
145
|
+
return this.#state.cache?.size ?? NaN;
|
|
146
|
+
}
|
|
147
|
+
constructor(callback, options) {
|
|
148
|
+
const cache = new SizedMap$1(options.cacheSize);
|
|
149
|
+
const getter = (...parameters) => {
|
|
150
|
+
const key = options.cacheKey?.(...parameters) ?? (parameters.length === 1 ? parameters[0] : join$1(parameters.map(getString$1), "_"));
|
|
151
|
+
if (cache.has(key)) return cache.get(key);
|
|
152
|
+
const value = callback(...parameters);
|
|
153
|
+
cache.set(key, value);
|
|
154
|
+
return value;
|
|
155
|
+
};
|
|
156
|
+
this.#state = {
|
|
157
|
+
cache,
|
|
158
|
+
getter
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Clear the cache
|
|
163
|
+
*/
|
|
164
|
+
clear() {
|
|
165
|
+
this.#state.cache?.clear();
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Delete a result from the cache
|
|
169
|
+
* @param key Key to delete
|
|
170
|
+
* @returns `true` if the key existed and was removed, otherwise `false`
|
|
171
|
+
*/
|
|
172
|
+
delete(key) {
|
|
173
|
+
return this.#state.cache?.delete(key) ?? false;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Destroy the instance _(clearing its cache and removing its callback)_
|
|
177
|
+
*/
|
|
178
|
+
destroy() {
|
|
179
|
+
this.#state.cache?.clear();
|
|
180
|
+
this.#state.cache = void 0;
|
|
181
|
+
this.#state.getter = void 0;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get a result from the cache
|
|
185
|
+
* @param key Key to get
|
|
186
|
+
* @returns Cached result or `undefined` if it does not exist
|
|
187
|
+
*/
|
|
188
|
+
get(key) {
|
|
189
|
+
return this.#state.cache?.get(key);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Does the result exist?
|
|
193
|
+
* @param key Key to check
|
|
194
|
+
* @returns `true` if the result exists, otherwise `false`
|
|
195
|
+
*/
|
|
196
|
+
has(key) {
|
|
197
|
+
return this.#state.cache?.has(key) ?? false;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Run the callback with the provided parameters
|
|
201
|
+
* @param parameters Parameters to pass to the callback
|
|
202
|
+
* @returns Cached or computed _(then cached)_ result
|
|
203
|
+
*/
|
|
204
|
+
run(...parameters) {
|
|
205
|
+
if (this.#state.cache == null || this.#state.getter == null) throw new Error("The Memoized instance has been destroyed");
|
|
206
|
+
return this.#state.getter(...parameters);
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
function getMemoizationOptions$1(input) {
|
|
210
|
+
const { cacheKey, cacheSize } = isPlainObject$1(input) ? input : {};
|
|
211
|
+
return {
|
|
212
|
+
cacheKey: typeof cacheKey === "function" ? cacheKey : void 0,
|
|
213
|
+
cacheSize: typeof cacheSize === "number" && cacheSize > 0 ? cacheSize : DEFAULT_CACHE_SIZE$1
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Memoize a function, caching and retrieving results based on the first parameter
|
|
218
|
+
* @param callback Callback to memoize
|
|
219
|
+
* @param options Memoization options
|
|
220
|
+
* @returns Memoized instance
|
|
221
|
+
*/
|
|
222
|
+
function memoize$1(callback, options) {
|
|
223
|
+
return new Memoized$1(callback, getMemoizationOptions$1(options));
|
|
224
|
+
}
|
|
225
|
+
var DEFAULT_CACHE_SIZE$1 = 1024;
|
|
226
|
+
/**
|
|
227
|
+
* Convert a string to camel case _(thisIsCamelCase)_
|
|
228
|
+
* @param value String to convert
|
|
229
|
+
* @returns Camel-cased string
|
|
230
|
+
*/
|
|
231
|
+
function camelCase(value) {
|
|
232
|
+
return toCase("camel", value, true, false);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Capitalize the first letter of a string _(and lowercase the rest)_
|
|
236
|
+
* @param value String to capitalize
|
|
237
|
+
* @returns Capitalized string
|
|
238
|
+
*/
|
|
239
|
+
function capitalize(value) {
|
|
240
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
241
|
+
memoizedCapitalize ??= memoize$1((v) => v.length === 1 ? v.toLocaleUpperCase() : `${v.charAt(0).toLocaleUpperCase()}${v.slice(1).toLocaleLowerCase()}`);
|
|
242
|
+
return memoizedCapitalize.run(value);
|
|
243
|
+
}
|
|
244
|
+
function toCase(type, value, capitalizeAny, capitalizeFirst) {
|
|
245
|
+
caseMemoizers[type] ??= memoize$1(toCaseCallback.bind({
|
|
246
|
+
type,
|
|
247
|
+
capitalizeAny,
|
|
248
|
+
capitalizeFirst
|
|
249
|
+
}));
|
|
250
|
+
return caseMemoizers[type].run(value);
|
|
251
|
+
}
|
|
252
|
+
function toCaseCallback(value) {
|
|
253
|
+
if (typeof value !== "string") return "";
|
|
254
|
+
if (value.length < 1) return value;
|
|
255
|
+
const { capitalizeAny, capitalizeFirst, type } = this;
|
|
256
|
+
const parts = words$1(value);
|
|
257
|
+
const partsLength = parts.length;
|
|
258
|
+
const cased = [];
|
|
259
|
+
for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
|
|
260
|
+
const items = parts[partIndex].replace(EXPRESSION_ACRONYM, (full, one, two, three) => three === "s" ? full : `${one}-${two}${three}`).replace(EXPRESSION_CAMEL_CASE, REPLACEMENT_CAMEL_CASE).split("-");
|
|
261
|
+
const itemsLength = items.length;
|
|
262
|
+
const partResult = [];
|
|
263
|
+
let itemCount = 0;
|
|
264
|
+
for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
|
|
265
|
+
const item = items[itemIndex];
|
|
266
|
+
if (item.length === 0) continue;
|
|
267
|
+
if (!capitalizeAny || itemCount === 0 && partIndex === 0 && !capitalizeFirst) partResult.push(item.toLocaleLowerCase());
|
|
268
|
+
else partResult.push(capitalize(item));
|
|
269
|
+
itemCount += 1;
|
|
270
|
+
}
|
|
271
|
+
cased.push(join$1(partResult, delimiters[type]));
|
|
272
|
+
}
|
|
273
|
+
return join$1(cased, delimiters[type]);
|
|
274
|
+
}
|
|
275
|
+
var caseMemoizers = {};
|
|
276
|
+
var delimiters = {
|
|
277
|
+
camel: "",
|
|
278
|
+
kebab: "-",
|
|
279
|
+
pascal: "",
|
|
280
|
+
snake: "_"
|
|
281
|
+
};
|
|
282
|
+
var EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
|
|
283
|
+
var EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
|
|
284
|
+
var REPLACEMENT_CAMEL_CASE = "$1-$2";
|
|
285
|
+
var memoizedCapitalize;
|
|
25
286
|
function getBoolean(value, defaultValue) {
|
|
26
287
|
return typeof value === "boolean" ? value : defaultValue ?? false;
|
|
27
288
|
}
|
|
289
|
+
function getStyleValue(element, property, computed) {
|
|
290
|
+
const name = camelCase(property);
|
|
291
|
+
return computed ? getComputedStyle(element)[name] : element.style[name];
|
|
292
|
+
}
|
|
28
293
|
/**
|
|
29
294
|
* Is the value an event target?
|
|
30
295
|
* @param value Value to check
|
|
@@ -53,10 +318,37 @@ new Set([
|
|
|
53
318
|
* @param value Value to check
|
|
54
319
|
* @returns `true` if the value is nullable or a whitespace-only string, otherwise `false`
|
|
55
320
|
*/
|
|
56
|
-
function isNullableOrWhitespace(value) {
|
|
57
|
-
return value == null || EXPRESSION_WHITESPACE$
|
|
321
|
+
function isNullableOrWhitespace$1(value) {
|
|
322
|
+
return value == null || EXPRESSION_WHITESPACE$2.test(getString$1(value));
|
|
323
|
+
}
|
|
324
|
+
var EXPRESSION_WHITESPACE$2 = /^\s*$/;
|
|
325
|
+
function setElementValue(element, first, second, third, callback) {
|
|
326
|
+
if (!isHTMLOrSVGElement(element)) return;
|
|
327
|
+
if (typeof first === "string") setElementValues(element, first, second, third, callback);
|
|
328
|
+
else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback);
|
|
329
|
+
}
|
|
330
|
+
function setElementValues(element, first, second, third, callback) {
|
|
331
|
+
if (!isHTMLOrSVGElement(element)) return;
|
|
332
|
+
if (typeof first === "string") {
|
|
333
|
+
callback(element, first, second, third);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const isArray = Array.isArray(first);
|
|
337
|
+
if (!isArray && !(typeof first === "object" && first !== null)) return;
|
|
338
|
+
const entries = isArray ? first : Object.entries(first).map(([name, value]) => ({
|
|
339
|
+
name,
|
|
340
|
+
value
|
|
341
|
+
}));
|
|
342
|
+
const { length } = entries;
|
|
343
|
+
for (let index = 0; index < length; index += 1) {
|
|
344
|
+
const entry = entries[index];
|
|
345
|
+
if (typeof entry === "object" && typeof entry?.name === "string") callback(element, entry.name, entry.value, third);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
function updateElementValue(element, key, value, set, remove, isBoolean, json) {
|
|
349
|
+
if (isBoolean ? value == null : isNullableOrWhitespace$1(value)) remove.call(element, key);
|
|
350
|
+
else set.call(element, key, json ? JSON.stringify(value) : String(value));
|
|
58
351
|
}
|
|
59
|
-
var EXPRESSION_WHITESPACE$1 = /^\s*$/;
|
|
60
352
|
function badAttributeHandler(name, value) {
|
|
61
353
|
if (typeof name !== "string" || name.trim().length === 0 || typeof value !== "string") return true;
|
|
62
354
|
if (EXPRESSION_CLOBBERED_NAME.test(name) && (value in document || value in formElement) || EXPRESSION_EVENT_NAME.test(name)) return true;
|
|
@@ -86,7 +378,7 @@ function handleAttribute(callback, decode, first, second) {
|
|
|
86
378
|
value = second;
|
|
87
379
|
}
|
|
88
380
|
if (decode && value != null) value = decodeAttribute(value);
|
|
89
|
-
return callback(name, value?.replace(EXPRESSION_WHITESPACE, ""));
|
|
381
|
+
return callback(name, value?.replace(EXPRESSION_WHITESPACE$1, ""));
|
|
90
382
|
}
|
|
91
383
|
function isAttribute(value) {
|
|
92
384
|
return value instanceof Attr || isPlainObject$1(value) && typeof value.name === "string" && "value" in value;
|
|
@@ -123,7 +415,7 @@ var EXPRESSION_SKIP_NAME = /^(aria-[-\w]+|data-[-\w.\u00B7-\uFFFF]+)$/i;
|
|
|
123
415
|
var EXPRESSION_SOURCE_NAME = /^src$/i;
|
|
124
416
|
var EXPRESSION_SOURCE_VALUE = /^data:/i;
|
|
125
417
|
var EXPRESSION_URI_VALUE = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i;
|
|
126
|
-
var EXPRESSION_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
|
|
418
|
+
var EXPRESSION_WHITESPACE$1 = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
|
|
127
419
|
/**
|
|
128
420
|
* List of boolean attributes
|
|
129
421
|
*/
|
|
@@ -165,32 +457,28 @@ var elementEvents = {
|
|
|
165
457
|
};
|
|
166
458
|
var formElement = document.createElement("form");
|
|
167
459
|
var textArea;
|
|
168
|
-
function
|
|
169
|
-
|
|
170
|
-
if (typeof first === "string") setElementValues(element, first, second, third, callback);
|
|
171
|
-
else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback);
|
|
460
|
+
function setAttribute(element, first, second, third) {
|
|
461
|
+
setElementValue(element, first, second, third, updateAttribute);
|
|
172
462
|
}
|
|
173
|
-
function
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
|
|
463
|
+
function setAttributes(element, attributes, dispatch) {
|
|
464
|
+
setElementValues(element, attributes, null, dispatch, updateAttribute);
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Get styles from an element
|
|
468
|
+
* @param element Element to get the styles from
|
|
469
|
+
* @param properties Styles to get
|
|
470
|
+
* @param computed Get the computed styles? _(defaults to `false`)_
|
|
471
|
+
* @returns Style values
|
|
472
|
+
*/
|
|
473
|
+
function getStyles(element, properties, computed) {
|
|
474
|
+
const styles = {};
|
|
475
|
+
if (!(isHTMLOrSVGElement(element) && Array.isArray(properties))) return styles;
|
|
476
|
+
const { length } = properties;
|
|
186
477
|
for (let index = 0; index < length; index += 1) {
|
|
187
|
-
const
|
|
188
|
-
if (typeof
|
|
478
|
+
const property = properties[index];
|
|
479
|
+
if (typeof property === "string") styles[property] = getStyleValue(element, property, computed === true);
|
|
189
480
|
}
|
|
190
|
-
|
|
191
|
-
function updateElementValue(element, key, value, set, remove, isBoolean, json) {
|
|
192
|
-
if (isBoolean ? value == null : isNullableOrWhitespace(value)) remove.call(element, key);
|
|
193
|
-
else set.call(element, key, json ? JSON.stringify(value) : String(value));
|
|
481
|
+
return styles;
|
|
194
482
|
}
|
|
195
483
|
/**
|
|
196
484
|
* Set styles on an element
|
|
@@ -200,6 +488,38 @@ function updateElementValue(element, key, value, set, remove, isBoolean, json) {
|
|
|
200
488
|
function setStyles(element, styles) {
|
|
201
489
|
setElementValues(element, styles, null, null, updateStyleProperty);
|
|
202
490
|
}
|
|
491
|
+
/**
|
|
492
|
+
* Toggle styles for an element
|
|
493
|
+
* @param element Element to style
|
|
494
|
+
* @param styles Styles to be set or removed
|
|
495
|
+
* @returns Style toggler
|
|
496
|
+
*/
|
|
497
|
+
function toggleStyles(element, styles) {
|
|
498
|
+
function toggle(set) {
|
|
499
|
+
hasSet = set;
|
|
500
|
+
let next;
|
|
501
|
+
if (set) {
|
|
502
|
+
values = getStyles(element, keys);
|
|
503
|
+
next = styles;
|
|
504
|
+
} else {
|
|
505
|
+
next = { ...values };
|
|
506
|
+
values = {};
|
|
507
|
+
for (const key of keys) values[key] = void 0;
|
|
508
|
+
}
|
|
509
|
+
setStyles(element, next);
|
|
510
|
+
}
|
|
511
|
+
const keys = Object.keys(styles);
|
|
512
|
+
let hasSet = false;
|
|
513
|
+
let values = {};
|
|
514
|
+
return {
|
|
515
|
+
set() {
|
|
516
|
+
if (!hasSet) toggle(true);
|
|
517
|
+
},
|
|
518
|
+
remove() {
|
|
519
|
+
if (hasSet) toggle(false);
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
}
|
|
203
523
|
function updateStyleProperty(element, key, value) {
|
|
204
524
|
updateElementValue(element, key, value, function(property, style) {
|
|
205
525
|
this.style[property] = style;
|
|
@@ -207,18 +527,12 @@ function updateStyleProperty(element, key, value) {
|
|
|
207
527
|
this.style[property] = "";
|
|
208
528
|
}, false, false);
|
|
209
529
|
}
|
|
210
|
-
function setAttribute(element, first, second, third) {
|
|
211
|
-
setElementValue(element, first, second, third, updateAttribute);
|
|
212
|
-
}
|
|
213
|
-
function setAttributes(element, attributes, dispatch) {
|
|
214
|
-
setElementValues(element, attributes, null, dispatch, updateAttribute);
|
|
215
|
-
}
|
|
216
530
|
function createCell(width, body) {
|
|
217
531
|
const cell = createElement("div", {
|
|
218
532
|
className: "tabela__cell",
|
|
219
533
|
role: "cell"
|
|
220
534
|
}, {}, { width: `${width}px` });
|
|
221
|
-
if (body ?? true) cell.classList.add("tabela__cell
|
|
535
|
+
if (body ?? true) cell.classList.add("tabela__cell--body");
|
|
222
536
|
return cell;
|
|
223
537
|
}
|
|
224
538
|
function createElement(tagName, properties, attributes, style) {
|
|
@@ -235,33 +549,21 @@ function createRowGroup(withRow) {
|
|
|
235
549
|
role: "rowgroup"
|
|
236
550
|
}, {}, {});
|
|
237
551
|
if (!(withRow ?? true)) return group;
|
|
238
|
-
const row = createRow(
|
|
552
|
+
const row = createRow();
|
|
239
553
|
group.append(row);
|
|
240
554
|
return {
|
|
241
555
|
group,
|
|
242
556
|
row
|
|
243
557
|
};
|
|
244
558
|
}
|
|
245
|
-
function createRow(
|
|
246
|
-
|
|
559
|
+
function createRow() {
|
|
560
|
+
return createElement("div", {
|
|
247
561
|
className: "tabela__row",
|
|
248
562
|
role: "row"
|
|
249
563
|
}, {}, {});
|
|
250
|
-
if (withStyle ?? true) setStyles(row, {
|
|
251
|
-
inset: "0 auto auto 0",
|
|
252
|
-
position: "absolute"
|
|
253
|
-
});
|
|
254
|
-
return row;
|
|
255
564
|
}
|
|
256
565
|
function createFaker() {
|
|
257
|
-
return createElement("div", {}, {}, {
|
|
258
|
-
height: "0",
|
|
259
|
-
inset: "0 auto auto 0",
|
|
260
|
-
opacity: "0",
|
|
261
|
-
pointerEvents: "none",
|
|
262
|
-
position: "absolute",
|
|
263
|
-
width: "1px"
|
|
264
|
-
});
|
|
566
|
+
return createElement("div", { className: "tabela__faker" }, {}, {});
|
|
265
567
|
}
|
|
266
568
|
var BodyComponent = class {
|
|
267
569
|
elements = {
|
|
@@ -271,13 +573,9 @@ var BodyComponent = class {
|
|
|
271
573
|
constructor() {
|
|
272
574
|
const group = createRowGroup(false);
|
|
273
575
|
this.elements.group = group;
|
|
274
|
-
group.className += " tabela__rowgroup
|
|
576
|
+
group.className += " tabela__rowgroup--body";
|
|
275
577
|
group.tabIndex = 0;
|
|
276
|
-
|
|
277
|
-
height: "100%",
|
|
278
|
-
overflow: "auto",
|
|
279
|
-
position: "relative"
|
|
280
|
-
});
|
|
578
|
+
group.setAttribute("data-event", "body");
|
|
281
579
|
group.append(this.elements.faker);
|
|
282
580
|
}
|
|
283
581
|
destroy() {
|
|
@@ -294,8 +592,8 @@ var FooterComponent = class {
|
|
|
294
592
|
row,
|
|
295
593
|
cells: []
|
|
296
594
|
};
|
|
297
|
-
group.className += " tabela__rowgroup
|
|
298
|
-
row.className += " tabela__row
|
|
595
|
+
group.className += " tabela__rowgroup--footer";
|
|
596
|
+
row.className += " tabela__row--footer";
|
|
299
597
|
}
|
|
300
598
|
destroy() {
|
|
301
599
|
this.elements.cells.length = 0;
|
|
@@ -309,7 +607,7 @@ var FooterComponent = class {
|
|
|
309
607
|
elements.row.innerHTML = "";
|
|
310
608
|
for (let index = 0; index < length; index += 1) {
|
|
311
609
|
const cell = createCell(columns[index].options.width ?? 4, false);
|
|
312
|
-
cell.className += " tabela__cell
|
|
610
|
+
cell.className += " tabela__cell--footer";
|
|
313
611
|
cell.innerHTML = " ";
|
|
314
612
|
elements.cells.push(cell);
|
|
315
613
|
elements.row.append(cell);
|
|
@@ -324,8 +622,8 @@ var HeaderComponent = class {
|
|
|
324
622
|
group,
|
|
325
623
|
row
|
|
326
624
|
};
|
|
327
|
-
group.className += " tabela__rowgroup
|
|
328
|
-
row.className += " tabela__row
|
|
625
|
+
group.className += " tabela__rowgroup--header";
|
|
626
|
+
row.className += " tabela__row--header";
|
|
329
627
|
}
|
|
330
628
|
destroy() {
|
|
331
629
|
this.elements.group = void 0;
|
|
@@ -377,18 +675,19 @@ function createHeading(field, title, width) {
|
|
|
377
675
|
}
|
|
378
676
|
var ColumnManager = class {
|
|
379
677
|
items = [];
|
|
380
|
-
constructor(
|
|
381
|
-
this.
|
|
382
|
-
this.
|
|
383
|
-
this.set(columns);
|
|
678
|
+
constructor(state) {
|
|
679
|
+
this.state = state;
|
|
680
|
+
this.set(state.options.columns);
|
|
384
681
|
}
|
|
385
682
|
destroy() {
|
|
386
683
|
const { length } = this.items;
|
|
387
684
|
for (let index = 0; index < length; index += 1) this.items[index].destroy();
|
|
388
|
-
this.items
|
|
685
|
+
this.items = void 0;
|
|
686
|
+
this.state = void 0;
|
|
389
687
|
}
|
|
390
688
|
remove(value) {
|
|
391
|
-
const {
|
|
689
|
+
const { items, state } = this;
|
|
690
|
+
const { components, managers } = state;
|
|
392
691
|
const fields = (Array.isArray(value) ? value : [value]).filter((item) => typeof item === "string");
|
|
393
692
|
const { length } = fields;
|
|
394
693
|
if (length === 0) return;
|
|
@@ -401,11 +700,11 @@ var ColumnManager = class {
|
|
|
401
700
|
}
|
|
402
701
|
components.header.update(items);
|
|
403
702
|
components.footer.update(items);
|
|
404
|
-
managers.
|
|
703
|
+
managers.render.removeCells(fields);
|
|
405
704
|
}
|
|
406
705
|
set(columns) {
|
|
407
|
-
const {
|
|
408
|
-
const { footer, header } = components;
|
|
706
|
+
const { items, state } = this;
|
|
707
|
+
const { footer, header } = state.components;
|
|
409
708
|
items.splice(0, items.length, ...columns.map((column) => new ColumnComponent(column)));
|
|
410
709
|
header.update(items);
|
|
411
710
|
footer.update(items);
|
|
@@ -485,6 +784,14 @@ function isConstructor(value) {
|
|
|
485
784
|
return typeof value === "function" && value.prototype?.constructor === value;
|
|
486
785
|
}
|
|
487
786
|
/**
|
|
787
|
+
* Is the value a key?
|
|
788
|
+
* @param value Value to check
|
|
789
|
+
* @returns `true` if the value is a `Key` _(`number` or `string`)_, otherwise `false`
|
|
790
|
+
*/
|
|
791
|
+
function isKey(value) {
|
|
792
|
+
return typeof value === "number" || typeof value === "string";
|
|
793
|
+
}
|
|
794
|
+
/**
|
|
488
795
|
* Is the value a number?
|
|
489
796
|
* @param value Value to check
|
|
490
797
|
* @returns `true` if the value is a `number`, otherwise `false`
|
|
@@ -776,7 +1083,7 @@ function getCallback(value, key, forObject) {
|
|
|
776
1083
|
if (forObject && typeof value.value === "function") return value.value;
|
|
777
1084
|
return typeof value === "function" ? value : void 0;
|
|
778
1085
|
}
|
|
779
|
-
function getKey(value, forObject) {
|
|
1086
|
+
function getKey$1(value, forObject) {
|
|
780
1087
|
if (forObject && typeof value.key === "string") return value.key;
|
|
781
1088
|
return typeof value === "string" ? value : void 0;
|
|
782
1089
|
}
|
|
@@ -792,7 +1099,7 @@ function getSorter(value, modifier) {
|
|
|
792
1099
|
modifier
|
|
793
1100
|
};
|
|
794
1101
|
sorter.compare = forObject && typeof value.compare === "function" ? value.compare : void 0;
|
|
795
|
-
sorter.key = getKey(value, forObject);
|
|
1102
|
+
sorter.key = getKey$1(value, forObject);
|
|
796
1103
|
sorter.modifier = getModifier(value, modifier, forObject);
|
|
797
1104
|
sorter.callback = getCallback(value, sorter.key, forObject);
|
|
798
1105
|
if (sorter.key != null || sorter.callback != null) {
|
|
@@ -852,6 +1159,15 @@ toMap.arrays = toMapArrays;
|
|
|
852
1159
|
function toMapArrays(array, first, second) {
|
|
853
1160
|
return getMapValues(array, first, second, true);
|
|
854
1161
|
}
|
|
1162
|
+
/**
|
|
1163
|
+
* Is the value `undefined`, `null`, or a whitespace-only string?
|
|
1164
|
+
* @param value Value to check
|
|
1165
|
+
* @returns `true` if the value is nullable or a whitespace-only string, otherwise `false`
|
|
1166
|
+
*/
|
|
1167
|
+
function isNullableOrWhitespace(value) {
|
|
1168
|
+
return value == null || EXPRESSION_WHITESPACE.test(getString(value));
|
|
1169
|
+
}
|
|
1170
|
+
var EXPRESSION_WHITESPACE = /^\s*$/;
|
|
855
1171
|
var DataManager = class {
|
|
856
1172
|
handlers = Object.freeze({
|
|
857
1173
|
add: (data) => void this.add(data, true),
|
|
@@ -871,15 +1187,13 @@ var DataManager = class {
|
|
|
871
1187
|
get size() {
|
|
872
1188
|
return this.values.keys.active?.length ?? this.values.keys.original.length;
|
|
873
1189
|
}
|
|
874
|
-
constructor(
|
|
875
|
-
this.
|
|
876
|
-
this.components = components;
|
|
877
|
-
this.field = field;
|
|
1190
|
+
constructor(state) {
|
|
1191
|
+
this.state = state;
|
|
878
1192
|
}
|
|
879
1193
|
async add(data, render) {
|
|
880
|
-
const {
|
|
1194
|
+
const { state, values } = this;
|
|
881
1195
|
push(values.objects.array, data);
|
|
882
|
-
values.objects.mapped = toMap(values.objects.array,
|
|
1196
|
+
values.objects.mapped = toMap(values.objects.array, state.key);
|
|
883
1197
|
if (render) this.render();
|
|
884
1198
|
}
|
|
885
1199
|
clear() {
|
|
@@ -892,48 +1206,54 @@ var DataManager = class {
|
|
|
892
1206
|
values.keys.original.length = 0;
|
|
893
1207
|
values.objects.array.length = 0;
|
|
894
1208
|
this.handlers = void 0;
|
|
1209
|
+
this.state = void 0;
|
|
1210
|
+
this.values = void 0;
|
|
895
1211
|
}
|
|
896
1212
|
get(active) {
|
|
897
1213
|
const { values } = this;
|
|
898
1214
|
return active ?? false ? values.keys.active?.map((key) => values.objects.mapped.get(key)) ?? [] : values.objects.array;
|
|
899
1215
|
}
|
|
1216
|
+
getIndex(key) {
|
|
1217
|
+
const { values } = this;
|
|
1218
|
+
return (values.keys.active ?? values.keys.original).indexOf(key);
|
|
1219
|
+
}
|
|
900
1220
|
async remove(items, render) {
|
|
901
|
-
const {
|
|
902
|
-
const keys = items.map((value) => isPlainObject(value) ? value[
|
|
1221
|
+
const { state, values } = this;
|
|
1222
|
+
const keys = items.map((value) => isPlainObject(value) ? value[state.key] : value).filter((key) => values.objects.mapped.has(key));
|
|
903
1223
|
const { length } = keys;
|
|
904
1224
|
if (length === 0) return;
|
|
905
1225
|
for (let keyIndex = 0; keyIndex < length; keyIndex += 1) {
|
|
906
1226
|
const key = keys[keyIndex];
|
|
907
1227
|
values.objects.mapped.delete(key);
|
|
908
|
-
const arrayIndex = values.objects.array.findIndex((object) => object[
|
|
1228
|
+
const arrayIndex = values.objects.array.findIndex((object) => object[state.key] === key);
|
|
909
1229
|
if (arrayIndex > -1) values.objects.array.splice(arrayIndex, 1);
|
|
910
1230
|
values.keys.original.splice(values.keys.original.indexOf(key), 1);
|
|
911
|
-
managers.row.remove(key);
|
|
1231
|
+
state.managers.row.remove(key);
|
|
912
1232
|
}
|
|
913
1233
|
if (render) this.render();
|
|
914
1234
|
}
|
|
915
1235
|
render() {
|
|
916
|
-
const {
|
|
917
|
-
values.keys.original = sort(values.objects.array.map((item) => item[
|
|
918
|
-
if (Object.keys(managers.filter.items).length > 0) managers.filter.filter();
|
|
919
|
-
else if (managers.sort.items.length > 0) managers.sort.sort();
|
|
920
|
-
else managers.
|
|
1236
|
+
const { state, values } = this;
|
|
1237
|
+
values.keys.original = sort(values.objects.array.map((item) => item[state.key]));
|
|
1238
|
+
if (Object.keys(state.managers.filter.items).length > 0) state.managers.filter.filter();
|
|
1239
|
+
else if (state.managers.sort.items.length > 0) state.managers.sort.sort();
|
|
1240
|
+
else state.managers.render.update(true);
|
|
921
1241
|
}
|
|
922
1242
|
set(data) {
|
|
923
|
-
const {
|
|
924
|
-
values.objects.mapped = toMap(data,
|
|
1243
|
+
const { state, values } = this;
|
|
1244
|
+
values.objects.mapped = toMap(data, state.key);
|
|
925
1245
|
values.objects.array = data;
|
|
926
1246
|
this.render();
|
|
927
1247
|
}
|
|
928
1248
|
async synchronize(data, remove) {
|
|
929
|
-
const {
|
|
1249
|
+
const { state, values } = this;
|
|
930
1250
|
const add = [];
|
|
931
1251
|
const updated = [];
|
|
932
1252
|
const keys = /* @__PURE__ */ new Set([]);
|
|
933
1253
|
const { length } = data;
|
|
934
1254
|
for (let index = 0; index < length; index += 1) {
|
|
935
1255
|
const object = data[index];
|
|
936
|
-
const key = object[
|
|
1256
|
+
const key = object[state.key];
|
|
937
1257
|
if (values.objects.mapped.has(key)) updated.push(object);
|
|
938
1258
|
else add.push(object);
|
|
939
1259
|
keys.add(key);
|
|
@@ -948,18 +1268,18 @@ var DataManager = class {
|
|
|
948
1268
|
if (add.length > 0 || (remove ?? false)) this.render();
|
|
949
1269
|
}
|
|
950
1270
|
async update(data) {
|
|
951
|
-
const {
|
|
1271
|
+
const { state, values } = this;
|
|
952
1272
|
const { length } = data;
|
|
953
1273
|
for (let index = 0; index < length; index += 1) {
|
|
954
1274
|
const object = data[index];
|
|
955
|
-
const key = object[
|
|
1275
|
+
const key = object[state.key];
|
|
956
1276
|
const value = values.objects.mapped.get(key);
|
|
957
1277
|
if (value != null) {
|
|
958
1278
|
values.objects.mapped.set(key, {
|
|
959
1279
|
...value,
|
|
960
1280
|
...object
|
|
961
1281
|
});
|
|
962
|
-
managers.row.update(key);
|
|
1282
|
+
state.managers.row.update(key);
|
|
963
1283
|
}
|
|
964
1284
|
}
|
|
965
1285
|
}
|
|
@@ -1057,6 +1377,26 @@ function createEventOptions(options) {
|
|
|
1057
1377
|
signal: options?.signal instanceof AbortSignal ? options.signal : void 0
|
|
1058
1378
|
};
|
|
1059
1379
|
}
|
|
1380
|
+
/**
|
|
1381
|
+
* Get the X- and Y-coordinates from a pointer event
|
|
1382
|
+
* @param event Pointer event
|
|
1383
|
+
* @returns X- and Y-coordinates
|
|
1384
|
+
*/
|
|
1385
|
+
function getPosition(event) {
|
|
1386
|
+
let x;
|
|
1387
|
+
let y;
|
|
1388
|
+
if (event instanceof MouseEvent) {
|
|
1389
|
+
x = event.clientX;
|
|
1390
|
+
y = event.clientY;
|
|
1391
|
+
} else if (event instanceof TouchEvent) {
|
|
1392
|
+
x = event.touches[0]?.clientX;
|
|
1393
|
+
y = event.touches[0]?.clientY;
|
|
1394
|
+
}
|
|
1395
|
+
return typeof x === "number" && typeof y === "number" ? {
|
|
1396
|
+
x,
|
|
1397
|
+
y
|
|
1398
|
+
} : void 0;
|
|
1399
|
+
}
|
|
1060
1400
|
function on(target, type, listener, options) {
|
|
1061
1401
|
if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return noop;
|
|
1062
1402
|
const extended = createEventOptions(options);
|
|
@@ -1088,199 +1428,53 @@ function getElement(origin) {
|
|
|
1088
1428
|
if (origin instanceof Element) return origin;
|
|
1089
1429
|
return origin instanceof Event && origin.target instanceof Element ? origin.target : void 0;
|
|
1090
1430
|
}
|
|
1091
|
-
function isInert(item) {
|
|
1092
|
-
return (item.element.inert ?? false) || EXPRESSION_TRUEISH.test(item.element.getAttribute(ATTRIBUTE_INERT)) || item.element.parentElement != null && isInert({
|
|
1093
|
-
element: item.element.parentElement,
|
|
1094
|
-
tabIndex: TABINDEX_DEFAULT
|
|
1095
|
-
});
|
|
1096
|
-
}
|
|
1097
|
-
var ATTRIBUTE_INERT = "inert";
|
|
1098
|
-
var EXPRESSION_TRUEISH = /^(|true)$/i;
|
|
1099
|
-
[
|
|
1100
|
-
"[contenteditable]:not([contenteditable=\"false\"])",
|
|
1101
|
-
"[tabindex]:not(slot)",
|
|
1102
|
-
"a[href]",
|
|
1103
|
-
"audio[controls]",
|
|
1104
|
-
"button",
|
|
1105
|
-
"details",
|
|
1106
|
-
"details > summary:first-of-type",
|
|
1107
|
-
"input",
|
|
1108
|
-
"select",
|
|
1109
|
-
"textarea",
|
|
1110
|
-
"video[controls]"
|
|
1111
|
-
].map((selector) => `${selector}:not([inert])`).join(",");
|
|
1112
|
-
var TABINDEX_DEFAULT = -1;
|
|
1113
|
-
function handleElement(element, depth) {
|
|
1114
|
-
if (depth === 0) {
|
|
1115
|
-
const removable = element.querySelectorAll(REMOVE_SELECTOR);
|
|
1116
|
-
for (const item of removable) item.remove();
|
|
1117
|
-
}
|
|
1118
|
-
sanitizeAttributes(element, [...element.attributes]);
|
|
1119
|
-
}
|
|
1120
|
-
/**
|
|
1121
|
-
* Is the element clobbered?
|
|
1122
|
-
*
|
|
1123
|
-
* Thanks, DOMPurify _(https://github.com/cure53/DOMPurify)_
|
|
1124
|
-
*/
|
|
1125
|
-
function isClobbered(value) {
|
|
1126
|
-
return value instanceof HTMLFormElement && (typeof value.nodeName !== "string" || typeof value.textContent !== "string" || typeof value.removeChild !== "function" || !(value.attributes instanceof NamedNodeMap) || typeof value.removeAttribute !== "function" || typeof value.setAttribute !== "function" || typeof value.namespaceURI !== "string" || typeof value.insertBefore !== "function" || typeof value.hasChildNodes !== "function");
|
|
1127
|
-
}
|
|
1128
|
-
function removeNode(node) {
|
|
1129
|
-
if (typeof node.remove === "function") node.remove();
|
|
1130
|
-
}
|
|
1131
|
-
function sanitizeAttributes(element, attributes) {
|
|
1132
|
-
const { length } = attributes;
|
|
1133
|
-
for (let index = 0; index < length; index += 1) {
|
|
1134
|
-
const { name, value } = attributes[index];
|
|
1135
|
-
if (_isBadAttribute(name, value, false) || _isEmptyNonBooleanAttribute(name, value, false)) element.removeAttribute(name);
|
|
1136
|
-
else if (_isInvalidBooleanAttribute(name, value, false)) setAttribute(element, name, true);
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
function sanitizeNodes(nodes, depth) {
|
|
1140
|
-
const actual = nodes.filter((node) => node instanceof Node);
|
|
1141
|
-
let { length } = nodes;
|
|
1142
|
-
for (let index = 0; index < length; index += 1) {
|
|
1143
|
-
const node = actual[index];
|
|
1144
|
-
let remove = isClobbered(node);
|
|
1145
|
-
if (!remove) switch (node.nodeType) {
|
|
1146
|
-
case Node.ELEMENT_NODE:
|
|
1147
|
-
handleElement(node, depth);
|
|
1148
|
-
break;
|
|
1149
|
-
case Node.COMMENT_NODE:
|
|
1150
|
-
remove = COMMENT_HARMFUL.test(node.data);
|
|
1151
|
-
break;
|
|
1152
|
-
case Node.DOCUMENT_TYPE_NODE:
|
|
1153
|
-
case Node.PROCESSING_INSTRUCTION_NODE:
|
|
1154
|
-
remove = true;
|
|
1155
|
-
break;
|
|
1156
|
-
}
|
|
1157
|
-
if (remove) {
|
|
1158
|
-
removeNode(node);
|
|
1159
|
-
actual.splice(index, 1);
|
|
1160
|
-
index -= 1;
|
|
1161
|
-
length -= 1;
|
|
1162
|
-
continue;
|
|
1163
|
-
}
|
|
1164
|
-
if (node.hasChildNodes()) sanitizeNodes([...node.childNodes], depth + 1);
|
|
1165
|
-
}
|
|
1166
|
-
return nodes;
|
|
1167
|
-
}
|
|
1168
|
-
var COMMENT_HARMFUL = /<[/\w]/g;
|
|
1169
|
-
var REMOVE_SELECTOR = "script, toretto-temporary";
|
|
1170
|
-
function createHtml(value) {
|
|
1171
|
-
const parsed = getParser().parseFromString(getHtml(value), PARSE_TYPE_HTML);
|
|
1172
|
-
parsed.body.normalize();
|
|
1173
|
-
sanitizeNodes([parsed.body], 0);
|
|
1174
|
-
return parsed.body.innerHTML;
|
|
1175
|
-
}
|
|
1176
|
-
function createTemplate(value, options) {
|
|
1177
|
-
const template = document.createElement(TEMPLATE_TAG);
|
|
1178
|
-
template.innerHTML = createHtml(value);
|
|
1179
|
-
if (typeof value === "string" && options.cache) templates[value] = template;
|
|
1180
|
-
return template;
|
|
1181
|
-
}
|
|
1182
|
-
function getHtml(value) {
|
|
1183
|
-
return `${TEMPORARY_ELEMENT}${typeof value === "string" ? value : value.innerHTML}${TEMPORARY_ELEMENT}`;
|
|
1184
|
-
}
|
|
1185
|
-
function getNodes(value, options) {
|
|
1186
|
-
if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
|
|
1187
|
-
const template = getTemplate(value, options);
|
|
1188
|
-
return template == null ? [] : [...template.content.cloneNode(true).childNodes];
|
|
1189
|
-
}
|
|
1190
|
-
function getOptions(input) {
|
|
1191
|
-
const options = isPlainObject$1(input) ? input : {};
|
|
1192
|
-
options.cache = typeof options.cache === "boolean" ? options.cache : true;
|
|
1193
|
-
return options;
|
|
1194
|
-
}
|
|
1195
|
-
function getParser() {
|
|
1196
|
-
parser ??= new DOMParser();
|
|
1197
|
-
return parser;
|
|
1198
|
-
}
|
|
1199
|
-
function getTemplate(value, options) {
|
|
1200
|
-
if (value instanceof HTMLTemplateElement) return createTemplate(value, options);
|
|
1201
|
-
if (value.trim().length === 0) return;
|
|
1202
|
-
let template = templates[value];
|
|
1203
|
-
if (template != null) return template;
|
|
1204
|
-
const element = EXPRESSION_ID.test(value) ? document.querySelector(`#${value}`) : null;
|
|
1205
|
-
return createTemplate(element instanceof HTMLTemplateElement ? element : value, options);
|
|
1206
|
-
}
|
|
1207
|
-
var html = ((value, options) => {
|
|
1208
|
-
return getNodes(value, getOptions(options));
|
|
1209
|
-
});
|
|
1210
|
-
html.clear = () => {
|
|
1211
|
-
templates = {};
|
|
1212
|
-
};
|
|
1213
|
-
html.remove = (template) => {
|
|
1214
|
-
if (typeof template !== "string" || templates[template] == null) return;
|
|
1215
|
-
const keys = Object.keys(templates);
|
|
1216
|
-
const { length } = keys;
|
|
1217
|
-
const updated = {};
|
|
1218
|
-
for (let index = 0; index < length; index += 1) {
|
|
1219
|
-
const key = keys[index];
|
|
1220
|
-
if (key !== template) updated[key] = templates[key];
|
|
1221
|
-
}
|
|
1222
|
-
templates = updated;
|
|
1223
|
-
};
|
|
1224
|
-
var EXPRESSION_ID = /^[a-z][\w-]*$/i;
|
|
1225
|
-
var PARSE_TYPE_HTML = "text/html";
|
|
1226
|
-
var TEMPLATE_TAG = "template";
|
|
1227
|
-
var TEMPORARY_ELEMENT = "<toretto-temporary></toretto-temporary>";
|
|
1228
|
-
var parser;
|
|
1229
|
-
var templates = {};
|
|
1230
|
-
function getSupport() {
|
|
1231
|
-
if (window == null || navigator == null) return false;
|
|
1232
|
-
if ("matchMedia" in window) {
|
|
1233
|
-
const media = matchMedia?.("(pointer: coarse)");
|
|
1234
|
-
if (typeof media?.matches === "boolean" && media.matches) return true;
|
|
1235
|
-
}
|
|
1236
|
-
if ("ontouchstart" in window) return true;
|
|
1237
|
-
if (typeof navigator.maxTouchPoints === "number" && navigator.maxTouchPoints > 0) return true;
|
|
1238
|
-
if (typeof navigator.msMaxTouchPoints === "number" && navigator.msMaxTouchPoints > 0) return true;
|
|
1239
|
-
return false;
|
|
1240
|
-
}
|
|
1241
|
-
(() => {
|
|
1242
|
-
let support = getSupport();
|
|
1243
|
-
const instance = Object.create({
|
|
1244
|
-
get() {
|
|
1245
|
-
return support;
|
|
1246
|
-
},
|
|
1247
|
-
update() {
|
|
1248
|
-
support = getSupport();
|
|
1249
|
-
return support;
|
|
1250
|
-
}
|
|
1251
|
-
});
|
|
1252
|
-
Object.defineProperty(instance, "value", { get() {
|
|
1253
|
-
return support;
|
|
1254
|
-
} });
|
|
1255
|
-
return instance;
|
|
1256
|
-
})();
|
|
1257
1431
|
var EventManager = class {
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
this.listener = on(element, "click", (event) => {
|
|
1262
|
-
this.onClick(event);
|
|
1263
|
-
}, { passive: false });
|
|
1432
|
+
constructor(state) {
|
|
1433
|
+
this.state = state;
|
|
1434
|
+
mapped$1.set(state.element, this);
|
|
1264
1435
|
}
|
|
1265
1436
|
destroy() {
|
|
1266
|
-
this.
|
|
1267
|
-
|
|
1268
|
-
onClick(event) {
|
|
1269
|
-
const target = findAncestor(event, "[data-event]");
|
|
1270
|
-
if (!(target instanceof HTMLElement)) return;
|
|
1271
|
-
switch (target?.getAttribute("data-event")) {
|
|
1272
|
-
case "heading":
|
|
1273
|
-
this.onSort(event, target);
|
|
1274
|
-
break;
|
|
1275
|
-
}
|
|
1437
|
+
mapped$1.delete(this.state.element);
|
|
1438
|
+
this.state = void 0;
|
|
1276
1439
|
}
|
|
1277
1440
|
onSort(event, target) {
|
|
1278
|
-
const { managers } = this;
|
|
1279
1441
|
const direction = target.getAttribute("data-sort-direction");
|
|
1280
1442
|
const field = target.getAttribute("data-field");
|
|
1281
|
-
if (field != null) managers.sort.toggle(event, field, direction);
|
|
1443
|
+
if (field != null) this.state.managers.sort.toggle(event, field, direction);
|
|
1282
1444
|
}
|
|
1283
1445
|
};
|
|
1446
|
+
function onClick(event) {
|
|
1447
|
+
const target = findAncestor(event, "[data-event]");
|
|
1448
|
+
const table = findAncestor(event, ".tabela");
|
|
1449
|
+
if (!(target instanceof HTMLElement) || !(table instanceof HTMLElement)) return;
|
|
1450
|
+
const manager = mapped$1.get(table);
|
|
1451
|
+
if (manager == null) return;
|
|
1452
|
+
switch (target?.getAttribute("data-event")) {
|
|
1453
|
+
case "heading":
|
|
1454
|
+
manager.onSort(event, target);
|
|
1455
|
+
break;
|
|
1456
|
+
case "row":
|
|
1457
|
+
manager.state.managers.selection.handle(event, target);
|
|
1458
|
+
break;
|
|
1459
|
+
default: break;
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
function onKeydown(event) {
|
|
1463
|
+
const target = findAncestor(event, "[data-event]");
|
|
1464
|
+
const table = findAncestor(event, ".tabela");
|
|
1465
|
+
if (!(target instanceof HTMLElement) || !(table instanceof HTMLElement)) return;
|
|
1466
|
+
const manager = mapped$1.get(table);
|
|
1467
|
+
if (manager == null) return;
|
|
1468
|
+
switch (target?.getAttribute("data-event")) {
|
|
1469
|
+
case "body":
|
|
1470
|
+
manager.state.managers.navigation.handle(event);
|
|
1471
|
+
break;
|
|
1472
|
+
default: break;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
const mapped$1 = /* @__PURE__ */ new WeakMap();
|
|
1476
|
+
on(document, "click", onClick);
|
|
1477
|
+
on(document, "keydown", onKeydown, { passive: false });
|
|
1284
1478
|
/**
|
|
1285
1479
|
* Clamp a number between a minimum and maximum value
|
|
1286
1480
|
* @param value Value to clamp
|
|
@@ -1685,8 +1879,8 @@ var FilterManager = class {
|
|
|
1685
1879
|
set: (items) => this.set(items)
|
|
1686
1880
|
});
|
|
1687
1881
|
items = {};
|
|
1688
|
-
constructor(
|
|
1689
|
-
this.
|
|
1882
|
+
constructor(state) {
|
|
1883
|
+
this.state = state;
|
|
1690
1884
|
}
|
|
1691
1885
|
add(item) {
|
|
1692
1886
|
if (this.items[item.field] == null) this.items[item.field] = [];
|
|
@@ -1702,16 +1896,17 @@ var FilterManager = class {
|
|
|
1702
1896
|
}
|
|
1703
1897
|
destroy() {
|
|
1704
1898
|
this.handlers = void 0;
|
|
1705
|
-
this.items =
|
|
1899
|
+
this.items = void 0;
|
|
1900
|
+
this.state = void 0;
|
|
1706
1901
|
}
|
|
1707
1902
|
filter() {
|
|
1708
|
-
const {
|
|
1903
|
+
const { state } = this;
|
|
1709
1904
|
const filtered = [];
|
|
1710
1905
|
const filters = Object.entries(this.items);
|
|
1711
|
-
const keysLength = managers.data.values.keys.original.length;
|
|
1906
|
+
const keysLength = state.managers.data.values.keys.original.length;
|
|
1712
1907
|
rowLoop: for (let keyIndex = 0; keyIndex < keysLength; keyIndex += 1) {
|
|
1713
|
-
const key = managers.data.values.keys.original[keyIndex];
|
|
1714
|
-
const row = managers.data.values.objects.mapped.get(key);
|
|
1908
|
+
const key = state.managers.data.values.keys.original[keyIndex];
|
|
1909
|
+
const row = state.managers.data.values.objects.mapped.get(key);
|
|
1715
1910
|
if (row == null) continue;
|
|
1716
1911
|
filterLoop: for (let filterIndex = 0; filterIndex < filters.length; filterIndex += 1) {
|
|
1717
1912
|
const [field, items] = filters[filterIndex];
|
|
@@ -1724,9 +1919,9 @@ var FilterManager = class {
|
|
|
1724
1919
|
}
|
|
1725
1920
|
filtered.push(key);
|
|
1726
1921
|
}
|
|
1727
|
-
managers.data.values.keys.active = filtered;
|
|
1728
|
-
if (managers.sort.items.length > 0) managers.sort.sort();
|
|
1729
|
-
else managers.
|
|
1922
|
+
state.managers.data.values.keys.active = filtered;
|
|
1923
|
+
if (state.managers.sort.items.length > 0) state.managers.sort.sort();
|
|
1924
|
+
else state.managers.render.update(true, true);
|
|
1730
1925
|
}
|
|
1731
1926
|
remove(value) {
|
|
1732
1927
|
if (typeof value === "string") {
|
|
@@ -1764,6 +1959,81 @@ const comparators = {
|
|
|
1764
1959
|
"starts-with": (row, filter) => startsWith(getString(row), getString(filter), true)
|
|
1765
1960
|
};
|
|
1766
1961
|
const equalizer = equal.initialize({ ignoreCase: true });
|
|
1962
|
+
function getKey(value) {
|
|
1963
|
+
if (typeof value === "number") return value;
|
|
1964
|
+
if (typeof value !== "string") return;
|
|
1965
|
+
return integerExpression.test(value) ? Number.parseInt(value, 10) : value;
|
|
1966
|
+
}
|
|
1967
|
+
const integerExpression = /^\d+$/;
|
|
1968
|
+
var NavigationManager = class {
|
|
1969
|
+
active;
|
|
1970
|
+
constructor(state) {
|
|
1971
|
+
this.state = state;
|
|
1972
|
+
}
|
|
1973
|
+
destroy() {
|
|
1974
|
+
this.state = void 0;
|
|
1975
|
+
}
|
|
1976
|
+
handle(event) {
|
|
1977
|
+
if (!allKeys.has(event.key)) return;
|
|
1978
|
+
event.preventDefault();
|
|
1979
|
+
const { components, id, managers } = this.state;
|
|
1980
|
+
const activeDescendant = components.body.elements.group.getAttribute("aria-activedescendant");
|
|
1981
|
+
const keys = managers.data.values.keys.active ?? managers.data.values.keys.original;
|
|
1982
|
+
const { length } = keys;
|
|
1983
|
+
let next;
|
|
1984
|
+
if (isNullableOrWhitespace(activeDescendant)) next = getDefaultIndex(event.key, length);
|
|
1985
|
+
else next = getIndex(event, activeDescendant, id, keys);
|
|
1986
|
+
if (next != null) this.setActive(keys.at(next));
|
|
1987
|
+
}
|
|
1988
|
+
setActive(key, scroll) {
|
|
1989
|
+
const { components, managers, options } = this.state;
|
|
1990
|
+
this.active = key;
|
|
1991
|
+
const active = components.body.elements.group.querySelectorAll("[data-active=\"true\"]");
|
|
1992
|
+
for (const item of active) item.setAttribute("data-active", "false");
|
|
1993
|
+
const row = managers.row.get(key);
|
|
1994
|
+
if (row != null) {
|
|
1995
|
+
row.element?.setAttribute("data-active", "true");
|
|
1996
|
+
if (scroll ?? true) if (row.element == null) components.body.elements.group.scrollTo({
|
|
1997
|
+
top: managers.data.getIndex(key) * options.rowHeight,
|
|
1998
|
+
behavior: "smooth"
|
|
1999
|
+
});
|
|
2000
|
+
else row.element.scrollIntoView({ block: "nearest" });
|
|
2001
|
+
}
|
|
2002
|
+
components.body.elements.group.setAttribute("aria-activedescendant", row == null ? "" : `tabela_${this.state.id}_row_${key}`);
|
|
2003
|
+
}
|
|
2004
|
+
};
|
|
2005
|
+
function getDefaultIndex(key, max) {
|
|
2006
|
+
switch (true) {
|
|
2007
|
+
case negativeDefaultKeys.has(key): return -1;
|
|
2008
|
+
case key === "PageDown": return Math.min(9, max - 1);
|
|
2009
|
+
case key === "PageUp": return max < 10 ? 0 : max - 10;
|
|
2010
|
+
default: return 0;
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
function getIndex(event, active, id, keys) {
|
|
2014
|
+
const key = getKey(active.replace(`tabela_${id}_row_`, ""));
|
|
2015
|
+
if (key == null) return;
|
|
2016
|
+
if (absoluteKeys.has(event.key)) return event.key === "Home" ? 0 : keys.length - 1;
|
|
2017
|
+
return clamp(keys.indexOf(key) + getOffset(event.key), 0, keys.length - 1, true);
|
|
2018
|
+
}
|
|
2019
|
+
function getOffset(key) {
|
|
2020
|
+
switch (key) {
|
|
2021
|
+
case "ArrowDown": return 1;
|
|
2022
|
+
case "ArrowUp": return -1;
|
|
2023
|
+
case "PageDown": return 10;
|
|
2024
|
+
case "PageUp": return -10;
|
|
2025
|
+
default: return 0;
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
const absoluteKeys = new Set(["End", "Home"]);
|
|
2029
|
+
const arrowKeys = new Set(["ArrowDown", "ArrowUp"]);
|
|
2030
|
+
const negativeDefaultKeys = new Set(["ArrowUp", "End"]);
|
|
2031
|
+
const pageKeys = new Set(["PageDown", "PageUp"]);
|
|
2032
|
+
const allKeys = new Set([
|
|
2033
|
+
...absoluteKeys,
|
|
2034
|
+
...arrowKeys,
|
|
2035
|
+
...pageKeys
|
|
2036
|
+
]);
|
|
1767
2037
|
function removeRow(pool, row) {
|
|
1768
2038
|
if (row.element != null) {
|
|
1769
2039
|
row.element.innerHTML = "";
|
|
@@ -1773,19 +2043,30 @@ function removeRow(pool, row) {
|
|
|
1773
2043
|
}
|
|
1774
2044
|
row.cells = {};
|
|
1775
2045
|
}
|
|
1776
|
-
function renderRow(
|
|
1777
|
-
const element = row.element ?? managers.
|
|
2046
|
+
function renderRow(state, row) {
|
|
2047
|
+
const element = row.element ?? state.managers.render.pool.rows.shift() ?? createRow();
|
|
1778
2048
|
row.element = element;
|
|
1779
|
-
element.dataset.key = String(row.key);
|
|
1780
2049
|
element.innerHTML = "";
|
|
1781
|
-
const
|
|
2050
|
+
const selected = state.managers.selection.items.has(row.key);
|
|
2051
|
+
const key = String(row.key);
|
|
2052
|
+
setAttributes(element, {
|
|
2053
|
+
"aria-selected": String(selected),
|
|
2054
|
+
"data-active": String(state.managers.navigation.active === row.key),
|
|
2055
|
+
"data-event": "row",
|
|
2056
|
+
"data-key": key,
|
|
2057
|
+
id: `tabela_${state.id}_row_${key}`
|
|
2058
|
+
});
|
|
2059
|
+
element.classList.add("tabela__row--body");
|
|
2060
|
+
if (selected) element.classList.add("tabela__row--selected");
|
|
2061
|
+
else element.classList.remove("tabela__row--selected");
|
|
2062
|
+
const columns = state.managers.column.items;
|
|
1782
2063
|
const { length } = columns;
|
|
1783
|
-
const data = managers.data.values.objects.mapped.get(row.key);
|
|
2064
|
+
const data = state.managers.data.values.objects.mapped.get(row.key);
|
|
1784
2065
|
if (data == null) return;
|
|
1785
2066
|
for (let index = 0; index < length; index += 1) {
|
|
1786
2067
|
const { options } = columns[index];
|
|
1787
|
-
managers.
|
|
1788
|
-
const cell = managers.
|
|
2068
|
+
state.managers.render.pool.cells[options.field] ??= [];
|
|
2069
|
+
const cell = state.managers.render.pool.cells[columns[index].options.field].shift() ?? createCell(options.width);
|
|
1789
2070
|
cell.textContent = String(data[options.field]);
|
|
1790
2071
|
row.cells[options.field] = cell;
|
|
1791
2072
|
element.append(cell);
|
|
@@ -1798,42 +2079,500 @@ var RowComponent = class {
|
|
|
1798
2079
|
this.key = key;
|
|
1799
2080
|
}
|
|
1800
2081
|
};
|
|
1801
|
-
|
|
1802
|
-
components
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
2082
|
+
function getRange(down) {
|
|
2083
|
+
const { components, managers, options } = this.state;
|
|
2084
|
+
const { clientHeight, scrollTop } = components.body.elements.group;
|
|
2085
|
+
const first = Math.floor(scrollTop / options.rowHeight);
|
|
2086
|
+
const last = Math.min((managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length) - 1, Math.ceil((scrollTop + clientHeight) / options.rowHeight) - 1);
|
|
2087
|
+
const before = Math.ceil(clientHeight / options.rowHeight) * (down ? 1 : 2);
|
|
2088
|
+
const after = Math.ceil(clientHeight / options.rowHeight) * (down ? 2 : 1);
|
|
2089
|
+
const start = Math.max(0, first - before);
|
|
2090
|
+
return {
|
|
2091
|
+
end: Math.min((managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length) - 1, last + after),
|
|
2092
|
+
start
|
|
2093
|
+
};
|
|
2094
|
+
}
|
|
2095
|
+
function onScroll() {
|
|
2096
|
+
const { state } = this;
|
|
2097
|
+
if (!state.active) {
|
|
2098
|
+
requestAnimationFrame(() => {
|
|
2099
|
+
const top = state.components.body.elements.group.scrollTop;
|
|
2100
|
+
this.update(top > state.top);
|
|
2101
|
+
state.active = false;
|
|
2102
|
+
state.top = top;
|
|
2103
|
+
});
|
|
2104
|
+
state.active = true;
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
var RenderManager = class {
|
|
2108
|
+
fragment;
|
|
2109
|
+
listener;
|
|
2110
|
+
pool = {
|
|
2111
|
+
cells: {},
|
|
2112
|
+
rows: []
|
|
2113
|
+
};
|
|
2114
|
+
state;
|
|
2115
|
+
visible = /* @__PURE__ */ new Map();
|
|
2116
|
+
constructor(state) {
|
|
2117
|
+
this.listener = on(state.components.body.elements.group, "scroll", onScroll.bind(this));
|
|
2118
|
+
this.state = {
|
|
2119
|
+
...state,
|
|
2120
|
+
active: false,
|
|
2121
|
+
top: 0
|
|
2122
|
+
};
|
|
1807
2123
|
}
|
|
1808
2124
|
destroy() {
|
|
1809
|
-
const
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
2125
|
+
const { listener, pool, visible } = this;
|
|
2126
|
+
listener();
|
|
2127
|
+
visible.clear();
|
|
2128
|
+
pool.cells = {};
|
|
2129
|
+
pool.rows = [];
|
|
2130
|
+
this.fragment = void 0;
|
|
2131
|
+
this.listener = void 0;
|
|
2132
|
+
this.pool = void 0;
|
|
2133
|
+
this.state = void 0;
|
|
2134
|
+
this.visible = void 0;
|
|
1813
2135
|
}
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
2136
|
+
removeCells(fields) {
|
|
2137
|
+
const { pool, state, visible } = this;
|
|
2138
|
+
const { length } = fields;
|
|
2139
|
+
for (let index = 0; index < length; index += 1) delete pool.cells[fields[index]];
|
|
2140
|
+
for (const [, key] of visible) {
|
|
2141
|
+
const row = state.managers.row.get(key);
|
|
2142
|
+
if (row == null || row.element == null) continue;
|
|
2143
|
+
for (let index = 0; index < length; index += 1) {
|
|
2144
|
+
row.cells[fields[index]].innerHTML = "";
|
|
2145
|
+
row.cells[fields[index]].remove();
|
|
2146
|
+
delete row.cells[fields[index]];
|
|
2147
|
+
}
|
|
1819
2148
|
}
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
2149
|
+
}
|
|
2150
|
+
getFragment() {
|
|
2151
|
+
this.fragment ??= document.createDocumentFragment();
|
|
2152
|
+
this.fragment.replaceChildren();
|
|
2153
|
+
return this.fragment;
|
|
2154
|
+
}
|
|
2155
|
+
update(down, rerender) {
|
|
2156
|
+
const { state, pool, visible } = this;
|
|
2157
|
+
const { components, managers, options } = state;
|
|
2158
|
+
components.body.elements.faker.style.height = `${managers.data.size * options.rowHeight}px`;
|
|
2159
|
+
const indices = /* @__PURE__ */ new Set();
|
|
2160
|
+
const range = getRange.call(this, down);
|
|
2161
|
+
for (let index = range.start; index <= range.end; index += 1) indices.add(index);
|
|
2162
|
+
let remove = rerender ?? false;
|
|
2163
|
+
for (const [index, key] of visible) {
|
|
2164
|
+
const row = managers.row.get(key);
|
|
2165
|
+
if (remove || row == null || !indices.has(index)) {
|
|
2166
|
+
visible.delete(index);
|
|
2167
|
+
if (row != null) removeRow(pool, row);
|
|
2168
|
+
}
|
|
2169
|
+
}
|
|
2170
|
+
const fragment = this.getFragment();
|
|
2171
|
+
const keys = managers.data.values.keys.active ?? managers.data.values.keys.original;
|
|
2172
|
+
let count = 0;
|
|
2173
|
+
for (let index = range.start; index <= range.end; index += 1) {
|
|
2174
|
+
if (visible.has(index)) continue;
|
|
2175
|
+
const key = keys[index];
|
|
2176
|
+
const row = managers.row.get(key);
|
|
2177
|
+
if (row == null) continue;
|
|
2178
|
+
count += 1;
|
|
2179
|
+
renderRow(state, row);
|
|
2180
|
+
visible.set(index, key);
|
|
2181
|
+
if (row.element != null) {
|
|
2182
|
+
row.element.style.transform = `translateY(${index * options.rowHeight}px)`;
|
|
2183
|
+
fragment.append(row.element);
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
if (count > 0) components.body.elements.group[down ? "append" : "prepend"](fragment);
|
|
2187
|
+
}
|
|
2188
|
+
};
|
|
2189
|
+
var RowManager = class {
|
|
2190
|
+
components = /* @__PURE__ */ new Map();
|
|
2191
|
+
constructor(state) {
|
|
2192
|
+
this.state = state;
|
|
2193
|
+
}
|
|
2194
|
+
destroy() {
|
|
2195
|
+
const components = [...this.components.values()];
|
|
2196
|
+
const { length } = components;
|
|
2197
|
+
for (let index = 0; index < length; index += 1) removeRow(this.state.managers.render.pool, components[index]);
|
|
2198
|
+
this.components.clear();
|
|
2199
|
+
this.components = void 0;
|
|
2200
|
+
this.state = void 0;
|
|
2201
|
+
}
|
|
2202
|
+
get(key) {
|
|
2203
|
+
let row = this.components.get(key);
|
|
2204
|
+
if (row == null) {
|
|
2205
|
+
row = new RowComponent(key);
|
|
2206
|
+
this.components.set(key, row);
|
|
2207
|
+
}
|
|
2208
|
+
return row;
|
|
2209
|
+
}
|
|
2210
|
+
has(key) {
|
|
2211
|
+
return this.components.has(key);
|
|
1824
2212
|
}
|
|
1825
2213
|
remove(key) {
|
|
1826
2214
|
const row = this.components.get(key);
|
|
1827
2215
|
if (row != null) {
|
|
1828
|
-
removeRow(this.managers.
|
|
2216
|
+
removeRow(this.state.managers.render.pool, row);
|
|
1829
2217
|
this.components.delete(key);
|
|
1830
2218
|
}
|
|
1831
2219
|
}
|
|
1832
2220
|
update(key) {
|
|
1833
2221
|
const row = this.components.get(key);
|
|
1834
|
-
if (row != null) renderRow(this.
|
|
2222
|
+
if (row != null) renderRow(this.state, row);
|
|
1835
2223
|
}
|
|
1836
2224
|
};
|
|
2225
|
+
function isInert(item) {
|
|
2226
|
+
return (item.element.inert ?? false) || EXPRESSION_TRUEISH.test(item.element.getAttribute(ATTRIBUTE_INERT)) || item.element.parentElement != null && isInert({
|
|
2227
|
+
element: item.element.parentElement,
|
|
2228
|
+
tabIndex: TABINDEX_DEFAULT
|
|
2229
|
+
});
|
|
2230
|
+
}
|
|
2231
|
+
var ATTRIBUTE_INERT = "inert";
|
|
2232
|
+
var EXPRESSION_TRUEISH = /^(|true)$/i;
|
|
2233
|
+
[
|
|
2234
|
+
"[contenteditable]:not([contenteditable=\"false\"])",
|
|
2235
|
+
"[tabindex]:not(slot)",
|
|
2236
|
+
"a[href]",
|
|
2237
|
+
"audio[controls]",
|
|
2238
|
+
"button",
|
|
2239
|
+
"details",
|
|
2240
|
+
"details > summary:first-of-type",
|
|
2241
|
+
"input",
|
|
2242
|
+
"select",
|
|
2243
|
+
"textarea",
|
|
2244
|
+
"video[controls]"
|
|
2245
|
+
].map((selector) => `${selector}:not([inert])`).join(",");
|
|
2246
|
+
var TABINDEX_DEFAULT = -1;
|
|
2247
|
+
function handleElement(element, depth) {
|
|
2248
|
+
if (depth === 0) {
|
|
2249
|
+
const removable = element.querySelectorAll(REMOVE_SELECTOR);
|
|
2250
|
+
for (const item of removable) item.remove();
|
|
2251
|
+
}
|
|
2252
|
+
sanitizeAttributes(element, [...element.attributes]);
|
|
2253
|
+
}
|
|
2254
|
+
/**
|
|
2255
|
+
* Is the element clobbered?
|
|
2256
|
+
*
|
|
2257
|
+
* Thanks, DOMPurify _(https://github.com/cure53/DOMPurify)_
|
|
2258
|
+
*/
|
|
2259
|
+
function isClobbered(value) {
|
|
2260
|
+
return value instanceof HTMLFormElement && (typeof value.nodeName !== "string" || typeof value.textContent !== "string" || typeof value.removeChild !== "function" || !(value.attributes instanceof NamedNodeMap) || typeof value.removeAttribute !== "function" || typeof value.setAttribute !== "function" || typeof value.namespaceURI !== "string" || typeof value.insertBefore !== "function" || typeof value.hasChildNodes !== "function");
|
|
2261
|
+
}
|
|
2262
|
+
function removeNode(node) {
|
|
2263
|
+
if (typeof node.remove === "function") node.remove();
|
|
2264
|
+
}
|
|
2265
|
+
function sanitizeAttributes(element, attributes) {
|
|
2266
|
+
const { length } = attributes;
|
|
2267
|
+
for (let index = 0; index < length; index += 1) {
|
|
2268
|
+
const { name, value } = attributes[index];
|
|
2269
|
+
if (_isBadAttribute(name, value, false) || _isEmptyNonBooleanAttribute(name, value, false)) element.removeAttribute(name);
|
|
2270
|
+
else if (_isInvalidBooleanAttribute(name, value, false)) setAttribute(element, name, true);
|
|
2271
|
+
}
|
|
2272
|
+
}
|
|
2273
|
+
function sanitizeNodes(nodes, depth) {
|
|
2274
|
+
const actual = nodes.filter((node) => node instanceof Node);
|
|
2275
|
+
let { length } = nodes;
|
|
2276
|
+
for (let index = 0; index < length; index += 1) {
|
|
2277
|
+
const node = actual[index];
|
|
2278
|
+
let remove = isClobbered(node);
|
|
2279
|
+
if (!remove) switch (node.nodeType) {
|
|
2280
|
+
case Node.ELEMENT_NODE:
|
|
2281
|
+
handleElement(node, depth);
|
|
2282
|
+
break;
|
|
2283
|
+
case Node.COMMENT_NODE:
|
|
2284
|
+
remove = COMMENT_HARMFUL.test(node.data);
|
|
2285
|
+
break;
|
|
2286
|
+
case Node.DOCUMENT_TYPE_NODE:
|
|
2287
|
+
case Node.PROCESSING_INSTRUCTION_NODE:
|
|
2288
|
+
remove = true;
|
|
2289
|
+
break;
|
|
2290
|
+
}
|
|
2291
|
+
if (remove) {
|
|
2292
|
+
removeNode(node);
|
|
2293
|
+
actual.splice(index, 1);
|
|
2294
|
+
index -= 1;
|
|
2295
|
+
length -= 1;
|
|
2296
|
+
continue;
|
|
2297
|
+
}
|
|
2298
|
+
if (node.hasChildNodes()) sanitizeNodes([...node.childNodes], depth + 1);
|
|
2299
|
+
}
|
|
2300
|
+
return nodes;
|
|
2301
|
+
}
|
|
2302
|
+
var COMMENT_HARMFUL = /<[/\w]/g;
|
|
2303
|
+
var REMOVE_SELECTOR = "script, toretto-temporary";
|
|
2304
|
+
function createHtml(value) {
|
|
2305
|
+
const parsed = getParser().parseFromString(getHtml(value), PARSE_TYPE_HTML);
|
|
2306
|
+
parsed.body.normalize();
|
|
2307
|
+
sanitizeNodes([parsed.body], 0);
|
|
2308
|
+
return parsed.body.innerHTML;
|
|
2309
|
+
}
|
|
2310
|
+
function createTemplate(value, options) {
|
|
2311
|
+
const template = document.createElement(TEMPLATE_TAG);
|
|
2312
|
+
template.innerHTML = createHtml(value);
|
|
2313
|
+
if (typeof value === "string" && options.cache) templates[value] = template;
|
|
2314
|
+
return template;
|
|
2315
|
+
}
|
|
2316
|
+
function getHtml(value) {
|
|
2317
|
+
return `${TEMPORARY_ELEMENT}${typeof value === "string" ? value : value.innerHTML}${TEMPORARY_ELEMENT}`;
|
|
2318
|
+
}
|
|
2319
|
+
function getNodes(value, options) {
|
|
2320
|
+
if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
|
|
2321
|
+
const template = getTemplate(value, options);
|
|
2322
|
+
return template == null ? [] : [...template.content.cloneNode(true).childNodes];
|
|
2323
|
+
}
|
|
2324
|
+
function getOptions(input) {
|
|
2325
|
+
const options = isPlainObject$1(input) ? input : {};
|
|
2326
|
+
options.cache = typeof options.cache === "boolean" ? options.cache : true;
|
|
2327
|
+
return options;
|
|
2328
|
+
}
|
|
2329
|
+
function getParser() {
|
|
2330
|
+
parser ??= new DOMParser();
|
|
2331
|
+
return parser;
|
|
2332
|
+
}
|
|
2333
|
+
function getTemplate(value, options) {
|
|
2334
|
+
if (value instanceof HTMLTemplateElement) return createTemplate(value, options);
|
|
2335
|
+
if (value.trim().length === 0) return;
|
|
2336
|
+
let template = templates[value];
|
|
2337
|
+
if (template != null) return template;
|
|
2338
|
+
const element = EXPRESSION_ID.test(value) ? document.querySelector(`#${value}`) : null;
|
|
2339
|
+
return createTemplate(element instanceof HTMLTemplateElement ? element : value, options);
|
|
2340
|
+
}
|
|
2341
|
+
var html = ((value, options) => {
|
|
2342
|
+
return getNodes(value, getOptions(options));
|
|
2343
|
+
});
|
|
2344
|
+
html.clear = () => {
|
|
2345
|
+
templates = {};
|
|
2346
|
+
};
|
|
2347
|
+
html.remove = (template) => {
|
|
2348
|
+
if (typeof template !== "string" || templates[template] == null) return;
|
|
2349
|
+
const keys = Object.keys(templates);
|
|
2350
|
+
const { length } = keys;
|
|
2351
|
+
const updated = {};
|
|
2352
|
+
for (let index = 0; index < length; index += 1) {
|
|
2353
|
+
const key = keys[index];
|
|
2354
|
+
if (key !== template) updated[key] = templates[key];
|
|
2355
|
+
}
|
|
2356
|
+
templates = updated;
|
|
2357
|
+
};
|
|
2358
|
+
var EXPRESSION_ID = /^[a-z][\w-]*$/i;
|
|
2359
|
+
var PARSE_TYPE_HTML = "text/html";
|
|
2360
|
+
var TEMPLATE_TAG = "template";
|
|
2361
|
+
var TEMPORARY_ELEMENT = "<toretto-temporary></toretto-temporary>";
|
|
2362
|
+
var parser;
|
|
2363
|
+
var templates = {};
|
|
2364
|
+
function getSupport() {
|
|
2365
|
+
if (window == null || navigator == null) return false;
|
|
2366
|
+
if ("matchMedia" in window) {
|
|
2367
|
+
const media = matchMedia?.("(pointer: coarse)");
|
|
2368
|
+
if (typeof media?.matches === "boolean" && media.matches) return true;
|
|
2369
|
+
}
|
|
2370
|
+
if ("ontouchstart" in window) return true;
|
|
2371
|
+
if (typeof navigator.maxTouchPoints === "number" && navigator.maxTouchPoints > 0) return true;
|
|
2372
|
+
if (typeof navigator.msMaxTouchPoints === "number" && navigator.msMaxTouchPoints > 0) return true;
|
|
2373
|
+
return false;
|
|
2374
|
+
}
|
|
2375
|
+
(() => {
|
|
2376
|
+
let support = getSupport();
|
|
2377
|
+
const instance = Object.create({
|
|
2378
|
+
get() {
|
|
2379
|
+
return support;
|
|
2380
|
+
},
|
|
2381
|
+
update() {
|
|
2382
|
+
support = getSupport();
|
|
2383
|
+
return support;
|
|
2384
|
+
}
|
|
2385
|
+
});
|
|
2386
|
+
Object.defineProperty(instance, "value", { get() {
|
|
2387
|
+
return support;
|
|
2388
|
+
} });
|
|
2389
|
+
return instance;
|
|
2390
|
+
})();
|
|
2391
|
+
const dragStyling = toggleStyles(document.body, {
|
|
2392
|
+
userSelect: "none",
|
|
2393
|
+
webkitUserSelect: "none"
|
|
2394
|
+
});
|
|
2395
|
+
var SelectionManager = class {
|
|
2396
|
+
handlers = Object.freeze({
|
|
2397
|
+
clear: () => this.clear(),
|
|
2398
|
+
deselect: (keys) => this.deselect(keys),
|
|
2399
|
+
select: (keys) => this.select(keys),
|
|
2400
|
+
toggle: () => this.toggle()
|
|
2401
|
+
});
|
|
2402
|
+
items = /* @__PURE__ */ new Set();
|
|
2403
|
+
last;
|
|
2404
|
+
constructor(state) {
|
|
2405
|
+
this.state = state;
|
|
2406
|
+
mapped.set(state.element, this);
|
|
2407
|
+
}
|
|
2408
|
+
clear() {
|
|
2409
|
+
if (this.items.size === 0) return;
|
|
2410
|
+
const removed = [...this.items];
|
|
2411
|
+
this.items.clear();
|
|
2412
|
+
this.update(removed);
|
|
2413
|
+
}
|
|
2414
|
+
deselect(keys) {
|
|
2415
|
+
const { length } = keys;
|
|
2416
|
+
const removed = [];
|
|
2417
|
+
for (let index = 0; index < length; index += 1) {
|
|
2418
|
+
const key = keys[index];
|
|
2419
|
+
if (this.items.delete(key)) removed.push(key);
|
|
2420
|
+
}
|
|
2421
|
+
if (removed.length > 0) this.update(removed);
|
|
2422
|
+
}
|
|
2423
|
+
destroy() {
|
|
2424
|
+
mapped.delete(this.state.element);
|
|
2425
|
+
this.handlers = void 0;
|
|
2426
|
+
this.items = void 0;
|
|
2427
|
+
this.last = void 0;
|
|
2428
|
+
this.state = void 0;
|
|
2429
|
+
}
|
|
2430
|
+
handle(event, target) {
|
|
2431
|
+
const key = getKey(target.getAttribute("data-key"));
|
|
2432
|
+
if (key == null) return;
|
|
2433
|
+
const { items } = this;
|
|
2434
|
+
if (event.shiftKey) {
|
|
2435
|
+
if (this.last == null) this.state.managers.navigation.setActive(key, false);
|
|
2436
|
+
else this.range(this.last, key);
|
|
2437
|
+
return;
|
|
2438
|
+
}
|
|
2439
|
+
this.last = key;
|
|
2440
|
+
this.state.managers.navigation.setActive(key, false);
|
|
2441
|
+
if (event.ctrlKey || event.metaKey) {
|
|
2442
|
+
if (items.has(key)) this.deselect([key]);
|
|
2443
|
+
else this.select([key]);
|
|
2444
|
+
return;
|
|
2445
|
+
}
|
|
2446
|
+
this.set([key]);
|
|
2447
|
+
}
|
|
2448
|
+
range(from, to) {
|
|
2449
|
+
const { state } = this;
|
|
2450
|
+
const keyed = isKey(from) && isKey(to);
|
|
2451
|
+
const fromKey = keyed ? from : getKey(from.getAttribute("data-key"));
|
|
2452
|
+
const toKey = keyed ? to : getKey(to.getAttribute("data-key"));
|
|
2453
|
+
if (fromKey === toKey) return;
|
|
2454
|
+
const keys = state.managers.data.values.keys.active ?? state.managers.data.values.keys.original;
|
|
2455
|
+
const fromIndex = state.managers.data.getIndex(fromKey);
|
|
2456
|
+
const toIndex = state.managers.data.getIndex(toKey);
|
|
2457
|
+
if (fromIndex === -1 || toIndex === -1) return;
|
|
2458
|
+
const [start, end] = fromIndex < toIndex ? [fromIndex, toIndex] : [toIndex, fromIndex];
|
|
2459
|
+
const selected = [];
|
|
2460
|
+
for (let index = start; index <= end; index += 1) selected.push(keys[index]);
|
|
2461
|
+
if (keyed) this.select(selected);
|
|
2462
|
+
else this.set(selected);
|
|
2463
|
+
this.last = toKey;
|
|
2464
|
+
this.state.managers.navigation.setActive(toKey, false);
|
|
2465
|
+
}
|
|
2466
|
+
select(keys) {
|
|
2467
|
+
const { length } = keys;
|
|
2468
|
+
let update = false;
|
|
2469
|
+
for (let index = 0; index < length; index += 1) {
|
|
2470
|
+
const key = keys[index];
|
|
2471
|
+
if (!this.items.has(key)) {
|
|
2472
|
+
this.items.add(key);
|
|
2473
|
+
update = true;
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2476
|
+
if (update) this.update([]);
|
|
2477
|
+
}
|
|
2478
|
+
set(keys) {
|
|
2479
|
+
const { items } = this;
|
|
2480
|
+
const removed = [...items].filter((key) => !keys.includes(key));
|
|
2481
|
+
const added = keys.filter((key) => !items.has(key));
|
|
2482
|
+
if (removed.length === 0 && added.length === 0) return;
|
|
2483
|
+
this.items = new Set(keys);
|
|
2484
|
+
this.update(removed);
|
|
2485
|
+
}
|
|
2486
|
+
toggle() {
|
|
2487
|
+
const { items, state } = this;
|
|
2488
|
+
const all = state.managers.data.values.keys.active ?? state.managers.data.values.keys.original;
|
|
2489
|
+
if (items.size === all.length) this.clear();
|
|
2490
|
+
else this.select(all);
|
|
2491
|
+
}
|
|
2492
|
+
update(removed) {
|
|
2493
|
+
const items = [...removed.map((key) => ({
|
|
2494
|
+
key,
|
|
2495
|
+
removed: true
|
|
2496
|
+
})), ...[...this.items].map((key) => ({
|
|
2497
|
+
key,
|
|
2498
|
+
removed: false
|
|
2499
|
+
}))];
|
|
2500
|
+
const { length } = items;
|
|
2501
|
+
for (let index = 0; index < length; index += 1) {
|
|
2502
|
+
const { key, removed } = items[index];
|
|
2503
|
+
const row = this.state.managers.row.get(key);
|
|
2504
|
+
if (row == null || row.element == null) continue;
|
|
2505
|
+
setAttribute(row.element, "aria-selected", String(!removed));
|
|
2506
|
+
if (removed) row.element.classList.remove("tabela__row--selected");
|
|
2507
|
+
else row.element.classList.add("tabela__row--selected");
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2510
|
+
};
|
|
2511
|
+
function getPlaceholder() {
|
|
2512
|
+
placeholder ??= createElement("div", { className: "tabela__selection--placeholder" }, {}, {});
|
|
2513
|
+
return placeholder;
|
|
2514
|
+
}
|
|
2515
|
+
function onMouseDown(event) {
|
|
2516
|
+
if (shifted) {
|
|
2517
|
+
const row = findAncestor(event.target, ".tabela__row--body");
|
|
2518
|
+
if (!(row instanceof HTMLElement)) return;
|
|
2519
|
+
startElement = row;
|
|
2520
|
+
startPosition = getPosition(event);
|
|
2521
|
+
dragStyling.set();
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
function onMouseMove(event) {
|
|
2525
|
+
if (startElement == null) return;
|
|
2526
|
+
const currentPosition = getPosition(event);
|
|
2527
|
+
if (currentPosition == null || startPosition == null) return;
|
|
2528
|
+
const element = getPlaceholder();
|
|
2529
|
+
if (element.parentElement == null) document.body.append(element);
|
|
2530
|
+
const { x: cX, y: cY } = currentPosition;
|
|
2531
|
+
const { x: sX, y: sY } = startPosition;
|
|
2532
|
+
const top = Math.min(cY, sY);
|
|
2533
|
+
const left = Math.min(cX, sX);
|
|
2534
|
+
const width = Math.abs(cX - sX);
|
|
2535
|
+
const height = Math.abs(cY - sY);
|
|
2536
|
+
element.style.inset = `${top}px ${window.innerWidth - left - width}px ${window.innerHeight - top - height}px ${left}px`;
|
|
2537
|
+
}
|
|
2538
|
+
function onMouseUp(event) {
|
|
2539
|
+
if (startElement == null) return;
|
|
2540
|
+
if (!event.shiftKey) {
|
|
2541
|
+
shifted = false;
|
|
2542
|
+
dragStyling.remove();
|
|
2543
|
+
}
|
|
2544
|
+
getPlaceholder().remove();
|
|
2545
|
+
const row = findAncestor(event.target, ".tabela__row--body");
|
|
2546
|
+
if (row instanceof HTMLElement) {
|
|
2547
|
+
endElement = row;
|
|
2548
|
+
const endTable = findAncestor(endElement, ".tabela");
|
|
2549
|
+
const startTable = findAncestor(startElement, ".tabela");
|
|
2550
|
+
if (startTable != null && startTable === endTable) mapped.get(startTable)?.range(startElement, endElement);
|
|
2551
|
+
}
|
|
2552
|
+
endElement = void 0;
|
|
2553
|
+
startElement = void 0;
|
|
2554
|
+
startPosition = void 0;
|
|
2555
|
+
}
|
|
2556
|
+
function onShift(event, value) {
|
|
2557
|
+
if (event.key === "Shift") shifted = value;
|
|
2558
|
+
}
|
|
2559
|
+
function onShiftDown(event) {
|
|
2560
|
+
onShift(event, true);
|
|
2561
|
+
}
|
|
2562
|
+
function onShiftUp(event) {
|
|
2563
|
+
onShift(event, false);
|
|
2564
|
+
}
|
|
2565
|
+
const mapped = /* @__PURE__ */ new WeakMap();
|
|
2566
|
+
let shifted = false;
|
|
2567
|
+
let endElement;
|
|
2568
|
+
let placeholder;
|
|
2569
|
+
let startPosition;
|
|
2570
|
+
let startElement;
|
|
2571
|
+
on(document, "keydown", onShiftDown);
|
|
2572
|
+
on(document, "keyup", onShiftUp);
|
|
2573
|
+
on(document, "mousedown", onMouseDown);
|
|
2574
|
+
on(document, "mousemove", onMouseMove);
|
|
2575
|
+
on(document, "mouseup", onMouseUp);
|
|
1837
2576
|
var SortManager = class {
|
|
1838
2577
|
handlers = Object.freeze({
|
|
1839
2578
|
add: (field, direction) => this.add(field, direction),
|
|
@@ -1843,8 +2582,8 @@ var SortManager = class {
|
|
|
1843
2582
|
set: (items) => this.set(items)
|
|
1844
2583
|
});
|
|
1845
2584
|
items = [];
|
|
1846
|
-
constructor(
|
|
1847
|
-
this.
|
|
2585
|
+
constructor(state) {
|
|
2586
|
+
this.state = state;
|
|
1848
2587
|
}
|
|
1849
2588
|
add(field, direction) {
|
|
1850
2589
|
if (this.items.findIndex((item) => item.key === field) > -1) return;
|
|
@@ -1869,7 +2608,8 @@ var SortManager = class {
|
|
|
1869
2608
|
}
|
|
1870
2609
|
destroy() {
|
|
1871
2610
|
this.handlers = void 0;
|
|
1872
|
-
this.items
|
|
2611
|
+
this.items = void 0;
|
|
2612
|
+
this.state = void 0;
|
|
1873
2613
|
}
|
|
1874
2614
|
flip(field) {
|
|
1875
2615
|
const item = this.items.find((item) => item.key === field);
|
|
@@ -1896,10 +2636,10 @@ var SortManager = class {
|
|
|
1896
2636
|
this.sort();
|
|
1897
2637
|
}
|
|
1898
2638
|
sort() {
|
|
1899
|
-
const { items,
|
|
1900
|
-
const { length } = managers.column.items;
|
|
2639
|
+
const { items, state } = this;
|
|
2640
|
+
const { length } = state.managers.column.items;
|
|
1901
2641
|
for (let index = 0; index < length; index += 1) {
|
|
1902
|
-
const column = managers.column.items[index];
|
|
2642
|
+
const column = state.managers.column.items[index];
|
|
1903
2643
|
const sorterIndex = items.findIndex((item) => item.key === column.options.field);
|
|
1904
2644
|
const sorterItem = items[sorterIndex];
|
|
1905
2645
|
setAttributes(column.elements.wrapper, {
|
|
@@ -1908,8 +2648,8 @@ var SortManager = class {
|
|
|
1908
2648
|
});
|
|
1909
2649
|
setAttribute(column.elements.sorter, "data-sort-position", sorterIndex > -1 && items.length > 1 ? sorterIndex + 1 : void 0);
|
|
1910
2650
|
}
|
|
1911
|
-
managers.data.values.keys.active = items.length === 0 ? void 0 : sort(managers.data.values.keys.active?.map((key) => managers.data.values.objects.mapped.get(key)) ?? managers.data.values.objects.array, items).map((row) => row[
|
|
1912
|
-
managers.
|
|
2651
|
+
state.managers.data.values.keys.active = items.length === 0 ? void 0 : sort(state.managers.data.values.keys.active?.map((key) => state.managers.data.values.objects.mapped.get(key)) ?? state.managers.data.values.objects.array, items).map((row) => row[state.key]);
|
|
2652
|
+
state.managers.render.update(true, true);
|
|
1913
2653
|
}
|
|
1914
2654
|
toggle(event, field, direction) {
|
|
1915
2655
|
switch (direction) {
|
|
@@ -1925,104 +2665,6 @@ var SortManager = class {
|
|
|
1925
2665
|
}
|
|
1926
2666
|
}
|
|
1927
2667
|
};
|
|
1928
|
-
function getRange(down) {
|
|
1929
|
-
const { components, managers } = this;
|
|
1930
|
-
const { clientHeight, scrollTop } = components.body.elements.group;
|
|
1931
|
-
const first = Math.floor(scrollTop / managers.row.height);
|
|
1932
|
-
const last = Math.min(managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length - 1, Math.ceil((scrollTop + clientHeight) / managers.row.height) - 1);
|
|
1933
|
-
const before = Math.ceil(clientHeight / managers.row.height) * (down ? 1 : 2);
|
|
1934
|
-
const after = Math.ceil(clientHeight / managers.row.height) * (down ? 2 : 1);
|
|
1935
|
-
const start = Math.max(0, first - before);
|
|
1936
|
-
return {
|
|
1937
|
-
end: Math.min(managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length - 1, last + after),
|
|
1938
|
-
start
|
|
1939
|
-
};
|
|
1940
|
-
}
|
|
1941
|
-
function onScroll() {
|
|
1942
|
-
if (!this.state.active) {
|
|
1943
|
-
requestAnimationFrame(() => {
|
|
1944
|
-
const top = this.components.body.elements.group.scrollTop;
|
|
1945
|
-
this.update(top > this.state.top);
|
|
1946
|
-
this.state.active = false;
|
|
1947
|
-
this.state.top = top;
|
|
1948
|
-
});
|
|
1949
|
-
this.state.active = true;
|
|
1950
|
-
}
|
|
1951
|
-
}
|
|
1952
|
-
var VirtualizationManager = class {
|
|
1953
|
-
fragment;
|
|
1954
|
-
listener;
|
|
1955
|
-
pool = {
|
|
1956
|
-
cells: {},
|
|
1957
|
-
rows: []
|
|
1958
|
-
};
|
|
1959
|
-
state = {
|
|
1960
|
-
active: false,
|
|
1961
|
-
top: 0
|
|
1962
|
-
};
|
|
1963
|
-
visible = /* @__PURE__ */ new Map();
|
|
1964
|
-
constructor(managers, components) {
|
|
1965
|
-
this.managers = managers;
|
|
1966
|
-
this.components = components;
|
|
1967
|
-
this.listener = on(components.body.elements.group, "scroll", onScroll.bind(this));
|
|
1968
|
-
}
|
|
1969
|
-
destroy() {
|
|
1970
|
-
this.listener();
|
|
1971
|
-
for (const [index, row] of this.visible) {
|
|
1972
|
-
removeRow(this.pool, row);
|
|
1973
|
-
this.visible.delete(index);
|
|
1974
|
-
}
|
|
1975
|
-
this.pool.cells = {};
|
|
1976
|
-
this.pool.rows = [];
|
|
1977
|
-
this.listener = void 0;
|
|
1978
|
-
this.visible = void 0;
|
|
1979
|
-
}
|
|
1980
|
-
removeCells(fields) {
|
|
1981
|
-
const { length } = fields;
|
|
1982
|
-
for (let index = 0; index < length; index += 1) delete this.pool.cells[fields[index]];
|
|
1983
|
-
for (const [, row] of this.visible) for (let index = 0; index < length; index += 1) {
|
|
1984
|
-
row.cells[fields[index]].innerHTML = "";
|
|
1985
|
-
row.cells[fields[index]].remove();
|
|
1986
|
-
delete row.cells[fields[index]];
|
|
1987
|
-
}
|
|
1988
|
-
}
|
|
1989
|
-
getFragment() {
|
|
1990
|
-
this.fragment ??= document.createDocumentFragment();
|
|
1991
|
-
this.fragment.replaceChildren();
|
|
1992
|
-
return this.fragment;
|
|
1993
|
-
}
|
|
1994
|
-
update(down, rerender) {
|
|
1995
|
-
const { components, managers, pool, visible } = this;
|
|
1996
|
-
components.body.elements.faker.style.height = `${managers.data.size * managers.row.height}px`;
|
|
1997
|
-
const indices = /* @__PURE__ */ new Set();
|
|
1998
|
-
const range = getRange.call(this, down);
|
|
1999
|
-
for (let index = range.start; index <= range.end; index += 1) indices.add(index);
|
|
2000
|
-
let remove = rerender ?? false;
|
|
2001
|
-
for (const [index, row] of visible) {
|
|
2002
|
-
if (!managers.row.has(row.key) || !indices.has(index)) remove = true;
|
|
2003
|
-
if (remove) {
|
|
2004
|
-
visible.delete(index);
|
|
2005
|
-
removeRow(pool, row);
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2008
|
-
const fragment = this.getFragment();
|
|
2009
|
-
const keys = managers.data.values.keys.active ?? managers.data.values.keys.original;
|
|
2010
|
-
let count = 0;
|
|
2011
|
-
for (let index = range.start; index <= range.end; index += 1) {
|
|
2012
|
-
if (visible.has(index)) continue;
|
|
2013
|
-
const row = managers.row.get(keys[index]);
|
|
2014
|
-
if (row == null) continue;
|
|
2015
|
-
count += 1;
|
|
2016
|
-
renderRow(managers, row);
|
|
2017
|
-
visible.set(index, row);
|
|
2018
|
-
if (row.element != null) {
|
|
2019
|
-
row.element.style.transform = `translateY(${index * managers.row.height}px)`;
|
|
2020
|
-
fragment.append(row.element);
|
|
2021
|
-
}
|
|
2022
|
-
}
|
|
2023
|
-
if (count > 0) components.body.elements.group[down ? "append" : "prepend"](fragment);
|
|
2024
|
-
}
|
|
2025
|
-
};
|
|
2026
2668
|
var Tabela = class {
|
|
2027
2669
|
#components = {
|
|
2028
2670
|
header: void 0,
|
|
@@ -2030,18 +2672,22 @@ var Tabela = class {
|
|
|
2030
2672
|
footer: void 0
|
|
2031
2673
|
};
|
|
2032
2674
|
#element;
|
|
2675
|
+
#id = getId();
|
|
2033
2676
|
#key;
|
|
2034
2677
|
#managers = {
|
|
2035
2678
|
column: void 0,
|
|
2036
2679
|
data: void 0,
|
|
2037
2680
|
event: void 0,
|
|
2038
2681
|
filter: void 0,
|
|
2682
|
+
navigation: void 0,
|
|
2683
|
+
render: void 0,
|
|
2039
2684
|
row: void 0,
|
|
2040
|
-
|
|
2041
|
-
|
|
2685
|
+
selection: void 0,
|
|
2686
|
+
sort: void 0
|
|
2042
2687
|
};
|
|
2043
2688
|
data;
|
|
2044
2689
|
filter;
|
|
2690
|
+
selection;
|
|
2045
2691
|
sort;
|
|
2046
2692
|
get key() {
|
|
2047
2693
|
return this.#key;
|
|
@@ -2056,17 +2702,28 @@ var Tabela = class {
|
|
|
2056
2702
|
this.#components.header = new HeaderComponent();
|
|
2057
2703
|
this.#components.body = new BodyComponent();
|
|
2058
2704
|
this.#components.footer = new FooterComponent();
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2705
|
+
const state = {
|
|
2706
|
+
element,
|
|
2707
|
+
options,
|
|
2708
|
+
components: this.#components,
|
|
2709
|
+
id: this.#id,
|
|
2710
|
+
key: this.#key,
|
|
2711
|
+
managers: this.#managers
|
|
2712
|
+
};
|
|
2713
|
+
this.#managers.column = new ColumnManager(state);
|
|
2714
|
+
this.#managers.data = new DataManager(state);
|
|
2715
|
+
this.#managers.event = new EventManager(state);
|
|
2716
|
+
this.#managers.filter = new FilterManager(state);
|
|
2717
|
+
this.#managers.navigation = new NavigationManager(state);
|
|
2718
|
+
this.#managers.render = new RenderManager(state);
|
|
2719
|
+
this.#managers.row = new RowManager(state);
|
|
2720
|
+
this.#managers.selection = new SelectionManager(state);
|
|
2721
|
+
this.#managers.sort = new SortManager(state);
|
|
2066
2722
|
element.append(this.#components.header.elements.group, this.#components.body.elements.group, this.#components.footer.elements.group);
|
|
2067
2723
|
this.#managers.data.set(options.data);
|
|
2068
2724
|
this.data = this.#managers.data.handlers;
|
|
2069
2725
|
this.filter = this.#managers.filter.handlers;
|
|
2726
|
+
this.selection = this.#managers.selection.handlers;
|
|
2070
2727
|
this.sort = this.#managers.sort.handlers;
|
|
2071
2728
|
}
|
|
2072
2729
|
destroy() {
|
|
@@ -2080,9 +2737,10 @@ var Tabela = class {
|
|
|
2080
2737
|
managers.data.destroy();
|
|
2081
2738
|
managers.event.destroy();
|
|
2082
2739
|
managers.filter.destroy();
|
|
2740
|
+
managers.render.destroy();
|
|
2083
2741
|
managers.row.destroy();
|
|
2742
|
+
managers.selection.destroy();
|
|
2084
2743
|
managers.sort.destroy();
|
|
2085
|
-
managers.virtualization.destroy();
|
|
2086
2744
|
element.innerHTML = "";
|
|
2087
2745
|
element.role = "";
|
|
2088
2746
|
element.classList.remove("tabela");
|
|
@@ -2091,6 +2749,11 @@ var Tabela = class {
|
|
|
2091
2749
|
this.#element = void 0;
|
|
2092
2750
|
}
|
|
2093
2751
|
};
|
|
2752
|
+
function getId() {
|
|
2753
|
+
id += 1;
|
|
2754
|
+
return id;
|
|
2755
|
+
}
|
|
2756
|
+
let id = 0;
|
|
2094
2757
|
function tabela(element, options) {
|
|
2095
2758
|
return new Tabela(element, options);
|
|
2096
2759
|
}
|