@myissue/vue-website-page-builder 3.2.93 → 3.2.95
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/README.md +1 -1
- package/dist/vue-website-page-builder.js +3756 -3752
- package/dist/vue-website-page-builder.umd.cjs +36 -36
- package/package.json +1 -1
- package/src/DemoComponents/HomeSection.vue +6 -1
- package/src/PageBuilder/PageBuilder.vue +7 -2
- package/src/composables/PageBuilderService.ts +88 -39
- package/src/composables/builderInstance.ts +1 -1
- package/src/types/index.ts +1 -1
package/package.json
CHANGED
|
@@ -83,7 +83,12 @@ const configPageBuilder = {
|
|
|
83
83
|
|
|
84
84
|
onMounted(async () => {
|
|
85
85
|
await pageBuilderService.startBuilder(configPageBuilder)
|
|
86
|
-
|
|
86
|
+
//
|
|
87
|
+
//
|
|
88
|
+
//
|
|
89
|
+
// await pageBuilderService.mountComponentsToDOM(JSON.stringify(html))
|
|
90
|
+
// await pageBuilderService.mountComponentsToDOM(JSON.stringify(oldhtmlfromdb))
|
|
91
|
+
await pageBuilderService.mountComponentsToDOM(rawHTML)
|
|
87
92
|
})
|
|
88
93
|
</script>
|
|
89
94
|
|
|
@@ -263,12 +263,17 @@ const ensureBuilderInitialized = function () {
|
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
onMounted(async () => {
|
|
266
|
+
// Try to mount any pending data if #pagebuilder is now present
|
|
267
|
+
if (pageBuilderService.statuspendingMountData()) {
|
|
268
|
+
await pageBuilderService.tryMountPendingData()
|
|
269
|
+
}
|
|
270
|
+
|
|
266
271
|
// Check if Builder started
|
|
267
|
-
await delay(
|
|
272
|
+
await delay(6000)
|
|
268
273
|
ensureBuilderInitialized()
|
|
269
274
|
|
|
270
275
|
// Re-check if Builder started
|
|
271
|
-
await delay(
|
|
276
|
+
await delay(6000)
|
|
272
277
|
ensureBuilderInitialized()
|
|
273
278
|
})
|
|
274
279
|
</script>
|
|
@@ -36,7 +36,10 @@ export class PageBuilderService {
|
|
|
36
36
|
private NoneListernesTags: string[]
|
|
37
37
|
private delay: (ms?: number) => Promise<void>
|
|
38
38
|
private hasStartedEditing: boolean = false
|
|
39
|
+
// Hold data from Database or Backend for updated post
|
|
39
40
|
private originalComponents: string | null = null
|
|
41
|
+
// Holds data to be mounted when #pagebuilder is not yet present in the DOM
|
|
42
|
+
private pendingMountData: string | null = null
|
|
40
43
|
|
|
41
44
|
constructor(pageBuilderStateStore: ReturnType<typeof usePageBuilderStateStore>) {
|
|
42
45
|
this.nextTick = nextTick()
|
|
@@ -90,7 +93,7 @@ export class PageBuilderService {
|
|
|
90
93
|
this.delay = delay
|
|
91
94
|
}
|
|
92
95
|
|
|
93
|
-
//
|
|
96
|
+
// Deselect any selected or hovered elements in the builder UI
|
|
94
97
|
async clearHtmlSelection(): Promise<void> {
|
|
95
98
|
this.pageBuilderStateStore.setComponent(null)
|
|
96
99
|
this.pageBuilderStateStore.setElement(null)
|
|
@@ -219,11 +222,12 @@ export class PageBuilderService {
|
|
|
219
222
|
// Clean up any old localStorage items related to previous builder sessions
|
|
220
223
|
this.deleteOldPageBuilderLocalStorage()
|
|
221
224
|
|
|
222
|
-
//
|
|
225
|
+
// Deselect any selected or hovered elements in the builder UI
|
|
223
226
|
await this.clearHtmlSelection()
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
+
// Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
|
|
228
|
+
await nextTick()
|
|
229
|
+
// Attach event listeners to all editable elements in the Builder
|
|
230
|
+
await this.#addListenersToEditableElements()
|
|
227
231
|
|
|
228
232
|
// Hide the global loading indicator and mark the builder as started
|
|
229
233
|
this.pageBuilderStateStore.setIsLoadingGlobal(false)
|
|
@@ -366,16 +370,14 @@ export class PageBuilderService {
|
|
|
366
370
|
* The function is used to
|
|
367
371
|
* attach event listeners to each element within a 'section'
|
|
368
372
|
*/
|
|
369
|
-
addListenersToEditableElements = async () => {
|
|
373
|
+
#addListenersToEditableElements = async () => {
|
|
370
374
|
const elementsWithListeners = new WeakSet<Element>()
|
|
371
375
|
|
|
372
376
|
const pagebuilder = document.querySelector('#pagebuilder')
|
|
373
|
-
|
|
374
377
|
if (!pagebuilder) return
|
|
375
378
|
|
|
376
|
-
// Wait for
|
|
379
|
+
// Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
|
|
377
380
|
await nextTick()
|
|
378
|
-
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
379
381
|
|
|
380
382
|
pagebuilder.querySelectorAll('section *').forEach((element) => {
|
|
381
383
|
// exclude NoneListernesTags && additional Tags for not listening
|
|
@@ -538,10 +540,7 @@ export class PageBuilderService {
|
|
|
538
540
|
}
|
|
539
541
|
|
|
540
542
|
async #removeHoveredAndSelected() {
|
|
541
|
-
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
542
|
-
|
|
543
543
|
const pagebuilder = document.querySelector('#pagebuilder')
|
|
544
|
-
|
|
545
544
|
if (!pagebuilder) return
|
|
546
545
|
|
|
547
546
|
const hoveredElement = pagebuilder.querySelector('[hovered]')
|
|
@@ -557,8 +556,6 @@ export class PageBuilderService {
|
|
|
557
556
|
}
|
|
558
557
|
|
|
559
558
|
async #syncCurrentClasses() {
|
|
560
|
-
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
561
|
-
|
|
562
559
|
// convert classList to array
|
|
563
560
|
const classListArray = Array.from(this.getElement.value?.classList || [])
|
|
564
561
|
|
|
@@ -653,7 +650,10 @@ export class PageBuilderService {
|
|
|
653
650
|
this.pageBuilderStateStore.setComponent(null)
|
|
654
651
|
this.pageBuilderStateStore.setElement(null)
|
|
655
652
|
|
|
656
|
-
|
|
653
|
+
// Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
|
|
654
|
+
await nextTick()
|
|
655
|
+
// Attach event listeners to all editable elements in the Builder
|
|
656
|
+
await this.#addListenersToEditableElements()
|
|
657
657
|
}
|
|
658
658
|
|
|
659
659
|
handleFontWeight(userSelectedFontWeight?: string): void {
|
|
@@ -836,8 +836,11 @@ export class PageBuilderService {
|
|
|
836
836
|
// Remove the component from the array
|
|
837
837
|
this.getComponents.value.splice(indexToDelete, 1)
|
|
838
838
|
this.pageBuilderStateStore.setComponents(this.getComponents.value)
|
|
839
|
+
|
|
840
|
+
// Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
|
|
839
841
|
await nextTick()
|
|
840
|
-
|
|
842
|
+
// Attach event listeners to all editable elements in the Builder
|
|
843
|
+
await this.#addListenersToEditableElements()
|
|
841
844
|
|
|
842
845
|
this.pageBuilderStateStore.setComponent(null)
|
|
843
846
|
this.pageBuilderStateStore.setElement(null)
|
|
@@ -963,7 +966,6 @@ export class PageBuilderService {
|
|
|
963
966
|
this.pageBuilderStateStore.setElement(null)
|
|
964
967
|
|
|
965
968
|
const pagebuilder = document.querySelector('#pagebuilder')
|
|
966
|
-
|
|
967
969
|
if (!pagebuilder) return
|
|
968
970
|
|
|
969
971
|
const addedHtmlComponents = ref<string[]>([])
|
|
@@ -1341,8 +1343,10 @@ export class PageBuilderService {
|
|
|
1341
1343
|
this.mountComponentsToDOM(this.originalComponents)
|
|
1342
1344
|
}
|
|
1343
1345
|
|
|
1346
|
+
// Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
|
|
1344
1347
|
await nextTick()
|
|
1345
|
-
|
|
1348
|
+
// Attach event listeners to all editable elements in the Builder
|
|
1349
|
+
await this.#addListenersToEditableElements()
|
|
1346
1350
|
|
|
1347
1351
|
this.pageBuilderStateStore.setIsRestoring(false)
|
|
1348
1352
|
}
|
|
@@ -1604,9 +1608,11 @@ export class PageBuilderService {
|
|
|
1604
1608
|
componentArrayAddMethod: this.getComponentArrayAddMethod.value || 'push',
|
|
1605
1609
|
})
|
|
1606
1610
|
|
|
1607
|
-
// Wait for
|
|
1611
|
+
// Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
|
|
1608
1612
|
await nextTick()
|
|
1609
|
-
|
|
1613
|
+
// Attach event listeners to all editable elements in the Builder
|
|
1614
|
+
await this.#addListenersToEditableElements()
|
|
1615
|
+
|
|
1610
1616
|
await this.handleAutoSave()
|
|
1611
1617
|
} catch (error) {
|
|
1612
1618
|
console.error('Error adding component:', error)
|
|
@@ -1644,18 +1650,18 @@ export class PageBuilderService {
|
|
|
1644
1650
|
* @param data - JSON string (e.g., '[{"html_code":"...","id":"123","title":"..."}]')
|
|
1645
1651
|
* OR HTML string (e.g., '<section data-componentid="123">...</section>')
|
|
1646
1652
|
*/
|
|
1647
|
-
#setComponentsFromData(htmlString: string): void {
|
|
1653
|
+
async #setComponentsFromData(htmlString: string): Promise<void> {
|
|
1648
1654
|
// Auto-detect if input is JSON or HTML
|
|
1649
1655
|
const trimmedData = htmlString.trim()
|
|
1650
1656
|
|
|
1651
1657
|
if (trimmedData.startsWith('[') || trimmedData.startsWith('{')) {
|
|
1652
1658
|
// Looks like JSON - parse as JSON
|
|
1653
|
-
this.#parseJSONComponents(trimmedData)
|
|
1659
|
+
await this.#parseJSONComponents(trimmedData)
|
|
1654
1660
|
} else if (trimmedData.startsWith('<')) {
|
|
1655
1661
|
// Looks like HTML - parse as HTML
|
|
1656
|
-
this.#parseHTMLComponents(trimmedData)
|
|
1662
|
+
await this.#parseHTMLComponents(trimmedData)
|
|
1657
1663
|
} else {
|
|
1658
|
-
this.#parseJSONComponents(trimmedData)
|
|
1664
|
+
await this.#parseJSONComponents(trimmedData)
|
|
1659
1665
|
}
|
|
1660
1666
|
}
|
|
1661
1667
|
|
|
@@ -1712,15 +1718,17 @@ export class PageBuilderService {
|
|
|
1712
1718
|
|
|
1713
1719
|
this.pageBuilderStateStore.setComponents(savedCurrentDesign)
|
|
1714
1720
|
|
|
1715
|
-
|
|
1716
|
-
await
|
|
1721
|
+
// Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
|
|
1722
|
+
await nextTick()
|
|
1723
|
+
// Attach event listeners to all editable elements in the Builder
|
|
1724
|
+
await this.#addListenersToEditableElements()
|
|
1717
1725
|
} catch (error) {
|
|
1718
1726
|
console.error('Error parsing JSON components:', error)
|
|
1719
1727
|
this.pageBuilderStateStore.setComponents([])
|
|
1720
1728
|
}
|
|
1721
1729
|
}
|
|
1722
1730
|
// Private method to parse HTML components
|
|
1723
|
-
#parseHTMLComponents(htmlData: string): void {
|
|
1731
|
+
async #parseHTMLComponents(htmlData: string): Promise<void> {
|
|
1724
1732
|
try {
|
|
1725
1733
|
const parser = new DOMParser()
|
|
1726
1734
|
const doc = parser.parseFromString(htmlData, 'text/html')
|
|
@@ -1730,6 +1738,14 @@ export class PageBuilderService {
|
|
|
1730
1738
|
|
|
1731
1739
|
const extractedSections: ComponentObject[] = []
|
|
1732
1740
|
sectionElements.forEach((section) => {
|
|
1741
|
+
// Process all elements inside section to add prefix to classes
|
|
1742
|
+
section.querySelectorAll('[class]').forEach((el) => {
|
|
1743
|
+
el.setAttribute(
|
|
1744
|
+
'class',
|
|
1745
|
+
this.#addTailwindPrefixToClasses(el.getAttribute('class') || '', 'pbx-'),
|
|
1746
|
+
)
|
|
1747
|
+
})
|
|
1748
|
+
|
|
1733
1749
|
const htmlElement = section as HTMLElement
|
|
1734
1750
|
|
|
1735
1751
|
// Ensure data-componentid exists
|
|
@@ -1754,6 +1770,13 @@ export class PageBuilderService {
|
|
|
1754
1770
|
})
|
|
1755
1771
|
|
|
1756
1772
|
this.pageBuilderStateStore.setComponents(extractedSections)
|
|
1773
|
+
|
|
1774
|
+
// Deselect any selected or hovered elements in the builder UI
|
|
1775
|
+
await this.clearHtmlSelection()
|
|
1776
|
+
// Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
|
|
1777
|
+
await nextTick()
|
|
1778
|
+
// Attach event listeners to all editable elements in the Builder
|
|
1779
|
+
await this.#addListenersToEditableElements()
|
|
1757
1780
|
} catch (error) {
|
|
1758
1781
|
console.error('Error parsing HTML components:', error)
|
|
1759
1782
|
this.pageBuilderStateStore.setComponents([])
|
|
@@ -1765,9 +1788,21 @@ export class PageBuilderService {
|
|
|
1765
1788
|
* @param passedData - HTML/JSON string to inject (optional)
|
|
1766
1789
|
* @param preferLocalStorage - if true, always try localStorage first
|
|
1767
1790
|
*/
|
|
1768
|
-
mountComponentsToDOM(passedData: string): void {
|
|
1769
|
-
|
|
1770
|
-
|
|
1791
|
+
async mountComponentsToDOM(passedData: string): Promise<void> {
|
|
1792
|
+
const pagebuilder = document.querySelector('#pagebuilder')
|
|
1793
|
+
|
|
1794
|
+
// If #pagebuilder is not present, cache the data and exit
|
|
1795
|
+
if (!pagebuilder) {
|
|
1796
|
+
this.pendingMountData = passedData
|
|
1797
|
+
return
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
// Clear the cache if we are mounting now
|
|
1801
|
+
this.pendingMountData = null
|
|
1802
|
+
|
|
1803
|
+
this.pageBuilderStateStore.setComponents([])
|
|
1804
|
+
|
|
1805
|
+
// On from type update Save Original Post
|
|
1771
1806
|
if (
|
|
1772
1807
|
this.pageBuilderStateStore.getPageBuilderConfig &&
|
|
1773
1808
|
this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate &&
|
|
@@ -1779,10 +1814,6 @@ export class PageBuilderService {
|
|
|
1779
1814
|
this.originalComponents = passedData
|
|
1780
1815
|
}
|
|
1781
1816
|
|
|
1782
|
-
this.pageBuilderStateStore.setComponents([])
|
|
1783
|
-
|
|
1784
|
-
if (!this.pageBuilderStateStore.getPageBuilderConfig) return
|
|
1785
|
-
|
|
1786
1817
|
// Form type Update
|
|
1787
1818
|
if (
|
|
1788
1819
|
this.pageBuilderStateStore.getPageBuilderConfig &&
|
|
@@ -1791,7 +1822,7 @@ export class PageBuilderService {
|
|
|
1791
1822
|
this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType === 'update'
|
|
1792
1823
|
) {
|
|
1793
1824
|
if (passedData) {
|
|
1794
|
-
this.#setComponentsFromData(passedData)
|
|
1825
|
+
await this.#setComponentsFromData(passedData)
|
|
1795
1826
|
return
|
|
1796
1827
|
}
|
|
1797
1828
|
}
|
|
@@ -1806,29 +1837,47 @@ export class PageBuilderService {
|
|
|
1806
1837
|
this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType === 'create'
|
|
1807
1838
|
) {
|
|
1808
1839
|
if (localStorageData) {
|
|
1809
|
-
this.#setComponentsFromData(localStorageData)
|
|
1840
|
+
await this.#setComponentsFromData(localStorageData)
|
|
1810
1841
|
return
|
|
1811
1842
|
}
|
|
1812
1843
|
|
|
1813
1844
|
// If no localStorage, but passedData exists (for demo), use it
|
|
1814
1845
|
if (passedData) {
|
|
1815
|
-
this.#setComponentsFromData(passedData)
|
|
1846
|
+
await this.#setComponentsFromData(passedData)
|
|
1816
1847
|
return
|
|
1817
1848
|
}
|
|
1818
1849
|
}
|
|
1819
1850
|
}
|
|
1820
1851
|
|
|
1852
|
+
statuspendingMountData(): string | null {
|
|
1853
|
+
return this.pendingMountData
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
// Try re-mounting
|
|
1857
|
+
async tryMountPendingData() {
|
|
1858
|
+
if (this.pendingMountData && document.querySelector('#pagebuilder')) {
|
|
1859
|
+
await this.mountComponentsToDOM(this.pendingMountData)
|
|
1860
|
+
this.pendingMountData = null
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1821
1864
|
async toggleTipTapModal(status: boolean): Promise<void> {
|
|
1822
1865
|
this.pageBuilderStateStore.setShowModalTipTap(status)
|
|
1823
1866
|
|
|
1867
|
+
// Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
|
|
1868
|
+
await nextTick()
|
|
1869
|
+
// Attach event listeners to all editable elements in the Builder
|
|
1870
|
+
await this.#addListenersToEditableElements()
|
|
1871
|
+
|
|
1824
1872
|
if (!status) {
|
|
1825
1873
|
await this.handleAutoSave()
|
|
1826
1874
|
}
|
|
1827
1875
|
}
|
|
1828
1876
|
|
|
1829
1877
|
async initializeElementStyles(): Promise<void> {
|
|
1830
|
-
|
|
1831
|
-
|
|
1878
|
+
// Wait for Vue to finish DOM updates before attaching event listeners.
|
|
1879
|
+
// This ensure elements exist in the DOM.
|
|
1880
|
+
await nextTick()
|
|
1832
1881
|
|
|
1833
1882
|
// handle custom URL
|
|
1834
1883
|
this.handleHyperlink(undefined, null, false)
|
|
@@ -18,7 +18,7 @@ export function initPageBuilder(): PageBuilderService {
|
|
|
18
18
|
export function getPageBuilder(): PageBuilderService {
|
|
19
19
|
if (!instance) {
|
|
20
20
|
throw new Error(
|
|
21
|
-
'PageBuilderService has not been created. Please call
|
|
21
|
+
'PageBuilderService has not been created. Please call initPageBuilder() first in your App.vue or setup file.',
|
|
22
22
|
)
|
|
23
23
|
}
|
|
24
24
|
return instance
|
package/src/types/index.ts
CHANGED