@cocreate/utils 1.21.15 → 1.22.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/index.js CHANGED
@@ -1,14 +1,621 @@
1
1
  (function (root, factory) {
2
2
  if (typeof define === 'function' && define.amd) {
3
- define(["./utils"], function(CoCreateUtils) {
4
- return factory(CoCreateUtils)
3
+ define([], function () {
4
+ return factory(true)
5
5
  });
6
6
  } else if (typeof module === 'object' && module.exports) {
7
- const CoCreateUtils = require("./utils.js")
8
- module.exports = factory(CoCreateUtils);
7
+ module.exports = factory(false);
9
8
  } else {
10
- root.returnExports = factory(root["./utils.js"]);
11
- }
12
- }(typeof self !== 'undefined' ? self : this, function (CoCreateUtils) {
13
- return CoCreateUtils;
14
- }));
9
+ root.returnExports = factory(true);
10
+ }
11
+ }(typeof self !== 'undefined' ? self : this, function (isBrowser) {
12
+
13
+ /*globals DOMParser*/
14
+ function clickedElement() {
15
+ document.addEventListener('click', e => {
16
+ document.clickedElement = e.target;
17
+ });
18
+
19
+ try {
20
+ let frameDocuments = window.top.frameDocuments;
21
+ if (!frameDocuments) {
22
+ window.top.frameDocuments = new Map();
23
+ frameDocuments = window.top.frameDocuments;
24
+ }
25
+ let frames = document.querySelectorAll('iframe');
26
+ 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
+ });
33
+ }
34
+ }
35
+
36
+ } catch (e) {
37
+ console.log('cross-origin failed')
38
+ }
39
+
40
+ }
41
+
42
+ const ObjectId = (rnd = r16 => Math.floor(r16).toString(16)) =>
43
+ rnd(Date.now() / 1000) + ' '.repeat(16).replace(/./g, () => rnd(Math.random() * 16));
44
+
45
+ function checkValue(value) {
46
+ if (/{{\s*([\w\W]+)\s*}}/g.test(value))
47
+ return false;
48
+ else
49
+ return true
50
+ }
51
+
52
+ function dotNotationToObject(data, obj = {}) {
53
+ try {
54
+ for (const key of Object.keys(data)) {
55
+ let value = data[key]
56
+ let newObject = obj
57
+ let oldObject = new Object(obj)
58
+ let keys = key.split('.');
59
+ let length = keys.length - 1
60
+ for (let i = 0; i < keys.length; i++) {
61
+ if (/\[([0-9]*)\]/g.test(keys[i])) {
62
+ let [k, index] = keys[i].split('[');
63
+ index = index.slice(0, -1)
64
+ if (length == i) {
65
+ if (value === undefined)
66
+ newObject[k].splice(index, 1);
67
+ else
68
+ newObject[k][index] = value;
69
+ } else {
70
+ newObject[k] = oldObject[k] || [];
71
+ newObject[k][index] = oldObject[k][index] || {};
72
+ newObject = newObject[k][index]
73
+ oldObject = oldObject[k][index]
74
+ }
75
+ } else {
76
+ if (length == i) {
77
+ if (value === undefined)
78
+ delete newObject[keys[i]]
79
+ else
80
+ newObject[keys[i]] = value;
81
+ } else {
82
+ newObject[keys[i]] = oldObject[keys[i]] || {};
83
+ newObject = newObject[keys[i]]
84
+ oldObject = oldObject[keys[i]]
85
+ }
86
+ }
87
+ }
88
+ }
89
+ return obj
90
+ } catch (error) {
91
+ console.log("Error converting dot notation to object", error);
92
+ return false;
93
+ }
94
+ }
95
+
96
+ function getValueFromObject(json, path) {
97
+ try {
98
+ if (typeof json == 'undefined' || !path)
99
+ return;
100
+
101
+ path = path.replace(/\[(\d+)\]/g, '.$1');
102
+
103
+ let jsonData = json, subpath = path.split('.');
104
+
105
+ for (let i = 0; i < subpath.length; i++) {
106
+ jsonData = jsonData[subpath[i]];
107
+ if (!jsonData)
108
+ return jsonData;
109
+ }
110
+ return jsonData;
111
+ } catch (error) {
112
+ console.log("Error in getValueFromObject", error);
113
+ return;
114
+ }
115
+ }
116
+
117
+ function isObjectEmpty(obj) {
118
+ for (var x in obj) { return false }
119
+ return true;
120
+ }
121
+
122
+ function domParser(str) {
123
+ try {
124
+ var mainTag = str.match(/\<(?<tag>[a-z0-9]+)(.*?)?\>/).groups.tag;
125
+ } catch (e) {
126
+ // console.log(e, 'find position: can not find the main tag');
127
+ }
128
+ let doc;
129
+ switch (mainTag) {
130
+ case 'html':
131
+ doc = new DOMParser().parseFromString(str, "text/html");
132
+ return doc.documentElement;
133
+ case 'body':
134
+ doc = new DOMParser().parseFromString(str, "text/html");
135
+ return doc.body;
136
+ case 'head':
137
+ doc = new DOMParser().parseFromString(str, "text/html");
138
+ return doc.head;
139
+
140
+ default:
141
+ let con = document.createElement('dom-parser');
142
+ con.innerHTML = str;
143
+ return con;
144
+ }
145
+ }
146
+
147
+ function parseTextToHtml(text) {
148
+ let doc = new DOMParser().parseFromString(text, "text/html");
149
+ if (doc.head.children[0]) return doc.head.children[0];
150
+ else return doc.body.children[0];
151
+ }
152
+
153
+ function escapeHtml(html) {
154
+ return html.replaceAll('&', '&amp').replaceAll('<', '&lt').replaceAll('>', '&gt;').replaceAll("'", '&#39;').replaceAll('"', '&quot;');
155
+ }
156
+
157
+ function cssPath(node, container) {
158
+ let pathSplits = [];
159
+ do {
160
+ if (!node || !node.tagName) return false;
161
+ let pathSplit = node.tagName.toLowerCase();
162
+ // if (node.tagName == "DOM-PARSER" || node.hasAttribute('contenteditable')){
163
+ // pathSplit = "[contenteditable]";
164
+ // node = '';
165
+ // }
166
+ if (node.id) {
167
+ pathSplit += "#" + node.id;
168
+ node = '';
169
+ }
170
+ else {
171
+ // let eid = node.getAttribute('eid');
172
+ // if (/{{\s*([\w\W]+)\s*}}/g.test(eid)) {
173
+ // eid = false;
174
+ // }
175
+ // if (eid) {
176
+ // pathSplit += `[eid="${eid}"]`;
177
+ // node = '';
178
+ // }
179
+ // else {
180
+ // if (node.classList.length) {
181
+ // node.classList.forEach((item) => {
182
+ // if (item.indexOf(":") === -1) pathSplit += "." + item;
183
+ // });
184
+ // }
185
+
186
+ if (node.parentNode && node.parentNode.children.length > 1) {
187
+ // TODO: improve array logic so ignores javascript generated html??
188
+ let children = []
189
+ for (let child of node.parentNode.children) {
190
+ // if (!child.matches('.mirror'))
191
+ // children.push(child);
192
+ if (child.tagName == node.tagName)
193
+ children.push(child);
194
+ }
195
+ let index = Array.prototype.indexOf.call(
196
+ children,
197
+ node
198
+ );
199
+ // if (children.length > 1)
200
+ // pathSplit += `:nth-child(${index + 1})`;
201
+ pathSplit += `:nth-of-type(${index + 1})`;
202
+ }
203
+
204
+ // pathSplits.unshift(pathSplit);
205
+ node = node.parentNode;
206
+ if (node == null || node.tagName == "HTML" || node.tagName == "DOM-PARSER" || node.nodeName == "#document" || node.hasAttribute('contenteditable'))
207
+ node = '';
208
+ }
209
+ // }
210
+ pathSplits.unshift(pathSplit);
211
+ } while (node);
212
+ let path = pathSplits.join(" > ")
213
+ if (path && path.includes('<')) {
214
+ let index = path.lastIndexOf(' >')
215
+ if (index != -1)
216
+ path = path.slice(0, index)
217
+ else {
218
+ index = path.lastIndexOf('<')
219
+ path = path.slice(0, index)
220
+ }
221
+ }
222
+
223
+ return path;
224
+ }
225
+
226
+ function queryElements({ element, prefix, type, selector }) {
227
+ let elements = new Map()
228
+ if (!element)
229
+ element = document
230
+ let hasAttribute = false
231
+
232
+ if (selector) {
233
+ if (!type)
234
+ type = ['selector']
235
+ else if (!Array.isArray(type))
236
+ type = [type]
237
+ } else
238
+ type = ['selector', 'closest', 'parent', 'next', 'previous']
239
+
240
+ for (let i = 0; i < type.length; i++) {
241
+ let Selector = selector
242
+ if (!Selector && element.nodeType !== 9) {
243
+
244
+ let name = prefix + '-' + type[i]
245
+ if (!element.hasAttribute(name))
246
+ continue
247
+ hasAttribute = true
248
+ Selector = element.getAttribute(name);
249
+ }
250
+
251
+ if (Selector) {
252
+
253
+ let selectors = Selector.split(',');
254
+ for (let j = 0; j < selectors.length; j++) {
255
+ let queriedElement = element
256
+ let specialSelectors = selectors[j].split(';')
257
+ for (let k = 0; k < specialSelectors.length; k++) {
258
+
259
+ // TODO: Support an array of queried elements and branch off to return matches for each
260
+ // if (!Array.isArray(queriedElement)) {
261
+ // queriedElement = [queriedElement]
262
+ // }
263
+ if (k === 0) {
264
+ if (type[i] === 'parent')
265
+ queriedElement = queriedElement.parentElement
266
+ else if (type[i] === 'next')
267
+ queriedElement = queriedElement.nextElementSibling
268
+ else if (type[i] === 'previous')
269
+ queriedElement = queriedElement.previousElementSibling
270
+ }
271
+
272
+ switch (specialSelectors[k] = specialSelectors[k].trim()) {
273
+ case 'top':
274
+ queriedElement = window.top.document
275
+ break;
276
+ case 'frame':
277
+ if (queriedElement.nodeType === 9)
278
+ queriedElement = queriedElement.window.frameElement;
279
+ else if (queriedElement.contentDocument)
280
+ queriedElement = queriedElement.contentDocument;
281
+ break;
282
+ case 'document':
283
+ queriedElement = document
284
+ break;
285
+ case 'parent':
286
+ queriedElement = queriedElement.parentElement
287
+ break;
288
+ case 'next':
289
+ queriedElement = queriedElement.nextElementSibling
290
+ break;
291
+ case 'previous':
292
+ queriedElement = queriedElement.previousElementSibling
293
+ break;
294
+ default:
295
+ if (k === 0 && type[i] === 'closest')
296
+ queriedElement = queriedElement.closest(specialSelectors[k])
297
+ else if (specialSelectors[k].endsWith('[]'))
298
+ queriedElement = queriedElement.querySelectorAll(specialSelectors[k].slice(0, -2))
299
+ else
300
+ queriedElement = queriedElement.querySelector(specialSelectors[k])
301
+ }
302
+ if (!queriedElement)
303
+ break;
304
+ }
305
+
306
+ if (Array.isArray(queriedElement) || queriedElement instanceof HTMLCollection || queriedElement instanceof NodeList) {
307
+ for (let el of queriedElement)
308
+ elements.set(el, '')
309
+ } else if (queriedElement) {
310
+ elements.set(queriedElement, '')
311
+ }
312
+
313
+ }
314
+ } else if (Selector === '') {
315
+ if (type[i] === 'parent')
316
+ elements.set(element.parentElement, '')
317
+ else if (type[i] === 'next')
318
+ elements.set(element.nextElementSibling, '')
319
+ else if (type[i] === 'previous')
320
+ elements.set(element.previousElementSibling, '')
321
+ }
322
+ }
323
+
324
+ if (!hasAttribute && !selector)
325
+ elements = false
326
+ else
327
+ elements = Array.from(elements.keys())
328
+
329
+ return elements
330
+ }
331
+
332
+ function queryData(data, query) {
333
+ if (!data)
334
+ return false;
335
+
336
+ if (!Array.isArray(data))
337
+ data = [data]
338
+
339
+ if (!query)
340
+ return true
341
+
342
+ if (!Array.isArray(query))
343
+ query = [query]
344
+ if (!query.length)
345
+ return true
346
+
347
+ let queryResult = false
348
+ for (let n = 0; n < data.length; n++) {
349
+ for (let i = 0; i < query.length; i++) {
350
+ let dataValue
351
+ if (query[i].key.includes('.') || /\[([0-9]*)\]/g.test(query[i].key))
352
+ dataValue = getValueFromObject(data[n], query[i].key)
353
+ else
354
+ dataValue = data[n][query[i].key]
355
+ if (dataValue == undefined)
356
+ dataValue = ''
357
+ let logicalOperator = query[i].logicalOperator || 'and'
358
+ let queryValues = query[i].value
359
+ if (!Array.isArray(queryValues))
360
+ queryValues = [queryValues]
361
+
362
+ let queryStatus = false
363
+ for (let queryValue of queryValues) {
364
+ if (query[i].caseSensitive != 'true' || query[i].caseSensitive != true) {
365
+ if (typeof dataValue == 'string')
366
+ dataValue = dataValue.toLowerCase()
367
+ if (typeof queryValue == 'string')
368
+ queryValue = queryValue.toLowerCase()
369
+ }
370
+
371
+ switch (query[i].operator) {
372
+ case '$includes':
373
+ case 'includes':
374
+ if (dataValue.includes(queryValue))
375
+ queryStatus = true
376
+ // if (queryValue === "" && logicalOperator === 'and') {
377
+ // if (dataValue !== "")
378
+ // queryStatus = false
379
+ // }
380
+ break;
381
+ case '$eq':
382
+ if (dataValue == queryValue)
383
+ queryStatus = true
384
+ break;
385
+ case '$ne':
386
+ if (dataValue != queryValue)
387
+ queryStatus = true
388
+ break;
389
+ case '$lt':
390
+ if (dataValue > queryValue)
391
+ queryStatus = true
392
+ break;
393
+ case '$lte':
394
+ if (dataValue >= queryValue)
395
+ queryStatus = true
396
+ break;
397
+ case '$gt':
398
+ if (dataValue < queryValue)
399
+ queryStatus = true
400
+ break;
401
+ case '$gte':
402
+ if (dataValue <= queryValue)
403
+ queryStatus = true
404
+ break;
405
+ case '$in':
406
+ if (Array.isArray(dataValue) && dataValue.some(x => queryValue.includes(x)))
407
+ queryStatus = true
408
+ break;
409
+ case '$nin':
410
+ if (!Array.isArray(dataValue) || !dataValue.some(x => queryValue.includes(x)))
411
+ queryStatus = true
412
+ break;
413
+ case '$range':
414
+ if (queryValue[0] !== null && queryValue[1] !== null) {
415
+ if (dataValue >= queryValue[0] && dataValue <= queryValue[1])
416
+ queryStatus = true
417
+ } else if (queryValue[0] == null && dataValue <= queryValue[1]) {
418
+ queryStatus = true
419
+ } else if (queryValue[1] == null && dataValue >= queryValue[0]) {
420
+ queryStatus = true
421
+ }
422
+ break;
423
+
424
+ default:
425
+ if (dataValue.includes(queryValue))
426
+ queryStatus = true
427
+ break;
428
+ }
429
+ if (queryStatus == true) {
430
+ queryResult = true
431
+ break;
432
+ }
433
+
434
+ }
435
+ switch (logicalOperator) {
436
+ case 'and':
437
+ if (queryStatus == false)
438
+ return false
439
+ break;
440
+ }
441
+ // if (logicalOperator == 'and' && queryStatus == false)
442
+ // return false
443
+ }
444
+ }
445
+
446
+ return queryResult;
447
+ }
448
+
449
+ function searchData(data, search) {
450
+ if (!search)
451
+ return true
452
+ if (!Array.isArray(search))
453
+ search = [search]
454
+ for (let i = 0; i < search.length; i++) {
455
+ let searchValue = search[i].value
456
+ if (!Array.isArray(searchValue))
457
+ searchValue = [searchValue]
458
+ for (let key in data) {
459
+ let value = data[key];
460
+ let status = false;
461
+ switch (typeof value) {
462
+ case 'number':
463
+ value = value.toString();
464
+ break;
465
+ case 'object':
466
+ value = JSON.stringify(value)
467
+ break;
468
+ case 'function':
469
+ value = value.toString();
470
+ break;
471
+ }
472
+ if (search[i].caseSensitive != 'true' || search[i].caseSensitive != true)
473
+ value = value.toLowerCase()
474
+
475
+ for (let i = 0; i < searchValue.length; i++) {
476
+ let searchString = searchValue[i]
477
+ if (search[i].caseSensitive != 'true' || search[i].caseSensitive != true)
478
+ searchString = searchString.toLowerCase()
479
+
480
+ if (searchString === "" && search[i].operator === 'and') {
481
+ if (value !== "")
482
+ return false
483
+ }
484
+
485
+ if (value.indexOf(searchString) > -1)
486
+ status = true;
487
+
488
+ if (status)
489
+ return true;
490
+ else if (search[i].operator == 'and')
491
+ return false;
492
+
493
+
494
+ }
495
+ }
496
+ if (search[i].value.length && search[i].operator == 'or')
497
+ return false
498
+
499
+ }
500
+ return true
501
+ }
502
+
503
+ function sortData(data, sort) {
504
+ if (!Array.isArray(sort))
505
+ sort = [sort]
506
+ for (let i = 0; i < sort.length; i++) {
507
+ let key = sort[i].key
508
+ if (key) {
509
+ try {
510
+ data.sort((a, b) => {
511
+ if (sort[i].direction == 'desc') {
512
+ switch (typeof b[key]) {
513
+ case 'string':
514
+ if (!b[key])
515
+ b[key] = ""
516
+ return b[key].localeCompare(a[key])
517
+ case 'number':
518
+ if (!b[key])
519
+ b[key] = 0
520
+ return b[key] - a[key]
521
+ case 'array':
522
+ case 'object':
523
+ break;
524
+ }
525
+ } else {
526
+ switch (typeof a[key]) {
527
+ case 'string':
528
+ if (!a[key])
529
+ a[key] = ""
530
+ return a[key].localeCompare(b[key])
531
+ case 'number':
532
+ if (!a[key])
533
+ a[key] = 0
534
+ return a[key] - b[key]
535
+ case 'array':
536
+ case 'object':
537
+ break;
538
+ }
539
+ }
540
+ });
541
+ } catch (error) {
542
+ console.log(error)
543
+ }
544
+ }
545
+ }
546
+ return data;
547
+ }
548
+
549
+ function getAttributes(el) {
550
+ if (!el) return;
551
+
552
+ let attributes = window.CoCreateConfig.attributes;
553
+ let object = {};
554
+
555
+ for (let attribute of el.attributes) {
556
+ let variable = attributes[attribute.name]
557
+ if (variable) {
558
+ object[variable] = attribute.value
559
+ }
560
+ }
561
+
562
+ return object
563
+ }
564
+
565
+ function getAttributeNames(variables) {
566
+ let reversedObject = {}
567
+ for (const key of Object.keys(CoCreateConfig.attributes)) {
568
+ reversedObject[CoCreateConfig.attributes[key]] = key
569
+ }
570
+
571
+ let attributes = [];
572
+ for (const variable of variables) {
573
+ let attribute = reversedObject[variable]
574
+ if (attribute)
575
+ attributes.push(attribute)
576
+ }
577
+ return attributes
578
+ }
579
+
580
+ function setAttributeNames(attributes, overWrite) {
581
+ let reversedObject = {}
582
+ for (const key of Object.keys(CoCreateConfig.attributes)) {
583
+ reversedObject[CoCreateConfig.attributes[key]] = key
584
+ }
585
+
586
+ for (const attribute of Object.keys(attributes)) {
587
+ const variable = attributes[attribute]
588
+ if (!reversedObject[variable] || overWrite != false)
589
+ reversedObject[variable] = attribute
590
+ }
591
+
592
+ let revertObject = {}
593
+ for (const key of Object.keys(reversedObject)) {
594
+ revertObject[reversedObject[key]] = key
595
+ }
596
+ CoCreateConfig.attributes = revertObject
597
+ }
598
+
599
+ if (isBrowser)
600
+ clickedElement();
601
+
602
+ return {
603
+ ObjectId,
604
+ checkValue,
605
+ dotNotationToObject,
606
+ getValueFromObject,
607
+ isObjectEmpty,
608
+ domParser,
609
+ parseTextToHtml,
610
+ escapeHtml,
611
+ cssPath,
612
+ queryElements,
613
+ queryData,
614
+ searchData,
615
+ sortData,
616
+ getAttributes,
617
+ setAttributeNames,
618
+ getAttributeNames
619
+ }
620
+
621
+ }));