@myissue/vue-website-page-builder 3.3.93 → 3.3.94
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 +51 -54
- package/dist/{ar-C3_B_jte.js → ar-B67ZvnES.js} +7 -6
- package/dist/{de-DdjFvQa0.js → de-2iNkasP-.js} +7 -6
- package/dist/{en-BUBdYOpm.js → en-BkPMvlrf.js} +7 -6
- package/dist/{es-B22SqDyv.js → es-CoKtBPFg.js} +11 -10
- package/dist/{fr-DvzSNDOH.js → fr-Bb-szPYF.js} +11 -10
- package/dist/{hi-BZT8U4mG.js → hi-Z-tSAHna.js} +2 -1
- package/dist/{ja-Dz8pZ4kc.js → ja-BsFKC04n.js} +7 -6
- package/dist/{pt-BKVGGQ7s.js → pt-CR27KWIb.js} +7 -6
- package/dist/{ru-CykvN5Tx.js → ru-CVy3Csm4.js} +7 -6
- package/dist/style.css +1 -1
- package/dist/vue-website-page-builder.js +4763 -4772
- package/dist/vue-website-page-builder.umd.cjs +35 -34
- package/dist/{zh-Hans-B-uPsE7N.js → zh-Hans-9bdCn2lI.js} +2 -1
- package/package.json +1 -1
- package/src/Components/PageBuilder/EditorMenu/Editables/Margin.vue +6 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/Padding.vue +6 -0
- package/src/PageBuilder/PageBuilder.vue +2 -2
- package/src/css/style.css +0 -1
- package/src/locales/ar.json +2 -1
- package/src/locales/de.json +2 -1
- package/src/locales/en.json +2 -1
- package/src/locales/es.json +2 -1
- package/src/locales/fr.json +2 -1
- package/src/locales/hi.json +2 -1
- package/src/locales/ja.json +2 -1
- package/src/locales/pt.json +2 -1
- package/src/locales/ru.json +2 -1
- package/src/locales/zh-Hans.json +2 -1
- package/src/services/PageBuilderService.ts +103 -181
- package/src/utils/builder/tailwind-padding-margin.ts +136 -136
|
@@ -166,7 +166,8 @@ const e = "保存", t = "选项", o = "头像", n = "发布", a = "组件", s =
|
|
|
166
166
|
"Use Saved Version": "使用保存的版本",
|
|
167
167
|
"Continue Where I Left Off": "从我离开的地方继续",
|
|
168
168
|
"HTML Editor": "HTML 编辑器",
|
|
169
|
-
"Gain full control over components by editing the raw HTML.": "通过编辑原始 HTML 获得对组件的完全控制。"
|
|
169
|
+
"Gain full control over components by editing the raw HTML.": "通过编辑原始 HTML 获得对组件的完全控制。",
|
|
170
|
+
"Large Screens Only": "仅限大屏幕"
|
|
170
171
|
};
|
|
171
172
|
export {
|
|
172
173
|
m as Add,
|
package/package.json
CHANGED
|
@@ -67,6 +67,12 @@ watch(
|
|
|
67
67
|
<template #title>{{ translate('Margin') }}</template>
|
|
68
68
|
<template #content>
|
|
69
69
|
<div class="pbx-my-2 pbx-py-2">
|
|
70
|
+
<div class="pbx-pt-4 pbx-pb-2 pbx-mb-4">
|
|
71
|
+
<p class="pbx-myPrimaryInputLabel pbx-font-medium pbx-italic">
|
|
72
|
+
{{ translate('Large Screens Only') }}
|
|
73
|
+
</p>
|
|
74
|
+
<hr />
|
|
75
|
+
</div>
|
|
70
76
|
<label for="vertical-margin" class="pbx-myPrimaryInputLabel">{{
|
|
71
77
|
translate('Vertical Margin')
|
|
72
78
|
}}</label>
|
|
@@ -68,6 +68,12 @@ watch(
|
|
|
68
68
|
<template #title>{{ translate('Padding') }}</template>
|
|
69
69
|
<template #content>
|
|
70
70
|
<div class="pbx-my-2 pbx-py-2">
|
|
71
|
+
<div class="pbx-pt-4 pbx-pb-2 pbx-mb-4">
|
|
72
|
+
<p class="pbx-myPrimaryInputLabel pbx-font-medium pbx-italic">
|
|
73
|
+
{{ translate('Large Screens Only') }}
|
|
74
|
+
</p>
|
|
75
|
+
<hr />
|
|
76
|
+
</div>
|
|
71
77
|
<label for="vertical-padding" class="pbx-myPrimaryInputLabel">{{
|
|
72
78
|
translate('Vertical Padding')
|
|
73
79
|
}}</label>
|
|
@@ -804,7 +804,7 @@ onMounted(async () => {
|
|
|
804
804
|
</template>
|
|
805
805
|
</template>
|
|
806
806
|
<template v-if="showCloseButton">
|
|
807
|
-
<div class="pbx-flex-1 pbx-ml-2">
|
|
807
|
+
<div class="pbx-flex-1 pbx-ml-2 pbx-mr-2">
|
|
808
808
|
<button
|
|
809
809
|
class="pbx-h-10 pbx-w-10 pbx-flex-end pbx-cursor-pointer pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-gray-50 pbx-aspect-square hover:pbx-bg-myPrimaryLinkColor hover:pbx-text-white hover:pbx-fill-white focus-visible:pbx-ring-0"
|
|
810
810
|
@click="
|
|
@@ -867,7 +867,7 @@ onMounted(async () => {
|
|
|
867
867
|
|
|
868
868
|
<main
|
|
869
869
|
ref="pbxToolBar"
|
|
870
|
-
class="pbx-transition-all pbx-duration-300 pbx-font-sans pbx-p-1 pbx-flex pbx-flex-col pbx-grow pbx-rounded-tr-2xl pbx-rounded-tl-2xl pbx-border-solid pbx-border pbx-border-gray-200 pbx-items-stretch pbx-text-black pbx-h-[100vh]"
|
|
870
|
+
class="pbx-transition-all pbx-duration-300 pbx-font-sans pbx-p-1 pbx-flex pbx-flex-col pbx-grow pbx-rounded-tr-2xl pbx-rounded-tl-2xl pbx-border-solid pbx-border pbx-border-gray-200 pbx-items-stretch pbx-text-black pbx-h-[100vh] pbx-overflow-y-auto"
|
|
871
871
|
:class="[getMenuRight ? 'pbx-w-full' : 'pbx-w-full']"
|
|
872
872
|
>
|
|
873
873
|
<div
|
package/src/css/style.css
CHANGED
package/src/locales/ar.json
CHANGED
|
@@ -165,5 +165,6 @@
|
|
|
165
165
|
"Use Saved Version": "استخدام النسخة المحفوظة",
|
|
166
166
|
"Continue Where I Left Off": "المتابعة من حيث توقفت",
|
|
167
167
|
"HTML Editor": "محرر HTML",
|
|
168
|
-
"Gain full control over components by editing the raw HTML.": "احصل على التحكم الكامل في المكونات عن طريق تحرير HTML الخام."
|
|
168
|
+
"Gain full control over components by editing the raw HTML.": "احصل على التحكم الكامل في المكونات عن طريق تحرير HTML الخام.",
|
|
169
|
+
"Large Screens Only": "الشاشات الكبيرة فقط"
|
|
169
170
|
}
|
package/src/locales/de.json
CHANGED
|
@@ -166,5 +166,6 @@
|
|
|
166
166
|
"Use Saved Version": "Gespeicherte Version verwenden",
|
|
167
167
|
"Continue Where I Left Off": "Dort weitermachen, wo ich aufgehört habe",
|
|
168
168
|
"HTML Editor": "HTML-Editor",
|
|
169
|
-
"Gain full control over components by editing the raw HTML.": "Erhalten Sie die vollständige Kontrolle über Komponenten, indem Sie das reine HTML bearbeiten."
|
|
169
|
+
"Gain full control over components by editing the raw HTML.": "Erhalten Sie die vollständige Kontrolle über Komponenten, indem Sie das reine HTML bearbeiten.",
|
|
170
|
+
"Large Screens Only": "Nur große Bildschirme"
|
|
170
171
|
}
|
package/src/locales/en.json
CHANGED
|
@@ -166,5 +166,6 @@
|
|
|
166
166
|
"Use Saved Version": "Use Saved Version",
|
|
167
167
|
"Continue Where I Left Off": "Continue Where I Left Off",
|
|
168
168
|
"HTML Editor": "HTML Editor",
|
|
169
|
-
"Gain full control over components by editing the raw HTML.": "Gain full control over components by editing the raw HTML."
|
|
169
|
+
"Gain full control over components by editing the raw HTML.": "Gain full control over components by editing the raw HTML.",
|
|
170
|
+
"Large Screens Only": "Large Screens Only"
|
|
170
171
|
}
|
package/src/locales/es.json
CHANGED
|
@@ -166,5 +166,6 @@
|
|
|
166
166
|
"Use Saved Version": "Usar la versión guardada",
|
|
167
167
|
"Continue Where I Left Off": "Continuar donde lo dejé",
|
|
168
168
|
"HTML Editor": "Editor HTML",
|
|
169
|
-
"Gain full control over components by editing the raw HTML.": "Obtenga control total sobre los componentes editando el HTML sin formato."
|
|
169
|
+
"Gain full control over components by editing the raw HTML.": "Obtenga control total sobre los componentes editando el HTML sin formato.",
|
|
170
|
+
"Large Screens Only": "Solo pantallas grandes"
|
|
170
171
|
}
|
package/src/locales/fr.json
CHANGED
|
@@ -166,5 +166,6 @@
|
|
|
166
166
|
"Use Saved Version": "Utiliser la version enregistrée",
|
|
167
167
|
"Continue Where I Left Off": "Continuer là où je me suis arrêté",
|
|
168
168
|
"HTML Editor": "Éditeur HTML",
|
|
169
|
-
"Gain full control over components by editing the raw HTML.": "Obtenez un contrôle total sur les composants en modifiant le code HTML brut."
|
|
169
|
+
"Gain full control over components by editing the raw HTML.": "Obtenez un contrôle total sur les composants en modifiant le code HTML brut.",
|
|
170
|
+
"Large Screens Only": "Grands écrans uniquement"
|
|
170
171
|
}
|
package/src/locales/hi.json
CHANGED
|
@@ -167,5 +167,6 @@
|
|
|
167
167
|
"Use Saved Version": "सहेजा गया संस्करण उपयोग करें",
|
|
168
168
|
"Continue Where I Left Off": "वहीं से शुरु करो जहाँ मैने छोड़ा था",
|
|
169
169
|
"HTML Editor": "HTML संपादक",
|
|
170
|
-
"Gain full control over components by editing the raw HTML.": "कच्चे HTML को संपादित करके घटकों पर पूर्ण नियंत्रण प्राप्त करें।"
|
|
170
|
+
"Gain full control over components by editing the raw HTML.": "कच्चे HTML को संपादित करके घटकों पर पूर्ण नियंत्रण प्राप्त करें।",
|
|
171
|
+
"Large Screens Only": "केवल बड़ी स्क्रीन"
|
|
171
172
|
}
|
package/src/locales/ja.json
CHANGED
|
@@ -166,5 +166,6 @@
|
|
|
166
166
|
"Use Saved Version": "保存されたバージョンを使用",
|
|
167
167
|
"Continue Where I Left Off": "中断したところから続行",
|
|
168
168
|
"HTML Editor": "HTMLエディター",
|
|
169
|
-
"Gain full control over components by editing the raw HTML.": "生の HTML を編集することで、コンポーネントを完全に制御できます。"
|
|
169
|
+
"Gain full control over components by editing the raw HTML.": "生の HTML を編集することで、コンポーネントを完全に制御できます。",
|
|
170
|
+
"Large Screens Only": "大型スクリーンのみ"
|
|
170
171
|
}
|
package/src/locales/pt.json
CHANGED
|
@@ -166,5 +166,6 @@
|
|
|
166
166
|
"Use Saved Version": "Usar a versão salva",
|
|
167
167
|
"Continue Where I Left Off": "Continuar de onde parei",
|
|
168
168
|
"HTML Editor": "Editor HTML",
|
|
169
|
-
"Gain full control over components by editing the raw HTML.": "Obtenha controlo total sobre os componentes editando o HTML em bruto."
|
|
169
|
+
"Gain full control over components by editing the raw HTML.": "Obtenha controlo total sobre os componentes editando o HTML em bruto.",
|
|
170
|
+
"Large Screens Only": "Somente telas grandes"
|
|
170
171
|
}
|
package/src/locales/ru.json
CHANGED
|
@@ -166,5 +166,6 @@
|
|
|
166
166
|
"Use Saved Version": "Использовать сохраненную версию",
|
|
167
167
|
"Continue Where I Left Off": "Продолжить с того места, где я остановился",
|
|
168
168
|
"HTML Editor": "HTML-редактор",
|
|
169
|
-
"Gain full control over components by editing the raw HTML.": "Получите полный контроль над компонентами, редактируя необработанный HTML-код."
|
|
169
|
+
"Gain full control over components by editing the raw HTML.": "Получите полный контроль над компонентами, редактируя необработанный HTML-код.",
|
|
170
|
+
"Large Screens Only": "Только большие экраны"
|
|
170
171
|
}
|
package/src/locales/zh-Hans.json
CHANGED
|
@@ -166,5 +166,6 @@
|
|
|
166
166
|
"Use Saved Version": "使用保存的版本",
|
|
167
167
|
"Continue Where I Left Off": "从我离开的地方继续",
|
|
168
168
|
"HTML Editor": "HTML 编辑器",
|
|
169
|
-
"Gain full control over components by editing the raw HTML.": "通过编辑原始 HTML 获得对组件的完全控制。"
|
|
169
|
+
"Gain full control over components by editing the raw HTML.": "通过编辑原始 HTML 获得对组件的完全控制。",
|
|
170
|
+
"Large Screens Only": "仅限大屏幕"
|
|
170
171
|
}
|
|
@@ -478,68 +478,97 @@ export class PageBuilderService {
|
|
|
478
478
|
await this.clearHtmlSelection()
|
|
479
479
|
|
|
480
480
|
if (formType === 'update' || formType === 'create') {
|
|
481
|
+
// Page Builder is initially present in the DOM
|
|
481
482
|
if (!this.pendingMountComponents) {
|
|
482
|
-
// Page Builder Is initially present in DOM
|
|
483
483
|
if (!passedComponentsArray && this.isPageBuilderMissingOnStart && localStorageData) {
|
|
484
484
|
await this.completeMountProcess(localStorageData)
|
|
485
485
|
return
|
|
486
486
|
}
|
|
487
487
|
if (passedComponentsArray && !localStorageData) {
|
|
488
|
-
|
|
488
|
+
const htmlString = this.renderComponentsToHtml(passedComponentsArray)
|
|
489
|
+
await this.completeMountProcess(htmlString, true)
|
|
489
490
|
this.saveDomComponentsToLocalStorage()
|
|
490
491
|
return
|
|
491
492
|
}
|
|
492
493
|
|
|
493
494
|
if (passedComponentsArray && localStorageData) {
|
|
494
|
-
|
|
495
|
+
const htmlString = this.renderComponentsToHtml(passedComponentsArray)
|
|
496
|
+
await this.completeMountProcess(htmlString, true)
|
|
495
497
|
await delay(500)
|
|
496
498
|
this.pageBuilderStateStore.setHasLocalDraftForUpdate(true)
|
|
497
499
|
return
|
|
498
500
|
}
|
|
501
|
+
|
|
499
502
|
if (!passedComponentsArray && localStorageData && !this.savedMountComponents) {
|
|
500
503
|
await this.completeMountProcess(localStorageData)
|
|
501
504
|
return
|
|
502
505
|
}
|
|
503
506
|
if (!passedComponentsArray && this.savedMountComponents && localStorageData) {
|
|
504
|
-
|
|
507
|
+
const htmlString = this.renderComponentsToHtml(this.savedMountComponents)
|
|
508
|
+
await this.completeMountProcess(htmlString)
|
|
505
509
|
return
|
|
506
510
|
}
|
|
507
511
|
|
|
508
512
|
if (!passedComponentsArray && !localStorageData && this.isPageBuilderMissingOnStart) {
|
|
509
|
-
|
|
513
|
+
const htmlString = this.renderComponentsToHtml([])
|
|
514
|
+
await this.completeMountProcess(htmlString)
|
|
515
|
+
|
|
510
516
|
return
|
|
511
517
|
}
|
|
512
518
|
|
|
513
519
|
if (!this.isPageBuilderMissingOnStart && !localStorageData && !passedComponentsArray) {
|
|
514
|
-
|
|
520
|
+
const htmlString = this.renderComponentsToHtml([])
|
|
521
|
+
await this.completeMountProcess(htmlString)
|
|
515
522
|
return
|
|
516
523
|
}
|
|
517
524
|
}
|
|
518
525
|
|
|
519
|
-
//
|
|
526
|
+
// Page Builder is not initially present in the DOM
|
|
520
527
|
if (this.pendingMountComponents) {
|
|
521
|
-
// No Page Builder Is present in DOM initially
|
|
522
528
|
if (localStorageData && this.isPageBuilderMissingOnStart) {
|
|
523
|
-
|
|
529
|
+
const htmlString = this.renderComponentsToHtml(this.pendingMountComponents)
|
|
530
|
+
await this.completeMountProcess(htmlString, true)
|
|
524
531
|
await delay(500)
|
|
525
532
|
this.pageBuilderStateStore.setHasLocalDraftForUpdate(true)
|
|
526
533
|
this.pendingMountComponents = null
|
|
527
534
|
return
|
|
528
535
|
}
|
|
529
536
|
if (!localStorageData && passedComponentsArray && this.isPageBuilderMissingOnStart) {
|
|
530
|
-
|
|
537
|
+
const htmlString = this.renderComponentsToHtml(this.pendingMountComponents)
|
|
538
|
+
await this.completeMountProcess(htmlString, true)
|
|
531
539
|
this.saveDomComponentsToLocalStorage()
|
|
532
540
|
return
|
|
533
541
|
}
|
|
534
542
|
|
|
535
543
|
if (!passedComponentsArray && !localStorageData && this.isPageBuilderMissingOnStart) {
|
|
536
|
-
|
|
544
|
+
const htmlString = this.renderComponentsToHtml(this.pendingMountComponents)
|
|
545
|
+
await this.completeMountProcess(htmlString, true)
|
|
537
546
|
this.saveDomComponentsToLocalStorage()
|
|
538
547
|
return
|
|
539
548
|
}
|
|
540
549
|
}
|
|
541
550
|
}
|
|
542
|
-
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Converts an array of ComponentObject into a single HTML string.
|
|
555
|
+
*
|
|
556
|
+
* @returns {string} A single HTML string containing all components.
|
|
557
|
+
*/
|
|
558
|
+
private renderComponentsToHtml(componentsArray: BuilderResourceData): string {
|
|
559
|
+
// If the componentsArray is empty or invalid, return a default HTML structure
|
|
560
|
+
if (!componentsArray || (Array.isArray(componentsArray) && componentsArray.length === 0)) {
|
|
561
|
+
return `<div id="pagebuilder" class="pbx-text-black pbx-font-sans"></div>`
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
const sectionsHtml = componentsArray
|
|
565
|
+
.map((component) => {
|
|
566
|
+
return component.html_code // Fallback in case section is not found
|
|
567
|
+
})
|
|
568
|
+
.join('\n')
|
|
569
|
+
|
|
570
|
+
// Return the combined HTML string
|
|
571
|
+
return sectionsHtml
|
|
543
572
|
}
|
|
544
573
|
|
|
545
574
|
/**
|
|
@@ -553,14 +582,8 @@ export class PageBuilderService {
|
|
|
553
582
|
|
|
554
583
|
// Clean up any old localStorage items related to previous builder sessions
|
|
555
584
|
this.deleteOldPageBuilderLocalStorage()
|
|
556
|
-
|
|
557
585
|
this.pageBuilderStateStore.setIsRestoring(false)
|
|
558
586
|
this.pageBuilderStateStore.setIsLoadingGlobal(false)
|
|
559
|
-
|
|
560
|
-
// Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
|
|
561
|
-
await nextTick()
|
|
562
|
-
// Attach event listeners to all editable elements in the Builder
|
|
563
|
-
await this.addListenersToEditableElements()
|
|
564
587
|
}
|
|
565
588
|
|
|
566
589
|
/**
|
|
@@ -1070,7 +1093,6 @@ export class PageBuilderService {
|
|
|
1070
1093
|
|
|
1071
1094
|
// Set the title attribute if present
|
|
1072
1095
|
if (clonedComponent.title) {
|
|
1073
|
-
section.setAttribute('title', clonedComponent.title)
|
|
1074
1096
|
section.setAttribute('data-component-title', clonedComponent.title)
|
|
1075
1097
|
}
|
|
1076
1098
|
|
|
@@ -1952,7 +1974,8 @@ export class PageBuilderService {
|
|
|
1952
1974
|
if (Array.isArray(this.originalComponents)) {
|
|
1953
1975
|
await this.clearClassesFromPage()
|
|
1954
1976
|
await this.clearInlineStylesFromPage()
|
|
1955
|
-
|
|
1977
|
+
const htmlString = this.renderComponentsToHtml(this.originalComponents)
|
|
1978
|
+
await this.mountComponentsToDOM(htmlString)
|
|
1956
1979
|
this.removeCurrentComponentsFromLocalStorage()
|
|
1957
1980
|
}
|
|
1958
1981
|
|
|
@@ -1992,9 +2015,24 @@ export class PageBuilderService {
|
|
|
1992
2015
|
const classes = (parsed.pageSettings && parsed.pageSettings.classes) || ''
|
|
1993
2016
|
const style = (parsed.pageSettings && parsed.pageSettings.style) || ''
|
|
1994
2017
|
|
|
1995
|
-
const sectionsHtml = parsed.components
|
|
2018
|
+
const sectionsHtml = parsed.components
|
|
2019
|
+
.map((c: ComponentObject) => {
|
|
2020
|
+
const parser = new DOMParser()
|
|
2021
|
+
const doc = parser.parseFromString(c.html_code, 'text/html')
|
|
2022
|
+
const section = doc.querySelector('section')
|
|
2023
|
+
|
|
2024
|
+
if (section) {
|
|
2025
|
+
section.removeAttribute('data-componentid') // Remove the data-componentid attribute
|
|
2026
|
+
return section.outerHTML
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
return c.html_code // Fallback in case section is not found
|
|
2030
|
+
})
|
|
2031
|
+
.join('\n')
|
|
2032
|
+
|
|
1996
2033
|
return `<div id="pagebuilder" class="${classes}" style="${style}">\n${sectionsHtml}\n</div>`
|
|
1997
2034
|
}
|
|
2035
|
+
|
|
1998
2036
|
return false
|
|
1999
2037
|
}
|
|
2000
2038
|
|
|
@@ -2371,10 +2409,7 @@ export class PageBuilderService {
|
|
|
2371
2409
|
components = topLevelSections.map((section) => ({
|
|
2372
2410
|
id: null,
|
|
2373
2411
|
html_code: section.outerHTML.trim(),
|
|
2374
|
-
title:
|
|
2375
|
-
section.getAttribute('data-component-title') ||
|
|
2376
|
-
section.getAttribute('title') ||
|
|
2377
|
-
'Untitled Component',
|
|
2412
|
+
title: section.getAttribute('data-component-title') || 'Untitled Component',
|
|
2378
2413
|
}))
|
|
2379
2414
|
}
|
|
2380
2415
|
if (topLevelSections.length === 0) {
|
|
@@ -2418,183 +2453,69 @@ export class PageBuilderService {
|
|
|
2418
2453
|
}
|
|
2419
2454
|
|
|
2420
2455
|
/**
|
|
2421
|
-
*
|
|
2456
|
+
* Mounts builder components to the DOM from an HTML string.
|
|
2422
2457
|
*
|
|
2423
|
-
*
|
|
2424
|
-
*
|
|
2425
|
-
*
|
|
2458
|
+
* Input format detection:
|
|
2459
|
+
* - If the input starts with `[` or `{`: treated as JSON (array or object).
|
|
2460
|
+
* - If the input starts with `<`: treated as HTML.
|
|
2426
2461
|
*
|
|
2427
|
-
*
|
|
2462
|
+
* This function should be used when:
|
|
2463
|
+
* - Restoring the builder from a published HTML snapshot.
|
|
2464
|
+
* - Importing a static HTML export.
|
|
2465
|
+
* - Loading the builder from previously published or saved HTML (e.g., from `getSavedPageHtml()`).
|
|
2428
2466
|
*
|
|
2429
|
-
*
|
|
2430
|
-
* OR HTML string (e.g., '<section data-componentid="123">...</section>')
|
|
2467
|
+
* Typical use cases include restoring a published state, importing templates, or previewing published content.
|
|
2431
2468
|
*/
|
|
2432
2469
|
private async mountComponentsToDOM(
|
|
2433
2470
|
htmlString: string,
|
|
2434
2471
|
usePassedPageSettings?: boolean,
|
|
2435
2472
|
): Promise<void> {
|
|
2436
|
-
/**
|
|
2437
|
-
* Mounts builder components to the DOM from either JSON or HTML input.
|
|
2438
|
-
*
|
|
2439
|
-
* Input format detection:
|
|
2440
|
-
* - If the input starts with `[` or `{`, it is treated as JSON (array or object).
|
|
2441
|
-
* - If the input starts with `<`, it is treated as HTML.
|
|
2442
|
-
*
|
|
2443
|
-
* When to use which format:
|
|
2444
|
-
*
|
|
2445
|
-
* 1. JSON input (from localStorage, API, or internal state like pina):
|
|
2446
|
-
* - Use when restoring builder state from localStorage, an API, or a previously saved draft.
|
|
2447
|
-
* - Example: `localStorage.getItem(...)` or API returns a JSON stringified array/object of components.
|
|
2448
|
-
* - This is the most common format for drafts, autosave, and programmatic state management.
|
|
2449
|
-
* - Example usage:
|
|
2450
|
-
* await this.mountComponentsToDOM(JSON.stringify(getComponents))
|
|
2451
|
-
*
|
|
2452
|
-
* 2. HTML input (from HTML snapshot, import, or published output):
|
|
2453
|
-
* - Use when restoring from a published HTML snapshot, importing a static HTML export, or loading the builder from a previously published HTML string.
|
|
2454
|
-
* - Example: output from `getSavedPageHtml()` or a static HTML export.
|
|
2455
|
-
* - This is used for restoring the builder from a published state, importing, or previewing published content.
|
|
2456
|
-
* - Example usage:
|
|
2457
|
-
* await this.mountComponentsToDOM(savedHtmlString)
|
|
2458
|
-
*
|
|
2459
|
-
* Best practice:
|
|
2460
|
-
* - Use JSON for local storage drafts, autosave, and API-driven workflows.
|
|
2461
|
-
* - Use HTML for published/imported content from DB or when restoring from a static HTML snapshot.
|
|
2462
|
-
*
|
|
2463
|
-
* The method auto-detects the format and calls the appropriate parser.
|
|
2464
|
-
*/
|
|
2465
2473
|
const trimmedData = htmlString.trim()
|
|
2466
2474
|
|
|
2475
|
+
// Return error since JSON data has been passed to mount HTML to DOM
|
|
2467
2476
|
if (trimmedData.startsWith('[') || trimmedData.startsWith('{')) {
|
|
2468
|
-
|
|
2469
|
-
await this.parseJSONComponents(trimmedData, usePassedPageSettings)
|
|
2470
|
-
return
|
|
2471
|
-
}
|
|
2472
|
-
if (trimmedData.startsWith('<')) {
|
|
2473
|
-
// HTML input: Use this when restoring from a published HTML snapshot, import, or static HTML export
|
|
2474
|
-
await this.parseHTMLComponents(trimmedData, usePassedPageSettings)
|
|
2477
|
+
console.error('Error: JSON data passed to mountComponentsToDOM for the Page Builder Package.')
|
|
2475
2478
|
return
|
|
2476
2479
|
}
|
|
2477
2480
|
|
|
2478
|
-
//
|
|
2479
|
-
await this.parseJSONComponents(trimmedData, usePassedPageSettings)
|
|
2480
|
-
}
|
|
2481
|
-
|
|
2482
|
-
// Private method to parse JSON components and save pageBuilderContentSavedAt to localStorage
|
|
2483
|
-
private async parseJSONComponents(
|
|
2484
|
-
jsonData: string,
|
|
2485
|
-
usePassedPageSettings?: boolean,
|
|
2486
|
-
): Promise<void> {
|
|
2487
|
-
const pageSettings =
|
|
2488
|
-
this.pageBuilderStateStore.getPageBuilderConfig &&
|
|
2489
|
-
this.pageBuilderStateStore.getPageBuilderConfig.pageSettings
|
|
2490
|
-
|
|
2491
|
-
const userPageSettings = usePassedPageSettings ? pageSettings : null
|
|
2492
|
-
|
|
2481
|
+
// HTML string
|
|
2493
2482
|
try {
|
|
2494
|
-
const
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
if (Array.isArray(parsedData)) {
|
|
2498
|
-
componentsArray = parsedData
|
|
2499
|
-
}
|
|
2500
|
-
if (parsedData && Array.isArray(parsedData.components)) {
|
|
2501
|
-
componentsArray = parsedData.components
|
|
2502
|
-
}
|
|
2503
|
-
|
|
2504
|
-
let savedCurrentDesign: ComponentObject[] = []
|
|
2505
|
-
|
|
2506
|
-
if (componentsArray.length > 0) {
|
|
2507
|
-
savedCurrentDesign = componentsArray.map((component: ComponentObject) => {
|
|
2508
|
-
const parser = new DOMParser()
|
|
2509
|
-
const doc = parser.parseFromString(component.html_code, 'text/html')
|
|
2510
|
-
const section = doc.querySelector('section')
|
|
2483
|
+
const parser = new DOMParser()
|
|
2484
|
+
const doc = parser.parseFromString(htmlString, 'text/html')
|
|
2511
2485
|
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
section.querySelectorAll('[class]').forEach((el) => {
|
|
2515
|
-
el.setAttribute(
|
|
2516
|
-
'class',
|
|
2517
|
-
this.addTailwindPrefixToClasses(el.getAttribute('class') || '', 'pbx-'),
|
|
2518
|
-
)
|
|
2519
|
-
})
|
|
2520
|
-
|
|
2521
|
-
// Ensure IDs & titles
|
|
2522
|
-
if (!section.hasAttribute('data-componentid')) {
|
|
2523
|
-
const newId = uuidv4()
|
|
2524
|
-
section.setAttribute('data-componentid', newId)
|
|
2525
|
-
component.id = newId
|
|
2526
|
-
} else {
|
|
2527
|
-
component.id = section.getAttribute('data-componentid')!
|
|
2528
|
-
}
|
|
2486
|
+
const importedPageBuilder = doc.querySelector('#pagebuilder') as HTMLElement | null
|
|
2487
|
+
const livePageBuilder = document.querySelector('#pagebuilder') as HTMLElement | null
|
|
2529
2488
|
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
component.title = title
|
|
2489
|
+
// Initialize pageSettings to null
|
|
2490
|
+
let pageSettings = null
|
|
2533
2491
|
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
return component
|
|
2538
|
-
})
|
|
2492
|
+
// Use stored page settings if the flag is true
|
|
2493
|
+
if (usePassedPageSettings) {
|
|
2494
|
+
pageSettings = this.pageBuilderStateStore.getPageBuilderConfig?.pageSettings || null
|
|
2539
2495
|
}
|
|
2540
2496
|
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
if (userPageSettings && pageSettings) {
|
|
2547
|
-
const pagebuilder = document.querySelector('#pagebuilder') as HTMLElement
|
|
2548
|
-
if (pagebuilder) {
|
|
2549
|
-
pagebuilder.removeAttribute('class')
|
|
2550
|
-
pagebuilder.removeAttribute('style')
|
|
2551
|
-
pagebuilder.className = pageSettings.classes || ''
|
|
2552
|
-
pagebuilder.setAttribute('style', this.convertStyleObjectToString(pageSettings.style))
|
|
2497
|
+
// Use imported page builder settings if available and pageSettings is still null
|
|
2498
|
+
if (!pageSettings && importedPageBuilder) {
|
|
2499
|
+
pageSettings = {
|
|
2500
|
+
classes: importedPageBuilder.className || '',
|
|
2501
|
+
style: importedPageBuilder.getAttribute('style') || '',
|
|
2553
2502
|
}
|
|
2554
2503
|
}
|
|
2555
|
-
} catch (error) {
|
|
2556
|
-
console.error('Error parsing JSON components:', error)
|
|
2557
|
-
this.deleteAllComponentsFromDOM()
|
|
2558
|
-
}
|
|
2559
|
-
}
|
|
2560
2504
|
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
): Promise<void> {
|
|
2566
|
-
try {
|
|
2567
|
-
const parser = new DOMParser()
|
|
2568
|
-
const doc = parser.parseFromString(htmlData, 'text/html')
|
|
2569
|
-
|
|
2570
|
-
const importedPageBuilder = doc.querySelector('#pagebuilder') as HTMLElement | null
|
|
2571
|
-
const livePageBuilder = document.querySelector('#pagebuilder') as HTMLElement | null
|
|
2505
|
+
// Fallback to stored page settings if pageSettings is still null
|
|
2506
|
+
if (!pageSettings) {
|
|
2507
|
+
pageSettings = this.pageBuilderStateStore.getPageBuilderConfig?.pageSettings || null
|
|
2508
|
+
}
|
|
2572
2509
|
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
// Decide which pageSettings to use
|
|
2579
|
-
let pageSettings = null
|
|
2580
|
-
if (usePassedPageSettings) {
|
|
2581
|
-
pageSettings = storedPageSettings
|
|
2582
|
-
} else if (importedPageBuilder) {
|
|
2583
|
-
pageSettings = {
|
|
2584
|
-
classes: importedPageBuilder.className || '',
|
|
2585
|
-
style: importedPageBuilder.getAttribute('style') || '',
|
|
2586
|
-
}
|
|
2587
|
-
} else {
|
|
2588
|
-
pageSettings = storedPageSettings
|
|
2589
|
-
}
|
|
2510
|
+
// Apply the page settings to the live page builder
|
|
2511
|
+
if (pageSettings && livePageBuilder) {
|
|
2512
|
+
// Remove existing class and style attributes
|
|
2513
|
+
livePageBuilder.removeAttribute('class')
|
|
2514
|
+
livePageBuilder.removeAttribute('style')
|
|
2590
2515
|
|
|
2591
|
-
//
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
livePageBuilder.removeAttribute('style')
|
|
2595
|
-
livePageBuilder.className = pageSettings.classes || ''
|
|
2596
|
-
livePageBuilder.setAttribute('style', this.convertStyleObjectToString(pageSettings.style))
|
|
2597
|
-
}
|
|
2516
|
+
// Apply new classes and styles
|
|
2517
|
+
livePageBuilder.className = pageSettings.classes || ''
|
|
2518
|
+
livePageBuilder.setAttribute('style', this.convertStyleObjectToString(pageSettings.style))
|
|
2598
2519
|
}
|
|
2599
2520
|
|
|
2600
2521
|
// Select all <section> elements
|
|
@@ -2619,10 +2540,7 @@ export class PageBuilderService {
|
|
|
2619
2540
|
const componentId = htmlElement.getAttribute('data-componentid')!
|
|
2620
2541
|
|
|
2621
2542
|
// Ensure data-component-title exists
|
|
2622
|
-
const title =
|
|
2623
|
-
htmlElement.getAttribute('title') ||
|
|
2624
|
-
htmlElement.getAttribute('data-component-title') ||
|
|
2625
|
-
'Untitled Component'
|
|
2543
|
+
const title = htmlElement.getAttribute('data-component-title') || 'Untitled Component'
|
|
2626
2544
|
|
|
2627
2545
|
htmlElement.setAttribute('data-component-title', title)
|
|
2628
2546
|
|
|
@@ -2642,6 +2560,10 @@ export class PageBuilderService {
|
|
|
2642
2560
|
} catch (error) {
|
|
2643
2561
|
console.error('Error parsing HTML components:', error)
|
|
2644
2562
|
this.deleteAllComponentsFromDOM()
|
|
2563
|
+
// Clear selections and re-bind events
|
|
2564
|
+
await this.clearHtmlSelection()
|
|
2565
|
+
await nextTick()
|
|
2566
|
+
await this.addListenersToEditableElements()
|
|
2645
2567
|
}
|
|
2646
2568
|
}
|
|
2647
2569
|
|