@cocreate/element-prototype 1.35.0 → 1.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/getValue.js CHANGED
@@ -17,21 +17,22 @@
17
17
  ********************************************************************************/
18
18
 
19
19
  import { astSync, astAsync } from "@cocreate/utils";
20
+ import { getValueAttribute, transformValue, parseJson, toBoolean, toArray } from "@cocreate/utils";
20
21
 
21
22
  const storage = new Map();
22
23
 
23
24
  HTMLElement.prototype.getValue = function () {
24
- return getValue(this);
25
+ return getValue(this);
25
26
  };
26
27
  SVGElement.prototype.getValue = function () {
27
- return getValue(this);
28
+ return getValue(this);
28
29
  };
29
30
 
30
31
  HTMLElement.prototype.getValueAsync = async function () {
31
- return await getValueAsync(this);
32
+ return await getValueAsync(this);
32
33
  };
33
34
  SVGElement.prototype.getValueAsync = async function () {
34
- return await getValueAsync(this);
35
+ return await getValueAsync(this);
35
36
  };
36
37
 
37
38
  /**
@@ -42,121 +43,128 @@ SVGElement.prototype.getValueAsync = async function () {
42
43
  * @returns {any} - The processed value.
43
44
  */
44
45
  const getValue = (element, valueType) => {
45
- if (!valueType) {
46
- valueType = element.getAttribute("value-type") || "";
47
- }
48
-
49
- let value = element.value || element.getAttribute("value") || "";
50
-
51
- if (
52
- element.hasAttribute("component") ||
53
- element.type === "file" ||
54
- element.getAttribute("type") === "file"
55
- ) {
56
- value = storage.get(element);
57
- storage.delete(element);
58
- return value;
59
- }
60
-
61
- let prefix = element.getAttribute("value-prefix") || "";
62
- let suffix = element.getAttribute("value-suffix") || "";
63
-
64
- const elementType = element.getAttribute("type") || element.type;
65
- const tagName = element.tagName.toUpperCase();
66
-
67
- switch (elementType) {
68
- case "checkbox":
69
- value = handleCheckbox(element, prefix, suffix);
70
- break;
71
-
72
- case "radio": {
73
- const key = element.getAttribute("key");
74
- let el = document.querySelector(`input[key="${key}"]:checked`);
75
- if (el) {
76
- value = el.value;
77
- }
78
- break;
79
- }
80
-
81
- case "number":
82
- value = Number(value);
83
- break;
84
-
85
- case "range":
86
- value = element.min
87
- ? [Number(element.min), Number(element.value)]
88
- : Number(element.value);
89
- break;
90
-
91
- case "password":
92
- value = btoa(value || "");
93
- break;
94
-
95
- case "email":
96
- value = value.toLowerCase();
97
- break;
98
-
99
- case "url":
100
- break;
101
-
102
- case "time":
103
- case "date":
104
- case "datetime":
105
- case "datetime-local":
106
- value = handleDateTime(element, value, valueType);
107
- break;
108
-
109
- default:
110
- switch (tagName) {
111
- case "INPUT":
112
- value = element.value;
113
- break;
114
-
115
- case "SELECT":
116
- value = element.hasAttribute("multiple")
117
- ? handleMultipleSelect(element, prefix, suffix)
118
- : element.value;
119
- break;
120
-
121
- case "TEXTAREA":
122
- value = element.hasAttribute("value")
123
- ? element.getAttribute("value")
124
- : element.value;
125
- break;
126
-
127
- case "IFRAME":
128
- value = element.srcdoc;
129
- break;
130
-
131
- default:
132
- value = handleElement(element, valueType);
133
- break;
134
- }
135
- break;
136
- }
137
-
138
- if (valueType === "boolean") {
139
- return value && value !== "false";
140
- }
141
-
142
- if (value) {
143
- value = astSync({ executeAST: value, node: element, exclude: ["$value"] });
144
- value = caseHandler(element, value);
145
- value = regex(element, value);
146
- value = encodeValue(value, element.getAttribute("value-encode") || "");
147
- value = decodeValue(value, element.getAttribute("value-decode") || "");
148
- }
149
-
150
- if (typeof value === "string" || typeof value === "number") {
151
- if (prefix || suffix) {
152
- value = prefix + value + suffix;
153
- }
154
- }
155
-
156
- value = parseJson(value, valueType);
157
- value = toArray(value, valueType);
158
-
159
- return value;
46
+ if (!valueType) {
47
+ valueType = getValueAttribute(element, "type", "get-value") || "";
48
+ }
49
+
50
+ const evaluateValue = getValueAttribute(element, "evaluate", "get-value", true) !== "false";
51
+ const readValueAttribute = () => evaluateValue
52
+ ? element.getAttribute("value")
53
+ : element.attributes.getNamedItem("value")?.value;
54
+ let value = element.value || readValueAttribute() || "";
55
+
56
+ if (
57
+ element.hasAttribute("component") ||
58
+ element.type === "file" ||
59
+ element.getAttribute("type") === "file"
60
+ ) {
61
+ value = storage.get(element);
62
+ // storage.delete(element);
63
+ return value;
64
+ }
65
+
66
+ let prefix = getValueAttribute(element, "prefix", "get-value") || "";
67
+ let suffix = getValueAttribute(element, "suffix", "get-value") || "";
68
+
69
+ const elementType = element.getAttribute("type") || element.type;
70
+ const tagName = element.tagName.toUpperCase();
71
+
72
+ switch (elementType) {
73
+ case "checkbox":
74
+ value = handleCheckbox(element, prefix, suffix, valueType);
75
+ break;
76
+
77
+ case "radio": {
78
+ const key = element.getAttribute("key");
79
+ let el = document.querySelector(`input[key="${key}"]:checked`);
80
+ if (el) {
81
+ value = el.value;
82
+ }
83
+ break;
84
+ }
85
+
86
+ case "number":
87
+ value = value === "" ? "" : Number(value);
88
+ break;
89
+ case "range":
90
+ value = element.min
91
+ ? [Number(element.min), Number(element.value)]
92
+ : Number(element.value);
93
+ break;
94
+
95
+ case "password":
96
+ value = btoa(value || "");
97
+ break;
98
+
99
+ case "email":
100
+ value = value.toLowerCase();
101
+ break;
102
+
103
+ case "url":
104
+ break;
105
+
106
+ case "time":
107
+ case "date":
108
+ case "datetime":
109
+ case "datetime-local":
110
+ value = handleDateTime(element, value, valueType);
111
+ break;
112
+
113
+ default:
114
+ switch (tagName) {
115
+ case "INPUT":
116
+ case "OPTION":
117
+ value = element.value;
118
+ break;
119
+
120
+ case "SELECT":
121
+ value = handleSelectedValues(element,
122
+ Array.from(element.selectedOptions, option => getValue(option)),
123
+ prefix, suffix);
124
+ break;
125
+
126
+ case "TEXTAREA":
127
+ value = element.hasAttribute("value")
128
+ ? readValueAttribute()
129
+ : element.value;
130
+ break;
131
+
132
+ case "IFRAME":
133
+ value = element.srcdoc;
134
+ break;
135
+
136
+ case "IMG":
137
+ value = element.src;
138
+ break;
139
+
140
+ default:
141
+ value = handleElement(element, valueType, evaluateValue);
142
+ break;
143
+ }
144
+ break;
145
+ }
146
+
147
+ if (valueType === "boolean") {
148
+ return toBoolean(value);
149
+ }
150
+
151
+ if (value) {
152
+ if (evaluateValue) {
153
+ value = astSync({ executeAST: value, node: element, exclude: ["$value"] });
154
+ }
155
+ value = transformValue(element, value, "get-value");
156
+ }
157
+
158
+ if (typeof value === "string" || typeof value === "number") {
159
+ if (prefix || suffix) {
160
+ value = prefix + value + suffix;
161
+ }
162
+ }
163
+
164
+ value = parseJson(value, valueType);
165
+ value = toArray(value, valueType);
166
+
167
+ return value;
160
168
  };
161
169
 
162
170
  /**
@@ -167,151 +175,158 @@ const getValue = (element, valueType) => {
167
175
  * @returns {Promise<any>} - A promise that resolves to the processed value.
168
176
  */
169
177
  const getValueAsync = async (element, valueType) => {
170
- if (!valueType) {
171
- valueType = element.getAttribute("value-type") || "";
172
- }
173
-
174
- let value = element.value || element.getAttribute("value") || "";
175
-
176
- if (
177
- element.hasAttribute("component") ||
178
- element.type === "file" ||
179
- element.getAttribute("type") === "file"
180
- ) {
181
- value = storage.get(element);
182
- storage.delete(element);
183
- return value;
184
- }
185
-
186
- let prefix = element.getAttribute("value-prefix") || "";
187
- let suffix = element.getAttribute("value-suffix") || "";
188
-
189
- const elementType = element.getAttribute("type") || element.type;
190
- const tagName = element.tagName.toUpperCase();
191
-
192
- switch (elementType) {
193
- case "checkbox":
194
- value = handleCheckbox(element, prefix, suffix);
195
- break;
196
-
197
- case "radio": {
198
- const key = element.getAttribute("key");
199
- let el = document.querySelector(`input[key="${key}"]:checked`);
200
- if (el) {
201
- value = el.value;
202
- }
203
- break;
204
- }
205
-
206
- case "number":
207
- value = Number(value);
208
- break;
209
-
210
- case "range":
211
- value = element.min
212
- ? [Number(element.min), Number(element.value)]
213
- : Number(element.value);
214
- break;
215
-
216
- case "password":
217
- value = btoa(value || "");
218
- break;
219
-
220
- case "email":
221
- value = value.toLowerCase();
222
- break;
223
-
224
- case "url":
225
- break;
226
-
227
- case "time":
228
- case "date":
229
- case "datetime":
230
- case "datetime-local":
231
- value = handleDateTime(element, value, valueType);
232
- break;
233
-
234
- default:
235
- switch (tagName) {
236
- case "INPUT":
237
- value = element.value;
238
- break;
239
-
240
- case "SELECT":
241
- value = element.hasAttribute("multiple")
242
- ? handleMultipleSelect(element, prefix, suffix)
243
- : element.value;
244
- break;
245
-
246
- case "TEXTAREA":
247
- value = element.hasAttribute("value")
248
- ? element.getAttribute("value")
249
- : element.value;
250
- break;
251
-
252
- case "IFRAME":
253
- value = element.srcdoc;
254
- break;
255
-
256
- default:
257
- value = handleElement(element, valueType);
258
- break;
259
- }
260
- break;
261
- }
262
-
263
- if (valueType === "boolean") {
264
- return value && value !== "false";
265
- }
266
-
267
- if (value) {
268
- value = await astAsync({ executeAST: value, node: element, exclude: ["$value"] });
269
- value = caseHandler(element, value);
270
- value = regex(element, value);
271
- value = encodeValue(value, element.getAttribute("value-encode") || "");
272
- value = decodeValue(value, element.getAttribute("value-decode") || "");
273
- }
274
-
275
- if (typeof value === "string" || typeof value === "number") {
276
- if (prefix || suffix) {
277
- value = prefix + value + suffix;
278
- }
279
- }
280
-
281
- value = parseJson(value, valueType);
282
- value = toArray(value, valueType);
283
-
284
- return value;
178
+ if (!valueType) {
179
+ valueType = getValueAttribute(element, "type", "get-value") || "";
180
+ }
181
+
182
+ const evaluateValue = getValueAttribute(element, "evaluate", "get-value", true) !== "false";
183
+ const readValueAttribute = () => evaluateValue
184
+ ? element.getAttribute("value")
185
+ : element.attributes.getNamedItem("value")?.value;
186
+ let value = element.value || readValueAttribute() || "";
187
+
188
+ if (
189
+ element.hasAttribute("component") ||
190
+ element.type === "file" ||
191
+ element.getAttribute("type") === "file"
192
+ ) {
193
+ value = storage.get(element);
194
+ storage.delete(element);
195
+ return value;
196
+ }
197
+
198
+ let prefix = getValueAttribute(element, "prefix", "get-value") || "";
199
+ let suffix = getValueAttribute(element, "suffix", "get-value") || "";
200
+
201
+ const elementType = element.getAttribute("type") || element.type;
202
+ const tagName = element.tagName.toUpperCase();
203
+
204
+ switch (elementType) {
205
+ case "checkbox":
206
+ value = handleCheckbox(element, prefix, suffix, valueType);
207
+ break;
208
+
209
+ case "radio": {
210
+ const key = element.getAttribute("key");
211
+ let el = document.querySelector(`input[key="${key}"]:checked`);
212
+ if (el) {
213
+ value = el.value;
214
+ }
215
+ break;
216
+ }
217
+
218
+ case "number":
219
+ value = Number(value);
220
+ break;
221
+
222
+ case "range":
223
+ value = element.min
224
+ ? [Number(element.min), Number(element.value)]
225
+ : Number(element.value);
226
+ break;
227
+
228
+ case "password":
229
+ value = btoa(value || "");
230
+ break;
231
+
232
+ case "email":
233
+ value = value.toLowerCase();
234
+ break;
235
+
236
+ case "url":
237
+ break;
238
+
239
+ case "time":
240
+ case "date":
241
+ case "datetime":
242
+ case "datetime-local":
243
+ value = handleDateTime(element, value, valueType);
244
+ break;
245
+
246
+ default:
247
+ switch (tagName) {
248
+ case "INPUT":
249
+ case "OPTION":
250
+ value = element.value;
251
+ break;
252
+
253
+ case "SELECT":
254
+ value = handleSelectedValues(element,
255
+ await Promise.all(Array.from(element.selectedOptions, option => getValueAsync(option))),
256
+ prefix, suffix);
257
+ break;
258
+
259
+ case "TEXTAREA":
260
+ value = element.hasAttribute("value")
261
+ ? readValueAttribute()
262
+ : element.value;
263
+ break;
264
+
265
+ case "IFRAME":
266
+ value = element.srcdoc;
267
+ break;
268
+
269
+ default:
270
+ value = handleElement(element, valueType, evaluateValue);
271
+ break;
272
+ }
273
+ break;
274
+ }
275
+
276
+ if (valueType === "boolean") {
277
+ return toBoolean(value);
278
+ }
279
+
280
+ if (value) {
281
+ if (evaluateValue) {
282
+ value = await astAsync({ executeAST: value, node: element, exclude: ["$value"] });
283
+ }
284
+ value = transformValue(element, value, "get-value");
285
+ }
286
+
287
+ if (typeof value === "string" || typeof value === "number") {
288
+ if (prefix || suffix) {
289
+ value = prefix + value + suffix;
290
+ }
291
+ }
292
+
293
+ value = parseJson(value, valueType);
294
+ value = toArray(value, valueType);
295
+
296
+ return value;
285
297
  };
286
298
 
287
299
  /**
288
300
  * Processes a checkbox or a group of checkboxes to determine their checked values.
289
301
  */
290
- const handleCheckbox = (element, prefix = "", suffix = "") => {
291
- const inputs = element.getAttribute("key")
292
- ? document.querySelectorAll(
293
- `input[type="${element.type}"][key="${element.getAttribute(
294
- "key"
295
- )}"]`
296
- )
297
- : [element];
298
-
299
- if (inputs.length === 1) {
300
- return element.checked ? element.value || true : false;
301
- } else {
302
- return Array.from(inputs)
303
- .filter((el) => el.checked)
304
- .map((el) => `${prefix}${el.value}${suffix}`);
305
- }
302
+ const handleCheckbox = (element, prefix = "", suffix = "", valueType = "") => {
303
+ const inputs = element.getAttribute("key")
304
+ ? document.querySelectorAll(
305
+ `input[type="${element.type}"][key="${element.getAttribute(
306
+ "key"
307
+ )}"]`
308
+ )
309
+ : [element];
310
+
311
+ if (inputs.length === 1) {
312
+ if (valueType.startsWith("array"))
313
+ return element.checked ? [element.value || true] : [];
314
+ return element.checked ? element.value || true : false;
315
+ } else {
316
+ return Array.from(inputs)
317
+ .filter((el) => el.checked)
318
+ .map((el) => `${prefix}${el.value}${suffix}`);
319
+ }
306
320
  };
307
321
 
308
322
  /**
309
323
  * Handles and transforms a date/time value based on the specified valueType.
310
324
  */
311
325
  const handleDateTime = (element, value, valueType) => {
326
+ if ((value === "" || value === null || value === undefined) && !element.hasAttribute("now")) return "";
312
327
  const inputType = (element.getAttribute("type") || element.type || "").toLowerCase();
313
328
  let date;
314
-
329
+
315
330
  if (value === "$now" || element.hasAttribute("now")) {
316
331
  date = new Date();
317
332
  } else if (value instanceof Date) {
@@ -464,7 +479,7 @@ const handleDateTime = (element, value, valueType) => {
464
479
  case "timeAgo": {
465
480
  const diffMs = Date.now() - date.getTime();
466
481
  const absSecs = Math.floor(Math.abs(diffMs) / 1000);
467
-
482
+
468
483
  const limitAttr = element.getAttribute("time-ago-limit");
469
484
  if (limitAttr) {
470
485
  const match = limitAttr.match(/^(\d+)([a-z]+)$/i);
@@ -472,7 +487,7 @@ const handleDateTime = (element, value, valueType) => {
472
487
  const amount = parseInt(match[1], 10);
473
488
  const limitUnit = match[2].toLowerCase();
474
489
  let multiplier = 0;
475
-
490
+
476
491
  switch (limitUnit) {
477
492
  case 's': multiplier = 1; break;
478
493
  case 'm': multiplier = 60; break;
@@ -482,9 +497,9 @@ const handleDateTime = (element, value, valueType) => {
482
497
  case 'mo': multiplier = 2592000; break;
483
498
  case 'y': multiplier = 31536000; break;
484
499
  }
485
-
500
+
486
501
  const limitInSeconds = amount * multiplier;
487
-
502
+
488
503
  if (absSecs > limitInSeconds) {
489
504
  const locale = element.getAttribute("locale") || "en-US";
490
505
  return date.toLocaleString(locale);
@@ -532,308 +547,48 @@ const handleDateTime = (element, value, valueType) => {
532
547
  };
533
548
 
534
549
  /**
535
- * Processes a <select> element with the "multiple" attribute.
550
+ * Collects processed option values, retaining select-level multi-value affixes.
536
551
  */
537
- const handleMultipleSelect = (element, prefix, suffix) => {
538
- let value = [];
539
- let options = element.selectedOptions;
540
-
541
- for (let i = 0; i < options.length; i++) {
542
- let optionValue = options[i].value;
543
- if (prefix || suffix) {
544
- optionValue = prefix + optionValue + suffix;
545
- }
546
- value.push(optionValue);
547
- }
548
-
549
- return value;
552
+ const handleSelectedValues = (element, values, prefix, suffix) => {
553
+ if (!element.hasAttribute("multiple")) return values.length ? values[0] : "";
554
+ return prefix || suffix
555
+ ? values.map(value => prefix + value + suffix)
556
+ : values;
550
557
  };
551
558
 
552
559
  /**
553
560
  * Retrieves a value from a standard element.
554
561
  */
555
- const handleElement = (element, valueType) => {
556
- if (element.hasAttribute("value")) {
557
- return element.getAttribute("value");
558
- }
559
-
560
- let targetElement = element;
561
- const excludeSelector = element.getAttribute("value-remove-query");
562
-
563
- if (excludeSelector) {
564
- targetElement = element.cloneNode(true);
565
- targetElement
566
- .querySelectorAll(excludeSelector)
567
- .forEach((el) => el.remove());
568
- }
569
-
570
- switch (valueType) {
571
- case "text":
572
- return targetElement.innerText;
573
- case "outerHTML":
574
- case "element":
575
- case "node":
576
- return targetElement.outerHTML;
577
- default:
578
- return targetElement.innerHTML;
579
- }
580
- };
581
-
582
- /**
583
- * Adjusts casing transformations on attributes.
584
- */
585
- function caseHandler(element, value) {
586
- const lowercase = element.getAttribute("value-lowercase");
587
- if (lowercase !== null && lowercase !== "false") {
588
- value = value.toLowerCase();
589
- }
590
-
591
- const uppercase = element.getAttribute("value-uppercase");
592
- if (uppercase !== null && uppercase !== "false") {
593
- value = value.toUpperCase();
594
- }
562
+ const handleElement = (element, valueType, evaluateValue) => {
563
+ if (element.hasAttribute("value")) {
564
+ return evaluateValue
565
+ ? element.getAttribute("value")
566
+ : element.attributes.getNamedItem("value")?.value;
567
+ }
595
568
 
596
- return value;
597
- }
569
+ let targetElement = element;
570
+ const excludeSelector = getValueAttribute(element, "remove-query", "get-value");
598
571
 
599
- /**
600
- * Transforms output based on Regular Expression definitions.
601
- */
602
- function regex(element, value) {
603
- try {
604
- const attributes = element.attributes;
605
- const regexAttribute = [
606
- "value-replace",
607
- "value-replaceall",
608
- "value-test",
609
- "value-match",
610
- "value-split",
611
- "value-lastindex",
612
- "value-search",
613
- "value-exec"
614
- ];
615
-
616
- for (let i = 0; i < attributes.length; i++) {
617
- if (value === null || value === undefined) break;
618
- if (!regexAttribute.includes(attributes[i].name)) continue;
619
-
620
- let regexAttributeValue = attributes[i].value;
621
- if (!regexAttributeValue) continue;
622
-
623
- let { regex, replacement } = regexParser(regexAttributeValue);
624
- if (regex) regexAttributeValue = regex;
625
-
626
- replacement =
627
- replacement || element.getAttribute("value-replacement") || "";
628
-
629
- switch (attributes[i].name) {
630
- case "value-replace":
631
- value = value.replace(regexAttributeValue, replacement);
632
- break;
633
- case "value-replaceall":
634
- value = value.replaceAll(regexAttributeValue, replacement);
635
- break;
636
- case "value-test":
637
- value = regex.test(value);
638
- break;
639
- case "value-match": {
640
- const matches = value.match(regexAttributeValue);
641
- if (matches) {
642
- value = matches[1] || matches[0];
643
- }
644
- break;
645
- }
646
- case "value-split":
647
- value = value.split(regexAttributeValue);
648
- break;
649
- case "value-lastindex":
650
- regex.lastIndex = 0;
651
- regex.test(value);
652
- value = regex.lastIndex;
653
- break;
654
- case "value-search":
655
- value = value.search(regexAttributeValue);
656
- break;
657
- case "value-exec": {
658
- const execResult = regex.exec(value);
659
- if (execResult) {
660
- value = execResult[1] || execResult[2] || execResult[0];
661
- }
662
- break;
663
- }
664
- }
665
- }
666
-
667
- return value;
668
- } catch (error) {
669
- console.warn(
670
- "Warning: Transformation error during regex operation:",
671
- error,
672
- element
673
- );
674
- return value;
675
- }
676
- }
677
-
678
- function regexParser(string) {
679
- let regex, replacement;
680
- let regexMatch = string.match(/\/(.+)\/([gimuy]*)/);
681
-
682
- if (regexMatch) {
683
- regex = new RegExp(regexMatch[1], regexMatch[2]);
684
- const splitReplace = string.split(", ");
685
- replacement =
686
- splitReplace.length > 1 ? splitReplace[1].slice(1, -1) : "";
687
- }
688
-
689
- return { regex, replacement };
690
- }
572
+ if (excludeSelector) {
573
+ targetElement = element.cloneNode(true);
574
+ targetElement
575
+ .querySelectorAll(excludeSelector)
576
+ .forEach((el) => el.remove());
577
+ }
691
578
 
692
- /**
693
- * Encodes calculated structures securely.
694
- */
695
- function encodeValue(value, encodingType) {
696
- if (!encodingType) {
697
- return value;
698
- }
699
-
700
- switch (encodingType.toLowerCase()) {
701
- case "url":
702
- case "uri":
703
- return encodeURI(value.replace(/ /g, "%20"));
704
-
705
- case "uri-component":
706
- return encodeURIComponent(value.replace(/ /g, "%20"));
707
-
708
- case "base64":
709
- case "atob":
710
- try {
711
- const encoder = new TextEncoder();
712
- const uint8Array = encoder.encode(value);
713
- return btoa(String.fromCharCode(...uint8Array));
714
- } catch (error) {
715
- console.warn(`Failed to encode as Base64: ${error.message}`);
716
- return value;
717
- }
718
-
719
- case "html-entities":
720
- return value.replace(/[\u00A0-\u9999<>\&]/g, (i) => {
721
- return `&#${i.charCodeAt(0)};`;
722
- });
723
-
724
- case "json":
725
- try {
726
- return JSON.stringify(value);
727
- } catch (error) {
728
- console.warn(`Failed to convert to JSON: ${error.message}`);
729
- return value;
730
- }
731
-
732
- default:
733
- console.warn(`Unsupported encoding type: ${encodingType}`);
734
- return value;
735
- }
736
- }
579
+ switch (valueType) {
580
+ case "text":
581
+ case "innerText":
582
+ return targetElement.innerText;
583
+ case "textContent":
584
+ return targetElement.textContent;
585
+ case "outerHTML":
586
+ case "element":
587
+ case "node":
588
+ return targetElement.outerHTML;
589
+ default:
590
+ return targetElement.innerHTML;
591
+ }
592
+ };
737
593
 
738
- /**
739
- * Decodes calculated structures securely.
740
- */
741
- function decodeValue(value, decodingType) {
742
- if (!decodingType) {
743
- return value;
744
- }
745
-
746
- switch (decodingType.toLowerCase()) {
747
- case "url":
748
- case "uri":
749
- return decodeURI(value);
750
-
751
- case "uri-component":
752
- return decodeURIComponent(value);
753
-
754
- case "base64":
755
- case "btoa":
756
- try {
757
- const decodedArray = Uint8Array.from(atob(value), (c) =>
758
- c.charCodeAt(0)
759
- );
760
- const decoder = new TextDecoder();
761
- return decoder.decode(decodedArray);
762
- } catch (error) {
763
- console.warn(`Failed to decode Base64: ${error.message}`);
764
- return value;
765
- }
766
-
767
- case "html-entities": {
768
- const tempElement = document.createElement("div");
769
- tempElement.innerHTML = value;
770
- return tempElement.textContent;
771
- }
772
-
773
- case "json":
774
- try {
775
- return JSON.parse(value);
776
- } catch (error) {
777
- console.warn(`Failed to parse JSON: ${error.message}`);
778
- return value;
779
- }
780
-
781
- default:
782
- console.warn(`Unsupported decoding type: ${decodingType}`);
783
- return value;
784
- }
785
- }
786
-
787
- function parseJson(value, valueType) {
788
- if (
789
- value &&
790
- (valueType === "object" ||
791
- valueType === "json" ||
792
- valueType.startsWith("array"))
793
- ) {
794
- try {
795
- value = JSON.parse(value);
796
- } catch {
797
- const jsonRegex = /(\{[\s\S]*}|\[[\s\S]*\])/;
798
- const match = value.match(jsonRegex);
799
-
800
- if (match) {
801
- try {
802
- value = JSON.parse(match[0]);
803
- } catch {
804
- console.warn(
805
- "Warning: Failed to parse JSON after extraction. Returning original value."
806
- );
807
- }
808
- } else {
809
- console.warn(
810
- "Warning: No valid JSON structure found in the string. Returning original value."
811
- );
812
- }
813
- }
814
- }
815
- return value;
816
- }
817
-
818
- function toArray(value, valueType) {
819
- if (valueType.startsWith("array")) {
820
- if (!Array.isArray(value)) {
821
- if (typeof value === "object" && value !== null) {
822
- if (valueType === "array.$keys") {
823
- value = Object.keys(value);
824
- } else if (valueType === "array.$values") {
825
- value = Object.values(value);
826
- } else if (valueType === "array.$entries") {
827
- value = Object.entries(value);
828
- } else {
829
- value = [value];
830
- }
831
- } else {
832
- value = [value];
833
- }
834
- }
835
- }
836
- return value;
837
- }
838
-
839
- export { getValue, getValueAsync, storage };
594
+ export { getValue, getValueAsync, storage };