@schukai/monster 3.98.3 → 3.99.1
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 +22 -0
- package/package.json +1 -1
- package/source/components/datatable/datatable.mjs +1159 -1139
- package/source/components/form/action-button.mjs +2 -1
- package/source/components/form/api-button.mjs +4 -4
- package/source/components/form/button-bar.mjs +2 -3
- package/source/components/form/button.mjs +1 -0
- package/source/components/form/context-error.mjs +1 -0
- package/source/components/form/field-set.mjs +1 -0
- package/source/components/form/popper-button.mjs +274 -273
- package/source/components/form/reload.mjs +1 -0
- package/source/components/form/toggle-switch.mjs +2 -2
- package/source/components/notify/monitor-attribute-errors.mjs +5 -1
- package/source/dom/customelement.mjs +944 -945
- package/source/dom/error.mjs +106 -0
- package/source/types/version.mjs +1 -1
- package/test/cases/dom/customcontrol.mjs +1 -1
- package/test/cases/dom/customelement.mjs +3 -3
- package/test/cases/monster.mjs +1 -1
- package/test/web/test.html +2 -2
- package/test/web/tests.js +87 -24
@@ -12,26 +12,27 @@
|
|
12
12
|
* SPDX-License-Identifier: AGPL-3.0
|
13
13
|
*/
|
14
14
|
|
15
|
-
import {
|
16
|
-
import {
|
15
|
+
import {instanceSymbol} from "../../constants.mjs";
|
16
|
+
import {addAttributeToken} from "../../dom/attributes.mjs";
|
17
17
|
import {
|
18
|
-
|
19
|
-
|
18
|
+
ATTRIBUTE_ERRORMESSAGE,
|
19
|
+
ATTRIBUTE_ROLE,
|
20
20
|
} from "../../dom/constants.mjs";
|
21
21
|
import {
|
22
|
-
|
23
|
-
|
22
|
+
assembleMethodSymbol,
|
23
|
+
registerCustomElement,
|
24
24
|
} from "../../dom/customelement.mjs";
|
25
|
-
import {
|
26
|
-
import {
|
27
|
-
import {
|
28
|
-
import {
|
29
|
-
import {
|
30
|
-
import {
|
31
|
-
import {
|
25
|
+
import {getDocument} from "../../dom/util.mjs";
|
26
|
+
import {isFunction} from "../../types/is.mjs";
|
27
|
+
import {DeadMansSwitch} from "../../util/deadmansswitch.mjs";
|
28
|
+
import {Popper} from "./popper.mjs";
|
29
|
+
import {STYLE_DISPLAY_MODE_BLOCK} from "./constants.mjs";
|
30
|
+
import {PopperButtonStyleSheet} from "./stylesheet/popper-button.mjs";
|
31
|
+
import {positionPopper} from "./util/floating-ui.mjs";
|
32
32
|
import "./button.mjs";
|
33
|
+
import {addErrorAttribute} from "../../dom/error.mjs";
|
33
34
|
|
34
|
-
export {
|
35
|
+
export {PopperButton};
|
35
36
|
|
36
37
|
/**
|
37
38
|
* @private
|
@@ -140,205 +141,205 @@ const arrowElementSymbol = Symbol("arrowElement");
|
|
140
141
|
* @fires monster-changed
|
141
142
|
*/
|
142
143
|
class PopperButton extends Popper {
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
144
|
+
/**
|
145
|
+
* This method is called by the `instanceof` operator.
|
146
|
+
* @return {symbol}
|
147
|
+
* @since 2.1.0
|
148
|
+
*/
|
149
|
+
static get [instanceSymbol]() {
|
150
|
+
return Symbol.for(
|
151
|
+
"@schukai/monster/components/form/popper-button@@instance",
|
152
|
+
);
|
153
|
+
}
|
154
|
+
|
155
|
+
/**
|
156
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
157
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
158
|
+
*
|
159
|
+
* The individual configuration values can be found in the table.
|
160
|
+
*
|
161
|
+
* @property {Object} templates - The templates for the control.
|
162
|
+
* @property {string} templates.main - The main template.
|
163
|
+
* @property {object} labels - The labels for the control.
|
164
|
+
* @property {string} labels.button - The label for the button.
|
165
|
+
* @property {string} content - The content of the popper.
|
166
|
+
* @property {object} popper - The popper options.
|
167
|
+
* @extends {Button.defaults}
|
168
|
+
*/
|
169
|
+
get defaults() {
|
170
|
+
return Object.assign({}, super.defaults, {
|
171
|
+
templates: {
|
172
|
+
main: getTemplate(),
|
173
|
+
},
|
174
|
+
actions: {
|
175
|
+
click: (e) => {
|
176
|
+
this.toggleDialog();
|
177
|
+
},
|
178
|
+
},
|
179
|
+
classes: {
|
180
|
+
button: "monster-button",
|
181
|
+
},
|
182
|
+
labels: {
|
183
|
+
button: '<slot name="button"></slot>',
|
184
|
+
},
|
185
|
+
mode: "click",
|
186
|
+
value: null,
|
187
|
+
});
|
188
|
+
}
|
189
|
+
|
190
|
+
/**
|
191
|
+
*
|
192
|
+
* @return {Monster.Components.Form.PopperButton}
|
193
|
+
*/
|
194
|
+
[assembleMethodSymbol]() {
|
195
|
+
super[assembleMethodSymbol]();
|
196
|
+
initControlReferences.call(this);
|
197
|
+
initEventHandler.call(this);
|
198
|
+
|
199
|
+
return this;
|
200
|
+
}
|
201
|
+
|
202
|
+
/**
|
203
|
+
* @return {string}
|
204
|
+
*/
|
205
|
+
static getTag() {
|
206
|
+
return "monster-popper-button";
|
207
|
+
}
|
208
|
+
|
209
|
+
/**
|
210
|
+
* @return {CSSStyleSheet[]}
|
211
|
+
*/
|
212
|
+
static getCSSStyleSheet() {
|
213
|
+
const styles = super.getCSSStyleSheet();
|
214
|
+
styles.push(PopperButtonStyleSheet);
|
215
|
+
return styles;
|
216
|
+
}
|
217
|
+
|
218
|
+
/**
|
219
|
+
* @return {void}
|
220
|
+
*/
|
221
|
+
connectedCallback() {
|
222
|
+
super.connectedCallback();
|
223
|
+
|
224
|
+
const document = getDocument();
|
225
|
+
|
226
|
+
for (const [, type] of Object.entries(["click", "touch"])) {
|
227
|
+
// close on outside ui-events
|
228
|
+
document.addEventListener(type, this[closeEventHandler]);
|
229
|
+
}
|
230
|
+
|
231
|
+
updatePopper.call(this);
|
232
|
+
attachResizeObserver.call(this);
|
233
|
+
}
|
234
|
+
|
235
|
+
/**
|
236
|
+
* @return {void}
|
237
|
+
*/
|
238
|
+
disconnectedCallback() {
|
239
|
+
super.disconnectedCallback();
|
240
|
+
|
241
|
+
// close on outside ui-events
|
242
|
+
for (const [, type] of Object.entries(["click", "touch"])) {
|
243
|
+
document.removeEventListener(type, this[closeEventHandler]);
|
244
|
+
}
|
245
|
+
|
246
|
+
disconnectResizeObserver.call(this);
|
247
|
+
}
|
248
|
+
|
249
|
+
/**
|
250
|
+
* The Button.click() method simulates a click on the internal button element.
|
251
|
+
*
|
252
|
+
* @since 3.27.0
|
253
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click}
|
254
|
+
*/
|
255
|
+
click() {
|
256
|
+
if (this.getOption("disabled") === true) {
|
257
|
+
return;
|
258
|
+
}
|
259
|
+
|
260
|
+
if (
|
261
|
+
this[buttonElementSymbol] &&
|
262
|
+
isFunction(this[buttonElementSymbol].click)
|
263
|
+
) {
|
264
|
+
this[buttonElementSymbol].click();
|
265
|
+
}
|
266
|
+
}
|
267
|
+
|
268
|
+
/**
|
269
|
+
* The Button.focus() method sets focus on the internal button element.
|
270
|
+
*
|
271
|
+
* @since 3.27.0
|
272
|
+
* @param {Object} options
|
273
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus}
|
274
|
+
*/
|
275
|
+
focus(options) {
|
276
|
+
if (this.getOption("disabled") === true) {
|
277
|
+
return;
|
278
|
+
}
|
279
|
+
|
280
|
+
if (
|
281
|
+
this[buttonElementSymbol] &&
|
282
|
+
isFunction(this[buttonElementSymbol].focus)
|
283
|
+
) {
|
284
|
+
this[buttonElementSymbol].focus(options);
|
285
|
+
}
|
286
|
+
}
|
287
|
+
|
288
|
+
/**
|
289
|
+
* The Button.blur() method removes focus from the internal button element.
|
290
|
+
*/
|
291
|
+
blur() {
|
292
|
+
if (
|
293
|
+
this[buttonElementSymbol] &&
|
294
|
+
isFunction(this[buttonElementSymbol].blur)
|
295
|
+
) {
|
296
|
+
this[buttonElementSymbol].blur();
|
297
|
+
}
|
298
|
+
}
|
299
|
+
|
300
|
+
/**
|
301
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals}
|
302
|
+
* @return {boolean}
|
303
|
+
*/
|
304
|
+
static get formAssociated() {
|
305
|
+
return true;
|
306
|
+
}
|
307
|
+
|
308
|
+
/**
|
309
|
+
* The current selection of the Select
|
310
|
+
*
|
311
|
+
* ```
|
312
|
+
* e = document.querySelector('monster-select');
|
313
|
+
* console.log(e.value)
|
314
|
+
* // ↦ 1
|
315
|
+
* // ↦ ['1','2']
|
316
|
+
* ```
|
317
|
+
*
|
318
|
+
* @property {string|array}
|
319
|
+
*/
|
320
|
+
get value() {
|
321
|
+
return this.getOption("value");
|
322
|
+
}
|
323
|
+
|
324
|
+
/**
|
325
|
+
* Set selection
|
326
|
+
*
|
327
|
+
* ```
|
328
|
+
* e = document.querySelector('monster-select');
|
329
|
+
* e.value=1
|
330
|
+
* ```
|
331
|
+
*
|
332
|
+
* @property {string|array} value
|
333
|
+
* @throws {Error} unsupported type
|
334
|
+
*/
|
335
|
+
set value(value) {
|
336
|
+
this.setOption("value", value);
|
337
|
+
try {
|
338
|
+
this?.setFormValue(this.value);
|
339
|
+
} catch (e) {
|
340
|
+
addErrorAttribute(this, e);
|
341
|
+
}
|
342
|
+
}
|
342
343
|
}
|
343
344
|
|
344
345
|
/**
|
@@ -346,67 +347,67 @@ class PopperButton extends Popper {
|
|
346
347
|
* @return {initEventHandler}
|
347
348
|
*/
|
348
349
|
function initEventHandler() {
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
350
|
+
this[closeEventHandler] = (event) => {
|
351
|
+
const path = event.composedPath();
|
352
|
+
|
353
|
+
for (const [, element] of Object.entries(path)) {
|
354
|
+
if (element === this) {
|
355
|
+
return;
|
356
|
+
}
|
357
|
+
}
|
358
|
+
this.hideDialog();
|
359
|
+
};
|
360
|
+
|
361
|
+
return this;
|
361
362
|
}
|
362
363
|
|
363
364
|
/**
|
364
365
|
* @private
|
365
366
|
*/
|
366
367
|
function attachResizeObserver() {
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
368
|
+
// against flickering
|
369
|
+
this[resizeObserverSymbol] = new ResizeObserver(() => {
|
370
|
+
if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
|
371
|
+
try {
|
372
|
+
this[timerCallbackSymbol].touch();
|
373
|
+
return;
|
374
|
+
} catch (e) {
|
375
|
+
delete this[timerCallbackSymbol];
|
376
|
+
}
|
377
|
+
}
|
378
|
+
|
379
|
+
this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
|
380
|
+
updatePopper.call(this);
|
381
|
+
});
|
382
|
+
});
|
383
|
+
|
384
|
+
this[resizeObserverSymbol].observe(this.parentElement);
|
384
385
|
}
|
385
386
|
|
386
387
|
function disconnectResizeObserver() {
|
387
|
-
|
388
|
-
|
389
|
-
|
388
|
+
if (this[resizeObserverSymbol] instanceof ResizeObserver) {
|
389
|
+
this[resizeObserverSymbol].disconnect();
|
390
|
+
}
|
390
391
|
}
|
391
392
|
|
392
393
|
/**
|
393
394
|
* @private
|
394
395
|
*/
|
395
396
|
function updatePopper() {
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
397
|
+
if (this[popperElementSymbol].style.display !== STYLE_DISPLAY_MODE_BLOCK) {
|
398
|
+
return;
|
399
|
+
}
|
400
|
+
|
401
|
+
if (this.getOption("disabled", false) === true) {
|
402
|
+
return;
|
403
|
+
}
|
404
|
+
|
405
|
+
positionPopper.call(
|
406
|
+
this,
|
407
|
+
this[controlElementSymbol],
|
408
|
+
this[popperElementSymbol],
|
409
|
+
this.getOption("popper", {}),
|
410
|
+
);
|
410
411
|
}
|
411
412
|
|
412
413
|
/**
|
@@ -414,21 +415,21 @@ function updatePopper() {
|
|
414
415
|
* @return {Select}
|
415
416
|
*/
|
416
417
|
function initControlReferences() {
|
417
|
-
|
418
|
-
|
419
|
-
|
418
|
+
this[controlElementSymbol] = this.shadowRoot.querySelector(
|
419
|
+
`[${ATTRIBUTE_ROLE}=control]`,
|
420
|
+
);
|
420
421
|
|
421
|
-
|
422
|
-
|
423
|
-
|
422
|
+
this[buttonElementSymbol] = this.shadowRoot.querySelector(
|
423
|
+
`[${ATTRIBUTE_ROLE}=button]`,
|
424
|
+
);
|
424
425
|
|
425
|
-
|
426
|
-
|
427
|
-
|
426
|
+
this[popperElementSymbol] = this.shadowRoot.querySelector(
|
427
|
+
`[${ATTRIBUTE_ROLE}=popper]`,
|
428
|
+
);
|
428
429
|
|
429
|
-
|
430
|
-
|
431
|
-
|
430
|
+
this[arrowElementSymbol] = this.shadowRoot.querySelector(
|
431
|
+
`[${ATTRIBUTE_ROLE}=arrow]`,
|
432
|
+
);
|
432
433
|
}
|
433
434
|
|
434
435
|
/**
|
@@ -436,8 +437,8 @@ function initControlReferences() {
|
|
436
437
|
* @return {string}
|
437
438
|
*/
|
438
439
|
function getTemplate() {
|
439
|
-
|
440
|
-
|
440
|
+
// language=HTML
|
441
|
+
return `
|
441
442
|
<div data-monster-role="control" part="control">
|
442
443
|
<button data-monster-attributes="disabled path:disabled | if:true, class path:classes.button"
|
443
444
|
data-monster-role="button"
|
@@ -28,6 +28,7 @@ import {
|
|
28
28
|
import { isString } from "../../types/is.mjs";
|
29
29
|
import { ATTRIBUTE_FORM_RELOAD, ATTRIBUTE_FORM_URL } from "./constants.mjs";
|
30
30
|
import { loadAndAssignContent } from "./util/fetch.mjs";
|
31
|
+
import {addErrorAttribute} from "../../dom/error.mjs";
|
31
32
|
|
32
33
|
export { Reload };
|
33
34
|
|
@@ -31,6 +31,7 @@ import {
|
|
31
31
|
} from "../../dom/constants.mjs";
|
32
32
|
import { getWindow } from "../../dom/util.mjs";
|
33
33
|
import { fireEvent } from "../../dom/events.mjs";
|
34
|
+
import {addErrorAttribute} from "../../dom/error.mjs";
|
34
35
|
|
35
36
|
export { ToggleSwitch };
|
36
37
|
|
@@ -293,9 +294,8 @@ class ToggleSwitch extends CustomControl {
|
|
293
294
|
return;
|
294
295
|
}
|
295
296
|
|
296
|
-
|
297
|
+
addErrorAttribute(
|
297
298
|
this,
|
298
|
-
ATTRIBUTE_ERRORMESSAGE,
|
299
299
|
'The value "' +
|
300
300
|
value +
|
301
301
|
'" must be "' +
|
@@ -192,7 +192,11 @@ function setupMutationObserver(root) {
|
|
192
192
|
|
193
193
|
fktOpen("MonitorAttributeErrors " + node.tagName);
|
194
194
|
fktLog(node);
|
195
|
-
|
195
|
+
|
196
|
+
const errors = node.getAttribute("data-monster-error").split("::");
|
197
|
+
errors.forEach((error) => {
|
198
|
+
fktLog(error);
|
199
|
+
});
|
196
200
|
fktClose();
|
197
201
|
|
198
202
|
if (self.getOption("features.notifyUser")) {
|