@myissue/vue-website-page-builder 3.3.90 → 3.3.91
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 +5 -5
- package/dist/style.css +1 -1
- package/dist/vue-website-page-builder.js +929 -605
- package/dist/vue-website-page-builder.umd.cjs +23 -23
- package/package.json +1 -1
- package/src/Components/TipTap/TipTap.vue +1 -1
- package/src/PageBuilder/PageBuilder.vue +7 -14
- package/src/composables/builderInstance.ts +30 -5
- package/src/services/PageBuilderService.ts +397 -74
|
@@ -136,20 +136,36 @@ export class PageBuilderService {
|
|
|
136
136
|
]
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Returns an array of available languages.
|
|
141
|
+
* @returns {AvailableLanguage[]} An array of available language codes.
|
|
142
|
+
*/
|
|
139
143
|
public availableLanguage(): AvailableLanguage[] {
|
|
140
144
|
return AVAILABLE_LANGUAGES
|
|
141
145
|
}
|
|
142
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Sets the current language in the page builder state.
|
|
149
|
+
* @param {string} lang - The language code to set.
|
|
150
|
+
*/
|
|
143
151
|
public changeLanguage(lang: string) {
|
|
144
152
|
this.pageBuilderStateStore.setCurrentLanguage(lang)
|
|
145
153
|
}
|
|
146
|
-
|
|
154
|
+
/**
|
|
155
|
+
* Deselects any selected or hovered elements in the builder UI.
|
|
156
|
+
* @returns {Promise<void>}
|
|
157
|
+
*/
|
|
147
158
|
async clearHtmlSelection(): Promise<void> {
|
|
148
159
|
this.pageBuilderStateStore.setComponent(null)
|
|
149
160
|
this.pageBuilderStateStore.setElement(null)
|
|
150
161
|
await this.removeHoveredAndSelected()
|
|
151
162
|
}
|
|
152
163
|
|
|
164
|
+
/**
|
|
165
|
+
* Ensures that the `updateOrCreate` configuration is valid and sets default values if necessary.
|
|
166
|
+
* @param {PageBuilderConfig} config - The page builder configuration.
|
|
167
|
+
* @private
|
|
168
|
+
*/
|
|
153
169
|
private ensureUpdateOrCreateConfig(config: PageBuilderConfig): void {
|
|
154
170
|
// Case A: updateOrCreate is missing or an empty object
|
|
155
171
|
if (!config.updateOrCreate || (config.updateOrCreate && isEmptyObject(config.updateOrCreate))) {
|
|
@@ -226,6 +242,12 @@ export class PageBuilderService {
|
|
|
226
242
|
}
|
|
227
243
|
}
|
|
228
244
|
|
|
245
|
+
/**
|
|
246
|
+
* Validates the user-provided components array.
|
|
247
|
+
* @param {unknown} components - The components data to validate.
|
|
248
|
+
* @returns {{error: true, warning: string, status: string} | {error: true, reason: string} | undefined} An error object if validation fails, otherwise undefined.
|
|
249
|
+
* @private
|
|
250
|
+
*/
|
|
229
251
|
private validateUserProvidedComponents(components: unknown) {
|
|
230
252
|
const formType =
|
|
231
253
|
this.pageBuilderStateStore.getPageBuilderConfig &&
|
|
@@ -278,6 +300,11 @@ export class PageBuilderService {
|
|
|
278
300
|
return
|
|
279
301
|
}
|
|
280
302
|
|
|
303
|
+
/**
|
|
304
|
+
* Ensures that the language configuration is valid and sets default values if necessary.
|
|
305
|
+
* @param {PageBuilderConfig} config - The page builder configuration.
|
|
306
|
+
* @private
|
|
307
|
+
*/
|
|
281
308
|
private ensureLanguage(config: PageBuilderConfig): void {
|
|
282
309
|
// Set default language config if missing, empty, or language missing/empty
|
|
283
310
|
const defaultLang = 'en'
|
|
@@ -327,6 +354,11 @@ export class PageBuilderService {
|
|
|
327
354
|
}
|
|
328
355
|
}
|
|
329
356
|
|
|
357
|
+
/**
|
|
358
|
+
* Validates the entire page builder configuration.
|
|
359
|
+
* @param {PageBuilderConfig} config - The page builder configuration.
|
|
360
|
+
* @private
|
|
361
|
+
*/
|
|
330
362
|
private validateConfig(config: PageBuilderConfig): void {
|
|
331
363
|
const defaultConfigValues = {
|
|
332
364
|
updateOrCreate: {
|
|
@@ -347,6 +379,10 @@ export class PageBuilderService {
|
|
|
347
379
|
this.ensureLanguage(config)
|
|
348
380
|
}
|
|
349
381
|
|
|
382
|
+
/**
|
|
383
|
+
* Saves user settings to local storage.
|
|
384
|
+
* @param {string} newLang - The new language to save.
|
|
385
|
+
*/
|
|
350
386
|
public saveUserSettingsStorage(newLang: string) {
|
|
351
387
|
localStorage.setItem(
|
|
352
388
|
'userSettingsPageBuilder',
|
|
@@ -355,14 +391,10 @@ export class PageBuilderService {
|
|
|
355
391
|
}
|
|
356
392
|
|
|
357
393
|
/**
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
* -
|
|
361
|
-
*
|
|
362
|
-
* - Updates the localStorage key name based on the config/resource.
|
|
363
|
-
* - Completes builder initialization if the DOM is ready.
|
|
364
|
-
*
|
|
365
|
-
* @param config - The configuration object for the Page Builder.
|
|
394
|
+
* Initializes the Page Builder.
|
|
395
|
+
* @param {PageBuilderConfig} config - The configuration object for the Page Builder.
|
|
396
|
+
* @param {BuilderResourceData} [passedComponentsArray] - Optional array of components to load.
|
|
397
|
+
* @returns {Promise<StartBuilderResult>} A result object indicating success or failure.
|
|
366
398
|
*/
|
|
367
399
|
async startBuilder(
|
|
368
400
|
config: PageBuilderConfig,
|
|
@@ -425,6 +457,11 @@ export class PageBuilderService {
|
|
|
425
457
|
}
|
|
426
458
|
}
|
|
427
459
|
|
|
460
|
+
/**
|
|
461
|
+
* Completes the builder initialization process once the DOM is ready.
|
|
462
|
+
* @param {BuilderResourceData} [passedComponentsArray] - Optional array of components to load.
|
|
463
|
+
* @returns {Promise<void>}
|
|
464
|
+
*/
|
|
428
465
|
async completeBuilderInitialization(passedComponentsArray?: BuilderResourceData): Promise<void> {
|
|
429
466
|
this.pageBuilderStateStore.setIsLoadingGlobal(true)
|
|
430
467
|
await delay(400)
|
|
@@ -504,6 +541,12 @@ export class PageBuilderService {
|
|
|
504
541
|
//
|
|
505
542
|
}
|
|
506
543
|
|
|
544
|
+
/**
|
|
545
|
+
* Completes the mounting process by loading components into the DOM and setting up listeners.
|
|
546
|
+
* @param {string} html - The HTML string of components to mount.
|
|
547
|
+
* @param {boolean} [usePassedPageSettings] - Whether to use page settings from the passed data.
|
|
548
|
+
* @private
|
|
549
|
+
*/
|
|
507
550
|
private async completeMountProcess(html: string, usePassedPageSettings?: boolean) {
|
|
508
551
|
await this.mountComponentsToDOM(html, usePassedPageSettings)
|
|
509
552
|
|
|
@@ -519,6 +562,14 @@ export class PageBuilderService {
|
|
|
519
562
|
await this.addListenersToEditableElements()
|
|
520
563
|
}
|
|
521
564
|
|
|
565
|
+
/**
|
|
566
|
+
* Applies CSS class changes to the currently selected element.
|
|
567
|
+
* @param {string | undefined} cssUserSelection - The user's CSS class selection.
|
|
568
|
+
* @param {string[]} CSSArray - The array of possible CSS classes for this property.
|
|
569
|
+
* @param {string} mutationName - The name of the store mutation to call.
|
|
570
|
+
* @returns {string | undefined} The previously applied CSS class.
|
|
571
|
+
* @private
|
|
572
|
+
*/
|
|
522
573
|
private applyElementClassChanges(
|
|
523
574
|
cssUserSelection: string | undefined,
|
|
524
575
|
CSSArray: string[],
|
|
@@ -591,6 +642,10 @@ export class PageBuilderService {
|
|
|
591
642
|
return currentCSS
|
|
592
643
|
}
|
|
593
644
|
|
|
645
|
+
/**
|
|
646
|
+
* Removes all CSS classes from the main page builder container.
|
|
647
|
+
* @returns {Promise<void>}
|
|
648
|
+
*/
|
|
594
649
|
public async clearClassesFromPage() {
|
|
595
650
|
const pagebuilder = document.querySelector('#pagebuilder')
|
|
596
651
|
if (!pagebuilder) return
|
|
@@ -600,6 +655,10 @@ export class PageBuilderService {
|
|
|
600
655
|
this.initializeElementStyles()
|
|
601
656
|
await nextTick()
|
|
602
657
|
}
|
|
658
|
+
/**
|
|
659
|
+
* Removes all inline styles from the main page builder container.
|
|
660
|
+
* @returns {Promise<void>}
|
|
661
|
+
*/
|
|
603
662
|
public async clearInlineStylesFromPagee() {
|
|
604
663
|
const pagebuilder = document.querySelector('#pagebuilder')
|
|
605
664
|
if (!pagebuilder) return
|
|
@@ -610,6 +669,10 @@ export class PageBuilderService {
|
|
|
610
669
|
await nextTick()
|
|
611
670
|
}
|
|
612
671
|
|
|
672
|
+
/**
|
|
673
|
+
* Selects the main page builder container for global styling.
|
|
674
|
+
* @returns {Promise<void>}
|
|
675
|
+
*/
|
|
613
676
|
public async globalPageStyles() {
|
|
614
677
|
const pagebuilder = document.querySelector('#pagebuilder')
|
|
615
678
|
if (!pagebuilder) return
|
|
@@ -626,6 +689,10 @@ export class PageBuilderService {
|
|
|
626
689
|
await nextTick()
|
|
627
690
|
}
|
|
628
691
|
|
|
692
|
+
/**
|
|
693
|
+
* Handles changes to the font weight of the selected element.
|
|
694
|
+
* @param {string} [userSelectedFontWeight] - The selected font weight class.
|
|
695
|
+
*/
|
|
629
696
|
public handleFontWeight(userSelectedFontWeight?: string): void {
|
|
630
697
|
this.applyElementClassChanges(
|
|
631
698
|
userSelectedFontWeight,
|
|
@@ -634,10 +701,18 @@ export class PageBuilderService {
|
|
|
634
701
|
)
|
|
635
702
|
}
|
|
636
703
|
|
|
704
|
+
/**
|
|
705
|
+
* Handles changes to the base font size of the selected element.
|
|
706
|
+
* @param {string} [userSelectedFontSize] - The selected font size class.
|
|
707
|
+
*/
|
|
637
708
|
public handleFontSizeBase(userSelectedFontSize?: string): void {
|
|
638
709
|
this.applyElementClassChanges(userSelectedFontSize, tailwindFontSizes.fontBase, 'setFontBase')
|
|
639
710
|
}
|
|
640
711
|
|
|
712
|
+
/**
|
|
713
|
+
* Handles changes to the desktop font size of the selected element.
|
|
714
|
+
* @param {string} [userSelectedFontSize] - The selected font size class for desktop.
|
|
715
|
+
*/
|
|
641
716
|
public handleFontSizeDesktop(userSelectedFontSize?: string): void {
|
|
642
717
|
const currentHTMLElement = this.getElement.value
|
|
643
718
|
if (!currentHTMLElement) return
|
|
@@ -693,6 +768,11 @@ export class PageBuilderService {
|
|
|
693
768
|
}
|
|
694
769
|
}
|
|
695
770
|
|
|
771
|
+
/**
|
|
772
|
+
* Applies helper CSS classes to elements, such as wrapping them or adding responsive text classes.
|
|
773
|
+
* @param {HTMLElement} element - The element to process.
|
|
774
|
+
* @private
|
|
775
|
+
*/
|
|
696
776
|
private applyHelperCSSToElements(element: HTMLElement): void {
|
|
697
777
|
this.wrapElementInDivIfExcluded(element)
|
|
698
778
|
|
|
@@ -720,6 +800,11 @@ export class PageBuilderService {
|
|
|
720
800
|
}
|
|
721
801
|
}
|
|
722
802
|
|
|
803
|
+
/**
|
|
804
|
+
* Toggles the visibility of the TipTap modal for rich text editing.
|
|
805
|
+
* @param {boolean} status - Whether to show or hide the modal.
|
|
806
|
+
* @returns {Promise<void>}
|
|
807
|
+
*/
|
|
723
808
|
public async toggleTipTapModal(status: boolean): Promise<void> {
|
|
724
809
|
this.pageBuilderStateStore.setShowModalTipTap(status)
|
|
725
810
|
|
|
@@ -733,6 +818,11 @@ export class PageBuilderService {
|
|
|
733
818
|
}
|
|
734
819
|
}
|
|
735
820
|
|
|
821
|
+
/**
|
|
822
|
+
* Wraps an element in a div if it's an excluded tag and adjacent to an image.
|
|
823
|
+
* @param {HTMLElement} element - The element to potentially wrap.
|
|
824
|
+
* @private
|
|
825
|
+
*/
|
|
736
826
|
private wrapElementInDivIfExcluded(element: HTMLElement): void {
|
|
737
827
|
if (!element) return
|
|
738
828
|
|
|
@@ -747,6 +837,12 @@ export class PageBuilderService {
|
|
|
747
837
|
}
|
|
748
838
|
}
|
|
749
839
|
|
|
840
|
+
/**
|
|
841
|
+
* Handles the mouseover event for editable elements, showing a hover state.
|
|
842
|
+
* @param {Event} e - The mouse event.
|
|
843
|
+
* @param {HTMLElement} element - The element being hovered over.
|
|
844
|
+
* @private
|
|
845
|
+
*/
|
|
750
846
|
private handleMouseOver = (e: Event, element: HTMLElement): void => {
|
|
751
847
|
e.preventDefault()
|
|
752
848
|
e.stopPropagation()
|
|
@@ -765,6 +861,11 @@ export class PageBuilderService {
|
|
|
765
861
|
}
|
|
766
862
|
}
|
|
767
863
|
|
|
864
|
+
/**
|
|
865
|
+
* Handles the mouseleave event for editable elements, removing the hover state.
|
|
866
|
+
* @param {Event} e - The mouse event.
|
|
867
|
+
* @private
|
|
868
|
+
*/
|
|
768
869
|
private handleMouseLeave = (e: Event): void => {
|
|
769
870
|
e.preventDefault()
|
|
770
871
|
e.stopPropagation()
|
|
@@ -778,27 +879,32 @@ export class PageBuilderService {
|
|
|
778
879
|
}
|
|
779
880
|
}
|
|
780
881
|
|
|
882
|
+
/**
|
|
883
|
+
* Checks if an element is editable based on its tag name.
|
|
884
|
+
* @param {Element | null} el - The element to check.
|
|
885
|
+
* @returns {boolean} True if the element is editable, false otherwise.
|
|
886
|
+
*/
|
|
781
887
|
public isEditableElement(el: Element | null): boolean {
|
|
782
888
|
if (!el) return false
|
|
783
889
|
return !this.NoneListernesTags.includes(el.tagName)
|
|
784
890
|
}
|
|
785
891
|
|
|
786
892
|
/**
|
|
787
|
-
*
|
|
788
|
-
*
|
|
893
|
+
* Attaches click, mouseover, and mouseleave event listeners to all editable elements in the page builder.
|
|
894
|
+
* @private
|
|
789
895
|
*/
|
|
790
896
|
private addListenersToEditableElements = async () => {
|
|
791
897
|
const pagebuilder = document.querySelector('#pagebuilder')
|
|
792
898
|
if (!pagebuilder) return
|
|
793
899
|
|
|
794
|
-
// Wait for
|
|
900
|
+
// Wait for the next DOM update cycle to ensure all elements are rendered.
|
|
795
901
|
await nextTick()
|
|
796
902
|
|
|
797
903
|
pagebuilder.querySelectorAll('section *').forEach((element) => {
|
|
798
904
|
if (this.isEditableElement(element)) {
|
|
799
905
|
const htmlElement = element as HTMLElement
|
|
800
906
|
|
|
801
|
-
//
|
|
907
|
+
// If the element already has listeners, remove them to avoid duplicates.
|
|
802
908
|
if (this.elementsWithListeners.has(htmlElement)) {
|
|
803
909
|
const listeners = this.elementsWithListeners.get(htmlElement)
|
|
804
910
|
if (listeners) {
|
|
@@ -808,17 +914,17 @@ export class PageBuilderService {
|
|
|
808
914
|
}
|
|
809
915
|
}
|
|
810
916
|
|
|
811
|
-
// Define new
|
|
917
|
+
// Define new listener functions.
|
|
812
918
|
const clickListener = (e: Event) => this.handleElementClick(e, htmlElement)
|
|
813
919
|
const mouseoverListener = (e: Event) => this.handleMouseOver(e, htmlElement)
|
|
814
920
|
const mouseleaveListener = (e: Event) => this.handleMouseLeave(e)
|
|
815
921
|
|
|
816
|
-
//
|
|
922
|
+
// Add the new event listeners.
|
|
817
923
|
htmlElement.addEventListener('click', clickListener)
|
|
818
924
|
htmlElement.addEventListener('mouseover', mouseoverListener)
|
|
819
925
|
htmlElement.addEventListener('mouseleave', mouseleaveListener)
|
|
820
926
|
|
|
821
|
-
// Store the new listeners in the WeakMap
|
|
927
|
+
// Store the new listeners in the WeakMap to track them.
|
|
822
928
|
this.elementsWithListeners.set(htmlElement, {
|
|
823
929
|
click: clickListener,
|
|
824
930
|
mouseover: mouseoverListener,
|
|
@@ -828,6 +934,12 @@ export class PageBuilderService {
|
|
|
828
934
|
})
|
|
829
935
|
}
|
|
830
936
|
|
|
937
|
+
/**
|
|
938
|
+
* Handles the click event for editable elements, setting the element as selected.
|
|
939
|
+
* @param {Event} e - The click event.
|
|
940
|
+
* @param {HTMLElement} element - The clicked element.
|
|
941
|
+
* @private
|
|
942
|
+
*/
|
|
831
943
|
private handleElementClick = async (e: Event, element: HTMLElement): Promise<void> => {
|
|
832
944
|
e.preventDefault()
|
|
833
945
|
e.stopPropagation()
|
|
@@ -852,6 +964,9 @@ export class PageBuilderService {
|
|
|
852
964
|
await this.handleAutoSave()
|
|
853
965
|
}
|
|
854
966
|
|
|
967
|
+
/**
|
|
968
|
+
* Triggers an auto-save of the current page builder content to local storage if enabled.
|
|
969
|
+
*/
|
|
855
970
|
public handleAutoSave = async () => {
|
|
856
971
|
this.startEditing()
|
|
857
972
|
const passedConfig = this.pageBuilderStateStore.getPageBuilderConfig
|
|
@@ -892,6 +1007,9 @@ export class PageBuilderService {
|
|
|
892
1007
|
}
|
|
893
1008
|
}
|
|
894
1009
|
|
|
1010
|
+
/**
|
|
1011
|
+
* Manually saves the current page builder content to local storage.
|
|
1012
|
+
*/
|
|
895
1013
|
public handleManualSave = async () => {
|
|
896
1014
|
this.pageBuilderStateStore.setIsSaving(true)
|
|
897
1015
|
this.clearHtmlSelection()
|
|
@@ -901,6 +1019,11 @@ export class PageBuilderService {
|
|
|
901
1019
|
this.pageBuilderStateStore.setIsSaving(false)
|
|
902
1020
|
}
|
|
903
1021
|
|
|
1022
|
+
/**
|
|
1023
|
+
* Clones a component object and prepares it for insertion into the DOM by adding unique IDs and prefixes.
|
|
1024
|
+
* @param {ComponentObject} componentObject - The component object to clone.
|
|
1025
|
+
* @returns {ComponentObject} The cloned and prepared component object.
|
|
1026
|
+
*/
|
|
904
1027
|
public cloneCompObjForDOMInsertion(componentObject: ComponentObject): ComponentObject {
|
|
905
1028
|
// Deep clone clone component
|
|
906
1029
|
const clonedComponent = { ...componentObject }
|
|
@@ -961,6 +1084,10 @@ export class PageBuilderService {
|
|
|
961
1084
|
return clonedComponent
|
|
962
1085
|
}
|
|
963
1086
|
|
|
1087
|
+
/**
|
|
1088
|
+
* Removes the 'hovered' and 'selected' attributes from all elements in the page builder.
|
|
1089
|
+
* @private
|
|
1090
|
+
*/
|
|
964
1091
|
private async removeHoveredAndSelected() {
|
|
965
1092
|
const pagebuilder = document.querySelector('#pagebuilder')
|
|
966
1093
|
if (!pagebuilder) return
|
|
@@ -977,6 +1104,10 @@ export class PageBuilderService {
|
|
|
977
1104
|
}
|
|
978
1105
|
}
|
|
979
1106
|
|
|
1107
|
+
/**
|
|
1108
|
+
* Syncs the CSS classes of the currently selected element to the state store.
|
|
1109
|
+
* @private
|
|
1110
|
+
*/
|
|
980
1111
|
private async syncCurrentClasses() {
|
|
981
1112
|
// convert classList to array
|
|
982
1113
|
const classListArray = Array.from(this.getElement.value?.classList || [])
|
|
@@ -985,6 +1116,10 @@ export class PageBuilderService {
|
|
|
985
1116
|
this.pageBuilderStateStore.setCurrentClasses(classListArray)
|
|
986
1117
|
}
|
|
987
1118
|
|
|
1119
|
+
/**
|
|
1120
|
+
* Syncs the inline styles of the currently selected element to the state store.
|
|
1121
|
+
* @private
|
|
1122
|
+
*/
|
|
988
1123
|
private async syncCurrentStyles() {
|
|
989
1124
|
const style = this.getElement.value?.getAttribute('style')
|
|
990
1125
|
if (style) {
|
|
@@ -995,6 +1130,10 @@ export class PageBuilderService {
|
|
|
995
1130
|
}
|
|
996
1131
|
}
|
|
997
1132
|
|
|
1133
|
+
/**
|
|
1134
|
+
* Adds a CSS class to the currently selected element.
|
|
1135
|
+
* @param {string} userSelectedClass - The class to add.
|
|
1136
|
+
*/
|
|
998
1137
|
public handleAddClasses(userSelectedClass: string): void {
|
|
999
1138
|
if (
|
|
1000
1139
|
typeof userSelectedClass === 'string' &&
|
|
@@ -1015,6 +1154,11 @@ export class PageBuilderService {
|
|
|
1015
1154
|
}
|
|
1016
1155
|
}
|
|
1017
1156
|
|
|
1157
|
+
/**
|
|
1158
|
+
* Adds or updates an inline style property on the currently selected element.
|
|
1159
|
+
* @param {string} property - The CSS property to add/update.
|
|
1160
|
+
* @param {string} value - The value of the CSS property.
|
|
1161
|
+
*/
|
|
1018
1162
|
public handleAddStyle(property: string, value: string): void {
|
|
1019
1163
|
const element = this.getElement.value
|
|
1020
1164
|
if (!element || !property || !value) return
|
|
@@ -1023,6 +1167,10 @@ export class PageBuilderService {
|
|
|
1023
1167
|
this.pageBuilderStateStore.setElement(element)
|
|
1024
1168
|
}
|
|
1025
1169
|
|
|
1170
|
+
/**
|
|
1171
|
+
* Removes an inline style property from the currently selected element.
|
|
1172
|
+
* @param {string} property - The CSS property to remove.
|
|
1173
|
+
*/
|
|
1026
1174
|
public handleRemoveStyle(property: string): void {
|
|
1027
1175
|
const element = this.getElement.value
|
|
1028
1176
|
if (!element || !property) return
|
|
@@ -1031,6 +1179,10 @@ export class PageBuilderService {
|
|
|
1031
1179
|
this.pageBuilderStateStore.setElement(element)
|
|
1032
1180
|
}
|
|
1033
1181
|
|
|
1182
|
+
/**
|
|
1183
|
+
* Handles changes to the font family of the selected element.
|
|
1184
|
+
* @param {string} [userSelectedFontFamily] - The selected font family class.
|
|
1185
|
+
*/
|
|
1034
1186
|
public handleFontFamily(userSelectedFontFamily?: string): void {
|
|
1035
1187
|
this.applyElementClassChanges(
|
|
1036
1188
|
userSelectedFontFamily,
|
|
@@ -1038,6 +1190,10 @@ export class PageBuilderService {
|
|
|
1038
1190
|
'setFontFamily',
|
|
1039
1191
|
)
|
|
1040
1192
|
}
|
|
1193
|
+
/**
|
|
1194
|
+
* Handles changes to the font style of the selected element.
|
|
1195
|
+
* @param {string} [userSelectedFontStyle] - The selected font style class.
|
|
1196
|
+
*/
|
|
1041
1197
|
public handleFontStyle(userSelectedFontStyle?: string): void {
|
|
1042
1198
|
this.applyElementClassChanges(
|
|
1043
1199
|
userSelectedFontStyle,
|
|
@@ -1045,6 +1201,10 @@ export class PageBuilderService {
|
|
|
1045
1201
|
'setFontStyle',
|
|
1046
1202
|
)
|
|
1047
1203
|
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Handles changes to the vertical padding of the selected element.
|
|
1206
|
+
* @param {string} [userSelectedVerticalPadding] - The selected vertical padding class.
|
|
1207
|
+
*/
|
|
1048
1208
|
public handleVerticalPadding(userSelectedVerticalPadding?: string): void {
|
|
1049
1209
|
this.applyElementClassChanges(
|
|
1050
1210
|
userSelectedVerticalPadding,
|
|
@@ -1052,6 +1212,10 @@ export class PageBuilderService {
|
|
|
1052
1212
|
'setFontVerticalPadding',
|
|
1053
1213
|
)
|
|
1054
1214
|
}
|
|
1215
|
+
/**
|
|
1216
|
+
* Handles changes to the horizontal padding of the selected element.
|
|
1217
|
+
* @param {string} [userSelectedHorizontalPadding] - The selected horizontal padding class.
|
|
1218
|
+
*/
|
|
1055
1219
|
public handleHorizontalPadding(userSelectedHorizontalPadding?: string): void {
|
|
1056
1220
|
this.applyElementClassChanges(
|
|
1057
1221
|
userSelectedHorizontalPadding,
|
|
@@ -1060,6 +1224,10 @@ export class PageBuilderService {
|
|
|
1060
1224
|
)
|
|
1061
1225
|
}
|
|
1062
1226
|
|
|
1227
|
+
/**
|
|
1228
|
+
* Handles changes to the vertical margin of the selected element.
|
|
1229
|
+
* @param {string} [userSelectedVerticalMargin] - The selected vertical margin class.
|
|
1230
|
+
*/
|
|
1063
1231
|
public handleVerticalMargin(userSelectedVerticalMargin?: string): void {
|
|
1064
1232
|
this.applyElementClassChanges(
|
|
1065
1233
|
userSelectedVerticalMargin,
|
|
@@ -1067,6 +1235,10 @@ export class PageBuilderService {
|
|
|
1067
1235
|
'setFontVerticalMargin',
|
|
1068
1236
|
)
|
|
1069
1237
|
}
|
|
1238
|
+
/**
|
|
1239
|
+
* Handles changes to the horizontal margin of the selected element.
|
|
1240
|
+
* @param {string} [userSelectedHorizontalMargin] - The selected horizontal margin class.
|
|
1241
|
+
*/
|
|
1070
1242
|
public handleHorizontalMargin(userSelectedHorizontalMargin?: string): void {
|
|
1071
1243
|
this.applyElementClassChanges(
|
|
1072
1244
|
userSelectedHorizontalMargin,
|
|
@@ -1075,6 +1247,10 @@ export class PageBuilderService {
|
|
|
1075
1247
|
)
|
|
1076
1248
|
}
|
|
1077
1249
|
|
|
1250
|
+
/**
|
|
1251
|
+
* Handles changes to the border style of the selected element.
|
|
1252
|
+
* @param {string} [borderStyle] - The selected border style class.
|
|
1253
|
+
*/
|
|
1078
1254
|
public handleBorderStyle(borderStyle?: string): void {
|
|
1079
1255
|
this.applyElementClassChanges(
|
|
1080
1256
|
borderStyle,
|
|
@@ -1082,6 +1258,10 @@ export class PageBuilderService {
|
|
|
1082
1258
|
'setBorderStyle',
|
|
1083
1259
|
)
|
|
1084
1260
|
}
|
|
1261
|
+
/**
|
|
1262
|
+
* Handles changes to the border width of the selected element.
|
|
1263
|
+
* @param {string} [borderWidth] - The selected border width class.
|
|
1264
|
+
*/
|
|
1085
1265
|
public handleBorderWidth(borderWidth?: string): void {
|
|
1086
1266
|
this.applyElementClassChanges(
|
|
1087
1267
|
borderWidth,
|
|
@@ -1089,6 +1269,10 @@ export class PageBuilderService {
|
|
|
1089
1269
|
'setBorderWidth',
|
|
1090
1270
|
)
|
|
1091
1271
|
}
|
|
1272
|
+
/**
|
|
1273
|
+
* Handles changes to the border color of the selected element.
|
|
1274
|
+
* @param {string} [borderColor] - The selected border color class.
|
|
1275
|
+
*/
|
|
1092
1276
|
public handleBorderColor(borderColor?: string): void {
|
|
1093
1277
|
this.applyElementClassChanges(
|
|
1094
1278
|
borderColor,
|
|
@@ -1098,6 +1282,10 @@ export class PageBuilderService {
|
|
|
1098
1282
|
}
|
|
1099
1283
|
// border color, style & width / end
|
|
1100
1284
|
|
|
1285
|
+
/**
|
|
1286
|
+
* Handles changes to the background color of the selected element.
|
|
1287
|
+
* @param {string} [color] - The selected background color class.
|
|
1288
|
+
*/
|
|
1101
1289
|
public handleBackgroundColor(color?: string): void {
|
|
1102
1290
|
this.applyElementClassChanges(
|
|
1103
1291
|
color,
|
|
@@ -1106,10 +1294,18 @@ export class PageBuilderService {
|
|
|
1106
1294
|
)
|
|
1107
1295
|
}
|
|
1108
1296
|
|
|
1297
|
+
/**
|
|
1298
|
+
* Handles changes to the text color of the selected element.
|
|
1299
|
+
* @param {string} [color] - The selected text color class.
|
|
1300
|
+
*/
|
|
1109
1301
|
public handleTextColor(color?: string): void {
|
|
1110
1302
|
this.applyElementClassChanges(color, tailwindColors.textColorVariables, 'setTextColor')
|
|
1111
1303
|
}
|
|
1112
1304
|
|
|
1305
|
+
/**
|
|
1306
|
+
* Handles changes to the global border radius of the selected element.
|
|
1307
|
+
* @param {string} [borderRadiusGlobal] - The selected global border radius class.
|
|
1308
|
+
*/
|
|
1113
1309
|
handleBorderRadiusGlobal(borderRadiusGlobal?: string): void {
|
|
1114
1310
|
this.applyElementClassChanges(
|
|
1115
1311
|
borderRadiusGlobal,
|
|
@@ -1117,6 +1313,10 @@ export class PageBuilderService {
|
|
|
1117
1313
|
'setBorderRadiusGlobal',
|
|
1118
1314
|
)
|
|
1119
1315
|
}
|
|
1316
|
+
/**
|
|
1317
|
+
* Handles changes to the top-left border radius of the selected element.
|
|
1318
|
+
* @param {string} [borderRadiusTopLeft] - The selected top-left border radius class.
|
|
1319
|
+
*/
|
|
1120
1320
|
handleBorderRadiusTopLeft(borderRadiusTopLeft?: string): void {
|
|
1121
1321
|
this.applyElementClassChanges(
|
|
1122
1322
|
borderRadiusTopLeft,
|
|
@@ -1124,6 +1324,10 @@ export class PageBuilderService {
|
|
|
1124
1324
|
'setBorderRadiusTopLeft',
|
|
1125
1325
|
)
|
|
1126
1326
|
}
|
|
1327
|
+
/**
|
|
1328
|
+
* Handles changes to the top-right border radius of the selected element.
|
|
1329
|
+
* @param {string} [borderRadiusTopRight] - The selected top-right border radius class.
|
|
1330
|
+
*/
|
|
1127
1331
|
handleBorderRadiusTopRight(borderRadiusTopRight?: string): void {
|
|
1128
1332
|
this.applyElementClassChanges(
|
|
1129
1333
|
borderRadiusTopRight,
|
|
@@ -1131,6 +1335,10 @@ export class PageBuilderService {
|
|
|
1131
1335
|
'setBorderRadiusTopRight',
|
|
1132
1336
|
)
|
|
1133
1337
|
}
|
|
1338
|
+
/**
|
|
1339
|
+
* Handles changes to the bottom-left border radius of the selected element.
|
|
1340
|
+
* @param {string} [borderRadiusBottomleft] - The selected bottom-left border radius class.
|
|
1341
|
+
*/
|
|
1134
1342
|
handleBorderRadiusBottomleft(borderRadiusBottomleft?: string): void {
|
|
1135
1343
|
this.applyElementClassChanges(
|
|
1136
1344
|
borderRadiusBottomleft,
|
|
@@ -1138,6 +1346,10 @@ export class PageBuilderService {
|
|
|
1138
1346
|
'setBorderRadiusBottomleft',
|
|
1139
1347
|
)
|
|
1140
1348
|
}
|
|
1349
|
+
/**
|
|
1350
|
+
* Handles changes to the bottom-right border radius of the selected element.
|
|
1351
|
+
* @param {string} [borderRadiusBottomRight] - The selected bottom-right border radius class.
|
|
1352
|
+
*/
|
|
1141
1353
|
handleBorderRadiusBottomRight(borderRadiusBottomRight?: string): void {
|
|
1142
1354
|
this.applyElementClassChanges(
|
|
1143
1355
|
borderRadiusBottomRight,
|
|
@@ -1147,6 +1359,10 @@ export class PageBuilderService {
|
|
|
1147
1359
|
}
|
|
1148
1360
|
// border radius / end
|
|
1149
1361
|
|
|
1362
|
+
/**
|
|
1363
|
+
* Handles changes to the tablet font size of the selected element.
|
|
1364
|
+
* @param {string} [userSelectedFontSize] - The selected font size class for tablet.
|
|
1365
|
+
*/
|
|
1150
1366
|
handleFontSizeTablet(userSelectedFontSize?: string): void {
|
|
1151
1367
|
this.applyElementClassChanges(
|
|
1152
1368
|
userSelectedFontSize,
|
|
@@ -1154,6 +1370,10 @@ export class PageBuilderService {
|
|
|
1154
1370
|
'setFontTablet',
|
|
1155
1371
|
)
|
|
1156
1372
|
}
|
|
1373
|
+
/**
|
|
1374
|
+
* Handles changes to the mobile font size of the selected element.
|
|
1375
|
+
* @param {string} [userSelectedFontSize] - The selected font size class for mobile.
|
|
1376
|
+
*/
|
|
1157
1377
|
handleFontSizeMobile(userSelectedFontSize?: string): void {
|
|
1158
1378
|
this.applyElementClassChanges(
|
|
1159
1379
|
userSelectedFontSize,
|
|
@@ -1162,6 +1382,10 @@ export class PageBuilderService {
|
|
|
1162
1382
|
)
|
|
1163
1383
|
}
|
|
1164
1384
|
|
|
1385
|
+
/**
|
|
1386
|
+
* Handles changes to the background opacity of the selected element.
|
|
1387
|
+
* @param {string} [opacity] - The selected background opacity class.
|
|
1388
|
+
*/
|
|
1165
1389
|
handleBackgroundOpacity(opacity?: string): void {
|
|
1166
1390
|
this.applyElementClassChanges(
|
|
1167
1391
|
opacity,
|
|
@@ -1169,20 +1393,18 @@ export class PageBuilderService {
|
|
|
1169
1393
|
'setBackgroundOpacity',
|
|
1170
1394
|
)
|
|
1171
1395
|
}
|
|
1396
|
+
/**
|
|
1397
|
+
* Handles changes to the opacity of the selected element.
|
|
1398
|
+
* @param {string} [opacity] - The selected opacity class.
|
|
1399
|
+
*/
|
|
1172
1400
|
handleOpacity(opacity?: string): void {
|
|
1173
1401
|
this.applyElementClassChanges(opacity, tailwindOpacities.opacities, 'setOpacity')
|
|
1174
1402
|
}
|
|
1175
1403
|
|
|
1176
1404
|
/**
|
|
1177
1405
|
* Removes all components from both the builder state and the DOM.
|
|
1178
|
-
*
|
|
1179
|
-
* - First clears the components array in the store.
|
|
1180
|
-
* - Then, as a defensive measure, also manually removes all sections elements from the DOM.
|
|
1181
|
-
*
|
|
1182
|
-
* This manual DOM clearing is only optional
|
|
1183
|
-
*
|
|
1406
|
+
* @private
|
|
1184
1407
|
*/
|
|
1185
|
-
|
|
1186
1408
|
private deleteAllComponentsFromDOM() {
|
|
1187
1409
|
// Clear the store
|
|
1188
1410
|
this.pageBuilderStateStore.setComponents([])
|
|
@@ -1197,6 +1419,10 @@ export class PageBuilderService {
|
|
|
1197
1419
|
}
|
|
1198
1420
|
}
|
|
1199
1421
|
|
|
1422
|
+
/**
|
|
1423
|
+
* Deletes the currently selected component from the DOM and the state.
|
|
1424
|
+
* @returns {Promise<void>}
|
|
1425
|
+
*/
|
|
1200
1426
|
public async deleteComponentFromDOM() {
|
|
1201
1427
|
this.syncDomToStoreOnly()
|
|
1202
1428
|
await nextTick()
|
|
@@ -1205,17 +1431,17 @@ export class PageBuilderService {
|
|
|
1205
1431
|
|
|
1206
1432
|
if (!components) return
|
|
1207
1433
|
|
|
1208
|
-
// Find the index of the component to
|
|
1434
|
+
// Find the index of the component to be deleted.
|
|
1209
1435
|
const indexToDelete = components.findIndex(
|
|
1210
1436
|
(component) => component.id === this.getComponent.value?.id,
|
|
1211
1437
|
)
|
|
1212
1438
|
|
|
1213
1439
|
if (indexToDelete === -1) {
|
|
1214
|
-
//
|
|
1440
|
+
// If the component is not found, do nothing.
|
|
1215
1441
|
return
|
|
1216
1442
|
}
|
|
1217
1443
|
|
|
1218
|
-
// Create a new array
|
|
1444
|
+
// Create a new array excluding the component to be deleted.
|
|
1219
1445
|
const newComponents = [
|
|
1220
1446
|
...components.slice(0, indexToDelete),
|
|
1221
1447
|
...components.slice(indexToDelete + 1),
|
|
@@ -1223,7 +1449,7 @@ export class PageBuilderService {
|
|
|
1223
1449
|
|
|
1224
1450
|
this.pageBuilderStateStore.setComponents(newComponents)
|
|
1225
1451
|
|
|
1226
|
-
// Remove the section from the DOM
|
|
1452
|
+
// Remove the component's corresponding section from the DOM.
|
|
1227
1453
|
const pagebuilder = document.querySelector('#pagebuilder')
|
|
1228
1454
|
if (pagebuilder && this.getComponent.value?.id) {
|
|
1229
1455
|
const section = pagebuilder.querySelector(
|
|
@@ -1232,22 +1458,26 @@ export class PageBuilderService {
|
|
|
1232
1458
|
if (section) section.remove()
|
|
1233
1459
|
}
|
|
1234
1460
|
|
|
1235
|
-
// Wait for
|
|
1461
|
+
// Wait for the DOM to update before re-attaching event listeners.
|
|
1236
1462
|
await nextTick()
|
|
1237
1463
|
await this.addListenersToEditableElements()
|
|
1238
1464
|
|
|
1239
1465
|
this.pageBuilderStateStore.setComponent(null)
|
|
1240
1466
|
this.pageBuilderStateStore.setElement(null)
|
|
1241
1467
|
|
|
1242
|
-
//
|
|
1468
|
+
// Trigger an auto-save after deletion.
|
|
1243
1469
|
await this.handleAutoSave()
|
|
1244
1470
|
}
|
|
1245
1471
|
|
|
1472
|
+
/**
|
|
1473
|
+
* Deletes the currently selected element from the DOM and stores it for potential restoration.
|
|
1474
|
+
* @returns {Promise<void>}
|
|
1475
|
+
*/
|
|
1246
1476
|
public async deleteElementFromDOM() {
|
|
1247
1477
|
const element = this.getElement.value
|
|
1248
1478
|
if (!element) return
|
|
1249
1479
|
|
|
1250
|
-
// Remove 'selected' attribute before deletion
|
|
1480
|
+
// Remove the 'selected' attribute before deletion to avoid visual artifacts.
|
|
1251
1481
|
element.removeAttribute('selected')
|
|
1252
1482
|
|
|
1253
1483
|
if (!element.parentNode) {
|
|
@@ -1256,56 +1486,64 @@ export class PageBuilderService {
|
|
|
1256
1486
|
return
|
|
1257
1487
|
}
|
|
1258
1488
|
|
|
1259
|
-
// If the element is
|
|
1489
|
+
// If the element is not a top-level section, store its information for undo functionality.
|
|
1260
1490
|
if (element.parentElement?.tagName !== 'SECTION') {
|
|
1261
1491
|
this.pageBuilderStateStore.setParentElement(element.parentNode as HTMLElement)
|
|
1262
1492
|
this.pageBuilderStateStore.setRestoredElement(element.outerHTML)
|
|
1263
1493
|
this.pageBuilderStateStore.setNextSibling(element.nextSibling as HTMLElement | null)
|
|
1264
|
-
// Remove
|
|
1494
|
+
// Remove the element from the DOM.
|
|
1265
1495
|
element.remove()
|
|
1266
1496
|
}
|
|
1267
1497
|
|
|
1268
|
-
// Clear selection state
|
|
1498
|
+
// Clear the selection state.
|
|
1269
1499
|
this.pageBuilderStateStore.setComponent(null)
|
|
1270
1500
|
this.pageBuilderStateStore.setElement(null)
|
|
1271
1501
|
|
|
1272
|
-
// Deselect any selected or hovered elements in the builder UI
|
|
1502
|
+
// Deselect any selected or hovered elements in the builder UI.
|
|
1273
1503
|
await this.clearHtmlSelection()
|
|
1274
|
-
// Wait for
|
|
1504
|
+
// Wait for the DOM to update before re-attaching event listeners.
|
|
1275
1505
|
await nextTick()
|
|
1276
|
-
//
|
|
1506
|
+
// Re-attach event listeners to all editable elements.
|
|
1277
1507
|
await this.addListenersToEditableElements()
|
|
1278
1508
|
}
|
|
1279
1509
|
|
|
1510
|
+
/**
|
|
1511
|
+
* Restores the last deleted element to its previous position in the DOM.
|
|
1512
|
+
* @returns {Promise<void>}
|
|
1513
|
+
*/
|
|
1280
1514
|
public async restoreDeletedElementToDOM() {
|
|
1281
|
-
//
|
|
1515
|
+
// Retrieve the details of the element to be restored.
|
|
1282
1516
|
const restoredHTML = this.getRestoredElement.value
|
|
1283
1517
|
const parent = this.getParentElement.value
|
|
1284
1518
|
const nextSibling = this.getNextSibling.value
|
|
1285
1519
|
|
|
1286
1520
|
if (restoredHTML && parent) {
|
|
1287
|
-
// Create a container
|
|
1521
|
+
// Create a temporary container to parse the stored HTML.
|
|
1288
1522
|
const container = document.createElement('div')
|
|
1289
1523
|
container.innerHTML = restoredHTML
|
|
1290
1524
|
|
|
1291
|
-
// Insert the restored element
|
|
1525
|
+
// Insert the restored element back into its original position.
|
|
1292
1526
|
if (container.firstChild) {
|
|
1293
1527
|
parent.insertBefore(container.firstChild, nextSibling)
|
|
1294
1528
|
}
|
|
1295
1529
|
}
|
|
1296
1530
|
|
|
1297
|
-
// Clear
|
|
1531
|
+
// Clear the state related to the restored element.
|
|
1298
1532
|
this.pageBuilderStateStore.setParentElement(null)
|
|
1299
1533
|
this.pageBuilderStateStore.setRestoredElement(null)
|
|
1300
1534
|
this.pageBuilderStateStore.setNextSibling(null)
|
|
1301
1535
|
this.pageBuilderStateStore.setComponent(null)
|
|
1302
1536
|
this.pageBuilderStateStore.setElement(null)
|
|
1303
1537
|
|
|
1304
|
-
// Wait for
|
|
1538
|
+
// Wait for the DOM to update before re-attaching event listeners.
|
|
1305
1539
|
await nextTick()
|
|
1306
1540
|
await this.addListenersToEditableElements()
|
|
1307
1541
|
}
|
|
1308
1542
|
|
|
1543
|
+
/**
|
|
1544
|
+
* Removes a CSS class from the currently selected element.
|
|
1545
|
+
* @param {string} userSelectedClass - The class to remove.
|
|
1546
|
+
*/
|
|
1309
1547
|
public handleRemoveClasses(userSelectedClass: string): void {
|
|
1310
1548
|
// remove selected class from element
|
|
1311
1549
|
if (this.getElement.value?.classList.contains(userSelectedClass)) {
|
|
@@ -1316,38 +1554,43 @@ export class PageBuilderService {
|
|
|
1316
1554
|
}
|
|
1317
1555
|
}
|
|
1318
1556
|
|
|
1319
|
-
|
|
1320
|
-
|
|
1557
|
+
/**
|
|
1558
|
+
* Reorders the currently selected component up or down in the component list.
|
|
1559
|
+
* @param {number} direction - The direction to move the component (-1 for up, 1 for down).
|
|
1560
|
+
*/
|
|
1321
1561
|
public reorderComponent(direction: number): void {
|
|
1322
1562
|
if (!this.getComponents.value || !this.getComponent.value) return
|
|
1323
1563
|
|
|
1324
1564
|
if (this.getComponents.value.length <= 1) return
|
|
1325
1565
|
|
|
1326
|
-
//
|
|
1566
|
+
// Find the component to move.
|
|
1327
1567
|
const componentToMove = this.getComponent.value
|
|
1328
1568
|
|
|
1329
|
-
// Determine the
|
|
1569
|
+
// Determine the current index of the component.
|
|
1330
1570
|
const currentIndex = this.getComponents.value.findIndex(
|
|
1331
1571
|
(component) => component.id === componentToMove.id,
|
|
1332
1572
|
)
|
|
1333
1573
|
|
|
1334
1574
|
if (currentIndex === -1) {
|
|
1335
|
-
// Component not found in the array
|
|
1575
|
+
// Component not found in the array.
|
|
1336
1576
|
return
|
|
1337
1577
|
}
|
|
1338
1578
|
|
|
1339
1579
|
const newIndex = currentIndex + direction
|
|
1340
1580
|
|
|
1341
|
-
// Ensure the
|
|
1581
|
+
// Ensure the new index is within the bounds of the array.
|
|
1342
1582
|
if (newIndex < 0 || newIndex >= this.getComponents.value.length) {
|
|
1343
1583
|
return
|
|
1344
1584
|
}
|
|
1345
1585
|
|
|
1346
|
-
// Move the component to the new position
|
|
1586
|
+
// Move the component to the new position in the array.
|
|
1347
1587
|
this.getComponents.value.splice(currentIndex, 1)
|
|
1348
1588
|
this.getComponents.value.splice(newIndex, 0, componentToMove)
|
|
1349
1589
|
}
|
|
1350
1590
|
|
|
1591
|
+
/**
|
|
1592
|
+
* Ensures that a text area element has content, adding a visual indicator if it's empty.
|
|
1593
|
+
*/
|
|
1351
1594
|
public ensureTextAreaHasContent = () => {
|
|
1352
1595
|
if (!this.getElement.value) return
|
|
1353
1596
|
|
|
@@ -1372,6 +1615,11 @@ export class PageBuilderService {
|
|
|
1372
1615
|
}
|
|
1373
1616
|
}
|
|
1374
1617
|
|
|
1618
|
+
/**
|
|
1619
|
+
* Handles text input for an element, updating its content.
|
|
1620
|
+
* @param {string} textContentVueModel - The new text content from the Vue model.
|
|
1621
|
+
* @returns {Promise<void>}
|
|
1622
|
+
*/
|
|
1375
1623
|
public handleTextInput = async (textContentVueModel: string): Promise<void> => {
|
|
1376
1624
|
if (typeof this.getElement.value?.innerHTML !== 'string') {
|
|
1377
1625
|
return
|
|
@@ -1391,8 +1639,10 @@ export class PageBuilderService {
|
|
|
1391
1639
|
this.ensureTextAreaHasContent()
|
|
1392
1640
|
}
|
|
1393
1641
|
|
|
1394
|
-
|
|
1395
|
-
|
|
1642
|
+
/**
|
|
1643
|
+
* Checks if the selected element or its first child is an iframe.
|
|
1644
|
+
* @returns {boolean} True if it is an iframe, false otherwise.
|
|
1645
|
+
*/
|
|
1396
1646
|
public ElOrFirstChildIsIframe() {
|
|
1397
1647
|
if (
|
|
1398
1648
|
this.getElement.value?.tagName === 'IFRAME' ||
|
|
@@ -1403,9 +1653,10 @@ export class PageBuilderService {
|
|
|
1403
1653
|
return false
|
|
1404
1654
|
}
|
|
1405
1655
|
}
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1656
|
+
/**
|
|
1657
|
+
* Checks if the selected element is a valid text container (i.e., does not contain images or divs).
|
|
1658
|
+
* @returns {boolean | undefined} True if it's a valid text element, otherwise undefined.
|
|
1659
|
+
*/
|
|
1409
1660
|
public isSelectedElementValidText() {
|
|
1410
1661
|
let reachedElseStatement = false
|
|
1411
1662
|
|
|
@@ -1432,6 +1683,9 @@ export class PageBuilderService {
|
|
|
1432
1683
|
return reachedElseStatement
|
|
1433
1684
|
}
|
|
1434
1685
|
|
|
1686
|
+
/**
|
|
1687
|
+
* Generates a preview of the current page design.
|
|
1688
|
+
*/
|
|
1435
1689
|
public previewCurrentDesign() {
|
|
1436
1690
|
this.pageBuilderStateStore.setElement(null)
|
|
1437
1691
|
|
|
@@ -1453,7 +1707,11 @@ export class PageBuilderService {
|
|
|
1453
1707
|
this.pageBuilderStateStore.setCurrentLayoutPreview(previewData)
|
|
1454
1708
|
}
|
|
1455
1709
|
}
|
|
1456
|
-
|
|
1710
|
+
/**
|
|
1711
|
+
* Sanitizes a string to be used as a key in local storage.
|
|
1712
|
+
* @param {string} input - The string to sanitize.
|
|
1713
|
+
* @returns {string} The sanitized string.
|
|
1714
|
+
*/
|
|
1457
1715
|
public sanitizeForLocalStorage(input: string): string {
|
|
1458
1716
|
return input
|
|
1459
1717
|
.trim() // Remove leading/trailing spaces
|
|
@@ -1465,9 +1723,10 @@ export class PageBuilderService {
|
|
|
1465
1723
|
}
|
|
1466
1724
|
|
|
1467
1725
|
/**
|
|
1468
|
-
*
|
|
1469
|
-
*
|
|
1470
|
-
* @
|
|
1726
|
+
* Clones an element and removes selection-related attributes from the clone.
|
|
1727
|
+
* @param {HTMLElement} element - The element to clone.
|
|
1728
|
+
* @returns {HTMLElement} The sanitized clone.
|
|
1729
|
+
* @private
|
|
1471
1730
|
*/
|
|
1472
1731
|
private cloneAndRemoveSelectionAttributes(element: HTMLElement): HTMLElement {
|
|
1473
1732
|
// Deep clone the element
|
|
@@ -1484,8 +1743,8 @@ export class PageBuilderService {
|
|
|
1484
1743
|
}
|
|
1485
1744
|
|
|
1486
1745
|
/**
|
|
1487
|
-
* Syncs the current DOM state
|
|
1488
|
-
*
|
|
1746
|
+
* Syncs the current DOM state of components to the in-memory store.
|
|
1747
|
+
* @private
|
|
1489
1748
|
*/
|
|
1490
1749
|
private syncDomToStoreOnly() {
|
|
1491
1750
|
const pagebuilder = document.querySelector('#pagebuilder')
|
|
@@ -1506,7 +1765,8 @@ export class PageBuilderService {
|
|
|
1506
1765
|
}
|
|
1507
1766
|
|
|
1508
1767
|
/**
|
|
1509
|
-
* Saves the current DOM state
|
|
1768
|
+
* Saves the current DOM state of components to local storage.
|
|
1769
|
+
* @private
|
|
1510
1770
|
*/
|
|
1511
1771
|
private saveDomComponentsToLocalStorage() {
|
|
1512
1772
|
this.updateLocalStorageItemName()
|
|
@@ -1546,6 +1806,10 @@ export class PageBuilderService {
|
|
|
1546
1806
|
localStorage.setItem(keyForSavingFromDomToLocal, JSON.stringify(dataToSave))
|
|
1547
1807
|
}
|
|
1548
1808
|
}
|
|
1809
|
+
/**
|
|
1810
|
+
* Removes the current page's components from local storage.
|
|
1811
|
+
* @private
|
|
1812
|
+
*/
|
|
1549
1813
|
private async removeCurrentComponentsFromLocalStorage() {
|
|
1550
1814
|
this.updateLocalStorageItemName()
|
|
1551
1815
|
await nextTick()
|
|
@@ -1556,12 +1820,22 @@ export class PageBuilderService {
|
|
|
1556
1820
|
}
|
|
1557
1821
|
}
|
|
1558
1822
|
|
|
1823
|
+
/**
|
|
1824
|
+
* Handles the form submission process, clearing local storage and the DOM.
|
|
1825
|
+
* @returns {Promise<void>}
|
|
1826
|
+
*/
|
|
1559
1827
|
public async handleFormSubmission() {
|
|
1560
1828
|
await this.removeCurrentComponentsFromLocalStorage()
|
|
1561
1829
|
this.deleteAllComponentsFromDOM()
|
|
1562
1830
|
this.pageBuilderStateStore.setComponents([])
|
|
1563
1831
|
}
|
|
1564
1832
|
|
|
1833
|
+
/**
|
|
1834
|
+
* Parses a CSS style string into a key-value object.
|
|
1835
|
+
* @param {string} style - The style string to parse.
|
|
1836
|
+
* @returns {Record<string, string>} The parsed style object.
|
|
1837
|
+
* @private
|
|
1838
|
+
*/
|
|
1565
1839
|
private parseStyleString(style: string): Record<string, string> {
|
|
1566
1840
|
return style
|
|
1567
1841
|
.split(';')
|
|
@@ -1577,6 +1851,9 @@ export class PageBuilderService {
|
|
|
1577
1851
|
)
|
|
1578
1852
|
}
|
|
1579
1853
|
|
|
1854
|
+
/**
|
|
1855
|
+
* Deletes old page builder data from local storage (older than 2 weeks).
|
|
1856
|
+
*/
|
|
1580
1857
|
deleteOldPageBuilderLocalStorage(): void {
|
|
1581
1858
|
const config = this.pageBuilderStateStore.getPageBuilderConfig
|
|
1582
1859
|
const formType = config && config.updateOrCreate && config.updateOrCreate.formType
|
|
@@ -1629,12 +1906,17 @@ export class PageBuilderService {
|
|
|
1629
1906
|
}
|
|
1630
1907
|
}
|
|
1631
1908
|
|
|
1632
|
-
|
|
1909
|
+
/**
|
|
1910
|
+
* Sets a flag to indicate that the user has started editing.
|
|
1911
|
+
*/
|
|
1633
1912
|
public startEditing() {
|
|
1634
1913
|
this.hasStartedEditing = true
|
|
1635
1914
|
}
|
|
1636
1915
|
|
|
1637
|
-
|
|
1916
|
+
/**
|
|
1917
|
+
* Resumes editing from a draft saved in local storage.
|
|
1918
|
+
* @returns {Promise<void>}
|
|
1919
|
+
*/
|
|
1638
1920
|
public async resumeEditingFromDraft() {
|
|
1639
1921
|
this.updateLocalStorageItemName()
|
|
1640
1922
|
|
|
@@ -1655,6 +1937,10 @@ export class PageBuilderService {
|
|
|
1655
1937
|
this.pageBuilderStateStore.setIsLoadingResumeEditing(false)
|
|
1656
1938
|
}
|
|
1657
1939
|
|
|
1940
|
+
/**
|
|
1941
|
+
* Restores the original content that was loaded when the builder started.
|
|
1942
|
+
* @returns {Promise<void>}
|
|
1943
|
+
*/
|
|
1658
1944
|
public async restoreOriginalContent() {
|
|
1659
1945
|
this.updateLocalStorageItemName()
|
|
1660
1946
|
|
|
@@ -1677,10 +1963,18 @@ export class PageBuilderService {
|
|
|
1677
1963
|
this.pageBuilderStateStore.setIsRestoring(false)
|
|
1678
1964
|
}
|
|
1679
1965
|
|
|
1966
|
+
/**
|
|
1967
|
+
* Gets the local storage key for the current resource.
|
|
1968
|
+
* @returns {string | null} The local storage key.
|
|
1969
|
+
*/
|
|
1680
1970
|
public getStorageItemNameForResource(): string | null {
|
|
1681
1971
|
return this.getLocalStorageItemName.value
|
|
1682
1972
|
}
|
|
1683
1973
|
|
|
1974
|
+
/**
|
|
1975
|
+
* Retrieves the saved page HTML from local storage.
|
|
1976
|
+
* @returns {string | false} The HTML string or false if not found.
|
|
1977
|
+
*/
|
|
1684
1978
|
public getSavedPageHtml() {
|
|
1685
1979
|
if (!this.getLocalStorageItemName.value) return false
|
|
1686
1980
|
|
|
@@ -1704,9 +1998,9 @@ export class PageBuilderService {
|
|
|
1704
1998
|
}
|
|
1705
1999
|
|
|
1706
2000
|
/**
|
|
1707
|
-
* Applies
|
|
1708
|
-
*
|
|
1709
|
-
*
|
|
2001
|
+
* Applies a selected image to the current element.
|
|
2002
|
+
* @param {ImageObject} image - The image object to apply.
|
|
2003
|
+
* @returns {Promise<void>}
|
|
1710
2004
|
*/
|
|
1711
2005
|
public async applySelectedImage(image: ImageObject): Promise<void> {
|
|
1712
2006
|
this.pageBuilderStateStore.setApplyImageToSelection(image)
|
|
@@ -1723,9 +2017,8 @@ export class PageBuilderService {
|
|
|
1723
2017
|
}
|
|
1724
2018
|
|
|
1725
2019
|
/**
|
|
1726
|
-
*
|
|
1727
|
-
*
|
|
1728
|
-
* If the element does not meet these criteria, clears the base primary image.
|
|
2020
|
+
* Sets the base primary image from the currently selected element if it's an image.
|
|
2021
|
+
* @private
|
|
1729
2022
|
*/
|
|
1730
2023
|
private setBasePrimaryImageFromSelectedElement() {
|
|
1731
2024
|
if (!this.getElement.value) return
|
|
@@ -1747,6 +2040,13 @@ export class PageBuilderService {
|
|
|
1747
2040
|
this.pageBuilderStateStore.setBasePrimaryImage(null)
|
|
1748
2041
|
}
|
|
1749
2042
|
|
|
2043
|
+
/**
|
|
2044
|
+
* Adds or removes a hyperlink from the selected element.
|
|
2045
|
+
* @param {boolean} hyperlinkEnable - Whether to enable or disable the hyperlink.
|
|
2046
|
+
* @param {string | null} urlInput - The URL for the hyperlink.
|
|
2047
|
+
* @param {boolean} openHyperlinkInNewTab - Whether the link should open in a new tab.
|
|
2048
|
+
* @private
|
|
2049
|
+
*/
|
|
1750
2050
|
private addHyperlinkToElement(
|
|
1751
2051
|
hyperlinkEnable: boolean,
|
|
1752
2052
|
urlInput: string | null,
|
|
@@ -1843,6 +2143,10 @@ export class PageBuilderService {
|
|
|
1843
2143
|
}
|
|
1844
2144
|
}
|
|
1845
2145
|
|
|
2146
|
+
/**
|
|
2147
|
+
* Checks if the selected element contains a hyperlink and updates the state accordingly.
|
|
2148
|
+
* @private
|
|
2149
|
+
*/
|
|
1846
2150
|
private checkForHyperlink() {
|
|
1847
2151
|
if (!this.getElement.value) return
|
|
1848
2152
|
|
|
@@ -1871,6 +2175,12 @@ export class PageBuilderService {
|
|
|
1871
2175
|
this.pageBuilderStateStore.setHyberlinkEnable(false)
|
|
1872
2176
|
}
|
|
1873
2177
|
|
|
2178
|
+
/**
|
|
2179
|
+
* Handles all hyperlink-related actions for the selected element.
|
|
2180
|
+
* @param {boolean} [hyperlinkEnable] - Whether to enable or disable the hyperlink.
|
|
2181
|
+
* @param {string | null} [urlInput] - The URL for the hyperlink.
|
|
2182
|
+
* @param {boolean} [openHyperlinkInNewTab] - Whether the link should open in a new tab.
|
|
2183
|
+
*/
|
|
1874
2184
|
public handleHyperlink(
|
|
1875
2185
|
hyperlinkEnable?: boolean,
|
|
1876
2186
|
urlInput?: string | null,
|
|
@@ -1916,7 +2226,11 @@ export class PageBuilderService {
|
|
|
1916
2226
|
this.addHyperlinkToElement(hyperlinkEnable, urlInput || null, openHyperlinkInNewTab || false)
|
|
1917
2227
|
}
|
|
1918
2228
|
|
|
1919
|
-
|
|
2229
|
+
/**
|
|
2230
|
+
* Adds a new component to the page builder.
|
|
2231
|
+
* @param {ComponentObject} componentObject - The component to add.
|
|
2232
|
+
* @returns {Promise<void>}
|
|
2233
|
+
*/
|
|
1920
2234
|
public async addComponent(componentObject: ComponentObject): Promise<void> {
|
|
1921
2235
|
try {
|
|
1922
2236
|
const clonedComponent = this.cloneCompObjForDOMInsertion({
|
|
@@ -1956,10 +2270,12 @@ export class PageBuilderService {
|
|
|
1956
2270
|
}
|
|
1957
2271
|
|
|
1958
2272
|
/**
|
|
1959
|
-
*
|
|
1960
|
-
*
|
|
2273
|
+
* Adds a prefix to Tailwind CSS classes in a string.
|
|
2274
|
+
* @param {string} classList - The string of classes.
|
|
2275
|
+
* @param {string} [prefix='pbx-'] - The prefix to add.
|
|
2276
|
+
* @returns {string} The prefixed class string.
|
|
2277
|
+
* @private
|
|
1961
2278
|
*/
|
|
1962
|
-
|
|
1963
2279
|
private addTailwindPrefixToClasses(classList: string, prefix = 'pbx-'): string {
|
|
1964
2280
|
return classList
|
|
1965
2281
|
.split(/\s+/)
|
|
@@ -1974,6 +2290,12 @@ export class PageBuilderService {
|
|
|
1974
2290
|
.join(' ')
|
|
1975
2291
|
}
|
|
1976
2292
|
|
|
2293
|
+
/**
|
|
2294
|
+
* Converts a style object to a CSS string.
|
|
2295
|
+
* @param {string | Record<string, string> | null | undefined} styleObj - The style object.
|
|
2296
|
+
* @returns {string} The CSS style string.
|
|
2297
|
+
* @private
|
|
2298
|
+
*/
|
|
1977
2299
|
private convertStyleObjectToString(
|
|
1978
2300
|
styleObj: string | Record<string, string> | null | undefined,
|
|
1979
2301
|
): string {
|
|
@@ -1990,8 +2312,6 @@ export class PageBuilderService {
|
|
|
1990
2312
|
|
|
1991
2313
|
/**
|
|
1992
2314
|
* Parses a string of HTML and extracts builder components and global page settings.
|
|
1993
|
-
*
|
|
1994
|
-
* ⚠️ **Important:**
|
|
1995
2315
|
* - This method expects an **HTML string** containing one or more `<section>...</section>` elements (such as the output from `getSavedPageHtml()` or a previously saved builder HTML string).
|
|
1996
2316
|
* - **Do NOT pass a JSON string** (such as the result of `JSON.stringify(componentsArray)`) to this method. Passing a JSON string to `DOMParser.parseFromString(..., 'text/html')` will not produce valid DOM nodes. Instead, it will treat the JSON as plain text, resulting in a `<html><head></head><body>{...json...}</body></html>` structure, not real HTML elements.
|
|
1997
2317
|
* - If you pass a JSON string, you will see lots of `\n` and strange HTML, because the parser is just wrapping your JSON in a `<body>` tag as text.
|
|
@@ -2472,6 +2792,9 @@ export class PageBuilderService {
|
|
|
2472
2792
|
}
|
|
2473
2793
|
}
|
|
2474
2794
|
|
|
2795
|
+
/**
|
|
2796
|
+
* Initializes the styles for the currently selected element.
|
|
2797
|
+
*/
|
|
2475
2798
|
public async initializeElementStyles(): Promise<void> {
|
|
2476
2799
|
// Wait for Vue to finish DOM updates before attaching event listeners.
|
|
2477
2800
|
// This ensures elements exist in the DOM.
|