{"version":3,"file":"live-preview-rails-client-DCYbIDvy.js","sources":["../../../app/javascript/live-preview-client/run-scripts.js","../../../app/javascript/live-preview-client/rails.js","../../../app/javascript/entrypoints/live-preview-rails-client.js"],"sourcesContent":["export default function (element) {\n var scripts\n\n // Get the scripts\n scripts = element.getElementsByTagName('script')\n\n // Run them in sequence (remember NodeLists are live)\n continueLoading()\n\n function continueLoading() {\n var script, newscript\n\n // While we have a script to load...\n while (scripts.length) {\n // Get it and remove it from the DOM\n script = scripts[0]\n script.parentNode.removeChild(script)\n\n // Create a replacement for it\n newscript = document.createElement('script')\n\n // External?\n if (script.src) {\n // Yes, we'll have to wait until it's loaded before continuing\n newscript.onerror = continueLoadingOnError\n newscript.onload = continueLoadingOnLoad\n newscript.onreadystatechange = continueLoadingOnReady\n newscript.src = script.src\n newscript.defer = script.defer\n newscript.type = script.type\n } else {\n // No, we can do it right away\n newscript.text = script.text\n newscript.type = script.type\n }\n\n // Start the script\n document.documentElement.appendChild(newscript)\n\n // If it's external, wait for callback\n if (script.src) {\n return\n }\n }\n\n // All scripts loaded\n newscript = undefined\n\n // Callback on most browsers when a script is loaded\n function continueLoadingOnLoad() {\n // Defend against duplicate calls\n if (this === newscript) {\n continueLoading()\n }\n }\n\n // Callback on most browsers when a script fails to load\n function continueLoadingOnError() {\n // Defend against duplicate calls\n if (this === newscript) {\n continueLoading()\n }\n }\n\n // Callback on IE when a script's loading status changes\n function continueLoadingOnReady() {\n // Defend against duplicate calls and check whether the\n // script is complete (complete = loaded or error)\n if (this === newscript && this.readyState === 'complete') {\n continueLoading()\n }\n }\n }\n}\n","import axios from 'axios'\nimport { debounce } from './utils'\nimport runScripts from './run-scripts'\n\nconst parentDocument = window.parent.document\nconst previewDocument = window.document\nconst csrfParam =\n window.location !== window.parent.location\n ? {\n [parentDocument\n .querySelector(\"meta[name='csrf-param']\")\n .getAttribute('content')]: parentDocument\n .querySelector(\"meta[name='csrf-token']\")\n .getAttribute('content'),\n }\n : {}\n\nconst start = () => {\n // Within a Rails site, no need to remove the event listeners\n window.addEventListener('maglev:section:add', addSection)\n window.addEventListener('maglev:section:move', moveSections)\n window.addEventListener('maglev:section:update', updateSection)\n window.addEventListener('maglev:section:remove', removeSection)\n window.addEventListener('maglev:block:add', replaceSection)\n window.addEventListener('maglev:block:move', replaceSection)\n window.addEventListener('maglev:block:update', updateBlock)\n window.addEventListener('maglev:block:remove', replaceSection)\n\n window.addEventListener('maglev:themeSettings:update', updateThemeSettings)\n}\n\nexport default { start }\n\n// === Section related actions ===\n\nconst addSection = (event) => {\n const { content, section, insertAt } = event.detail\n debouncedUpdatePreviewDocument(content, section, insertAt)\n}\n\nconst moveSections = (event) => {\n const { sectionId, targetSectionId, direction } = event.detail\n\n const sectionElement = previewDocument.querySelector(\n `[data-maglev-section-id='${sectionId}']`,\n )\n const targetSectionElement = previewDocument.querySelector(\n `[data-maglev-section-id='${targetSectionId}']`,\n )\n\n if (direction === 'up')\n targetSectionElement.parentNode.insertBefore(\n sectionElement,\n targetSectionElement,\n )\n else\n targetSectionElement.parentNode.insertBefore(\n sectionElement,\n targetSectionElement.nextSibling,\n )\n\n // scroll to the new placement of the section\n sectionElement.scrollIntoView(true)\n}\n\nconst updateSection = (event) => {\n const { content, section, change } = event.detail\n updateSectionOrBlock(content, section, section, change)\n}\n\nconst removeSection = (event) => {\n const { sectionId } = event.detail\n const selector = `[data-maglev-section-id='${sectionId}']`\n let element = previewDocument.querySelector(selector)\n element.remove()\n}\n\n// === Block related actions ===\n\nconst updateBlock = (event) => {\n const { content, section, sectionBlock, change } = event.detail\n updateSectionOrBlock(content, section, sectionBlock, change)\n}\n\nconst replaceSection = (event) => {\n const { content, section } = event.detail\n debouncedUpdatePreviewDocument(content, section)\n}\n\n// === Other actions ===\n\nconst updateThemeSettings = async (event) => {\n const { content, themeSettings } = event.detail\n\n const doc = await getUpdatedDoc({\n pageSections: JSON.stringify(content.pageSections),\n themeSettings: JSON.stringify(themeSettings),\n })\n // removeEventListeners()\n // previewDocument.querySelector('body').replaceWith(doc.querySelector('body'))\n // setupEvents(previewDocument)\n previewDocument.querySelector('head').innerHTML = doc.querySelector('head').innerHTML\n previewDocument.querySelector('body').innerHTML = doc.querySelector('body').innerHTML\n runScripts(previewDocument.querySelector('head'))\n runScripts(previewDocument.querySelector('body'))\n}\n\n// === Helpers ===\n\nconst updateSectionOrBlock = (content, section, source, change) => {\n const foundSetting = updateSetting(source, change)\n if (!foundSetting) debouncedUpdatePreviewDocument(content, section)\n}\n\nconst updateSetting = (source, change) => {\n switch (change.settingType) {\n case 'text':\n return updateTextSetting(source, change)\n case 'link':\n if (change.settingOptions.withText && change.value)\n return updateTextSetting(source, {\n ...change,\n value: change.value.text,\n settingId: `${change.settingId}.text`,\n })\n break\n default:\n // ok, we can't cherry-pick the modification so we have to refresh the whole section\n break\n }\n return false\n}\n\nconst updateTextSetting = (source, change) => {\n const selector = `[data-maglev-id='${source.id}.${change.settingId}']`\n const settings = previewDocument.querySelectorAll(selector)\n settings.forEach(($el) => ($el.innerHTML = change.value))\n return settings.length > 0\n}\n\nconst updatePreviewDocument = async (content, section, insertAt) => {\n const doc = await getUpdatedDoc({\n pageSections: JSON.stringify([\n content.pageSections.find((s) => s.id == section.id), // no need to render the other sections\n ]),\n })\n\n // NOTE: Instructions to refresh the whole document\n // removeEventListeners()\n // previewDocument.querySelector('body').replaceWith(doc.querySelector('body'))\n // setupEvents(previewDocument)\n\n const selector = `[data-maglev-section-id='${section.id}']`\n const sourceElement = doc.querySelector(selector)\n let targetElement = previewDocument.querySelector(selector)\n\n if (!sourceElement)\n throw new Error(`Maglev section ${section.id} not generated by the server`)\n\n if (targetElement) {\n targetElement.replaceWith(sourceElement)\n } else {\n insertSectionInDOM(sourceElement, insertAt)\n targetElement = previewDocument.querySelector(selector)\n }\n\n runScripts(targetElement)\n\n targetElement.scrollIntoView(true)\n}\n\nconst debouncedUpdatePreviewDocument = debounce(updatePreviewDocument, 300)\n\nconst insertSectionInDOM = (element, insertAt) => {\n switch (insertAt) {\n case 'top': {\n const parentNode = previewDocument.querySelector('[data-maglev-dropzone]')\n parentNode.prepend(element)\n break\n }\n case 'bottom':\n case undefined:\n case null:\n case '': {\n const parentNode = previewDocument.querySelector('[data-maglev-dropzone]')\n parentNode.appendChild(element)\n break\n }\n default: {\n const selector = `[data-maglev-section-id='${insertAt}']`\n const pivotElement = previewDocument.querySelector(selector)\n pivotElement.parentNode.insertBefore(element, pivotElement.nextSibling)\n }\n }\n}\n\nconst getUpdatedDoc = async (attributes) => {\n const { data } = await axios.post(previewDocument.location.href, {\n ...attributes,\n ...csrfParam,\n })\n const parser = new DOMParser()\n const doc = parser.parseFromString(data, 'text/html')\n return doc\n}\n","import Client from '~/live-preview-client/index'\nimport RailsClient from '~/live-preview-client/rails'\n\ndocument.addEventListener('DOMContentLoaded', () => {\n console.log('[Rails] Maglev Live Preview 🚀')\n if (Client.start()) {\n RailsClient.start()\n }\n})\n"],"names":["runScripts","element","scripts","continueLoading","script","newscript","continueLoadingOnError","continueLoadingOnLoad","continueLoadingOnReady","parentDocument","previewDocument","csrfParam","start","addSection","moveSections","updateSection","removeSection","replaceSection","updateBlock","updateThemeSettings","RailsClient","event","content","section","insertAt","debouncedUpdatePreviewDocument","sectionId","targetSectionId","direction","sectionElement","targetSectionElement","change","updateSectionOrBlock","selector","sectionBlock","themeSettings","doc","getUpdatedDoc","source","updateSetting","updateTextSetting","settings","$el","updatePreviewDocument","sourceElement","targetElement","insertSectionInDOM","debounce","pivotElement","attributes","data","axios","Client"],"mappings":"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"}