@cocreate/element-prototype 1.27.0 → 1.28.1

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/setValue.js CHANGED
@@ -1,242 +1,242 @@
1
- import { storage } from './getValue';
1
+ import { storage } from "./getValue";
2
2
 
3
3
  HTMLElement.prototype.setValue = function (value, dispatch) {
4
- setValue(this, value, dispatch)
5
- };
6
-
7
- HTMLInputElement.prototype.setValue = function (value, dispatch) {
8
- setValue(this, value, dispatch)
9
- };
10
-
11
- HTMLHeadingElement.prototype.setValue = function (value, dispatch) {
12
- setValue(this, value, dispatch)
4
+ setValue(this, value, dispatch);
13
5
  };
14
6
 
15
7
  // TODO: check if using a a switch case will provide better performance
16
8
  const setValue = (el, value, dispatch) => {
17
- let valueDispatch = el.getAttribute('value-dispatch')
18
- if ((valueDispatch || valueDispatch === '') && (value === '$false' || value === undefined || value === null)) {
19
- return dispatchEvents(el, dispatch)
20
- };
21
-
22
- if (value === null || value === undefined) return;
23
- if (el.hasAttribute('component') || el.hasAttribute('plugin'))
24
- return storage.set(el, value)
25
- else if (typeof value === 'object')
26
- value = JSON.stringify(value, null, 2)
27
-
28
- if (["time", "datetime", "datetime-local"].includes(el.type))
29
- value = new Date(el.value).toLocalString();
30
-
31
- let valueType = el.getAttribute('value-type');
32
- let prefix = el.getAttribute('value-prefix') || "";
33
- if (prefix)
34
- value = value.toString().replace(prefix, "");
35
-
36
- let suffix = el.getAttribute('value-suffix') || "";
37
- if (suffix)
38
- value = value.toString().replace(suffix, "");
39
-
40
- // TODO: el.options vs rendenring options from src
41
- if (el.tagName == 'INPUT' || el.tagName == 'TEXTAREA' || el.tagName == 'SELECT' && el.options.length) {
42
- // TODO: attribute config undefined when used with onload-value
43
- let isCrdt = el.getAttribute('crdt')
44
- if (isCrdt == "true" || el.type === 'file')
45
- return;
46
-
47
- if (el.type == 'checkbox') {
48
- let inputs = [el]
49
- let key = el.getAttribute('key');
50
- if (key)
51
- inputs = document.querySelectorAll(`input[type="${el.type}"][key="${key}"]`);
52
-
53
- for (let i = 0; i < inputs.length; i++) {
54
- if (inputs[i].value) {
55
- if (value === true || value === false)
56
- inputs[i].checked = value;
57
- else if (value.includes(inputs[i].value))
58
- inputs[i].checked = true;
59
- else
60
- inputs[i].checked = false;
61
- } else {
62
- if (value === 'true' || value === true || value === 'checked')
63
- inputs[i].checked = true;
64
- else
65
- inputs[i].checked = false;
66
-
67
- }
68
- }
69
- } else if (el.type === 'radio') {
70
- el.value == value ? el.checked = true : el.checked = false;
71
- } else if (el.type === 'password') {
72
- el.value = __decryptPassword(value);
73
- } else if (el.tagName == "SELECT" && el.hasAttribute('multiple') && Array.isArray(value)) {
74
- let options = el.options;
75
- for (let i = 0; i < options.length; i++) {
76
- if (value.includes && value.includes(options[i].value)) {
77
- options[i].selected = "selected";
78
- } else {
79
- options[i].selected = "";
80
- }
81
- }
82
- } else {
83
- if (el.value === value)
84
- return
85
-
86
- el.value = value;
87
- }
88
- dispatchEvents(el, dispatch)
89
- } else if (el.tagName === 'IMG' || el.tagName === 'SOURCE') {
90
- el.src = value;
91
- } else if (el.tagName === 'IFRAME') {
92
- el.srcdoc = value;
93
- } else if (el.tagName === 'SCRIPT') {
94
- setScript(el, value);
95
- } else {
96
- if (el.hasAttribute('contenteditable') && el == document.activeElement) return;
97
-
98
- if (valueType == 'string' || valueType == 'text')
99
- el.textContent = value;
100
- else {
101
- let newElement = document.createElement("div");
102
- newElement.innerHTML = value;
103
- setState(newElement)
104
-
105
- let CoCreateJS = newElement.querySelector('script[src*="CoCreate.js"], script[src*="CoCreate.min.js"]')
106
- if (CoCreateJS)
107
- CoCreateJS.remove()
108
-
109
- let CoCreateCSS = newElement.querySelector('link[href*="CoCreate.css"], link[href*="CoCreate.min.css"]')
110
- if (CoCreateCSS)
111
- CoCreateCSS.remove()
112
-
113
- let css = newElement.querySelector('link[array], link[object]')
114
- if (css)
115
- css.remove()
116
-
117
- if (valueType == 'outerHTML') {
118
- let parentNode = el.parentNode;
119
- if (parentNode) {
120
- if (newElement.children.length > 0) {
121
- let fragment = document.createDocumentFragment();
122
- while (newElement.firstChild) {
123
- fragment.appendChild(newElement.firstChild);
124
- }
125
- parentNode.replaceChild(fragment, el);
126
- } else {
127
- parentNode.replaceChild(newElement, el);
128
- }
129
- }
130
- } else
131
- el.innerHTML = newElement.innerHTML;
132
-
133
- let scripts = el.querySelectorAll('script');
134
- for (let script of scripts) {
135
- setScript(script)
136
- }
137
-
138
- }
139
-
140
- if (el.hasAttribute("value")) {
141
- el.setAttribute("value", value);
142
- }
143
-
144
-
145
- dispatchEvents(el, dispatch);
146
-
147
- }
148
-
149
- if (el.getAttribute('contenteditable'))
150
- dispatchEvents(el, dispatch);
151
-
152
- if (el.tagName == 'HEAD' || el.tagName == 'BODY') {
153
- el.removeAttribute('array');
154
- el.removeAttribute('object');
155
- el.removeAttribute('state_id');
156
-
157
- let scripts = el.querySelectorAll('script');
158
- for (let script of scripts) {
159
- setScript(script)
160
- }
161
- }
9
+ let bubbles = el.hasAttribute("value-bubbles");
10
+ let valueDispatch = el.hasAttribute("value-dispatch");
11
+ if (valueDispatch || valueDispatch === "") {
12
+ if (value === "$false" || value === undefined || value === null)
13
+ return dispatchEvents(el, bubbles, dispatch);
14
+ }
15
+
16
+ if (value === null || value === undefined) return;
17
+ if (el.hasAttribute("component") || el.hasAttribute("plugin"))
18
+ return storage.set(el, value);
19
+ else if (typeof value === "object") value = JSON.stringify(value, null, 2);
20
+
21
+ if (["time", "datetime", "datetime-local"].includes(el.type)) {
22
+ if (el.value) {
23
+ value = new Date(el.value).toLocalString();
24
+ } else {
25
+ value = "";
26
+ }
27
+ }
28
+
29
+ let valueType = el.getAttribute("value-type");
30
+ let prefix = el.getAttribute("value-prefix") || "";
31
+ if (prefix) value = value.toString().replace(prefix, "");
32
+
33
+ let suffix = el.getAttribute("value-suffix") || "";
34
+ if (suffix) value = value.toString().replace(suffix, "");
35
+
36
+ // TODO: el.options vs rendenring options from src
37
+ if (
38
+ el.tagName == "INPUT" ||
39
+ el.tagName == "TEXTAREA" ||
40
+ (el.tagName == "SELECT" && el.options.length)
41
+ ) {
42
+ // TODO: attribute config undefined when used with onload-value
43
+ let isCrdt = el.getAttribute("crdt");
44
+ if (isCrdt == "true" || el.type === "file") return;
45
+
46
+ if (el.type == "checkbox") {
47
+ let inputs = [el];
48
+ let key = el.getAttribute("key");
49
+ if (key)
50
+ inputs = document.querySelectorAll(
51
+ `input[type="${el.type}"][key="${key}"]`
52
+ );
53
+
54
+ for (let i = 0; i < inputs.length; i++) {
55
+ let inputValue = inputs[i].getAttribute("value");
56
+ if (inputs[i].value) {
57
+ if (value === true || value === false)
58
+ inputs[i].checked = value;
59
+ else if (value.includes(inputValue))
60
+ inputs[i].checked = true;
61
+ else inputs[i].checked = false;
62
+ } else {
63
+ if (
64
+ value === "true" ||
65
+ value === true ||
66
+ value === "checked"
67
+ )
68
+ inputs[i].checked = true;
69
+ else inputs[i].checked = false;
70
+ }
71
+ }
72
+ } else if (el.type === "radio") {
73
+ el.value == value ? (el.checked = true) : (el.checked = false);
74
+ } else if (el.type === "password") {
75
+ el.value = __decryptPassword(value);
76
+ } else if (
77
+ el.tagName == "SELECT" &&
78
+ el.hasAttribute("multiple") &&
79
+ Array.isArray(value)
80
+ ) {
81
+ let options = el.options;
82
+ for (let i = 0; i < options.length; i++) {
83
+ if (value.includes && value.includes(options[i].value)) {
84
+ options[i].selected = "selected";
85
+ } else {
86
+ options[i].selected = "";
87
+ }
88
+ }
89
+ } else {
90
+ if (el.value === value && !valueDispatch) {
91
+ return;
92
+ }
93
+
94
+ el.value = value;
95
+ }
96
+ // dispatchEvents(el, bubbles, dispatch);
97
+ } else if (el.tagName === "IMG" || el.tagName === "SOURCE") {
98
+ el.src = value;
99
+ } else if (el.tagName === "IFRAME") {
100
+ el.srcdoc = value;
101
+ } else if (el.tagName === "SCRIPT") {
102
+ setScript(el, value);
103
+ } else {
104
+ if (el.hasAttribute("contenteditable") && el == document.activeElement)
105
+ return;
106
+
107
+ if (valueType == "string" || valueType == "text")
108
+ el.textContent = value;
109
+ else {
110
+ let newElement = document.createElement("div");
111
+ newElement.innerHTML = value;
112
+ setState(newElement);
113
+
114
+ let CoCreateJS = newElement.querySelector(
115
+ 'script[src*="CoCreate.js"], script[src*="CoCreate.min.js"]'
116
+ );
117
+ if (CoCreateJS) CoCreateJS.remove();
118
+
119
+ let CoCreateCSS = newElement.querySelector(
120
+ 'link[href*="CoCreate.css"], link[href*="CoCreate.min.css"]'
121
+ );
122
+ if (CoCreateCSS) CoCreateCSS.remove();
123
+
124
+ let css = newElement.querySelector("link[array], link[object]");
125
+ if (css) css.remove();
126
+
127
+ if (valueType == "outerHTML") {
128
+ let parentNode = el.parentNode;
129
+ if (parentNode) {
130
+ if (newElement.children.length > 0) {
131
+ let fragment = document.createDocumentFragment();
132
+ while (newElement.firstChild) {
133
+ fragment.appendChild(newElement.firstChild);
134
+ }
135
+ parentNode.replaceChild(fragment, el);
136
+ } else {
137
+ parentNode.replaceChild(newElement, el);
138
+ }
139
+ }
140
+ } else el.innerHTML = newElement.innerHTML;
141
+
142
+ let scripts = el.querySelectorAll("script");
143
+ for (let script of scripts) {
144
+ setScript(script);
145
+ }
146
+ }
147
+
148
+ if (el.hasAttribute("value")) {
149
+ el.setAttribute("value", value);
150
+ }
151
+ }
152
+
153
+ // if (el.getAttribute("contenteditable")) dispatchEvents(el, bubbles, dispatch);
154
+
155
+ if (el.tagName == "HEAD" || el.tagName == "BODY") {
156
+ el.removeAttribute("array");
157
+ el.removeAttribute("object");
158
+ el.removeAttribute("state_id");
159
+
160
+ let scripts = el.querySelectorAll("script");
161
+ for (let script of scripts) {
162
+ setScript(script);
163
+ }
164
+ }
165
+
166
+ dispatchEvents(el, bubbles, dispatch);
162
167
  };
163
168
 
164
169
  function setState(el) {
165
- if (CoCreate.state) {
166
- let stateElements = el.querySelectorAll('[state_id]');
167
- if (stateElements)
168
- CoCreate.state.initElements(stateElements)
169
- }
170
+ if (CoCreate.state) {
171
+ let stateElements = el.querySelectorAll("[state_id]");
172
+ if (stateElements) CoCreate.state.initElements(stateElements);
173
+ }
170
174
  }
171
175
 
172
176
  function setScript(script, value) {
173
- let srcAttribute = script.src
174
- if (srcAttribute) {
175
- let pageOrigin = window.location.origin;
176
- let srcOrigin;
177
-
178
- try {
179
- srcOrigin = new URL(srcAttribute, document.baseURI).origin;
180
- } catch (e) {
181
- // Handle invalid URLs
182
- console.error("Invalid URL in src attribute:", srcAttribute);
183
- return;
184
- }
185
- if (pageOrigin !== srcOrigin)
186
- return
187
- }
188
-
189
- let newScript = document.createElement('script');
190
- for (let attr of script.attributes) {
191
- newScript.setAttribute(attr.name, attr.value);
192
- }
193
- newScript.innerHTML = script.innerHTML;
194
- if (value) {
195
- if (script.hasAttribute("src"))
196
- newScript.src = value;
197
- else
198
- newScript.innerHTML = value;
199
- }
200
- try {
201
- script.replaceWith(newScript);
202
- } catch (error) {
203
- console.log(error)
204
- }
177
+ let srcAttribute = script.src;
178
+ if (srcAttribute) {
179
+ let pageOrigin = window.location.origin;
180
+ let srcOrigin;
181
+
182
+ try {
183
+ srcOrigin = new URL(srcAttribute, document.baseURI).origin;
184
+ } catch (e) {
185
+ // Handle invalid URLs
186
+ console.error("Invalid URL in src attribute:", srcAttribute);
187
+ return;
188
+ }
189
+ if (pageOrigin !== srcOrigin) return;
190
+ }
191
+
192
+ let newScript = document.createElement("script");
193
+ for (let attr of script.attributes) {
194
+ newScript.setAttribute(attr.name, attr.value);
195
+ }
196
+ newScript.innerHTML = script.innerHTML;
197
+ if (value) {
198
+ if (script.hasAttribute("src")) newScript.src = value;
199
+ else newScript.innerHTML = value;
200
+ }
201
+ try {
202
+ script.replaceWith(newScript);
203
+ } catch (error) {
204
+ console.log(error);
205
+ }
205
206
  }
206
207
 
207
208
  function __decryptPassword(str) {
208
- if (!str) return "";
209
- let decode_str = atob(str);
210
- return decode_str;
209
+ if (!str) return "";
210
+ let decode_str = atob(str);
211
+ return decode_str;
211
212
  }
212
213
 
213
- function dispatchEvents(el, skip = true) {
214
- let inputEvent = new CustomEvent('input', {
215
- bubbles: true,
216
- detail: {
217
- skip
218
- },
219
- });
220
-
221
- Object.defineProperty(inputEvent, 'target', {
222
- writable: false,
223
- value: el
224
- });
225
- el.dispatchEvent(inputEvent);
226
-
227
- let changeEvent = new CustomEvent('change', {
228
- bubbles: true,
229
- detail: {
230
- skip
231
- },
232
- });
233
-
234
- Object.defineProperty(changeEvent, 'target', {
235
- writable: false,
236
- value: el
237
- });
238
- el.dispatchEvent(changeEvent);
214
+ function dispatchEvents(el, bubbles = true, skip = true) {
215
+ let inputEvent = new CustomEvent("input", {
216
+ bubbles,
217
+ detail: {
218
+ skip
219
+ }
220
+ });
221
+
222
+ Object.defineProperty(inputEvent, "target", {
223
+ writable: false,
224
+ value: el
225
+ });
226
+ el.dispatchEvent(inputEvent);
227
+
228
+ let changeEvent = new CustomEvent("change", {
229
+ bubbles,
230
+ detail: {
231
+ skip
232
+ }
233
+ });
234
+
235
+ Object.defineProperty(changeEvent, "target", {
236
+ writable: false,
237
+ value: el
238
+ });
239
+ el.dispatchEvent(changeEvent);
239
240
  }
240
241
 
241
-
242
242
  export { setValue };
package/src/utility.js ADDED
@@ -0,0 +1,80 @@
1
+ import { ObjectId } from "@cocreate/utils";
2
+
3
+ function getSubdomain() {
4
+ const hostname = window.location.hostname; // e.g., "api.dev.example.com"
5
+ const parts = hostname.split(".");
6
+
7
+ // Handle edge cases for single-word hostnames or IPs
8
+ if (parts.length > 2 && isNaN(parts[parts.length - 1])) {
9
+ return parts.slice(0, parts.length - 2).join("."); // Subdomain
10
+ }
11
+
12
+ return null; // No subdomain
13
+ }
14
+
15
+ const operatorsMap = {
16
+ $href: function () {
17
+ return window.location.href;
18
+ },
19
+ $origin: function () {
20
+ return window.location.origin;
21
+ },
22
+ $protocol: function () {
23
+ return window.location.protocol;
24
+ },
25
+ $host: function () {
26
+ return window.location.host;
27
+ },
28
+ $hostname: function () {
29
+ return window.location.hostname;
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();
45
+ }
46
+ };
47
+
48
+ function urlOperators(value) {
49
+ if (typeof value !== "string") {
50
+ console.error("Value is not a string:", value);
51
+ return value; // Return as-is for non-string input
52
+ }
53
+
54
+ // Dynamically construct a regex from the keys in operatorsMap
55
+ const operatorKeys = Object.keys(operatorsMap)
56
+ .map((key) => `\\${key}`)
57
+ .join("|");
58
+ const regex = new RegExp(operatorKeys, "g");
59
+
60
+ // Debugging regex match
61
+ // if (!regex.test(value)) {
62
+ // console.warn("Regex did not match any part of the input value.");
63
+ // }
64
+
65
+ // Replace matched operators with their resolved values
66
+ const updatedValue = value.replace(regex, function (match) {
67
+ if (operatorsMap[match]) {
68
+ const replacement = operatorsMap[match]();
69
+ console.log(`Replacing "${match}" with "${replacement}"`);
70
+ return replacement || "";
71
+ } else {
72
+ console.warn(`No match found for "${match}" in operatorsMap.`);
73
+ return ""; // Default replacement if operator not found
74
+ }
75
+ });
76
+
77
+ return updatedValue;
78
+ }
79
+
80
+ export default { urlOperators };