@optionfactory/fml 9.0.0-rc3 → 9.0.0-rc30
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/README.md +16 -88
- package/dist/client-errors.iife.js +40 -49
- package/dist/client-errors.iife.js.map +1 -1
- package/dist/client-errors.iife.min.js +1 -1
- package/dist/client-errors.iife.min.js.map +1 -1
- package/dist/custom-elements.json +483 -50
- package/dist/fml.css +25 -20
- package/dist/fml.css.map +1 -1
- package/dist/fml.iife.js +5688 -2542
- package/dist/fml.iife.js.map +1 -1
- package/dist/fml.iife.min.js +1 -1
- package/dist/fml.iife.min.js.map +1 -1
- package/dist/ftl.d.mts +398 -227
- package/dist/ftl.iife.js +682 -1016
- package/dist/ftl.iife.js.map +1 -1
- package/dist/ftl.iife.min.js +1 -1
- package/dist/ftl.iife.min.js.map +1 -1
- package/dist/ftl.min.mjs +1 -1
- package/dist/ftl.min.mjs.map +1 -1
- package/dist/ftl.mjs +682 -1016
- package/dist/ftl.mjs.map +1 -1
- package/dist/ful.css +25 -20
- package/dist/ful.css.map +1 -1
- package/dist/ful.d.mts +3043 -546
- package/dist/ful.iife.js +4875 -1387
- package/dist/ful.iife.js.map +1 -1
- package/dist/ful.iife.min.js +1 -1
- package/dist/ful.iife.min.js.map +1 -1
- package/dist/ful.min.mjs +1 -1
- package/dist/ful.min.mjs.map +1 -1
- package/dist/ful.mjs +4873 -1389
- package/dist/ful.mjs.map +1 -1
- package/dist/httpc.d.mts +143 -123
- package/dist/httpc.iife.js +163 -175
- package/dist/httpc.iife.js.map +1 -1
- package/dist/httpc.iife.min.js +1 -1
- package/dist/httpc.iife.min.js.map +1 -1
- package/dist/httpc.min.mjs +1 -1
- package/dist/httpc.min.mjs.map +1 -1
- package/dist/httpc.mjs +163 -175
- package/dist/httpc.mjs.map +1 -1
- package/dist/vscode.html-custom-data.json +234 -38
- package/dist/web-types.json +489 -50
- package/package.json +2 -2
package/dist/ftl.iife.js
CHANGED
|
@@ -2,12 +2,8 @@ var ftl = (function (exports) {
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* A Map bounded by entry count, evicting
|
|
6
|
-
*
|
|
7
|
-
* expressions, compiled masks, formatter instances) from growing forever. The
|
|
8
|
-
* capacity is sized so eviction never happens on a sane page: hitting it means
|
|
9
|
-
* dynamically generated keys, where FIFO's worst case (evicting a hot entry)
|
|
10
|
-
* costs one recomputation.
|
|
5
|
+
* A Map bounded by entry count, evicting the oldest entry when full. A hit does
|
|
6
|
+
* not refresh an entry: eviction follows insertion order, not use.
|
|
11
7
|
*/
|
|
12
8
|
class BoundedCache {
|
|
13
9
|
#max;
|
|
@@ -36,6 +32,7 @@ var ftl = (function (exports) {
|
|
|
36
32
|
this.#entries.set(key, value);
|
|
37
33
|
return value;
|
|
38
34
|
}
|
|
35
|
+
/** @returns {number} the number of entries held */
|
|
39
36
|
get size() {
|
|
40
37
|
return this.#entries.size;
|
|
41
38
|
}
|
|
@@ -74,14 +71,10 @@ var ftl = (function (exports) {
|
|
|
74
71
|
},
|
|
75
72
|
};
|
|
76
73
|
|
|
77
|
-
// @generated by Peggy 5.1.
|
|
74
|
+
// @generated by Peggy 5.1.1.
|
|
78
75
|
//
|
|
79
76
|
// https://peggyjs.org/
|
|
80
77
|
|
|
81
|
-
//keyword classification lives here, not in the grammar's ordered choice: the
|
|
82
|
-
//identifier rule consumes the whole word and the action decides, so no keyword
|
|
83
|
-
//can grab a longer identifier's prefix. A Map, not a plain object: `in` on the
|
|
84
|
-
//latter would classify inherited names such as `constructor` as keywords
|
|
85
78
|
const keywords = new Map([
|
|
86
79
|
['true', true],
|
|
87
80
|
['false', false],
|
|
@@ -144,10 +137,9 @@ var ftl = (function (exports) {
|
|
|
144
137
|
return s;
|
|
145
138
|
}
|
|
146
139
|
|
|
147
|
-
function
|
|
140
|
+
function escape(s, special) {
|
|
148
141
|
return unicodeEscape(s
|
|
149
|
-
.replace(
|
|
150
|
-
.replace(/"/g, "\\\"")
|
|
142
|
+
.replace(special, "\\$&")
|
|
151
143
|
.replace(/\0/g, "\\0")
|
|
152
144
|
.replace(/\t/g, "\\t")
|
|
153
145
|
.replace(/\n/g, "\\n")
|
|
@@ -156,18 +148,12 @@ var ftl = (function (exports) {
|
|
|
156
148
|
.replace(/[\x10-\x1F\x7F-\x9F]/g, ch => "\\x" + hex(ch)));
|
|
157
149
|
}
|
|
158
150
|
|
|
151
|
+
function literalEscape(s) {
|
|
152
|
+
return escape(s, /[\\"]/g);
|
|
153
|
+
}
|
|
154
|
+
|
|
159
155
|
function classEscape(s) {
|
|
160
|
-
return
|
|
161
|
-
.replace(/\\/g, "\\\\")
|
|
162
|
-
.replace(/\]/g, "\\]")
|
|
163
|
-
.replace(/\^/g, "\\^")
|
|
164
|
-
.replace(/-/g, "\\-")
|
|
165
|
-
.replace(/\0/g, "\\0")
|
|
166
|
-
.replace(/\t/g, "\\t")
|
|
167
|
-
.replace(/\n/g, "\\n")
|
|
168
|
-
.replace(/\r/g, "\\r")
|
|
169
|
-
.replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch))
|
|
170
|
-
.replace(/[\x10-\x1F\x7F-\x9F]/g, ch => "\\x" + hex(ch)));
|
|
156
|
+
return escape(s, /[\\\]^-]/g);
|
|
171
157
|
}
|
|
172
158
|
|
|
173
159
|
const DESCRIBE_EXPECTATION_FNS = {
|
|
@@ -285,14 +271,6 @@ var ftl = (function (exports) {
|
|
|
285
271
|
const peg$c53 = "<=";
|
|
286
272
|
const peg$c54 = "<";
|
|
287
273
|
|
|
288
|
-
const peg$r0 = /^[^\\{]/;
|
|
289
|
-
const peg$r1 = /^[0-9]/;
|
|
290
|
-
const peg$r2 = /^[^']/;
|
|
291
|
-
const peg$r3 = /^[^"]/;
|
|
292
|
-
const peg$r4 = /^[^\\`{]/;
|
|
293
|
-
const peg$r5 = /^[a-zA-Z$_]/;
|
|
294
|
-
const peg$r6 = /^[a-zA-Z$_0-9]/;
|
|
295
|
-
const peg$r7 = /^[ \t\n\r]/;
|
|
296
274
|
|
|
297
275
|
const peg$e0 = peg$literalExpectation("{{{{", false);
|
|
298
276
|
const peg$e1 = peg$literalExpectation("}}}}", false);
|
|
@@ -450,9 +428,10 @@ var ftl = (function (exports) {
|
|
|
450
428
|
let peg$maxFailExpected = options.peg$maxFailExpected || [];
|
|
451
429
|
let peg$silentFails = options.peg$silentFails | 0;
|
|
452
430
|
|
|
453
|
-
let peg$resultsCache =
|
|
431
|
+
let peg$resultsCache = new Map();
|
|
454
432
|
|
|
455
433
|
let peg$result;
|
|
434
|
+
let peg$charCode;
|
|
456
435
|
|
|
457
436
|
if (options.startRule) {
|
|
458
437
|
if (!(options.startRule in peg$startRuleFunctions)) {
|
|
@@ -571,7 +550,7 @@ var ftl = (function (exports) {
|
|
|
571
550
|
let s0, s1;
|
|
572
551
|
|
|
573
552
|
const key = peg$currPos * 38 + 0;
|
|
574
|
-
const cached = peg$resultsCache
|
|
553
|
+
const cached = peg$resultsCache.get(key);
|
|
575
554
|
|
|
576
555
|
if (cached) {
|
|
577
556
|
peg$currPos = cached.nextPos;
|
|
@@ -580,13 +559,13 @@ var ftl = (function (exports) {
|
|
|
580
559
|
}
|
|
581
560
|
|
|
582
561
|
s0 = [];
|
|
583
|
-
|
|
584
|
-
while (s1 !== peg$FAILED) {
|
|
585
|
-
s0.push(s1);
|
|
562
|
+
for (;;) {
|
|
586
563
|
s1 = peg$parseTemplatedExpression();
|
|
564
|
+
if (s1 === peg$FAILED) { break; }
|
|
565
|
+
s0.push(s1);
|
|
587
566
|
}
|
|
588
567
|
|
|
589
|
-
peg$resultsCache
|
|
568
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
590
569
|
|
|
591
570
|
return s0;
|
|
592
571
|
}
|
|
@@ -595,7 +574,7 @@ var ftl = (function (exports) {
|
|
|
595
574
|
let s0, s1, s2, s3, s4;
|
|
596
575
|
|
|
597
576
|
const key = peg$currPos * 38 + 1;
|
|
598
|
-
const cached = peg$resultsCache
|
|
577
|
+
const cached = peg$resultsCache.get(key);
|
|
599
578
|
|
|
600
579
|
if (cached) {
|
|
601
580
|
peg$currPos = cached.nextPos;
|
|
@@ -691,7 +670,7 @@ var ftl = (function (exports) {
|
|
|
691
670
|
}
|
|
692
671
|
}
|
|
693
672
|
|
|
694
|
-
peg$resultsCache
|
|
673
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
695
674
|
|
|
696
675
|
return s0;
|
|
697
676
|
}
|
|
@@ -700,7 +679,7 @@ var ftl = (function (exports) {
|
|
|
700
679
|
let s0;
|
|
701
680
|
|
|
702
681
|
const key = peg$currPos * 38 + 2;
|
|
703
|
-
const cached = peg$resultsCache
|
|
682
|
+
const cached = peg$resultsCache.get(key);
|
|
704
683
|
|
|
705
684
|
if (cached) {
|
|
706
685
|
peg$currPos = cached.nextPos;
|
|
@@ -716,7 +695,7 @@ var ftl = (function (exports) {
|
|
|
716
695
|
if (peg$silentFails === 0) { peg$fail(peg$e0); }
|
|
717
696
|
}
|
|
718
697
|
|
|
719
|
-
peg$resultsCache
|
|
698
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
720
699
|
|
|
721
700
|
return s0;
|
|
722
701
|
}
|
|
@@ -725,7 +704,7 @@ var ftl = (function (exports) {
|
|
|
725
704
|
let s0;
|
|
726
705
|
|
|
727
706
|
const key = peg$currPos * 38 + 3;
|
|
728
|
-
const cached = peg$resultsCache
|
|
707
|
+
const cached = peg$resultsCache.get(key);
|
|
729
708
|
|
|
730
709
|
if (cached) {
|
|
731
710
|
peg$currPos = cached.nextPos;
|
|
@@ -741,7 +720,7 @@ var ftl = (function (exports) {
|
|
|
741
720
|
if (peg$silentFails === 0) { peg$fail(peg$e1); }
|
|
742
721
|
}
|
|
743
722
|
|
|
744
|
-
peg$resultsCache
|
|
723
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
745
724
|
|
|
746
725
|
return s0;
|
|
747
726
|
}
|
|
@@ -750,7 +729,7 @@ var ftl = (function (exports) {
|
|
|
750
729
|
let s0;
|
|
751
730
|
|
|
752
731
|
const key = peg$currPos * 38 + 4;
|
|
753
|
-
const cached = peg$resultsCache
|
|
732
|
+
const cached = peg$resultsCache.get(key);
|
|
754
733
|
|
|
755
734
|
if (cached) {
|
|
756
735
|
peg$currPos = cached.nextPos;
|
|
@@ -766,7 +745,7 @@ var ftl = (function (exports) {
|
|
|
766
745
|
if (peg$silentFails === 0) { peg$fail(peg$e2); }
|
|
767
746
|
}
|
|
768
747
|
|
|
769
|
-
peg$resultsCache
|
|
748
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
770
749
|
|
|
771
750
|
return s0;
|
|
772
751
|
}
|
|
@@ -775,7 +754,7 @@ var ftl = (function (exports) {
|
|
|
775
754
|
let s0;
|
|
776
755
|
|
|
777
756
|
const key = peg$currPos * 38 + 5;
|
|
778
|
-
const cached = peg$resultsCache
|
|
757
|
+
const cached = peg$resultsCache.get(key);
|
|
779
758
|
|
|
780
759
|
if (cached) {
|
|
781
760
|
peg$currPos = cached.nextPos;
|
|
@@ -791,7 +770,7 @@ var ftl = (function (exports) {
|
|
|
791
770
|
if (peg$silentFails === 0) { peg$fail(peg$e3); }
|
|
792
771
|
}
|
|
793
772
|
|
|
794
|
-
peg$resultsCache
|
|
773
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
795
774
|
|
|
796
775
|
return s0;
|
|
797
776
|
}
|
|
@@ -800,7 +779,7 @@ var ftl = (function (exports) {
|
|
|
800
779
|
let s0;
|
|
801
780
|
|
|
802
781
|
const key = peg$currPos * 38 + 6;
|
|
803
|
-
const cached = peg$resultsCache
|
|
782
|
+
const cached = peg$resultsCache.get(key);
|
|
804
783
|
|
|
805
784
|
if (cached) {
|
|
806
785
|
peg$currPos = cached.nextPos;
|
|
@@ -816,7 +795,7 @@ var ftl = (function (exports) {
|
|
|
816
795
|
if (peg$silentFails === 0) { peg$fail(peg$e4); }
|
|
817
796
|
}
|
|
818
797
|
|
|
819
|
-
peg$resultsCache
|
|
798
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
820
799
|
|
|
821
800
|
return s0;
|
|
822
801
|
}
|
|
@@ -825,7 +804,7 @@ var ftl = (function (exports) {
|
|
|
825
804
|
let s0;
|
|
826
805
|
|
|
827
806
|
const key = peg$currPos * 38 + 7;
|
|
828
|
-
const cached = peg$resultsCache
|
|
807
|
+
const cached = peg$resultsCache.get(key);
|
|
829
808
|
|
|
830
809
|
if (cached) {
|
|
831
810
|
peg$currPos = cached.nextPos;
|
|
@@ -841,7 +820,7 @@ var ftl = (function (exports) {
|
|
|
841
820
|
if (peg$silentFails === 0) { peg$fail(peg$e5); }
|
|
842
821
|
}
|
|
843
822
|
|
|
844
|
-
peg$resultsCache
|
|
823
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
845
824
|
|
|
846
825
|
return s0;
|
|
847
826
|
}
|
|
@@ -850,7 +829,7 @@ var ftl = (function (exports) {
|
|
|
850
829
|
let s0, s1, s2, s3, s4, s5, s6;
|
|
851
830
|
|
|
852
831
|
const key = peg$currPos * 38 + 8;
|
|
853
|
-
const cached = peg$resultsCache
|
|
832
|
+
const cached = peg$resultsCache.get(key);
|
|
854
833
|
|
|
855
834
|
if (cached) {
|
|
856
835
|
peg$currPos = cached.nextPos;
|
|
@@ -860,211 +839,104 @@ var ftl = (function (exports) {
|
|
|
860
839
|
|
|
861
840
|
s0 = peg$currPos;
|
|
862
841
|
s1 = [];
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
peg$currPos++;
|
|
868
|
-
} else {
|
|
869
|
-
s4 = peg$FAILED;
|
|
870
|
-
if (peg$silentFails === 0) { peg$fail(peg$e6); }
|
|
871
|
-
}
|
|
872
|
-
if (s4 !== peg$FAILED) {
|
|
873
|
-
while (s4 !== peg$FAILED) {
|
|
874
|
-
s3.push(s4);
|
|
842
|
+
for (;;) {
|
|
843
|
+
s2 = peg$currPos;
|
|
844
|
+
s3 = [];
|
|
845
|
+
for (;;) {
|
|
875
846
|
s4 = input.charAt(peg$currPos);
|
|
876
|
-
if (peg$
|
|
847
|
+
if (s4 !== "" && !(peg$charCode = s4.charCodeAt(0), peg$charCode === 92 || peg$charCode === 123)) {
|
|
877
848
|
peg$currPos++;
|
|
878
849
|
} else {
|
|
879
850
|
s4 = peg$FAILED;
|
|
880
851
|
if (peg$silentFails === 0) { peg$fail(peg$e6); }
|
|
881
852
|
}
|
|
853
|
+
if (s4 === peg$FAILED) { break; }
|
|
854
|
+
s3.push(s4);
|
|
882
855
|
}
|
|
883
|
-
|
|
884
|
-
s3 = peg$FAILED;
|
|
885
|
-
}
|
|
886
|
-
if (s3 !== peg$FAILED) {
|
|
887
|
-
s2 = input.substring(s2, peg$currPos);
|
|
888
|
-
} else {
|
|
889
|
-
s2 = s3;
|
|
890
|
-
}
|
|
891
|
-
if (s2 === peg$FAILED) {
|
|
892
|
-
s2 = peg$currPos;
|
|
893
|
-
if (input.charCodeAt(peg$currPos) === 92) {
|
|
894
|
-
s3 = peg$c7;
|
|
895
|
-
peg$currPos++;
|
|
896
|
-
} else {
|
|
856
|
+
if (s3.length < 1) {
|
|
897
857
|
s3 = peg$FAILED;
|
|
898
|
-
if (peg$silentFails === 0) { peg$fail(peg$e7); }
|
|
899
858
|
}
|
|
900
859
|
if (s3 !== peg$FAILED) {
|
|
901
|
-
|
|
902
|
-
s4 = input.charAt(peg$currPos);
|
|
903
|
-
peg$currPos++;
|
|
904
|
-
} else {
|
|
905
|
-
s4 = peg$FAILED;
|
|
906
|
-
if (peg$silentFails === 0) { peg$fail(peg$e8); }
|
|
907
|
-
}
|
|
908
|
-
if (s4 !== peg$FAILED) {
|
|
909
|
-
s2 = peg$f4(s4);
|
|
910
|
-
} else {
|
|
911
|
-
peg$currPos = s2;
|
|
912
|
-
s2 = peg$FAILED;
|
|
913
|
-
}
|
|
860
|
+
s2 = input.substring(s2, peg$currPos);
|
|
914
861
|
} else {
|
|
915
|
-
|
|
916
|
-
s2 = peg$FAILED;
|
|
862
|
+
s2 = s3;
|
|
917
863
|
}
|
|
918
864
|
if (s2 === peg$FAILED) {
|
|
919
865
|
s2 = peg$currPos;
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
s4 = peg$c9;
|
|
866
|
+
if (input.charCodeAt(peg$currPos) === 92) {
|
|
867
|
+
s3 = peg$c7;
|
|
923
868
|
peg$currPos++;
|
|
924
869
|
} else {
|
|
925
|
-
|
|
926
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
870
|
+
s3 = peg$FAILED;
|
|
871
|
+
if (peg$silentFails === 0) { peg$fail(peg$e7); }
|
|
927
872
|
}
|
|
928
|
-
if (
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
if (input.charCodeAt(peg$currPos) === 123) {
|
|
932
|
-
s6 = peg$c9;
|
|
873
|
+
if (s3 !== peg$FAILED) {
|
|
874
|
+
if (input.length > peg$currPos) {
|
|
875
|
+
s4 = input.charAt(peg$currPos);
|
|
933
876
|
peg$currPos++;
|
|
934
877
|
} else {
|
|
935
|
-
|
|
936
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
937
|
-
}
|
|
938
|
-
peg$silentFails--;
|
|
939
|
-
if (s6 === peg$FAILED) {
|
|
940
|
-
s5 = undefined;
|
|
941
|
-
} else {
|
|
942
|
-
peg$currPos = s5;
|
|
943
|
-
s5 = peg$FAILED;
|
|
878
|
+
s4 = peg$FAILED;
|
|
879
|
+
if (peg$silentFails === 0) { peg$fail(peg$e8); }
|
|
944
880
|
}
|
|
945
|
-
if (
|
|
946
|
-
|
|
947
|
-
s3 = s4;
|
|
881
|
+
if (s4 !== peg$FAILED) {
|
|
882
|
+
s2 = peg$f4(s4);
|
|
948
883
|
} else {
|
|
949
|
-
peg$currPos =
|
|
950
|
-
|
|
951
|
-
}
|
|
952
|
-
} else {
|
|
953
|
-
peg$currPos = s3;
|
|
954
|
-
s3 = peg$FAILED;
|
|
955
|
-
}
|
|
956
|
-
if (s3 !== peg$FAILED) {
|
|
957
|
-
s2 = input.substring(s2, peg$currPos);
|
|
958
|
-
} else {
|
|
959
|
-
s2 = s3;
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
if (s2 !== peg$FAILED) {
|
|
964
|
-
while (s2 !== peg$FAILED) {
|
|
965
|
-
s1.push(s2);
|
|
966
|
-
s2 = peg$currPos;
|
|
967
|
-
s3 = [];
|
|
968
|
-
s4 = input.charAt(peg$currPos);
|
|
969
|
-
if (peg$r0.test(s4)) {
|
|
970
|
-
peg$currPos++;
|
|
971
|
-
} else {
|
|
972
|
-
s4 = peg$FAILED;
|
|
973
|
-
if (peg$silentFails === 0) { peg$fail(peg$e6); }
|
|
974
|
-
}
|
|
975
|
-
if (s4 !== peg$FAILED) {
|
|
976
|
-
while (s4 !== peg$FAILED) {
|
|
977
|
-
s3.push(s4);
|
|
978
|
-
s4 = input.charAt(peg$currPos);
|
|
979
|
-
if (peg$r0.test(s4)) {
|
|
980
|
-
peg$currPos++;
|
|
981
|
-
} else {
|
|
982
|
-
s4 = peg$FAILED;
|
|
983
|
-
if (peg$silentFails === 0) { peg$fail(peg$e6); }
|
|
984
|
-
}
|
|
884
|
+
peg$currPos = s2;
|
|
885
|
+
s2 = peg$FAILED;
|
|
985
886
|
}
|
|
986
887
|
} else {
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
if (s3 !== peg$FAILED) {
|
|
990
|
-
s2 = input.substring(s2, peg$currPos);
|
|
991
|
-
} else {
|
|
992
|
-
s2 = s3;
|
|
888
|
+
peg$currPos = s2;
|
|
889
|
+
s2 = peg$FAILED;
|
|
993
890
|
}
|
|
994
891
|
if (s2 === peg$FAILED) {
|
|
995
892
|
s2 = peg$currPos;
|
|
996
|
-
|
|
997
|
-
|
|
893
|
+
s3 = peg$currPos;
|
|
894
|
+
if (input.charCodeAt(peg$currPos) === 123) {
|
|
895
|
+
s4 = peg$c9;
|
|
998
896
|
peg$currPos++;
|
|
999
897
|
} else {
|
|
1000
|
-
|
|
1001
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
1002
|
-
}
|
|
1003
|
-
if (s3 !== peg$FAILED) {
|
|
1004
|
-
if (input.length > peg$currPos) {
|
|
1005
|
-
s4 = input.charAt(peg$currPos);
|
|
1006
|
-
peg$currPos++;
|
|
1007
|
-
} else {
|
|
1008
|
-
s4 = peg$FAILED;
|
|
1009
|
-
if (peg$silentFails === 0) { peg$fail(peg$e8); }
|
|
1010
|
-
}
|
|
1011
|
-
if (s4 !== peg$FAILED) {
|
|
1012
|
-
s2 = peg$f4(s4);
|
|
1013
|
-
} else {
|
|
1014
|
-
peg$currPos = s2;
|
|
1015
|
-
s2 = peg$FAILED;
|
|
1016
|
-
}
|
|
1017
|
-
} else {
|
|
1018
|
-
peg$currPos = s2;
|
|
1019
|
-
s2 = peg$FAILED;
|
|
898
|
+
s4 = peg$FAILED;
|
|
899
|
+
if (peg$silentFails === 0) { peg$fail(peg$e9); }
|
|
1020
900
|
}
|
|
1021
|
-
if (
|
|
1022
|
-
|
|
1023
|
-
|
|
901
|
+
if (s4 !== peg$FAILED) {
|
|
902
|
+
s5 = peg$currPos;
|
|
903
|
+
peg$silentFails++;
|
|
1024
904
|
if (input.charCodeAt(peg$currPos) === 123) {
|
|
1025
|
-
|
|
905
|
+
s6 = peg$c9;
|
|
1026
906
|
peg$currPos++;
|
|
1027
907
|
} else {
|
|
1028
|
-
|
|
908
|
+
s6 = peg$FAILED;
|
|
1029
909
|
if (peg$silentFails === 0) { peg$fail(peg$e9); }
|
|
1030
910
|
}
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
if (input.charCodeAt(peg$currPos) === 123) {
|
|
1035
|
-
s6 = peg$c9;
|
|
1036
|
-
peg$currPos++;
|
|
1037
|
-
} else {
|
|
1038
|
-
s6 = peg$FAILED;
|
|
1039
|
-
if (peg$silentFails === 0) { peg$fail(peg$e9); }
|
|
1040
|
-
}
|
|
1041
|
-
peg$silentFails--;
|
|
1042
|
-
if (s6 === peg$FAILED) {
|
|
1043
|
-
s5 = undefined;
|
|
1044
|
-
} else {
|
|
1045
|
-
peg$currPos = s5;
|
|
1046
|
-
s5 = peg$FAILED;
|
|
1047
|
-
}
|
|
1048
|
-
if (s5 !== peg$FAILED) {
|
|
1049
|
-
s4 = [s4, s5];
|
|
1050
|
-
s3 = s4;
|
|
1051
|
-
} else {
|
|
1052
|
-
peg$currPos = s3;
|
|
1053
|
-
s3 = peg$FAILED;
|
|
1054
|
-
}
|
|
911
|
+
peg$silentFails--;
|
|
912
|
+
if (s6 === peg$FAILED) {
|
|
913
|
+
s5 = undefined;
|
|
1055
914
|
} else {
|
|
1056
|
-
peg$currPos =
|
|
1057
|
-
|
|
915
|
+
peg$currPos = s5;
|
|
916
|
+
s5 = peg$FAILED;
|
|
1058
917
|
}
|
|
1059
|
-
if (
|
|
1060
|
-
|
|
918
|
+
if (s5 !== peg$FAILED) {
|
|
919
|
+
s4 = [s4, s5];
|
|
920
|
+
s3 = s4;
|
|
1061
921
|
} else {
|
|
1062
|
-
|
|
922
|
+
peg$currPos = s3;
|
|
923
|
+
s3 = peg$FAILED;
|
|
1063
924
|
}
|
|
925
|
+
} else {
|
|
926
|
+
peg$currPos = s3;
|
|
927
|
+
s3 = peg$FAILED;
|
|
928
|
+
}
|
|
929
|
+
if (s3 !== peg$FAILED) {
|
|
930
|
+
s2 = input.substring(s2, peg$currPos);
|
|
931
|
+
} else {
|
|
932
|
+
s2 = s3;
|
|
1064
933
|
}
|
|
1065
934
|
}
|
|
1066
935
|
}
|
|
1067
|
-
|
|
936
|
+
if (s2 === peg$FAILED) { break; }
|
|
937
|
+
s1.push(s2);
|
|
938
|
+
}
|
|
939
|
+
if (s1.length < 1) {
|
|
1068
940
|
s1 = peg$FAILED;
|
|
1069
941
|
}
|
|
1070
942
|
if (s1 !== peg$FAILED) {
|
|
@@ -1072,7 +944,7 @@ var ftl = (function (exports) {
|
|
|
1072
944
|
}
|
|
1073
945
|
s0 = s1;
|
|
1074
946
|
|
|
1075
|
-
peg$resultsCache
|
|
947
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1076
948
|
|
|
1077
949
|
return s0;
|
|
1078
950
|
}
|
|
@@ -1081,7 +953,7 @@ var ftl = (function (exports) {
|
|
|
1081
953
|
let s0, s2;
|
|
1082
954
|
|
|
1083
955
|
const key = peg$currPos * 38 + 9;
|
|
1084
|
-
const cached = peg$resultsCache
|
|
956
|
+
const cached = peg$resultsCache.get(key);
|
|
1085
957
|
|
|
1086
958
|
if (cached) {
|
|
1087
959
|
peg$currPos = cached.nextPos;
|
|
@@ -1100,7 +972,7 @@ var ftl = (function (exports) {
|
|
|
1100
972
|
s0 = peg$FAILED;
|
|
1101
973
|
}
|
|
1102
974
|
|
|
1103
|
-
peg$resultsCache
|
|
975
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1104
976
|
|
|
1105
977
|
return s0;
|
|
1106
978
|
}
|
|
@@ -1109,7 +981,7 @@ var ftl = (function (exports) {
|
|
|
1109
981
|
let s0, s1, s3, s5, s7, s9;
|
|
1110
982
|
|
|
1111
983
|
const key = peg$currPos * 38 + 10;
|
|
1112
|
-
const cached = peg$resultsCache
|
|
984
|
+
const cached = peg$resultsCache.get(key);
|
|
1113
985
|
|
|
1114
986
|
if (cached) {
|
|
1115
987
|
peg$currPos = cached.nextPos;
|
|
@@ -1169,7 +1041,7 @@ var ftl = (function (exports) {
|
|
|
1169
1041
|
s0 = peg$parseElvisExpression();
|
|
1170
1042
|
}
|
|
1171
1043
|
|
|
1172
|
-
peg$resultsCache
|
|
1044
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1173
1045
|
|
|
1174
1046
|
return s0;
|
|
1175
1047
|
}
|
|
@@ -1178,7 +1050,7 @@ var ftl = (function (exports) {
|
|
|
1178
1050
|
let s0, s1, s3, s5;
|
|
1179
1051
|
|
|
1180
1052
|
const key = peg$currPos * 38 + 11;
|
|
1181
|
-
const cached = peg$resultsCache
|
|
1053
|
+
const cached = peg$resultsCache.get(key);
|
|
1182
1054
|
|
|
1183
1055
|
if (cached) {
|
|
1184
1056
|
peg$currPos = cached.nextPos;
|
|
@@ -1218,7 +1090,7 @@ var ftl = (function (exports) {
|
|
|
1218
1090
|
s0 = peg$parseNullCoalescingExpression();
|
|
1219
1091
|
}
|
|
1220
1092
|
|
|
1221
|
-
peg$resultsCache
|
|
1093
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1222
1094
|
|
|
1223
1095
|
return s0;
|
|
1224
1096
|
}
|
|
@@ -1227,7 +1099,7 @@ var ftl = (function (exports) {
|
|
|
1227
1099
|
let s0, s1, s3, s5;
|
|
1228
1100
|
|
|
1229
1101
|
const key = peg$currPos * 38 + 12;
|
|
1230
|
-
const cached = peg$resultsCache
|
|
1102
|
+
const cached = peg$resultsCache.get(key);
|
|
1231
1103
|
|
|
1232
1104
|
if (cached) {
|
|
1233
1105
|
peg$currPos = cached.nextPos;
|
|
@@ -1267,7 +1139,7 @@ var ftl = (function (exports) {
|
|
|
1267
1139
|
s0 = peg$parseOrExpression();
|
|
1268
1140
|
}
|
|
1269
1141
|
|
|
1270
|
-
peg$resultsCache
|
|
1142
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1271
1143
|
|
|
1272
1144
|
return s0;
|
|
1273
1145
|
}
|
|
@@ -1276,7 +1148,7 @@ var ftl = (function (exports) {
|
|
|
1276
1148
|
let s0, s1, s2, s3, s5, s7;
|
|
1277
1149
|
|
|
1278
1150
|
const key = peg$currPos * 38 + 13;
|
|
1279
|
-
const cached = peg$resultsCache
|
|
1151
|
+
const cached = peg$resultsCache.get(key);
|
|
1280
1152
|
|
|
1281
1153
|
if (cached) {
|
|
1282
1154
|
peg$currPos = cached.nextPos;
|
|
@@ -1288,30 +1160,7 @@ var ftl = (function (exports) {
|
|
|
1288
1160
|
s1 = peg$parseAndExpression();
|
|
1289
1161
|
if (s1 !== peg$FAILED) {
|
|
1290
1162
|
s2 = [];
|
|
1291
|
-
|
|
1292
|
-
peg$parse_();
|
|
1293
|
-
if (input.substr(peg$currPos, 2) === peg$c22) {
|
|
1294
|
-
s5 = peg$c22;
|
|
1295
|
-
peg$currPos += 2;
|
|
1296
|
-
} else {
|
|
1297
|
-
s5 = peg$FAILED;
|
|
1298
|
-
if (peg$silentFails === 0) { peg$fail(peg$e14); }
|
|
1299
|
-
}
|
|
1300
|
-
if (s5 !== peg$FAILED) {
|
|
1301
|
-
peg$parse_();
|
|
1302
|
-
s7 = peg$parseAndExpression();
|
|
1303
|
-
if (s7 !== peg$FAILED) {
|
|
1304
|
-
s3 = s7;
|
|
1305
|
-
} else {
|
|
1306
|
-
peg$currPos = s3;
|
|
1307
|
-
s3 = peg$FAILED;
|
|
1308
|
-
}
|
|
1309
|
-
} else {
|
|
1310
|
-
peg$currPos = s3;
|
|
1311
|
-
s3 = peg$FAILED;
|
|
1312
|
-
}
|
|
1313
|
-
while (s3 !== peg$FAILED) {
|
|
1314
|
-
s2.push(s3);
|
|
1163
|
+
for (;;) {
|
|
1315
1164
|
s3 = peg$currPos;
|
|
1316
1165
|
peg$parse_();
|
|
1317
1166
|
if (input.substr(peg$currPos, 2) === peg$c22) {
|
|
@@ -1334,6 +1183,8 @@ var ftl = (function (exports) {
|
|
|
1334
1183
|
peg$currPos = s3;
|
|
1335
1184
|
s3 = peg$FAILED;
|
|
1336
1185
|
}
|
|
1186
|
+
if (s3 === peg$FAILED) { break; }
|
|
1187
|
+
s2.push(s3);
|
|
1337
1188
|
}
|
|
1338
1189
|
s0 = peg$f10(s1, s2);
|
|
1339
1190
|
} else {
|
|
@@ -1341,7 +1192,7 @@ var ftl = (function (exports) {
|
|
|
1341
1192
|
s0 = peg$FAILED;
|
|
1342
1193
|
}
|
|
1343
1194
|
|
|
1344
|
-
peg$resultsCache
|
|
1195
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1345
1196
|
|
|
1346
1197
|
return s0;
|
|
1347
1198
|
}
|
|
@@ -1350,7 +1201,7 @@ var ftl = (function (exports) {
|
|
|
1350
1201
|
let s0, s1, s2, s3, s5, s7;
|
|
1351
1202
|
|
|
1352
1203
|
const key = peg$currPos * 38 + 14;
|
|
1353
|
-
const cached = peg$resultsCache
|
|
1204
|
+
const cached = peg$resultsCache.get(key);
|
|
1354
1205
|
|
|
1355
1206
|
if (cached) {
|
|
1356
1207
|
peg$currPos = cached.nextPos;
|
|
@@ -1362,30 +1213,7 @@ var ftl = (function (exports) {
|
|
|
1362
1213
|
s1 = peg$parseEqExpression();
|
|
1363
1214
|
if (s1 !== peg$FAILED) {
|
|
1364
1215
|
s2 = [];
|
|
1365
|
-
|
|
1366
|
-
peg$parse_();
|
|
1367
|
-
if (input.substr(peg$currPos, 2) === peg$c24) {
|
|
1368
|
-
s5 = peg$c24;
|
|
1369
|
-
peg$currPos += 2;
|
|
1370
|
-
} else {
|
|
1371
|
-
s5 = peg$FAILED;
|
|
1372
|
-
if (peg$silentFails === 0) { peg$fail(peg$e15); }
|
|
1373
|
-
}
|
|
1374
|
-
if (s5 !== peg$FAILED) {
|
|
1375
|
-
peg$parse_();
|
|
1376
|
-
s7 = peg$parseEqExpression();
|
|
1377
|
-
if (s7 !== peg$FAILED) {
|
|
1378
|
-
s3 = s7;
|
|
1379
|
-
} else {
|
|
1380
|
-
peg$currPos = s3;
|
|
1381
|
-
s3 = peg$FAILED;
|
|
1382
|
-
}
|
|
1383
|
-
} else {
|
|
1384
|
-
peg$currPos = s3;
|
|
1385
|
-
s3 = peg$FAILED;
|
|
1386
|
-
}
|
|
1387
|
-
while (s3 !== peg$FAILED) {
|
|
1388
|
-
s2.push(s3);
|
|
1216
|
+
for (;;) {
|
|
1389
1217
|
s3 = peg$currPos;
|
|
1390
1218
|
peg$parse_();
|
|
1391
1219
|
if (input.substr(peg$currPos, 2) === peg$c24) {
|
|
@@ -1408,6 +1236,8 @@ var ftl = (function (exports) {
|
|
|
1408
1236
|
peg$currPos = s3;
|
|
1409
1237
|
s3 = peg$FAILED;
|
|
1410
1238
|
}
|
|
1239
|
+
if (s3 === peg$FAILED) { break; }
|
|
1240
|
+
s2.push(s3);
|
|
1411
1241
|
}
|
|
1412
1242
|
s0 = peg$f11(s1, s2);
|
|
1413
1243
|
} else {
|
|
@@ -1415,7 +1245,7 @@ var ftl = (function (exports) {
|
|
|
1415
1245
|
s0 = peg$FAILED;
|
|
1416
1246
|
}
|
|
1417
1247
|
|
|
1418
|
-
peg$resultsCache
|
|
1248
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1419
1249
|
|
|
1420
1250
|
return s0;
|
|
1421
1251
|
}
|
|
@@ -1424,7 +1254,7 @@ var ftl = (function (exports) {
|
|
|
1424
1254
|
let s0, s1, s2, s3, s5, s7;
|
|
1425
1255
|
|
|
1426
1256
|
const key = peg$currPos * 38 + 15;
|
|
1427
|
-
const cached = peg$resultsCache
|
|
1257
|
+
const cached = peg$resultsCache.get(key);
|
|
1428
1258
|
|
|
1429
1259
|
if (cached) {
|
|
1430
1260
|
peg$currPos = cached.nextPos;
|
|
@@ -1436,24 +1266,7 @@ var ftl = (function (exports) {
|
|
|
1436
1266
|
s1 = peg$parseRelExpression();
|
|
1437
1267
|
if (s1 !== peg$FAILED) {
|
|
1438
1268
|
s2 = [];
|
|
1439
|
-
|
|
1440
|
-
peg$parse_();
|
|
1441
|
-
s5 = peg$parseEqualityOp();
|
|
1442
|
-
if (s5 !== peg$FAILED) {
|
|
1443
|
-
peg$parse_();
|
|
1444
|
-
s7 = peg$parseRelExpression();
|
|
1445
|
-
if (s7 !== peg$FAILED) {
|
|
1446
|
-
s3 = peg$f12(s1, s5, s7);
|
|
1447
|
-
} else {
|
|
1448
|
-
peg$currPos = s3;
|
|
1449
|
-
s3 = peg$FAILED;
|
|
1450
|
-
}
|
|
1451
|
-
} else {
|
|
1452
|
-
peg$currPos = s3;
|
|
1453
|
-
s3 = peg$FAILED;
|
|
1454
|
-
}
|
|
1455
|
-
while (s3 !== peg$FAILED) {
|
|
1456
|
-
s2.push(s3);
|
|
1269
|
+
for (;;) {
|
|
1457
1270
|
s3 = peg$currPos;
|
|
1458
1271
|
peg$parse_();
|
|
1459
1272
|
s5 = peg$parseEqualityOp();
|
|
@@ -1470,6 +1283,8 @@ var ftl = (function (exports) {
|
|
|
1470
1283
|
peg$currPos = s3;
|
|
1471
1284
|
s3 = peg$FAILED;
|
|
1472
1285
|
}
|
|
1286
|
+
if (s3 === peg$FAILED) { break; }
|
|
1287
|
+
s2.push(s3);
|
|
1473
1288
|
}
|
|
1474
1289
|
s0 = peg$f13(s1, s2);
|
|
1475
1290
|
} else {
|
|
@@ -1477,7 +1292,7 @@ var ftl = (function (exports) {
|
|
|
1477
1292
|
s0 = peg$FAILED;
|
|
1478
1293
|
}
|
|
1479
1294
|
|
|
1480
|
-
peg$resultsCache
|
|
1295
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1481
1296
|
|
|
1482
1297
|
return s0;
|
|
1483
1298
|
}
|
|
@@ -1486,7 +1301,7 @@ var ftl = (function (exports) {
|
|
|
1486
1301
|
let s0, s1, s2, s3, s5, s7;
|
|
1487
1302
|
|
|
1488
1303
|
const key = peg$currPos * 38 + 16;
|
|
1489
|
-
const cached = peg$resultsCache
|
|
1304
|
+
const cached = peg$resultsCache.get(key);
|
|
1490
1305
|
|
|
1491
1306
|
if (cached) {
|
|
1492
1307
|
peg$currPos = cached.nextPos;
|
|
@@ -1498,24 +1313,7 @@ var ftl = (function (exports) {
|
|
|
1498
1313
|
s1 = peg$parseNotExpression();
|
|
1499
1314
|
if (s1 !== peg$FAILED) {
|
|
1500
1315
|
s2 = [];
|
|
1501
|
-
|
|
1502
|
-
peg$parse_();
|
|
1503
|
-
s5 = peg$parseRelationalOp();
|
|
1504
|
-
if (s5 !== peg$FAILED) {
|
|
1505
|
-
peg$parse_();
|
|
1506
|
-
s7 = peg$parseNotExpression();
|
|
1507
|
-
if (s7 !== peg$FAILED) {
|
|
1508
|
-
s3 = peg$f14(s1, s5, s7);
|
|
1509
|
-
} else {
|
|
1510
|
-
peg$currPos = s3;
|
|
1511
|
-
s3 = peg$FAILED;
|
|
1512
|
-
}
|
|
1513
|
-
} else {
|
|
1514
|
-
peg$currPos = s3;
|
|
1515
|
-
s3 = peg$FAILED;
|
|
1516
|
-
}
|
|
1517
|
-
while (s3 !== peg$FAILED) {
|
|
1518
|
-
s2.push(s3);
|
|
1316
|
+
for (;;) {
|
|
1519
1317
|
s3 = peg$currPos;
|
|
1520
1318
|
peg$parse_();
|
|
1521
1319
|
s5 = peg$parseRelationalOp();
|
|
@@ -1532,6 +1330,8 @@ var ftl = (function (exports) {
|
|
|
1532
1330
|
peg$currPos = s3;
|
|
1533
1331
|
s3 = peg$FAILED;
|
|
1534
1332
|
}
|
|
1333
|
+
if (s3 === peg$FAILED) { break; }
|
|
1334
|
+
s2.push(s3);
|
|
1535
1335
|
}
|
|
1536
1336
|
s0 = peg$f15(s1, s2);
|
|
1537
1337
|
} else {
|
|
@@ -1539,7 +1339,7 @@ var ftl = (function (exports) {
|
|
|
1539
1339
|
s0 = peg$FAILED;
|
|
1540
1340
|
}
|
|
1541
1341
|
|
|
1542
|
-
peg$resultsCache
|
|
1342
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1543
1343
|
|
|
1544
1344
|
return s0;
|
|
1545
1345
|
}
|
|
@@ -1548,7 +1348,7 @@ var ftl = (function (exports) {
|
|
|
1548
1348
|
let s0, s1, s3;
|
|
1549
1349
|
|
|
1550
1350
|
const key = peg$currPos * 38 + 17;
|
|
1551
|
-
const cached = peg$resultsCache
|
|
1351
|
+
const cached = peg$resultsCache.get(key);
|
|
1552
1352
|
|
|
1553
1353
|
if (cached) {
|
|
1554
1354
|
peg$currPos = cached.nextPos;
|
|
@@ -1581,7 +1381,7 @@ var ftl = (function (exports) {
|
|
|
1581
1381
|
s0 = peg$parseAccess();
|
|
1582
1382
|
}
|
|
1583
1383
|
|
|
1584
|
-
peg$resultsCache
|
|
1384
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1585
1385
|
|
|
1586
1386
|
return s0;
|
|
1587
1387
|
}
|
|
@@ -1590,7 +1390,7 @@ var ftl = (function (exports) {
|
|
|
1590
1390
|
let s0, s1, s3, s4, s5;
|
|
1591
1391
|
|
|
1592
1392
|
const key = peg$currPos * 38 + 18;
|
|
1593
|
-
const cached = peg$resultsCache
|
|
1393
|
+
const cached = peg$resultsCache.get(key);
|
|
1594
1394
|
|
|
1595
1395
|
if (cached) {
|
|
1596
1396
|
peg$currPos = cached.nextPos;
|
|
@@ -1603,29 +1403,20 @@ var ftl = (function (exports) {
|
|
|
1603
1403
|
if (s1 !== peg$FAILED) {
|
|
1604
1404
|
peg$parse_();
|
|
1605
1405
|
s3 = [];
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
peg$
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
if (s4 !== peg$FAILED) {
|
|
1616
|
-
while (s4 !== peg$FAILED) {
|
|
1617
|
-
s3.push(s4);
|
|
1618
|
-
s4 = peg$currPos;
|
|
1619
|
-
s5 = peg$parseAccessExpression();
|
|
1620
|
-
if (s5 !== peg$FAILED) {
|
|
1621
|
-
peg$parse_();
|
|
1622
|
-
s4 = s5;
|
|
1623
|
-
} else {
|
|
1624
|
-
peg$currPos = s4;
|
|
1625
|
-
s4 = peg$FAILED;
|
|
1626
|
-
}
|
|
1406
|
+
for (;;) {
|
|
1407
|
+
s4 = peg$currPos;
|
|
1408
|
+
s5 = peg$parseAccessExpression();
|
|
1409
|
+
if (s5 !== peg$FAILED) {
|
|
1410
|
+
peg$parse_();
|
|
1411
|
+
s4 = s5;
|
|
1412
|
+
} else {
|
|
1413
|
+
peg$currPos = s4;
|
|
1414
|
+
s4 = peg$FAILED;
|
|
1627
1415
|
}
|
|
1628
|
-
|
|
1416
|
+
if (s4 === peg$FAILED) { break; }
|
|
1417
|
+
s3.push(s4);
|
|
1418
|
+
}
|
|
1419
|
+
if (s3.length < 1) {
|
|
1629
1420
|
s3 = peg$FAILED;
|
|
1630
1421
|
}
|
|
1631
1422
|
if (s3 !== peg$FAILED) {
|
|
@@ -1642,7 +1433,7 @@ var ftl = (function (exports) {
|
|
|
1642
1433
|
s0 = peg$parseGroupingExpression();
|
|
1643
1434
|
}
|
|
1644
1435
|
|
|
1645
|
-
peg$resultsCache
|
|
1436
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1646
1437
|
|
|
1647
1438
|
return s0;
|
|
1648
1439
|
}
|
|
@@ -1651,7 +1442,7 @@ var ftl = (function (exports) {
|
|
|
1651
1442
|
let s0;
|
|
1652
1443
|
|
|
1653
1444
|
const key = peg$currPos * 38 + 19;
|
|
1654
|
-
const cached = peg$resultsCache
|
|
1445
|
+
const cached = peg$resultsCache.get(key);
|
|
1655
1446
|
|
|
1656
1447
|
if (cached) {
|
|
1657
1448
|
peg$currPos = cached.nextPos;
|
|
@@ -1667,7 +1458,7 @@ var ftl = (function (exports) {
|
|
|
1667
1458
|
}
|
|
1668
1459
|
}
|
|
1669
1460
|
|
|
1670
|
-
peg$resultsCache
|
|
1461
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1671
1462
|
|
|
1672
1463
|
return s0;
|
|
1673
1464
|
}
|
|
@@ -1676,7 +1467,7 @@ var ftl = (function (exports) {
|
|
|
1676
1467
|
let s0, s1, s3;
|
|
1677
1468
|
|
|
1678
1469
|
const key = peg$currPos * 38 + 20;
|
|
1679
|
-
const cached = peg$resultsCache
|
|
1470
|
+
const cached = peg$resultsCache.get(key);
|
|
1680
1471
|
|
|
1681
1472
|
if (cached) {
|
|
1682
1473
|
peg$currPos = cached.nextPos;
|
|
@@ -1721,7 +1512,7 @@ var ftl = (function (exports) {
|
|
|
1721
1512
|
if (peg$silentFails === 0) { peg$fail(peg$e17); }
|
|
1722
1513
|
}
|
|
1723
1514
|
|
|
1724
|
-
peg$resultsCache
|
|
1515
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1725
1516
|
|
|
1726
1517
|
return s0;
|
|
1727
1518
|
}
|
|
@@ -1730,7 +1521,7 @@ var ftl = (function (exports) {
|
|
|
1730
1521
|
let s0, s1, s2, s4, s6;
|
|
1731
1522
|
|
|
1732
1523
|
const key = peg$currPos * 38 + 21;
|
|
1733
|
-
const cached = peg$resultsCache
|
|
1524
|
+
const cached = peg$resultsCache.get(key);
|
|
1734
1525
|
|
|
1735
1526
|
if (cached) {
|
|
1736
1527
|
peg$currPos = cached.nextPos;
|
|
@@ -1789,7 +1580,7 @@ var ftl = (function (exports) {
|
|
|
1789
1580
|
if (peg$silentFails === 0) { peg$fail(peg$e20); }
|
|
1790
1581
|
}
|
|
1791
1582
|
|
|
1792
|
-
peg$resultsCache
|
|
1583
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1793
1584
|
|
|
1794
1585
|
return s0;
|
|
1795
1586
|
}
|
|
@@ -1798,7 +1589,7 @@ var ftl = (function (exports) {
|
|
|
1798
1589
|
let s0, s1, s2, s4, s5, s6, s7, s9;
|
|
1799
1590
|
|
|
1800
1591
|
const key = peg$currPos * 38 + 22;
|
|
1801
|
-
const cached = peg$resultsCache
|
|
1592
|
+
const cached = peg$resultsCache.get(key);
|
|
1802
1593
|
|
|
1803
1594
|
if (cached) {
|
|
1804
1595
|
peg$currPos = cached.nextPos;
|
|
@@ -1840,30 +1631,7 @@ var ftl = (function (exports) {
|
|
|
1840
1631
|
s4 = null;
|
|
1841
1632
|
}
|
|
1842
1633
|
s5 = [];
|
|
1843
|
-
|
|
1844
|
-
if (input.charCodeAt(peg$currPos) === 44) {
|
|
1845
|
-
s7 = peg$c34;
|
|
1846
|
-
peg$currPos++;
|
|
1847
|
-
} else {
|
|
1848
|
-
s7 = peg$FAILED;
|
|
1849
|
-
if (peg$silentFails === 0) { peg$fail(peg$e25); }
|
|
1850
|
-
}
|
|
1851
|
-
if (s7 !== peg$FAILED) {
|
|
1852
|
-
peg$parse_();
|
|
1853
|
-
s9 = peg$parseTernaryExpression();
|
|
1854
|
-
if (s9 !== peg$FAILED) {
|
|
1855
|
-
peg$parse_();
|
|
1856
|
-
s6 = s9;
|
|
1857
|
-
} else {
|
|
1858
|
-
peg$currPos = s6;
|
|
1859
|
-
s6 = peg$FAILED;
|
|
1860
|
-
}
|
|
1861
|
-
} else {
|
|
1862
|
-
peg$currPos = s6;
|
|
1863
|
-
s6 = peg$FAILED;
|
|
1864
|
-
}
|
|
1865
|
-
while (s6 !== peg$FAILED) {
|
|
1866
|
-
s5.push(s6);
|
|
1634
|
+
for (;;) {
|
|
1867
1635
|
s6 = peg$currPos;
|
|
1868
1636
|
if (input.charCodeAt(peg$currPos) === 44) {
|
|
1869
1637
|
s7 = peg$c34;
|
|
@@ -1886,6 +1654,8 @@ var ftl = (function (exports) {
|
|
|
1886
1654
|
peg$currPos = s6;
|
|
1887
1655
|
s6 = peg$FAILED;
|
|
1888
1656
|
}
|
|
1657
|
+
if (s6 === peg$FAILED) { break; }
|
|
1658
|
+
s5.push(s6);
|
|
1889
1659
|
}
|
|
1890
1660
|
if (input.charCodeAt(peg$currPos) === 41) {
|
|
1891
1661
|
s6 = peg$c36;
|
|
@@ -1910,7 +1680,7 @@ var ftl = (function (exports) {
|
|
|
1910
1680
|
if (peg$silentFails === 0) { peg$fail(peg$e23); }
|
|
1911
1681
|
}
|
|
1912
1682
|
|
|
1913
|
-
peg$resultsCache
|
|
1683
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1914
1684
|
|
|
1915
1685
|
return s0;
|
|
1916
1686
|
}
|
|
@@ -1919,7 +1689,7 @@ var ftl = (function (exports) {
|
|
|
1919
1689
|
let s0, s1, s3, s5;
|
|
1920
1690
|
|
|
1921
1691
|
const key = peg$currPos * 38 + 23;
|
|
1922
|
-
const cached = peg$resultsCache
|
|
1692
|
+
const cached = peg$resultsCache.get(key);
|
|
1923
1693
|
|
|
1924
1694
|
if (cached) {
|
|
1925
1695
|
peg$currPos = cached.nextPos;
|
|
@@ -1971,7 +1741,7 @@ var ftl = (function (exports) {
|
|
|
1971
1741
|
}
|
|
1972
1742
|
}
|
|
1973
1743
|
|
|
1974
|
-
peg$resultsCache
|
|
1744
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
1975
1745
|
|
|
1976
1746
|
return s0;
|
|
1977
1747
|
}
|
|
@@ -1980,7 +1750,7 @@ var ftl = (function (exports) {
|
|
|
1980
1750
|
let s0, s1, s2, s4, s5, s6, s7, s9;
|
|
1981
1751
|
|
|
1982
1752
|
const key = peg$currPos * 38 + 24;
|
|
1983
|
-
const cached = peg$resultsCache
|
|
1753
|
+
const cached = peg$resultsCache.get(key);
|
|
1984
1754
|
|
|
1985
1755
|
if (cached) {
|
|
1986
1756
|
peg$currPos = cached.nextPos;
|
|
@@ -2014,30 +1784,7 @@ var ftl = (function (exports) {
|
|
|
2014
1784
|
s4 = null;
|
|
2015
1785
|
}
|
|
2016
1786
|
s5 = [];
|
|
2017
|
-
|
|
2018
|
-
if (input.charCodeAt(peg$currPos) === 44) {
|
|
2019
|
-
s7 = peg$c34;
|
|
2020
|
-
peg$currPos++;
|
|
2021
|
-
} else {
|
|
2022
|
-
s7 = peg$FAILED;
|
|
2023
|
-
if (peg$silentFails === 0) { peg$fail(peg$e25); }
|
|
2024
|
-
}
|
|
2025
|
-
if (s7 !== peg$FAILED) {
|
|
2026
|
-
peg$parse_();
|
|
2027
|
-
s9 = peg$parseTernaryExpression();
|
|
2028
|
-
if (s9 !== peg$FAILED) {
|
|
2029
|
-
peg$parse_();
|
|
2030
|
-
s6 = s9;
|
|
2031
|
-
} else {
|
|
2032
|
-
peg$currPos = s6;
|
|
2033
|
-
s6 = peg$FAILED;
|
|
2034
|
-
}
|
|
2035
|
-
} else {
|
|
2036
|
-
peg$currPos = s6;
|
|
2037
|
-
s6 = peg$FAILED;
|
|
2038
|
-
}
|
|
2039
|
-
while (s6 !== peg$FAILED) {
|
|
2040
|
-
s5.push(s6);
|
|
1787
|
+
for (;;) {
|
|
2041
1788
|
s6 = peg$currPos;
|
|
2042
1789
|
if (input.charCodeAt(peg$currPos) === 44) {
|
|
2043
1790
|
s7 = peg$c34;
|
|
@@ -2060,6 +1807,8 @@ var ftl = (function (exports) {
|
|
|
2060
1807
|
peg$currPos = s6;
|
|
2061
1808
|
s6 = peg$FAILED;
|
|
2062
1809
|
}
|
|
1810
|
+
if (s6 === peg$FAILED) { break; }
|
|
1811
|
+
s5.push(s6);
|
|
2063
1812
|
}
|
|
2064
1813
|
if (input.charCodeAt(peg$currPos) === 41) {
|
|
2065
1814
|
s6 = peg$c36;
|
|
@@ -2088,7 +1837,7 @@ var ftl = (function (exports) {
|
|
|
2088
1837
|
if (peg$silentFails === 0) { peg$fail(peg$e27); }
|
|
2089
1838
|
}
|
|
2090
1839
|
|
|
2091
|
-
peg$resultsCache
|
|
1840
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
2092
1841
|
|
|
2093
1842
|
return s0;
|
|
2094
1843
|
}
|
|
@@ -2097,7 +1846,7 @@ var ftl = (function (exports) {
|
|
|
2097
1846
|
let s0;
|
|
2098
1847
|
|
|
2099
1848
|
const key = peg$currPos * 38 + 25;
|
|
2100
|
-
const cached = peg$resultsCache
|
|
1849
|
+
const cached = peg$resultsCache.get(key);
|
|
2101
1850
|
|
|
2102
1851
|
if (cached) {
|
|
2103
1852
|
peg$currPos = cached.nextPos;
|
|
@@ -2116,7 +1865,7 @@ var ftl = (function (exports) {
|
|
|
2116
1865
|
}
|
|
2117
1866
|
}
|
|
2118
1867
|
|
|
2119
|
-
peg$resultsCache
|
|
1868
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
2120
1869
|
|
|
2121
1870
|
return s0;
|
|
2122
1871
|
}
|
|
@@ -2125,7 +1874,7 @@ var ftl = (function (exports) {
|
|
|
2125
1874
|
let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
|
|
2126
1875
|
|
|
2127
1876
|
const key = peg$currPos * 38 + 26;
|
|
2128
|
-
const cached = peg$resultsCache
|
|
1877
|
+
const cached = peg$resultsCache.get(key);
|
|
2129
1878
|
|
|
2130
1879
|
if (cached) {
|
|
2131
1880
|
peg$currPos = cached.nextPos;
|
|
@@ -2149,25 +1898,18 @@ var ftl = (function (exports) {
|
|
|
2149
1898
|
}
|
|
2150
1899
|
s4 = peg$currPos;
|
|
2151
1900
|
s5 = [];
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
peg$
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
if (s6 !== peg$FAILED) {
|
|
2160
|
-
while (s6 !== peg$FAILED) {
|
|
2161
|
-
s5.push(s6);
|
|
2162
|
-
s6 = input.charAt(peg$currPos);
|
|
2163
|
-
if (peg$r1.test(s6)) {
|
|
2164
|
-
peg$currPos++;
|
|
2165
|
-
} else {
|
|
2166
|
-
s6 = peg$FAILED;
|
|
2167
|
-
if (peg$silentFails === 0) { peg$fail(peg$e30); }
|
|
2168
|
-
}
|
|
1901
|
+
for (;;) {
|
|
1902
|
+
s6 = input.charAt(peg$currPos);
|
|
1903
|
+
if ((peg$charCode = s6.charCodeAt(0), (peg$charCode >= 48 && peg$charCode <= 57))) {
|
|
1904
|
+
peg$currPos++;
|
|
1905
|
+
} else {
|
|
1906
|
+
s6 = peg$FAILED;
|
|
1907
|
+
if (peg$silentFails === 0) { peg$fail(peg$e30); }
|
|
2169
1908
|
}
|
|
2170
|
-
|
|
1909
|
+
if (s6 === peg$FAILED) { break; }
|
|
1910
|
+
s5.push(s6);
|
|
1911
|
+
}
|
|
1912
|
+
if (s5.length < 1) {
|
|
2171
1913
|
s5 = peg$FAILED;
|
|
2172
1914
|
}
|
|
2173
1915
|
if (s5 !== peg$FAILED) {
|
|
@@ -2181,22 +1923,16 @@ var ftl = (function (exports) {
|
|
|
2181
1923
|
}
|
|
2182
1924
|
if (s7 !== peg$FAILED) {
|
|
2183
1925
|
s8 = [];
|
|
2184
|
-
|
|
2185
|
-
if (peg$r1.test(s9)) {
|
|
2186
|
-
peg$currPos++;
|
|
2187
|
-
} else {
|
|
2188
|
-
s9 = peg$FAILED;
|
|
2189
|
-
if (peg$silentFails === 0) { peg$fail(peg$e30); }
|
|
2190
|
-
}
|
|
2191
|
-
while (s9 !== peg$FAILED) {
|
|
2192
|
-
s8.push(s9);
|
|
1926
|
+
for (;;) {
|
|
2193
1927
|
s9 = input.charAt(peg$currPos);
|
|
2194
|
-
if (peg$
|
|
1928
|
+
if ((peg$charCode = s9.charCodeAt(0), (peg$charCode >= 48 && peg$charCode <= 57))) {
|
|
2195
1929
|
peg$currPos++;
|
|
2196
1930
|
} else {
|
|
2197
1931
|
s9 = peg$FAILED;
|
|
2198
1932
|
if (peg$silentFails === 0) { peg$fail(peg$e30); }
|
|
2199
1933
|
}
|
|
1934
|
+
if (s9 === peg$FAILED) { break; }
|
|
1935
|
+
s8.push(s9);
|
|
2200
1936
|
}
|
|
2201
1937
|
s7 = [s7, s8];
|
|
2202
1938
|
s6 = s7;
|
|
@@ -2224,25 +1960,18 @@ var ftl = (function (exports) {
|
|
|
2224
1960
|
}
|
|
2225
1961
|
if (s5 !== peg$FAILED) {
|
|
2226
1962
|
s6 = [];
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
peg$
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
if (s7 !== peg$FAILED) {
|
|
2235
|
-
while (s7 !== peg$FAILED) {
|
|
2236
|
-
s6.push(s7);
|
|
2237
|
-
s7 = input.charAt(peg$currPos);
|
|
2238
|
-
if (peg$r1.test(s7)) {
|
|
2239
|
-
peg$currPos++;
|
|
2240
|
-
} else {
|
|
2241
|
-
s7 = peg$FAILED;
|
|
2242
|
-
if (peg$silentFails === 0) { peg$fail(peg$e30); }
|
|
2243
|
-
}
|
|
1963
|
+
for (;;) {
|
|
1964
|
+
s7 = input.charAt(peg$currPos);
|
|
1965
|
+
if ((peg$charCode = s7.charCodeAt(0), (peg$charCode >= 48 && peg$charCode <= 57))) {
|
|
1966
|
+
peg$currPos++;
|
|
1967
|
+
} else {
|
|
1968
|
+
s7 = peg$FAILED;
|
|
1969
|
+
if (peg$silentFails === 0) { peg$fail(peg$e30); }
|
|
2244
1970
|
}
|
|
2245
|
-
|
|
1971
|
+
if (s7 === peg$FAILED) { break; }
|
|
1972
|
+
s6.push(s7);
|
|
1973
|
+
}
|
|
1974
|
+
if (s6.length < 1) {
|
|
2246
1975
|
s6 = peg$FAILED;
|
|
2247
1976
|
}
|
|
2248
1977
|
if (s6 !== peg$FAILED) {
|
|
@@ -2279,7 +2008,7 @@ var ftl = (function (exports) {
|
|
|
2279
2008
|
if (peg$silentFails === 0) { peg$fail(peg$e28); }
|
|
2280
2009
|
}
|
|
2281
2010
|
|
|
2282
|
-
peg$resultsCache
|
|
2011
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
2283
2012
|
|
|
2284
2013
|
return s0;
|
|
2285
2014
|
}
|
|
@@ -2288,7 +2017,7 @@ var ftl = (function (exports) {
|
|
|
2288
2017
|
let s0, s1, s2, s3, s4;
|
|
2289
2018
|
|
|
2290
2019
|
const key = peg$currPos * 38 + 27;
|
|
2291
|
-
const cached = peg$resultsCache
|
|
2020
|
+
const cached = peg$resultsCache.get(key);
|
|
2292
2021
|
|
|
2293
2022
|
if (cached) {
|
|
2294
2023
|
peg$currPos = cached.nextPos;
|
|
@@ -2308,22 +2037,16 @@ var ftl = (function (exports) {
|
|
|
2308
2037
|
if (s1 !== peg$FAILED) {
|
|
2309
2038
|
s2 = peg$currPos;
|
|
2310
2039
|
s3 = [];
|
|
2311
|
-
|
|
2312
|
-
if (peg$r2.test(s4)) {
|
|
2313
|
-
peg$currPos++;
|
|
2314
|
-
} else {
|
|
2315
|
-
s4 = peg$FAILED;
|
|
2316
|
-
if (peg$silentFails === 0) { peg$fail(peg$e33); }
|
|
2317
|
-
}
|
|
2318
|
-
while (s4 !== peg$FAILED) {
|
|
2319
|
-
s3.push(s4);
|
|
2040
|
+
for (;;) {
|
|
2320
2041
|
s4 = input.charAt(peg$currPos);
|
|
2321
|
-
if (peg$
|
|
2042
|
+
if (s4 !== "" && !(peg$charCode = s4.charCodeAt(0), peg$charCode === 39)) {
|
|
2322
2043
|
peg$currPos++;
|
|
2323
2044
|
} else {
|
|
2324
2045
|
s4 = peg$FAILED;
|
|
2325
2046
|
if (peg$silentFails === 0) { peg$fail(peg$e33); }
|
|
2326
2047
|
}
|
|
2048
|
+
if (s4 === peg$FAILED) { break; }
|
|
2049
|
+
s3.push(s4);
|
|
2327
2050
|
}
|
|
2328
2051
|
s2 = input.substring(s2, peg$currPos);
|
|
2329
2052
|
if (input.charCodeAt(peg$currPos) === 39) {
|
|
@@ -2355,22 +2078,16 @@ var ftl = (function (exports) {
|
|
|
2355
2078
|
if (s1 !== peg$FAILED) {
|
|
2356
2079
|
s2 = peg$currPos;
|
|
2357
2080
|
s3 = [];
|
|
2358
|
-
|
|
2359
|
-
if (peg$r3.test(s4)) {
|
|
2360
|
-
peg$currPos++;
|
|
2361
|
-
} else {
|
|
2362
|
-
s4 = peg$FAILED;
|
|
2363
|
-
if (peg$silentFails === 0) { peg$fail(peg$e35); }
|
|
2364
|
-
}
|
|
2365
|
-
while (s4 !== peg$FAILED) {
|
|
2366
|
-
s3.push(s4);
|
|
2081
|
+
for (;;) {
|
|
2367
2082
|
s4 = input.charAt(peg$currPos);
|
|
2368
|
-
if (peg$
|
|
2083
|
+
if (s4 !== "" && !(peg$charCode = s4.charCodeAt(0), peg$charCode === 34)) {
|
|
2369
2084
|
peg$currPos++;
|
|
2370
2085
|
} else {
|
|
2371
2086
|
s4 = peg$FAILED;
|
|
2372
2087
|
if (peg$silentFails === 0) { peg$fail(peg$e35); }
|
|
2373
2088
|
}
|
|
2089
|
+
if (s4 === peg$FAILED) { break; }
|
|
2090
|
+
s3.push(s4);
|
|
2374
2091
|
}
|
|
2375
2092
|
s2 = input.substring(s2, peg$currPos);
|
|
2376
2093
|
if (input.charCodeAt(peg$currPos) === 34) {
|
|
@@ -2401,16 +2118,13 @@ var ftl = (function (exports) {
|
|
|
2401
2118
|
}
|
|
2402
2119
|
if (s1 !== peg$FAILED) {
|
|
2403
2120
|
s2 = [];
|
|
2404
|
-
|
|
2405
|
-
if (s3 === peg$FAILED) {
|
|
2406
|
-
s3 = peg$parseTemplateStringLiteral();
|
|
2407
|
-
}
|
|
2408
|
-
while (s3 !== peg$FAILED) {
|
|
2409
|
-
s2.push(s3);
|
|
2121
|
+
for (;;) {
|
|
2410
2122
|
s3 = peg$parseTemplateStringExpression();
|
|
2411
2123
|
if (s3 === peg$FAILED) {
|
|
2412
2124
|
s3 = peg$parseTemplateStringLiteral();
|
|
2413
2125
|
}
|
|
2126
|
+
if (s3 === peg$FAILED) { break; }
|
|
2127
|
+
s2.push(s3);
|
|
2414
2128
|
}
|
|
2415
2129
|
if (input.charCodeAt(peg$currPos) === 96) {
|
|
2416
2130
|
s3 = peg$c42;
|
|
@@ -2437,7 +2151,7 @@ var ftl = (function (exports) {
|
|
|
2437
2151
|
if (peg$silentFails === 0) { peg$fail(peg$e31); }
|
|
2438
2152
|
}
|
|
2439
2153
|
|
|
2440
|
-
peg$resultsCache
|
|
2154
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
2441
2155
|
|
|
2442
2156
|
return s0;
|
|
2443
2157
|
}
|
|
@@ -2446,7 +2160,7 @@ var ftl = (function (exports) {
|
|
|
2446
2160
|
let s0, s1, s3, s5;
|
|
2447
2161
|
|
|
2448
2162
|
const key = peg$currPos * 38 + 28;
|
|
2449
|
-
const cached = peg$resultsCache
|
|
2163
|
+
const cached = peg$resultsCache.get(key);
|
|
2450
2164
|
|
|
2451
2165
|
if (cached) {
|
|
2452
2166
|
peg$currPos = cached.nextPos;
|
|
@@ -2495,7 +2209,7 @@ var ftl = (function (exports) {
|
|
|
2495
2209
|
if (peg$silentFails === 0) { peg$fail(peg$e37); }
|
|
2496
2210
|
}
|
|
2497
2211
|
|
|
2498
|
-
peg$resultsCache
|
|
2212
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
2499
2213
|
|
|
2500
2214
|
return s0;
|
|
2501
2215
|
}
|
|
@@ -2504,7 +2218,7 @@ var ftl = (function (exports) {
|
|
|
2504
2218
|
let s0, s1, s2, s3, s4;
|
|
2505
2219
|
|
|
2506
2220
|
const key = peg$currPos * 38 + 29;
|
|
2507
|
-
const cached = peg$resultsCache
|
|
2221
|
+
const cached = peg$resultsCache.get(key);
|
|
2508
2222
|
|
|
2509
2223
|
if (cached) {
|
|
2510
2224
|
peg$currPos = cached.nextPos;
|
|
@@ -2515,123 +2229,60 @@ var ftl = (function (exports) {
|
|
|
2515
2229
|
peg$silentFails++;
|
|
2516
2230
|
s0 = peg$currPos;
|
|
2517
2231
|
s1 = [];
|
|
2518
|
-
|
|
2519
|
-
s3 = [];
|
|
2520
|
-
s4 = input.charAt(peg$currPos);
|
|
2521
|
-
if (peg$r4.test(s4)) {
|
|
2522
|
-
peg$currPos++;
|
|
2523
|
-
} else {
|
|
2524
|
-
s4 = peg$FAILED;
|
|
2525
|
-
if (peg$silentFails === 0) { peg$fail(peg$e40); }
|
|
2526
|
-
}
|
|
2527
|
-
if (s4 !== peg$FAILED) {
|
|
2528
|
-
while (s4 !== peg$FAILED) {
|
|
2529
|
-
s3.push(s4);
|
|
2530
|
-
s4 = input.charAt(peg$currPos);
|
|
2531
|
-
if (peg$r4.test(s4)) {
|
|
2532
|
-
peg$currPos++;
|
|
2533
|
-
} else {
|
|
2534
|
-
s4 = peg$FAILED;
|
|
2535
|
-
if (peg$silentFails === 0) { peg$fail(peg$e40); }
|
|
2536
|
-
}
|
|
2537
|
-
}
|
|
2538
|
-
} else {
|
|
2539
|
-
s3 = peg$FAILED;
|
|
2540
|
-
}
|
|
2541
|
-
if (s3 !== peg$FAILED) {
|
|
2542
|
-
s2 = input.substring(s2, peg$currPos);
|
|
2543
|
-
} else {
|
|
2544
|
-
s2 = s3;
|
|
2545
|
-
}
|
|
2546
|
-
if (s2 === peg$FAILED) {
|
|
2232
|
+
for (;;) {
|
|
2547
2233
|
s2 = peg$currPos;
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
peg$currPos
|
|
2551
|
-
|
|
2552
|
-
s3 = peg$FAILED;
|
|
2553
|
-
if (peg$silentFails === 0) { peg$fail(peg$e7); }
|
|
2554
|
-
}
|
|
2555
|
-
if (s3 !== peg$FAILED) {
|
|
2556
|
-
if (input.length > peg$currPos) {
|
|
2557
|
-
s4 = input.charAt(peg$currPos);
|
|
2234
|
+
s3 = [];
|
|
2235
|
+
for (;;) {
|
|
2236
|
+
s4 = input.charAt(peg$currPos);
|
|
2237
|
+
if (s4 !== "" && !(peg$charCode = s4.charCodeAt(0), peg$charCode === 92 || peg$charCode === 96 || peg$charCode === 123)) {
|
|
2558
2238
|
peg$currPos++;
|
|
2559
2239
|
} else {
|
|
2560
2240
|
s4 = peg$FAILED;
|
|
2561
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2562
|
-
}
|
|
2563
|
-
if (s4 !== peg$FAILED) {
|
|
2564
|
-
s2 = peg$f28(s4);
|
|
2565
|
-
} else {
|
|
2566
|
-
peg$currPos = s2;
|
|
2567
|
-
s2 = peg$FAILED;
|
|
2241
|
+
if (peg$silentFails === 0) { peg$fail(peg$e40); }
|
|
2568
2242
|
}
|
|
2243
|
+
if (s4 === peg$FAILED) { break; }
|
|
2244
|
+
s3.push(s4);
|
|
2245
|
+
}
|
|
2246
|
+
if (s3.length < 1) {
|
|
2247
|
+
s3 = peg$FAILED;
|
|
2248
|
+
}
|
|
2249
|
+
if (s3 !== peg$FAILED) {
|
|
2250
|
+
s2 = input.substring(s2, peg$currPos);
|
|
2569
2251
|
} else {
|
|
2570
|
-
|
|
2571
|
-
s2 = peg$FAILED;
|
|
2252
|
+
s2 = s3;
|
|
2572
2253
|
}
|
|
2573
|
-
|
|
2574
|
-
if (s2 !== peg$FAILED) {
|
|
2575
|
-
while (s2 !== peg$FAILED) {
|
|
2576
|
-
s1.push(s2);
|
|
2254
|
+
if (s2 === peg$FAILED) {
|
|
2577
2255
|
s2 = peg$currPos;
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
if (peg$r4.test(s4)) {
|
|
2256
|
+
if (input.charCodeAt(peg$currPos) === 92) {
|
|
2257
|
+
s3 = peg$c7;
|
|
2581
2258
|
peg$currPos++;
|
|
2582
|
-
} else {
|
|
2583
|
-
s4 = peg$FAILED;
|
|
2584
|
-
if (peg$silentFails === 0) { peg$fail(peg$e40); }
|
|
2585
|
-
}
|
|
2586
|
-
if (s4 !== peg$FAILED) {
|
|
2587
|
-
while (s4 !== peg$FAILED) {
|
|
2588
|
-
s3.push(s4);
|
|
2589
|
-
s4 = input.charAt(peg$currPos);
|
|
2590
|
-
if (peg$r4.test(s4)) {
|
|
2591
|
-
peg$currPos++;
|
|
2592
|
-
} else {
|
|
2593
|
-
s4 = peg$FAILED;
|
|
2594
|
-
if (peg$silentFails === 0) { peg$fail(peg$e40); }
|
|
2595
|
-
}
|
|
2596
|
-
}
|
|
2597
2259
|
} else {
|
|
2598
2260
|
s3 = peg$FAILED;
|
|
2261
|
+
if (peg$silentFails === 0) { peg$fail(peg$e7); }
|
|
2599
2262
|
}
|
|
2600
2263
|
if (s3 !== peg$FAILED) {
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
s2 = s3;
|
|
2604
|
-
}
|
|
2605
|
-
if (s2 === peg$FAILED) {
|
|
2606
|
-
s2 = peg$currPos;
|
|
2607
|
-
if (input.charCodeAt(peg$currPos) === 92) {
|
|
2608
|
-
s3 = peg$c7;
|
|
2264
|
+
if (input.length > peg$currPos) {
|
|
2265
|
+
s4 = input.charAt(peg$currPos);
|
|
2609
2266
|
peg$currPos++;
|
|
2610
2267
|
} else {
|
|
2611
|
-
|
|
2612
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
2268
|
+
s4 = peg$FAILED;
|
|
2269
|
+
if (peg$silentFails === 0) { peg$fail(peg$e8); }
|
|
2613
2270
|
}
|
|
2614
|
-
if (
|
|
2615
|
-
|
|
2616
|
-
s4 = input.charAt(peg$currPos);
|
|
2617
|
-
peg$currPos++;
|
|
2618
|
-
} else {
|
|
2619
|
-
s4 = peg$FAILED;
|
|
2620
|
-
if (peg$silentFails === 0) { peg$fail(peg$e8); }
|
|
2621
|
-
}
|
|
2622
|
-
if (s4 !== peg$FAILED) {
|
|
2623
|
-
s2 = peg$f28(s4);
|
|
2624
|
-
} else {
|
|
2625
|
-
peg$currPos = s2;
|
|
2626
|
-
s2 = peg$FAILED;
|
|
2627
|
-
}
|
|
2271
|
+
if (s4 !== peg$FAILED) {
|
|
2272
|
+
s2 = peg$f28(s4);
|
|
2628
2273
|
} else {
|
|
2629
2274
|
peg$currPos = s2;
|
|
2630
2275
|
s2 = peg$FAILED;
|
|
2631
2276
|
}
|
|
2277
|
+
} else {
|
|
2278
|
+
peg$currPos = s2;
|
|
2279
|
+
s2 = peg$FAILED;
|
|
2632
2280
|
}
|
|
2633
2281
|
}
|
|
2634
|
-
|
|
2282
|
+
if (s2 === peg$FAILED) { break; }
|
|
2283
|
+
s1.push(s2);
|
|
2284
|
+
}
|
|
2285
|
+
if (s1.length < 1) {
|
|
2635
2286
|
s1 = peg$FAILED;
|
|
2636
2287
|
}
|
|
2637
2288
|
if (s1 !== peg$FAILED) {
|
|
@@ -2658,7 +2309,7 @@ var ftl = (function (exports) {
|
|
|
2658
2309
|
if (peg$silentFails === 0) { peg$fail(peg$e39); }
|
|
2659
2310
|
}
|
|
2660
2311
|
|
|
2661
|
-
peg$resultsCache
|
|
2312
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
2662
2313
|
|
|
2663
2314
|
return s0;
|
|
2664
2315
|
}
|
|
@@ -2667,7 +2318,7 @@ var ftl = (function (exports) {
|
|
|
2667
2318
|
let s0, s1, s3, s5, s6, s7, s9;
|
|
2668
2319
|
|
|
2669
2320
|
const key = peg$currPos * 38 + 30;
|
|
2670
|
-
const cached = peg$resultsCache
|
|
2321
|
+
const cached = peg$resultsCache.get(key);
|
|
2671
2322
|
|
|
2672
2323
|
if (cached) {
|
|
2673
2324
|
peg$currPos = cached.nextPos;
|
|
@@ -2692,30 +2343,7 @@ var ftl = (function (exports) {
|
|
|
2692
2343
|
}
|
|
2693
2344
|
peg$parse_();
|
|
2694
2345
|
s5 = [];
|
|
2695
|
-
|
|
2696
|
-
if (input.charCodeAt(peg$currPos) === 44) {
|
|
2697
|
-
s7 = peg$c34;
|
|
2698
|
-
peg$currPos++;
|
|
2699
|
-
} else {
|
|
2700
|
-
s7 = peg$FAILED;
|
|
2701
|
-
if (peg$silentFails === 0) { peg$fail(peg$e25); }
|
|
2702
|
-
}
|
|
2703
|
-
if (s7 !== peg$FAILED) {
|
|
2704
|
-
peg$parse_();
|
|
2705
|
-
s9 = peg$parseTernaryExpression();
|
|
2706
|
-
if (s9 !== peg$FAILED) {
|
|
2707
|
-
peg$parse_();
|
|
2708
|
-
s6 = s9;
|
|
2709
|
-
} else {
|
|
2710
|
-
peg$currPos = s6;
|
|
2711
|
-
s6 = peg$FAILED;
|
|
2712
|
-
}
|
|
2713
|
-
} else {
|
|
2714
|
-
peg$currPos = s6;
|
|
2715
|
-
s6 = peg$FAILED;
|
|
2716
|
-
}
|
|
2717
|
-
while (s6 !== peg$FAILED) {
|
|
2718
|
-
s5.push(s6);
|
|
2346
|
+
for (;;) {
|
|
2719
2347
|
s6 = peg$currPos;
|
|
2720
2348
|
if (input.charCodeAt(peg$currPos) === 44) {
|
|
2721
2349
|
s7 = peg$c34;
|
|
@@ -2738,6 +2366,8 @@ var ftl = (function (exports) {
|
|
|
2738
2366
|
peg$currPos = s6;
|
|
2739
2367
|
s6 = peg$FAILED;
|
|
2740
2368
|
}
|
|
2369
|
+
if (s6 === peg$FAILED) { break; }
|
|
2370
|
+
s5.push(s6);
|
|
2741
2371
|
}
|
|
2742
2372
|
if (input.charCodeAt(peg$currPos) === 93) {
|
|
2743
2373
|
s6 = peg$c31;
|
|
@@ -2762,7 +2392,7 @@ var ftl = (function (exports) {
|
|
|
2762
2392
|
if (peg$silentFails === 0) { peg$fail(peg$e41); }
|
|
2763
2393
|
}
|
|
2764
2394
|
|
|
2765
|
-
peg$resultsCache
|
|
2395
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
2766
2396
|
|
|
2767
2397
|
return s0;
|
|
2768
2398
|
}
|
|
@@ -2771,7 +2401,7 @@ var ftl = (function (exports) {
|
|
|
2771
2401
|
let s0, s1, s3, s4, s5, s6, s7, s8, s9, s11, s13;
|
|
2772
2402
|
|
|
2773
2403
|
const key = peg$currPos * 38 + 31;
|
|
2774
|
-
const cached = peg$resultsCache
|
|
2404
|
+
const cached = peg$resultsCache.get(key);
|
|
2775
2405
|
|
|
2776
2406
|
if (cached) {
|
|
2777
2407
|
peg$currPos = cached.nextPos;
|
|
@@ -2823,50 +2453,7 @@ var ftl = (function (exports) {
|
|
|
2823
2453
|
}
|
|
2824
2454
|
s4 = peg$parse_();
|
|
2825
2455
|
s5 = [];
|
|
2826
|
-
|
|
2827
|
-
if (input.charCodeAt(peg$currPos) === 44) {
|
|
2828
|
-
s7 = peg$c34;
|
|
2829
|
-
peg$currPos++;
|
|
2830
|
-
} else {
|
|
2831
|
-
s7 = peg$FAILED;
|
|
2832
|
-
if (peg$silentFails === 0) { peg$fail(peg$e25); }
|
|
2833
|
-
}
|
|
2834
|
-
if (s7 !== peg$FAILED) {
|
|
2835
|
-
s8 = peg$parse_();
|
|
2836
|
-
s9 = peg$parseStringLiteral();
|
|
2837
|
-
if (s9 !== peg$FAILED) {
|
|
2838
|
-
peg$parse_();
|
|
2839
|
-
if (input.charCodeAt(peg$currPos) === 58) {
|
|
2840
|
-
s11 = peg$c15;
|
|
2841
|
-
peg$currPos++;
|
|
2842
|
-
} else {
|
|
2843
|
-
s11 = peg$FAILED;
|
|
2844
|
-
if (peg$silentFails === 0) { peg$fail(peg$e11); }
|
|
2845
|
-
}
|
|
2846
|
-
if (s11 !== peg$FAILED) {
|
|
2847
|
-
peg$parse_();
|
|
2848
|
-
s13 = peg$parseTernaryExpression();
|
|
2849
|
-
if (s13 !== peg$FAILED) {
|
|
2850
|
-
peg$parse_();
|
|
2851
|
-
s6 = [ s9, s13 ];
|
|
2852
|
-
} else {
|
|
2853
|
-
peg$currPos = s6;
|
|
2854
|
-
s6 = peg$FAILED;
|
|
2855
|
-
}
|
|
2856
|
-
} else {
|
|
2857
|
-
peg$currPos = s6;
|
|
2858
|
-
s6 = peg$FAILED;
|
|
2859
|
-
}
|
|
2860
|
-
} else {
|
|
2861
|
-
peg$currPos = s6;
|
|
2862
|
-
s6 = peg$FAILED;
|
|
2863
|
-
}
|
|
2864
|
-
} else {
|
|
2865
|
-
peg$currPos = s6;
|
|
2866
|
-
s6 = peg$FAILED;
|
|
2867
|
-
}
|
|
2868
|
-
while (s6 !== peg$FAILED) {
|
|
2869
|
-
s5.push(s6);
|
|
2456
|
+
for (;;) {
|
|
2870
2457
|
s6 = peg$currPos;
|
|
2871
2458
|
if (input.charCodeAt(peg$currPos) === 44) {
|
|
2872
2459
|
s7 = peg$c34;
|
|
@@ -2909,6 +2496,8 @@ var ftl = (function (exports) {
|
|
|
2909
2496
|
peg$currPos = s6;
|
|
2910
2497
|
s6 = peg$FAILED;
|
|
2911
2498
|
}
|
|
2499
|
+
if (s6 === peg$FAILED) { break; }
|
|
2500
|
+
s5.push(s6);
|
|
2912
2501
|
}
|
|
2913
2502
|
if (input.charCodeAt(peg$currPos) === 125) {
|
|
2914
2503
|
s6 = peg$c43;
|
|
@@ -2933,7 +2522,7 @@ var ftl = (function (exports) {
|
|
|
2933
2522
|
if (peg$silentFails === 0) { peg$fail(peg$e42); }
|
|
2934
2523
|
}
|
|
2935
2524
|
|
|
2936
|
-
peg$resultsCache
|
|
2525
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
2937
2526
|
|
|
2938
2527
|
return s0;
|
|
2939
2528
|
}
|
|
@@ -2942,7 +2531,7 @@ var ftl = (function (exports) {
|
|
|
2942
2531
|
let s0, s1, s2, s3, s4;
|
|
2943
2532
|
|
|
2944
2533
|
const key = peg$currPos * 38 + 32;
|
|
2945
|
-
const cached = peg$resultsCache
|
|
2534
|
+
const cached = peg$resultsCache.get(key);
|
|
2946
2535
|
|
|
2947
2536
|
if (cached) {
|
|
2948
2537
|
peg$currPos = cached.nextPos;
|
|
@@ -3000,7 +2589,7 @@ var ftl = (function (exports) {
|
|
|
3000
2589
|
if (peg$silentFails === 0) { peg$fail(peg$e43); }
|
|
3001
2590
|
}
|
|
3002
2591
|
|
|
3003
|
-
peg$resultsCache
|
|
2592
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
3004
2593
|
|
|
3005
2594
|
return s0;
|
|
3006
2595
|
}
|
|
@@ -3009,7 +2598,7 @@ var ftl = (function (exports) {
|
|
|
3009
2598
|
let s0, s1, s2, s3, s4;
|
|
3010
2599
|
|
|
3011
2600
|
const key = peg$currPos * 38 + 33;
|
|
3012
|
-
const cached = peg$resultsCache
|
|
2601
|
+
const cached = peg$resultsCache.get(key);
|
|
3013
2602
|
|
|
3014
2603
|
if (cached) {
|
|
3015
2604
|
peg$currPos = cached.nextPos;
|
|
@@ -3020,7 +2609,7 @@ var ftl = (function (exports) {
|
|
|
3020
2609
|
s0 = peg$currPos;
|
|
3021
2610
|
s1 = peg$currPos;
|
|
3022
2611
|
s2 = input.charAt(peg$currPos);
|
|
3023
|
-
if (peg$
|
|
2612
|
+
if ((peg$charCode = s2.charCodeAt(0), (peg$charCode >= 97 && peg$charCode <= 122) || (peg$charCode >= 65 && peg$charCode <= 90) || peg$charCode === 36 || peg$charCode === 95)) {
|
|
3024
2613
|
peg$currPos++;
|
|
3025
2614
|
} else {
|
|
3026
2615
|
s2 = peg$FAILED;
|
|
@@ -3028,22 +2617,16 @@ var ftl = (function (exports) {
|
|
|
3028
2617
|
}
|
|
3029
2618
|
if (s2 !== peg$FAILED) {
|
|
3030
2619
|
s3 = [];
|
|
3031
|
-
|
|
3032
|
-
if (peg$r6.test(s4)) {
|
|
3033
|
-
peg$currPos++;
|
|
3034
|
-
} else {
|
|
3035
|
-
s4 = peg$FAILED;
|
|
3036
|
-
if (peg$silentFails === 0) { peg$fail(peg$e46); }
|
|
3037
|
-
}
|
|
3038
|
-
while (s4 !== peg$FAILED) {
|
|
3039
|
-
s3.push(s4);
|
|
2620
|
+
for (;;) {
|
|
3040
2621
|
s4 = input.charAt(peg$currPos);
|
|
3041
|
-
if (peg$
|
|
2622
|
+
if ((peg$charCode = s4.charCodeAt(0), (peg$charCode >= 97 && peg$charCode <= 122) || (peg$charCode >= 65 && peg$charCode <= 90) || peg$charCode === 36 || peg$charCode === 95 || (peg$charCode >= 48 && peg$charCode <= 57))) {
|
|
3042
2623
|
peg$currPos++;
|
|
3043
2624
|
} else {
|
|
3044
2625
|
s4 = peg$FAILED;
|
|
3045
2626
|
if (peg$silentFails === 0) { peg$fail(peg$e46); }
|
|
3046
2627
|
}
|
|
2628
|
+
if (s4 === peg$FAILED) { break; }
|
|
2629
|
+
s3.push(s4);
|
|
3047
2630
|
}
|
|
3048
2631
|
s2 = [s2, s3];
|
|
3049
2632
|
s1 = s2;
|
|
@@ -3057,7 +2640,7 @@ var ftl = (function (exports) {
|
|
|
3057
2640
|
s0 = s1;
|
|
3058
2641
|
}
|
|
3059
2642
|
|
|
3060
|
-
peg$resultsCache
|
|
2643
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
3061
2644
|
|
|
3062
2645
|
return s0;
|
|
3063
2646
|
}
|
|
@@ -3066,7 +2649,7 @@ var ftl = (function (exports) {
|
|
|
3066
2649
|
let s0, s1;
|
|
3067
2650
|
|
|
3068
2651
|
const key = peg$currPos * 38 + 34;
|
|
3069
|
-
const cached = peg$resultsCache
|
|
2652
|
+
const cached = peg$resultsCache.get(key);
|
|
3070
2653
|
|
|
3071
2654
|
if (cached) {
|
|
3072
2655
|
peg$currPos = cached.nextPos;
|
|
@@ -3087,7 +2670,7 @@ var ftl = (function (exports) {
|
|
|
3087
2670
|
if (peg$silentFails === 0) { peg$fail(peg$e47); }
|
|
3088
2671
|
}
|
|
3089
2672
|
|
|
3090
|
-
peg$resultsCache
|
|
2673
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
3091
2674
|
|
|
3092
2675
|
return s0;
|
|
3093
2676
|
}
|
|
@@ -3096,7 +2679,7 @@ var ftl = (function (exports) {
|
|
|
3096
2679
|
let s0;
|
|
3097
2680
|
|
|
3098
2681
|
const key = peg$currPos * 38 + 35;
|
|
3099
|
-
const cached = peg$resultsCache
|
|
2682
|
+
const cached = peg$resultsCache.get(key);
|
|
3100
2683
|
|
|
3101
2684
|
if (cached) {
|
|
3102
2685
|
peg$currPos = cached.nextPos;
|
|
@@ -3121,7 +2704,7 @@ var ftl = (function (exports) {
|
|
|
3121
2704
|
}
|
|
3122
2705
|
}
|
|
3123
2706
|
|
|
3124
|
-
peg$resultsCache
|
|
2707
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
3125
2708
|
|
|
3126
2709
|
return s0;
|
|
3127
2710
|
}
|
|
@@ -3130,7 +2713,7 @@ var ftl = (function (exports) {
|
|
|
3130
2713
|
let s0;
|
|
3131
2714
|
|
|
3132
2715
|
const key = peg$currPos * 38 + 36;
|
|
3133
|
-
const cached = peg$resultsCache
|
|
2716
|
+
const cached = peg$resultsCache.get(key);
|
|
3134
2717
|
|
|
3135
2718
|
if (cached) {
|
|
3136
2719
|
peg$currPos = cached.nextPos;
|
|
@@ -3173,7 +2756,7 @@ var ftl = (function (exports) {
|
|
|
3173
2756
|
}
|
|
3174
2757
|
}
|
|
3175
2758
|
|
|
3176
|
-
peg$resultsCache
|
|
2759
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
3177
2760
|
|
|
3178
2761
|
return s0;
|
|
3179
2762
|
}
|
|
@@ -3182,7 +2765,7 @@ var ftl = (function (exports) {
|
|
|
3182
2765
|
let s0, s1;
|
|
3183
2766
|
|
|
3184
2767
|
const key = peg$currPos * 38 + 37;
|
|
3185
|
-
const cached = peg$resultsCache
|
|
2768
|
+
const cached = peg$resultsCache.get(key);
|
|
3186
2769
|
|
|
3187
2770
|
if (cached) {
|
|
3188
2771
|
peg$currPos = cached.nextPos;
|
|
@@ -3192,26 +2775,20 @@ var ftl = (function (exports) {
|
|
|
3192
2775
|
|
|
3193
2776
|
peg$silentFails++;
|
|
3194
2777
|
s0 = [];
|
|
3195
|
-
|
|
3196
|
-
if (peg$r7.test(s1)) {
|
|
3197
|
-
peg$currPos++;
|
|
3198
|
-
} else {
|
|
3199
|
-
s1 = peg$FAILED;
|
|
3200
|
-
if (peg$silentFails === 0) { peg$fail(peg$e54); }
|
|
3201
|
-
}
|
|
3202
|
-
while (s1 !== peg$FAILED) {
|
|
3203
|
-
s0.push(s1);
|
|
2778
|
+
for (;;) {
|
|
3204
2779
|
s1 = input.charAt(peg$currPos);
|
|
3205
|
-
if (peg$
|
|
2780
|
+
if ((peg$charCode = s1.charCodeAt(0), peg$charCode === 32 || peg$charCode === 9 || peg$charCode === 10 || peg$charCode === 13)) {
|
|
3206
2781
|
peg$currPos++;
|
|
3207
2782
|
} else {
|
|
3208
2783
|
s1 = peg$FAILED;
|
|
3209
2784
|
if (peg$silentFails === 0) { peg$fail(peg$e54); }
|
|
3210
2785
|
}
|
|
2786
|
+
if (s1 === peg$FAILED) { break; }
|
|
2787
|
+
s0.push(s1);
|
|
3211
2788
|
}
|
|
3212
2789
|
peg$silentFails--;
|
|
3213
2790
|
|
|
3214
|
-
peg$resultsCache
|
|
2791
|
+
peg$resultsCache.set(key, { nextPos: peg$currPos, result: s0 });
|
|
3215
2792
|
|
|
3216
2793
|
return s0;
|
|
3217
2794
|
}
|
|
@@ -3253,10 +2830,10 @@ var ftl = (function (exports) {
|
|
|
3253
2830
|
/**
|
|
3254
2831
|
* The one lookup against a data stack: the innermost overlay carrying the name
|
|
3255
2832
|
* wins, `self` is the innermost overlay itself, and a function overlay counts
|
|
3256
|
-
* like an object one.
|
|
3257
|
-
* imperative facades cannot drift from what a template sees.
|
|
2833
|
+
* like an object one.
|
|
3258
2834
|
* @param {any[]} dataStack
|
|
3259
2835
|
* @param {string|symbol} prop
|
|
2836
|
+
* @returns {any} undefined when no overlay carries the name
|
|
3260
2837
|
*/
|
|
3261
2838
|
const resolveInStack = (dataStack, prop) => {
|
|
3262
2839
|
if (prop === 'self') {
|
|
@@ -3320,8 +2897,7 @@ var ftl = (function (exports) {
|
|
|
3320
2897
|
return this.visit(node.lhs) || this.visit(node.rhs);
|
|
3321
2898
|
}
|
|
3322
2899
|
[nodes.nullc](node) {
|
|
3323
|
-
|
|
3324
|
-
return lhs !== null && lhs !== undefined ? lhs : this.visit(node.rhs);
|
|
2900
|
+
return this.visit(node.lhs) ?? this.visit(node.rhs);
|
|
3325
2901
|
}
|
|
3326
2902
|
[nodes.not](node) {
|
|
3327
2903
|
return !this.visit(node.expr);
|
|
@@ -3388,8 +2964,7 @@ var ftl = (function (exports) {
|
|
|
3388
2964
|
return this.visit(node.cond) ? this.visit(node.ifTrue) : this.visit(node.ifFalse);
|
|
3389
2965
|
}
|
|
3390
2966
|
[nodes.elv](node) {
|
|
3391
|
-
|
|
3392
|
-
return cond ? cond : this.visit(node.ifFalse);
|
|
2967
|
+
return this.visit(node.cond) || this.visit(node.ifFalse);
|
|
3393
2968
|
}
|
|
3394
2969
|
[nodes.access](node) {
|
|
3395
2970
|
let prev;
|
|
@@ -3455,16 +3030,23 @@ var ftl = (function (exports) {
|
|
|
3455
3030
|
* spliced into the expression text.
|
|
3456
3031
|
*/
|
|
3457
3032
|
class Expressions {
|
|
3033
|
+
/** Parses the whole text as one expression: `user.name`. */
|
|
3458
3034
|
static MODE_EXPRESSION = Symbol('MODE_EXPRESSION');
|
|
3035
|
+
/**
|
|
3036
|
+
* Parses text with interpolations, `Hello {{ user.name }}`, evaluating to
|
|
3037
|
+
* its parts: `{ type, value }` for each literal run and each `{{ }}` (text),
|
|
3038
|
+
* `{{{ }}}` (html) or `{{{{ }}}}` (node) interpolation, in order.
|
|
3039
|
+
*/
|
|
3459
3040
|
static MODE_TEMPLATED = Symbol('MODE_TEMPLATED');
|
|
3460
3041
|
|
|
3461
3042
|
static #astCache = new BoundedCache(1000);
|
|
3462
3043
|
|
|
3463
3044
|
/**
|
|
3464
|
-
* Parses an expression.
|
|
3045
|
+
* Parses an expression, caching the ast by mode and text.
|
|
3465
3046
|
* @param {string} expression
|
|
3466
|
-
* @param {(typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED)?} [mode]
|
|
3467
|
-
* @returns the ast
|
|
3047
|
+
* @param {(typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED)?} [mode] MODE_EXPRESSION when omitted
|
|
3048
|
+
* @returns {any} the ast
|
|
3049
|
+
* @throws a peggy syntax error when the text does not parse
|
|
3468
3050
|
*/
|
|
3469
3051
|
static parse(expression, mode) {
|
|
3470
3052
|
const key = mode?.toString() + expression;
|
|
@@ -3475,12 +3057,12 @@ var ftl = (function (exports) {
|
|
|
3475
3057
|
);
|
|
3476
3058
|
}
|
|
3477
3059
|
/**
|
|
3478
|
-
* Evaluates
|
|
3060
|
+
* Evaluates a parsed ast against the modules and the data stack.
|
|
3479
3061
|
* @param {{[k: string]: any } | null | undefined } modules
|
|
3480
|
-
* @param {any[]} dataStack
|
|
3481
|
-
* @param {any} ast
|
|
3482
|
-
* @param {(typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED)?} [mode]
|
|
3483
|
-
* @returns the
|
|
3062
|
+
* @param {any[]} dataStack innermost overlay last
|
|
3063
|
+
* @param {any} ast what `parse` answered
|
|
3064
|
+
* @param {(typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED)?} [mode] the mode it was parsed in
|
|
3065
|
+
* @returns {any} the value, or the list of parts in MODE_TEMPLATED
|
|
3484
3066
|
*/
|
|
3485
3067
|
static evaluate(modules, dataStack, ast, mode) {
|
|
3486
3068
|
return new EvaluatingVisitor(modules, dataStack).visitRoot(ast, mode === Expressions.MODE_TEMPLATED);
|
|
@@ -3488,10 +3070,10 @@ var ftl = (function (exports) {
|
|
|
3488
3070
|
/**
|
|
3489
3071
|
* Parses and evaluates an expression.
|
|
3490
3072
|
* @param {{ [x: string]: any; } | null | undefined} modules
|
|
3491
|
-
* @param {any[]} dataStack
|
|
3073
|
+
* @param {any[]} dataStack innermost overlay last
|
|
3492
3074
|
* @param {string} expression
|
|
3493
|
-
* @param {(typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED)?} [mode]
|
|
3494
|
-
* @returns the
|
|
3075
|
+
* @param {(typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED)?} [mode] MODE_EXPRESSION when omitted
|
|
3076
|
+
* @returns {any} the value, or the list of parts in MODE_TEMPLATED
|
|
3495
3077
|
*/
|
|
3496
3078
|
static interpret(modules, dataStack, expression, mode) {
|
|
3497
3079
|
return Expressions.evaluate(modules, dataStack, Expressions.parse(expression, mode), mode);
|
|
@@ -3507,14 +3089,31 @@ var ftl = (function (exports) {
|
|
|
3507
3089
|
class ExpressionEvaluator {
|
|
3508
3090
|
#modules;
|
|
3509
3091
|
#dataStack;
|
|
3092
|
+
/**
|
|
3093
|
+
* @param {{ [k: string]: any } | null | undefined} modules
|
|
3094
|
+
* @param {any[]} dataStack innermost overlay last
|
|
3095
|
+
*/
|
|
3510
3096
|
constructor(modules, dataStack) {
|
|
3511
3097
|
this.#modules = modules;
|
|
3512
3098
|
this.#dataStack = dataStack;
|
|
3513
3099
|
}
|
|
3100
|
+
/**
|
|
3101
|
+
* A new evaluator with one more module: `#name:fn()` resolves into it, and an
|
|
3102
|
+
* empty name merges a whole map whose functions resolve bare, as `#fn()`.
|
|
3103
|
+
* @param {string} name
|
|
3104
|
+
* @param {object} value
|
|
3105
|
+
* @returns {ExpressionEvaluator}
|
|
3106
|
+
*/
|
|
3514
3107
|
withModule(name, value) {
|
|
3515
3108
|
const module = name ? { [name]: value } : value;
|
|
3516
3109
|
return new ExpressionEvaluator({ ...this.#modules, ...module }, this.#dataStack);
|
|
3517
3110
|
}
|
|
3111
|
+
/**
|
|
3112
|
+
* A new evaluator with the data pushed as the innermost overlays, the last
|
|
3113
|
+
* one winning a shared name.
|
|
3114
|
+
* @param {...any} data
|
|
3115
|
+
* @returns {ExpressionEvaluator}
|
|
3116
|
+
*/
|
|
3518
3117
|
withOverlay(...data) {
|
|
3519
3118
|
return new ExpressionEvaluator(
|
|
3520
3119
|
this.#modules,
|
|
@@ -3525,26 +3124,36 @@ var ftl = (function (exports) {
|
|
|
3525
3124
|
* Resolves a name against the data stack, with no parse round trip: the
|
|
3526
3125
|
* lookup a template's bare identifier makes, for an imperative caller.
|
|
3527
3126
|
* @param {string} name
|
|
3127
|
+
* @returns {any} undefined when no overlay carries the name
|
|
3528
3128
|
*/
|
|
3529
3129
|
resolve(name) {
|
|
3530
3130
|
return resolveInStack(this.#dataStack, name);
|
|
3531
3131
|
}
|
|
3532
|
-
/**
|
|
3132
|
+
/**
|
|
3133
|
+
* Evaluates an expression against this scope.
|
|
3134
|
+
* @param {string} expression
|
|
3135
|
+
* @returns {any}
|
|
3136
|
+
*/
|
|
3533
3137
|
evaluateExpression(expression) {
|
|
3534
3138
|
return Expressions.interpret(this.#modules, this.#dataStack, expression, Expressions.MODE_EXPRESSION);
|
|
3535
3139
|
}
|
|
3536
|
-
/**
|
|
3140
|
+
/**
|
|
3141
|
+
* Evaluates a templated text, the `{{ }}` form, against this scope.
|
|
3142
|
+
* @param {string} text
|
|
3143
|
+
* @returns {{ type: symbol, value: any }[]} its parts, as MODE_TEMPLATED describes
|
|
3144
|
+
*/
|
|
3537
3145
|
evaluateTemplated(text) {
|
|
3538
3146
|
return Expressions.interpret(this.#modules, this.#dataStack, text, Expressions.MODE_TEMPLATED);
|
|
3539
3147
|
}
|
|
3540
3148
|
}
|
|
3541
3149
|
|
|
3542
|
-
/** Creates and inspects
|
|
3150
|
+
/** Creates, serializes and inspects DocumentFragments. */
|
|
3543
3151
|
class Fragments {
|
|
3544
3152
|
/**
|
|
3545
|
-
*
|
|
3546
|
-
*
|
|
3547
|
-
* @
|
|
3153
|
+
* Parses html into a DocumentFragment adopted by the document, each piece
|
|
3154
|
+
* trimmed and the pieces joined.
|
|
3155
|
+
* @param {...string} html
|
|
3156
|
+
* @returns {DocumentFragment}
|
|
3548
3157
|
*/
|
|
3549
3158
|
static fromHtml(...html) {
|
|
3550
3159
|
const el = document.createElement('template');
|
|
@@ -3552,11 +3161,11 @@ var ftl = (function (exports) {
|
|
|
3552
3161
|
return document.adoptNode(el.content);
|
|
3553
3162
|
}
|
|
3554
3163
|
/**
|
|
3555
|
-
*
|
|
3556
|
-
*
|
|
3164
|
+
* Serializes a fragment, or a single node, to html, consuming it: the nodes
|
|
3165
|
+
* are moved out, not copied, and a fragment is left empty. Pass
|
|
3557
3166
|
* `fragment.cloneNode(true)` to keep the original usable.
|
|
3558
|
-
* @param {DocumentFragment} fragment
|
|
3559
|
-
* @returns {string}
|
|
3167
|
+
* @param {DocumentFragment|Node} fragment
|
|
3168
|
+
* @returns {string}
|
|
3560
3169
|
*/
|
|
3561
3170
|
static toHtml(fragment) {
|
|
3562
3171
|
var el = document.createElement('template');
|
|
@@ -3564,17 +3173,17 @@ var ftl = (function (exports) {
|
|
|
3564
3173
|
return el.innerHTML;
|
|
3565
3174
|
}
|
|
3566
3175
|
/**
|
|
3567
|
-
*
|
|
3176
|
+
* Whether a fragment holds no element and no text but whitespace.
|
|
3568
3177
|
* @param {DocumentFragment} fragment
|
|
3569
|
-
* @returns {boolean}
|
|
3178
|
+
* @returns {boolean}
|
|
3570
3179
|
*/
|
|
3571
3180
|
static isBlank(fragment) {
|
|
3572
3181
|
return fragment.childElementCount === 0 && fragment.textContent.trim() === '';
|
|
3573
3182
|
}
|
|
3574
3183
|
/**
|
|
3575
|
-
*
|
|
3576
|
-
* @param
|
|
3577
|
-
* @returns {DocumentFragment}
|
|
3184
|
+
* Moves the nodes, in order, into a new DocumentFragment.
|
|
3185
|
+
* @param {...Node} nodes
|
|
3186
|
+
* @returns {DocumentFragment}
|
|
3578
3187
|
*/
|
|
3579
3188
|
static from(...nodes) {
|
|
3580
3189
|
const fragment = new DocumentFragment();
|
|
@@ -3584,9 +3193,10 @@ var ftl = (function (exports) {
|
|
|
3584
3193
|
return fragment;
|
|
3585
3194
|
}
|
|
3586
3195
|
/**
|
|
3587
|
-
*
|
|
3196
|
+
* Moves the children of a node into a new DocumentFragment, leaving the
|
|
3197
|
+
* node empty.
|
|
3588
3198
|
* @param {Node} el
|
|
3589
|
-
* @returns {DocumentFragment}
|
|
3199
|
+
* @returns {DocumentFragment}
|
|
3590
3200
|
*/
|
|
3591
3201
|
static fromChildNodes(el) {
|
|
3592
3202
|
const fragment = new DocumentFragment();
|
|
@@ -3597,23 +3207,23 @@ var ftl = (function (exports) {
|
|
|
3597
3207
|
}
|
|
3598
3208
|
}
|
|
3599
3209
|
|
|
3600
|
-
/** Attribute
|
|
3210
|
+
/** Attribute helpers: unique ids, defaults, prefixed forwarding, and writes where a nullish value removes the attribute. */
|
|
3601
3211
|
class Attributes {
|
|
3602
3212
|
static id = 0;
|
|
3603
3213
|
/**
|
|
3604
|
-
*
|
|
3214
|
+
* A page-unique id under the prefix, as `prefix-n`.
|
|
3605
3215
|
* @param {string} prefix
|
|
3606
|
-
* @returns
|
|
3216
|
+
* @returns {string}
|
|
3607
3217
|
*/
|
|
3608
3218
|
static uid(prefix) {
|
|
3609
3219
|
return `${prefix}-${++Attributes.id}`;
|
|
3610
3220
|
}
|
|
3611
3221
|
/**
|
|
3612
|
-
* Sets an attribute
|
|
3222
|
+
* Sets an attribute when the element does not carry it.
|
|
3613
3223
|
* @param {Element} el
|
|
3614
3224
|
* @param {string} k
|
|
3615
3225
|
* @param {string} v
|
|
3616
|
-
* @returns
|
|
3226
|
+
* @returns {string|null} the attribute's value afterwards
|
|
3617
3227
|
*/
|
|
3618
3228
|
static defaultValue(el, k, v) {
|
|
3619
3229
|
if (!el.hasAttribute(k)) {
|
|
@@ -3622,7 +3232,9 @@ var ftl = (function (exports) {
|
|
|
3622
3232
|
return el.getAttribute(k);
|
|
3623
3233
|
}
|
|
3624
3234
|
/**
|
|
3625
|
-
*
|
|
3235
|
+
* Copies every attribute whose name starts with the prefix onto another
|
|
3236
|
+
* element, under the name without the prefix. `<prefix>class` adds its
|
|
3237
|
+
* classes to the target's instead of replacing them.
|
|
3626
3238
|
* @param {string} prefix
|
|
3627
3239
|
* @param {Element} from
|
|
3628
3240
|
* @param {Element} to
|
|
@@ -3645,7 +3257,7 @@ var ftl = (function (exports) {
|
|
|
3645
3257
|
});
|
|
3646
3258
|
}
|
|
3647
3259
|
/**
|
|
3648
|
-
* Sets
|
|
3260
|
+
* Sets an attribute, or removes it when the value is nullish.
|
|
3649
3261
|
* @param {Element} el
|
|
3650
3262
|
* @param {string} attr
|
|
3651
3263
|
* @param {string | null | undefined} value
|
|
@@ -3667,13 +3279,14 @@ var ftl = (function (exports) {
|
|
|
3667
3279
|
*/
|
|
3668
3280
|
class LightSlots {
|
|
3669
3281
|
/**
|
|
3670
|
-
*
|
|
3282
|
+
* Takes an element's children apart into slots, leaving the element empty.
|
|
3283
|
+
* A named child is removed and contributes what `slotFromNode` answers;
|
|
3284
|
+
* children sharing a name are gathered in order. A child with an empty
|
|
3285
|
+
* `slot` belongs to the default slot, in document order among the rest.
|
|
3671
3286
|
* @param {Element} el
|
|
3672
|
-
* @returns the slots
|
|
3287
|
+
* @returns {Record<string, DocumentFragment>} the slots by name, `default` always present
|
|
3673
3288
|
*/
|
|
3674
3289
|
static from(el) {
|
|
3675
|
-
//the platform reads slot="" as the default slot: such children stay in
|
|
3676
|
-
//the document order of the default content, their claim stripped like any named one
|
|
3677
3290
|
for (const child of el.children) {
|
|
3678
3291
|
if (child.matches('[slot=""]')) {
|
|
3679
3292
|
child.removeAttribute('slot');
|
|
@@ -3688,7 +3301,7 @@ var ftl = (function (exports) {
|
|
|
3688
3301
|
el.removeAttribute('slot');
|
|
3689
3302
|
return [slot, LightSlots.slotFromNode(el)];
|
|
3690
3303
|
});
|
|
3691
|
-
const slots =
|
|
3304
|
+
const slots = Object.create(null);
|
|
3692
3305
|
slots.default = new DocumentFragment();
|
|
3693
3306
|
slots.default.append(...el.childNodes);
|
|
3694
3307
|
for (const [name, el] of namedSlots) {
|
|
@@ -3699,6 +3312,12 @@ var ftl = (function (exports) {
|
|
|
3699
3312
|
}
|
|
3700
3313
|
return slots;
|
|
3701
3314
|
}
|
|
3315
|
+
/**
|
|
3316
|
+
* What a slotted node contributes: a template's content, the parsed markup
|
|
3317
|
+
* of a `<script type="text/html">`, or the node itself.
|
|
3318
|
+
* @param {Element} el
|
|
3319
|
+
* @returns {Element|DocumentFragment}
|
|
3320
|
+
*/
|
|
3702
3321
|
static slotFromNode(el) {
|
|
3703
3322
|
if (el instanceof HTMLTemplateElement) {
|
|
3704
3323
|
return document.adoptNode(el.content);
|
|
@@ -3710,12 +3329,13 @@ var ftl = (function (exports) {
|
|
|
3710
3329
|
}
|
|
3711
3330
|
}
|
|
3712
3331
|
|
|
3713
|
-
/** Waits
|
|
3332
|
+
/** Waits on the parser and the document, and queries an element's own children. */
|
|
3714
3333
|
class Nodes {
|
|
3715
3334
|
/**
|
|
3716
|
-
*
|
|
3335
|
+
* Whether the parser has moved past the element: the element, or one of
|
|
3336
|
+
* its ancestors, has a next sibling.
|
|
3717
3337
|
* @param {Element} el
|
|
3718
|
-
* @returns
|
|
3338
|
+
* @returns {boolean}
|
|
3719
3339
|
*/
|
|
3720
3340
|
static isParsed(el) {
|
|
3721
3341
|
for (let c = /** @type {Node | null} */ (el); c; c = c.parentNode) {
|
|
@@ -3727,13 +3347,12 @@ var ftl = (function (exports) {
|
|
|
3727
3347
|
}
|
|
3728
3348
|
|
|
3729
3349
|
/**
|
|
3730
|
-
* Waits for the document's DOMContentLoaded
|
|
3731
|
-
*
|
|
3732
|
-
*
|
|
3733
|
-
*
|
|
3734
|
-
*
|
|
3735
|
-
*
|
|
3736
|
-
* never early.
|
|
3350
|
+
* Waits for the document's DOMContentLoaded. Resolves at once when that
|
|
3351
|
+
* moment already passed, and for a document with no view, which receives
|
|
3352
|
+
* no events. Never resolves early for a document still running its
|
|
3353
|
+
* deferred scripts.
|
|
3354
|
+
* @param {Document} doc
|
|
3355
|
+
* @returns {Promise<void>}
|
|
3737
3356
|
*/
|
|
3738
3357
|
static waitDomContentLoaded(doc) {
|
|
3739
3358
|
if (doc.readyState === 'loading') {
|
|
@@ -3746,7 +3365,13 @@ var ftl = (function (exports) {
|
|
|
3746
3365
|
}
|
|
3747
3366
|
const win = doc.defaultView;
|
|
3748
3367
|
if (win === null) {
|
|
3749
|
-
|
|
3368
|
+
return Promise.resolve();
|
|
3369
|
+
}
|
|
3370
|
+
// interactive spans both the deferred scripts and the time between DOMContentLoaded and load
|
|
3371
|
+
const [navigation] = /** @type {PerformanceNavigationTiming[]} */ (
|
|
3372
|
+
win.performance?.getEntriesByType('navigation') ?? []
|
|
3373
|
+
);
|
|
3374
|
+
if (navigation?.domContentLoadedEventStart > 0) {
|
|
3750
3375
|
return Promise.resolve();
|
|
3751
3376
|
}
|
|
3752
3377
|
return new Promise((resolve) => {
|
|
@@ -3765,22 +3390,12 @@ var ftl = (function (exports) {
|
|
|
3765
3390
|
* resolves once the element, or any of its ancestors, gains a next sibling,
|
|
3766
3391
|
* which is the parser having moved past this subtree. The document's
|
|
3767
3392
|
* DOMContentLoaded is the deadline. Resolves immediately for an element
|
|
3768
|
-
* that is already parsed.
|
|
3769
|
-
*
|
|
3770
|
-
*
|
|
3771
|
-
* predicate reads: an element last among its siblings becomes parsed when
|
|
3772
|
-
* an ancestor gains one, and a childList observer on the parent never sees
|
|
3773
|
-
* that. Formatted markup usually hides the difference, the whitespace
|
|
3774
|
-
* before a closing tag being a text node the parent does gain, so the gap
|
|
3775
|
-
* shows on whitespace-free markup, where the wait fell back to the
|
|
3776
|
-
* deadline. One observer takes many targets, so the cost is one observe()
|
|
3777
|
-
* per level, and it is disconnected at the first checkpoint past the
|
|
3778
|
-
* element either way.
|
|
3779
|
-
* @param {any} el
|
|
3780
|
-
* @returns {Promise<any>}
|
|
3393
|
+
* that is already parsed, or once the parser has finished the document.
|
|
3394
|
+
* @param {Element} el
|
|
3395
|
+
* @returns {Promise<Element>} the element
|
|
3781
3396
|
*/
|
|
3782
3397
|
static waitParsed(el) {
|
|
3783
|
-
if (Nodes.isParsed(el)) {
|
|
3398
|
+
if (Nodes.isParsed(el) || el.ownerDocument.readyState !== 'loading') {
|
|
3784
3399
|
return Promise.resolve(el);
|
|
3785
3400
|
}
|
|
3786
3401
|
return new Promise((resolve) => {
|
|
@@ -3802,10 +3417,10 @@ var ftl = (function (exports) {
|
|
|
3802
3417
|
}
|
|
3803
3418
|
|
|
3804
3419
|
/**
|
|
3805
|
-
*
|
|
3806
|
-
* @param {Element} el
|
|
3420
|
+
* The first child element matching the selector, descendants excluded.
|
|
3421
|
+
* @param {Element|DocumentFragment} el
|
|
3807
3422
|
* @param {string} selector
|
|
3808
|
-
* @returns
|
|
3423
|
+
* @returns {Element|null}
|
|
3809
3424
|
*/
|
|
3810
3425
|
static queryChildren(el, selector) {
|
|
3811
3426
|
for (const c of el.children) {
|
|
@@ -3816,10 +3431,10 @@ var ftl = (function (exports) {
|
|
|
3816
3431
|
return null;
|
|
3817
3432
|
}
|
|
3818
3433
|
/**
|
|
3819
|
-
*
|
|
3820
|
-
* @param {Element} el
|
|
3434
|
+
* Every child element matching the selector, descendants excluded.
|
|
3435
|
+
* @param {Element|DocumentFragment} el
|
|
3821
3436
|
* @param {string} selector
|
|
3822
|
-
* @returns
|
|
3437
|
+
* @returns {Element[]}
|
|
3823
3438
|
*/
|
|
3824
3439
|
static queryChildrenAll(el, selector) {
|
|
3825
3440
|
const r = [];
|
|
@@ -3876,9 +3491,11 @@ var ftl = (function (exports) {
|
|
|
3876
3491
|
|
|
3877
3492
|
/** The `data-tpl-*` commands, each taking the node it is written on and the scope it evaluates in. */
|
|
3878
3493
|
class CommandsHandler {
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3494
|
+
/**
|
|
3495
|
+
* The order the commands run in on one element, each seeing the node as the
|
|
3496
|
+
* ones before left it: tplIf gates before tplWith and tplEach push their
|
|
3497
|
+
* overlay, tplWhen gates after, inside the scope that overlay opened.
|
|
3498
|
+
*/
|
|
3882
3499
|
static ORDERED_COMMANDS = [
|
|
3883
3500
|
'tplIf',
|
|
3884
3501
|
'tplWith',
|
|
@@ -3889,8 +3506,7 @@ var ftl = (function (exports) {
|
|
|
3889
3506
|
'tplRemove',
|
|
3890
3507
|
'tplVerbatim',
|
|
3891
3508
|
];
|
|
3892
|
-
|
|
3893
|
-
//if evaluates in the outer scope, before with/each
|
|
3509
|
+
/** Removes the node when the expression is falsy, evaluated before tplWith and tplEach open their overlay. */
|
|
3894
3510
|
static tplIf(node, expression, ops, evaluator) {
|
|
3895
3511
|
const accept = evaluator.evaluateExpression(expression);
|
|
3896
3512
|
if (!accept) {
|
|
@@ -3905,49 +3521,37 @@ var ftl = (function (exports) {
|
|
|
3905
3521
|
.render();
|
|
3906
3522
|
ops.replace(node, newNode);
|
|
3907
3523
|
}
|
|
3524
|
+
/**
|
|
3525
|
+
* Renders the node once per entry, in place of the node. A Map iterates as
|
|
3526
|
+
* `{ key, value }` entries in its own order, a plain object as `{ key, value }`
|
|
3527
|
+
* entries in `Object.entries` order, and any other iterable as itself; a
|
|
3528
|
+
* value that is none of these throws. Each render sees its entry under
|
|
3529
|
+
* `data-tpl-var`, or as the whole overlay without one. `data-tpl-stat` names
|
|
3530
|
+
* an overlay beneath the entry carrying `index`, `count`, `size`, `first`,
|
|
3531
|
+
* `last`, `even` and `odd`, so an entry property of the same name wins; the
|
|
3532
|
+
* size, and so `last`, is null for a collection that knows neither its
|
|
3533
|
+
* `length` nor its `size`, which is never consumed to learn it.
|
|
3534
|
+
*/
|
|
3908
3535
|
static tplEach(node, expression, ops, evaluator) {
|
|
3909
3536
|
const varName = ops.popData(node, 'tplVar');
|
|
3910
3537
|
const statName = ops.popData(node, 'tplStat');
|
|
3911
3538
|
const template = new Template(node, evaluator);
|
|
3912
3539
|
const evaluated = evaluator.evaluateExpression(expression);
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
const proto = evaluated === null || typeof evaluated !== 'object' ? undefined : Object.getPrototypeOf(evaluated);
|
|
3919
|
-
const keyed =
|
|
3920
|
-
evaluated instanceof Map
|
|
3921
|
-
? [...evaluated]
|
|
3922
|
-
: !evaluated?.[Symbol.iterator] && (proto === Object.prototype || proto === null)
|
|
3923
|
-
? Object.entries(evaluated)
|
|
3924
|
-
: null;
|
|
3540
|
+
const proto =
|
|
3541
|
+
evaluated === null || typeof evaluated !== 'object' ? undefined : Object.getPrototypeOf(evaluated);
|
|
3542
|
+
const plain = !evaluated?.[Symbol.iterator] && (proto === Object.prototype || proto === null);
|
|
3543
|
+
const dict = plain ? Object.entries(evaluated) : null;
|
|
3544
|
+
const keyed = evaluated instanceof Map ? [...evaluated] : dict;
|
|
3925
3545
|
const entries = keyed === null ? evaluated : keyed.map(([key, value]) => ({ key, value }));
|
|
3926
3546
|
if (!entries?.[Symbol.iterator]) {
|
|
3927
3547
|
throw new Error(`Expected an iterable got '${evaluated}'`);
|
|
3928
3548
|
}
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
}
|
|
3933
|
-
ops.remove(node);
|
|
3934
|
-
return;
|
|
3935
|
-
}
|
|
3936
|
-
//the stat rides grouped under its declared name, overlaid below the
|
|
3937
|
-
//item, so data can never collide with its fields and an item property
|
|
3938
|
-
//sharing the stat's very name wins, as data always does. The size is
|
|
3939
|
-
//read where the collection already knows it (arrays and keyed entries
|
|
3940
|
-
//by length, sets and the like by size): an arbitrary iterator is never
|
|
3941
|
-
//consumed to learn it, so its size and last read null, the unknown
|
|
3942
|
-
const size = Array.isArray(entries)
|
|
3943
|
-
? entries.length
|
|
3944
|
-
: typeof entries.length === 'number'
|
|
3945
|
-
? entries.length
|
|
3946
|
-
: typeof entries.size === 'number'
|
|
3947
|
-
? entries.size
|
|
3948
|
-
: null;
|
|
3549
|
+
const measured = statName ? entries : null;
|
|
3550
|
+
const counted = typeof measured?.length === 'number' ? measured.length : measured?.size;
|
|
3551
|
+
const size = typeof counted === 'number' ? counted : null;
|
|
3949
3552
|
let index = 0;
|
|
3950
3553
|
for (const v of entries) {
|
|
3554
|
+
const item = varName ? { [varName]: v } : v;
|
|
3951
3555
|
const stat = {
|
|
3952
3556
|
index,
|
|
3953
3557
|
count: index + 1,
|
|
@@ -3957,16 +3561,13 @@ var ftl = (function (exports) {
|
|
|
3957
3561
|
even: index % 2 === 0,
|
|
3958
3562
|
odd: index % 2 === 1,
|
|
3959
3563
|
};
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
template.withOverlay({ [statName]: stat }, varName ? { [varName]: v } : v).render(),
|
|
3963
|
-
);
|
|
3564
|
+
const layers = statName ? [{ [statName]: stat }, item] : [item];
|
|
3565
|
+
ops.prepend(node, template.withOverlay(...layers).render());
|
|
3964
3566
|
++index;
|
|
3965
3567
|
}
|
|
3966
3568
|
ops.remove(node);
|
|
3967
3569
|
}
|
|
3968
|
-
|
|
3969
|
-
//when evaluates after with/each, in the scope their overlay opened
|
|
3570
|
+
/** Removes the node when the expression is falsy, evaluated in the overlay tplWith or tplEach opened. */
|
|
3970
3571
|
static tplWhen(node, expression, ops, evaluator) {
|
|
3971
3572
|
const accept = evaluator.evaluateExpression(expression);
|
|
3972
3573
|
if (!accept) {
|
|
@@ -3980,12 +3581,8 @@ var ftl = (function (exports) {
|
|
|
3980
3581
|
static tplRemove(node, value, ops, evaluator) {
|
|
3981
3582
|
switch (value.toLowerCase()) {
|
|
3982
3583
|
case 'tag': {
|
|
3983
|
-
const fragment =
|
|
3984
|
-
while (node.firstChild) {
|
|
3985
|
-
fragment.appendChild(node.firstChild);
|
|
3986
|
-
}
|
|
3584
|
+
const fragment = Fragments.fromChildNodes(node);
|
|
3987
3585
|
if ('tplVerbatim' in node.dataset) {
|
|
3988
|
-
//we are removing the parent element so we have to handle the lower priority commands
|
|
3989
3586
|
ops.popData(node, 'tplVerbatim');
|
|
3990
3587
|
ops.replace(node, fragment);
|
|
3991
3588
|
} else {
|
|
@@ -4021,6 +3618,9 @@ var ftl = (function (exports) {
|
|
|
4021
3618
|
}
|
|
4022
3619
|
const tuples = Array.isArray(attributesAndValues[0]) ? attributesAndValues : [attributesAndValues];
|
|
4023
3620
|
tuples.forEach(([k, v]) => {
|
|
3621
|
+
if (v === null || v === undefined) {
|
|
3622
|
+
return;
|
|
3623
|
+
}
|
|
4024
3624
|
node.setAttribute(k, v);
|
|
4025
3625
|
});
|
|
4026
3626
|
}
|
|
@@ -4048,12 +3648,10 @@ var ftl = (function (exports) {
|
|
|
4048
3648
|
}
|
|
4049
3649
|
}
|
|
4050
3650
|
|
|
4051
|
-
// Module-isolated string cache for dataset-to-attribute conversions
|
|
4052
3651
|
const attributeCache = new BoundedCache(1000);
|
|
4053
3652
|
|
|
4054
3653
|
/**
|
|
4055
|
-
*
|
|
4056
|
-
* Uses a cache lookup to avoid repetitive regex/string splitting.
|
|
3654
|
+
* The attribute a `tpl` dataset key targets: `tplAriaLabel` is `aria-label`.
|
|
4057
3655
|
* @param {string} dataSetKey
|
|
4058
3656
|
* @returns {string}
|
|
4059
3657
|
*/
|
|
@@ -4075,38 +3673,40 @@ var ftl = (function (exports) {
|
|
|
4075
3673
|
*/
|
|
4076
3674
|
class Template {
|
|
4077
3675
|
/**
|
|
4078
|
-
* Creates a template from
|
|
3676
|
+
* Creates a template from html.
|
|
4079
3677
|
* @param {string} html
|
|
4080
3678
|
* @param {{ [k: string] : any }?} [modules]
|
|
4081
|
-
* @param {...*} data
|
|
4082
|
-
* @returns
|
|
3679
|
+
* @param {...*} data the data stack, innermost last
|
|
3680
|
+
* @returns {Template}
|
|
4083
3681
|
*/
|
|
4084
3682
|
static fromHtml(html, modules, ...data) {
|
|
4085
3683
|
return new Template(Fragments.fromHtml(html), new ExpressionEvaluator(modules, data));
|
|
4086
3684
|
}
|
|
4087
3685
|
|
|
4088
3686
|
/**
|
|
4089
|
-
* Creates a template from the content of the first
|
|
3687
|
+
* Creates a template from the content of the first element matching the
|
|
3688
|
+
* selector, which is adopted: the template element is left empty.
|
|
4090
3689
|
* @param {string} selector for an HTMLTemplateElement
|
|
4091
3690
|
* @param {{ [k: string] : any }?} [modules]
|
|
4092
|
-
* @param {...*} data
|
|
4093
|
-
* @returns
|
|
3691
|
+
* @param {...*} data the data stack, innermost last
|
|
3692
|
+
* @returns {Template}
|
|
3693
|
+
* @throws when the selector matches no template element
|
|
4094
3694
|
*/
|
|
4095
3695
|
static fromSelector(selector, modules, ...data) {
|
|
4096
3696
|
const templateEl = document.querySelector(selector);
|
|
4097
3697
|
if (!(templateEl instanceof HTMLTemplateElement)) {
|
|
4098
3698
|
throw new Error('template selector does not match any template tag');
|
|
4099
3699
|
}
|
|
4100
|
-
|
|
4101
|
-
return new Template(fragment, new ExpressionEvaluator(modules, data));
|
|
3700
|
+
return Template.fromTemplate(templateEl, modules, ...data);
|
|
4102
3701
|
}
|
|
4103
3702
|
|
|
4104
3703
|
/**
|
|
4105
|
-
* Creates a template from the content of
|
|
3704
|
+
* Creates a template from the content of a template element, which is
|
|
3705
|
+
* adopted: the template element is left empty.
|
|
4106
3706
|
* @param {HTMLTemplateElement} templateEl
|
|
4107
3707
|
* @param {{ [k: string] : any }?} [modules]
|
|
4108
|
-
* @param {...*} data
|
|
4109
|
-
* @returns
|
|
3708
|
+
* @param {...*} data the data stack, innermost last
|
|
3709
|
+
* @returns {Template}
|
|
4110
3710
|
*/
|
|
4111
3711
|
static fromTemplate(templateEl, modules, ...data) {
|
|
4112
3712
|
const fragment = document.adoptNode(templateEl.content);
|
|
@@ -4114,11 +3714,12 @@ var ftl = (function (exports) {
|
|
|
4114
3714
|
}
|
|
4115
3715
|
|
|
4116
3716
|
/**
|
|
4117
|
-
* Creates a template
|
|
3717
|
+
* Creates a template over a fragment, which is imported afresh on every
|
|
3718
|
+
* render and never modified.
|
|
4118
3719
|
* @param {DocumentFragment} fragment
|
|
4119
3720
|
* @param { { [k: string] : any }? } [modules]
|
|
4120
|
-
* @param {...*} data
|
|
4121
|
-
* @returns
|
|
3721
|
+
* @param {...*} data the data stack, innermost last
|
|
3722
|
+
* @returns {Template}
|
|
4122
3723
|
*/
|
|
4123
3724
|
static fromFragment(fragment, modules, ...data) {
|
|
4124
3725
|
return new Template(fragment, new ExpressionEvaluator(modules, data));
|
|
@@ -4138,28 +3739,32 @@ var ftl = (function (exports) {
|
|
|
4138
3739
|
* Creates a new Template rendering in another scope: the one way to rebind
|
|
4139
3740
|
* a compiled template to a registry's modules and data.
|
|
4140
3741
|
* @param {ExpressionEvaluator} evaluator
|
|
3742
|
+
* @returns {Template}
|
|
4141
3743
|
*/
|
|
4142
3744
|
withEvaluator(evaluator) {
|
|
4143
3745
|
return new Template(this.#fragment, evaluator);
|
|
4144
3746
|
}
|
|
4145
3747
|
/**
|
|
4146
|
-
* Creates a new Template
|
|
3748
|
+
* Creates a new Template over another fragment, in the same scope.
|
|
4147
3749
|
* @param {DocumentFragment} fragment
|
|
3750
|
+
* @returns {Template}
|
|
4148
3751
|
*/
|
|
4149
3752
|
withFragment(fragment) {
|
|
4150
3753
|
return new Template(fragment, this.#evaluator);
|
|
4151
3754
|
}
|
|
4152
3755
|
/**
|
|
4153
|
-
* Creates a new Template with a
|
|
3756
|
+
* Creates a new Template with a module added, as `ExpressionEvaluator.withModule` does.
|
|
4154
3757
|
* @param {string?} name
|
|
4155
3758
|
* @param {{[k: string]: any}} value
|
|
3759
|
+
* @returns {Template}
|
|
4156
3760
|
*/
|
|
4157
3761
|
withModule(name, value) {
|
|
4158
3762
|
return new Template(this.#fragment, this.#evaluator.withModule(name, value));
|
|
4159
3763
|
}
|
|
4160
3764
|
/**
|
|
4161
|
-
* Creates a new Template with
|
|
3765
|
+
* Creates a new Template with the data pushed as the innermost overlays.
|
|
4162
3766
|
* @param {...*} data
|
|
3767
|
+
* @returns {Template}
|
|
4163
3768
|
*/
|
|
4164
3769
|
withOverlay(...data) {
|
|
4165
3770
|
return new Template(this.#fragment, this.#evaluator.withOverlay(...data));
|
|
@@ -4168,7 +3773,7 @@ var ftl = (function (exports) {
|
|
|
4168
3773
|
* Evaluates an expression in this template's scope, widened by the overlays.
|
|
4169
3774
|
* @param {string} expression
|
|
4170
3775
|
* @param {...*} data
|
|
4171
|
-
* @returns
|
|
3776
|
+
* @returns {any}
|
|
4172
3777
|
*/
|
|
4173
3778
|
evaluateExpression(expression, ...data) {
|
|
4174
3779
|
return this.#evaluator.withOverlay(...data).evaluateExpression(expression);
|
|
@@ -4177,33 +3782,29 @@ var ftl = (function (exports) {
|
|
|
4177
3782
|
* Evaluates a templated text, the `{{ }}` form, in this template's scope.
|
|
4178
3783
|
* @param {string} text
|
|
4179
3784
|
* @param {...*} data
|
|
4180
|
-
* @returns the parts
|
|
3785
|
+
* @returns {{ type: symbol, value: any }[]} the parts, as `Expressions.MODE_TEMPLATED` describes
|
|
4181
3786
|
*/
|
|
4182
3787
|
evaluateTemplated(text, ...data) {
|
|
4183
3788
|
return this.#evaluator.withOverlay(...data).evaluateTemplated(text);
|
|
4184
3789
|
}
|
|
4185
3790
|
/**
|
|
4186
|
-
*
|
|
3791
|
+
* The scope this template renders in.
|
|
3792
|
+
* @returns {ExpressionEvaluator}
|
|
4187
3793
|
*/
|
|
4188
3794
|
evaluator() {
|
|
4189
3795
|
return this.#evaluator;
|
|
4190
3796
|
}
|
|
4191
3797
|
/**
|
|
4192
|
-
* Renders the template
|
|
4193
|
-
*
|
|
3798
|
+
* Renders the template into a new fragment, applying the `data-tpl-*`
|
|
3799
|
+
* commands and bindings and the `{{ }}` interpolations.
|
|
3800
|
+
* @returns {DocumentFragment}
|
|
3801
|
+
* @throws {RenderError} naming the node and the directive that failed
|
|
4194
3802
|
*/
|
|
4195
3803
|
render() {
|
|
4196
3804
|
try {
|
|
4197
3805
|
const ops = new NodeOperations();
|
|
4198
3806
|
const imported = document.importNode(this.#fragment, true);
|
|
4199
|
-
const fragment =
|
|
4200
|
-
imported.nodeType === Node.DOCUMENT_FRAGMENT_NODE
|
|
4201
|
-
? imported
|
|
4202
|
-
: (() => {
|
|
4203
|
-
const d = new DocumentFragment();
|
|
4204
|
-
d.appendChild(imported);
|
|
4205
|
-
return d;
|
|
4206
|
-
})();
|
|
3807
|
+
const fragment = imported.nodeType === Node.DOCUMENT_FRAGMENT_NODE ? imported : Fragments.from(imported);
|
|
4207
3808
|
const iterator = document.createNodeIterator(
|
|
4208
3809
|
fragment,
|
|
4209
3810
|
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
|
|
@@ -4229,8 +3830,6 @@ var ftl = (function (exports) {
|
|
|
4229
3830
|
try {
|
|
4230
3831
|
CommandsHandler[command](el, value, ops, this.#evaluator);
|
|
4231
3832
|
} catch (ex) {
|
|
4232
|
-
//the directive is popped before it runs, so the open tag no
|
|
4233
|
-
//longer carries it: the frame names it and its expression
|
|
4234
3833
|
throw RenderError.wrap(`Error evaluating data-tpl-${toAttr(command)}="${value}"`, el, ex);
|
|
4235
3834
|
}
|
|
4236
3835
|
if (ops.removed(el)) {
|
|
@@ -4253,17 +3852,13 @@ var ftl = (function (exports) {
|
|
|
4253
3852
|
el.setAttribute(attributeName, evaluated);
|
|
4254
3853
|
}
|
|
4255
3854
|
} catch (ex) {
|
|
4256
|
-
throw RenderError.wrap(`Error evaluating data-tpl-${
|
|
3855
|
+
throw RenderError.wrap(`Error evaluating data-tpl-${attributeName}="${expression}"`, el, ex);
|
|
4257
3856
|
}
|
|
4258
3857
|
}
|
|
4259
3858
|
}
|
|
4260
3859
|
ops.cleanup();
|
|
4261
3860
|
return fragment;
|
|
4262
3861
|
} catch (ex) {
|
|
4263
|
-
//a command, a text node or a nested render already named the node it
|
|
4264
|
-
//failed on: wrapping again would add a frame for the fragment that
|
|
4265
|
-
//contains it, one per level, serializing the whole template into the
|
|
4266
|
-
//message that survives. Only a failure outside those is framed here
|
|
4267
3862
|
if (ex instanceof RenderError) {
|
|
4268
3863
|
throw ex;
|
|
4269
3864
|
}
|
|
@@ -4271,22 +3866,26 @@ var ftl = (function (exports) {
|
|
|
4271
3866
|
}
|
|
4272
3867
|
}
|
|
4273
3868
|
/**
|
|
4274
|
-
* Renders this template
|
|
3869
|
+
* Renders this template into the element, replacing its children.
|
|
4275
3870
|
* @param {Element} el
|
|
3871
|
+
* @throws {RenderError}
|
|
4276
3872
|
*/
|
|
4277
3873
|
renderTo(el) {
|
|
4278
3874
|
el.replaceChildren(this.render());
|
|
4279
3875
|
}
|
|
4280
3876
|
/**
|
|
4281
|
-
* Renders this template
|
|
3877
|
+
* Renders this template and appends the result to the element.
|
|
4282
3878
|
* @param {Element} el
|
|
3879
|
+
* @throws {RenderError}
|
|
4283
3880
|
*/
|
|
4284
3881
|
appendTo(el) {
|
|
4285
3882
|
el.appendChild(this.render());
|
|
4286
3883
|
}
|
|
4287
3884
|
/**
|
|
4288
|
-
* Renders this template
|
|
3885
|
+
* Renders this template into the first element matching the selector,
|
|
3886
|
+
* replacing its children; does nothing when none matches.
|
|
4289
3887
|
* @param {string} selector
|
|
3888
|
+
* @throws {RenderError}
|
|
4290
3889
|
*/
|
|
4291
3890
|
renderToSelector(selector) {
|
|
4292
3891
|
const el = document.querySelector(selector);
|
|
@@ -4295,8 +3894,10 @@ var ftl = (function (exports) {
|
|
|
4295
3894
|
}
|
|
4296
3895
|
}
|
|
4297
3896
|
/**
|
|
4298
|
-
* Renders this template
|
|
3897
|
+
* Renders this template and appends the result to the first element
|
|
3898
|
+
* matching the selector; does nothing when none matches.
|
|
4299
3899
|
* @param {string} selector
|
|
3900
|
+
* @throws {RenderError}
|
|
4300
3901
|
*/
|
|
4301
3902
|
appendToSelector(selector) {
|
|
4302
3903
|
const el = document.querySelector(selector);
|
|
@@ -4320,30 +3921,26 @@ var ftl = (function (exports) {
|
|
|
4320
3921
|
}
|
|
4321
3922
|
|
|
4322
3923
|
/**
|
|
4323
|
-
* A render failure, one frame per nesting level
|
|
4324
|
-
*
|
|
4325
|
-
*
|
|
4326
|
-
*
|
|
4327
|
-
* the
|
|
4328
|
-
* `node`, so a failure costs no clone and a nested failure does not embed the
|
|
4329
|
-
* page in its own message.
|
|
3924
|
+
* A render failure, one frame per nesting level, chained through `cause` from
|
|
3925
|
+
* the outermost frame down to the error that failed the expression. A frame's
|
|
3926
|
+
* message names what was being evaluated and the node's open tag, with the
|
|
3927
|
+
* attributes it still carries: the directive being evaluated is already off
|
|
3928
|
+
* the tag. The subtree is not in the message; `html` serializes it on demand.
|
|
4330
3929
|
*/
|
|
4331
3930
|
class RenderError extends Error {
|
|
4332
|
-
/**
|
|
4333
|
-
* How many frames a chain keeps. The innermost are the specific ones, so a
|
|
4334
|
-
* deeper nesting drops the outer context rather than the failure site: three
|
|
4335
|
-
* frames name the offending node and the two levels that hold it, which is
|
|
4336
|
-
* the path a reader follows without the page arriving with it.
|
|
4337
|
-
*/
|
|
3931
|
+
/** How many frames a chain keeps: a deeper nesting drops the outermost ones and marks the chain `truncated`. */
|
|
4338
3932
|
static FRAMES = 3;
|
|
4339
3933
|
#node;
|
|
4340
3934
|
#depth;
|
|
4341
|
-
/**
|
|
3935
|
+
/** Whether the chain dropped outer frames to stay within FRAMES. */
|
|
4342
3936
|
truncated = false;
|
|
4343
3937
|
/**
|
|
4344
|
-
* Frames a failure, unless the chain already
|
|
4345
|
-
* cause
|
|
4346
|
-
*
|
|
3938
|
+
* Frames a failure, unless the chain already holds FRAMES frames: then the
|
|
3939
|
+
* cause is returned as it is, marked `truncated`.
|
|
3940
|
+
* @param {string} message
|
|
3941
|
+
* @param {Node} nodeOrFragment the node that failed
|
|
3942
|
+
* @param {any} cause
|
|
3943
|
+
* @returns {RenderError}
|
|
4347
3944
|
*/
|
|
4348
3945
|
static wrap(message, nodeOrFragment, cause) {
|
|
4349
3946
|
if (cause instanceof RenderError && cause.depth >= RenderError.FRAMES) {
|
|
@@ -4352,27 +3949,44 @@ var ftl = (function (exports) {
|
|
|
4352
3949
|
}
|
|
4353
3950
|
return new RenderError(message, nodeOrFragment, cause);
|
|
4354
3951
|
}
|
|
3952
|
+
/**
|
|
3953
|
+
* @param {string} message
|
|
3954
|
+
* @param {Node} nodeOrFragment the node that failed
|
|
3955
|
+
* @param {any} cause
|
|
3956
|
+
*/
|
|
4355
3957
|
constructor(message, nodeOrFragment, cause) {
|
|
4356
3958
|
super(`${message} in \`${RenderError.describe(nodeOrFragment)}\``, { cause });
|
|
4357
3959
|
this.name = 'RenderError';
|
|
4358
3960
|
this.#node = nodeOrFragment;
|
|
4359
3961
|
this.#depth = (cause instanceof RenderError ? cause.depth : 0) + 1;
|
|
4360
3962
|
}
|
|
4361
|
-
/**
|
|
3963
|
+
/**
|
|
3964
|
+
* How many frames this chain carries, this one included.
|
|
3965
|
+
* @returns {number}
|
|
3966
|
+
*/
|
|
4362
3967
|
get depth() {
|
|
4363
3968
|
return this.#depth;
|
|
4364
3969
|
}
|
|
4365
|
-
/**
|
|
3970
|
+
/**
|
|
3971
|
+
* The node the render failed on, live in the fragment being built.
|
|
3972
|
+
* @returns {Node}
|
|
3973
|
+
*/
|
|
4366
3974
|
get node() {
|
|
4367
3975
|
return this.#node;
|
|
4368
3976
|
}
|
|
4369
|
-
/**
|
|
3977
|
+
/**
|
|
3978
|
+
* The failed node's markup, whitespace trimmed, serialized on each read.
|
|
3979
|
+
* @returns {string}
|
|
3980
|
+
*/
|
|
4370
3981
|
get html() {
|
|
4371
3982
|
return RenderError.stringify(this.#node);
|
|
4372
3983
|
}
|
|
4373
3984
|
/**
|
|
4374
3985
|
* What identifies a node in a frame: an element by its open tag, a text node
|
|
4375
|
-
* by its source, a fragment by the open tags of the elements it holds
|
|
3986
|
+
* by its source, a fragment by the open tags of the elements it holds, cut
|
|
3987
|
+
* at 120 characters.
|
|
3988
|
+
* @param {Node} nodeOrFragment
|
|
3989
|
+
* @returns {string}
|
|
4376
3990
|
*/
|
|
4377
3991
|
static describe(nodeOrFragment) {
|
|
4378
3992
|
if (nodeOrFragment.nodeType === Node.TEXT_NODE) {
|
|
@@ -4391,10 +4005,13 @@ var ftl = (function (exports) {
|
|
|
4391
4005
|
static #ellipsize(text) {
|
|
4392
4006
|
return text.length > 120 ? `${text.slice(0, 120)}…` : text;
|
|
4393
4007
|
}
|
|
4008
|
+
/**
|
|
4009
|
+
* A node's markup with its whitespace-only text dropped and the rest trimmed.
|
|
4010
|
+
* @param {Node} nodeOrFragment left untouched: a clone is serialized
|
|
4011
|
+
* @returns {string}
|
|
4012
|
+
*/
|
|
4394
4013
|
static stringify(nodeOrFragment) {
|
|
4395
|
-
|
|
4396
|
-
t.content.appendChild(RenderError.#cleanup(nodeOrFragment.cloneNode(true)));
|
|
4397
|
-
return t.innerHTML;
|
|
4014
|
+
return Fragments.toHtml(RenderError.#cleanup(nodeOrFragment.cloneNode(true)));
|
|
4398
4015
|
}
|
|
4399
4016
|
static #cleanup(node) {
|
|
4400
4017
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
@@ -4416,11 +4033,6 @@ var ftl = (function (exports) {
|
|
|
4416
4033
|
}
|
|
4417
4034
|
}
|
|
4418
4035
|
|
|
4419
|
-
/**
|
|
4420
|
-
* Tracks the elements waiting to render. `ready` resolves once the queue has
|
|
4421
|
-
* drained and never rejects; the promise kept per element resolves when that
|
|
4422
|
-
* element has rendered and rejects with whatever its upgrade threw.
|
|
4423
|
-
*/
|
|
4424
4036
|
class UpgradeQueue {
|
|
4425
4037
|
#q = new Map();
|
|
4426
4038
|
#readyResolve;
|
|
@@ -4432,12 +4044,6 @@ var ftl = (function (exports) {
|
|
|
4432
4044
|
this.#start();
|
|
4433
4045
|
});
|
|
4434
4046
|
}
|
|
4435
|
-
/**
|
|
4436
|
-
* Waits for the page's readiness: the promise resolves right after the
|
|
4437
|
-
* ftl:ready event is dispatched, and immediately when that moment already
|
|
4438
|
-
* passed.
|
|
4439
|
-
* @returns {Promise<void>}
|
|
4440
|
-
*/
|
|
4441
4047
|
ready() {
|
|
4442
4048
|
return this.#ready;
|
|
4443
4049
|
}
|
|
@@ -4453,13 +4059,8 @@ var ftl = (function (exports) {
|
|
|
4453
4059
|
}
|
|
4454
4060
|
enqueue(el) {
|
|
4455
4061
|
if (this.#q.has(el)) {
|
|
4456
|
-
//already upgrading, can happen when disconnecting an element
|
|
4457
|
-
//while it's already queued for upgrade (e.g.: ful-form)
|
|
4458
4062
|
return;
|
|
4459
4063
|
}
|
|
4460
|
-
//one entry, two signals: readiness waits on a signal that only ever
|
|
4461
|
-
//resolves, so nothing here attaches a rejection handler to the upgrade
|
|
4462
|
-
//itself and a component that fails is still reported the way it always was
|
|
4463
4064
|
const { promise: finished, resolve: markFinished } = /** @type {PromiseWithResolvers<void>} */ (
|
|
4464
4065
|
Promise.withResolvers()
|
|
4465
4066
|
);
|
|
@@ -4471,11 +4072,6 @@ var ftl = (function (exports) {
|
|
|
4471
4072
|
});
|
|
4472
4073
|
this.#q.set(el, { upgrade, finished });
|
|
4473
4074
|
}
|
|
4474
|
-
/**
|
|
4475
|
-
* The one fixed-point loop: drains the accepted entries, including the ones
|
|
4476
|
-
* enqueued while waiting, since a component is only queued once its parent
|
|
4477
|
-
* connects it and a single pass would miss everything nested.
|
|
4478
|
-
*/
|
|
4479
4075
|
async #drain(accept, pick) {
|
|
4480
4076
|
for (;;) {
|
|
4481
4077
|
const pending = Array.from(this.#q)
|
|
@@ -4488,22 +4084,25 @@ var ftl = (function (exports) {
|
|
|
4488
4084
|
}
|
|
4489
4085
|
}
|
|
4490
4086
|
/**
|
|
4491
|
-
* Waits for the whole queue to drain
|
|
4492
|
-
*
|
|
4493
|
-
*
|
|
4087
|
+
* Waits for the whole queue to drain, the upgrades enqueued meanwhile included.
|
|
4088
|
+
* Never rejects: a failed upgrade counts as drained.
|
|
4089
|
+
* @returns {Promise<void>}
|
|
4494
4090
|
*/
|
|
4495
4091
|
settled() {
|
|
4496
4092
|
return this.#drain(() => true, (entry) => entry.finished);
|
|
4497
4093
|
}
|
|
4498
|
-
/**
|
|
4094
|
+
/**
|
|
4095
|
+
* Waits for the accepted upgrades, the ones enqueued meanwhile included,
|
|
4096
|
+
* rejecting with the first that failed.
|
|
4097
|
+
* @param {(el: Element) => boolean} accept
|
|
4098
|
+
* @returns {Promise<void>}
|
|
4099
|
+
*/
|
|
4499
4100
|
upgraded(accept) {
|
|
4500
4101
|
return this.#drain(accept, (entry) => entry.upgrade);
|
|
4501
4102
|
}
|
|
4502
|
-
/** The pending upgrade of one element, undefined when it is not queued. */
|
|
4503
4103
|
whenUpgraded(el) {
|
|
4504
4104
|
return this.#q.get(el)?.upgrade;
|
|
4505
4105
|
}
|
|
4506
|
-
/** The elements whose upgrade is still pending, in queue order. */
|
|
4507
4106
|
pending() {
|
|
4508
4107
|
return Array.from(this.#q.keys());
|
|
4509
4108
|
}
|
|
@@ -4514,8 +4113,8 @@ var ftl = (function (exports) {
|
|
|
4514
4113
|
* and attribute mappers. Elements defined before configure() are deferred and
|
|
4515
4114
|
* defined by it; from then on every defineElement takes effect immediately.
|
|
4516
4115
|
* The exported `registry` singleton is the page's own; a `new Registry()` is a
|
|
4517
|
-
* separate instance
|
|
4518
|
-
* singleton alone.
|
|
4116
|
+
* separate instance with its own upgrade queue, which dispatches its own
|
|
4117
|
+
* ftl:ready on the document, while Rendering waits on the singleton alone.
|
|
4519
4118
|
*/
|
|
4520
4119
|
class Registry {
|
|
4521
4120
|
#tagToClass = {};
|
|
@@ -4584,9 +4183,12 @@ var ftl = (function (exports) {
|
|
|
4584
4183
|
* Registers a custom element under its tag: the class is augmented with its
|
|
4585
4184
|
* BITS (observed attributes, mappers, templates) and handed to the platform.
|
|
4586
4185
|
* Before configure() the definition is deferred, so import order never
|
|
4587
|
-
* matters.
|
|
4186
|
+
* matters. The element resolves its templates and components through this
|
|
4187
|
+
* registry, whichever one a module imports, and its `static config` is read
|
|
4188
|
+
* here, so a page replacing it does so before the definition.
|
|
4588
4189
|
* @param {string} tag
|
|
4589
4190
|
* @param {*} klass a ParsedElement subclass
|
|
4191
|
+
* @returns {Registry} this registry
|
|
4590
4192
|
*/
|
|
4591
4193
|
defineElement(tag, klass) {
|
|
4592
4194
|
if (!this.#configured) {
|
|
@@ -4604,13 +4206,8 @@ var ftl = (function (exports) {
|
|
|
4604
4206
|
* ancestors', so a base class declares what every subclass keeps observing
|
|
4605
4207
|
* (a protocol attribute such as Field's disabled claim) and a leaf refines a
|
|
4606
4208
|
* mapping, or moves a name's position, without repeating the whole list.
|
|
4607
|
-
*
|
|
4608
|
-
*
|
|
4609
|
-
* stop can work, since a registered ancestor carries an own BITS of its own,
|
|
4610
|
-
* and nothing above the elements declares anything.
|
|
4611
|
-
*
|
|
4612
|
-
* Everything deriving a component's attribute vocabulary reads it here, so
|
|
4613
|
-
* the runtime and whatever documents it cannot walk the chain differently.
|
|
4209
|
+
* The observed attributes are applied in the composed order, a re-declared
|
|
4210
|
+
* name taking the position of its last declaration.
|
|
4614
4211
|
* @param {*} klass a ParsedElement subclass
|
|
4615
4212
|
* @returns {{ observed: string[], attributes: string[] }}
|
|
4616
4213
|
*/
|
|
@@ -4626,14 +4223,7 @@ var ftl = (function (exports) {
|
|
|
4626
4223
|
* The property an observed attribute drives, by the platform's own
|
|
4627
4224
|
* dash-to-camel rule: the one `dataset` applies, so `clear-invalid-on-change`
|
|
4628
4225
|
* would reach `clearInvalidOnChange` the way `data-clear-invalid-on-change`
|
|
4629
|
-
* reaches `dataset.clearInvalidOnChange`.
|
|
4630
|
-
* unchanged, which is what every observed attribute in the library is.
|
|
4631
|
-
*
|
|
4632
|
-
* It exists because the observed tier is the one that becomes properties:
|
|
4633
|
-
* without it an attribute could only be observed if its name happened to be
|
|
4634
|
-
* a usable identifier, which is why every multiword observed attribute here
|
|
4635
|
-
* used to be squashed into one word while the configuration tier, which
|
|
4636
|
-
* never becomes a property, spelled the same idea with a dash.
|
|
4226
|
+
* reaches `dataset.clearInvalidOnChange`.
|
|
4637
4227
|
*
|
|
4638
4228
|
* Only this direction is mapped. A property never derives its attribute: a
|
|
4639
4229
|
* setter reflects through `reflectTo`, naming the attribute it writes.
|
|
@@ -4646,10 +4236,6 @@ var ftl = (function (exports) {
|
|
|
4646
4236
|
#augmentAndDefineElement(tag, klass) {
|
|
4647
4237
|
const { observed, attributes } = Registry.declarationsOf(klass);
|
|
4648
4238
|
const { template, templates, slots, mappers, config } = klass;
|
|
4649
|
-
//a name a subclass re-declares takes the subclass's position, which is
|
|
4650
|
-
//how a field whose value setter reads its own shape attributes declares
|
|
4651
|
-
//that its value lands after them: the order the declarations compose in
|
|
4652
|
-
//is the order the base applies them
|
|
4653
4239
|
const declaredNames = observed.map((a) => a.split(':')[0]);
|
|
4654
4240
|
const observedNames = [...new Set(declaredNames.reverse())].reverse();
|
|
4655
4241
|
const attrToMapper = [...attributes, ...observed].reduce((acc, a) => {
|
|
@@ -4668,20 +4254,13 @@ var ftl = (function (exports) {
|
|
|
4668
4254
|
const nameToTemplate = Object.fromEntries(namesAndTemplates);
|
|
4669
4255
|
|
|
4670
4256
|
klass.BITS = {
|
|
4671
|
-
//the defining registry travels with the definition: an element resolves
|
|
4672
|
-
//its templates and its components through the registry that defined it,
|
|
4673
|
-
//not through whichever one a module happened to import
|
|
4674
4257
|
registry: this,
|
|
4675
4258
|
enqueue: (el) => this.#upgradeQueue.enqueue(el),
|
|
4676
4259
|
SLOTS: slots,
|
|
4677
|
-
//the class's own constants, overlaid on its templates as `config`:
|
|
4678
|
-
//read here with the rest of the declaration, so a page replacing them
|
|
4679
|
-
//does it before configure() like every other definition-time choice
|
|
4680
4260
|
CONFIG: config,
|
|
4681
4261
|
OBSERVED: observedNames,
|
|
4682
4262
|
DECLARED: [...new Set([...observedNames, ...attributes.map((a) => a.split(':')[0])])],
|
|
4683
4263
|
ATTR_TO_MAPPER: attrToMapper,
|
|
4684
|
-
//resolved once here rather than at every attribute write
|
|
4685
4264
|
ATTR_TO_PROPERTY: Object.fromEntries(observedNames.map((a) => [a, Registry.propertyOf(a)])),
|
|
4686
4265
|
TEMPLATES: nameToTemplate,
|
|
4687
4266
|
};
|
|
@@ -4693,6 +4272,7 @@ var ftl = (function (exports) {
|
|
|
4693
4272
|
* as `#fn`.
|
|
4694
4273
|
* @param {string} name
|
|
4695
4274
|
* @param {object} value
|
|
4275
|
+
* @returns {Registry} this registry
|
|
4696
4276
|
*/
|
|
4697
4277
|
defineModule(name, value) {
|
|
4698
4278
|
const module = name ? { [name]: value } : value;
|
|
@@ -4703,6 +4283,7 @@ var ftl = (function (exports) {
|
|
|
4703
4283
|
/**
|
|
4704
4284
|
* Replaces the whole module map.
|
|
4705
4285
|
* @param {object} ms
|
|
4286
|
+
* @returns {Registry} this registry
|
|
4706
4287
|
*/
|
|
4707
4288
|
defineModules(ms) {
|
|
4708
4289
|
this.#modules = ms;
|
|
@@ -4714,6 +4295,7 @@ var ftl = (function (exports) {
|
|
|
4714
4295
|
* through component().
|
|
4715
4296
|
* @param {string} name
|
|
4716
4297
|
* @param {*} value
|
|
4298
|
+
* @returns {Registry} this registry
|
|
4717
4299
|
*/
|
|
4718
4300
|
defineComponent(name, value) {
|
|
4719
4301
|
this.#components[name] = value;
|
|
@@ -4722,6 +4304,7 @@ var ftl = (function (exports) {
|
|
|
4722
4304
|
/**
|
|
4723
4305
|
* Replaces the data stack the templates evaluate over.
|
|
4724
4306
|
* @param {...any} data
|
|
4307
|
+
* @returns {Registry} this registry
|
|
4725
4308
|
*/
|
|
4726
4309
|
defineData(...data) {
|
|
4727
4310
|
this.#data = data;
|
|
@@ -4731,6 +4314,7 @@ var ftl = (function (exports) {
|
|
|
4731
4314
|
/**
|
|
4732
4315
|
* Appends to the data stack, the later entry winning a shared name.
|
|
4733
4316
|
* @param {...any} data
|
|
4317
|
+
* @returns {Registry} this registry
|
|
4734
4318
|
*/
|
|
4735
4319
|
defineOverlay(...data) {
|
|
4736
4320
|
this.#data = [...this.#data, ...data];
|
|
@@ -4742,6 +4326,7 @@ var ftl = (function (exports) {
|
|
|
4742
4326
|
* `name:type` declaration.
|
|
4743
4327
|
* @param {string} k
|
|
4744
4328
|
* @param {{ unmarshal(str: string|null, name: string, el: Element): any, marshal(value: any, name: string, el: Element): string|null }} v
|
|
4329
|
+
* @returns {Registry} this registry
|
|
4745
4330
|
*/
|
|
4746
4331
|
defineMapper(k, v) {
|
|
4747
4332
|
this.#mappers[k] = v;
|
|
@@ -4750,6 +4335,7 @@ var ftl = (function (exports) {
|
|
|
4750
4335
|
/**
|
|
4751
4336
|
* Hands the registry over to the plugin's configure.
|
|
4752
4337
|
* @param {{ configure(registry: Registry): void }} p
|
|
4338
|
+
* @returns {Registry} this registry
|
|
4753
4339
|
*/
|
|
4754
4340
|
plugin(p) {
|
|
4755
4341
|
p.configure(this);
|
|
@@ -4758,6 +4344,7 @@ var ftl = (function (exports) {
|
|
|
4758
4344
|
/**
|
|
4759
4345
|
* Defines every element deferred so far; from then on, defineElement takes
|
|
4760
4346
|
* effect immediately.
|
|
4347
|
+
* @returns {Registry} this registry
|
|
4761
4348
|
*/
|
|
4762
4349
|
configure() {
|
|
4763
4350
|
for (const [tag, klass] of Object.entries(this.#tagToClass)) {
|
|
@@ -4769,23 +4356,36 @@ var ftl = (function (exports) {
|
|
|
4769
4356
|
}
|
|
4770
4357
|
/**
|
|
4771
4358
|
* Waits for the queued upgrades the filter accepts, rejecting with the first
|
|
4772
|
-
* that failed
|
|
4359
|
+
* that failed, the upgrades enqueued meanwhile included: the rejecting
|
|
4360
|
+
* barrier Rendering is a facade over.
|
|
4773
4361
|
* @param {(el: Element) => boolean} accept
|
|
4362
|
+
* @returns {Promise<void>}
|
|
4774
4363
|
*/
|
|
4775
4364
|
settle(accept) {
|
|
4776
4365
|
return this.#upgradeQueue.upgraded(accept);
|
|
4777
4366
|
}
|
|
4778
|
-
/**
|
|
4367
|
+
/**
|
|
4368
|
+
* The pending upgrade of one element: resolving when it has rendered,
|
|
4369
|
+
* rejecting with what its upgrade threw.
|
|
4370
|
+
* @param {Element} el
|
|
4371
|
+
* @returns {Promise<void>|undefined} undefined when the element is not queued
|
|
4372
|
+
*/
|
|
4779
4373
|
whenUpgraded(el) {
|
|
4780
4374
|
return this.#upgradeQueue.whenUpgraded(el);
|
|
4781
4375
|
}
|
|
4782
|
-
/**
|
|
4376
|
+
/**
|
|
4377
|
+
* The elements whose upgrade is still pending, in queue order.
|
|
4378
|
+
* @returns {Element[]}
|
|
4379
|
+
*/
|
|
4783
4380
|
pending() {
|
|
4784
4381
|
return this.#upgradeQueue.pending();
|
|
4785
4382
|
}
|
|
4786
4383
|
/**
|
|
4787
|
-
* Waits for
|
|
4788
|
-
* dispatched
|
|
4384
|
+
* Waits for this registry's readiness: resolves right after its ftl:ready
|
|
4385
|
+
* event is dispatched on the document, and immediately when that already
|
|
4386
|
+
* happened. Never rejects: a failed upgrade counts as settled, and its
|
|
4387
|
+
* rejection is left unhandled so it still reaches the console and the
|
|
4388
|
+
* page's error reporting.
|
|
4789
4389
|
* @returns {Promise<void>}
|
|
4790
4390
|
*/
|
|
4791
4391
|
ready() {
|
|
@@ -4798,11 +4398,16 @@ var ftl = (function (exports) {
|
|
|
4798
4398
|
* The scope every template on this registry renders in: the modules and the
|
|
4799
4399
|
* data stack, as one value. Replaced whenever either is defined, so a holder
|
|
4800
4400
|
* of an older one keeps rendering against what it was handed.
|
|
4401
|
+
* @returns {ExpressionEvaluator}
|
|
4801
4402
|
*/
|
|
4802
4403
|
evaluator() {
|
|
4803
4404
|
return this.#evaluator;
|
|
4804
4405
|
}
|
|
4805
|
-
/**
|
|
4406
|
+
/**
|
|
4407
|
+
* The component registered under the name.
|
|
4408
|
+
* @param {string} name
|
|
4409
|
+
* @returns {any} undefined when none is
|
|
4410
|
+
*/
|
|
4806
4411
|
component(name) {
|
|
4807
4412
|
return this.#components[name];
|
|
4808
4413
|
}
|
|
@@ -4810,33 +4415,59 @@ var ftl = (function (exports) {
|
|
|
4810
4415
|
|
|
4811
4416
|
const registry = new Registry();
|
|
4812
4417
|
|
|
4813
|
-
/** The Template factories, each bound to the page registry's scope. */
|
|
4814
4418
|
/** The Template factories bound to the page's own registry: the same four sources, with its modules and data already applied. */
|
|
4815
4419
|
class Templates {
|
|
4420
|
+
/**
|
|
4421
|
+
* @param {string} html
|
|
4422
|
+
* @returns {Template}
|
|
4423
|
+
*/
|
|
4816
4424
|
static fromHtml(html) {
|
|
4817
4425
|
return Template.fromHtml(html).withEvaluator(registry.evaluator());
|
|
4818
4426
|
}
|
|
4427
|
+
/**
|
|
4428
|
+
* @param {string} selector for an HTMLTemplateElement
|
|
4429
|
+
* @returns {Template}
|
|
4430
|
+
*/
|
|
4819
4431
|
static fromSelector(selector) {
|
|
4820
4432
|
return Template.fromSelector(selector).withEvaluator(registry.evaluator());
|
|
4821
4433
|
}
|
|
4434
|
+
/**
|
|
4435
|
+
* @param {HTMLTemplateElement} templateEl consumed: its content is adopted
|
|
4436
|
+
* @returns {Template}
|
|
4437
|
+
*/
|
|
4822
4438
|
static fromTemplate(templateEl) {
|
|
4823
4439
|
return Template.fromTemplate(templateEl).withEvaluator(registry.evaluator());
|
|
4824
4440
|
}
|
|
4441
|
+
/**
|
|
4442
|
+
* @param {DocumentFragment} fragment
|
|
4443
|
+
* @returns {Template}
|
|
4444
|
+
*/
|
|
4825
4445
|
static fromFragment(fragment) {
|
|
4826
4446
|
return Template.fromFragment(fragment).withEvaluator(registry.evaluator());
|
|
4827
4447
|
}
|
|
4828
4448
|
}
|
|
4829
4449
|
|
|
4830
4450
|
/**
|
|
4831
|
-
*
|
|
4832
|
-
*
|
|
4833
|
-
*
|
|
4834
|
-
* leaves a failed component to its own unhandled-rejection report.
|
|
4451
|
+
* Waits for elements queued on the page's `registry` to render. Unlike
|
|
4452
|
+
* `registry.ready()`, these reject when an awaited upgrade fails. An element
|
|
4453
|
+
* defined by another Registry is awaited through that registry instead.
|
|
4835
4454
|
*/
|
|
4836
4455
|
class Rendering {
|
|
4456
|
+
/**
|
|
4457
|
+
* Waits for the element and its descendants, the ones their own renders
|
|
4458
|
+
* enqueue included.
|
|
4459
|
+
* @param {Element} el
|
|
4460
|
+
* @returns {Promise<void>} rejecting with the first upgrade that failed
|
|
4461
|
+
*/
|
|
4837
4462
|
static waitFor(el) {
|
|
4838
4463
|
return registry.settle((child) => el.contains(child));
|
|
4839
4464
|
}
|
|
4465
|
+
/**
|
|
4466
|
+
* Waits for the element's descendants, the element itself excluded: what a
|
|
4467
|
+
* component awaits from inside its own render.
|
|
4468
|
+
* @param {Element} el
|
|
4469
|
+
* @returns {Promise<void>} rejecting with the first upgrade that failed
|
|
4470
|
+
*/
|
|
4840
4471
|
static waitForChildren(el) {
|
|
4841
4472
|
return registry.settle((child) => el !== child && el.contains(child));
|
|
4842
4473
|
}
|
|
@@ -4850,9 +4481,15 @@ var ftl = (function (exports) {
|
|
|
4850
4481
|
* @property {(val: any, name: string, el: Element) => string|null} marshal
|
|
4851
4482
|
*/
|
|
4852
4483
|
|
|
4484
|
+
/**
|
|
4485
|
+
* The base of every fml element. A subclass declares its attributes, slots and
|
|
4486
|
+
* templates in statics and builds its dom in `render`; the base reads the light
|
|
4487
|
+
* slots, reads the declared attributes through their mappers, renders once, and
|
|
4488
|
+
* then forwards observed attribute writes to the matching properties. An element
|
|
4489
|
+
* resolves templates and components through the registry that defined it.
|
|
4490
|
+
*/
|
|
4853
4491
|
class ParsedElement extends HTMLElement {
|
|
4854
4492
|
static BITS = {
|
|
4855
|
-
//an element the registry never defined still answers the page's own
|
|
4856
4493
|
registry,
|
|
4857
4494
|
enqueue: (el) => {},
|
|
4858
4495
|
SLOTS: false,
|
|
@@ -4876,14 +4513,12 @@ var ftl = (function (exports) {
|
|
|
4876
4513
|
this.internals = this.attachInternals();
|
|
4877
4514
|
}
|
|
4878
4515
|
/**
|
|
4879
|
-
* The
|
|
4880
|
-
*
|
|
4881
|
-
*
|
|
4882
|
-
*
|
|
4883
|
-
*
|
|
4884
|
-
*
|
|
4885
|
-
* A subclass must not redeclare it: a class field with no initializer
|
|
4886
|
-
* assigns undefined after super() returns, which would wipe it.
|
|
4516
|
+
* The element's ElementInternals, attached by the base for every element: a
|
|
4517
|
+
* subclass never calls attachInternals itself, since a second call throws.
|
|
4518
|
+
* A subclass declaring `static formAssociated` gets the form apis here.
|
|
4519
|
+
* A subclass must not redeclare the field: a class field without an
|
|
4520
|
+
* initializer assigns undefined after super() returns, wiping it.
|
|
4521
|
+
* @type {ElementInternals}
|
|
4887
4522
|
*/
|
|
4888
4523
|
internals;
|
|
4889
4524
|
#parsed = false;
|
|
@@ -4900,26 +4535,36 @@ var ftl = (function (exports) {
|
|
|
4900
4535
|
#mapper(attr) {
|
|
4901
4536
|
const mapper = this.#bits().ATTR_TO_MAPPER[attr];
|
|
4902
4537
|
if (!mapper) {
|
|
4903
|
-
//an attribute the class never declared has no type to read it as:
|
|
4904
|
-
//say so rather than dying on the missing mapper. Content this
|
|
4905
|
-
//element does not own, such as a custom loader's own configuration,
|
|
4906
|
-
//is read with getAttribute, the platform's own answer
|
|
4907
4538
|
throw new Error(
|
|
4908
4539
|
`${this.constructor.name} declares no attribute '${attr}': declare it in static observed or static attributes, or read it with getAttribute`,
|
|
4909
4540
|
);
|
|
4910
4541
|
}
|
|
4911
4542
|
return mapper;
|
|
4912
4543
|
}
|
|
4544
|
+
/**
|
|
4545
|
+
* Reads an attribute value through the mapper it was declared with.
|
|
4546
|
+
* @param {string} attr
|
|
4547
|
+
* @param {string|null} str
|
|
4548
|
+
* @returns {any}
|
|
4549
|
+
* @throws when the class declares no such attribute; read undeclared ones with getAttribute
|
|
4550
|
+
*/
|
|
4913
4551
|
unmarshal(attr, str) {
|
|
4914
4552
|
return this.#mapper(attr).unmarshal(str, attr, this);
|
|
4915
4553
|
}
|
|
4554
|
+
/**
|
|
4555
|
+
* Writes a value as the attribute string its declared mapper produces.
|
|
4556
|
+
* @param {string} attr
|
|
4557
|
+
* @param {any} value
|
|
4558
|
+
* @returns {string|null} null for a value that removes the attribute
|
|
4559
|
+
* @throws when the class declares no such attribute
|
|
4560
|
+
*/
|
|
4916
4561
|
marshal(attr, value) {
|
|
4917
4562
|
return this.#mapper(attr).marshal(value, attr, this);
|
|
4918
4563
|
}
|
|
4919
4564
|
/**
|
|
4920
|
-
*
|
|
4565
|
+
* The registry that defined this element, the page's own for an undefined one.
|
|
4566
|
+
* @returns {typeof registry}
|
|
4921
4567
|
*/
|
|
4922
|
-
/** The registry that defined this element, the page's own for an undefined one. */
|
|
4923
4568
|
get _registry() {
|
|
4924
4569
|
return this.#bits().registry;
|
|
4925
4570
|
}
|
|
@@ -4927,10 +4572,18 @@ var ftl = (function (exports) {
|
|
|
4927
4572
|
* The component registered under the name on this element's registry, the
|
|
4928
4573
|
* one every ful loader and mapper resolves through.
|
|
4929
4574
|
* @param {string} name
|
|
4575
|
+
* @returns {any} undefined when none is registered
|
|
4930
4576
|
*/
|
|
4931
4577
|
component(name) {
|
|
4932
4578
|
return this.#bits().registry.component(name);
|
|
4933
4579
|
}
|
|
4580
|
+
/**
|
|
4581
|
+
* One of the class's templates, bound to its registry's scope with the
|
|
4582
|
+
* class's `static config` overlaid as `config`.
|
|
4583
|
+
* @param {string} [name] 'default', the `static template`, when omitted
|
|
4584
|
+
* @returns {Template}
|
|
4585
|
+
* @throws when the class declares no template of that name
|
|
4586
|
+
*/
|
|
4934
4587
|
template(name) {
|
|
4935
4588
|
const target = this.#bits().TEMPLATES[name ?? 'default'];
|
|
4936
4589
|
if (!target) {
|
|
@@ -4950,15 +4603,9 @@ var ftl = (function (exports) {
|
|
|
4950
4603
|
if (oldValue === newValue) {
|
|
4951
4604
|
return;
|
|
4952
4605
|
}
|
|
4953
|
-
//the mute is the attribute being reflected, not the element: a component
|
|
4954
|
-
//that legitimately changes another observed attribute while one reflects
|
|
4955
|
-
//is a change like any other, and used to be swallowed
|
|
4956
4606
|
if (this.#reflecting.has(attr)) {
|
|
4957
4607
|
return;
|
|
4958
4608
|
}
|
|
4959
|
-
//the properties go live only once the render is done: before that, an
|
|
4960
|
-
//attribute write lands in the observed snapshot and the base applies it
|
|
4961
|
-
//with the rest of the declared state
|
|
4962
4609
|
if (!this.#parsed) {
|
|
4963
4610
|
if (this.#pending !== null && attr in this.#pending) {
|
|
4964
4611
|
this.#pending[attr] = this.unmarshal(attr, newValue);
|
|
@@ -4968,14 +4615,18 @@ var ftl = (function (exports) {
|
|
|
4968
4615
|
this[this.#bits().ATTR_TO_PROPERTY[attr]] = this.unmarshal(attr, newValue);
|
|
4969
4616
|
}
|
|
4970
4617
|
/**
|
|
4971
|
-
* Upgrades once
|
|
4972
|
-
* to writes made while the render is
|
|
4973
|
-
*
|
|
4618
|
+
* Upgrades once, however often the element is connected: reads the declared
|
|
4619
|
+
* attributes, keeps the observed ones open to writes made while the render is
|
|
4620
|
+
* pending, renders, then applies the observed values to their properties in
|
|
4621
|
+
* the order the registry composed them, a base class's before a subclass's.
|
|
4622
|
+
* Only then do attribute writes forward to properties, and the element gains
|
|
4623
|
+
* the `rendered` custom state. A render that throws leaves the forwarding
|
|
4624
|
+
* shut and the state unset.
|
|
4974
4625
|
*
|
|
4975
4626
|
* An observed attribute drives the property the registry's `propertyOf`
|
|
4976
4627
|
* names, so a hyphenated attribute is authored with its dashes and read as
|
|
4977
|
-
* a camelCase property.
|
|
4978
|
-
*
|
|
4628
|
+
* a camelCase property.
|
|
4629
|
+
* @returns {Promise<void>} rejecting with what the render threw
|
|
4979
4630
|
*/
|
|
4980
4631
|
async upgrade() {
|
|
4981
4632
|
if (this.#started) {
|
|
@@ -4983,9 +4634,6 @@ var ftl = (function (exports) {
|
|
|
4983
4634
|
}
|
|
4984
4635
|
this.#started = true;
|
|
4985
4636
|
const slots = this.#bits().SLOTS ? LightSlots.from(this) : undefined;
|
|
4986
|
-
//both tiers are read here: the observed ones forward to a property once
|
|
4987
|
-
//the render is done, the rest are the element's configuration, read the
|
|
4988
|
-
//one time and never again
|
|
4989
4637
|
const declared = Object.fromEntries(
|
|
4990
4638
|
this.#bits().DECLARED.map((attribute) => [
|
|
4991
4639
|
attribute,
|
|
@@ -4997,21 +4645,11 @@ var ftl = (function (exports) {
|
|
|
4997
4645
|
this.#pending = declared;
|
|
4998
4646
|
try {
|
|
4999
4647
|
await this.render({ slots });
|
|
5000
|
-
//the declared state reaches the properties once the dom the setters
|
|
5001
|
-
//drive exists, in the order the registry composed the declarations:
|
|
5002
|
-
//a base class's attributes before the subclass's own
|
|
5003
4648
|
const properties = this.#bits().ATTR_TO_PROPERTY;
|
|
5004
4649
|
for (const name of this.#bits().OBSERVED) {
|
|
5005
4650
|
this[properties[name]] = declared[name];
|
|
5006
4651
|
}
|
|
5007
|
-
//the properties go live once the render is done: from here on, an
|
|
5008
|
-
//attribute write forwards to the property. A render that threw
|
|
5009
|
-
//leaves it shut, so a later attribute write cannot reach setters
|
|
5010
|
-
//that assume pieces the failed render never adopted
|
|
5011
4652
|
this.#parsed = true;
|
|
5012
|
-
//the same moment, said to css. :defined is true from the constructor,
|
|
5013
|
-
//which is before the dom exists, so a guard written against it reveals
|
|
5014
|
-
//an element that has nothing in it yet
|
|
5015
4653
|
this.internals.states.add('rendered');
|
|
5016
4654
|
} finally {
|
|
5017
4655
|
this.#pending = null;
|
|
@@ -5022,8 +4660,9 @@ var ftl = (function (exports) {
|
|
|
5022
4660
|
* drive, and the base applies the declared state onto the properties as
|
|
5023
4661
|
* soon as it returns. A render needing a declared value while it builds
|
|
5024
4662
|
* reads it through `declared(name)`. The slots are undefined for an element
|
|
5025
|
-
* declaring no slots.
|
|
5026
|
-
* @param {{ slots:
|
|
4663
|
+
* declaring no slots. It may be async; the upgrade awaits it.
|
|
4664
|
+
* @param {{ slots: Record<string, DocumentFragment> | undefined }} c
|
|
4665
|
+
* @returns {void | Promise<void>}
|
|
5027
4666
|
*/
|
|
5028
4667
|
render(c) {}
|
|
5029
4668
|
/**
|
|
@@ -5035,12 +4674,9 @@ var ftl = (function (exports) {
|
|
|
5035
4674
|
* observed name answers the snapshot while the render is pending, kept
|
|
5036
4675
|
* open to attribute writes landing in that window, and the live attribute
|
|
5037
4676
|
* afterwards, the property being live by then.
|
|
5038
|
-
*
|
|
5039
|
-
* The snapshot exists rather than a read of the dom because an element may
|
|
5040
|
-
* write its own observed attributes while it renders, whether a reflection
|
|
5041
|
-
* or a value the platform normalizes on the way in, and what the author
|
|
5042
|
-
* declared is what the base applies, not what the render left behind.
|
|
5043
4677
|
* @param {string} name
|
|
4678
|
+
* @returns {any}
|
|
4679
|
+
* @throws when the class declares no such attribute
|
|
5044
4680
|
*/
|
|
5045
4681
|
declared(name) {
|
|
5046
4682
|
if (name in this.#frozen) {
|
|
@@ -5051,15 +4687,18 @@ var ftl = (function (exports) {
|
|
|
5051
4687
|
}
|
|
5052
4688
|
return this.unmarshal(name, this.getAttribute(name));
|
|
5053
4689
|
}
|
|
5054
|
-
/**
|
|
4690
|
+
/**
|
|
4691
|
+
* Whether the element's render completed: the moment its properties went
|
|
4692
|
+
* live, which css reads as `:state(rendered)`. Unlike `:defined`, which holds
|
|
4693
|
+
* from the constructor, it is false until the dom exists.
|
|
4694
|
+
* @returns {boolean}
|
|
4695
|
+
*/
|
|
5055
4696
|
get rendered() {
|
|
5056
4697
|
return this.#parsed;
|
|
5057
4698
|
}
|
|
5058
4699
|
/**
|
|
5059
4700
|
* Projects a property back onto its observed attribute, marshalled through
|
|
5060
|
-
* the mapper the attribute was declared with
|
|
5061
|
-
* reaches its attribute, so a setter never has to know how its own type
|
|
5062
|
-
* serializes.
|
|
4701
|
+
* the mapper the attribute was declared with.
|
|
5063
4702
|
*
|
|
5064
4703
|
* A value the attribute already carries is not written at all, so reflecting
|
|
5065
4704
|
* what an attribute write just delivered ends there rather than looping, and
|
|
@@ -5099,9 +4738,13 @@ var ftl = (function (exports) {
|
|
|
5099
4738
|
const PLACEHOLDER = /\{(\w+)\}/g;
|
|
5100
4739
|
const POSITIONAL = /\{(\d+)\}/g;
|
|
5101
4740
|
/** @param {any} v @returns {v is Record<string, string>} */
|
|
5102
|
-
const isPlainObject = (v) =>
|
|
4741
|
+
const isPlainObject = (v) =>
|
|
4742
|
+
typeof v === 'object' && v !== null && [Object.prototype, null].includes(Object.getPrototypeOf(v));
|
|
4743
|
+
|
|
4744
|
+
/** @param {any} problem @returns {string|undefined} the reason, unless it is missing or blank */
|
|
4745
|
+
const reasonOf = (problem) =>
|
|
4746
|
+
typeof problem?.reason === 'string' && problem.reason.trim() !== '' ? problem.reason : undefined;
|
|
5103
4747
|
|
|
5104
|
-
/** every l10n problem is reported once per session: a missing key in a row template must not flood the console */
|
|
5105
4748
|
const warned = new Set();
|
|
5106
4749
|
const warnOnce = (problem) => {
|
|
5107
4750
|
if (!warned.has(problem)) {
|
|
@@ -5112,11 +4755,7 @@ var ftl = (function (exports) {
|
|
|
5112
4755
|
|
|
5113
4756
|
const formatters = new BoundedCache(100);
|
|
5114
4757
|
/**
|
|
5115
|
-
* Intl
|
|
5116
|
-
* lookups), while formatting on a built instance is near free: a list rendering
|
|
5117
|
-
* a size per row must not rebuild a NumberFormat per cell, so instances are
|
|
5118
|
-
* memoized by constructor, locale and options.
|
|
5119
|
-
*
|
|
4758
|
+
* An Intl instance, memoized by constructor, locale and options.
|
|
5120
4759
|
* @param {{ new (locale: string | undefined, options: any): any }} ctor
|
|
5121
4760
|
* @param {string | undefined} locale
|
|
5122
4761
|
* @param {any} [options]
|
|
@@ -5135,26 +4774,29 @@ var ftl = (function (exports) {
|
|
|
5135
4774
|
class Localization {
|
|
5136
4775
|
/**
|
|
5137
4776
|
* Resolves a message from the translations and interpolates its arguments.
|
|
5138
|
-
* A single plain object argument
|
|
5139
|
-
* ({name}); anything else interpolates positional ones ({0}).
|
|
4777
|
+
* A single plain object argument (an object literal, or one with a null
|
|
4778
|
+
* prototype) interpolates named placeholders ({name}); anything else interpolates positional ones ({0}).
|
|
5140
4779
|
* A plural leaf selects its form through Intl.PluralRules over the
|
|
5141
4780
|
* numeric {count} named argument.
|
|
5142
4781
|
*
|
|
5143
4782
|
* @param {string} key
|
|
5144
4783
|
* @param {...any} args
|
|
4784
|
+
* Each problem (a missing key, placeholder or plural form) is warned once
|
|
4785
|
+
* per page.
|
|
4786
|
+
*
|
|
5145
4787
|
* @this {Receiver}
|
|
5146
4788
|
* @returns {string} the message, or the key itself when the translations do not carry it
|
|
5147
4789
|
*/
|
|
5148
4790
|
static t(key, ...args) {
|
|
5149
4791
|
const messages = this.l10n ?? {};
|
|
5150
|
-
let message = messages[key];
|
|
4792
|
+
let message = Object.hasOwn(messages, key) ? messages[key] : undefined;
|
|
5151
4793
|
if (message === undefined) {
|
|
5152
4794
|
warnOnce(`missing message "${key}"`);
|
|
5153
4795
|
return key;
|
|
5154
4796
|
}
|
|
4797
|
+
const named = args.length === 1 && isPlainObject(args[0]) ? args[0] : null;
|
|
5155
4798
|
if (isPlainObject(message)) {
|
|
5156
|
-
|
|
5157
|
-
if (typeof named.count !== 'number') {
|
|
4799
|
+
if (typeof named?.count !== 'number') {
|
|
5158
4800
|
warnOnce(`plural message "${key}" needs a numeric {count}`);
|
|
5159
4801
|
message = message.other;
|
|
5160
4802
|
} else {
|
|
@@ -5167,10 +4809,9 @@ var ftl = (function (exports) {
|
|
|
5167
4809
|
warnOnce(`plural message "${key}" has no "other" form`);
|
|
5168
4810
|
return key;
|
|
5169
4811
|
}
|
|
5170
|
-
if (
|
|
5171
|
-
const named = args[0];
|
|
4812
|
+
if (named) {
|
|
5172
4813
|
return message.replace(PLACEHOLDER, (literal, name) => {
|
|
5173
|
-
if (!(name
|
|
4814
|
+
if (!Object.hasOwn(named, name)) {
|
|
5174
4815
|
warnOnce(`message "${key}" wants {${name}}`);
|
|
5175
4816
|
return literal;
|
|
5176
4817
|
}
|
|
@@ -5196,6 +4837,7 @@ var ftl = (function (exports) {
|
|
|
5196
4837
|
* @param {Date | number} value
|
|
5197
4838
|
* @param {Intl.DateTimeFormatOptions} [options]
|
|
5198
4839
|
* @this {Receiver}
|
|
4840
|
+
* @returns {string}
|
|
5199
4841
|
*/
|
|
5200
4842
|
static date(value, options) {
|
|
5201
4843
|
return formatter(Intl.DateTimeFormat, this.locale, options).format(value);
|
|
@@ -5207,6 +4849,7 @@ var ftl = (function (exports) {
|
|
|
5207
4849
|
* @param {number} value
|
|
5208
4850
|
* @param {Intl.NumberFormatOptions} [options]
|
|
5209
4851
|
* @this {Receiver}
|
|
4852
|
+
* @returns {string}
|
|
5210
4853
|
*/
|
|
5211
4854
|
static number(value, options) {
|
|
5212
4855
|
return formatter(Intl.NumberFormat, this.locale, options).format(value);
|
|
@@ -5219,6 +4862,7 @@ var ftl = (function (exports) {
|
|
|
5219
4862
|
*
|
|
5220
4863
|
* @param {number} value
|
|
5221
4864
|
* @this {Receiver}
|
|
4865
|
+
* @returns {string}
|
|
5222
4866
|
*/
|
|
5223
4867
|
static bytes(value) {
|
|
5224
4868
|
const format = formatter(Intl.NumberFormat, this.locale, { maximumFractionDigits: 2 }).format;
|
|
@@ -5234,16 +4878,37 @@ var ftl = (function (exports) {
|
|
|
5234
4878
|
return `${format(value)}B`;
|
|
5235
4879
|
}
|
|
5236
4880
|
|
|
4881
|
+
/**
|
|
4882
|
+
* What went wrong, as text for the reader. A value carrying a non-empty
|
|
4883
|
+
* `problems` array reads as their reasons, one per line, a blank or missing
|
|
4884
|
+
* reason reading as the `failure.no-reason` message. Any other value with a
|
|
4885
|
+
* `message` reads as that message; anything else as its string form, and
|
|
4886
|
+
* null or undefined as the empty string.
|
|
4887
|
+
*
|
|
4888
|
+
* @param {any} value what was thrown or rejected with
|
|
4889
|
+
* @this {Receiver}
|
|
4890
|
+
* @returns {string}
|
|
4891
|
+
*/
|
|
4892
|
+
static failure(value) {
|
|
4893
|
+
if (Array.isArray(value?.problems) && value.problems.length > 0) {
|
|
4894
|
+
return value.problems.map((p) => reasonOf(p) ?? Localization.t.call(this, 'failure.no-reason')).join('\n');
|
|
4895
|
+
}
|
|
4896
|
+
if (value?.message !== undefined) {
|
|
4897
|
+
return String(value.message);
|
|
4898
|
+
}
|
|
4899
|
+
return value == null ? '' : String(value);
|
|
4900
|
+
}
|
|
4901
|
+
|
|
5237
4902
|
/**
|
|
5238
4903
|
* An imperative facade over the module functions, resolving the translations
|
|
5239
|
-
* and the locale from the registry overlays on every call
|
|
4904
|
+
* and the locale from the registry overlays on every call, the same lookup a
|
|
4905
|
+
* template makes: a facade taken at module scope, before the plugin
|
|
4906
|
+
* configures, still sees the translations.
|
|
5240
4907
|
*
|
|
5241
4908
|
* @param {{ locale?: string }} [overrides] an explicit locale, winning over the registry one
|
|
4909
|
+
* @returns {{ t: (key: string, ...args: any[]) => string, date: (value: Date | number, options?: Intl.DateTimeFormatOptions) => string, number: (value: number, options?: Intl.NumberFormatOptions) => string, bytes: (value: number) => string, failure: (value: any) => string }}
|
|
5242
4910
|
*/
|
|
5243
4911
|
static of(overrides = {}) {
|
|
5244
|
-
//resolved per call, not per facade: a module-scope `Localization.of()` is
|
|
5245
|
-
//bound before the plugin configures. The registry's own evaluator does the
|
|
5246
|
-
//lookup, so this cannot drift from what a template sees
|
|
5247
4912
|
const resolve = (prop) => registry.evaluator().resolve(prop);
|
|
5248
4913
|
/** @param {any} fn */
|
|
5249
4914
|
const bind =
|
|
@@ -5255,6 +4920,7 @@ var ftl = (function (exports) {
|
|
|
5255
4920
|
date: bind(Localization.date),
|
|
5256
4921
|
number: bind(Localization.number),
|
|
5257
4922
|
bytes: bind(Localization.bytes),
|
|
4923
|
+
failure: bind(Localization.failure),
|
|
5258
4924
|
};
|
|
5259
4925
|
}
|
|
5260
4926
|
}
|