@cntwg/html-helper 0.0.15 → 0.0.17
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/lib/html-ctrls-list.js +177 -100
- package/package.json +1 -1
package/lib/html-ctrls-list.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
// [v0.1.
|
|
1
|
+
// [v0.1.053-20221022]
|
|
2
2
|
|
|
3
3
|
// === module init block ===
|
|
4
4
|
|
|
5
5
|
const {
|
|
6
|
-
readAsBool,
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
//readAsBool,
|
|
7
|
+
readAsNumber,
|
|
8
|
+
//valueToIndex,
|
|
9
|
+
//isArray, isObject,
|
|
9
10
|
isPlainObject,
|
|
10
11
|
TItemsListEx,
|
|
11
12
|
} = require('@ygracs/bsfoc-lib-js');
|
|
@@ -28,6 +29,10 @@ const {
|
|
|
28
29
|
CSS_CLASS_ACTIVE,
|
|
29
30
|
} = CSS_CLASS_STRING;
|
|
30
31
|
|
|
32
|
+
const ILC_SMODE_DEF = 0;
|
|
33
|
+
const ILC_SMODE_SHFT = 1;
|
|
34
|
+
const ILC_SMODE_CTRL = 2;
|
|
35
|
+
|
|
31
36
|
// === module extra block (helper functions) ===
|
|
32
37
|
|
|
33
38
|
function readAsAttrValue(value){
|
|
@@ -227,17 +232,21 @@ class THtmlItemsListContainer {
|
|
|
227
232
|
return isSUCCEED ? index : -1;
|
|
228
233
|
}
|
|
229
234
|
|
|
230
|
-
delItem(index, opt){
|
|
231
|
-
const
|
|
232
|
-
const item =
|
|
233
|
-
const isSUCCEED =
|
|
235
|
+
delItem(index, opt, optEx){
|
|
236
|
+
const _items = this.#_items;
|
|
237
|
+
const item = _items.delItemEx(index, opt);
|
|
238
|
+
const isSUCCEED = item !== undefined;
|
|
234
239
|
if (isSUCCEED) {
|
|
235
|
-
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
240
|
+
if (this.#_host && isHTMLElement(item)) item.remove();
|
|
241
|
+
const doProcEx = typeof optEx === 'boolean' ? optEx : true;
|
|
242
|
+
if (doProcEx) {
|
|
243
|
+
const index = _items.curIndex;
|
|
244
|
+
if (index === -1) {
|
|
245
|
+
this.rstCurIndex();
|
|
246
|
+
} else {
|
|
247
|
+
this.setCurIndex(index);
|
|
248
|
+
};
|
|
249
|
+
};
|
|
241
250
|
};
|
|
242
251
|
return isSUCCEED;
|
|
243
252
|
}
|
|
@@ -313,6 +322,9 @@ class THtmlItemsListController extends THtmlItemsListContainer {
|
|
|
313
322
|
isStubItemShown: false,
|
|
314
323
|
isHostEnabled: isHostEnabled,
|
|
315
324
|
catchEventOnHost: false,
|
|
325
|
+
execDelItem: false,
|
|
326
|
+
execDelItemDI: -1,
|
|
327
|
+
execDelItemCI: -1,
|
|
316
328
|
}
|
|
317
329
|
// bind ref to host
|
|
318
330
|
this.#_host = _host;
|
|
@@ -334,23 +346,31 @@ class THtmlItemsListController extends THtmlItemsListContainer {
|
|
|
334
346
|
|
|
335
347
|
#_on_will_select_item = (e) => {
|
|
336
348
|
//console.log('THtmlItemsListController._on_will_select_item() ==> was called...');
|
|
337
|
-
//console.log('CHECK: e => ditail:['+e.detail+']');
|
|
338
|
-
//console.log('CHECK: e => phase:['+e.eventPhase+']');
|
|
339
349
|
//e.preventDefault(); /* need to reconsider reason for use */
|
|
350
|
+
const {
|
|
351
|
+
eventPhase,
|
|
352
|
+
target,
|
|
353
|
+
currentTarget,
|
|
354
|
+
ctrlKey,
|
|
355
|
+
shiftKey,
|
|
356
|
+
} = e;
|
|
357
|
+
//console.log('CHECK: e => ditail:['+e.detail+']');
|
|
358
|
+
//console.log('CHECK: e => phase:['+eventPhase+']');
|
|
359
|
+
const onClickNum = readAsNumber(e.detail, 0);
|
|
340
360
|
const _status = this.#_status;
|
|
341
361
|
const { isSelectionLocked, catchEventOnHost } = _status;
|
|
342
|
-
const on_click_num = readAsNumber(e.detail, 0);
|
|
343
362
|
let curItem = null;
|
|
344
|
-
switch (
|
|
345
|
-
//*case 1:
|
|
363
|
+
switch (eventPhase) {
|
|
346
364
|
//* // NOTE: currently on eventPhase = 2 and 3
|
|
347
|
-
case
|
|
365
|
+
//*case 1:
|
|
348
366
|
/**/// capturing stage
|
|
349
|
-
|
|
367
|
+
case 2:
|
|
368
|
+
/**/// target stage
|
|
369
|
+
if (target !== this.#_host) curItem = target;
|
|
350
370
|
break;
|
|
351
371
|
case 3:
|
|
352
372
|
/**/// bubblig stage
|
|
353
|
-
curItem = catchEventOnHost ?
|
|
373
|
+
curItem = catchEventOnHost ? target : currentTarget;
|
|
354
374
|
break;
|
|
355
375
|
default:
|
|
356
376
|
break;
|
|
@@ -358,61 +378,15 @@ class THtmlItemsListController extends THtmlItemsListContainer {
|
|
|
358
378
|
if (
|
|
359
379
|
!isSelectionLocked
|
|
360
380
|
&& curItem instanceof HTMLElement
|
|
361
|
-
&& (
|
|
381
|
+
&& (onClickNum === 0 || onClickNum === 1)
|
|
362
382
|
&& !curItem.classList.contains(CSS_CLASS_DISABLED)
|
|
363
383
|
) {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
//console.log('THtmlItemsListController._on_will_select_item() ==> current:['+c_index+']');
|
|
371
|
-
//console.log('THtmlItemsListController._on_will_select_item() ==> next:['+n_index+']');
|
|
372
|
-
let act_in_mode = 0;
|
|
373
|
-
let act_unsel_grp = false;
|
|
374
|
-
if (this.#_options.allowGroupSelection) {
|
|
375
|
-
if (c_index !== -1) {
|
|
376
|
-
if (key_ctrl) {
|
|
377
|
-
act_in_mode = 2;
|
|
378
|
-
} else if (key_shft) {
|
|
379
|
-
act_in_mode = 1;
|
|
380
|
-
} else if (this.#_selects.size > 0) {
|
|
381
|
-
//console.log('THtmlItemsListController._on_will_select_item() ==> _selects.size:['+this.#_selects.size+']');
|
|
382
|
-
act_unsel_grp = true;
|
|
383
|
-
};
|
|
384
|
-
};
|
|
385
|
-
};
|
|
386
|
-
//console.log('THtmlItemsListController._on_will_select_item() ==> mode:['+act_in_mode+']');
|
|
387
|
-
//console.log('THtmlItemsListController._on_will_select_item() ==> act_unsel_grp:['+act_unsel_grp+']');
|
|
388
|
-
if (act_unsel_grp) {
|
|
389
|
-
for (let item of this.#_selects) {
|
|
390
|
-
c_index = this.srchIndex(item);
|
|
391
|
-
if (c_index !== -1) this.unselectItem(c_index);
|
|
392
|
-
};
|
|
393
|
-
c_index = -1;
|
|
394
|
-
};
|
|
395
|
-
if (act_in_mode === 1) {
|
|
396
|
-
if (c_index > n_index) [ c_index, n_index ] = [ n_index, c_index ];
|
|
397
|
-
let t_index = 0;
|
|
398
|
-
for (let item of this.#_selects) {
|
|
399
|
-
t_index = this.srchIndex(item);
|
|
400
|
-
if (t_index !== -1) this.unselectItem(t_index);
|
|
401
|
-
};
|
|
402
|
-
this.#_selects.clear();
|
|
403
|
-
for (let i = c_index; i < n_index + 1; i++) {
|
|
404
|
-
this.selectItem(i, false);
|
|
405
|
-
};
|
|
406
|
-
} else if (act_in_mode === 2) {
|
|
407
|
-
if (this.isSelectedItem(n_index)) {
|
|
408
|
-
this.unselectItem(n_index);
|
|
409
|
-
} else {
|
|
410
|
-
this.selectItem(n_index, false);
|
|
411
|
-
};
|
|
412
|
-
} else if (c_index !== n_index) {
|
|
413
|
-
if (c_index !== -1) this.unselectItem(c_index);
|
|
414
|
-
this.selectItem(n_index, true);
|
|
415
|
-
};
|
|
384
|
+
//console.log('CHECK: e => tag:['+curItem.tagName+']');
|
|
385
|
+
this.#_selectItemEx(curItem, {
|
|
386
|
+
ctrlKey: ctrlKey,
|
|
387
|
+
shiftKey: shiftKey,
|
|
388
|
+
forceCI: true,
|
|
389
|
+
});
|
|
416
390
|
};
|
|
417
391
|
};
|
|
418
392
|
|
|
@@ -463,19 +437,39 @@ class THtmlItemsListController extends THtmlItemsListContainer {
|
|
|
463
437
|
this.#_status.isSelectionLocked = false;
|
|
464
438
|
}
|
|
465
439
|
|
|
466
|
-
|
|
440
|
+
#_setCurIndex(index){
|
|
467
441
|
const isSUCCEED = super.setCurIndex(index);
|
|
468
442
|
if (isSUCCEED) this.#_triggerEvent('current-item-chosen', {
|
|
469
443
|
index: Number(index),
|
|
470
444
|
item: null,
|
|
471
445
|
});
|
|
472
446
|
return isSUCCEED;
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
setCurIndex(index){
|
|
450
|
+
return this.selectItem(index, true);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
rstCurIndex(){
|
|
454
|
+
const {
|
|
455
|
+
execDelItem,
|
|
456
|
+
execDelItemDI,
|
|
457
|
+
execDelItemCI,
|
|
458
|
+
} = this.#_status;
|
|
459
|
+
if (execDelItem) {
|
|
460
|
+
let index = execDelItemCI;
|
|
461
|
+
if (execDelItemCI !== -1) index--;
|
|
462
|
+
if (index !== -1 && execDelItemDI !== execDelItemCI) {
|
|
463
|
+
this.unselectItem(index);
|
|
464
|
+
};
|
|
465
|
+
};
|
|
466
|
+
super.rstCurIndex();
|
|
473
467
|
}
|
|
474
468
|
|
|
475
469
|
addItem(item, opt){
|
|
476
470
|
const index = super.addItem(item, false);
|
|
477
471
|
if (index !== -1) {
|
|
478
|
-
const { autoHideNewItems, showStubsIfEmpty }
|
|
472
|
+
const { autoHideNewItems, showStubsIfEmpty } = this.#_options;
|
|
479
473
|
const _status = this.#_status;
|
|
480
474
|
const { catchEventOnHost, isStubItemShown } = _status;
|
|
481
475
|
if (!catchEventOnHost) {
|
|
@@ -504,49 +498,132 @@ class THtmlItemsListController extends THtmlItemsListContainer {
|
|
|
504
498
|
item: item,
|
|
505
499
|
});
|
|
506
500
|
};
|
|
507
|
-
if (forceCI)
|
|
501
|
+
if (forceCI) {
|
|
502
|
+
this.#_selectItemEx(item, {
|
|
503
|
+
ctrlKey: false,
|
|
504
|
+
shiftKey: false,
|
|
505
|
+
forceCI: forceCI,
|
|
506
|
+
});
|
|
507
|
+
};
|
|
508
508
|
};
|
|
509
509
|
return index;
|
|
510
510
|
}
|
|
511
511
|
|
|
512
512
|
delItem(index, opt){
|
|
513
|
-
|
|
514
|
-
let isSUCCEED =
|
|
513
|
+
const item = super.getItem(index);
|
|
514
|
+
let isSUCCEED = item !== undefined;
|
|
515
|
+
const _status = this.#_status;
|
|
515
516
|
if (isSUCCEED) {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
517
|
+
_status.execDelItem = true;
|
|
518
|
+
_status.execDelItemCI = this.curIndex;
|
|
519
|
+
_status.execDelItemDI = Number(index);
|
|
520
|
+
isSUCCEED = super.delItem(index, opt, false);
|
|
521
|
+
if (isSUCCEED) {
|
|
522
|
+
const _options = this.#_options;
|
|
523
|
+
if (!_status.catchEventOnHost && isHTMLElement(item)) {
|
|
524
|
+
// remove event handler on element if it was set by addItem()
|
|
525
|
+
item.removeEventListener('click', this.#_on_will_select_item);
|
|
526
|
+
};
|
|
527
|
+
if (this.isEmpty()) {
|
|
528
|
+
this.#_selects.clear();
|
|
529
|
+
if (_options.showStubsIfEmpty) {
|
|
530
|
+
// show default stub-item
|
|
531
|
+
_status.isStubItemShown = this.#_stubs.showDefItem();
|
|
532
|
+
};
|
|
533
|
+
this.#_triggerEvent('list-clear');
|
|
534
|
+
} else {
|
|
535
|
+
this.#_selects.delete(item);
|
|
536
|
+
this.#_triggerEvent('item-removed', {
|
|
537
|
+
index: Number(index),
|
|
538
|
+
item: item,
|
|
539
|
+
});
|
|
540
|
+
const current = this.curIndex;
|
|
541
|
+
if (current === -1) {
|
|
542
|
+
this.rstCurIndex();
|
|
543
|
+
} else {
|
|
544
|
+
this.setCurIndex(current);
|
|
545
|
+
};
|
|
527
546
|
};
|
|
528
|
-
this.#_triggerEvent('list-clear');
|
|
529
|
-
} else {
|
|
530
|
-
this.#_triggerEvent('item-removed', {
|
|
531
|
-
index: Number(index),
|
|
532
|
-
item: item,
|
|
533
|
-
});
|
|
534
547
|
};
|
|
548
|
+
_status.execDelItemDI = -1;
|
|
549
|
+
_status.execDelItemCI = -1;
|
|
550
|
+
_status.execDelItem = false;
|
|
535
551
|
};
|
|
536
552
|
return isSUCCEED;
|
|
537
553
|
}
|
|
538
554
|
|
|
539
|
-
|
|
555
|
+
#_selectItem(index){
|
|
540
556
|
const item = super.getItem(index);
|
|
541
|
-
|
|
557
|
+
const isSUCCEED = selectHtmlElement(item);
|
|
542
558
|
if (isSUCCEED) {
|
|
543
559
|
this.#_selects.add(item);
|
|
544
560
|
this.#_triggerEvent('item-selected', {
|
|
545
561
|
index: Number(index),
|
|
546
562
|
item: item,
|
|
547
563
|
});
|
|
564
|
+
};
|
|
565
|
+
return isSUCCEED;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
#_selectItemEx(item, opt){
|
|
569
|
+
const _selects = this.#_selects;
|
|
570
|
+
let {
|
|
571
|
+
ctrlKey = false,
|
|
572
|
+
shiftKey = false,
|
|
573
|
+
forceCI = false,
|
|
574
|
+
} = opt;
|
|
575
|
+
let mode = ILC_SMODE_DEF;
|
|
576
|
+
let doUnSelGrp = false;
|
|
577
|
+
let indexCI = this.curIndex;
|
|
578
|
+
let indexNI = this.srchIndex(item);
|
|
579
|
+
if (indexCI !== -1) {
|
|
580
|
+
if (this.#_options.allowGroupSelection) {
|
|
581
|
+
if (shiftKey) {
|
|
582
|
+
mode = ILC_SMODE_SHFT;
|
|
583
|
+
if (_selects.size > 0) doUnSelGrp = true;
|
|
584
|
+
} else if (ctrlKey) {
|
|
585
|
+
mode = ILC_SMODE_CTRL;
|
|
586
|
+
} else if (_selects.size > 0) {
|
|
587
|
+
doUnSelGrp = true;
|
|
588
|
+
};
|
|
589
|
+
} else if (_selects.size > 0) {
|
|
590
|
+
doUnSelGrp = true;
|
|
591
|
+
};
|
|
592
|
+
};
|
|
593
|
+
if (doUnSelGrp) {
|
|
594
|
+
for (let item of _selects) {
|
|
595
|
+
this.unselectItem(this.srchIndex(item));
|
|
596
|
+
};
|
|
597
|
+
_selects.clear();
|
|
598
|
+
};
|
|
599
|
+
switch (mode) {
|
|
600
|
+
case ILC_SMODE_SHFT:
|
|
601
|
+
if (indexCI > indexNI) [ indexCI, indexNI ] = [ indexNI, indexCI ];
|
|
602
|
+
for (let i = indexCI; i < indexNI + 1; i++) {
|
|
603
|
+
this.#_selectItem(i);
|
|
604
|
+
};
|
|
605
|
+
break;
|
|
606
|
+
case ILC_SMODE_CTRL:
|
|
607
|
+
this.#_selectItem(this.srchIndex(item));
|
|
608
|
+
break;
|
|
609
|
+
default:
|
|
610
|
+
if (this.#_selectItem(this.srchIndex(item))) {
|
|
611
|
+
if (forceCI) this.#_setCurIndex(indexNI);
|
|
612
|
+
};
|
|
613
|
+
break;
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
selectItem(index, opt){
|
|
618
|
+
const item = super.getItem(index);
|
|
619
|
+
let isSUCCEED = isHTMLElement(item);
|
|
620
|
+
if (isSUCCEED) {
|
|
548
621
|
const forceCI = typeof opt === 'boolean' ? opt : false;
|
|
549
|
-
|
|
622
|
+
this.#_selectItemEx(item, {
|
|
623
|
+
ctrlKey: false,
|
|
624
|
+
shiftKey: false,
|
|
625
|
+
forceCI: forceCI,
|
|
626
|
+
});
|
|
550
627
|
};
|
|
551
628
|
return isSUCCEED;
|
|
552
629
|
}
|