@cocreate/state 1.23.0 → 1.24.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 +12 -0
- package/package.json +1 -1
- package/src/index.js +222 -164
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# [1.24.0](https://github.com/CoCreate-app/CoCreate-state/compare/v1.23.0...v1.24.0) (2024-12-14)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* support setting empty string ([ee2ad83](https://github.com/CoCreate-app/CoCreate-state/commit/ee2ad83dfddfb9209b64fdbd154c5ed85340b238))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* support comma seperated states to apply multiple states ([1777635](https://github.com/CoCreate-app/CoCreate-state/commit/1777635b0d3f98979c08735e07d137d9bfc40230))
|
|
12
|
+
|
|
1
13
|
# [1.23.0](https://github.com/CoCreate-app/CoCreate-state/compare/v1.22.2...v1.23.0) (2024-11-04)
|
|
2
14
|
|
|
3
15
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/state",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0",
|
|
4
4
|
"description": "Data attributes which can be used for components in CoCreate framework combined as a group of attributes that dynamically change attributes & fetch custom data.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"state",
|
package/src/index.js
CHANGED
|
@@ -1,205 +1,263 @@
|
|
|
1
|
-
import
|
|
2
|
-
import observer from
|
|
3
|
-
import action from
|
|
4
|
-
import uid from
|
|
5
|
-
import localStorage from
|
|
6
|
-
|
|
1
|
+
import "@cocreate/element-prototype";
|
|
2
|
+
import observer from "@cocreate/observer";
|
|
3
|
+
import action from "@cocreate/actions";
|
|
4
|
+
import uid from "@cocreate/uuid";
|
|
5
|
+
import localStorage from "@cocreate/local-storage";
|
|
7
6
|
|
|
8
7
|
function init() {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
8
|
+
let elements = document.querySelectorAll("[state_id]");
|
|
9
|
+
initElements(elements);
|
|
10
|
+
window.addEventListener("storage", function (e) {
|
|
11
|
+
if (e.key == "statedAttributes") {
|
|
12
|
+
elements = document.querySelectorAll(
|
|
13
|
+
'[state_id]:not([state-onstoragechange="false"])'
|
|
14
|
+
);
|
|
15
|
+
initElements(elements);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
document.addEventListener("click", function (e) {
|
|
19
|
+
const target = e.target.closest("[state_to]");
|
|
20
|
+
if (target) {
|
|
21
|
+
if (target.closest('[actions*="state"]')) return;
|
|
22
|
+
stateAttributes(target);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
function initElements(elements) {
|
|
27
|
-
|
|
28
|
-
initElement(element);
|
|
28
|
+
for (let element of elements) initElement(element);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
function initElement(element) {
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
let state_id = element.getAttribute("state_id");
|
|
33
|
+
if (!state_id) return;
|
|
34
|
+
|
|
35
|
+
let statedAttributes = localStorage.getItem("statedAttributes");
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
if (!statedAttributes || statedAttributes.length == 0) return;
|
|
38
|
+
statedAttributes = JSON.parse(statedAttributes);
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
statedAttributes = JSON.parse(statedAttributes);
|
|
40
|
+
if (state_id.includes(",")) state_id = state_id.split(",");
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
if (!Array.isArray(state_id)) state_id = [state_id];
|
|
43
|
+
|
|
44
|
+
for (let i = 0; i < state_id.length; i++) {
|
|
45
|
+
let attrValues = statedAttributes[`${state_id[i].trim()}`];
|
|
46
|
+
if (!attrValues) return;
|
|
47
|
+
_setAttributeValues(element, attrValues);
|
|
48
|
+
}
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
function _setAttributeValues(el, attrValues) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
52
|
+
let isOverwrite = el.getAttribute("state-overwrite");
|
|
53
|
+
if (isOverwrite === null || isOverwrite === undefined)
|
|
54
|
+
isOverwrite = attrValues["overwrite"];
|
|
55
|
+
|
|
56
|
+
if ((isOverwrite && isOverwrite != "false") || isOverwrite === "")
|
|
57
|
+
isOverwrite = true;
|
|
58
|
+
else if (!isOverwrite || isOverwrite === "false") isOverwrite = false;
|
|
59
|
+
|
|
60
|
+
// delete attrValues["overwrite"];
|
|
61
|
+
|
|
62
|
+
for (const key of Object.keys(attrValues)) {
|
|
63
|
+
_setAttributeValue(el, key, attrValues[key], isOverwrite);
|
|
64
|
+
_setAttributeValue(el, `state-${key}`, attrValues[key], isOverwrite);
|
|
65
|
+
if (key == "array" || key == "object" || key == "name") {
|
|
66
|
+
_setAttributeValue(
|
|
67
|
+
el,
|
|
68
|
+
`fetch-${key}`,
|
|
69
|
+
attrValues[key],
|
|
70
|
+
isOverwrite
|
|
71
|
+
);
|
|
72
|
+
_setAttributeValue(
|
|
73
|
+
el,
|
|
74
|
+
`state-fetch-${key}`,
|
|
75
|
+
attrValues[key],
|
|
76
|
+
isOverwrite
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
if (key == "template") {
|
|
80
|
+
_setAttributeValue(el, "template_id", attrValues[key], isOverwrite);
|
|
81
|
+
}
|
|
82
|
+
if (key == "template_id") {
|
|
83
|
+
_setAttributeValue(el, "template", attrValues[key], isOverwrite);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
71
86
|
}
|
|
72
87
|
|
|
73
88
|
async function _setAttributeValue(element, attribute, value, isOverwrite) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
89
|
+
// TODO: if (value !== undefined)???
|
|
90
|
+
if (!element.getAttribute(attribute) || isOverwrite) {
|
|
91
|
+
if (attribute == "value") {
|
|
92
|
+
if (element.value == "" || (element.value && isOverwrite))
|
|
93
|
+
element.value = value;
|
|
94
|
+
else if (
|
|
95
|
+
isOverwrite ||
|
|
96
|
+
(element.hasAttribute("value") && !(await element.getValue()))
|
|
97
|
+
)
|
|
98
|
+
element.setValue(value);
|
|
99
|
+
} else if (element.hasAttribute(attribute) && (value || value === ""))
|
|
100
|
+
element.setAttribute(attribute, value);
|
|
101
|
+
}
|
|
84
102
|
}
|
|
85
103
|
|
|
86
104
|
async function stateAttributes(element) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
let state_to = elements[i].getAttribute('state_to');
|
|
114
|
-
Object.assign(statedAttributes, { [`${state_to}`]: attrValues });
|
|
115
|
-
_getStateId(attrValues, state_to);
|
|
116
|
-
}
|
|
117
|
-
statedAttributes = JSON.stringify(statedAttributes)
|
|
118
|
-
let href = element.closest('href')
|
|
119
|
-
if (!changeState && !href) {
|
|
120
|
-
// TODO: Handle $title when adding statedAttributes
|
|
121
|
-
let title = element.getAttribute('title') || document.title || '';
|
|
122
|
-
history.pushState({ statedAttributes, title, url: location.href }, title, location.href);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (!changeState)
|
|
126
|
-
localStorage.setItem('statedAttributes', statedAttributes);
|
|
127
|
-
|
|
128
|
-
document.dispatchEvent(new CustomEvent('stateEnd', {
|
|
129
|
-
detail: {}
|
|
130
|
-
}))
|
|
105
|
+
let statedAttributes = {};
|
|
106
|
+
try {
|
|
107
|
+
const storedAttributes = localStorage.getItem("statedAttributes");
|
|
108
|
+
if (storedAttributes) {
|
|
109
|
+
statedAttributes = JSON.parse(storedAttributes);
|
|
110
|
+
}
|
|
111
|
+
} catch (error) {
|
|
112
|
+
console.error(
|
|
113
|
+
"Failed to parse statedAttributes from localStorage:",
|
|
114
|
+
error
|
|
115
|
+
);
|
|
116
|
+
// Optionally reset `statedAttributes` in localStorage to ensure valid data:
|
|
117
|
+
localStorage.setItem("statedAttributes", JSON.stringify({}));
|
|
118
|
+
}
|
|
119
|
+
let elements = [];
|
|
120
|
+
|
|
121
|
+
let form = element.closest("form");
|
|
122
|
+
if (form) {
|
|
123
|
+
elements = form.querySelectorAll("[state_to]");
|
|
124
|
+
} else {
|
|
125
|
+
if (element.hasAttribute("state_to")) elements.push(element);
|
|
126
|
+
let nestedElements = element.querySelectorAll("[state_to]");
|
|
127
|
+
elements.push(...nestedElements);
|
|
128
|
+
}
|
|
131
129
|
|
|
130
|
+
let changeState = false;
|
|
131
|
+
for (let i = 0; i < elements.length; i++) {
|
|
132
|
+
let attrValues = await _getAttributeValues(elements[i]);
|
|
133
|
+
if (attrValues.src === "$back" || attrValues.href === "$back") {
|
|
134
|
+
changeState = true;
|
|
135
|
+
window.history.back();
|
|
136
|
+
break;
|
|
137
|
+
} else if (
|
|
138
|
+
attrValues.src === "$forward" ||
|
|
139
|
+
attrValues.href === "$forward"
|
|
140
|
+
) {
|
|
141
|
+
changeState = true;
|
|
142
|
+
window.history.forward();
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
let state_to = elements[i].getAttribute("state_to");
|
|
147
|
+
Object.assign(statedAttributes, { [`${state_to}`]: attrValues });
|
|
148
|
+
_getStateId(attrValues, state_to);
|
|
149
|
+
}
|
|
150
|
+
statedAttributes = JSON.stringify(statedAttributes);
|
|
151
|
+
let href = element.closest("href");
|
|
152
|
+
if (!changeState && !href) {
|
|
153
|
+
// TODO: Handle $title when adding statedAttributes
|
|
154
|
+
let title = element.getAttribute("title") || document.title || "";
|
|
155
|
+
history.pushState(
|
|
156
|
+
{ statedAttributes, title, url: location.href },
|
|
157
|
+
title,
|
|
158
|
+
location.href
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!changeState)
|
|
163
|
+
localStorage.setItem("statedAttributes", statedAttributes);
|
|
164
|
+
|
|
165
|
+
document.dispatchEvent(
|
|
166
|
+
new CustomEvent("stateEnd", {
|
|
167
|
+
detail: {}
|
|
168
|
+
})
|
|
169
|
+
);
|
|
132
170
|
}
|
|
133
171
|
|
|
134
172
|
async function _getAttributeValues(element) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
173
|
+
let attributeValues = {};
|
|
174
|
+
let attributes = element.attributes;
|
|
175
|
+
for (let attribute of attributes) {
|
|
176
|
+
if (attribute.name.startsWith("state-")) {
|
|
177
|
+
if (attribute.value == "$uid")
|
|
178
|
+
Object.assign(attributeValues, {
|
|
179
|
+
[`${attribute.name.substring(5)}`]: uid.generate(6)
|
|
180
|
+
});
|
|
181
|
+
else if (attribute.name == "state-value" && !attribute.value)
|
|
182
|
+
Object.assign(attributeValues, {
|
|
183
|
+
value: await element.getvalue()
|
|
184
|
+
});
|
|
185
|
+
else
|
|
186
|
+
Object.assign(attributeValues, {
|
|
187
|
+
[`${attribute.name.substring(6)}`]: attribute.value
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (
|
|
192
|
+
element.value !== undefined &&
|
|
193
|
+
!element.hasAttribute("state-value") &&
|
|
194
|
+
element.getvalue
|
|
195
|
+
)
|
|
196
|
+
Object.assign(attributeValues, { value: await element.getvalue() });
|
|
197
|
+
|
|
198
|
+
return attributeValues;
|
|
151
199
|
}
|
|
152
200
|
|
|
153
201
|
function _getStateId(attrValues, state_to) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
_setAttributeValues(element, attrValues);
|
|
202
|
+
const elements = document.querySelectorAll(`[state_id="${state_to}"]`);
|
|
203
|
+
for (let element of elements) _setAttributeValues(element, attrValues);
|
|
157
204
|
}
|
|
158
205
|
|
|
159
206
|
window.onload = function () {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
207
|
+
if (!history.length) {
|
|
208
|
+
const statedAttributes = localStorage.getItem("statedAttributes") || "";
|
|
209
|
+
history.replaceState(
|
|
210
|
+
{ statedAttributes, url: location.href, title: document.title },
|
|
211
|
+
document.title,
|
|
212
|
+
location.href
|
|
213
|
+
);
|
|
214
|
+
} else if (!history.state || history.state.url !== location.href) {
|
|
215
|
+
const statedAttributes = localStorage.getItem("statedAttributes") || "";
|
|
216
|
+
history.pushState(
|
|
217
|
+
{ statedAttributes, url: location.href, title: document.title },
|
|
218
|
+
document.title,
|
|
219
|
+
location.href
|
|
220
|
+
);
|
|
221
|
+
}
|
|
167
222
|
};
|
|
168
223
|
|
|
169
|
-
window.addEventListener(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
224
|
+
window.addEventListener("popstate", function (event) {
|
|
225
|
+
if (event.state) {
|
|
226
|
+
if (event.state.statedAttributes) {
|
|
227
|
+
localStorage.setItem(
|
|
228
|
+
"statedAttributes",
|
|
229
|
+
event.state.statedAttributes
|
|
230
|
+
);
|
|
231
|
+
let elements = document.querySelectorAll("[state_id]");
|
|
232
|
+
initElements(elements);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (event.state.url && event.state.url !== window.location.href) {
|
|
236
|
+
if (event.state.title)
|
|
237
|
+
sessionStorage.setItem("currentPageTitle", event.state.title); // Store title in session storage
|
|
238
|
+
|
|
239
|
+
location.href = event.state.url; // Navigate if the URL is different
|
|
240
|
+
} else if (event.state.title) {
|
|
241
|
+
document.title = event.state.title; // Update the title if provided
|
|
242
|
+
}
|
|
243
|
+
}
|
|
186
244
|
});
|
|
187
245
|
|
|
188
246
|
observer.init({
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
247
|
+
name: "CoCreateState",
|
|
248
|
+
observe: ["addedNodes"],
|
|
249
|
+
selector: "[state_id]",
|
|
250
|
+
callback: function (mutation) {
|
|
251
|
+
initElement(mutation.target);
|
|
252
|
+
}
|
|
195
253
|
});
|
|
196
254
|
|
|
197
255
|
action.init({
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
256
|
+
name: "state",
|
|
257
|
+
endEvent: "stateEnd",
|
|
258
|
+
callback: (data) => {
|
|
259
|
+
stateAttributes(data.element);
|
|
260
|
+
}
|
|
203
261
|
});
|
|
204
262
|
|
|
205
263
|
init();
|