{"version":3,"file":"index-BnoYVvoC.js","sources":["../../../app/javascript/live-preview-client/utils.js","../../../app/javascript/live-preview-client/iframe-decorator.js","../../../app/javascript/live-preview-client/message.js","../../../app/javascript/live-preview-client/index.js"],"sourcesContent":["export const isBlank = (object) => {\n return (\n object === undefined ||\n object === null ||\n (typeof object === 'string' && object.length === 0) ||\n (typeof object === 'object' && object.length === 0)\n )\n}\n\nexport function debounce (fn, delay) {\n var timeoutID = null\n return function () {\n clearTimeout(timeoutID)\n var args = arguments\n var that = this\n timeoutID = setTimeout(function () {\n fn.apply(that, args)\n }, delay)\n }\n}","import { postMessage } from './message'\nimport { debounce, isBlank } from './utils'\n\n// keep track of the current hovered section\nlet listeners = []\nlet hoveredSectionId = null\n\nexport const start = (config) => {\n const previewDocument = window.document\n // mousescroll\n listenScrolling(previewDocument)\n\n // mouseenter\n listen(previewDocument, 'mouseenter', (el, type) => {\n switch (type) {\n case 'section':\n return onSectionHovered(previewDocument, el, config.stickySectionIds)\n case 'setting':\n return onSettingHovered(el)\n default:\n break\n }\n })\n\n // mouseleave\n listen(previewDocument, 'mouseleave', (el, type) => {\n switch (type) {\n case 'section':\n return onSectionLeft(el)\n case 'setting':\n return onSettingLeft(el)\n default:\n break\n }\n })\n\n // click\n listen(previewDocument, 'click', (el, type, event) => {\n switch (type) {\n case 'setting':\n return onSettingClicked(el, event)\n default:\n break\n }\n })\n\n // click on links\n disableLinks(previewDocument)\n}\n\nconst listen = (previewDocument, eventType, handler) => {\n const capture = eventType === 'mouseenter' || eventType === 'mouseleave'\n addEventListener(\n previewDocument.body,\n eventType,\n (event) => {\n if (event.target === previewDocument) return\n\n let sectionElement = event.target.closest('[data-maglev-section-id]')\n let settingElement = event.target.closest('[data-maglev-id]')\n let el = settingElement || sectionElement\n\n // not related to maglev element, no need to continue\n if (!el) return\n\n if (eventType === 'mouseleave') {\n if (settingElement) {\n if (settingElement != event.target) return\n } else {\n if (sectionElement != event.target) return\n // special case: hovering the section-highlighter component from the parent document\n const rect = sectionElement.getBoundingClientRect()\n const scrollX = previewDocument.defaultView.scrollX\n const scrollY = previewDocument.defaultView.scrollY\n if (\n event.pageX > rect.left + scrollX &&\n event.pageX < rect.right + scrollX &&\n event.pageY > rect.top + scrollY &&\n event.pageY < rect.bottom + scrollY\n )\n return\n }\n }\n\n handler(el, getElementType(el), event)\n },\n capture,\n )\n}\n\nconst listenScrolling = (previewDocument) => {\n let mouseX = 0\n let mouseY = 0\n\n addEventListener(previewDocument, 'mousemove', (e) => {\n mouseX = e.clientX\n mouseY = e.clientY\n })\n\n const debouncedScrollNotifier = debounce(() => {\n const el = previewDocument\n .elementFromPoint(mouseX, mouseY)\n ?.closest('[data-maglev-section-id]')\n\n if (el) postMessage('scroll', { boundingRect: el.getBoundingClientRect() })\n }, 10)\n\n addEventListener(previewDocument, 'scroll', debouncedScrollNotifier)\n}\n\nconst onSectionHovered = (previewDocument, el, stickySectionIds) => {\n const sectionId = el.dataset.maglevSectionId\n if (hoveredSectionId !== sectionId) {\n postMessage('section:hover', {\n sectionId,\n sectionRect: el.getBoundingClientRect(),\n sectionOffsetTop: getMinTop(previewDocument, sectionId, stickySectionIds),\n })\n hoveredSectionId = sectionId\n }\n}\n\nconst getMinTop = (previewDocument, currentSectionId, stickySectionIds) => {\n for (var i = 0; i < stickySectionIds.length; i++) {\n const sectionId = stickySectionIds[i]\n if (sectionId === currentSectionId) return 0 // hovering a sticky section!\n\n const selector = `[data-maglev-section-id='${sectionId}']`\n const stickyElement = previewDocument.querySelector(selector)\n\n if (stickyElement) return stickyElement.offsetHeight // found sticky element found\n }\n return 0\n}\n\nconst onSectionLeft = () => {\n postMessage('section:leave')\n hoveredSectionId = null\n}\n\nconst onSettingHovered = (el) => {\n if (!el) return null\n el.style.outline = '2px solid transparent'\n el.style.outlineOffset = '2px'\n el.style.boxShadow = '0 0 0 2px var(--color-primary)'\n if (\n !el.style.borderRadius &&\n window.getComputedStyle(el).borderRadius === '0px'\n )\n el.style.borderRadius = '2px'\n}\n\nconst onSettingLeft = (el) => {\n el.style.boxShadow = 'none'\n}\n\nconst onSettingClicked = (el, event) => {\n event.stopPropagation() & event.preventDefault()\n\n const fragments = el.dataset.maglevId.split('.')\n\n // is it a section or a block setting?\n const isSectionBlock = !!el.closest('[data-maglev-block-id]')\n const prefix = isSectionBlock ? 'sectionBlock' : 'section'\n\n postMessage(`${prefix}:setting:clicked`, {\n [`${prefix}Id`]: fragments[0],\n settingId: fragments[1],\n })\n}\n\nconst addEventListener = (target, type, listener, capture) => {\n listeners.push({ target, type, listener })\n target.addEventListener(type, listener, capture)\n}\n\nconst disableLinks = (previewDocument) => {\n addEventListener(previewDocument.body, 'click', (event) => {\n const link = event.target.closest('a')\n if (link && !isBlank(link.href)) {\n event.stopPropagation() & event.preventDefault()\n return false\n }\n })\n}\n\nconst getElementType = (el) => {\n return el.dataset.maglevSectionId ? 'section' : 'setting'\n}\n","import { start as decorateIframe } from './iframe-decorator'\n\nconst mainWindow = window.parent\n\nexport const listenMessages = () => {\n window.addEventListener('message', ({ data: { type, ...data } }) => {\n // a message MUST have a type\n if (!type) return\n\n switch (type) {\n case 'config':\n decorateIframe({\n stickySectionIds: data.stickySectionIds,\n })\n\n // we answer back we're ready!\n postMessage('ready', { message: \"👋, I'm a Maglev site and I'm ready\" })\n break\n case 'section:add':\n case 'section:move':\n case 'section:update':\n case 'section:remove':\n case 'block:add':\n case 'block:move':\n case 'block:update':\n case 'block:remove':\n case 'themeSettings:update':\n triggerEvent(type, data)\n break\n default:\n console.log('[maglev][iframe] unknown message type', type)\n break\n }\n })\n}\n\nexport const postMessage = (type, data) => {\n mainWindow.postMessage({ type, ...(data || {}) }, '*')\n}\n\n// local event\nconst triggerEvent = (type, data) => {\n const event = new CustomEvent(`maglev:${type}`, { detail: data })\n window.dispatchEvent(event)\n}\n","import { listenMessages } from './message'\n\nconst start = () => {\n if (window.location === window.parent.location) {\n return false\n }\n listenMessages()\n return true\n}\n\nexport default { start }\n"],"names":["isBlank","object","debounce","fn","delay","timeoutID","args","that","hoveredSectionId","start","config","previewDocument","listenScrolling","listen","el","type","onSectionHovered","onSettingHovered","onSectionLeft","onSettingLeft","event","onSettingClicked","disableLinks","eventType","handler","capture","addEventListener","sectionElement","settingElement","rect","scrollX","scrollY","getElementType","mouseX","mouseY","e","debouncedScrollNotifier","_a","postMessage","stickySectionIds","sectionId","getMinTop","currentSectionId","i","selector","stickyElement","fragments","prefix","target","listener","link","mainWindow","listenMessages","data","decorateIframe","triggerEvent","Client"],"mappings":"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"}