@cocreate/element-prototype 1.26.0 → 1.28.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/setValue.js CHANGED
@@ -1,241 +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
- if (value === '$false') {
18
- return dispatchEvents(el, dispatch)
19
- };
20
-
21
- if (value === null || value === undefined) return;
22
- if (el.hasAttribute('component') || el.hasAttribute('plugin'))
23
- return storage.set(el, value)
24
- else if (typeof value === 'object')
25
- value = JSON.stringify(value, null, 2)
26
-
27
- if (["time", "datetime", "datetime-local"].includes(el.type))
28
- value = new Date(el.value).toLocalString();
29
-
30
- let valueType = el.getAttribute('value-type');
31
- let prefix = el.getAttribute('value-prefix') || "";
32
- if (prefix)
33
- value = value.toString().replace(prefix, "");
34
-
35
- let suffix = el.getAttribute('value-suffix') || "";
36
- if (suffix)
37
- value = value.toString().replace(suffix, "");
38
-
39
- // TODO: el.options vs rendenring options from src
40
- if (el.tagName == 'INPUT' || el.tagName == 'TEXTAREA' || el.tagName == 'SELECT' && el.options.length) {
41
- // TODO: attribute config undefined when used with onload-value
42
- let isCrdt = el.getAttribute('crdt')
43
- if (isCrdt == "true" || el.type === 'file')
44
- return;
45
-
46
- if (el.type == 'checkbox') {
47
- let inputs = [el]
48
- let key = el.getAttribute('key');
49
- if (key)
50
- inputs = document.querySelectorAll(`input[type="${el.type}"][key="${key}"]`);
51
-
52
- for (let i = 0; i < inputs.length; i++) {
53
- if (inputs[i].value) {
54
- if (value === true || value === false)
55
- inputs[i].checked = value;
56
- else if (value.includes(inputs[i].value))
57
- inputs[i].checked = true;
58
- else
59
- inputs[i].checked = false;
60
- } else {
61
- if (value === 'true' || value === true || value === 'checked')
62
- inputs[i].checked = true;
63
- else
64
- inputs[i].checked = false;
65
-
66
- }
67
- }
68
- } else if (el.type === 'radio') {
69
- el.value == value ? el.checked = true : el.checked = false;
70
- } else if (el.type === 'password') {
71
- el.value = __decryptPassword(value);
72
- } else if (el.tagName == "SELECT" && el.hasAttribute('multiple') && Array.isArray(value)) {
73
- let options = el.options;
74
- for (let i = 0; i < options.length; i++) {
75
- if (value.includes(options[i].value)) {
76
- options[i].selected = "selected";
77
- } else {
78
- options[i].selected = "";
79
- }
80
- }
81
- } else {
82
- if (el.value === value)
83
- return
84
-
85
- el.value = value;
86
- }
87
- dispatchEvents(el, dispatch)
88
- } else if (el.tagName === 'IMG' || el.tagName === 'SOURCE') {
89
- el.src = value;
90
- } else if (el.tagName === 'IFRAME') {
91
- el.srcdoc = value;
92
- } else if (el.tagName === 'SCRIPT') {
93
- setScript(el, value);
94
- } else {
95
- if (el.hasAttribute('contenteditable') && el == document.activeElement) return;
96
-
97
- if (valueType == 'string' || valueType == 'text')
98
- el.textContent = value;
99
- else {
100
- let newElement = document.createElement("div");
101
- newElement.innerHTML = value;
102
- setState(newElement)
103
-
104
- let CoCreateJS = newElement.querySelector('script[src*="CoCreate.js"], script[src*="CoCreate.min.js"]')
105
- if (CoCreateJS)
106
- CoCreateJS.remove()
107
-
108
- let CoCreateCSS = newElement.querySelector('link[href*="CoCreate.css"], link[href*="CoCreate.min.css"]')
109
- if (CoCreateCSS)
110
- CoCreateCSS.remove()
111
-
112
- let css = newElement.querySelector('link[array], link[object]')
113
- if (css)
114
- css.remove()
115
-
116
- if (valueType == 'outerHTML') {
117
- let parentNode = el.parentNode;
118
- if (parentNode) {
119
- if (newElement.children.length > 0) {
120
- let fragment = document.createDocumentFragment();
121
- while (newElement.firstChild) {
122
- fragment.appendChild(newElement.firstChild);
123
- }
124
- parentNode.replaceChild(fragment, el);
125
- } else {
126
- parentNode.replaceChild(newElement, el);
127
- }
128
- }
129
- } else
130
- el.innerHTML = newElement.innerHTML;
131
-
132
- let scripts = el.querySelectorAll('script');
133
- for (let script of scripts) {
134
- setScript(script)
135
- }
136
-
137
- }
138
-
139
- if (el.hasAttribute("value")) {
140
- el.setAttribute("value", value);
141
- }
142
-
143
-
144
- dispatchEvents(el, dispatch);
145
-
146
- }
147
-
148
- if (el.getAttribute('contenteditable'))
149
- dispatchEvents(el, dispatch);
150
-
151
- if (el.tagName == 'HEAD' || el.tagName == 'BODY') {
152
- el.removeAttribute('array');
153
- el.removeAttribute('object');
154
- el.removeAttribute('state_id');
155
-
156
- let scripts = el.querySelectorAll('script');
157
- for (let script of scripts) {
158
- setScript(script)
159
- }
160
- }
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);
161
167
  };
162
168
 
163
169
  function setState(el) {
164
- if (CoCreate.state) {
165
- let stateElements = el.querySelectorAll('[state_id]');
166
- if (stateElements)
167
- CoCreate.state.initElements(stateElements)
168
- }
170
+ if (CoCreate.state) {
171
+ let stateElements = el.querySelectorAll("[state_id]");
172
+ if (stateElements) CoCreate.state.initElements(stateElements);
173
+ }
169
174
  }
170
175
 
171
176
  function setScript(script, value) {
172
- let srcAttribute = script.src
173
- if (srcAttribute) {
174
- let pageOrigin = window.location.origin;
175
- let srcOrigin;
176
-
177
- try {
178
- srcOrigin = new URL(srcAttribute, document.baseURI).origin;
179
- } catch (e) {
180
- // Handle invalid URLs
181
- console.error("Invalid URL in src attribute:", srcAttribute);
182
- return;
183
- }
184
- if (pageOrigin !== srcOrigin)
185
- return
186
- }
187
-
188
- let newScript = document.createElement('script');
189
- for (let attr of script.attributes) {
190
- newScript.setAttribute(attr.name, attr.value);
191
- }
192
- newScript.innerHTML = script.innerHTML;
193
- if (value) {
194
- if (script.hasAttribute("src"))
195
- newScript.src = value;
196
- else
197
- newScript.innerHTML = value;
198
- }
199
- try {
200
- script.replaceWith(newScript);
201
- } catch (error) {
202
- console.log(error)
203
- }
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
+ }
204
206
  }
205
207
 
206
208
  function __decryptPassword(str) {
207
- if (!str) return "";
208
- let decode_str = atob(str);
209
- return decode_str;
209
+ if (!str) return "";
210
+ let decode_str = atob(str);
211
+ return decode_str;
210
212
  }
211
213
 
212
- function dispatchEvents(el, skip = true) {
213
- let inputEvent = new CustomEvent('input', {
214
- bubbles: true,
215
- detail: {
216
- skip
217
- },
218
- });
219
-
220
- Object.defineProperty(inputEvent, 'target', {
221
- writable: false,
222
- value: el
223
- });
224
- el.dispatchEvent(inputEvent);
225
-
226
- let changeEvent = new CustomEvent('change', {
227
- bubbles: true,
228
- detail: {
229
- skip
230
- },
231
- });
232
-
233
- Object.defineProperty(changeEvent, 'target', {
234
- writable: false,
235
- value: el
236
- });
237
- 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);
238
240
  }
239
241
 
240
-
241
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 };