@myissue/vue-website-page-builder 3.2.96 → 3.3.1
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 +97 -355
- package/dist/vue-website-page-builder.js +1628 -1612
- package/dist/vue-website-page-builder.umd.cjs +31 -31
- package/package.json +1 -1
- package/src/DemoComponents/HomeSection.vue +2 -5
- package/src/PageBuilder/PageBuilder.vue +2 -5
- package/src/composables/PageBuilderService.ts +54 -15
package/package.json
CHANGED
|
@@ -83,12 +83,9 @@ const configPageBuilder = {
|
|
|
83
83
|
|
|
84
84
|
onMounted(async () => {
|
|
85
85
|
await pageBuilderService.startBuilder(configPageBuilder)
|
|
86
|
-
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
// await pageBuilderService.mountComponentsToDOM(JSON.stringify(html))
|
|
86
|
+
await pageBuilderService.mountComponentsToDOM(JSON.stringify(html))
|
|
90
87
|
// await pageBuilderService.mountComponentsToDOM(JSON.stringify(oldhtmlfromdb))
|
|
91
|
-
await pageBuilderService.mountComponentsToDOM(rawHTML)
|
|
88
|
+
// await pageBuilderService.mountComponentsToDOM(rawHTML)
|
|
92
89
|
})
|
|
93
90
|
</script>
|
|
94
91
|
|
|
@@ -169,9 +169,6 @@ const getIsSaving = computed(() => {
|
|
|
169
169
|
})
|
|
170
170
|
|
|
171
171
|
const getIsLoadingResumeEditing = computed(() => {
|
|
172
|
-
if (pageBuilderStateStore.getIsLoadingResumeEditing) {
|
|
173
|
-
handlerRumeEditingForUpdate()
|
|
174
|
-
}
|
|
175
172
|
return pageBuilderStateStore.getIsLoadingResumeEditing
|
|
176
173
|
})
|
|
177
174
|
const getIsRestoring = computed(() => {
|
|
@@ -269,11 +266,11 @@ onMounted(async () => {
|
|
|
269
266
|
}
|
|
270
267
|
|
|
271
268
|
// Check if Builder started
|
|
272
|
-
await delay(
|
|
269
|
+
await delay(10000)
|
|
273
270
|
ensureBuilderInitialized()
|
|
274
271
|
|
|
275
272
|
// Re-check if Builder started
|
|
276
|
-
await delay(
|
|
273
|
+
await delay(10000)
|
|
277
274
|
ensureBuilderInitialized()
|
|
278
275
|
})
|
|
279
276
|
</script>
|
|
@@ -195,10 +195,20 @@ export class PageBuilderService {
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
/**
|
|
198
|
-
*
|
|
199
|
-
*
|
|
198
|
+
* - Entry point for initializing the Page Builder.
|
|
199
|
+
* - Sets the builder as started in the state store.
|
|
200
|
+
* - Shows a global loading indicator.
|
|
201
|
+
* - Stores and validates the provided configuration.
|
|
202
|
+
* - Updates the localStorage key name based on the config/resource.
|
|
203
|
+
* - Completes builder initialization if the DOM is ready.
|
|
204
|
+
*
|
|
205
|
+
* @param config - The configuration object for the Page Builder.
|
|
200
206
|
*/
|
|
201
207
|
async startBuilder(config: PageBuilderConfig): Promise<void> {
|
|
208
|
+
// Reactive flag signals to the UI that the builder has been successfully initialized
|
|
209
|
+
// Prevents builder actions to prevent errors caused by missing DOM .
|
|
210
|
+
this.pageBuilderStateStore.setBuilderStarted(true)
|
|
211
|
+
|
|
202
212
|
// Show a global loading indicator while initializing
|
|
203
213
|
this.pageBuilderStateStore.setIsLoadingGlobal(true)
|
|
204
214
|
|
|
@@ -213,25 +223,30 @@ export class PageBuilderService {
|
|
|
213
223
|
// Update the localStorage key name based on the config/resource
|
|
214
224
|
this.#updateLocalStorageItemName()
|
|
215
225
|
|
|
216
|
-
this
|
|
226
|
+
this.completeBuilderInitialization()
|
|
217
227
|
}
|
|
218
228
|
|
|
219
|
-
async
|
|
220
|
-
this.pageBuilderStateStore.setIsLoadingGlobal(true)
|
|
221
|
-
|
|
229
|
+
async completeBuilderInitialization() {
|
|
222
230
|
const pagebuilder = document.querySelector('#pagebuilder')
|
|
223
231
|
if (!pagebuilder) return
|
|
224
232
|
|
|
233
|
+
// Deselect any selected or hovered elements in the builder UI
|
|
234
|
+
await this.clearHtmlSelection()
|
|
235
|
+
this.pageBuilderStateStore.setIsLoadingGlobal(true)
|
|
225
236
|
await this.delay(300)
|
|
226
237
|
|
|
227
238
|
// Hide the global loading indicator and mark the builder as started
|
|
228
239
|
this.pageBuilderStateStore.setIsLoadingGlobal(false)
|
|
229
|
-
this.pageBuilderStateStore.setBuilderStarted(true)
|
|
230
240
|
|
|
231
|
-
// If there is a local draft for this resource, mark it in the state
|
|
232
241
|
if (await this.hasLocalDraftForUpdate()) {
|
|
233
242
|
this.pageBuilderStateStore.setHasLocalDraftForUpdate(true)
|
|
234
243
|
}
|
|
244
|
+
|
|
245
|
+
// Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
|
|
246
|
+
await nextTick()
|
|
247
|
+
// Attach event listeners to all editable elements in the Builder
|
|
248
|
+
await this.#addListenersToEditableElements()
|
|
249
|
+
|
|
235
250
|
// Clean up any old localStorage items related to previous builder sessions
|
|
236
251
|
this.deleteOldPageBuilderLocalStorage()
|
|
237
252
|
}
|
|
@@ -415,6 +430,8 @@ export class PageBuilderService {
|
|
|
415
430
|
|
|
416
431
|
try {
|
|
417
432
|
this.pageBuilderStateStore.setIsSaving(true)
|
|
433
|
+
// Deselect any selected or hovered elements in the builder UI
|
|
434
|
+
//
|
|
418
435
|
await this.saveComponentsLocalStorage()
|
|
419
436
|
await this.delay(500)
|
|
420
437
|
} catch (err) {
|
|
@@ -1163,7 +1180,26 @@ export class PageBuilderService {
|
|
|
1163
1180
|
}
|
|
1164
1181
|
|
|
1165
1182
|
/**
|
|
1166
|
-
*
|
|
1183
|
+
* Returns a clone of the given element with [hovered] and [selected] attributes
|
|
1184
|
+
* removed from itself and all descendants. Does NOT mutate the live DOM.
|
|
1185
|
+
* @param element The HTMLElement to clone and sanitize
|
|
1186
|
+
*/
|
|
1187
|
+
#cloneAndRemoveSelectionAttributes(element: HTMLElement): HTMLElement {
|
|
1188
|
+
// Deep clone the element
|
|
1189
|
+
const clone = element.cloneNode(true) as HTMLElement
|
|
1190
|
+
|
|
1191
|
+
// Remove [hovered] and [selected] from the clone and all descendants
|
|
1192
|
+
clone.querySelectorAll('[hovered]').forEach((el) => el.removeAttribute('hovered'))
|
|
1193
|
+
clone.querySelectorAll('[selected]').forEach((el) => el.removeAttribute('selected'))
|
|
1194
|
+
// Also remove from the root element itself if present
|
|
1195
|
+
clone.removeAttribute('hovered')
|
|
1196
|
+
clone.removeAttribute('selected')
|
|
1197
|
+
|
|
1198
|
+
return clone
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
/**
|
|
1202
|
+
* Components from DOM → JS (not JS → DOM). øøø
|
|
1167
1203
|
* Saving the current DOM state into JS this.getComponents (for example, before saving to localStorage).
|
|
1168
1204
|
* This function Only copies the current DOM HTML into JS this.getComponents (component.html_code).
|
|
1169
1205
|
*/
|
|
@@ -1179,10 +1215,12 @@ export class PageBuilderService {
|
|
|
1179
1215
|
const componentsToSave: { html_code: string; id: string | null; title: string }[] = []
|
|
1180
1216
|
|
|
1181
1217
|
pagebuilder.querySelectorAll('section[data-componentid]').forEach((section) => {
|
|
1218
|
+
const sanitizedSection = this.#cloneAndRemoveSelectionAttributes(section as HTMLElement)
|
|
1219
|
+
|
|
1182
1220
|
componentsToSave.push({
|
|
1183
|
-
html_code:
|
|
1184
|
-
id:
|
|
1185
|
-
title:
|
|
1221
|
+
html_code: sanitizedSection.outerHTML,
|
|
1222
|
+
id: sanitizedSection.getAttribute('data-componentid'),
|
|
1223
|
+
title: sanitizedSection.getAttribute('data-component-title') || 'Untitled Component',
|
|
1186
1224
|
})
|
|
1187
1225
|
})
|
|
1188
1226
|
|
|
@@ -1291,8 +1329,8 @@ export class PageBuilderService {
|
|
|
1291
1329
|
const draft = localStorage.getItem(key)
|
|
1292
1330
|
if (draft) {
|
|
1293
1331
|
try {
|
|
1294
|
-
await this.delay(
|
|
1295
|
-
|
|
1332
|
+
await this.delay(500)
|
|
1333
|
+
this.pageBuilderStateStore.setHasLocalDraftForUpdate(false)
|
|
1296
1334
|
return true
|
|
1297
1335
|
} catch (err) {
|
|
1298
1336
|
console.error('Unable to mount components to DOM.', err)
|
|
@@ -1359,6 +1397,7 @@ export class PageBuilderService {
|
|
|
1359
1397
|
getStorageItemNameForResource(): string | null {
|
|
1360
1398
|
return this.getLocalStorageItemName.value
|
|
1361
1399
|
}
|
|
1400
|
+
|
|
1362
1401
|
loadStoredComponentsFromStorage() {
|
|
1363
1402
|
if (!this.getLocalStorageItemName.value) return false
|
|
1364
1403
|
|
|
@@ -1862,7 +1901,7 @@ export class PageBuilderService {
|
|
|
1862
1901
|
if (this.pendingMountData && document.querySelector('#pagebuilder')) {
|
|
1863
1902
|
await this.mountComponentsToDOM(this.pendingMountData)
|
|
1864
1903
|
this.pendingMountData = null
|
|
1865
|
-
this
|
|
1904
|
+
this.completeBuilderInitialization()
|
|
1866
1905
|
}
|
|
1867
1906
|
}
|
|
1868
1907
|
|