@myissue/vue-website-page-builder 3.0.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/LICENSE +21 -0
- package/README.md +470 -0
- package/dist/android-chrome-192x192.png +0 -0
- package/dist/android-chrome-512x512.png +0 -0
- package/dist/apple-touch-icon.png +0 -0
- package/dist/browserconfig.xml +9 -0
- package/dist/components.json +36 -0
- package/dist/favicon-16x16.png +0 -0
- package/dist/favicon-32x32.png +0 -0
- package/dist/favicon.ico +0 -0
- package/dist/home/features.jpg +0 -0
- package/dist/home/page-builder-example.jpg +0 -0
- package/dist/logo/logo.svg +49 -0
- package/dist/mstile-310x150.png +0 -0
- package/dist/mstile-310x310.png +0 -0
- package/dist/page-builder/2-images-text-top.png +0 -0
- package/dist/page-builder/2-images.png +0 -0
- package/dist/page-builder/3-images.png +0 -0
- package/dist/page-builder/6-images.png +0 -0
- package/dist/page-builder/image.png +0 -0
- package/dist/page-builder/placeholder.jpg +0 -0
- package/dist/page-builder/two-vertical-images.png +0 -0
- package/dist/placeholder_image.jpg +0 -0
- package/dist/robots.txt +2 -0
- package/dist/vue-website-page-builder.css +1 -0
- package/dist/vue-website-page-builder.js +24794 -0
- package/dist/vue-website-page-builder.umd.cjs +195 -0
- package/package.json +99 -0
- package/src/App.vue +122 -0
- package/src/Components/Homepage/Footer.vue +42 -0
- package/src/Components/Homepage/HomeSection.vue +540 -0
- package/src/Components/Homepage/Navbar.vue +30 -0
- package/src/Components/Layouts/FullWidthElement.vue +34 -0
- package/src/Components/Loaders/FullScreenSpinner.vue +13 -0
- package/src/Components/Loaders/SmallUniversalSpinner.vue +26 -0
- package/src/Components/MediaLibrary/SidebarUnsplash.vue +40 -0
- package/src/Components/MediaLibrary/Unsplash.vue +306 -0
- package/src/Components/Modals/DynamicModal.vue +476 -0
- package/src/Components/Modals/MediaLibraryModal.vue +418 -0
- package/src/Components/Modals/Modal.vue +102 -0
- package/src/Components/Modals/PageBuilderModal.vue +233 -0
- package/src/Components/Modals/PageBuilderPreviewModal.vue +123 -0
- package/src/Components/PageBuilder/DropdownsPlusToggles/OptionsDropdown.vue +202 -0
- package/src/Components/PageBuilder/DropdownsPlusToggles/SaveDesign.vue +7 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/BackgroundColorEditor.vue +91 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/BorderRadius.vue +163 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/Borders.vue +164 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/ClassEditor.vue +80 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/ComponentTopMenu.vue +93 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/DeleteElement.vue +42 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/EditGetElement.vue +338 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/ElementEditor.vue +58 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/ImageEditor.vue +82 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/LinkEditor.vue +301 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/ManageBackgroundOpacity.vue +109 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/ManageOpacity.vue +107 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/OpacityEditor.vue +16 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/PaddingPlusMargin.vue +134 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/TextColorEditor.vue +91 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/Typography.vue +199 -0
- package/src/Components/PageBuilder/EditorMenu/EditorAccordion.vue +42 -0
- package/src/Components/PageBuilder/EditorMenu/RightSidebarEditor.vue +113 -0
- package/src/Components/PageBuilder/Settings/AdvancedPageBuilderSettings.vue +229 -0
- package/src/Components/PageBuilder/Settings/PageBuilderSettings.vue +101 -0
- package/src/Components/PageBuilder/Slidebars/SlideOverRight.vue +91 -0
- package/src/Components/PageBuilder/Slidebars/SlideOverRightParent.vue +91 -0
- package/src/Components/Search/SearchComponents.vue +259 -0
- package/src/Components/TipTap/TipTap.vue +32 -0
- package/src/Components/TipTap/TipTapInput.vue +325 -0
- package/src/PageBuilder/PageBuilder.vue +347 -0
- package/src/PageBuilder/Preview.vue +24 -0
- package/src/composables/PageBuilder.ts +1483 -0
- package/src/composables/delay.ts +5 -0
- package/src/composables/extract-text-content-html.ts +34 -0
- package/src/composables/isObject.ts +6 -0
- package/src/composables/usePromise.ts +10 -0
- package/src/composables/vueFetch.ts +278 -0
- package/src/css/app.css +614 -0
- package/src/index.ts +16 -0
- package/src/main.ts +11 -0
- package/src/stores/media-library.ts +34 -0
- package/src/stores/page-builder-state.ts +461 -0
- package/src/stores/unsplash.ts +107 -0
- package/src/stores/user.ts +30 -0
- package/src/types/global.d.ts +49 -0
- package/src/utils/builder/compiledCSS.ts +2205 -0
- package/src/utils/builder/html-doc-declaration-with-components.ts +7 -0
- package/src/utils/builder/html-elements/componentHelpers.ts +101 -0
- package/src/utils/builder/tailwaind-colors.ts +503 -0
- package/src/utils/builder/tailwind-border-radius.ts +67 -0
- package/src/utils/builder/tailwind-border-style-width-color.ts +272 -0
- package/src/utils/builder/tailwind-font-sizes.ts +76 -0
- package/src/utils/builder/tailwind-font-styles.ts +24 -0
- package/src/utils/builder/tailwind-opacities.ts +45 -0
- package/src/utils/builder/tailwind-padding-margin.ts +159 -0
|
@@ -0,0 +1,1483 @@
|
|
|
1
|
+
// Type definitions
|
|
2
|
+
interface ComponentObject {
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
[key: string]: any
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface ImageObject {
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
[key: string]: any
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface PageBuilderStateStore {
|
|
13
|
+
getTextAreaVueModel: string | null
|
|
14
|
+
getLocalStorageItemName: string | null
|
|
15
|
+
getLocalStorageItemNameUpdate: string | null
|
|
16
|
+
getHyberlinkEnable: boolean
|
|
17
|
+
getComponents: ComponentObject[] | null
|
|
18
|
+
getComponent: ComponentObject | null
|
|
19
|
+
getElement: HTMLElement | null
|
|
20
|
+
getNextSibling: HTMLElement | null
|
|
21
|
+
getParentElement: HTMLElement | null
|
|
22
|
+
getRestoredElement: string | null
|
|
23
|
+
getComponentArrayAddMethod: string | null
|
|
24
|
+
setElement: (element: HTMLElement | null) => void
|
|
25
|
+
setMenuRight: (value: boolean) => void
|
|
26
|
+
setComponent: (component: ComponentObject | null) => void
|
|
27
|
+
setComponents: (components: ComponentObject[] | null) => void
|
|
28
|
+
setComponentArrayAddMethod: (method: string) => void
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
[key: string]: any // For dynamic mutation methods
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface MediaLibraryStore {
|
|
34
|
+
getCurrentImage: ImageObject | null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
+
import tailwindColors from '@/utils/builder/tailwaind-colors'
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
40
|
+
import tailwindOpacities from '@/utils/builder/tailwind-opacities'
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
42
|
+
import tailwindFontSizes from '@/utils/builder/tailwind-font-sizes'
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
44
|
+
import tailwindFontStyles from '@/utils/builder/tailwind-font-styles'
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
|
+
import tailwindPaddingAndMargin from '@/utils/builder/tailwind-padding-margin'
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
48
|
+
import tailwindBorderRadius from '@/utils/builder/tailwind-border-radius'
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
50
|
+
import tailwindBorderStyleWidthPlusColor from '@/utils/builder/tailwind-border-style-width-color'
|
|
51
|
+
import { computed, ref, nextTick } from 'vue'
|
|
52
|
+
import type { ComputedRef } from 'vue'
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
|
+
import { v4 as uuidv4 } from 'uuid'
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
56
|
+
import { delay } from '@/composables/delay'
|
|
57
|
+
|
|
58
|
+
class PageBuilder {
|
|
59
|
+
// Class properties with types
|
|
60
|
+
private elementsWithListeners: WeakSet<Element>
|
|
61
|
+
private nextTick: Promise<void>
|
|
62
|
+
private containsPagebuilder: Element | null
|
|
63
|
+
private timer: number | null
|
|
64
|
+
private pageBuilderStateStore: PageBuilderStateStore
|
|
65
|
+
private mediaLibraryStore: MediaLibraryStore
|
|
66
|
+
private getTextAreaVueModel: ComputedRef<string | null>
|
|
67
|
+
private getLocalStorageItemName: ComputedRef<string | null>
|
|
68
|
+
private getLocalStorageItemNameUpdate: ComputedRef<string | null>
|
|
69
|
+
private getCurrentImage: ComputedRef<ImageObject | null>
|
|
70
|
+
private getHyberlinkEnable: ComputedRef<boolean>
|
|
71
|
+
private getComponents: ComputedRef<ComponentObject[] | null>
|
|
72
|
+
private getComponent: ComputedRef<ComponentObject | null>
|
|
73
|
+
private getElement: ComputedRef<HTMLElement | null>
|
|
74
|
+
private getNextSibling: ComputedRef<HTMLElement | null>
|
|
75
|
+
private getParentElement: ComputedRef<HTMLElement | null>
|
|
76
|
+
private getRestoredElement: ComputedRef<string | null>
|
|
77
|
+
private getComponentArrayAddMethod: ComputedRef<string | null>
|
|
78
|
+
private headerTags: string[]
|
|
79
|
+
private additionalTagsNoneListernes: string[]
|
|
80
|
+
private structuringTags: string[]
|
|
81
|
+
private showRunningMethodLogs: boolean
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
83
|
+
private delay: any
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
85
|
+
private observer?: any // Add missing observer property
|
|
86
|
+
|
|
87
|
+
constructor(pageBuilderStateStore: PageBuilderStateStore, mediaLibraryStore: MediaLibraryStore) {
|
|
88
|
+
/**
|
|
89
|
+
* Initialize an instance variable 'elementsWithListeners' as a WeakSet.
|
|
90
|
+
*
|
|
91
|
+
* A WeakSet is a special type of Set that holds weak references to its elements,
|
|
92
|
+
* meaning that an element could be garbage collected if there is no other reference to it.
|
|
93
|
+
* This is especially useful in the context of managing DOM elements and their associated events,
|
|
94
|
+
* as it allows for efficient and automated cleanup of references to DOM elements that have been removed.
|
|
95
|
+
*
|
|
96
|
+
* By checking if an element is in this WeakSet before attaching an event listener,
|
|
97
|
+
* we can prevent redundant addition of the same event listener to an element.
|
|
98
|
+
* This helps in managing the memory usage and performance of the application.
|
|
99
|
+
*/
|
|
100
|
+
this.elementsWithListeners = new WeakSet()
|
|
101
|
+
|
|
102
|
+
this.nextTick = nextTick()
|
|
103
|
+
|
|
104
|
+
this.containsPagebuilder = document.querySelector('#contains-pagebuilder')
|
|
105
|
+
|
|
106
|
+
this.timer = null
|
|
107
|
+
this.pageBuilderStateStore = pageBuilderStateStore
|
|
108
|
+
this.mediaLibraryStore = mediaLibraryStore
|
|
109
|
+
|
|
110
|
+
this.getTextAreaVueModel = computed(() => this.pageBuilderStateStore.getTextAreaVueModel)
|
|
111
|
+
this.getLocalStorageItemName = computed(
|
|
112
|
+
() => this.pageBuilderStateStore.getLocalStorageItemName,
|
|
113
|
+
)
|
|
114
|
+
this.getLocalStorageItemNameUpdate = computed(
|
|
115
|
+
() => this.pageBuilderStateStore.getLocalStorageItemNameUpdate,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
this.getCurrentImage = computed(() => this.mediaLibraryStore.getCurrentImage)
|
|
119
|
+
this.getHyberlinkEnable = computed(() => this.pageBuilderStateStore.getHyberlinkEnable)
|
|
120
|
+
this.getComponents = computed(() => this.pageBuilderStateStore.getComponents)
|
|
121
|
+
|
|
122
|
+
this.getComponent = computed(() => this.pageBuilderStateStore.getComponent)
|
|
123
|
+
|
|
124
|
+
this.getElement = computed(() => this.pageBuilderStateStore.getElement)
|
|
125
|
+
this.getNextSibling = computed(() => this.pageBuilderStateStore.getNextSibling)
|
|
126
|
+
this.getParentElement = computed(() => this.pageBuilderStateStore.getParentElement)
|
|
127
|
+
this.getRestoredElement = computed(() => this.pageBuilderStateStore.getRestoredElement)
|
|
128
|
+
|
|
129
|
+
this.getComponentArrayAddMethod = computed(
|
|
130
|
+
() => this.pageBuilderStateStore.getComponentArrayAddMethod,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
this.headerTags = ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'IFRAME']
|
|
134
|
+
|
|
135
|
+
this.additionalTagsNoneListernes = [
|
|
136
|
+
'UL',
|
|
137
|
+
'OL',
|
|
138
|
+
'LI',
|
|
139
|
+
'EM',
|
|
140
|
+
'STRONG',
|
|
141
|
+
'B',
|
|
142
|
+
'A',
|
|
143
|
+
'SPAN',
|
|
144
|
+
'BLOCKQUOTE',
|
|
145
|
+
'BR',
|
|
146
|
+
]
|
|
147
|
+
|
|
148
|
+
this.structuringTags = [
|
|
149
|
+
'DIV',
|
|
150
|
+
'IFRAME',
|
|
151
|
+
'HEADER',
|
|
152
|
+
'NAV',
|
|
153
|
+
'MAIN',
|
|
154
|
+
'ARTICLE',
|
|
155
|
+
'SECTION',
|
|
156
|
+
'ASIDE',
|
|
157
|
+
'FOOTER',
|
|
158
|
+
]
|
|
159
|
+
|
|
160
|
+
this.showRunningMethodLogs = false
|
|
161
|
+
|
|
162
|
+
this.delay = delay()
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
shouldRunMethods(): boolean {
|
|
166
|
+
if (!this.getComponents.value) {
|
|
167
|
+
return false
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (!this.getComponent.value) {
|
|
171
|
+
return false
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (!this.getElement.value) {
|
|
175
|
+
return false
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return true
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
#applyElementClassChanges(
|
|
182
|
+
selectedCSS: string,
|
|
183
|
+
CSSArray: string[],
|
|
184
|
+
mutationName: string,
|
|
185
|
+
): string | undefined {
|
|
186
|
+
if (this.showRunningMethodLogs) {
|
|
187
|
+
console.log('#applyElementClassChanges')
|
|
188
|
+
}
|
|
189
|
+
if (!this.shouldRunMethods()) return
|
|
190
|
+
|
|
191
|
+
const currentCSS = CSSArray.find((CSS) => {
|
|
192
|
+
return this.getElement.value?.classList.contains(CSS)
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
// set to 'none' if undefined
|
|
196
|
+
let elementClass = currentCSS || 'none'
|
|
197
|
+
|
|
198
|
+
this.pageBuilderStateStore[mutationName](elementClass)
|
|
199
|
+
|
|
200
|
+
if (typeof selectedCSS === 'string' && selectedCSS !== 'none') {
|
|
201
|
+
if (elementClass && this.getElement.value?.classList.contains(elementClass)) {
|
|
202
|
+
this.getElement.value?.classList.remove(elementClass)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
this.getElement.value?.classList.add(selectedCSS)
|
|
206
|
+
elementClass = selectedCSS
|
|
207
|
+
} else if (typeof selectedCSS === 'string' && selectedCSS === 'none' && elementClass) {
|
|
208
|
+
this.getElement.value?.classList.remove(elementClass)
|
|
209
|
+
elementClass = selectedCSS
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
this.pageBuilderStateStore[mutationName](elementClass)
|
|
213
|
+
this.pageBuilderStateStore.setElement(this.getElement.value)
|
|
214
|
+
|
|
215
|
+
return currentCSS
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
#applyHelperCSSToElements(element: HTMLElement): void {
|
|
219
|
+
this.#wrapElementInDivIfExcluded(element)
|
|
220
|
+
|
|
221
|
+
if (this.showRunningMethodLogs) {
|
|
222
|
+
console.log('#applyHelperCSSToElements')
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (element.tagName === 'IMG') {
|
|
226
|
+
element.classList.add('smooth-transition')
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Add padding to DIV
|
|
230
|
+
if (element.tagName === 'DIV') {
|
|
231
|
+
if (element.classList.length === 0) {
|
|
232
|
+
// element.classList.add("p-2");
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
#wrapElementInDivIfExcluded(element: HTMLElement): void {
|
|
238
|
+
if (this.showRunningMethodLogs) {
|
|
239
|
+
console.log('#wrapElementInDivIfExcluded')
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (
|
|
243
|
+
this.headerTags.includes(element.tagName) &&
|
|
244
|
+
((element.previousElementSibling && element.previousElementSibling.tagName === 'IMG') ||
|
|
245
|
+
(element.nextElementSibling && element.nextElementSibling.tagName === 'IMG'))
|
|
246
|
+
) {
|
|
247
|
+
const divWrapper = document.createElement('div')
|
|
248
|
+
element.parentNode?.insertBefore(divWrapper, element)
|
|
249
|
+
divWrapper.appendChild(element)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
#handleElementClick = (e: Event, element: HTMLElement): void => {
|
|
254
|
+
e.stopPropagation()
|
|
255
|
+
|
|
256
|
+
const pagebuilder = document.querySelector('#pagebuilder')
|
|
257
|
+
|
|
258
|
+
if (!pagebuilder) return
|
|
259
|
+
|
|
260
|
+
this.pageBuilderStateStore.setMenuRight(true)
|
|
261
|
+
|
|
262
|
+
const selectedElement = pagebuilder.querySelector('[selected]')
|
|
263
|
+
if (selectedElement) {
|
|
264
|
+
selectedElement.removeAttribute('selected')
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
element.removeAttribute('hovered')
|
|
268
|
+
|
|
269
|
+
element.setAttribute('selected', '')
|
|
270
|
+
|
|
271
|
+
this.pageBuilderStateStore.setElement(element)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
#handleMouseOver = (e: Event, element: HTMLElement): void => {
|
|
275
|
+
if (this.showRunningMethodLogs) {
|
|
276
|
+
console.log('#handleMouseOver')
|
|
277
|
+
}
|
|
278
|
+
// console.log("YOU MOUSE OVER ME!");
|
|
279
|
+
|
|
280
|
+
e.preventDefault()
|
|
281
|
+
e.stopPropagation()
|
|
282
|
+
|
|
283
|
+
const pagebuilder = document.querySelector('#pagebuilder')
|
|
284
|
+
|
|
285
|
+
if (!pagebuilder) return
|
|
286
|
+
|
|
287
|
+
const hoveredElement = pagebuilder.querySelector('[hovered]')
|
|
288
|
+
if (hoveredElement) {
|
|
289
|
+
hoveredElement.removeAttribute('hovered')
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (!element.hasAttribute('selected')) {
|
|
293
|
+
element.setAttribute('hovered', '')
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
#handleMouseLeave = (e: Event): void => {
|
|
298
|
+
if (this.showRunningMethodLogs) {
|
|
299
|
+
console.log('#handleMouseLeave')
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
e.preventDefault()
|
|
303
|
+
e.stopPropagation()
|
|
304
|
+
|
|
305
|
+
const pagebuilder = document.querySelector('#pagebuilder')
|
|
306
|
+
if (!pagebuilder) return
|
|
307
|
+
|
|
308
|
+
const hoveredElement = pagebuilder.querySelector('[hovered]')
|
|
309
|
+
if (hoveredElement) {
|
|
310
|
+
hoveredElement.removeAttribute('hovered')
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* The function is used to
|
|
316
|
+
* attach event listeners to each element within a 'section'
|
|
317
|
+
*/
|
|
318
|
+
setEventListenersForElements = () => {
|
|
319
|
+
if (this.showRunningMethodLogs) {
|
|
320
|
+
console.log('setEventListenersForElements')
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const pagebuilder = document.querySelector('#pagebuilder')
|
|
324
|
+
|
|
325
|
+
if (!pagebuilder) return
|
|
326
|
+
|
|
327
|
+
pagebuilder.querySelectorAll('section *').forEach(async (element) => {
|
|
328
|
+
// exclude headerTags && additional Tags for not listening
|
|
329
|
+
if (
|
|
330
|
+
!this.headerTags.includes(element.tagName) &&
|
|
331
|
+
!this.additionalTagsNoneListernes.includes(element.tagName)
|
|
332
|
+
) {
|
|
333
|
+
if (this.elementsWithListeners && !this.elementsWithListeners.has(element)) {
|
|
334
|
+
this.elementsWithListeners.add(element)
|
|
335
|
+
// Type assertion to HTMLElement since we know these are DOM elements
|
|
336
|
+
const htmlElement = element as HTMLElement
|
|
337
|
+
// Attach event listeners directly to individual elements
|
|
338
|
+
htmlElement.addEventListener('click', (e) => this.#handleElementClick(e, htmlElement))
|
|
339
|
+
htmlElement.addEventListener('mouseover', (e) => this.#handleMouseOver(e, htmlElement))
|
|
340
|
+
htmlElement.addEventListener('mouseleave', (e) => this.#handleMouseLeave(e))
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// end for each iterating over elements
|
|
345
|
+
})
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* The Intersection Observer API provides a way to asynchronously observe changes in the
|
|
350
|
+
* intersection of a target element with an ancestor element or with a top-level document's viewport.
|
|
351
|
+
*/
|
|
352
|
+
synchronizeDOMAndComponents = async () => {
|
|
353
|
+
if (this.showRunningMethodLogs) {
|
|
354
|
+
console.log('synchronizeDOMAndComponents')
|
|
355
|
+
}
|
|
356
|
+
if (!this.getComponents.value) {
|
|
357
|
+
this.pageBuilderStateStore.setComponents([])
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const hoveredElement = document.querySelector('[hovered]')
|
|
361
|
+
if (hoveredElement) {
|
|
362
|
+
hoveredElement.removeAttribute('hovered')
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
this.getComponents.value?.forEach((component) => {
|
|
366
|
+
const section = document.querySelector(`section[data-componentid="${component.id}"]`)
|
|
367
|
+
|
|
368
|
+
if (section) {
|
|
369
|
+
component.html_code = section.outerHTML
|
|
370
|
+
}
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
// Initialize the MutationObserver
|
|
374
|
+
this.observer = new MutationObserver((mutationsList, observer) => {
|
|
375
|
+
// Once we have seen a mutation, stop observing and resolve the promise
|
|
376
|
+
observer.disconnect()
|
|
377
|
+
})
|
|
378
|
+
|
|
379
|
+
// Start observing the document with the configured parameters
|
|
380
|
+
this.observer.observe(document, {
|
|
381
|
+
attributes: true,
|
|
382
|
+
childList: true,
|
|
383
|
+
subtree: true,
|
|
384
|
+
})
|
|
385
|
+
|
|
386
|
+
// Use the MutationObserver to wait for the next DOM change
|
|
387
|
+
await new Promise<void>((resolve) => {
|
|
388
|
+
resolve()
|
|
389
|
+
})
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
cloneCompObjForDOMInsertion(componentObject: ComponentObject): ComponentObject {
|
|
393
|
+
if (this.showRunningMethodLogs) {
|
|
394
|
+
console.log('cloneCompObjForDOMInsertion')
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Deep clone clone component
|
|
398
|
+
const clonedComponent = { ...componentObject }
|
|
399
|
+
|
|
400
|
+
// scoll to top or bottom # end
|
|
401
|
+
if (this.containsPagebuilder) {
|
|
402
|
+
if (
|
|
403
|
+
this.getComponentArrayAddMethod.value === 'unshift' ||
|
|
404
|
+
this.getComponentArrayAddMethod.value === 'push'
|
|
405
|
+
) {
|
|
406
|
+
// push to top
|
|
407
|
+
if (this.getComponentArrayAddMethod.value === 'unshift') {
|
|
408
|
+
this.containsPagebuilder.scrollTo({
|
|
409
|
+
top: 0,
|
|
410
|
+
behavior: 'smooth',
|
|
411
|
+
})
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// push to bottom
|
|
415
|
+
if (this.getComponentArrayAddMethod.value === 'push') {
|
|
416
|
+
const maxHeight = this.containsPagebuilder.scrollHeight
|
|
417
|
+
this.containsPagebuilder.scrollTo({
|
|
418
|
+
top: maxHeight,
|
|
419
|
+
behavior: 'smooth',
|
|
420
|
+
})
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Create a DOMParser instance
|
|
426
|
+
const parser = new DOMParser()
|
|
427
|
+
|
|
428
|
+
// Parse the HTML content of the clonedComponent using the DOMParser
|
|
429
|
+
const doc = parser.parseFromString(clonedComponent.html_code, 'text/html')
|
|
430
|
+
|
|
431
|
+
// Selects all elements within the HTML document, including elements like:
|
|
432
|
+
const elements = doc.querySelectorAll('*')
|
|
433
|
+
|
|
434
|
+
elements.forEach((element) => {
|
|
435
|
+
this.#applyHelperCSSToElements(element as HTMLElement)
|
|
436
|
+
})
|
|
437
|
+
|
|
438
|
+
// Add the component id to the section element
|
|
439
|
+
const section = doc.querySelector('section')
|
|
440
|
+
if (section) {
|
|
441
|
+
// Generate a unique ID using uuidv4() and assign it to the section
|
|
442
|
+
section.dataset.componentid = uuidv4()
|
|
443
|
+
|
|
444
|
+
// Find all images within elements with "flex" or "grid" classes inside the section
|
|
445
|
+
const images = section.querySelectorAll('img')
|
|
446
|
+
|
|
447
|
+
// Add a unique ID as a data attribute to each image element
|
|
448
|
+
images.forEach((image) => {
|
|
449
|
+
image.setAttribute('data-image', uuidv4())
|
|
450
|
+
})
|
|
451
|
+
|
|
452
|
+
// Update the clonedComponent id with the newly generated unique ID
|
|
453
|
+
clonedComponent.id = section.dataset.componentid
|
|
454
|
+
|
|
455
|
+
// Update the HTML content of the clonedComponent with the modified HTML
|
|
456
|
+
clonedComponent.html_code = section.outerHTML
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// return to the cloned element to be dropped
|
|
460
|
+
return clonedComponent
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
removeHoveredAndSelected() {
|
|
464
|
+
if (this.showRunningMethodLogs) {
|
|
465
|
+
console.log('removeHoveredAndSelected')
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const hoveredElement = document.querySelector('[hovered]')
|
|
469
|
+
if (hoveredElement) {
|
|
470
|
+
hoveredElement.removeAttribute('hovered')
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
const selectedElement = document.querySelector('[selected]')
|
|
474
|
+
if (selectedElement) {
|
|
475
|
+
selectedElement.removeAttribute('selected')
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
currentClasses() {
|
|
480
|
+
if (this.showRunningMethodLogs) {
|
|
481
|
+
console.log('handleAddClasses')
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (!this.shouldRunMethods()) return
|
|
485
|
+
|
|
486
|
+
// convert classList to array
|
|
487
|
+
const classListArray = Array.from(this.getElement.value?.classList || [])
|
|
488
|
+
|
|
489
|
+
// commit array to store
|
|
490
|
+
this.pageBuilderStateStore.setCurrentClasses(classListArray)
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
handleAddClasses(userSelectedClass: string): void {
|
|
494
|
+
if (this.showRunningMethodLogs) {
|
|
495
|
+
console.log('handleAddClasses')
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
if (!this.shouldRunMethods()) return
|
|
499
|
+
|
|
500
|
+
if (
|
|
501
|
+
typeof userSelectedClass === 'string' &&
|
|
502
|
+
userSelectedClass !== '' &&
|
|
503
|
+
!userSelectedClass.includes(' ') &&
|
|
504
|
+
// Check if class already exists
|
|
505
|
+
!this.getElement.value?.classList.contains(userSelectedClass)
|
|
506
|
+
) {
|
|
507
|
+
// Remove any leading/trailing spaces
|
|
508
|
+
const cleanedClass = userSelectedClass.trim()
|
|
509
|
+
|
|
510
|
+
this.getElement.value?.classList.add(cleanedClass)
|
|
511
|
+
|
|
512
|
+
this.pageBuilderStateStore.setElement(this.getElement.value)
|
|
513
|
+
|
|
514
|
+
this.pageBuilderStateStore.setClass(userSelectedClass)
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
handleRemoveClasses(userSelectedClass: string): void {
|
|
518
|
+
if (this.showRunningMethodLogs) {
|
|
519
|
+
console.log('handleRemoveClasses')
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
if (!this.shouldRunMethods()) return
|
|
523
|
+
|
|
524
|
+
// remove selected class from element
|
|
525
|
+
if (this.getElement.value?.classList.contains(userSelectedClass)) {
|
|
526
|
+
this.getElement.value?.classList.remove(userSelectedClass)
|
|
527
|
+
|
|
528
|
+
this.pageBuilderStateStore.setElement(this.getElement.value)
|
|
529
|
+
this.pageBuilderStateStore.removeClass(userSelectedClass)
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
handleDeleteElement() {
|
|
534
|
+
if (this.showRunningMethodLogs) {
|
|
535
|
+
console.log('handleDeleteElement')
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// Get the element to be deleted
|
|
539
|
+
const element = this.getElement.value
|
|
540
|
+
|
|
541
|
+
if (!element) return
|
|
542
|
+
|
|
543
|
+
if (!element?.parentNode) {
|
|
544
|
+
this.pageBuilderStateStore.setComponent(null)
|
|
545
|
+
this.pageBuilderStateStore.setElement(null)
|
|
546
|
+
return
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Store the parent of the deleted element
|
|
550
|
+
// if parent element tag is section remove the hole component
|
|
551
|
+
if (element.parentElement?.tagName !== 'SECTION') {
|
|
552
|
+
this.pageBuilderStateStore.setParentElement(element.parentNode)
|
|
553
|
+
|
|
554
|
+
// Store the outerHTML of the deleted element
|
|
555
|
+
this.pageBuilderStateStore.setRestoredElement(element.outerHTML)
|
|
556
|
+
|
|
557
|
+
// Store the next sibling of the deleted element
|
|
558
|
+
this.pageBuilderStateStore.setNextSibling(element.nextSibling)
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// if parent element tag is section remove the hole component
|
|
562
|
+
if (element.parentElement?.tagName === 'SECTION') {
|
|
563
|
+
this.deleteComponent()
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// Remove the element from the DOM
|
|
567
|
+
element.remove()
|
|
568
|
+
this.pageBuilderStateStore.setComponent(null)
|
|
569
|
+
this.pageBuilderStateStore.setElement(null)
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
handleRestoreElement() {
|
|
573
|
+
if (this.showRunningMethodLogs) {
|
|
574
|
+
console.log('handleRestoreElement')
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// Get the stored deleted element and its parent
|
|
578
|
+
if (this.getRestoredElement.value && this.getParentElement.value) {
|
|
579
|
+
// Create a new element from the stored outerHTML
|
|
580
|
+
const newElement = document.createElement('div')
|
|
581
|
+
// Fixed type conversion issue
|
|
582
|
+
newElement.innerHTML = this.getRestoredElement.value
|
|
583
|
+
|
|
584
|
+
// Append the restored element to its parent
|
|
585
|
+
// Insert the restored element before its next sibling in its parent
|
|
586
|
+
if (newElement.firstChild) {
|
|
587
|
+
this.getParentElement.value.insertBefore(newElement.firstChild, this.getNextSibling.value)
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// Clear
|
|
592
|
+
|
|
593
|
+
this.pageBuilderStateStore.setParentElement(null)
|
|
594
|
+
this.pageBuilderStateStore.setRestoredElement(null)
|
|
595
|
+
this.pageBuilderStateStore.setComponent(null)
|
|
596
|
+
this.pageBuilderStateStore.setElement(null)
|
|
597
|
+
|
|
598
|
+
this.setEventListenersForElements()
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
handleFontWeight(userSelectedFontWeight?: string): void {
|
|
602
|
+
if (this.showRunningMethodLogs) {
|
|
603
|
+
console.log('handleFontWeight')
|
|
604
|
+
}
|
|
605
|
+
if (!userSelectedFontWeight) return
|
|
606
|
+
|
|
607
|
+
this.#applyElementClassChanges(
|
|
608
|
+
userSelectedFontWeight,
|
|
609
|
+
tailwindFontStyles.fontWeight,
|
|
610
|
+
'setFontWeight',
|
|
611
|
+
)
|
|
612
|
+
}
|
|
613
|
+
handleFontFamily(userSelectedFontFamily?: string): void {
|
|
614
|
+
if (this.showRunningMethodLogs) {
|
|
615
|
+
console.log('handleFontFamily')
|
|
616
|
+
}
|
|
617
|
+
if (!userSelectedFontFamily) return
|
|
618
|
+
|
|
619
|
+
this.#applyElementClassChanges(
|
|
620
|
+
userSelectedFontFamily,
|
|
621
|
+
tailwindFontStyles.fontFamily,
|
|
622
|
+
'setFontFamily',
|
|
623
|
+
)
|
|
624
|
+
}
|
|
625
|
+
handleFontStyle(userSelectedFontStyle?: string): void {
|
|
626
|
+
if (this.showRunningMethodLogs) {
|
|
627
|
+
console.log('handleFontStyle')
|
|
628
|
+
}
|
|
629
|
+
if (!userSelectedFontStyle) return
|
|
630
|
+
|
|
631
|
+
this.#applyElementClassChanges(
|
|
632
|
+
userSelectedFontStyle,
|
|
633
|
+
tailwindFontStyles.fontStyle,
|
|
634
|
+
'setFontStyle',
|
|
635
|
+
)
|
|
636
|
+
}
|
|
637
|
+
handleVerticalPadding(userSelectedVerticalPadding?: string): void {
|
|
638
|
+
if (this.showRunningMethodLogs) {
|
|
639
|
+
console.log('handleVerticalPadding')
|
|
640
|
+
}
|
|
641
|
+
if (!userSelectedVerticalPadding) return
|
|
642
|
+
|
|
643
|
+
this.#applyElementClassChanges(
|
|
644
|
+
userSelectedVerticalPadding,
|
|
645
|
+
tailwindPaddingAndMargin.verticalPadding,
|
|
646
|
+
'setFontVerticalPadding',
|
|
647
|
+
)
|
|
648
|
+
}
|
|
649
|
+
handleHorizontalPadding(userSelectedHorizontalPadding?: string): void {
|
|
650
|
+
if (this.showRunningMethodLogs) {
|
|
651
|
+
console.log('handleHorizontalPadding')
|
|
652
|
+
}
|
|
653
|
+
if (!userSelectedHorizontalPadding) return
|
|
654
|
+
|
|
655
|
+
this.#applyElementClassChanges(
|
|
656
|
+
userSelectedHorizontalPadding,
|
|
657
|
+
tailwindPaddingAndMargin.horizontalPadding,
|
|
658
|
+
'setFontHorizontalPadding',
|
|
659
|
+
)
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
handleVerticalMargin(userSelectedVerticalMargin?: string): void {
|
|
663
|
+
if (this.showRunningMethodLogs) {
|
|
664
|
+
console.log('handleVerticalMargin')
|
|
665
|
+
}
|
|
666
|
+
if (!userSelectedVerticalMargin) return
|
|
667
|
+
|
|
668
|
+
this.#applyElementClassChanges(
|
|
669
|
+
userSelectedVerticalMargin,
|
|
670
|
+
tailwindPaddingAndMargin.verticalMargin,
|
|
671
|
+
'setFontVerticalMargin',
|
|
672
|
+
)
|
|
673
|
+
}
|
|
674
|
+
handleHorizontalMargin(userSelectedHorizontalMargin?: string): void {
|
|
675
|
+
if (this.showRunningMethodLogs) {
|
|
676
|
+
console.log('handleHorizontalMargin')
|
|
677
|
+
}
|
|
678
|
+
if (!userSelectedHorizontalMargin) return
|
|
679
|
+
|
|
680
|
+
this.#applyElementClassChanges(
|
|
681
|
+
userSelectedHorizontalMargin,
|
|
682
|
+
tailwindPaddingAndMargin.horizontalMargin,
|
|
683
|
+
'setFontHorizontalMargin',
|
|
684
|
+
)
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// border color, style & width / start
|
|
688
|
+
handleBorderStyle(borderStyle?: string): void {
|
|
689
|
+
if (this.showRunningMethodLogs) {
|
|
690
|
+
console.log('handleBorderStyle')
|
|
691
|
+
}
|
|
692
|
+
if (!borderStyle) return
|
|
693
|
+
|
|
694
|
+
this.#applyElementClassChanges(
|
|
695
|
+
borderStyle,
|
|
696
|
+
tailwindBorderStyleWidthPlusColor.borderStyle,
|
|
697
|
+
'setBorderStyle',
|
|
698
|
+
)
|
|
699
|
+
}
|
|
700
|
+
handleBorderWidth(borderWidth?: string): void {
|
|
701
|
+
if (this.showRunningMethodLogs) {
|
|
702
|
+
console.log('handleBorderWidth')
|
|
703
|
+
}
|
|
704
|
+
if (!borderWidth) return
|
|
705
|
+
|
|
706
|
+
this.#applyElementClassChanges(
|
|
707
|
+
borderWidth,
|
|
708
|
+
tailwindBorderStyleWidthPlusColor.borderWidth,
|
|
709
|
+
'setBorderWidth',
|
|
710
|
+
)
|
|
711
|
+
}
|
|
712
|
+
handleBorderColor(borderColor?: string): void {
|
|
713
|
+
if (this.showRunningMethodLogs) {
|
|
714
|
+
console.log('handleBorderColor')
|
|
715
|
+
}
|
|
716
|
+
if (!borderColor) return
|
|
717
|
+
|
|
718
|
+
this.#applyElementClassChanges(
|
|
719
|
+
borderColor,
|
|
720
|
+
tailwindBorderStyleWidthPlusColor.borderColor,
|
|
721
|
+
'setBorderColor',
|
|
722
|
+
)
|
|
723
|
+
}
|
|
724
|
+
// border color, style & width / end
|
|
725
|
+
|
|
726
|
+
handleBackgroundColor(color?: string): void {
|
|
727
|
+
if (!color) return
|
|
728
|
+
this.#applyElementClassChanges(
|
|
729
|
+
color,
|
|
730
|
+
tailwindColors.backgroundColorVariables,
|
|
731
|
+
'setBackgroundColor',
|
|
732
|
+
)
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
handleTextColor(color?: string): void {
|
|
736
|
+
if (!color) return
|
|
737
|
+
this.#applyElementClassChanges(color, tailwindColors.textColorVariables, 'setTextColor')
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
// border radius / start
|
|
741
|
+
handleBorderRadiusGlobal(borderRadiusGlobal?: string): void {
|
|
742
|
+
if (this.showRunningMethodLogs) {
|
|
743
|
+
console.log('handleBorderRadiusGlobal')
|
|
744
|
+
}
|
|
745
|
+
if (!borderRadiusGlobal) return
|
|
746
|
+
|
|
747
|
+
this.#applyElementClassChanges(
|
|
748
|
+
borderRadiusGlobal,
|
|
749
|
+
tailwindBorderRadius.roundedGlobal,
|
|
750
|
+
'setBorderRadiusGlobal',
|
|
751
|
+
)
|
|
752
|
+
}
|
|
753
|
+
handleBorderRadiusTopLeft(borderRadiusTopLeft?: string): void {
|
|
754
|
+
if (this.showRunningMethodLogs) {
|
|
755
|
+
console.log('handleBorderRadiusTopLeft')
|
|
756
|
+
}
|
|
757
|
+
if (!borderRadiusTopLeft) return
|
|
758
|
+
|
|
759
|
+
this.#applyElementClassChanges(
|
|
760
|
+
borderRadiusTopLeft,
|
|
761
|
+
tailwindBorderRadius.roundedTopLeft,
|
|
762
|
+
'setBorderRadiusTopLeft',
|
|
763
|
+
)
|
|
764
|
+
}
|
|
765
|
+
handleBorderRadiusTopRight(borderRadiusTopRight?: string): void {
|
|
766
|
+
if (this.showRunningMethodLogs) {
|
|
767
|
+
console.log('handleBorderRadiusTopRight')
|
|
768
|
+
}
|
|
769
|
+
if (!borderRadiusTopRight) return
|
|
770
|
+
|
|
771
|
+
this.#applyElementClassChanges(
|
|
772
|
+
borderRadiusTopRight,
|
|
773
|
+
tailwindBorderRadius.roundedTopRight,
|
|
774
|
+
'setBorderRadiusTopRight',
|
|
775
|
+
)
|
|
776
|
+
}
|
|
777
|
+
handleBorderRadiusBottomleft(borderRadiusBottomleft?: string): void {
|
|
778
|
+
if (this.showRunningMethodLogs) {
|
|
779
|
+
console.log('handleBorderRadiusBottomleft')
|
|
780
|
+
}
|
|
781
|
+
if (!borderRadiusBottomleft) return
|
|
782
|
+
|
|
783
|
+
this.#applyElementClassChanges(
|
|
784
|
+
borderRadiusBottomleft,
|
|
785
|
+
tailwindBorderRadius.roundedBottomLeft,
|
|
786
|
+
'setBorderRadiusBottomleft',
|
|
787
|
+
)
|
|
788
|
+
}
|
|
789
|
+
handleBorderRadiusBottomRight(borderRadiusBottomRight?: string): void {
|
|
790
|
+
if (this.showRunningMethodLogs) {
|
|
791
|
+
console.log('handleBorderRadiusBottomRight')
|
|
792
|
+
}
|
|
793
|
+
if (!borderRadiusBottomRight) return
|
|
794
|
+
|
|
795
|
+
this.#applyElementClassChanges(
|
|
796
|
+
borderRadiusBottomRight,
|
|
797
|
+
tailwindBorderRadius.roundedBottomRight,
|
|
798
|
+
'setBorderRadiusBottomRight',
|
|
799
|
+
)
|
|
800
|
+
}
|
|
801
|
+
// border radius / end
|
|
802
|
+
|
|
803
|
+
handleFontSize(userSelectedFontSize?: string): void {
|
|
804
|
+
if (this.showRunningMethodLogs) {
|
|
805
|
+
console.log('handleFontSize')
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
if (!this.shouldRunMethods()) return
|
|
809
|
+
if (!userSelectedFontSize) return
|
|
810
|
+
if (!this.getElement.value) return
|
|
811
|
+
|
|
812
|
+
let fontBase = tailwindFontSizes.fontBase.find((size: string) => {
|
|
813
|
+
return this.getElement.value?.classList.contains(size)
|
|
814
|
+
})
|
|
815
|
+
if (fontBase === undefined) {
|
|
816
|
+
fontBase = 'base:none'
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
let fontDesktop = tailwindFontSizes.fontDesktop.find((size: string) => {
|
|
820
|
+
return this.getElement.value?.classList.contains(size)
|
|
821
|
+
})
|
|
822
|
+
if (fontDesktop === undefined) {
|
|
823
|
+
fontDesktop = 'lg:none'
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
let fontTablet = tailwindFontSizes.fontTablet.find((size: string) => {
|
|
827
|
+
return this.getElement.value?.classList.contains(size)
|
|
828
|
+
})
|
|
829
|
+
if (fontTablet === undefined) {
|
|
830
|
+
fontTablet = 'md:none'
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
let fontMobile = tailwindFontSizes.fontMobile.find((size: string) => {
|
|
834
|
+
return this.getElement.value?.classList.contains(size)
|
|
835
|
+
})
|
|
836
|
+
if (fontMobile === undefined) {
|
|
837
|
+
fontMobile = 'sm:none'
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
// set fonts
|
|
841
|
+
this.pageBuilderStateStore.setFontBase(fontBase)
|
|
842
|
+
this.pageBuilderStateStore.setFontDesktop(fontDesktop)
|
|
843
|
+
this.pageBuilderStateStore.setFontTablet(fontTablet)
|
|
844
|
+
this.pageBuilderStateStore.setFontMobile(fontMobile)
|
|
845
|
+
|
|
846
|
+
const getFontBase = computed(() => {
|
|
847
|
+
return this.pageBuilderStateStore.getFontBase
|
|
848
|
+
})
|
|
849
|
+
const getFontDesktop = computed(() => {
|
|
850
|
+
return this.pageBuilderStateStore.getFontDesktop
|
|
851
|
+
})
|
|
852
|
+
const getFontTablet = computed(() => {
|
|
853
|
+
return this.pageBuilderStateStore.getFontTablet
|
|
854
|
+
})
|
|
855
|
+
const getFontMobile = computed(() => {
|
|
856
|
+
return this.pageBuilderStateStore.getFontMobile
|
|
857
|
+
})
|
|
858
|
+
|
|
859
|
+
if (userSelectedFontSize !== undefined && this.getElement.value) {
|
|
860
|
+
if (
|
|
861
|
+
!userSelectedFontSize.includes('sm:') &&
|
|
862
|
+
!userSelectedFontSize.includes('md:') &&
|
|
863
|
+
!userSelectedFontSize.includes('lg:')
|
|
864
|
+
) {
|
|
865
|
+
this.getElement.value.classList.remove(getFontBase.value)
|
|
866
|
+
if (!userSelectedFontSize.includes('base:none')) {
|
|
867
|
+
this.getElement.value.classList.add(userSelectedFontSize)
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
this.pageBuilderStateStore.setFontBase(userSelectedFontSize)
|
|
871
|
+
}
|
|
872
|
+
if (userSelectedFontSize.includes('lg:')) {
|
|
873
|
+
this.getElement.value.classList.remove(getFontDesktop.value)
|
|
874
|
+
if (!userSelectedFontSize.includes('lg:none')) {
|
|
875
|
+
this.getElement.value.classList.add(userSelectedFontSize)
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
this.pageBuilderStateStore.setFontDesktop(userSelectedFontSize)
|
|
879
|
+
}
|
|
880
|
+
if (userSelectedFontSize.includes('md:')) {
|
|
881
|
+
this.getElement.value.classList.remove(getFontTablet.value)
|
|
882
|
+
if (!userSelectedFontSize.includes('md:none')) {
|
|
883
|
+
this.getElement.value.classList.add(userSelectedFontSize)
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
this.pageBuilderStateStore.setFontTablet(userSelectedFontSize)
|
|
887
|
+
}
|
|
888
|
+
if (userSelectedFontSize.includes('sm:')) {
|
|
889
|
+
this.getElement.value.classList.remove(getFontMobile.value)
|
|
890
|
+
if (!userSelectedFontSize.includes('sm:none')) {
|
|
891
|
+
this.getElement.value.classList.add(userSelectedFontSize)
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
this.pageBuilderStateStore.setFontMobile(userSelectedFontSize)
|
|
895
|
+
}
|
|
896
|
+
this.pageBuilderStateStore.setElement(this.getElement.value)
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
handleBackgroundOpacity(opacity?: string): void {
|
|
901
|
+
if (this.showRunningMethodLogs) {
|
|
902
|
+
console.log('handleBackgroundOpacity')
|
|
903
|
+
}
|
|
904
|
+
if (!opacity) return
|
|
905
|
+
|
|
906
|
+
this.#applyElementClassChanges(
|
|
907
|
+
opacity,
|
|
908
|
+
tailwindOpacities.backgroundOpacities,
|
|
909
|
+
'setBackgroundOpacity',
|
|
910
|
+
)
|
|
911
|
+
}
|
|
912
|
+
handleOpacity(opacity?: string): void {
|
|
913
|
+
if (this.showRunningMethodLogs) {
|
|
914
|
+
console.log('handleOpacity')
|
|
915
|
+
}
|
|
916
|
+
if (!opacity) return
|
|
917
|
+
|
|
918
|
+
this.#applyElementClassChanges(opacity, tailwindOpacities.opacities, 'setOpacity')
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
deleteAllComponents() {
|
|
922
|
+
if (this.showRunningMethodLogs) {
|
|
923
|
+
console.log('deleteAllComponents')
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
this.pageBuilderStateStore.setComponents([])
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
deleteComponent() {
|
|
930
|
+
if (this.showRunningMethodLogs) {
|
|
931
|
+
console.log('deleteComponent')
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
if (!this.shouldRunMethods()) return
|
|
935
|
+
if (!this.getComponents.value || !this.getComponent.value) return
|
|
936
|
+
|
|
937
|
+
// Find the index of the component to delete
|
|
938
|
+
const indexToDelete = this.getComponents.value.findIndex(
|
|
939
|
+
(component) => component.id === this.getComponent.value?.id,
|
|
940
|
+
)
|
|
941
|
+
|
|
942
|
+
if (indexToDelete === -1) {
|
|
943
|
+
// Component not found in the array, handle this case as needed.
|
|
944
|
+
return
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
// Remove the component from the array
|
|
948
|
+
this.getComponents.value.splice(indexToDelete, 1)
|
|
949
|
+
this.pageBuilderStateStore.setComponents(this.getComponents.value)
|
|
950
|
+
|
|
951
|
+
this.pageBuilderStateStore.setComponent(null)
|
|
952
|
+
this.pageBuilderStateStore.setElement(null)
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
// move component
|
|
956
|
+
// runs when html components are rearranged
|
|
957
|
+
moveComponent(direction: number): void {
|
|
958
|
+
if (this.showRunningMethodLogs) {
|
|
959
|
+
console.log('moveComponent')
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
if (!this.shouldRunMethods()) return
|
|
963
|
+
if (!this.getComponents.value || !this.getComponent.value) return
|
|
964
|
+
|
|
965
|
+
if (this.getComponents.value.length <= 1) return
|
|
966
|
+
|
|
967
|
+
// Get the component you want to move (replace this with your actual logic)
|
|
968
|
+
const componentToMove = this.getComponent.value
|
|
969
|
+
|
|
970
|
+
// Determine the new index where you want to move the component
|
|
971
|
+
const currentIndex = this.getComponents.value.findIndex(
|
|
972
|
+
(component) => component.id === componentToMove.id,
|
|
973
|
+
)
|
|
974
|
+
|
|
975
|
+
if (currentIndex === -1) {
|
|
976
|
+
// Component not found in the array, handle this case as needed.
|
|
977
|
+
return
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
const newIndex = currentIndex + direction
|
|
981
|
+
|
|
982
|
+
// Ensure the newIndex is within bounds
|
|
983
|
+
if (newIndex < 0 || newIndex >= this.getComponents.value.length) {
|
|
984
|
+
return
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// Move the component to the new position
|
|
988
|
+
this.getComponents.value.splice(currentIndex, 1)
|
|
989
|
+
this.getComponents.value.splice(newIndex, 0, componentToMove)
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
ensureTextAreaHasContent = () => {
|
|
993
|
+
if (this.showRunningMethodLogs) {
|
|
994
|
+
console.log('ensureTextAreaHasContent')
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
if (!this.shouldRunMethods()) return
|
|
998
|
+
if (!this.getElement.value) return
|
|
999
|
+
|
|
1000
|
+
// text content
|
|
1001
|
+
if (typeof this.getElement.value.innerHTML !== 'string') {
|
|
1002
|
+
return
|
|
1003
|
+
}
|
|
1004
|
+
const element = this.getElement.value
|
|
1005
|
+
const elementTag = element.tagName
|
|
1006
|
+
|
|
1007
|
+
if (
|
|
1008
|
+
['DIV'].includes(elementTag) &&
|
|
1009
|
+
element.tagName.toLowerCase() !== 'img' &&
|
|
1010
|
+
element.textContent &&
|
|
1011
|
+
Number(element.textContent.length) === 0
|
|
1012
|
+
) {
|
|
1013
|
+
element.classList.add('h-6')
|
|
1014
|
+
element.classList.add('bg-red-50')
|
|
1015
|
+
} else {
|
|
1016
|
+
element.classList.remove('h-6')
|
|
1017
|
+
element.classList.remove('bg-red-50')
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
//
|
|
1022
|
+
handleTextInput = async (textContentVueModel: string): Promise<void> => {
|
|
1023
|
+
if (this.showRunningMethodLogs) {
|
|
1024
|
+
console.log('handleTextInput')
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
if (!this.shouldRunMethods()) return
|
|
1028
|
+
|
|
1029
|
+
// // text content
|
|
1030
|
+
if (typeof this.getElement.value?.innerHTML !== 'string') {
|
|
1031
|
+
return
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
if (typeof this.getElement.value.innerHTML === 'string') {
|
|
1035
|
+
await this.nextTick
|
|
1036
|
+
|
|
1037
|
+
// Update text content
|
|
1038
|
+
this.getElement.value.textContent = textContentVueModel
|
|
1039
|
+
|
|
1040
|
+
this.pageBuilderStateStore.setTextAreaVueModel(this.getElement.value.innerHTML)
|
|
1041
|
+
|
|
1042
|
+
this.getElement.value.innerHTML = textContentVueModel
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
this.ensureTextAreaHasContent()
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
//
|
|
1049
|
+
//
|
|
1050
|
+
ElOrFirstChildIsIframe() {
|
|
1051
|
+
if (
|
|
1052
|
+
this.getElement.value?.tagName === 'IFRAME' ||
|
|
1053
|
+
this.getElement.value?.firstElementChild?.tagName === 'IFRAME'
|
|
1054
|
+
) {
|
|
1055
|
+
return true
|
|
1056
|
+
} else {
|
|
1057
|
+
return false
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
//
|
|
1061
|
+
//
|
|
1062
|
+
//
|
|
1063
|
+
selectedElementIsValidText() {
|
|
1064
|
+
let reachedElseStatement = false
|
|
1065
|
+
|
|
1066
|
+
// Get all child elements of the parentDiv
|
|
1067
|
+
const childElements = this.getElement.value?.children
|
|
1068
|
+
if (
|
|
1069
|
+
this.getElement.value?.tagName === 'IMG' ||
|
|
1070
|
+
this.getElement.value?.firstElementChild?.tagName === 'IFRAME'
|
|
1071
|
+
) {
|
|
1072
|
+
return
|
|
1073
|
+
}
|
|
1074
|
+
if (!childElements) {
|
|
1075
|
+
return
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
Array.from(childElements).forEach((element) => {
|
|
1079
|
+
if (element?.tagName === 'IMG' || element?.tagName === 'DIV') {
|
|
1080
|
+
reachedElseStatement = false
|
|
1081
|
+
} else {
|
|
1082
|
+
reachedElseStatement = true
|
|
1083
|
+
}
|
|
1084
|
+
})
|
|
1085
|
+
|
|
1086
|
+
return reachedElseStatement
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
previewCurrentDesign() {
|
|
1090
|
+
if (this.showRunningMethodLogs) {
|
|
1091
|
+
console.log('previewCurrentDesign')
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
this.pageBuilderStateStore.setElement(null)
|
|
1095
|
+
|
|
1096
|
+
const addedHtmlComponents = ref<string[]>([])
|
|
1097
|
+
// preview current design in external browser tab
|
|
1098
|
+
// iterate over each top-level section component
|
|
1099
|
+
document.querySelectorAll('section:not(section section)').forEach((section) => {
|
|
1100
|
+
// remove hovered and selected
|
|
1101
|
+
|
|
1102
|
+
// remove hovered
|
|
1103
|
+
const hoveredElement = section.querySelector('[hovered]')
|
|
1104
|
+
if (hoveredElement) {
|
|
1105
|
+
hoveredElement.removeAttribute('hovered')
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
// remove selected
|
|
1109
|
+
const selectedElement = section.querySelector('[selected]')
|
|
1110
|
+
if (selectedElement) {
|
|
1111
|
+
selectedElement.removeAttribute('selected')
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
// push outer html into the array
|
|
1115
|
+
addedHtmlComponents.value.push(section.outerHTML)
|
|
1116
|
+
})
|
|
1117
|
+
|
|
1118
|
+
// stringify added html components
|
|
1119
|
+
const stringifiedComponents = JSON.stringify(addedHtmlComponents.value)
|
|
1120
|
+
|
|
1121
|
+
// commit
|
|
1122
|
+
this.pageBuilderStateStore.setCurrentLayoutPreview(stringifiedComponents)
|
|
1123
|
+
|
|
1124
|
+
// set added html components back to empty array
|
|
1125
|
+
addedHtmlComponents.value = []
|
|
1126
|
+
|
|
1127
|
+
//
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
async saveComponentsLocalStorage() {
|
|
1131
|
+
await this.nextTick
|
|
1132
|
+
this.synchronizeDOMAndComponents()
|
|
1133
|
+
|
|
1134
|
+
if (this.showRunningMethodLogs) {
|
|
1135
|
+
console.log('saveComponentsLocalStorage')
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
await this.nextTick
|
|
1139
|
+
if (this.getLocalStorageItemName.value) {
|
|
1140
|
+
localStorage.setItem(
|
|
1141
|
+
this.getLocalStorageItemName.value,
|
|
1142
|
+
JSON.stringify(this.getComponents.value),
|
|
1143
|
+
)
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
async saveComponentsLocalStorageUpdate() {
|
|
1148
|
+
if (this.showRunningMethodLogs) {
|
|
1149
|
+
console.log('saveComponentsLocalStorageUpdate')
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
await this.nextTick
|
|
1153
|
+
if (this.getLocalStorageItemNameUpdate.value) {
|
|
1154
|
+
localStorage.setItem(
|
|
1155
|
+
this.getLocalStorageItemNameUpdate.value,
|
|
1156
|
+
JSON.stringify(this.getComponents.value),
|
|
1157
|
+
)
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
async removeItemComponentsLocalStorageUpdate() {
|
|
1161
|
+
if (this.showRunningMethodLogs) {
|
|
1162
|
+
console.log('saveComponentsLocalStorageUpdate')
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
await this.nextTick
|
|
1166
|
+
if (this.getLocalStorageItemNameUpdate.value) {
|
|
1167
|
+
localStorage.removeItem(this.getLocalStorageItemNameUpdate.value)
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
areComponentsStoredInLocalStorage() {
|
|
1172
|
+
if (this.showRunningMethodLogs) {
|
|
1173
|
+
console.log('areComponentsStoredInLocalStorage')
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
if (!this.getLocalStorageItemName.value) return false
|
|
1177
|
+
|
|
1178
|
+
const savedCurrentDesign = localStorage.getItem(this.getLocalStorageItemName.value)
|
|
1179
|
+
if (savedCurrentDesign) {
|
|
1180
|
+
let components = JSON.parse(savedCurrentDesign)
|
|
1181
|
+
if (!components) {
|
|
1182
|
+
components = []
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
this.pageBuilderStateStore.setComponents(components)
|
|
1186
|
+
|
|
1187
|
+
return true
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
return false
|
|
1191
|
+
}
|
|
1192
|
+
//
|
|
1193
|
+
areComponentsStoredInLocalStorageUpdate() {
|
|
1194
|
+
if (this.showRunningMethodLogs) {
|
|
1195
|
+
console.log('areComponentsStoredInLocalStorageUpdate')
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
if (!this.getLocalStorageItemNameUpdate.value) return false
|
|
1199
|
+
|
|
1200
|
+
const savedCurrentDesign = localStorage.getItem(this.getLocalStorageItemNameUpdate.value)
|
|
1201
|
+
if (savedCurrentDesign) {
|
|
1202
|
+
let components = JSON.parse(savedCurrentDesign)
|
|
1203
|
+
if (!components) {
|
|
1204
|
+
components = []
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
this.pageBuilderStateStore.setComponents(components)
|
|
1208
|
+
|
|
1209
|
+
return true
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
return false
|
|
1213
|
+
}
|
|
1214
|
+
//
|
|
1215
|
+
async updateBasePrimaryImage(data: { type: string }): Promise<void> {
|
|
1216
|
+
if (this.showRunningMethodLogs) {
|
|
1217
|
+
console.log('updateBasePrimaryImage')
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
if (!this.getElement.value) return
|
|
1221
|
+
|
|
1222
|
+
if (data.type === 'unsplash' && this.getCurrentImage.value) {
|
|
1223
|
+
if (this.getCurrentImage.value.file) {
|
|
1224
|
+
await this.nextTick
|
|
1225
|
+
|
|
1226
|
+
this.pageBuilderStateStore.setBasePrimaryImage(`${this.getCurrentImage.value.file}`)
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
showBasePrimaryImage() {
|
|
1232
|
+
if (this.showRunningMethodLogs) {
|
|
1233
|
+
console.log('showBasePrimaryImage')
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
if (!this.getElement.value) return
|
|
1237
|
+
|
|
1238
|
+
const currentImageContainer = document.createElement('div')
|
|
1239
|
+
|
|
1240
|
+
currentImageContainer.innerHTML = this.getElement.value.outerHTML
|
|
1241
|
+
|
|
1242
|
+
// Get all img and div within the current image container
|
|
1243
|
+
const imgElements = currentImageContainer.getElementsByTagName('img')
|
|
1244
|
+
const divElements = currentImageContainer.getElementsByTagName('div')
|
|
1245
|
+
|
|
1246
|
+
// Check if there is exactly one img and no div
|
|
1247
|
+
if (imgElements.length === 1 && divElements.length === 0) {
|
|
1248
|
+
// Return the source of the only img
|
|
1249
|
+
|
|
1250
|
+
this.pageBuilderStateStore.setBasePrimaryImage(imgElements[0].src)
|
|
1251
|
+
|
|
1252
|
+
return
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
this.pageBuilderStateStore.setBasePrimaryImage(null)
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
#addHyperlinkToElement(
|
|
1259
|
+
hyperlinkEnable: boolean,
|
|
1260
|
+
urlInput: string | null,
|
|
1261
|
+
openHyperlinkInNewTab: boolean,
|
|
1262
|
+
) {
|
|
1263
|
+
if (this.showRunningMethodLogs) {
|
|
1264
|
+
console.log('#addHyperlinkToElement')
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
if (!this.shouldRunMethods()) return
|
|
1268
|
+
if (!this.getElement.value) return
|
|
1269
|
+
|
|
1270
|
+
const parentHyperlink = this.getElement.value.closest('a')
|
|
1271
|
+
const hyperlink = this.getElement.value.querySelector('a')
|
|
1272
|
+
|
|
1273
|
+
this.pageBuilderStateStore.setHyperlinkError(null)
|
|
1274
|
+
|
|
1275
|
+
// url validation
|
|
1276
|
+
const urlRegex = /^https?:\/\//
|
|
1277
|
+
|
|
1278
|
+
const isValidURL = ref(true)
|
|
1279
|
+
|
|
1280
|
+
if (hyperlinkEnable === true && urlInput !== null) {
|
|
1281
|
+
isValidURL.value = urlRegex.test(urlInput)
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
if (isValidURL.value === false) {
|
|
1285
|
+
this.pageBuilderStateStore.setHyperlinkMessage(null)
|
|
1286
|
+
|
|
1287
|
+
this.pageBuilderStateStore.setHyperlinkError('URL is not valid')
|
|
1288
|
+
return
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
if (hyperlinkEnable === true && typeof urlInput === 'string') {
|
|
1292
|
+
// check if element contains child hyperlink tag
|
|
1293
|
+
// updated existing url
|
|
1294
|
+
if (hyperlink !== null && urlInput.length !== 0) {
|
|
1295
|
+
hyperlink.href = urlInput
|
|
1296
|
+
|
|
1297
|
+
// Conditionally set the target attribute if openHyperlinkInNewTab is true
|
|
1298
|
+
if (openHyperlinkInNewTab === true) {
|
|
1299
|
+
hyperlink.target = '_blank'
|
|
1300
|
+
}
|
|
1301
|
+
if (openHyperlinkInNewTab === false) {
|
|
1302
|
+
hyperlink.removeAttribute('target')
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
hyperlink.textContent = this.getElement.value.textContent
|
|
1306
|
+
|
|
1307
|
+
this.pageBuilderStateStore.setHyperlinkMessage('Succesfully updated element hyperlink')
|
|
1308
|
+
|
|
1309
|
+
this.pageBuilderStateStore.setElementContainsHyperlink(true)
|
|
1310
|
+
|
|
1311
|
+
return
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
// check if element contains child a tag
|
|
1315
|
+
if (hyperlink === null && urlInput.length !== 0) {
|
|
1316
|
+
// add a href
|
|
1317
|
+
if (parentHyperlink === null) {
|
|
1318
|
+
const link = document.createElement('a')
|
|
1319
|
+
link.href = urlInput
|
|
1320
|
+
|
|
1321
|
+
// Conditionally set the target attribute if openHyperlinkInNewTab is true
|
|
1322
|
+
if (openHyperlinkInNewTab === true) {
|
|
1323
|
+
link.target = '_blank'
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
link.textContent = this.getElement.value.textContent
|
|
1327
|
+
this.getElement.value.textContent = ''
|
|
1328
|
+
this.getElement.value.appendChild(link)
|
|
1329
|
+
|
|
1330
|
+
this.pageBuilderStateStore.setHyperlinkMessage('Successfully added hyperlink to element')
|
|
1331
|
+
|
|
1332
|
+
this.pageBuilderStateStore.setElementContainsHyperlink(true)
|
|
1333
|
+
|
|
1334
|
+
return
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
//
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
if (hyperlinkEnable === false && urlInput === 'removeHyperlink') {
|
|
1341
|
+
// To remove the added hyperlink tag
|
|
1342
|
+
const originalText = this.getElement.value.textContent || ''
|
|
1343
|
+
const textNode = document.createTextNode(originalText)
|
|
1344
|
+
this.getElement.value.textContent = ''
|
|
1345
|
+
this.getElement.value.appendChild(textNode)
|
|
1346
|
+
|
|
1347
|
+
this.pageBuilderStateStore.setHyberlinkEnable(false)
|
|
1348
|
+
this.pageBuilderStateStore.setElementContainsHyperlink(false)
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
#checkForHyperlink() {
|
|
1353
|
+
if (this.showRunningMethodLogs) {
|
|
1354
|
+
console.log('#checkForHyperlink')
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
if (!this.shouldRunMethods()) return
|
|
1358
|
+
if (!this.getElement.value) return
|
|
1359
|
+
|
|
1360
|
+
const hyperlink = this.getElement.value.querySelector('a')
|
|
1361
|
+
if (hyperlink !== null) {
|
|
1362
|
+
this.pageBuilderStateStore.setHyberlinkEnable(true)
|
|
1363
|
+
this.pageBuilderStateStore.setElementContainsHyperlink(true)
|
|
1364
|
+
this.pageBuilderStateStore.setHyperlinkInput(hyperlink.href)
|
|
1365
|
+
this.pageBuilderStateStore.setHyperlinkMessage(null)
|
|
1366
|
+
this.pageBuilderStateStore.setHyperlinkError(null)
|
|
1367
|
+
|
|
1368
|
+
if (hyperlink.target === '_blank') {
|
|
1369
|
+
this.pageBuilderStateStore.setOpenHyperlinkInNewTab(true)
|
|
1370
|
+
}
|
|
1371
|
+
if (hyperlink.target !== '_blank') {
|
|
1372
|
+
this.pageBuilderStateStore.setOpenHyperlinkInNewTab(false)
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
return
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
this.pageBuilderStateStore.setElementContainsHyperlink(false)
|
|
1379
|
+
this.pageBuilderStateStore.setHyperlinkInput('')
|
|
1380
|
+
this.pageBuilderStateStore.setHyperlinkError(null)
|
|
1381
|
+
this.pageBuilderStateStore.setHyperlinkMessage(null)
|
|
1382
|
+
this.pageBuilderStateStore.setHyberlinkEnable(false)
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
handleHyperlink(
|
|
1386
|
+
hyperlinkEnable?: boolean,
|
|
1387
|
+
urlInput?: string | null,
|
|
1388
|
+
openHyperlinkInNewTab?: boolean,
|
|
1389
|
+
): void {
|
|
1390
|
+
if (this.showRunningMethodLogs) {
|
|
1391
|
+
console.log('handleHyperlink')
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
if (!this.shouldRunMethods()) return
|
|
1395
|
+
|
|
1396
|
+
this.pageBuilderStateStore.setHyperlinkAbility(true)
|
|
1397
|
+
|
|
1398
|
+
const parentHyperlink = this.getElement.value?.closest('a')
|
|
1399
|
+
|
|
1400
|
+
// handle case where parent element already has an a href tag
|
|
1401
|
+
// when clicking directly on a hyperlink
|
|
1402
|
+
if (parentHyperlink !== null) {
|
|
1403
|
+
this.pageBuilderStateStore.setHyperlinkAbility(false)
|
|
1404
|
+
}
|
|
1405
|
+
//
|
|
1406
|
+
const elementTag = this.getElement.value?.tagName.toUpperCase()
|
|
1407
|
+
|
|
1408
|
+
if (
|
|
1409
|
+
elementTag !== 'P' &&
|
|
1410
|
+
elementTag !== 'H1' &&
|
|
1411
|
+
elementTag !== 'H2' &&
|
|
1412
|
+
elementTag !== 'H3' &&
|
|
1413
|
+
elementTag !== 'H4' &&
|
|
1414
|
+
elementTag !== 'H5' &&
|
|
1415
|
+
elementTag !== 'H6'
|
|
1416
|
+
) {
|
|
1417
|
+
this.pageBuilderStateStore.setHyperlinkAbility(false)
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
if (hyperlinkEnable === undefined) {
|
|
1421
|
+
this.#checkForHyperlink()
|
|
1422
|
+
return
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
this.#addHyperlinkToElement(hyperlinkEnable, urlInput || null, openHyperlinkInNewTab || false)
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
handlePageBuilderMethods(): void {
|
|
1429
|
+
if (!this.shouldRunMethods()) return
|
|
1430
|
+
|
|
1431
|
+
this.pageBuilderStateStore.setParentElement(null)
|
|
1432
|
+
this.pageBuilderStateStore.setRestoredElement(null)
|
|
1433
|
+
|
|
1434
|
+
// handle custom URL
|
|
1435
|
+
this.handleHyperlink(undefined, null, false)
|
|
1436
|
+
// handle opacity
|
|
1437
|
+
this.handleOpacity(undefined)
|
|
1438
|
+
// handle BG opacity
|
|
1439
|
+
this.handleBackgroundOpacity(undefined)
|
|
1440
|
+
// displayed image
|
|
1441
|
+
this.showBasePrimaryImage()
|
|
1442
|
+
// border style
|
|
1443
|
+
this.handleBorderStyle(undefined)
|
|
1444
|
+
// border width
|
|
1445
|
+
this.handleBorderWidth(undefined)
|
|
1446
|
+
// border color
|
|
1447
|
+
this.handleBorderColor(undefined)
|
|
1448
|
+
// border radius
|
|
1449
|
+
this.handleBorderRadiusGlobal(undefined)
|
|
1450
|
+
// border radius
|
|
1451
|
+
this.handleBorderRadiusTopLeft(undefined)
|
|
1452
|
+
// border radius
|
|
1453
|
+
this.handleBorderRadiusTopRight(undefined)
|
|
1454
|
+
// border radius
|
|
1455
|
+
this.handleBorderRadiusBottomleft(undefined)
|
|
1456
|
+
// border radius
|
|
1457
|
+
this.handleBorderRadiusBottomRight(undefined)
|
|
1458
|
+
// handle font size
|
|
1459
|
+
this.handleFontSize(undefined)
|
|
1460
|
+
// handle font weight
|
|
1461
|
+
this.handleFontWeight(undefined)
|
|
1462
|
+
// handle font family
|
|
1463
|
+
this.handleFontFamily(undefined)
|
|
1464
|
+
// handle font style
|
|
1465
|
+
this.handleFontStyle(undefined)
|
|
1466
|
+
// handle vertical padding
|
|
1467
|
+
this.handleVerticalPadding(undefined)
|
|
1468
|
+
// handle horizontal padding
|
|
1469
|
+
this.handleHorizontalPadding(undefined)
|
|
1470
|
+
// handle vertical margin
|
|
1471
|
+
this.handleVerticalMargin(undefined)
|
|
1472
|
+
// handle horizontal margin
|
|
1473
|
+
this.handleHorizontalMargin(undefined)
|
|
1474
|
+
// handle color
|
|
1475
|
+
this.handleBackgroundColor(undefined)
|
|
1476
|
+
// handle text color
|
|
1477
|
+
this.handleTextColor(undefined)
|
|
1478
|
+
// handle classes
|
|
1479
|
+
this.currentClasses()
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
export default PageBuilder
|