Skip to content

Commit 1dc9b4d

Browse files
committed
feat: Add support for rendering elements using different selectors
- Added support for rendering elements using different selectors by introducing the `getElement` function. - Extended the `render` function to use the `getElement` function when no specific elements are provided. - Updated the `init` function to use the `elementSelector` variable for querying elements if no specific elements are provided. - Modified the `render` function to handle elements passed as HTMLCollection or NodeList to ensure compatibility. - Refactored the code to improve clarity and organization. - Updated the observer callbacks to utilize the `render` function for rendering elements. - Removed unnecessary code related to deleted nodes.
1 parent df4c810 commit 1dc9b4d

File tree

1 file changed

+77
-46
lines changed

1 file changed

+77
-46
lines changed

src/index.js

Lines changed: 77 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,69 @@
22
import Actions from '@cocreate/actions';
33
import Observer from '@cocreate/observer';
44
import uuid from '@cocreate/uuid';
5-
import { queryDocumentSelector, queryDocumentSelectorAll, getValueFromObject, dotNotationToObject } from '@cocreate/utils';
5+
import { queryDocumentSelector, queryDocumentSelectorAll, getValueFromObject, dotNotationToObject, ObjectId } from '@cocreate/utils';
66
import '@cocreate/element-prototype';
77
import './index.css';
88

99
const sources = new Map()
1010
const renderedNodes = new Map()
1111
const deletedNodes = new Map()
12+
const elementSelector = '[render-selector], [render-closest], [render-parent], [render-next], [render-previous]'
1213

1314
function init(element) {
1415
if (element && !(element instanceof HTMLCollection) && !Array.isArray(element))
1516
element = [element]
1617
else if (!element)
17-
element = document.querySelectorAll('[render-selector]')
18+
element = document.querySelectorAll(elementSelector)
1819

1920
for (let i = 0; i < element.length; i++) {
20-
let selector = element[i].getAttribute('render-selector')
21-
if (!selector) return
22-
2321
let source = sources.get(element[i])
24-
if (!source || source && source.selector !== selector) {
25-
sources.set(element[i], { element: element[i], selector })
22+
if (!source) {
23+
sources.set(element[i], { element: element[i] })
2624
element[i].setValue = (data) => render({ source: element[i], data })
2725
element[i].getValue = () => sources.get(element[i]).data
2826
}
2927
}
3028
}
3129

30+
function getElement(element, prefix = 'render') {
31+
let elements = [];
32+
33+
let selectors = ['selector', 'closest', 'parent', 'next', 'previous']
34+
for (let i = 0; i < selectors.length; i++) {
35+
let name = prefix + '-' + selectors[i]
36+
const selector = element.getAttribute(name);
37+
if (selector) {
38+
if (selectors[i] === 'selector')
39+
elements = document.querySelectorAll(selector)
40+
else if (selectors[i] === 'closest')
41+
elements = element.closest(selector)
42+
else if (selectors[i] === 'parent')
43+
elements = element.parentElement.querySelectorAll(selector)
44+
else if (selectors[i] === 'next')
45+
elements = element.nextElementSibling.querySelectorAll(selector)
46+
else if (selectors[i] === 'previous')
47+
elements = element.previousElementSibling.querySelectorAll(selector)
48+
} else if (selector === '') {
49+
if (selectors[i] === 'parent')
50+
elements = element.parentElement
51+
else if (selectors[i] === 'next')
52+
elements = element.nextElementSibling
53+
else if (selectors[i] === 'previous')
54+
elements = element.previousElementSibling
55+
}
56+
}
57+
58+
return elements
59+
}
60+
3261
function renderTemplate(template, data, key, index, keyPath) {
3362
if (!key)
3463
key = template.getAttribute('render')
3564

3665
let templateData = renderedNodes.get(template)
3766
if (!templateData) {
38-
templateData = { element: template, clones: new Map(), data, renderKeys: new Map() }
67+
templateData = { element: template, clones: new Map() }
3968
renderedNodes.set(template, templateData)
4069
}
4170

@@ -63,13 +92,15 @@ function renderTemplate(template, data, key, index, keyPath) {
6392
element.remove()
6493
template.clones.delete(key)
6594
}
66-
template.data = data
67-
} else if (index) {
68-
// updates data that has already been rendered
69-
template.data = dotNotationToObject(renderData, template.data)
95+
// template.data = renderData
7096
}
97+
// else if (index) {
98+
// updates data that has already been rendered
99+
// template.data = dotNotationToObject(renderData, template.data)
100+
// }
71101

72102
let renderAs = template.element.getAttribute('render-as') || key;
103+
template.renderAs = renderAs
73104

74105
if (key && !Array.isArray(renderData)) {
75106
let exclude = template.element.getAttribute('render-exclude') || ''
@@ -95,9 +126,15 @@ function renderTemplate(template, data, key, index, keyPath) {
95126
let Data = { [renderAs]: { key: keys[i], value, type } }
96127

97128
let clone = cloneTemplate(template);
98-
// TODO: clone.parentKey
99-
clone.keyPath = template.keyPath + '.' + renderAs
100-
clone.element.setAttribute('renderedKey', Data[renderAs].key)
129+
let renderedKey = key.split('.')
130+
renderedKey = renderedKey[renderedKey.length - 1];
131+
//renderedKey needs to remove the parent.renderAs/key
132+
133+
clone.key = keys[i]
134+
clone.keyPath = template.keyPath + '.' + renderedKey
135+
clone.parentKey = renderedKey
136+
clone.renderKey = key
137+
clone.element.setAttribute('renderedKey', keys[i])
101138
renderValues(clone.element, Data, keys[i], renderAs);
102139
insertElement(template, clone.element, index);
103140

@@ -401,8 +438,14 @@ function getRenderValue(node, data, key, renderAs) {
401438
do {
402439
if (key.includes('keyPath'))
403440
value = parentNode.keyPath || parent.keyPath
404-
// else if (key.includes('parentKey'))
405-
// value = parentNode.parentKey || parent.parentKey
441+
else if (key.includes('parentKey')) {
442+
value = parentNode.parentKey || parent.parentKey || parent.parent.parentKey
443+
} else if (key.includes('renderAs')) {
444+
value = renderAs
445+
} else if (key === 'document_id' || key === '_id')
446+
value = ObjectId()
447+
else if (key === 'uuid')
448+
value = uuid.generate(6)
406449
else if (parent.source)
407450
Data = parent.source.data
408451
else if (parent.parent)
@@ -412,7 +455,6 @@ function getRenderValue(node, data, key, renderAs) {
412455
else
413456
parent = undefined
414457

415-
416458
if (!Data && parent && parent.eid)
417459
eid = parent.eid
418460

@@ -463,21 +505,21 @@ function getRenderValue(node, data, key, renderAs) {
463505
// render({ source, selector, element, data, key, index, update, remove })
464506
// }
465507

466-
function render({ source, selector, element, data, key, index, currentIndex, update, remove }) {
508+
function render({ source, element, data, key, index, currentIndex, update, remove }) {
467509
if (!element) {
468-
if (!selector && source)
469-
selector = source.getAttribute('render-selector')
470-
if (selector)
471-
element = queryDocumentSelectorAll(selector);
472-
if (!element && source)
473-
element = source.querySelector('template, [template], .template', '[render]')
510+
if (source) {
511+
element = getElement(source)
512+
if (!element)
513+
element = source.querySelector('template, [template], .template', '[render]')
514+
}
515+
474516
if (!element) return;
475517
}
476518

477519
if (source) {
478520
let sourceData = sources.get(source)
479521
if (!sourceData) {
480-
sourceData = { element: source, selector, data }
522+
sourceData = { element: source, data }
481523
sources.set(source, sourceData)
482524
}
483525

@@ -493,7 +535,7 @@ function render({ source, selector, element, data, key, index, currentIndex, upd
493535
remove = remove || data.filter.remove
494536
}
495537

496-
if (!(element instanceof HTMLCollection) && !Array.isArray(element))
538+
if (!Array.isArray(element) && !(element instanceof HTMLCollection) && !(element instanceof NodeList))
497539
element = [element]
498540

499541
for (let i = 0; i < element.length; i++) {
@@ -503,7 +545,7 @@ function render({ source, selector, element, data, key, index, currentIndex, upd
503545
let renderedNode = renderedNodes.get(element[i])
504546
if (source) {
505547
if (!renderedNode) {
506-
renderedNode = { element: element[i], source, clones: new Map(), renderAss: new Map() }
548+
renderedNode = { element: element[i], source, clones: new Map(), renderAs: new Map() }
507549
renderedNodes.set(element[i], renderedNode)
508550
}
509551
}
@@ -594,7 +636,7 @@ Actions.init({
594636
Observer.init({
595637
name: 'render',
596638
observe: ['addedNodes'],
597-
target: '[render-selector]',
639+
target: elementSelector,
598640
callback: function (mutation) {
599641
init(mutation.target)
600642
}
@@ -605,15 +647,10 @@ Observer.init({
605647
observe: ['addedNodes'],
606648
target: '[render-clone]',
607649
callback: function (mutation) {
608-
let deletedNode = deletedNodes.get(mutation.target)
609-
if (deletedNode) {
610-
clearTimeout(deletedNode.delayTimer);
611-
deletedNodes.delete(mutation.target)
612-
}
650+
let renderedNode = renderedNodes.get(mutation.target)
651+
if (!renderedNode) return
613652

614-
// let renderedNode = mutation.target.renderedNode
615-
// if (renderedNode) return
616-
// delete mutation.target.renderedNode
653+
// render({ source, element, data, key, index, currentIndex, update, remove })
617654

618655
// let nextElement = mutation.target.nextElementSibling
619656
// if (!nextElement) return
@@ -643,17 +680,11 @@ Observer.init({
643680
observe: ['removedNodes'],
644681
target: '[render-clone]',
645682
callback: function (mutation) {
683+
if (mutation.target.parentElement) return
646684
let renderedNode = renderedNodes.get(mutation.target)
647685
if (!renderedNode) return
648-
649-
mutation.target.renderedNode = renderedNode
650-
let delayTimer = setTimeout(function () {
651-
deletedNodes.delete(mutation.target)
652-
renderedNode.template.clones.delete(renderedNode.eid)
653-
renderedNodes.delete(mutation.target)
654-
}, 1000);
655-
656-
deletedNodes.set(mutation.target, { renderedNode, delayTimer })
686+
renderedNode.template.clones.delete(renderedNode.eid)
687+
renderedNodes.delete(mutation.target)
657688
}
658689
})
659690

0 commit comments

Comments
 (0)