@myissue/vue-website-page-builder 3.3.92 → 3.3.94

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +51 -54
  2. package/dist/{ar-7SHqp8Wu.js → ar-B67ZvnES.js} +10 -7
  3. package/dist/{de-BqPxfNSH.js → de-2iNkasP-.js} +17 -14
  4. package/dist/{en-DJriivpm.js → en-BkPMvlrf.js} +27 -24
  5. package/dist/{es-DFK5Ddk2.js → es-CoKtBPFg.js} +21 -18
  6. package/dist/{fr-8Y1jH_zD.js → fr-Bb-szPYF.js} +19 -16
  7. package/dist/{hi-CAUlTFgq.js → hi-Z-tSAHna.js} +4 -1
  8. package/dist/{ja-pz4uHxB3.js → ja-BsFKC04n.js} +12 -9
  9. package/dist/{pt-DieK86-G.js → pt-CR27KWIb.js} +21 -18
  10. package/dist/{ru-MPhaLer-.js → ru-CVy3Csm4.js} +16 -13
  11. package/dist/style.css +1 -1
  12. package/dist/vue-website-page-builder.js +5205 -5121
  13. package/dist/vue-website-page-builder.umd.cjs +35 -33
  14. package/dist/{zh-Hans-BEWY32Aq.js → zh-Hans-9bdCn2lI.js} +4 -1
  15. package/package.json +1 -1
  16. package/src/Components/Modals/ModalBuilder.vue +1 -1
  17. package/src/Components/PageBuilder/EditorMenu/Editables/HTMLEditor.vue +152 -28
  18. package/src/Components/PageBuilder/EditorMenu/Editables/Margin.vue +6 -0
  19. package/src/Components/PageBuilder/EditorMenu/Editables/Padding.vue +6 -0
  20. package/src/Components/PageBuilder/EditorMenu/RightSidebarEditor.vue +1 -1
  21. package/src/PageBuilder/PageBuilder.vue +2 -2
  22. package/src/css/style.css +1 -2
  23. package/src/locales/ar.json +5 -2
  24. package/src/locales/de.json +4 -1
  25. package/src/locales/en.json +4 -1
  26. package/src/locales/es.json +4 -1
  27. package/src/locales/fr.json +4 -1
  28. package/src/locales/hi.json +4 -1
  29. package/src/locales/ja.json +7 -4
  30. package/src/locales/pt.json +4 -1
  31. package/src/locales/ru.json +5 -2
  32. package/src/locales/zh-Hans.json +4 -1
  33. package/src/services/PageBuilderService.ts +135 -187
  34. package/src/utils/builder/tailwind-padding-margin.ts +136 -136
@@ -478,67 +478,97 @@ export class PageBuilderService {
478
478
  await this.clearHtmlSelection()
479
479
 
480
480
  if (formType === 'update' || formType === 'create') {
481
+ // Page Builder is initially present in the DOM
481
482
  if (!this.pendingMountComponents) {
482
- // Page Builder Is initially present in DOM
483
483
  if (!passedComponentsArray && this.isPageBuilderMissingOnStart && localStorageData) {
484
484
  await this.completeMountProcess(localStorageData)
485
485
  return
486
486
  }
487
487
  if (passedComponentsArray && !localStorageData) {
488
- await this.completeMountProcess(JSON.stringify(passedComponentsArray), true)
488
+ const htmlString = this.renderComponentsToHtml(passedComponentsArray)
489
+ await this.completeMountProcess(htmlString, true)
489
490
  this.saveDomComponentsToLocalStorage()
490
491
  return
491
492
  }
492
493
 
493
494
  if (passedComponentsArray && localStorageData) {
495
+ const htmlString = this.renderComponentsToHtml(passedComponentsArray)
496
+ await this.completeMountProcess(htmlString, true)
497
+ await delay(500)
494
498
  this.pageBuilderStateStore.setHasLocalDraftForUpdate(true)
495
- await this.completeMountProcess(JSON.stringify(passedComponentsArray), true)
496
499
  return
497
500
  }
501
+
498
502
  if (!passedComponentsArray && localStorageData && !this.savedMountComponents) {
499
503
  await this.completeMountProcess(localStorageData)
500
504
  return
501
505
  }
502
506
  if (!passedComponentsArray && this.savedMountComponents && localStorageData) {
503
- await this.completeMountProcess(JSON.stringify(this.savedMountComponents))
507
+ const htmlString = this.renderComponentsToHtml(this.savedMountComponents)
508
+ await this.completeMountProcess(htmlString)
504
509
  return
505
510
  }
506
511
 
507
512
  if (!passedComponentsArray && !localStorageData && this.isPageBuilderMissingOnStart) {
508
- await this.completeMountProcess(JSON.stringify([]))
513
+ const htmlString = this.renderComponentsToHtml([])
514
+ await this.completeMountProcess(htmlString)
515
+
509
516
  return
510
517
  }
511
518
 
512
519
  if (!this.isPageBuilderMissingOnStart && !localStorageData && !passedComponentsArray) {
513
- await this.completeMountProcess(JSON.stringify([]))
520
+ const htmlString = this.renderComponentsToHtml([])
521
+ await this.completeMountProcess(htmlString)
514
522
  return
515
523
  }
516
524
  }
517
525
 
518
- // FOCUS ON: pendingMountComponents
526
+ // Page Builder is not initially present in the DOM
519
527
  if (this.pendingMountComponents) {
520
- // No Page Builder Is present in DOM initially
521
528
  if (localStorageData && this.isPageBuilderMissingOnStart) {
522
- await this.completeMountProcess(JSON.stringify(this.pendingMountComponents), true)
523
- await delay(400)
529
+ const htmlString = this.renderComponentsToHtml(this.pendingMountComponents)
530
+ await this.completeMountProcess(htmlString, true)
531
+ await delay(500)
524
532
  this.pageBuilderStateStore.setHasLocalDraftForUpdate(true)
525
533
  this.pendingMountComponents = null
526
534
  return
527
535
  }
528
536
  if (!localStorageData && passedComponentsArray && this.isPageBuilderMissingOnStart) {
529
- await this.completeMountProcess(JSON.stringify(this.pendingMountComponents), true)
537
+ const htmlString = this.renderComponentsToHtml(this.pendingMountComponents)
538
+ await this.completeMountProcess(htmlString, true)
530
539
  this.saveDomComponentsToLocalStorage()
531
540
  return
532
541
  }
533
542
 
534
543
  if (!passedComponentsArray && !localStorageData && this.isPageBuilderMissingOnStart) {
535
- await this.completeMountProcess(JSON.stringify(this.pendingMountComponents), true)
544
+ const htmlString = this.renderComponentsToHtml(this.pendingMountComponents)
545
+ await this.completeMountProcess(htmlString, true)
536
546
  this.saveDomComponentsToLocalStorage()
537
547
  return
538
548
  }
539
549
  }
540
550
  }
541
- //
551
+ }
552
+
553
+ /**
554
+ * Converts an array of ComponentObject into a single HTML string.
555
+ *
556
+ * @returns {string} A single HTML string containing all components.
557
+ */
558
+ private renderComponentsToHtml(componentsArray: BuilderResourceData): string {
559
+ // If the componentsArray is empty or invalid, return a default HTML structure
560
+ if (!componentsArray || (Array.isArray(componentsArray) && componentsArray.length === 0)) {
561
+ return `<div id="pagebuilder" class="pbx-text-black pbx-font-sans"></div>`
562
+ }
563
+
564
+ const sectionsHtml = componentsArray
565
+ .map((component) => {
566
+ return component.html_code // Fallback in case section is not found
567
+ })
568
+ .join('\n')
569
+
570
+ // Return the combined HTML string
571
+ return sectionsHtml
542
572
  }
543
573
 
544
574
  /**
@@ -552,14 +582,8 @@ export class PageBuilderService {
552
582
 
553
583
  // Clean up any old localStorage items related to previous builder sessions
554
584
  this.deleteOldPageBuilderLocalStorage()
555
-
556
585
  this.pageBuilderStateStore.setIsRestoring(false)
557
586
  this.pageBuilderStateStore.setIsLoadingGlobal(false)
558
-
559
- // Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
560
- await nextTick()
561
- // Attach event listeners to all editable elements in the Builder
562
- await this.addListenersToEditableElements()
563
587
  }
564
588
 
565
589
  /**
@@ -1069,7 +1093,6 @@ export class PageBuilderService {
1069
1093
 
1070
1094
  // Set the title attribute if present
1071
1095
  if (clonedComponent.title) {
1072
- section.setAttribute('title', clonedComponent.title)
1073
1096
  section.setAttribute('data-component-title', clonedComponent.title)
1074
1097
  }
1075
1098
 
@@ -1951,7 +1974,8 @@ export class PageBuilderService {
1951
1974
  if (Array.isArray(this.originalComponents)) {
1952
1975
  await this.clearClassesFromPage()
1953
1976
  await this.clearInlineStylesFromPage()
1954
- await this.mountComponentsToDOM(JSON.stringify(this.originalComponents), true)
1977
+ const htmlString = this.renderComponentsToHtml(this.originalComponents)
1978
+ await this.mountComponentsToDOM(htmlString)
1955
1979
  this.removeCurrentComponentsFromLocalStorage()
1956
1980
  }
1957
1981
 
@@ -1991,9 +2015,24 @@ export class PageBuilderService {
1991
2015
  const classes = (parsed.pageSettings && parsed.pageSettings.classes) || ''
1992
2016
  const style = (parsed.pageSettings && parsed.pageSettings.style) || ''
1993
2017
 
1994
- const sectionsHtml = parsed.components.map((c: ComponentObject) => c.html_code).join('\n')
2018
+ const sectionsHtml = parsed.components
2019
+ .map((c: ComponentObject) => {
2020
+ const parser = new DOMParser()
2021
+ const doc = parser.parseFromString(c.html_code, 'text/html')
2022
+ const section = doc.querySelector('section')
2023
+
2024
+ if (section) {
2025
+ section.removeAttribute('data-componentid') // Remove the data-componentid attribute
2026
+ return section.outerHTML
2027
+ }
2028
+
2029
+ return c.html_code // Fallback in case section is not found
2030
+ })
2031
+ .join('\n')
2032
+
1995
2033
  return `<div id="pagebuilder" class="${classes}" style="${style}">\n${sectionsHtml}\n</div>`
1996
2034
  }
2035
+
1997
2036
  return false
1998
2037
  }
1999
2038
 
@@ -2370,10 +2409,7 @@ export class PageBuilderService {
2370
2409
  components = topLevelSections.map((section) => ({
2371
2410
  id: null,
2372
2411
  html_code: section.outerHTML.trim(),
2373
- title:
2374
- section.getAttribute('data-component-title') ||
2375
- section.getAttribute('title') ||
2376
- 'Untitled Component',
2412
+ title: section.getAttribute('data-component-title') || 'Untitled Component',
2377
2413
  }))
2378
2414
  }
2379
2415
  if (topLevelSections.length === 0) {
@@ -2417,183 +2453,69 @@ export class PageBuilderService {
2417
2453
  }
2418
2454
 
2419
2455
  /**
2420
- * Parse and set components from JSON or HTML data
2456
+ * Mounts builder components to the DOM from an HTML string.
2421
2457
  *
2422
- * Supports:
2423
- * - JSON: Array of ComponentObject with html_code, id, title
2424
- * - HTML: String containing <section data-componentid="..."> elements
2458
+ * Input format detection:
2459
+ * - If the input starts with `[` or `{`: treated as JSON (array or object).
2460
+ * - If the input starts with `<`: treated as HTML.
2425
2461
  *
2426
- * Auto-detects format and parses accordingly
2462
+ * This function should be used when:
2463
+ * - Restoring the builder from a published HTML snapshot.
2464
+ * - Importing a static HTML export.
2465
+ * - Loading the builder from previously published or saved HTML (e.g., from `getSavedPageHtml()`).
2427
2466
  *
2428
- * @param data - JSON string (e.g., '[{"html_code":"...","id":"123","title":"..."}]')
2429
- * OR HTML string (e.g., '<section data-componentid="123">...</section>')
2467
+ * Typical use cases include restoring a published state, importing templates, or previewing published content.
2430
2468
  */
2431
2469
  private async mountComponentsToDOM(
2432
2470
  htmlString: string,
2433
2471
  usePassedPageSettings?: boolean,
2434
2472
  ): Promise<void> {
2435
- /**
2436
- * Mounts builder components to the DOM from either JSON or HTML input.
2437
- *
2438
- * Input format detection:
2439
- * - If the input starts with `[` or `{`, it is treated as JSON (array or object).
2440
- * - If the input starts with `<`, it is treated as HTML.
2441
- *
2442
- * When to use which format:
2443
- *
2444
- * 1. JSON input (from localStorage, API, or internal state like pina):
2445
- * - Use when restoring builder state from localStorage, an API, or a previously saved draft.
2446
- * - Example: `localStorage.getItem(...)` or API returns a JSON stringified array/object of components.
2447
- * - This is the most common format for drafts, autosave, and programmatic state management.
2448
- * - Example usage:
2449
- * await this.mountComponentsToDOM(JSON.stringify(getComponents))
2450
- *
2451
- * 2. HTML input (from HTML snapshot, import, or published output):
2452
- * - Use when restoring from a published HTML snapshot, importing a static HTML export, or loading the builder from a previously published HTML string.
2453
- * - Example: output from `getSavedPageHtml()` or a static HTML export.
2454
- * - This is used for restoring the builder from a published state, importing, or previewing published content.
2455
- * - Example usage:
2456
- * await this.mountComponentsToDOM(savedHtmlString)
2457
- *
2458
- * Best practice:
2459
- * - Use JSON for local storage drafts, autosave, and API-driven workflows.
2460
- * - Use HTML for published/imported content from DB or when restoring from a static HTML snapshot.
2461
- *
2462
- * The method auto-detects the format and calls the appropriate parser.
2463
- */
2464
2473
  const trimmedData = htmlString.trim()
2465
2474
 
2475
+ // Return error since JSON data has been passed to mount HTML to DOM
2466
2476
  if (trimmedData.startsWith('[') || trimmedData.startsWith('{')) {
2467
- // JSON input: Use this when restoring from localStorage, API, or internal builder state (drafts, autosave, etc.)
2468
- await this.parseJSONComponents(trimmedData, usePassedPageSettings)
2469
- return
2470
- }
2471
- if (trimmedData.startsWith('<')) {
2472
- // HTML input: Use this when restoring from a published HTML snapshot, import, or static HTML export
2473
- await this.parseHTMLComponents(trimmedData, usePassedPageSettings)
2477
+ console.error('Error: JSON data passed to mountComponentsToDOM for the Page Builder Package.')
2474
2478
  return
2475
2479
  }
2476
2480
 
2477
- // Fallback: If format is unknown, default to JSON parser (defensive)
2478
- await this.parseJSONComponents(trimmedData, usePassedPageSettings)
2479
- }
2480
-
2481
- // Private method to parse JSON components and save pageBuilderContentSavedAt to localStorage
2482
- private async parseJSONComponents(
2483
- jsonData: string,
2484
- usePassedPageSettings?: boolean,
2485
- ): Promise<void> {
2486
- const pageSettings =
2487
- this.pageBuilderStateStore.getPageBuilderConfig &&
2488
- this.pageBuilderStateStore.getPageBuilderConfig.pageSettings
2489
-
2490
- const userPageSettings = usePassedPageSettings ? pageSettings : null
2491
-
2481
+ // HTML string
2492
2482
  try {
2493
- const parsedData = JSON.parse(jsonData)
2494
- let componentsArray: ComponentObject[] = []
2495
-
2496
- if (Array.isArray(parsedData)) {
2497
- componentsArray = parsedData
2498
- }
2499
- if (parsedData && Array.isArray(parsedData.components)) {
2500
- componentsArray = parsedData.components
2501
- }
2502
-
2503
- let savedCurrentDesign: ComponentObject[] = []
2504
-
2505
- if (componentsArray.length > 0) {
2506
- savedCurrentDesign = componentsArray.map((component: ComponentObject) => {
2507
- const parser = new DOMParser()
2508
- const doc = parser.parseFromString(component.html_code, 'text/html')
2509
- const section = doc.querySelector('section')
2483
+ const parser = new DOMParser()
2484
+ const doc = parser.parseFromString(htmlString, 'text/html')
2510
2485
 
2511
- if (section) {
2512
- // Prefix Tailwind classes
2513
- section.querySelectorAll('[class]').forEach((el) => {
2514
- el.setAttribute(
2515
- 'class',
2516
- this.addTailwindPrefixToClasses(el.getAttribute('class') || '', 'pbx-'),
2517
- )
2518
- })
2519
-
2520
- // Ensure IDs & titles
2521
- if (!section.hasAttribute('data-componentid')) {
2522
- const newId = uuidv4()
2523
- section.setAttribute('data-componentid', newId)
2524
- component.id = newId
2525
- } else {
2526
- component.id = section.getAttribute('data-componentid')!
2527
- }
2486
+ const importedPageBuilder = doc.querySelector('#pagebuilder') as HTMLElement | null
2487
+ const livePageBuilder = document.querySelector('#pagebuilder') as HTMLElement | null
2528
2488
 
2529
- const title = component.title || 'Untitled Component'
2530
- section.setAttribute('data-component-title', title)
2531
- component.title = title
2489
+ // Initialize pageSettings to null
2490
+ let pageSettings = null
2532
2491
 
2533
- // Update html_code
2534
- component.html_code = section.outerHTML
2535
- }
2536
- return component
2537
- })
2492
+ // Use stored page settings if the flag is true
2493
+ if (usePassedPageSettings) {
2494
+ pageSettings = this.pageBuilderStateStore.getPageBuilderConfig?.pageSettings || null
2538
2495
  }
2539
2496
 
2540
- this.pageBuilderStateStore.setComponents(savedCurrentDesign)
2541
-
2542
- await nextTick()
2543
- await this.addListenersToEditableElements()
2544
-
2545
- if (userPageSettings && pageSettings) {
2546
- const pagebuilder = document.querySelector('#pagebuilder') as HTMLElement
2547
- if (pagebuilder) {
2548
- pagebuilder.removeAttribute('class')
2549
- pagebuilder.removeAttribute('style')
2550
- pagebuilder.className = pageSettings.classes || ''
2551
- pagebuilder.setAttribute('style', this.convertStyleObjectToString(pageSettings.style))
2497
+ // Use imported page builder settings if available and pageSettings is still null
2498
+ if (!pageSettings && importedPageBuilder) {
2499
+ pageSettings = {
2500
+ classes: importedPageBuilder.className || '',
2501
+ style: importedPageBuilder.getAttribute('style') || '',
2552
2502
  }
2553
2503
  }
2554
- } catch (error) {
2555
- console.error('Error parsing JSON components:', error)
2556
- this.deleteAllComponentsFromDOM()
2557
- }
2558
- }
2559
2504
 
2560
- // Private method to parse HTML components
2561
- private async parseHTMLComponents(
2562
- htmlData: string,
2563
- usePassedPageSettings?: boolean,
2564
- ): Promise<void> {
2565
- try {
2566
- const parser = new DOMParser()
2567
- const doc = parser.parseFromString(htmlData, 'text/html')
2505
+ // Fallback to stored page settings if pageSettings is still null
2506
+ if (!pageSettings) {
2507
+ pageSettings = this.pageBuilderStateStore.getPageBuilderConfig?.pageSettings || null
2508
+ }
2568
2509
 
2569
- const importedPageBuilder = doc.querySelector('#pagebuilder') as HTMLElement | null
2570
- const livePageBuilder = document.querySelector('#pagebuilder') as HTMLElement | null
2510
+ // Apply the page settings to the live page builder
2511
+ if (pageSettings && livePageBuilder) {
2512
+ // Remove existing class and style attributes
2513
+ livePageBuilder.removeAttribute('class')
2514
+ livePageBuilder.removeAttribute('style')
2571
2515
 
2572
- if (livePageBuilder) {
2573
- const storedPageSettings =
2574
- this.pageBuilderStateStore.getPageBuilderConfig &&
2575
- this.pageBuilderStateStore.getPageBuilderConfig.pageSettings
2576
-
2577
- // Decide which pageSettings to use
2578
- let pageSettings = null
2579
- if (usePassedPageSettings) {
2580
- pageSettings = storedPageSettings
2581
- } else if (importedPageBuilder) {
2582
- pageSettings = {
2583
- classes: importedPageBuilder.className || '',
2584
- style: importedPageBuilder.getAttribute('style') || '',
2585
- }
2586
- } else {
2587
- pageSettings = storedPageSettings
2588
- }
2589
-
2590
- // Restore page-level settings like class and style
2591
- if (pageSettings) {
2592
- livePageBuilder.removeAttribute('class')
2593
- livePageBuilder.removeAttribute('style')
2594
- livePageBuilder.className = pageSettings.classes || ''
2595
- livePageBuilder.setAttribute('style', this.convertStyleObjectToString(pageSettings.style))
2596
- }
2516
+ // Apply new classes and styles
2517
+ livePageBuilder.className = pageSettings.classes || ''
2518
+ livePageBuilder.setAttribute('style', this.convertStyleObjectToString(pageSettings.style))
2597
2519
  }
2598
2520
 
2599
2521
  // Select all <section> elements
@@ -2618,10 +2540,7 @@ export class PageBuilderService {
2618
2540
  const componentId = htmlElement.getAttribute('data-componentid')!
2619
2541
 
2620
2542
  // Ensure data-component-title exists
2621
- const title =
2622
- htmlElement.getAttribute('title') ||
2623
- htmlElement.getAttribute('data-component-title') ||
2624
- 'Untitled Component'
2543
+ const title = htmlElement.getAttribute('data-component-title') || 'Untitled Component'
2625
2544
 
2626
2545
  htmlElement.setAttribute('data-component-title', title)
2627
2546
 
@@ -2641,6 +2560,10 @@ export class PageBuilderService {
2641
2560
  } catch (error) {
2642
2561
  console.error('Error parsing HTML components:', error)
2643
2562
  this.deleteAllComponentsFromDOM()
2563
+ // Clear selections and re-bind events
2564
+ await this.clearHtmlSelection()
2565
+ await nextTick()
2566
+ await this.addListenersToEditableElements()
2644
2567
  }
2645
2568
  }
2646
2569
 
@@ -2792,30 +2715,55 @@ export class PageBuilderService {
2792
2715
  }
2793
2716
  }
2794
2717
 
2795
- public async applyModifiedHTML(htmlString: string) {
2718
+ /**
2719
+ * Applies modified components by mounting them to the DOM and attaching listeners.
2720
+ * @param htmlString - The HTML string to apply
2721
+ * @returns {Promise<string | null>} - Returns error message if failed, otherwise null
2722
+ */
2723
+ public async applyModifiedHTML(htmlString: string): Promise<string | null> {
2724
+ if (!htmlString || (typeof htmlString === 'string' && htmlString.length === 0)) {
2725
+ return 'No HTML content was provided. Please ensure a valid HTML string is passed.'
2726
+ }
2727
+
2796
2728
  const tempDiv = document.createElement('div')
2797
2729
  tempDiv.innerHTML = htmlString.trim()
2798
2730
 
2799
2731
  const parsedElement = tempDiv.firstElementChild as HTMLElement | null
2800
2732
 
2801
2733
  if (!parsedElement) {
2802
- console.warn('Could not parse element from HTML string:', htmlString)
2803
- return
2734
+ return 'Could not parse element from HTML string.'
2804
2735
  }
2805
2736
 
2806
2737
  // Replace the actual DOM element
2807
2738
  const oldElement = this.pageBuilderStateStore.getElement
2739
+
2808
2740
  if (oldElement && oldElement.parentElement) {
2809
2741
  oldElement.replaceWith(parsedElement)
2810
2742
 
2811
2743
  // Update the element in the store (now referencing the new one)
2812
2744
  this.pageBuilderStateStore.setElement(parsedElement)
2813
- } else {
2814
- console.warn('No valid element to replace in DOM')
2815
2745
  }
2816
2746
 
2817
2747
  await this.addListenersToEditableElements()
2818
2748
  await nextTick()
2749
+ return null
2750
+ }
2751
+
2752
+ /**
2753
+ * Applies modified components by mounting them to the DOM and attaching listeners.
2754
+ * @param htmlString - The HTML string to apply
2755
+ * @returns {Promise<string | null>} - Returns error message if failed, otherwise null
2756
+ */
2757
+ public async applyModifiedComponents(htmlString: string): Promise<string | null> {
2758
+ if (!htmlString || (typeof htmlString === 'string' && htmlString.length === 0)) {
2759
+ return 'No HTML content was provided. Please ensure a valid HTML string is passed.'
2760
+ }
2761
+
2762
+ await this.mountComponentsToDOM(htmlString)
2763
+
2764
+ await this.addListenersToEditableElements()
2765
+ await nextTick()
2766
+ return null
2819
2767
  }
2820
2768
 
2821
2769
  /**