@cocreate/element-prototype 1.28.0 → 1.29.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/CHANGELOG.md +29 -0
- package/package.json +4 -2
- package/src/getAttribute.js +2 -31
- package/src/getValue.js +57 -56
- package/src/index.js +12 -4
- package/src/queryElements.js +5 -0
- package/src/setValue.js +20 -3
- package/src/utility.js +185 -65
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
# [1.29.0](https://github.com/CoCreate-app/CoCreate-element-prototype/compare/v1.28.1...v1.29.0) (2025-04-11)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* default to string if value is falsy and not 0 ([b8eadb1](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/b8eadb19405393eb1121e257571d3cff45db6263))
|
|
7
|
+
* format dat and time to correct format to set on inputs ([35dd407](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/35dd4071c89741b468ac8e9a3927abf06cef5838))
|
|
8
|
+
* if value-type condition before switch case ([066da57](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/066da57a48fb8c0758254525a9d273977d8dba0a))
|
|
9
|
+
* setAttribute value ([afcc695](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/afcc695ba678cc2c8a525ea5093a5421407eebf5))
|
|
10
|
+
* update exports ([19eb2ae](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/19eb2aeab014f367d67009e6e9ae38f50f2b0104))
|
|
11
|
+
* utility import ([1f3337a](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/1f3337a6422e0615a3e3d38532f71d489b0d9690))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* $scrollWidth , $relativPath and $path operators ([08844ba](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/08844ba13c82f9542cf70b68a42a77d3e259f999))
|
|
17
|
+
* add [@cocreate](https://github.com/cocreate) utils ([d82ee9b](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/d82ee9b685e98eec292e96dfc247b87847fde56e))
|
|
18
|
+
* added queryElements() to element prototype. wiil automatically use attibutes if found on element as well as options could be passed ([70114a1](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/70114a1dde8dc8263b1fd4f86907a118aa596167))
|
|
19
|
+
* improved operators to target element poperties and methods ([2734187](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/2734187b6640119f8e00dc374e056acd502f8d71))
|
|
20
|
+
* utility for operator handling ([d76a0f6](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/d76a0f6640ce5069823f7b8a71272d3738a44e17))
|
|
21
|
+
|
|
22
|
+
## [1.28.1](https://github.com/CoCreate-app/CoCreate-element-prototype/compare/v1.28.0...v1.28.1) (2025-01-18)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* comment new regex and reinstate previous regex ([dfe7354](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/dfe7354052718e247414e5c29b566c9532d80e79))
|
|
28
|
+
* range input returns a single number if if min not defiened ([07afdc4](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/07afdc4f5132e800e3f63fa16edc2b8232afa5fe))
|
|
29
|
+
|
|
1
30
|
# [1.28.0](https://github.com/CoCreate-app/CoCreate-element-prototype/compare/v1.27.0...v1.28.0) (2024-12-14)
|
|
2
31
|
|
|
3
32
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/element-prototype",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.29.0",
|
|
4
4
|
"description": "A simple element-prototype component in vanilla javascript. Easily configured using HTML5 data-attributes and/or JavaScript API.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"element-prototype",
|
|
@@ -57,5 +57,7 @@
|
|
|
57
57
|
"webpack-cli": "^4.5.0",
|
|
58
58
|
"webpack-log": "^3.0.1"
|
|
59
59
|
},
|
|
60
|
-
"dependencies": {
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"@cocreate/utils": "1.37.3"
|
|
62
|
+
}
|
|
61
63
|
}
|
package/src/getAttribute.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { processOperators } from "./utility";
|
|
2
2
|
|
|
3
3
|
// Store a reference to the original getAttribute function
|
|
4
4
|
const originalGetAttribute = Element.prototype.getAttribute;
|
|
@@ -22,34 +22,5 @@ function updateAttributes(e) {
|
|
|
22
22
|
// Override the getAttribute function
|
|
23
23
|
Element.prototype.getAttribute = function (name) {
|
|
24
24
|
let value = originalGetAttribute.call(this, name);
|
|
25
|
-
|
|
26
|
-
const localKeys = {
|
|
27
|
-
$organization_id: "organization_id",
|
|
28
|
-
$user_id: "user_id",
|
|
29
|
-
$clientId: "clientId",
|
|
30
|
-
$session_id: "session_id"
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
if (localKeys.hasOwnProperty(value)) {
|
|
34
|
-
let newValue = localStorage.getItem(localKeys[value]);
|
|
35
|
-
|
|
36
|
-
if (!attributes.has(localKeys[value])) {
|
|
37
|
-
attributes.set(localKeys[value], []);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
attributes.get(localKeys[value]).push({
|
|
41
|
-
element: this,
|
|
42
|
-
name,
|
|
43
|
-
value: newValue
|
|
44
|
-
});
|
|
45
|
-
value = newValue;
|
|
46
|
-
} else if (value === "$innerWidth") {
|
|
47
|
-
value = window.innerWidth;
|
|
48
|
-
} else if (value === "$innerHeight") {
|
|
49
|
-
value = window.innerHeight;
|
|
50
|
-
} else if (typeof value === "string" && value.includes("$")) {
|
|
51
|
-
value = utility.urlOperators(value);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return value;
|
|
25
|
+
return processOperators(this, value);
|
|
55
26
|
};
|
package/src/getValue.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { processOperators } from "./utility";
|
|
2
2
|
|
|
3
3
|
const storage = new Map();
|
|
4
4
|
|
|
@@ -59,7 +59,9 @@ const getValue = (element) => {
|
|
|
59
59
|
} else if (element.type === "number") {
|
|
60
60
|
value = Number(value);
|
|
61
61
|
} else if (element.type === "range") {
|
|
62
|
-
|
|
62
|
+
if (Number(element.min))
|
|
63
|
+
value = [Number(element.min), Number(element.value)];
|
|
64
|
+
else value = Number(element.value);
|
|
63
65
|
} else if (element.type === "password") {
|
|
64
66
|
value = btoa(value || "");
|
|
65
67
|
} else if (element.type === "email") {
|
|
@@ -93,51 +95,53 @@ const getValue = (element) => {
|
|
|
93
95
|
// value = value.substring(11, 8) + 'Z';
|
|
94
96
|
value = value.substring(11, 19) + "Z";
|
|
95
97
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
98
|
+
if (valueType) {
|
|
99
|
+
switch (valueType) {
|
|
100
|
+
case "getDayName":
|
|
101
|
+
const days = [
|
|
102
|
+
"Sunday",
|
|
103
|
+
"Monday",
|
|
104
|
+
"Tuesday",
|
|
105
|
+
"Wednesday",
|
|
106
|
+
"Thursday",
|
|
107
|
+
"Friday",
|
|
108
|
+
"Saturday"
|
|
109
|
+
];
|
|
110
|
+
value = days[value.getDay()];
|
|
111
|
+
break;
|
|
112
|
+
case "getMonthName":
|
|
113
|
+
const months = [
|
|
114
|
+
"January",
|
|
115
|
+
"February",
|
|
116
|
+
"March",
|
|
117
|
+
"April",
|
|
118
|
+
"May",
|
|
119
|
+
"June",
|
|
120
|
+
"July",
|
|
121
|
+
"August",
|
|
122
|
+
"September",
|
|
123
|
+
"October",
|
|
124
|
+
"November",
|
|
125
|
+
"December"
|
|
126
|
+
];
|
|
127
|
+
value = months[value.getMonth()];
|
|
128
|
+
break;
|
|
129
|
+
case "toUnixTimestamp":
|
|
130
|
+
value = Math.floor(value.getTime() / 1000);
|
|
131
|
+
break;
|
|
132
|
+
case "toLocaleString":
|
|
133
|
+
let locale = element.getAttribute("locale") || "en-US";
|
|
134
|
+
value = value[valueType](locale);
|
|
135
|
+
break;
|
|
136
|
+
default:
|
|
137
|
+
if (typeof value[valueType] === "function") {
|
|
138
|
+
value = value[valueType]();
|
|
139
|
+
} else {
|
|
140
|
+
console.warn(
|
|
141
|
+
`The method ${valueType} is not a function of Date object.`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
141
145
|
}
|
|
142
146
|
}
|
|
143
147
|
} else if (element.tagName == "INPUT" || element.tagName == "SELECT") {
|
|
@@ -169,6 +173,8 @@ const getValue = (element) => {
|
|
|
169
173
|
value = targetElement.innerText;
|
|
170
174
|
} else if (valueType === "outerHTML") {
|
|
171
175
|
value = targetElement.outerHTML;
|
|
176
|
+
} else if (valueType === "element" || valueType === "node") {
|
|
177
|
+
value = targetElement.outerHTML;
|
|
172
178
|
} else {
|
|
173
179
|
value = targetElement.innerHTML;
|
|
174
180
|
}
|
|
@@ -179,15 +185,7 @@ const getValue = (element) => {
|
|
|
179
185
|
else return true;
|
|
180
186
|
}
|
|
181
187
|
|
|
182
|
-
|
|
183
|
-
value = localStorage.getItem("organization_id");
|
|
184
|
-
else if (value === "$user_id") value = localStorage.getItem("user_id");
|
|
185
|
-
else if (value === "$clientId") value = localStorage.getItem("clientId");
|
|
186
|
-
else if (value === "$session_id")
|
|
187
|
-
value = localStorage.getItem("session_id");
|
|
188
|
-
else if (typeof value === "string" && value.includes("$")) {
|
|
189
|
-
value = utility.urlOperators(value);
|
|
190
|
-
}
|
|
188
|
+
value = processOperators(element, value, ["$value"]);
|
|
191
189
|
|
|
192
190
|
try {
|
|
193
191
|
const attributes = element.attributes; // Get all attributes of the element
|
|
@@ -344,6 +342,9 @@ const getValue = (element) => {
|
|
|
344
342
|
|
|
345
343
|
function regexParser(string) {
|
|
346
344
|
let regex, replacement;
|
|
345
|
+
// Match a regex pattern enclosed by delimiters or a bare regex string
|
|
346
|
+
// let regexMatch = string.match(/^\/(.+)\/([gimuy]*)$/) || [null, string, ""];
|
|
347
|
+
|
|
347
348
|
let regexMatch = string.match(/\/(.+)\/([gimuy]*)/);
|
|
348
349
|
if (regexMatch) {
|
|
349
350
|
regex = new RegExp(regexMatch[1], regexMatch[2]);
|
package/src/index.js
CHANGED
|
@@ -20,8 +20,16 @@
|
|
|
20
20
|
// you must obtain a commercial license from CoCreate LLC.
|
|
21
21
|
// For details, visit <https://cocreate.app/licenses/> or contact us at sales@cocreate.app.
|
|
22
22
|
|
|
23
|
-
import { getAttribute } from
|
|
24
|
-
import { setValue } from
|
|
25
|
-
import { getValue } from
|
|
23
|
+
import { getAttribute } from "./getAttribute";
|
|
24
|
+
import { setValue } from "./setValue";
|
|
25
|
+
import { getValue } from "./getValue";
|
|
26
|
+
import { queryElements } from "./queryElements";
|
|
27
|
+
import { processOperators } from "./utility";
|
|
26
28
|
|
|
27
|
-
export default {
|
|
29
|
+
export default {
|
|
30
|
+
getAttribute,
|
|
31
|
+
getValue,
|
|
32
|
+
setValue,
|
|
33
|
+
processOperators,
|
|
34
|
+
queryElements
|
|
35
|
+
};
|
package/src/setValue.js
CHANGED
|
@@ -19,11 +19,26 @@ const setValue = (el, value, dispatch) => {
|
|
|
19
19
|
else if (typeof value === "object") value = JSON.stringify(value, null, 2);
|
|
20
20
|
|
|
21
21
|
if (["time", "datetime", "datetime-local"].includes(el.type)) {
|
|
22
|
-
if (
|
|
23
|
-
|
|
22
|
+
if (value) {
|
|
23
|
+
const date = new Date(value);
|
|
24
|
+
if (el.type === "time") {
|
|
25
|
+
// Format time as "HH:MM"
|
|
26
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
27
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
28
|
+
el.value = `${hours}:${minutes}`;
|
|
29
|
+
} else if (el.type === "datetime-local") {
|
|
30
|
+
// Format datetime-local as "YYYY-MM-DDTHH:MM"
|
|
31
|
+
const year = date.getFullYear();
|
|
32
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
33
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
34
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
35
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
36
|
+
el.value = `${year}-${month}-${day}T${hours}:${minutes}`;
|
|
37
|
+
}
|
|
24
38
|
} else {
|
|
25
|
-
value = "";
|
|
39
|
+
el.value = "";
|
|
26
40
|
}
|
|
41
|
+
return dispatchEvents(el, bubbles, dispatch);
|
|
27
42
|
}
|
|
28
43
|
|
|
29
44
|
let valueType = el.getAttribute("value-type");
|
|
@@ -100,6 +115,8 @@ const setValue = (el, value, dispatch) => {
|
|
|
100
115
|
el.srcdoc = value;
|
|
101
116
|
} else if (el.tagName === "SCRIPT") {
|
|
102
117
|
setScript(el, value);
|
|
118
|
+
} else if (el.hasAttribute("value")) {
|
|
119
|
+
value = el.setAttribute("value", value);
|
|
103
120
|
} else {
|
|
104
121
|
if (el.hasAttribute("contenteditable") && el == document.activeElement)
|
|
105
122
|
return;
|
package/src/utility.js
CHANGED
|
@@ -1,80 +1,200 @@
|
|
|
1
|
-
import { ObjectId } from "@cocreate/utils";
|
|
1
|
+
import { ObjectId, queryElements } from "@cocreate/utils";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
// Operators handled directly for simple, synchronous value retrieval
|
|
4
|
+
const customOperators = new Map(
|
|
5
|
+
Object.entries({
|
|
6
|
+
$organization_id: () => localStorage.getItem("organization_id"),
|
|
7
|
+
$user_id: () => localStorage.getItem("user_id"),
|
|
8
|
+
$clientId: () => localStorage.getItem("clientId"),
|
|
9
|
+
$session_id: () => localStorage.getItem("session_id"),
|
|
10
|
+
$value: (element) => element.getValue() || "",
|
|
11
|
+
$innerWidth: () => window.innerWidth,
|
|
12
|
+
$innerHeight: () => window.innerHeight,
|
|
13
|
+
$href: () => window.location.href.replace(/\/$/, ""),
|
|
14
|
+
$origin: () => window.location.origin,
|
|
15
|
+
$protocol: () => window.location.protocol,
|
|
16
|
+
$hostname: () => window.location.hostname,
|
|
17
|
+
$host: () => window.location.host,
|
|
18
|
+
$port: () => window.location.port,
|
|
19
|
+
$pathname: () => window.location.pathname.replace(/\/$/, ""),
|
|
20
|
+
$hash: () => window.location.hash,
|
|
21
|
+
$subdomain: () => getSubdomain() || "",
|
|
22
|
+
$object_id: () => ObjectId().toString(),
|
|
23
|
+
"ObjectId()": () => ObjectId().toString(),
|
|
24
|
+
$relativePath: () => {
|
|
25
|
+
let depth = window.location.pathname.split("/").length - 1;
|
|
26
|
+
return depth > 0 ? "../".repeat(depth) : "./";
|
|
27
|
+
},
|
|
28
|
+
$path: () => {
|
|
29
|
+
let path = window.location.pathname;
|
|
30
|
+
if (path.split("/").pop().includes(".")) {
|
|
31
|
+
path = path.replace(/\/[^\/]+$/, "/");
|
|
32
|
+
}
|
|
33
|
+
return path === "/" ? "" : path;
|
|
34
|
+
},
|
|
35
|
+
$param: (element, args) => args,
|
|
36
|
+
$setValue: (element, args) => element.setValue(...args) || ""
|
|
37
|
+
})
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
// Operators that access a specific property of a target element
|
|
41
|
+
const propertyOperators = new Set([
|
|
42
|
+
"$scrollWidth",
|
|
43
|
+
"$scrollHeight",
|
|
44
|
+
"$offsetWidth",
|
|
45
|
+
"$offsetHeight",
|
|
46
|
+
"$id",
|
|
47
|
+
"$tagName",
|
|
48
|
+
"$className",
|
|
49
|
+
"$textContent",
|
|
50
|
+
"$innerHTML",
|
|
51
|
+
"$getValue"
|
|
52
|
+
]);
|
|
53
|
+
|
|
54
|
+
// Combine all known operator keys for the main parsing regex
|
|
55
|
+
const knownOperatorKeys = [
|
|
56
|
+
...customOperators.keys(),
|
|
57
|
+
...propertyOperators
|
|
58
|
+
].sort((a, b) => b.length - a.length);
|
|
59
|
+
|
|
60
|
+
function escapeRegexKey(key) {
|
|
61
|
+
if (key.startsWith("$")) {
|
|
62
|
+
return "\\" + key; // Escape the leading $
|
|
63
|
+
} else if (key === "ObjectId()") {
|
|
64
|
+
return "ObjectId\\(\\)"; // Escape the parentheses
|
|
65
|
+
}
|
|
66
|
+
return key; // Should not happen with current keys, but fallback
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const operatorPattern = knownOperatorKeys.map(escapeRegexKey).join("|");
|
|
70
|
+
|
|
71
|
+
// Regex to find potential operators and their arguments
|
|
72
|
+
// $1: Potential operator identifier (e.g., $user_id, $closestDiv)
|
|
73
|
+
// $2: Arguments within parentheses (optional)
|
|
74
|
+
const regex = new RegExp(`(${operatorPattern})(?:\\s*\\((.*?)\\))?`, "g");
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Synchronously processes a string, finding and replacing operators recursively.
|
|
78
|
+
* Assumes ALL underlying operations (getValue, queryElements) are synchronous.
|
|
79
|
+
* @param {Element | null} element - Context element.
|
|
80
|
+
* @param {string} value - String containing operators.
|
|
81
|
+
* @param {string[]} [exclude=[]] - Operator prefixes to ignore.
|
|
82
|
+
* @returns {string} - Processed string.
|
|
83
|
+
*/
|
|
84
|
+
function processOperators(element, value, exclude = [], parent) {
|
|
85
|
+
// Early exit if no operators are possible or value is not a string
|
|
86
|
+
if (typeof value !== "string" || !value.includes("$")) {
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
let params = [];
|
|
90
|
+
const processedValue = value.replace(
|
|
91
|
+
regex,
|
|
92
|
+
(match, operator, args = "") => {
|
|
93
|
+
// 'match' is the full matched string (e.g., "$closest(.myClass)")
|
|
94
|
+
// 'operator' is the identifier part (e.g., "$closest")
|
|
95
|
+
// 'args' is the content within parentheses (e.g., ".myClass") or "" if no parentheses
|
|
96
|
+
|
|
97
|
+
if (operator === "$param" && !args) {
|
|
98
|
+
return match;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// If a valid operator was identified AND it's not in the exclude list
|
|
102
|
+
if (operator && !exclude.includes(operator)) {
|
|
103
|
+
// Resolve the value for the identified operator and its arguments
|
|
104
|
+
// Pass the *trimmed* arguments to the resolver
|
|
105
|
+
let resolvedValue = resolveOperator(
|
|
106
|
+
element,
|
|
107
|
+
operator,
|
|
108
|
+
args.replace(/^['"]|['"]$/g, "").trim(),
|
|
109
|
+
parent
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
if (operator === "$param") {
|
|
113
|
+
params.push(resolvedValue);
|
|
114
|
+
return "";
|
|
115
|
+
}
|
|
6
116
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
117
|
+
return resolvedValue ?? "";
|
|
118
|
+
} else {
|
|
119
|
+
// If no known operator matched, or if it was excluded,
|
|
120
|
+
// return the original matched string (no replacement).
|
|
121
|
+
return match;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
if (params.length) {
|
|
127
|
+
return params;
|
|
10
128
|
}
|
|
11
129
|
|
|
12
|
-
return
|
|
130
|
+
return processedValue;
|
|
13
131
|
}
|
|
14
132
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
$port: function () {
|
|
32
|
-
return window.location.port;
|
|
33
|
-
},
|
|
34
|
-
$pathname: function () {
|
|
35
|
-
return window.location.pathname;
|
|
36
|
-
},
|
|
37
|
-
$hash: function () {
|
|
38
|
-
return window.location.hash;
|
|
39
|
-
},
|
|
40
|
-
$subdomain: function () {
|
|
41
|
-
return getSubdomain() || "";
|
|
42
|
-
},
|
|
43
|
-
$object_id: function () {
|
|
44
|
-
return ObjectId().toString();
|
|
133
|
+
/**
|
|
134
|
+
* Synchronously determines and executes the action for a single operator token.
|
|
135
|
+
* @returns {string} The final string value for the token.
|
|
136
|
+
*/
|
|
137
|
+
function resolveOperator(element, operator, args, parent) {
|
|
138
|
+
if (args && args.includes("$")) {
|
|
139
|
+
args = processOperators(element, args, "", operator);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
let targetElements = element ? [element] : [];
|
|
143
|
+
if (args && typeof args === "string") {
|
|
144
|
+
targetElements = queryElements({
|
|
145
|
+
element,
|
|
146
|
+
args
|
|
147
|
+
});
|
|
45
148
|
}
|
|
46
|
-
};
|
|
47
149
|
|
|
48
|
-
|
|
49
|
-
if (typeof value
|
|
50
|
-
|
|
51
|
-
return value; // Return as-is for non-string input
|
|
150
|
+
let value = processValues(targetElements, operator, args, parent);
|
|
151
|
+
if (value && typeof value === "string" && value.includes("$")) {
|
|
152
|
+
value = processOperators(element, value, parent);
|
|
52
153
|
}
|
|
53
154
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
155
|
+
return value;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Synchronously aggregates values.
|
|
160
|
+
* @returns {string} The aggregated string value.
|
|
161
|
+
*/
|
|
162
|
+
function processValues(elements, operator, args, parent) {
|
|
163
|
+
let customOp = customOperators.get(operator);
|
|
164
|
+
let aggregatedString = "";
|
|
165
|
+
for (const el of elements) {
|
|
166
|
+
if (!el) continue;
|
|
167
|
+
let rawValue = customOp || el?.[operator.substring(1)];
|
|
168
|
+
if (typeof rawValue === "function") {
|
|
169
|
+
if (Array.isArray(args)) {
|
|
170
|
+
if (args.length) {
|
|
171
|
+
return "";
|
|
172
|
+
}
|
|
173
|
+
rawValue = rawValue(el, ...args);
|
|
174
|
+
} else {
|
|
175
|
+
rawValue = rawValue(el, args);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (parent === "$param") {
|
|
180
|
+
if (rawValue) {
|
|
181
|
+
return rawValue;
|
|
182
|
+
}
|
|
71
183
|
} else {
|
|
72
|
-
|
|
73
|
-
return ""; // Default replacement if operator not found
|
|
184
|
+
aggregatedString += String(rawValue ?? "");
|
|
74
185
|
}
|
|
75
|
-
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return aggregatedString;
|
|
189
|
+
}
|
|
76
190
|
|
|
77
|
-
|
|
191
|
+
function getSubdomain() {
|
|
192
|
+
const hostname = window.location.hostname;
|
|
193
|
+
const parts = hostname.split(".");
|
|
194
|
+
if (parts.length > 2 && isNaN(parseInt(parts[parts.length - 1]))) {
|
|
195
|
+
return parts.slice(0, parts.length - 2).join(".");
|
|
196
|
+
}
|
|
197
|
+
return null;
|
|
78
198
|
}
|
|
79
199
|
|
|
80
|
-
export
|
|
200
|
+
export { processOperators };
|