@cocreate/utils 1.34.2 → 1.35.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.
Files changed (3) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/package.json +1 -1
  3. package/src/index.js +146 -81
package/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ # [1.35.0](https://github.com/CoCreate-app/CoCreate-utils/compare/v1.34.3...v1.35.0) (2024-11-02)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * assign clickedElementListenerAdded = true and improve eroor catching ([e8caa1d](https://github.com/CoCreate-app/CoCreate-utils/commit/e8caa1d5818eff8b44ba552446faac2533ba1d46))
7
+ * csspathformating and removed dead code ([fb7da92](https://github.com/CoCreate-app/CoCreate-utils/commit/fb7da920947ccb1b12ab56a08e3e755610ee0a92))
8
+
9
+
10
+ ### Features
11
+
12
+ * dotNotationToObject improved array support and dynamically create an index with aplha charater to represent the group index [a] ([75c51cf](https://github.com/CoCreate-app/CoCreate-utils/commit/75c51cf4c6e6a0338ca16a8924a07d2e84f5e06d))
13
+
14
+ ## [1.34.3](https://github.com/CoCreate-app/CoCreate-utils/compare/v1.34.2...v1.34.3) (2024-07-09)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * $pull continue if key does not exist ([41f44a0](https://github.com/CoCreate-app/CoCreate-utils/commit/41f44a0f374ce2f264bc5cfcf37fae0279559351))
20
+
1
21
  ## [1.34.2](https://github.com/CoCreate-app/CoCreate-utils/compare/v1.34.1...v1.34.2) (2024-06-23)
2
22
 
3
23
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/utils",
3
- "version": "1.34.2",
3
+ "version": "1.35.0",
4
4
  "description": "A simple utils component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "utils",
package/src/index.js CHANGED
@@ -17,26 +17,25 @@
17
17
  });
18
18
 
19
19
  try {
20
- let frameDocuments = window.top.frameDocuments;
21
- if (!frameDocuments) {
22
- window.top.frameDocuments = new Map();
23
- frameDocuments = window.top.frameDocuments;
24
- }
25
20
  let frames = document.querySelectorAll('iframe');
26
21
  for (let frame of frames) {
27
- let frameDocument = frame.contentDocument;
28
- if (!frameDocuments.has(frameDocument)) {
29
- frameDocuments.set(frameDocument, '')
30
- frameDocument.addEventListener('click', e => {
31
- frameDocument.clickedElement = e.target;
32
- });
22
+ try {
23
+ let frameDocument = frame.contentDocument;
24
+ if (!frameDocument.clickedElementListenerAdded) {
25
+ frameDocument.addEventListener('click', e => {
26
+ frameDocument.clickedElement = e.target;
27
+ });
28
+
29
+ // Mark the document to avoid adding duplicate listeners
30
+ frameDocument.clickedElementListenerAdded = true;
31
+ }
32
+ } catch (iframeError) {
33
+ console.log(`Cross-origin frame handling failed for: ${frame}`, iframeError);
33
34
  }
34
35
  }
35
-
36
36
  } catch (e) {
37
- console.log('cross-origin failed')
37
+ console.log('Top-level frame document handling failed:', e);
38
38
  }
39
-
40
39
  }
41
40
 
42
41
  /**
@@ -100,42 +99,106 @@
100
99
 
101
100
  function dotNotationToObject(data, obj = {}) {
102
101
  try {
102
+ let arrayGroup = {}; // Track groups by key paths (e.g., 'messages[a]')
103
+
103
104
  for (const key of Object.keys(data)) {
104
- let value = data[key]
105
- let newObject = obj
106
- let oldObject = new Object(obj)
105
+ let value = data[key];
106
+ let newObject = obj;
107
+ let oldObject = new Object(obj);
107
108
  let keys = key.split('.');
108
- let length = keys.length - 1
109
+ let length = keys.length - 1;
110
+
109
111
  for (let i = 0; i < keys.length; i++) {
110
- if (/\[([0-9]*)\]/g.test(keys[i])) {
111
- let [k, index] = keys[i].split('[');
112
- index = index.slice(0, -1) || 0
113
- newObject[k] = oldObject[k] || [];
114
- if (length == i) {
115
- if (value === undefined)
116
- newObject[k].splice(index, 1);
117
- else
118
- newObject[k][index] = value;
119
- } else {
120
- newObject[k][index] = oldObject[k][index] || {};
121
- newObject = newObject[k][index]
122
- oldObject = oldObject[k][index]
112
+ // Check if the key ends with ']', indicating an array or grouping operation
113
+ if (keys[i].endsWith(']')) {
114
+ // Handle array push (e.g., messages[] -> push value)
115
+ if (keys[i].endsWith('[]')) {
116
+ let baseKey = keys[i].slice(0, -2); // Remove '[]'
117
+
118
+ // Initialize newObject[baseKey] as an array if not an array or doesn't exist
119
+ if (!Array.isArray(newObject[baseKey])) {
120
+ newObject[baseKey] = [];
121
+ }
122
+
123
+ if (length == i) {
124
+ // If value is an array, spread the array values into newObject[baseKey]
125
+ if (Array.isArray(value)) {
126
+ newObject[baseKey].push(...value);
127
+ } else {
128
+ // If value is not an array, just push the single value
129
+ newObject[baseKey].push(value);
130
+ }
131
+ }
123
132
  }
124
- } else {
133
+ // Check for array index (e.g., messages[0])
134
+ else if (/\[([0-9]+)\]/g.test(keys[i])) {
135
+ let [k, index] = keys[i].split('[');
136
+ index = index.slice(0, -1); // Get the index
137
+
138
+ // Initialize newObject[k] as an array if it doesn't exist or is not an array
139
+ if (!Array.isArray(newObject[k])) {
140
+ newObject[k] = [];
141
+ }
142
+
143
+ if (length == i) {
144
+ if (value === undefined) {
145
+ newObject[k].splice(index, 1); // Remove element if value is undefined
146
+ } else {
147
+ newObject[k][index] = value; // Replace value at specified index
148
+ }
149
+ } else {
150
+ newObject[k][index] = oldObject[k][index] || {}; // Initialize inner object
151
+ newObject = newObject[k][index];
152
+ oldObject = oldObject[k][index];
153
+ }
154
+ }
155
+ // Handle letter-based groupings (e.g., messages[a].role)
156
+ else if (/\[\w\]/g.test(keys[i])) {
157
+ let [k, group] = keys[i].split('[');
158
+ group = group.slice(0, -1); // Get the letter inside []
159
+
160
+ // Initialize newObject[k] as an array if not an array or doesn't exist
161
+ if (!Array.isArray(newObject[k])) {
162
+ newObject[k] = [];
163
+ }
164
+
165
+ // If there's no object at this group index yet, push a new object
166
+ let index;
167
+ if (arrayGroup[keys.slice(0, i + 1).join('.')]) {
168
+ // Reuse the existing index for the group
169
+ index = arrayGroup[keys.slice(0, i + 1).join('.')];
170
+ } else {
171
+ // Create a new group and track the index
172
+ index = newObject[k].length;
173
+ arrayGroup[keys.slice(0, i + 1).join('.')] = index;
174
+ newObject[k][index] = {};
175
+ }
176
+
177
+ // Move into the newly created or existing object for the group
178
+ if (length == i) {
179
+ newObject[k][index] = value; // Set value in the group
180
+ } else {
181
+ newObject = newObject[k][index]; // Continue with the group object
182
+ }
183
+ }
184
+ }
185
+ // Handle regular object keys (non-array keys)
186
+ else {
125
187
  if (length == i) {
126
- if (value === undefined)
127
- delete newObject[keys[i]]
128
- else
129
- newObject[keys[i]] = value;
188
+ if (value === undefined) {
189
+ delete newObject[keys[i]]; // Delete key if value is undefined
190
+ } else {
191
+ newObject[keys[i]] = value; // Set value
192
+ }
130
193
  } else {
131
- newObject[keys[i]] = oldObject[keys[i]] || {};
132
- newObject = newObject[keys[i]]
133
- oldObject = oldObject[keys[i]]
194
+ newObject[keys[i]] = oldObject[keys[i]] || {}; // Initialize inner object
195
+ newObject = newObject[keys[i]];
196
+ oldObject = oldObject[keys[i]];
134
197
  }
135
198
  }
136
199
  }
137
200
  }
138
- return obj
201
+ return obj;
139
202
  } catch (error) {
140
203
  console.log("Error converting dot notation to object", error);
141
204
  return false;
@@ -257,6 +320,8 @@
257
320
  if (!exists)
258
321
  newObject[keys[i]].push(value)
259
322
  } else if (operator === '$pull') {
323
+ if (!newObject[keys[i]])
324
+ continue
260
325
  if (Array.isArray(value)) {
261
326
  newObject[keys[i]] = newObject[keys[i]].filter(item => !Array.isArray(item) || !isEqualArray(item, value));
262
327
  } else if (typeof value === 'object' && value !== null) {
@@ -345,54 +410,42 @@
345
410
  do {
346
411
  if (!node || !node.tagName) return false;
347
412
  let pathSplit = node.tagName.toLowerCase();
348
- // if (node.tagName == "DOM-PARSER" || node.hasAttribute('contenteditable')){
349
- // pathSplit = "[contenteditable]";
350
- // node = '';
351
- // }
413
+
352
414
  if (node.id) {
353
415
  pathSplit += "#" + node.id;
354
416
  node = '';
355
- }
356
- else {
357
- // let eid = node.getAttribute('eid');
358
- // if (/{{\s*([\w\W]+)\s*}}/g.test(eid)) {
359
- // eid = false;
360
- // }
361
- // if (eid) {
362
- // pathSplit += `[eid="${eid}"]`;
363
- // node = '';
364
- // }
365
- // else {
366
- // if (node.classList.length) {
367
- // node.classList.forEach((item) => {
368
- // if (item.indexOf(":") === -1) pathSplit += "." + item;
369
- // });
370
- // }
371
-
372
- if (node.parentNode && node.parentNode.children.length > 1) {
373
- // TODO: improve array logic so ignores javascript generated html??
374
- let children = []
375
- for (let child of node.parentNode.children) {
376
- // if (!child.matches('.mirror'))
377
- // children.push(child);
378
- if (child.tagName == node.tagName)
379
- children.push(child);
417
+ } else {
418
+ let eid = node.getAttribute('eid');
419
+ if (eid && !(/{{\s*([\w\W]+)\s*}}/g.test(eid))) {
420
+ pathSplit += `[eid="${eid}"]`;
421
+ node = '';
422
+ } else
423
+ // if (node.classList.length) {
424
+ // node.classList.forEach((item) => {
425
+ // if (item.indexOf(":") === -1) pathSplit += "." + item;
426
+ // });
427
+ // }
428
+
429
+ if (node.parentNode && node.parentNode.children.length > 1) {
430
+ // TODO: improve array logic so ignores javascript generated html??
431
+ let children = []
432
+ for (let child of node.parentNode.children) {
433
+ if (child.tagName == node.tagName)
434
+ children.push(child);
435
+ }
436
+ let index = Array.prototype.indexOf.call(
437
+ children,
438
+ node
439
+ );
440
+
441
+ pathSplit += `:nth-of-type(${index + 1})`;
380
442
  }
381
- let index = Array.prototype.indexOf.call(
382
- children,
383
- node
384
- );
385
- // if (children.length > 1)
386
- // pathSplit += `:nth-child(${index + 1})`;
387
- pathSplit += `:nth-of-type(${index + 1})`;
388
- }
389
443
 
390
- // pathSplits.unshift(pathSplit);
391
444
  node = node.parentNode;
392
- if (node == null || node.tagName == "HTML" || node.tagName == "DOM-PARSER" || node.nodeName == "#document" || node.hasAttribute('contenteditable'))
445
+ if (node == null || node.tagName == "HTML" || node.tagName == "BODY" || node.tagName == "DOM-PARSER" || node.nodeName == "#document" || node.hasAttribute('contenteditable'))
393
446
  node = '';
394
447
  }
395
- // }
448
+
396
449
  pathSplits.unshift(pathSplit);
397
450
  } while (node);
398
451
  let path = pathSplits.join(" > ")
@@ -487,7 +540,19 @@
487
540
  break;
488
541
  default:
489
542
  if (k === 0 && type[i] === 'closest')
490
- queriedElement = queriedElement.closest(specialSelectors[k])
543
+ if (specialSelectors[k].includes(' ')) {
544
+ let [firstSelector, ...restSelectors] = specialSelectors[k].split(/ (.+)/);
545
+ queriedElement = queriedElement.closest(firstSelector);
546
+ if (restSelectors.length > 0) {
547
+ if (restSelectors[0].endsWith('[]'))
548
+ queriedElement = queriedElement.querySelectorAll(restSelectors[0].slice(0, -2))
549
+ else
550
+ queriedElement = queriedElement.querySelector(restSelectors[0])
551
+ }
552
+ } else {
553
+ // If no space, just use the selector with closest
554
+ queriedElement = queriedElement.closest(specialSelectors[k]);
555
+ }
491
556
  else if (specialSelectors[k].endsWith('[]'))
492
557
  queriedElement = queriedElement.querySelectorAll(specialSelectors[k].slice(0, -2))
493
558
  else