simplyflow 0.3.3 → 0.4.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/simply.flow.js +361 -425
- package/dist/simply.flow.min.js +1 -1
- package/dist/simply.flow.min.js.map +4 -4
- package/package.json +1 -1
- package/src/bind.mjs +46 -526
- package/src/bind.render.mjs +410 -0
- package/src/bind.transformers.mjs +25 -0
package/dist/simply.flow.js
CHANGED
|
@@ -419,7 +419,314 @@
|
|
|
419
419
|
}
|
|
420
420
|
}
|
|
421
421
|
|
|
422
|
+
// src/bind.transformers.mjs
|
|
423
|
+
function escape_html(context, next) {
|
|
424
|
+
let content = context.value.innerHTML;
|
|
425
|
+
if (typeof context.value == "string") {
|
|
426
|
+
content = context.value;
|
|
427
|
+
context.value = { innerHTML: content };
|
|
428
|
+
}
|
|
429
|
+
if (content) {
|
|
430
|
+
content = content.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
431
|
+
context.value.innerHTML = content;
|
|
432
|
+
}
|
|
433
|
+
next(context);
|
|
434
|
+
}
|
|
435
|
+
function fixed_content(context, next) {
|
|
436
|
+
if (typeof context.value == "string") {
|
|
437
|
+
context.value = {};
|
|
438
|
+
} else {
|
|
439
|
+
delete context.value.innerHTML;
|
|
440
|
+
}
|
|
441
|
+
next(context);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// src/bind.render.mjs
|
|
445
|
+
function field(context) {
|
|
446
|
+
if (context.templates?.length) {
|
|
447
|
+
fieldByTemplates.call(this, context);
|
|
448
|
+
} else if (Object.hasOwnProperty.call(this.options.renderers, context.element.tagName)) {
|
|
449
|
+
const renderer = this.options.renderers[context.element.tagName];
|
|
450
|
+
if (renderer) {
|
|
451
|
+
renderer.call(this, context);
|
|
452
|
+
}
|
|
453
|
+
} else if (this.options.renderers["*"]) {
|
|
454
|
+
this.options.renderers["*"].call(this, context);
|
|
455
|
+
}
|
|
456
|
+
return context;
|
|
457
|
+
}
|
|
458
|
+
function list(context) {
|
|
459
|
+
if (!Array.isArray(context.value)) {
|
|
460
|
+
console.error("Value is not an array.", context.element, context.path, context.value);
|
|
461
|
+
} else if (!context.templates?.length) {
|
|
462
|
+
console.error("No templates found in", context.element);
|
|
463
|
+
} else {
|
|
464
|
+
arrayByTemplates.call(this, context);
|
|
465
|
+
}
|
|
466
|
+
return context;
|
|
467
|
+
}
|
|
468
|
+
function map(context) {
|
|
469
|
+
if (typeof context.value != "object" || !context.value) {
|
|
470
|
+
console.error("Value is not an object.", context.element, context.path, context.value);
|
|
471
|
+
} else if (!context.templates?.length) {
|
|
472
|
+
console.error("No templates found in", context.element);
|
|
473
|
+
} else {
|
|
474
|
+
objectByTemplates.call(this, context);
|
|
475
|
+
}
|
|
476
|
+
return context;
|
|
477
|
+
}
|
|
478
|
+
function arrayByTemplates(context) {
|
|
479
|
+
const attribute = this.options.attribute;
|
|
480
|
+
let items = context.element.querySelectorAll(":scope > [" + attribute + "-key]");
|
|
481
|
+
let lastKey = 0;
|
|
482
|
+
let skipped = 0;
|
|
483
|
+
context.list = context.value;
|
|
484
|
+
for (let item of items) {
|
|
485
|
+
let currentKey = parseInt(item.getAttribute(attribute + "-key"));
|
|
486
|
+
if (currentKey > lastKey) {
|
|
487
|
+
context.index = lastKey;
|
|
488
|
+
context.element.insertBefore(this.applyTemplate(context), item);
|
|
489
|
+
} else if (currentKey < lastKey) {
|
|
490
|
+
item.remove();
|
|
491
|
+
} else {
|
|
492
|
+
let bindings = Array.from(item.querySelectorAll(`[${attribute}]`));
|
|
493
|
+
if (item.matches(`[${attribute}]`)) {
|
|
494
|
+
bindings.unshift(item);
|
|
495
|
+
}
|
|
496
|
+
let needsReplacement = bindings.find((b) => {
|
|
497
|
+
let databind = b.getAttribute(attribute);
|
|
498
|
+
return databind.substr(0, 5) !== ":root" && databind.substr(0, context.path.length) !== context.path;
|
|
499
|
+
});
|
|
500
|
+
if (!needsReplacement) {
|
|
501
|
+
if (item[Symbol.bindTemplate]) {
|
|
502
|
+
let newTemplate = this.findTemplate(context.templates, context.list[lastKey]);
|
|
503
|
+
if (newTemplate != item[Symbol.bindTemplate]) {
|
|
504
|
+
needsReplacement = true;
|
|
505
|
+
if (!newTemplate) {
|
|
506
|
+
skipped++;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
if (needsReplacement) {
|
|
512
|
+
context.index = lastKey;
|
|
513
|
+
context.element.replaceChild(this.applyTemplate(context), item);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
lastKey++;
|
|
517
|
+
if (lastKey >= context.value.length) {
|
|
518
|
+
break;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
items = context.element.querySelectorAll(":scope > [" + attribute + "-key]");
|
|
522
|
+
let length = items.length + skipped;
|
|
523
|
+
if (length > context.value.length) {
|
|
524
|
+
while (length > context.value.length) {
|
|
525
|
+
let child = context.element.querySelectorAll(":scope > :not(template)")?.[length - 1];
|
|
526
|
+
child?.remove();
|
|
527
|
+
length--;
|
|
528
|
+
}
|
|
529
|
+
} else if (length < context.value.length) {
|
|
530
|
+
while (length < context.value.length) {
|
|
531
|
+
context.index = length;
|
|
532
|
+
context.element.appendChild(this.applyTemplate(context));
|
|
533
|
+
length++;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
function objectByTemplates(context) {
|
|
538
|
+
const attribute = this.options.attribute;
|
|
539
|
+
context.list = context.value;
|
|
540
|
+
let items = Array.from(context.element.querySelectorAll(":scope > [" + attribute + "-key]"));
|
|
541
|
+
for (let key in context.list) {
|
|
542
|
+
context.index = key;
|
|
543
|
+
let item = items.shift();
|
|
544
|
+
if (!item) {
|
|
545
|
+
let clone = this.applyTemplate(context);
|
|
546
|
+
context.element.appendChild(clone);
|
|
547
|
+
continue;
|
|
548
|
+
}
|
|
549
|
+
if (item.getAttribute[attribute + "-key"] != key) {
|
|
550
|
+
items.unshift(item);
|
|
551
|
+
let outOfOrderItem = context.element.querySelector(":scope > [" + attribute + '-key="' + key + '"]');
|
|
552
|
+
if (!outOfOrderItem) {
|
|
553
|
+
let clone = this.applyTemplate(context);
|
|
554
|
+
context.element.insertBefore(clone, item);
|
|
555
|
+
continue;
|
|
556
|
+
} else {
|
|
557
|
+
context.element.insertBefore(outOfOrderItem, item);
|
|
558
|
+
item = outOfOrderItem;
|
|
559
|
+
items = items.filter((i) => i != outOfOrderItem);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
let newTemplate = this.findTemplate(context.templates, context.list[context.index]);
|
|
563
|
+
if (newTemplate != item[Symbol.bindTemplate]) {
|
|
564
|
+
let clone = this.applyTemplate(context);
|
|
565
|
+
context.element.replaceChild(clone, item);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
while (items.length) {
|
|
569
|
+
let item = items.shift();
|
|
570
|
+
item.remove();
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
function fieldByTemplates(context) {
|
|
574
|
+
const rendered = context.element.querySelector(":scope > :not(template)");
|
|
575
|
+
const template = this.findTemplate(context.templates, context.value);
|
|
576
|
+
if (rendered) {
|
|
577
|
+
if (template) {
|
|
578
|
+
if (rendered?.[Symbol.bindTemplate] != template) {
|
|
579
|
+
const clone = this.applyTemplate(context);
|
|
580
|
+
context.element.replaceChild(clone, rendered);
|
|
581
|
+
}
|
|
582
|
+
} else {
|
|
583
|
+
context.element.removeChild(rendered);
|
|
584
|
+
}
|
|
585
|
+
} else if (template) {
|
|
586
|
+
const clone = this.applyTemplate(context);
|
|
587
|
+
context.element.appendChild(clone);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
function input(context) {
|
|
591
|
+
const el = context.element;
|
|
592
|
+
let value = context.value;
|
|
593
|
+
element(context);
|
|
594
|
+
if (typeof value == "undefined") {
|
|
595
|
+
value = "";
|
|
596
|
+
}
|
|
597
|
+
if (el.type == "checkbox" || el.type == "radio") {
|
|
598
|
+
if (matchValue(el.value, value)) {
|
|
599
|
+
el.checked = true;
|
|
600
|
+
} else {
|
|
601
|
+
el.checked = false;
|
|
602
|
+
}
|
|
603
|
+
} else if (!matchValue(el.value, value)) {
|
|
604
|
+
el.value = "" + value;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
function button(context) {
|
|
608
|
+
element(context);
|
|
609
|
+
setProperties(context.element, context.value, "value");
|
|
610
|
+
}
|
|
611
|
+
function select(context) {
|
|
612
|
+
const el = context.element;
|
|
613
|
+
let value = context.value;
|
|
614
|
+
if (value === null) {
|
|
615
|
+
value = "";
|
|
616
|
+
}
|
|
617
|
+
if (typeof value != "object") {
|
|
618
|
+
if (el.multiple) {
|
|
619
|
+
if (Array.isArray(value)) {
|
|
620
|
+
for (let option of el.options) {
|
|
621
|
+
if (value.indexOf(option.value) === false) {
|
|
622
|
+
option.selected = false;
|
|
623
|
+
} else {
|
|
624
|
+
option.selected = true;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
} else {
|
|
629
|
+
let option = el.options.find((o) => matchValue(o.value, value));
|
|
630
|
+
if (option) {
|
|
631
|
+
option.selected = true;
|
|
632
|
+
option.setAttribute("selected", true);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
} else {
|
|
636
|
+
if (value.options) {
|
|
637
|
+
setSelectOptions(el, value.options);
|
|
638
|
+
}
|
|
639
|
+
if (value.selected) {
|
|
640
|
+
select(Object.asssign({}, context, { value: value.selected }));
|
|
641
|
+
}
|
|
642
|
+
setProperties(el, value, "name", "id", "selectedIndex", "className");
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
function addOption(select2, option) {
|
|
646
|
+
if (!option) {
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
if (typeof option !== "object") {
|
|
650
|
+
select2.options.add(new Option("" + option));
|
|
651
|
+
} else if (option.text) {
|
|
652
|
+
select2.options.add(new Option(option.text, option.value, option.defaultSelected, option.selected));
|
|
653
|
+
} else if (typeof option.value != "undefined") {
|
|
654
|
+
select2.options.add(new Option("" + option.value, option.value, option.defaultSelected, option.selected));
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
function setSelectOptions(select2, options) {
|
|
658
|
+
select2.innerHTML = "";
|
|
659
|
+
if (Array.isArray(options)) {
|
|
660
|
+
for (const option of options) {
|
|
661
|
+
addOption(select2, option);
|
|
662
|
+
}
|
|
663
|
+
} else if (options && typeof options == "object") {
|
|
664
|
+
for (const option in options) {
|
|
665
|
+
addOption(select2, { text: options[option], value: option });
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
function anchor(context) {
|
|
670
|
+
element(context);
|
|
671
|
+
setProperties(context.element, context.value, "target", "href", "name", "newwindow", "nofollow");
|
|
672
|
+
}
|
|
673
|
+
function image(context) {
|
|
674
|
+
setProperties(context.element, context.value, "title", "alt", "src", "id");
|
|
675
|
+
}
|
|
676
|
+
function iframe(context) {
|
|
677
|
+
setProperties(context.element, context.value, "title", "src", "id");
|
|
678
|
+
}
|
|
679
|
+
function meta(context) {
|
|
680
|
+
setProperties(context.element, context.value, "content", "id");
|
|
681
|
+
}
|
|
682
|
+
function element(context) {
|
|
683
|
+
const el = context.element;
|
|
684
|
+
let value = context.value;
|
|
685
|
+
if (typeof value == "undefined" || value == null) {
|
|
686
|
+
value = "";
|
|
687
|
+
}
|
|
688
|
+
let strValue = "" + value;
|
|
689
|
+
if (typeof value != "object" || strValue.substring(0, 8) != "[object ") {
|
|
690
|
+
el.innerHTML = strValue;
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
setProperties(el, value, "innerHTML", "title", "id", "className");
|
|
694
|
+
}
|
|
695
|
+
function setProperties(el, data, ...properties) {
|
|
696
|
+
if (!data || typeof data !== "object") {
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
for (const property of properties) {
|
|
700
|
+
if (typeof data[property] === "undefined") {
|
|
701
|
+
continue;
|
|
702
|
+
}
|
|
703
|
+
if (matchValue(el[property], data[property])) {
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
if (data[property] === null) {
|
|
707
|
+
el[property] = "";
|
|
708
|
+
} else {
|
|
709
|
+
el[property] = "" + data[property];
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
function matchValue(a, b) {
|
|
714
|
+
if (a == ":empty" && !b) {
|
|
715
|
+
return true;
|
|
716
|
+
}
|
|
717
|
+
if (b == ":empty" && !a) {
|
|
718
|
+
return true;
|
|
719
|
+
}
|
|
720
|
+
if ("" + a == "" + b) {
|
|
721
|
+
return true;
|
|
722
|
+
}
|
|
723
|
+
return false;
|
|
724
|
+
}
|
|
725
|
+
|
|
422
726
|
// src/bind.mjs
|
|
727
|
+
if (!Symbol.bindTemplate) {
|
|
728
|
+
Symbol.bindTemplate = Symbol("bindTemplate");
|
|
729
|
+
}
|
|
423
730
|
var SimplyBind = class {
|
|
424
731
|
/**
|
|
425
732
|
* @param Object options - a set of options for this instance, options may include:
|
|
@@ -427,22 +734,33 @@
|
|
|
427
734
|
* - container (HTMLElement) - the dom element to use as the root for all bindings
|
|
428
735
|
* - attribute (string) - the prefix for the field, list and map attributes, e.g. 'data-bind'
|
|
429
736
|
* - transformers (object name:function) - a map of transformer names and functions
|
|
430
|
-
* -
|
|
737
|
+
* - render (object with field, list and map properties)
|
|
431
738
|
*/
|
|
432
739
|
constructor(options) {
|
|
433
740
|
this.bindings = /* @__PURE__ */ new Map();
|
|
434
|
-
const
|
|
741
|
+
const defaultTransformers = {
|
|
435
742
|
escape_html,
|
|
436
743
|
fixed_content
|
|
437
744
|
};
|
|
438
745
|
const defaultOptions = {
|
|
439
746
|
container: document.body,
|
|
440
|
-
attribute: "data-
|
|
441
|
-
transformers:
|
|
442
|
-
|
|
443
|
-
field: [
|
|
444
|
-
list: [
|
|
445
|
-
map: [
|
|
747
|
+
attribute: "data-flow",
|
|
748
|
+
transformers: defaultTransformers,
|
|
749
|
+
render: {
|
|
750
|
+
field: [field],
|
|
751
|
+
list: [list],
|
|
752
|
+
map: [map]
|
|
753
|
+
},
|
|
754
|
+
renderers: {
|
|
755
|
+
"INPUT": input,
|
|
756
|
+
"BUTTON": button,
|
|
757
|
+
"SELECT": select,
|
|
758
|
+
"A": anchor,
|
|
759
|
+
"IMG": image,
|
|
760
|
+
"IFRAME": iframe,
|
|
761
|
+
"META": meta,
|
|
762
|
+
"TEMPLATE": null,
|
|
763
|
+
"*": element
|
|
446
764
|
}
|
|
447
765
|
};
|
|
448
766
|
if (!options?.root) {
|
|
@@ -450,26 +768,26 @@
|
|
|
450
768
|
}
|
|
451
769
|
this.options = Object.assign({}, defaultOptions, options);
|
|
452
770
|
if (options.transformers) {
|
|
453
|
-
this.options.transformers = Object.assign({},
|
|
771
|
+
this.options.transformers = Object.assign({}, defaultTransformers, options?.transformers);
|
|
454
772
|
}
|
|
455
773
|
const attribute = this.options.attribute;
|
|
456
774
|
const bindAttributes = [attribute + "-field", attribute + "-list", attribute + "-map"];
|
|
457
775
|
const transformAttribute = attribute + "-transform";
|
|
458
776
|
const getBindingAttribute = (el) => {
|
|
459
|
-
const foundAttribute = bindAttributes.find((
|
|
777
|
+
const foundAttribute = bindAttributes.find((attr) => el.hasAttribute(attr));
|
|
460
778
|
if (!foundAttribute) {
|
|
461
|
-
console.error("No matching attribute found", el,
|
|
779
|
+
console.error("No matching attribute found", el, bindAttributes);
|
|
462
780
|
}
|
|
463
781
|
return foundAttribute;
|
|
464
782
|
};
|
|
465
|
-
const
|
|
783
|
+
const renderElement = (el) => {
|
|
466
784
|
this.bindings.set(el, throttledEffect(() => {
|
|
467
785
|
if (!el.isConnected) {
|
|
468
786
|
untrack(el, this.getBindingPath(el));
|
|
469
787
|
destroy(this.bindings.get(el));
|
|
470
788
|
return;
|
|
471
789
|
}
|
|
472
|
-
|
|
790
|
+
let context = {
|
|
473
791
|
templates: el.querySelectorAll(":scope > template"),
|
|
474
792
|
attribute: getBindingAttribute(el)
|
|
475
793
|
};
|
|
@@ -484,13 +802,16 @@
|
|
|
484
802
|
let transformers;
|
|
485
803
|
switch (context.attribute) {
|
|
486
804
|
case this.options.attribute + "-field":
|
|
487
|
-
transformers = Array.from(this.options.
|
|
805
|
+
transformers = Array.from(this.options.render.field);
|
|
488
806
|
break;
|
|
489
807
|
case this.options.attribute + "-list":
|
|
490
|
-
transformers = Array.from(this.options.
|
|
808
|
+
transformers = Array.from(this.options.render.list);
|
|
491
809
|
break;
|
|
492
810
|
case this.options.attribute + "-map":
|
|
493
|
-
transformers = Array.from(this.options.
|
|
811
|
+
transformers = Array.from(this.options.render.map);
|
|
812
|
+
break;
|
|
813
|
+
default:
|
|
814
|
+
throw new Error("no valid context attribute specified", context);
|
|
494
815
|
break;
|
|
495
816
|
}
|
|
496
817
|
if (context.element.hasAttribute(transformAttribute)) {
|
|
@@ -515,7 +836,7 @@
|
|
|
515
836
|
const applyBindings = (bindings2) => {
|
|
516
837
|
for (let bindingEl of bindings2) {
|
|
517
838
|
if (!this.bindings.get(bindingEl)) {
|
|
518
|
-
|
|
839
|
+
renderElement(bindingEl);
|
|
519
840
|
}
|
|
520
841
|
}
|
|
521
842
|
};
|
|
@@ -560,10 +881,9 @@
|
|
|
560
881
|
applyTemplate(context) {
|
|
561
882
|
const path = context.path;
|
|
562
883
|
const templates = context.templates;
|
|
563
|
-
const
|
|
884
|
+
const list2 = context.list;
|
|
564
885
|
const index = context.index;
|
|
565
|
-
const
|
|
566
|
-
const value = list ? list[index] : context.value;
|
|
886
|
+
const value = list2 ? list2[index] : context.value;
|
|
567
887
|
let template = this.findTemplate(templates, value);
|
|
568
888
|
if (!template) {
|
|
569
889
|
let result = new DocumentFragment();
|
|
@@ -581,31 +901,22 @@
|
|
|
581
901
|
const attributes = [attribute + "-field", attribute + "-list", attribute + "-map"];
|
|
582
902
|
const bindings = clone.querySelectorAll(`[${attribute}-field],[${attribute}-list],[${attribute}-map]`);
|
|
583
903
|
for (let binding of bindings) {
|
|
584
|
-
const
|
|
585
|
-
const bind2 = binding.getAttribute(
|
|
904
|
+
const attr = attributes.find((attr2) => binding.hasAttribute(attr2));
|
|
905
|
+
const bind2 = binding.getAttribute(attr);
|
|
586
906
|
if (bind2.substring(0, ":root.".length) == ":root.") {
|
|
587
|
-
binding.setAttribute(
|
|
907
|
+
binding.setAttribute(attr, bind2.substring(":root.".length));
|
|
588
908
|
} else if (bind2 == ":value" && index != null) {
|
|
589
|
-
binding.setAttribute(
|
|
909
|
+
binding.setAttribute(attr, path + "." + index);
|
|
590
910
|
} else if (index != null) {
|
|
591
|
-
binding.setAttribute(
|
|
911
|
+
binding.setAttribute(attr, path + "." + index + "." + bind2);
|
|
592
912
|
} else {
|
|
593
|
-
binding.setAttribute(
|
|
913
|
+
binding.setAttribute(attr, path + "." + bind2);
|
|
594
914
|
}
|
|
595
915
|
}
|
|
596
916
|
if (typeof index !== "undefined") {
|
|
597
917
|
clone.children[0].setAttribute(attribute + "-key", index);
|
|
598
918
|
}
|
|
599
|
-
|
|
600
|
-
clone.children[0],
|
|
601
|
-
"$bindTemplate",
|
|
602
|
-
{
|
|
603
|
-
value: template,
|
|
604
|
-
enumerable: false,
|
|
605
|
-
writable: true,
|
|
606
|
-
configurable: true
|
|
607
|
-
}
|
|
608
|
-
);
|
|
919
|
+
clone.children[0][Symbol.bindTemplate] = template;
|
|
609
920
|
return clone;
|
|
610
921
|
}
|
|
611
922
|
/**
|
|
@@ -619,9 +930,9 @@
|
|
|
619
930
|
this.options.attribute + "-list",
|
|
620
931
|
this.options.attribute + "-map"
|
|
621
932
|
];
|
|
622
|
-
for (let
|
|
623
|
-
if (el.hasAttribute(
|
|
624
|
-
return el.getAttribute(
|
|
933
|
+
for (let attr of attributes) {
|
|
934
|
+
if (el.hasAttribute(attr)) {
|
|
935
|
+
return el.getAttribute(attr);
|
|
625
936
|
}
|
|
626
937
|
}
|
|
627
938
|
}
|
|
@@ -689,399 +1000,24 @@
|
|
|
689
1000
|
}
|
|
690
1001
|
}
|
|
691
1002
|
function untrack(el, path) {
|
|
692
|
-
let
|
|
693
|
-
if (
|
|
694
|
-
|
|
695
|
-
tracking.set(path,
|
|
1003
|
+
let list2 = tracking.get(path);
|
|
1004
|
+
if (list2) {
|
|
1005
|
+
list2 = list2.filter((context) => context.element == el);
|
|
1006
|
+
tracking.set(path, list2);
|
|
696
1007
|
}
|
|
697
1008
|
}
|
|
698
|
-
function matchValue(a, b) {
|
|
699
|
-
if (a == ":empty" && !b) {
|
|
700
|
-
return true;
|
|
701
|
-
}
|
|
702
|
-
if (b == ":empty" && !a) {
|
|
703
|
-
return true;
|
|
704
|
-
}
|
|
705
|
-
if ("" + a == "" + b) {
|
|
706
|
-
return true;
|
|
707
|
-
}
|
|
708
|
-
return false;
|
|
709
|
-
}
|
|
710
1009
|
function getValueByPath(root, path) {
|
|
711
1010
|
let parts = path.split(".");
|
|
712
1011
|
let curr = root;
|
|
713
|
-
let part
|
|
714
|
-
|
|
1012
|
+
let part;
|
|
1013
|
+
part = parts.shift();
|
|
1014
|
+
while (part && curr) {
|
|
1015
|
+
part = decodeURIComponent(part);
|
|
1016
|
+
curr = curr[part];
|
|
715
1017
|
part = parts.shift();
|
|
716
|
-
if (part == ":key") {
|
|
717
|
-
return prevPart;
|
|
718
|
-
} else if (part == ":value") {
|
|
719
|
-
return curr;
|
|
720
|
-
} else if (part == ":root") {
|
|
721
|
-
curr = root;
|
|
722
|
-
} else {
|
|
723
|
-
part = decodeURIComponent(part);
|
|
724
|
-
curr = curr[part];
|
|
725
|
-
prevPart = part;
|
|
726
|
-
}
|
|
727
1018
|
}
|
|
728
1019
|
return curr;
|
|
729
1020
|
}
|
|
730
|
-
function defaultFieldTransformer(context) {
|
|
731
|
-
const el = context.element;
|
|
732
|
-
const templates = context.templates;
|
|
733
|
-
if (templates?.length) {
|
|
734
|
-
transformLiteralByTemplates.call(this, context);
|
|
735
|
-
} else {
|
|
736
|
-
switch (el.tagName) {
|
|
737
|
-
case "INPUT":
|
|
738
|
-
transformInput.call(this, context);
|
|
739
|
-
break;
|
|
740
|
-
case "BUTTON":
|
|
741
|
-
transformButton.call(this, context);
|
|
742
|
-
break;
|
|
743
|
-
case "SELECT":
|
|
744
|
-
transformSelect.call(this, context);
|
|
745
|
-
break;
|
|
746
|
-
case "A":
|
|
747
|
-
transformAnchor.call(this, context);
|
|
748
|
-
break;
|
|
749
|
-
case "IMG":
|
|
750
|
-
transformImage.call(this, context);
|
|
751
|
-
break;
|
|
752
|
-
case "IFRAME":
|
|
753
|
-
transformIframe.call(this, context);
|
|
754
|
-
break;
|
|
755
|
-
case "META":
|
|
756
|
-
transformMeta.call(this, context);
|
|
757
|
-
break;
|
|
758
|
-
case "TEMPLATE":
|
|
759
|
-
break;
|
|
760
|
-
default:
|
|
761
|
-
transformElement.call(this, context);
|
|
762
|
-
break;
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
return context;
|
|
766
|
-
}
|
|
767
|
-
function defaultListTransformer(context) {
|
|
768
|
-
const el = context.element;
|
|
769
|
-
const templates = context.templates;
|
|
770
|
-
const path = context.path;
|
|
771
|
-
const value = context.value;
|
|
772
|
-
if (!Array.isArray(value)) {
|
|
773
|
-
console.error("Value is not an array.", el, path, value);
|
|
774
|
-
} else if (!templates?.length) {
|
|
775
|
-
console.error("No templates found in", el);
|
|
776
|
-
} else {
|
|
777
|
-
transformArrayByTemplates.call(this, context);
|
|
778
|
-
}
|
|
779
|
-
return context;
|
|
780
|
-
}
|
|
781
|
-
function defaultMapTransformer(context) {
|
|
782
|
-
const el = context.element;
|
|
783
|
-
const templates = context.templates;
|
|
784
|
-
const path = context.path;
|
|
785
|
-
const value = context.value;
|
|
786
|
-
if (typeof value != "object") {
|
|
787
|
-
console.error("Value is not an object.", el, path, value);
|
|
788
|
-
} else if (!templates?.length) {
|
|
789
|
-
console.error("No templates found in", el);
|
|
790
|
-
} else {
|
|
791
|
-
transformObjectByTemplates.call(this, context);
|
|
792
|
-
}
|
|
793
|
-
return context;
|
|
794
|
-
}
|
|
795
|
-
function transformArrayByTemplates(context) {
|
|
796
|
-
const el = context.element;
|
|
797
|
-
const templates = context.templates;
|
|
798
|
-
const path = context.path;
|
|
799
|
-
const value = context.value;
|
|
800
|
-
const attribute = this.options.attribute;
|
|
801
|
-
let items = el.querySelectorAll(":scope > [" + attribute + "-key]");
|
|
802
|
-
let lastKey = 0;
|
|
803
|
-
let skipped = 0;
|
|
804
|
-
context.list = value;
|
|
805
|
-
for (let item of items) {
|
|
806
|
-
let currentKey = parseInt(item.getAttribute(attribute + "-key"));
|
|
807
|
-
if (currentKey > lastKey) {
|
|
808
|
-
context.index = lastKey;
|
|
809
|
-
el.insertBefore(this.applyTemplate(context), item);
|
|
810
|
-
} else if (currentKey < lastKey) {
|
|
811
|
-
item.remove();
|
|
812
|
-
} else {
|
|
813
|
-
let bindings = Array.from(item.querySelectorAll(`[${attribute}]`));
|
|
814
|
-
if (item.matches(`[${attribute}]`)) {
|
|
815
|
-
bindings.unshift(item);
|
|
816
|
-
}
|
|
817
|
-
let needsReplacement = bindings.find((b) => {
|
|
818
|
-
let databind = b.getAttribute(attribute);
|
|
819
|
-
return databind.substr(0, 5) !== ":root" && databind.substr(0, path.length) !== path;
|
|
820
|
-
});
|
|
821
|
-
if (!needsReplacement) {
|
|
822
|
-
if (item.$bindTemplate) {
|
|
823
|
-
let newTemplate = this.findTemplate(templates, value[lastKey]);
|
|
824
|
-
if (newTemplate != item.$bindTemplate) {
|
|
825
|
-
needsReplacement = true;
|
|
826
|
-
if (!newTemplate) {
|
|
827
|
-
skipped++;
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
if (needsReplacement) {
|
|
833
|
-
context.index = lastKey;
|
|
834
|
-
el.replaceChild(this.applyTemplate(context), item);
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
lastKey++;
|
|
838
|
-
if (lastKey >= value.length) {
|
|
839
|
-
break;
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
items = el.querySelectorAll(":scope > [" + attribute + "-key]");
|
|
843
|
-
let length = items.length + skipped;
|
|
844
|
-
if (length > value.length) {
|
|
845
|
-
while (length > value.length) {
|
|
846
|
-
let child = el.querySelectorAll(":scope > :not(template)")?.[length - 1];
|
|
847
|
-
child?.remove();
|
|
848
|
-
length--;
|
|
849
|
-
}
|
|
850
|
-
} else if (length < value.length) {
|
|
851
|
-
while (length < value.length) {
|
|
852
|
-
context.index = length;
|
|
853
|
-
el.appendChild(this.applyTemplate(context));
|
|
854
|
-
length++;
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
function transformObjectByTemplates(context) {
|
|
859
|
-
const el = context.element;
|
|
860
|
-
const templates = context.templates;
|
|
861
|
-
const value = context.value;
|
|
862
|
-
const attribute = this.options.attribute;
|
|
863
|
-
context.list = value;
|
|
864
|
-
let items = Array.from(el.querySelectorAll(":scope > [" + attribute + "-key]"));
|
|
865
|
-
for (let key in context.list) {
|
|
866
|
-
context.index = key;
|
|
867
|
-
let item = items.shift();
|
|
868
|
-
if (!item) {
|
|
869
|
-
let clone = this.applyTemplate(context);
|
|
870
|
-
el.appendChild(clone);
|
|
871
|
-
continue;
|
|
872
|
-
}
|
|
873
|
-
if (item.getAttribute[attribute + "-key"] != key) {
|
|
874
|
-
items.unshift(item);
|
|
875
|
-
let outOfOrderItem = el.querySelector(":scope > [" + attribute + '-key="' + key + '"]');
|
|
876
|
-
if (!outOfOrderItem) {
|
|
877
|
-
let clone = this.applyTemplate(context);
|
|
878
|
-
el.insertBefore(clone, item);
|
|
879
|
-
continue;
|
|
880
|
-
} else {
|
|
881
|
-
el.insertBefore(outOfOrderItem, item);
|
|
882
|
-
item = outOfOrderItem;
|
|
883
|
-
items = items.filter((i) => i != outOfOrderItem);
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
let newTemplate = this.findTemplate(templates, value[key]);
|
|
887
|
-
if (newTemplate != item.$bindTemplate) {
|
|
888
|
-
let clone = this.applyTemplate(context);
|
|
889
|
-
el.replaceChild(clone, item);
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
while (items.length) {
|
|
893
|
-
let item = items.shift();
|
|
894
|
-
item.remove();
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
function getParentPath(el, attribute) {
|
|
898
|
-
const parentEl = el.parentElement?.closest(`[${attribute}-list],[${attribute}-map]`);
|
|
899
|
-
if (!parentEl) {
|
|
900
|
-
return ":root";
|
|
901
|
-
}
|
|
902
|
-
if (parentEl.hasAttribute(`${attribute}-list`)) {
|
|
903
|
-
return parentEl.getAttribute(`${attribute}-list`);
|
|
904
|
-
}
|
|
905
|
-
return parentEl.getAttribute(`${attribute}-map`);
|
|
906
|
-
}
|
|
907
|
-
function transformLiteralByTemplates(context) {
|
|
908
|
-
const el = context.element;
|
|
909
|
-
const templates = context.templates;
|
|
910
|
-
const value = context.value;
|
|
911
|
-
const attribute = this.options.attribute;
|
|
912
|
-
const rendered = el.querySelector(":scope > :not(template)");
|
|
913
|
-
const template = this.findTemplate(templates, value);
|
|
914
|
-
context.parent = getParentPath(el, attribute);
|
|
915
|
-
if (rendered) {
|
|
916
|
-
if (template) {
|
|
917
|
-
if (rendered?.$bindTemplate != template) {
|
|
918
|
-
const clone = this.applyTemplate(context);
|
|
919
|
-
el.replaceChild(clone, rendered);
|
|
920
|
-
}
|
|
921
|
-
} else {
|
|
922
|
-
el.removeChild(rendered);
|
|
923
|
-
}
|
|
924
|
-
} else if (template) {
|
|
925
|
-
const clone = this.applyTemplate(context);
|
|
926
|
-
el.appendChild(clone);
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
function transformInput(context) {
|
|
930
|
-
const el = context.element;
|
|
931
|
-
let value = context.value;
|
|
932
|
-
transformElement(context);
|
|
933
|
-
if (typeof value == "undefined") {
|
|
934
|
-
value = "";
|
|
935
|
-
}
|
|
936
|
-
if (el.type == "checkbox" || el.type == "radio") {
|
|
937
|
-
if (matchValue(el.value, value)) {
|
|
938
|
-
el.checked = true;
|
|
939
|
-
} else {
|
|
940
|
-
el.checked = false;
|
|
941
|
-
}
|
|
942
|
-
} else if (!matchValue(el.value, value)) {
|
|
943
|
-
el.value = "" + value;
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
function transformButton(context) {
|
|
947
|
-
const el = context.element;
|
|
948
|
-
const value = context.value;
|
|
949
|
-
transformElement(context);
|
|
950
|
-
setProperties(el, value, "value");
|
|
951
|
-
}
|
|
952
|
-
function transformSelect(context) {
|
|
953
|
-
const el = context.element;
|
|
954
|
-
let value = context.value;
|
|
955
|
-
if (value === null) {
|
|
956
|
-
value = "";
|
|
957
|
-
}
|
|
958
|
-
if (typeof value != "object") {
|
|
959
|
-
if (el.multiple) {
|
|
960
|
-
if (Array.isArray(value)) {
|
|
961
|
-
for (let option of el.options) {
|
|
962
|
-
if (value.indexOf(option.value) === false) {
|
|
963
|
-
option.selected = false;
|
|
964
|
-
} else {
|
|
965
|
-
option.selected = true;
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
} else {
|
|
970
|
-
let option = el.options.find((o) => matchValue(o.value, value));
|
|
971
|
-
if (option) {
|
|
972
|
-
option.selected = true;
|
|
973
|
-
option.setAttribute("selected", true);
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
} else {
|
|
977
|
-
if (value.options) {
|
|
978
|
-
setSelectOptions(el, value.options);
|
|
979
|
-
}
|
|
980
|
-
if (value.selected) {
|
|
981
|
-
transformSelect(Object.asssign({}, context, { value: value.selected }));
|
|
982
|
-
}
|
|
983
|
-
setProperties(el, value, "name", "id", "selectedIndex", "className");
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
function addOption(select, option) {
|
|
987
|
-
if (!option) {
|
|
988
|
-
return;
|
|
989
|
-
}
|
|
990
|
-
if (typeof option !== "object") {
|
|
991
|
-
select.options.add(new Option("" + option));
|
|
992
|
-
} else if (option.text) {
|
|
993
|
-
select.options.add(new Option(option.text, option.value, option.defaultSelected, option.selected));
|
|
994
|
-
} else if (typeof option.value != "undefined") {
|
|
995
|
-
select.options.add(new Option("" + option.value, option.value, option.defaultSelected, option.selected));
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
function setSelectOptions(select, options) {
|
|
999
|
-
select.innerHTML = "";
|
|
1000
|
-
if (Array.isArray(options)) {
|
|
1001
|
-
for (const option of options) {
|
|
1002
|
-
addOption(select, option);
|
|
1003
|
-
}
|
|
1004
|
-
} else if (options && typeof options == "object") {
|
|
1005
|
-
for (const option in options) {
|
|
1006
|
-
addOption(select, { text: options[option], value: option });
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
function transformAnchor(context) {
|
|
1011
|
-
const el = context.element;
|
|
1012
|
-
const value = context.value;
|
|
1013
|
-
transformElement(context);
|
|
1014
|
-
setProperties(el, value, "title", "target", "href", "name", "newwindow", "nofollow");
|
|
1015
|
-
}
|
|
1016
|
-
function transformImage(context) {
|
|
1017
|
-
const el = context.element;
|
|
1018
|
-
const value = context.value;
|
|
1019
|
-
transformElement(context);
|
|
1020
|
-
setProperties(el, value, "title", "alt", "src");
|
|
1021
|
-
}
|
|
1022
|
-
function transformIframe(context) {
|
|
1023
|
-
const el = context.element;
|
|
1024
|
-
const value = context.value;
|
|
1025
|
-
transformElement(context);
|
|
1026
|
-
setProperties(el, value, "title", "src");
|
|
1027
|
-
}
|
|
1028
|
-
function transformMeta(context) {
|
|
1029
|
-
const el = context.element;
|
|
1030
|
-
const value = context.value;
|
|
1031
|
-
transformElement(context);
|
|
1032
|
-
setProperties(el, value, "content");
|
|
1033
|
-
}
|
|
1034
|
-
function transformElement(context) {
|
|
1035
|
-
const el = context.element;
|
|
1036
|
-
let value = context.value;
|
|
1037
|
-
if (typeof value == "undefined" || value == null) {
|
|
1038
|
-
value = "";
|
|
1039
|
-
}
|
|
1040
|
-
let strValue = "" + value;
|
|
1041
|
-
if (typeof value != "object" || strValue.substring(0, 8) != "[object ") {
|
|
1042
|
-
el.innerHTML = strValue;
|
|
1043
|
-
return;
|
|
1044
|
-
}
|
|
1045
|
-
setProperties(el, value, "innerHTML", "title", "id", "className");
|
|
1046
|
-
}
|
|
1047
|
-
function setProperties(el, data, ...properties) {
|
|
1048
|
-
if (!data || typeof data !== "object") {
|
|
1049
|
-
return;
|
|
1050
|
-
}
|
|
1051
|
-
for (const property of properties) {
|
|
1052
|
-
if (typeof data[property] === "undefined") {
|
|
1053
|
-
continue;
|
|
1054
|
-
}
|
|
1055
|
-
if (matchValue(el[property], data[property])) {
|
|
1056
|
-
continue;
|
|
1057
|
-
}
|
|
1058
|
-
if (data[property] === null) {
|
|
1059
|
-
el[property] = "";
|
|
1060
|
-
} else {
|
|
1061
|
-
el[property] = "" + data[property];
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
function escape_html(context, next) {
|
|
1066
|
-
let content = context.value.innerHTML;
|
|
1067
|
-
if (typeof context.value == "string") {
|
|
1068
|
-
content = context.value;
|
|
1069
|
-
context.value = { innerHTML: content };
|
|
1070
|
-
}
|
|
1071
|
-
if (content) {
|
|
1072
|
-
content = content.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1073
|
-
context.value.innerHTML = content;
|
|
1074
|
-
}
|
|
1075
|
-
next(context);
|
|
1076
|
-
}
|
|
1077
|
-
function fixed_content(context, next) {
|
|
1078
|
-
if (typeof context.value == "string") {
|
|
1079
|
-
context.value = {};
|
|
1080
|
-
} else {
|
|
1081
|
-
delete context.value.innerHTML;
|
|
1082
|
-
}
|
|
1083
|
-
next(context);
|
|
1084
|
-
}
|
|
1085
1021
|
|
|
1086
1022
|
// src/model.mjs
|
|
1087
1023
|
var model_exports = {};
|
|
@@ -1214,11 +1150,11 @@
|
|
|
1214
1150
|
return function(data) {
|
|
1215
1151
|
this.state.options.columns = options;
|
|
1216
1152
|
return throttledEffect(() => {
|
|
1217
|
-
return data.current.map((
|
|
1153
|
+
return data.current.map((input2) => {
|
|
1218
1154
|
let result = {};
|
|
1219
1155
|
for (let key of Object.keys(this.state.options.columns)) {
|
|
1220
1156
|
if (!this.state.options.columns[key]?.hidden) {
|
|
1221
|
-
result[key] =
|
|
1157
|
+
result[key] = input2[key];
|
|
1222
1158
|
}
|
|
1223
1159
|
}
|
|
1224
1160
|
return result;
|