simplyflow 0.3.2 → 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 +366 -413
- 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 +55 -512
- 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,43 +734,60 @@
|
|
|
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();
|
|
741
|
+
const defaultTransformers = {
|
|
742
|
+
escape_html,
|
|
743
|
+
fixed_content
|
|
744
|
+
};
|
|
434
745
|
const defaultOptions = {
|
|
435
746
|
container: document.body,
|
|
436
|
-
attribute: "data-
|
|
437
|
-
transformers:
|
|
438
|
-
|
|
439
|
-
field: [
|
|
440
|
-
list: [
|
|
441
|
-
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
|
|
442
764
|
}
|
|
443
765
|
};
|
|
444
766
|
if (!options?.root) {
|
|
445
767
|
throw new Error("bind needs at least options.root set");
|
|
446
768
|
}
|
|
447
769
|
this.options = Object.assign({}, defaultOptions, options);
|
|
770
|
+
if (options.transformers) {
|
|
771
|
+
this.options.transformers = Object.assign({}, defaultTransformers, options?.transformers);
|
|
772
|
+
}
|
|
448
773
|
const attribute = this.options.attribute;
|
|
449
774
|
const bindAttributes = [attribute + "-field", attribute + "-list", attribute + "-map"];
|
|
450
|
-
const bindSelector = `[${attribute}-field],[${attribute}-list],[${attribute}-map]`;
|
|
451
775
|
const transformAttribute = attribute + "-transform";
|
|
452
776
|
const getBindingAttribute = (el) => {
|
|
453
|
-
const foundAttribute = bindAttributes.find((
|
|
777
|
+
const foundAttribute = bindAttributes.find((attr) => el.hasAttribute(attr));
|
|
454
778
|
if (!foundAttribute) {
|
|
455
|
-
console.error("No matching attribute found", el,
|
|
779
|
+
console.error("No matching attribute found", el, bindAttributes);
|
|
456
780
|
}
|
|
457
781
|
return foundAttribute;
|
|
458
782
|
};
|
|
459
|
-
const
|
|
783
|
+
const renderElement = (el) => {
|
|
460
784
|
this.bindings.set(el, throttledEffect(() => {
|
|
461
785
|
if (!el.isConnected) {
|
|
462
786
|
untrack(el, this.getBindingPath(el));
|
|
463
787
|
destroy(this.bindings.get(el));
|
|
464
788
|
return;
|
|
465
789
|
}
|
|
466
|
-
|
|
790
|
+
let context = {
|
|
467
791
|
templates: el.querySelectorAll(":scope > template"),
|
|
468
792
|
attribute: getBindingAttribute(el)
|
|
469
793
|
};
|
|
@@ -478,13 +802,16 @@
|
|
|
478
802
|
let transformers;
|
|
479
803
|
switch (context.attribute) {
|
|
480
804
|
case this.options.attribute + "-field":
|
|
481
|
-
transformers = Array.from(this.options.
|
|
805
|
+
transformers = Array.from(this.options.render.field);
|
|
482
806
|
break;
|
|
483
807
|
case this.options.attribute + "-list":
|
|
484
|
-
transformers = Array.from(this.options.
|
|
808
|
+
transformers = Array.from(this.options.render.list);
|
|
485
809
|
break;
|
|
486
810
|
case this.options.attribute + "-map":
|
|
487
|
-
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);
|
|
488
815
|
break;
|
|
489
816
|
}
|
|
490
817
|
if (context.element.hasAttribute(transformAttribute)) {
|
|
@@ -509,7 +836,7 @@
|
|
|
509
836
|
const applyBindings = (bindings2) => {
|
|
510
837
|
for (let bindingEl of bindings2) {
|
|
511
838
|
if (!this.bindings.get(bindingEl)) {
|
|
512
|
-
|
|
839
|
+
renderElement(bindingEl);
|
|
513
840
|
}
|
|
514
841
|
}
|
|
515
842
|
};
|
|
@@ -554,10 +881,9 @@
|
|
|
554
881
|
applyTemplate(context) {
|
|
555
882
|
const path = context.path;
|
|
556
883
|
const templates = context.templates;
|
|
557
|
-
const
|
|
884
|
+
const list2 = context.list;
|
|
558
885
|
const index = context.index;
|
|
559
|
-
const
|
|
560
|
-
const value = list ? list[index] : context.value;
|
|
886
|
+
const value = list2 ? list2[index] : context.value;
|
|
561
887
|
let template = this.findTemplate(templates, value);
|
|
562
888
|
if (!template) {
|
|
563
889
|
let result = new DocumentFragment();
|
|
@@ -575,31 +901,22 @@
|
|
|
575
901
|
const attributes = [attribute + "-field", attribute + "-list", attribute + "-map"];
|
|
576
902
|
const bindings = clone.querySelectorAll(`[${attribute}-field],[${attribute}-list],[${attribute}-map]`);
|
|
577
903
|
for (let binding of bindings) {
|
|
578
|
-
const
|
|
579
|
-
const bind2 = binding.getAttribute(
|
|
904
|
+
const attr = attributes.find((attr2) => binding.hasAttribute(attr2));
|
|
905
|
+
const bind2 = binding.getAttribute(attr);
|
|
580
906
|
if (bind2.substring(0, ":root.".length) == ":root.") {
|
|
581
|
-
binding.setAttribute(
|
|
907
|
+
binding.setAttribute(attr, bind2.substring(":root.".length));
|
|
582
908
|
} else if (bind2 == ":value" && index != null) {
|
|
583
|
-
binding.setAttribute(
|
|
909
|
+
binding.setAttribute(attr, path + "." + index);
|
|
584
910
|
} else if (index != null) {
|
|
585
|
-
binding.setAttribute(
|
|
911
|
+
binding.setAttribute(attr, path + "." + index + "." + bind2);
|
|
586
912
|
} else {
|
|
587
|
-
binding.setAttribute(
|
|
913
|
+
binding.setAttribute(attr, path + "." + bind2);
|
|
588
914
|
}
|
|
589
915
|
}
|
|
590
916
|
if (typeof index !== "undefined") {
|
|
591
917
|
clone.children[0].setAttribute(attribute + "-key", index);
|
|
592
918
|
}
|
|
593
|
-
|
|
594
|
-
clone.children[0],
|
|
595
|
-
"$bindTemplate",
|
|
596
|
-
{
|
|
597
|
-
value: template,
|
|
598
|
-
enumerable: false,
|
|
599
|
-
writable: true,
|
|
600
|
-
configurable: true
|
|
601
|
-
}
|
|
602
|
-
);
|
|
919
|
+
clone.children[0][Symbol.bindTemplate] = template;
|
|
603
920
|
return clone;
|
|
604
921
|
}
|
|
605
922
|
/**
|
|
@@ -613,9 +930,9 @@
|
|
|
613
930
|
this.options.attribute + "-list",
|
|
614
931
|
this.options.attribute + "-map"
|
|
615
932
|
];
|
|
616
|
-
for (let
|
|
617
|
-
if (el.hasAttribute(
|
|
618
|
-
return el.getAttribute(
|
|
933
|
+
for (let attr of attributes) {
|
|
934
|
+
if (el.hasAttribute(attr)) {
|
|
935
|
+
return el.getAttribute(attr);
|
|
619
936
|
}
|
|
620
937
|
}
|
|
621
938
|
}
|
|
@@ -683,388 +1000,24 @@
|
|
|
683
1000
|
}
|
|
684
1001
|
}
|
|
685
1002
|
function untrack(el, path) {
|
|
686
|
-
let
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
function matchValue(a, b) {
|
|
691
|
-
if (a == ":empty" && !b) {
|
|
692
|
-
return true;
|
|
1003
|
+
let list2 = tracking.get(path);
|
|
1004
|
+
if (list2) {
|
|
1005
|
+
list2 = list2.filter((context) => context.element == el);
|
|
1006
|
+
tracking.set(path, list2);
|
|
693
1007
|
}
|
|
694
|
-
if (b == ":empty" && !a) {
|
|
695
|
-
return true;
|
|
696
|
-
}
|
|
697
|
-
if ("" + a == "" + b) {
|
|
698
|
-
return true;
|
|
699
|
-
}
|
|
700
|
-
return false;
|
|
701
1008
|
}
|
|
702
1009
|
function getValueByPath(root, path) {
|
|
703
1010
|
let parts = path.split(".");
|
|
704
1011
|
let curr = root;
|
|
705
|
-
let part
|
|
706
|
-
|
|
1012
|
+
let part;
|
|
1013
|
+
part = parts.shift();
|
|
1014
|
+
while (part && curr) {
|
|
1015
|
+
part = decodeURIComponent(part);
|
|
1016
|
+
curr = curr[part];
|
|
707
1017
|
part = parts.shift();
|
|
708
|
-
if (part == ":key") {
|
|
709
|
-
return prevPart;
|
|
710
|
-
} else if (part == ":value") {
|
|
711
|
-
return curr;
|
|
712
|
-
} else if (part == ":root") {
|
|
713
|
-
curr = root;
|
|
714
|
-
} else {
|
|
715
|
-
part = decodeURIComponent(part);
|
|
716
|
-
curr = curr[part];
|
|
717
|
-
prevPart = part;
|
|
718
|
-
}
|
|
719
1018
|
}
|
|
720
1019
|
return curr;
|
|
721
1020
|
}
|
|
722
|
-
function defaultFieldTransformer(context) {
|
|
723
|
-
const el = context.element;
|
|
724
|
-
const templates = context.templates;
|
|
725
|
-
const templatesCount = templates.length;
|
|
726
|
-
const path = context.path;
|
|
727
|
-
const value = context.value;
|
|
728
|
-
const attribute = this.options.attribute;
|
|
729
|
-
if (templates?.length) {
|
|
730
|
-
transformLiteralByTemplates.call(this, context);
|
|
731
|
-
} else {
|
|
732
|
-
switch (el.tagName) {
|
|
733
|
-
case "INPUT":
|
|
734
|
-
transformInput.call(this, context);
|
|
735
|
-
break;
|
|
736
|
-
case "BUTTON":
|
|
737
|
-
transformButton.call(this, context);
|
|
738
|
-
break;
|
|
739
|
-
case "SELECT":
|
|
740
|
-
transformSelect.call(this, context);
|
|
741
|
-
break;
|
|
742
|
-
case "A":
|
|
743
|
-
transformAnchor.call(this, context);
|
|
744
|
-
break;
|
|
745
|
-
case "IMG":
|
|
746
|
-
transformImage.call(this, contet);
|
|
747
|
-
break;
|
|
748
|
-
case "IFRAME":
|
|
749
|
-
transformIframe.call(this, context);
|
|
750
|
-
break;
|
|
751
|
-
case "META":
|
|
752
|
-
transformMeta.call(this, context);
|
|
753
|
-
break;
|
|
754
|
-
case "TEMPLATE":
|
|
755
|
-
break;
|
|
756
|
-
default:
|
|
757
|
-
transformElement.call(this, context);
|
|
758
|
-
break;
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
return context;
|
|
762
|
-
}
|
|
763
|
-
function defaultListTransformer(context) {
|
|
764
|
-
const el = context.element;
|
|
765
|
-
const templates = context.templates;
|
|
766
|
-
const templatesCount = templates.length;
|
|
767
|
-
const path = context.path;
|
|
768
|
-
const value = context.value;
|
|
769
|
-
const attribute = this.options.attribute;
|
|
770
|
-
if (!Array.isArray(value)) {
|
|
771
|
-
console.error("Value is not an array.", el, path, value);
|
|
772
|
-
} else if (!templates?.length) {
|
|
773
|
-
console.error("No templates found in", el);
|
|
774
|
-
} else {
|
|
775
|
-
transformArrayByTemplates.call(this, context);
|
|
776
|
-
}
|
|
777
|
-
return context;
|
|
778
|
-
}
|
|
779
|
-
function defaultMapTransformer(context) {
|
|
780
|
-
const el = context.element;
|
|
781
|
-
const templates = context.templates;
|
|
782
|
-
const templatesCount = templates.length;
|
|
783
|
-
const path = context.path;
|
|
784
|
-
const value = context.value;
|
|
785
|
-
const attribute = this.options.attribute;
|
|
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 templatesCount = templates.length;
|
|
799
|
-
const path = context.path;
|
|
800
|
-
const value = context.value;
|
|
801
|
-
const attribute = this.options.attribute;
|
|
802
|
-
let items = el.querySelectorAll(":scope > [" + attribute + "-key]");
|
|
803
|
-
let lastKey = 0;
|
|
804
|
-
let skipped = 0;
|
|
805
|
-
context.list = value;
|
|
806
|
-
for (let item of items) {
|
|
807
|
-
let currentKey = parseInt(item.getAttribute(attribute + "-key"));
|
|
808
|
-
if (currentKey > lastKey) {
|
|
809
|
-
context.index = lastKey;
|
|
810
|
-
el.insertBefore(this.applyTemplate(context), item);
|
|
811
|
-
} else if (currentKey < lastKey) {
|
|
812
|
-
item.remove();
|
|
813
|
-
} else {
|
|
814
|
-
let bindings = Array.from(item.querySelectorAll(`[${attribute}]`));
|
|
815
|
-
if (item.matches(`[${attribute}]`)) {
|
|
816
|
-
bindings.unshift(item);
|
|
817
|
-
}
|
|
818
|
-
let needsReplacement = bindings.find((b) => {
|
|
819
|
-
let databind = b.getAttribute(attribute);
|
|
820
|
-
return databind.substr(0, 5) !== ":root" && databind.substr(0, path.length) !== path;
|
|
821
|
-
});
|
|
822
|
-
if (!needsReplacement) {
|
|
823
|
-
if (item.$bindTemplate) {
|
|
824
|
-
let newTemplate = this.findTemplate(templates, value[lastKey]);
|
|
825
|
-
if (newTemplate != item.$bindTemplate) {
|
|
826
|
-
needsReplacement = true;
|
|
827
|
-
if (!newTemplate) {
|
|
828
|
-
skipped++;
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
if (needsReplacement) {
|
|
834
|
-
context.index = lastKey;
|
|
835
|
-
el.replaceChild(this.applyTemplate(context), item);
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
lastKey++;
|
|
839
|
-
if (lastKey >= value.length) {
|
|
840
|
-
break;
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
items = el.querySelectorAll(":scope > [" + attribute + "-key]");
|
|
844
|
-
let length = items.length + skipped;
|
|
845
|
-
if (length > value.length) {
|
|
846
|
-
while (length > value.length) {
|
|
847
|
-
let child = el.querySelectorAll(":scope > :not(template)")?.[length - 1];
|
|
848
|
-
child?.remove();
|
|
849
|
-
length--;
|
|
850
|
-
}
|
|
851
|
-
} else if (length < value.length) {
|
|
852
|
-
while (length < value.length) {
|
|
853
|
-
context.index = length;
|
|
854
|
-
el.appendChild(this.applyTemplate(context));
|
|
855
|
-
length++;
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
function transformObjectByTemplates(context) {
|
|
860
|
-
const el = context.element;
|
|
861
|
-
const templates = context.templates;
|
|
862
|
-
const templatesCount = templates.length;
|
|
863
|
-
const path = context.path;
|
|
864
|
-
const value = context.value;
|
|
865
|
-
const attribute = this.options.attribute;
|
|
866
|
-
context.list = value;
|
|
867
|
-
let items = Array.from(el.querySelectorAll(":scope > [" + attribute + "-key]"));
|
|
868
|
-
for (let key in context.list) {
|
|
869
|
-
context.index = key;
|
|
870
|
-
let item = items.shift();
|
|
871
|
-
if (!item) {
|
|
872
|
-
let clone = this.applyTemplate(context);
|
|
873
|
-
el.appendChild(clone);
|
|
874
|
-
continue;
|
|
875
|
-
}
|
|
876
|
-
if (item.getAttribute[attribute + "-key"] != key) {
|
|
877
|
-
items.unshift(item);
|
|
878
|
-
let outOfOrderItem = el.querySelector(":scope > [" + attribute + '-key="' + key + '"]');
|
|
879
|
-
if (!outOfOrderItem) {
|
|
880
|
-
let clone = this.applyTemplate(context);
|
|
881
|
-
el.insertBefore(clone, item);
|
|
882
|
-
continue;
|
|
883
|
-
} else {
|
|
884
|
-
el.insertBefore(outOfOrderItem, item);
|
|
885
|
-
item = outOfOrderItem;
|
|
886
|
-
items = items.filter((i) => i != outOfOrderItem);
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
let newTemplate = this.findTemplate(templates, value[key]);
|
|
890
|
-
if (newTemplate != item.$bindTemplate) {
|
|
891
|
-
let clone = this.applyTemplate(context);
|
|
892
|
-
el.replaceChild(clone, item);
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
while (items.length) {
|
|
896
|
-
let item = items.shift();
|
|
897
|
-
item.remove();
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
function getParentPath(el, attribute) {
|
|
901
|
-
const parentEl = el.parentElement?.closest(`[${attribute}-list],[${attribute}-map]`);
|
|
902
|
-
if (!parentEl) {
|
|
903
|
-
return ":root";
|
|
904
|
-
}
|
|
905
|
-
if (parentEl.hasAttribute(`${attribute}-list`)) {
|
|
906
|
-
return parentEl.getAttribute(`${attribute}-list`);
|
|
907
|
-
}
|
|
908
|
-
return parentEl.getAttribute(`${attribute}-map`);
|
|
909
|
-
}
|
|
910
|
-
function transformLiteralByTemplates(context) {
|
|
911
|
-
const el = context.element;
|
|
912
|
-
const templates = context.templates;
|
|
913
|
-
const value = context.value;
|
|
914
|
-
const attribute = this.options.attribute;
|
|
915
|
-
const rendered = el.querySelector(":scope > :not(template)");
|
|
916
|
-
const template = this.findTemplate(templates, value);
|
|
917
|
-
context.parent = getParentPath(el, attribute);
|
|
918
|
-
if (rendered) {
|
|
919
|
-
if (template) {
|
|
920
|
-
if (rendered?.$bindTemplate != template) {
|
|
921
|
-
const clone = this.applyTemplate(context);
|
|
922
|
-
el.replaceChild(clone, rendered);
|
|
923
|
-
}
|
|
924
|
-
} else {
|
|
925
|
-
el.removeChild(rendered);
|
|
926
|
-
}
|
|
927
|
-
} else if (template) {
|
|
928
|
-
const clone = this.applyTemplate(context);
|
|
929
|
-
el.appendChild(clone);
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
function transformInput(context) {
|
|
933
|
-
const el = context.element;
|
|
934
|
-
let value = context.value;
|
|
935
|
-
transformElement(context);
|
|
936
|
-
if (typeof value == "undefined") {
|
|
937
|
-
value = "";
|
|
938
|
-
}
|
|
939
|
-
if (el.type == "checkbox" || el.type == "radio") {
|
|
940
|
-
if (matchValue(el.value, value)) {
|
|
941
|
-
el.checked = true;
|
|
942
|
-
} else {
|
|
943
|
-
el.checked = false;
|
|
944
|
-
}
|
|
945
|
-
} else if (!matchValue(el.value, value)) {
|
|
946
|
-
el.value = "" + value;
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
function transformButton(context) {
|
|
950
|
-
const el = context.element;
|
|
951
|
-
const value = context.value;
|
|
952
|
-
transformElement(context);
|
|
953
|
-
setProperties(el, value, "value");
|
|
954
|
-
}
|
|
955
|
-
function transformSelect(context) {
|
|
956
|
-
const el = context.element;
|
|
957
|
-
let value = context.value;
|
|
958
|
-
if (value === null) {
|
|
959
|
-
value = "";
|
|
960
|
-
}
|
|
961
|
-
if (typeof value != "object") {
|
|
962
|
-
if (el.multiple) {
|
|
963
|
-
if (Array.isArray(value)) {
|
|
964
|
-
for (let option of el.options) {
|
|
965
|
-
if (value.indexOf(option.value) === false) {
|
|
966
|
-
option.selected = false;
|
|
967
|
-
} else {
|
|
968
|
-
option.selected = true;
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
} else {
|
|
973
|
-
let option = el.options.find((o) => matchValue(o.value, value));
|
|
974
|
-
if (option) {
|
|
975
|
-
option.selected = true;
|
|
976
|
-
option.setAttribute("selected", true);
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
} else {
|
|
980
|
-
if (value.options) {
|
|
981
|
-
setSelectOptions(el, value.options);
|
|
982
|
-
}
|
|
983
|
-
if (value.selected) {
|
|
984
|
-
transformSelect(Object.asssign({}, context, { value: value.selected }));
|
|
985
|
-
}
|
|
986
|
-
setProperties(el, value, "name", "id", "selectedIndex", "className");
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
function addOption(select, option) {
|
|
990
|
-
if (!option) {
|
|
991
|
-
return;
|
|
992
|
-
}
|
|
993
|
-
if (typeof option !== "object") {
|
|
994
|
-
select.options.add(new Option("" + option));
|
|
995
|
-
} else if (option.text) {
|
|
996
|
-
select.options.add(new Option(option.text, option.value, option.defaultSelected, option.selected));
|
|
997
|
-
} else if (typeof option.value != "undefined") {
|
|
998
|
-
select.options.add(new Option("" + option.value, option.value, option.defaultSelected, option.selected));
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
function setSelectOptions(select, options) {
|
|
1002
|
-
select.innerHTML = "";
|
|
1003
|
-
if (Array.isArray(options)) {
|
|
1004
|
-
for (const option of options) {
|
|
1005
|
-
addOption(select, option);
|
|
1006
|
-
}
|
|
1007
|
-
} else if (options && typeof options == "object") {
|
|
1008
|
-
for (const option in options) {
|
|
1009
|
-
addOption(select, { text: options[option], value: option });
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
function transformAnchor(context) {
|
|
1014
|
-
const el = context.element;
|
|
1015
|
-
const value = context.value;
|
|
1016
|
-
transformElement(context);
|
|
1017
|
-
setProperties(el, value, "title", "target", "href", "name", "newwindow", "nofollow");
|
|
1018
|
-
}
|
|
1019
|
-
function transformImage(context) {
|
|
1020
|
-
const el = context.element;
|
|
1021
|
-
const value = context.value;
|
|
1022
|
-
transformElement(context);
|
|
1023
|
-
setProperties(el, value, "title", "alt", "src");
|
|
1024
|
-
}
|
|
1025
|
-
function transformIframe(context) {
|
|
1026
|
-
const el = context.element;
|
|
1027
|
-
const value = context.value;
|
|
1028
|
-
transformElement(context);
|
|
1029
|
-
setProperties(el, value, "title", "src");
|
|
1030
|
-
}
|
|
1031
|
-
function transformMeta(context) {
|
|
1032
|
-
const el = context.element;
|
|
1033
|
-
const value = context.value;
|
|
1034
|
-
transformElement(context);
|
|
1035
|
-
setProperties(el, value, "content");
|
|
1036
|
-
}
|
|
1037
|
-
function transformElement(context) {
|
|
1038
|
-
const el = context.element;
|
|
1039
|
-
let value = context.value;
|
|
1040
|
-
if (typeof value == "undefined" || value == null) {
|
|
1041
|
-
value = "";
|
|
1042
|
-
}
|
|
1043
|
-
let strValue = "" + value;
|
|
1044
|
-
if (typeof value != "object" || strValue.substring(0, 8) != "[object ") {
|
|
1045
|
-
el.innerHTML = strValue;
|
|
1046
|
-
return;
|
|
1047
|
-
}
|
|
1048
|
-
setProperties(el, value, "innerHTML", "title", "id", "className");
|
|
1049
|
-
}
|
|
1050
|
-
function setProperties(el, data, ...properties) {
|
|
1051
|
-
if (!data || typeof data !== "object") {
|
|
1052
|
-
return;
|
|
1053
|
-
}
|
|
1054
|
-
for (const property of properties) {
|
|
1055
|
-
if (typeof data[property] === "undefined") {
|
|
1056
|
-
continue;
|
|
1057
|
-
}
|
|
1058
|
-
if (matchValue(el[property], data[property])) {
|
|
1059
|
-
continue;
|
|
1060
|
-
}
|
|
1061
|
-
if (data[property] === null) {
|
|
1062
|
-
el[property] = "";
|
|
1063
|
-
} else {
|
|
1064
|
-
el[property] = "" + data[property];
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
1021
|
|
|
1069
1022
|
// src/model.mjs
|
|
1070
1023
|
var model_exports = {};
|
|
@@ -1197,11 +1150,11 @@
|
|
|
1197
1150
|
return function(data) {
|
|
1198
1151
|
this.state.options.columns = options;
|
|
1199
1152
|
return throttledEffect(() => {
|
|
1200
|
-
return data.current.map((
|
|
1153
|
+
return data.current.map((input2) => {
|
|
1201
1154
|
let result = {};
|
|
1202
1155
|
for (let key of Object.keys(this.state.options.columns)) {
|
|
1203
1156
|
if (!this.state.options.columns[key]?.hidden) {
|
|
1204
|
-
result[key] =
|
|
1157
|
+
result[key] = input2[key];
|
|
1205
1158
|
}
|
|
1206
1159
|
}
|
|
1207
1160
|
return result;
|