@getdraft/plugin 1.14.0 → 1.15.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/routes.ts","../src/utils.ts","../src/plugin.ts","../src/types.ts","../src/index.ts"],"sourcesContent":["export const LOCAL_ENDPOINT = 'http://localhost:5174';\nexport const PROD_ENDPOINT = 'https://seplugin.sendsay.ru';\n","import { ImageParams } from './types';\n\nconst getImageFileSize = async (imageUrl: string) => {\n try {\n const response = await fetch(imageUrl, { method: 'HEAD' });\n\n if (!response.ok) {\n return null;\n }\n\n const contentLength = response.headers.get('Content-Length');\n\n if (contentLength) {\n return parseInt(contentLength, 10);\n } else {\n return null;\n }\n } catch (error) {\n return null;\n }\n};\n\nexport const getImageParamsFromFileUrl = (imgSrc: string) =>\n new Promise<Omit<ImageParams, 'url'>>((resolve, reject) => {\n const img = new Image();\n\n img.onload = async () => {\n const fileSize = (await getImageFileSize(imgSrc)) ?? 0;\n\n resolve({\n originalWidth: img.width,\n originalHeight: img.height,\n ratio: img.width / img.height,\n fileSize,\n });\n };\n\n img.onerror = (error) => {\n reject(error);\n };\n\n img.src = imgSrc;\n });\n\nconst getLatinKey = (key: string, code: string) => {\n if (key.length !== 1) {\n return key;\n }\n\n const capitalHetaCode = 880;\n const isNonLatin = key.charCodeAt(0) >= capitalHetaCode;\n\n if (isNonLatin) {\n if (code.indexOf('Key') === 0 && code.length === 4) {\n return code.charAt(3);\n }\n\n if (code.indexOf('Digit') === 0 && code.length === 6) {\n return code.charAt(5);\n }\n }\n\n return key;\n};\n\nexport const constructKeyCode = (event: KeyboardEvent) => {\n let keyCode =\n `${getLatinKey(event.key, event.code)}`.toLowerCase() || event.key;\n const macOs = navigator.userAgent.includes('Mac OS');\n\n if (keyCode === 'backspace' && macOs) {\n keyCode = 'delete';\n }\n\n const prefix = [];\n\n if ((macOs && event.metaKey) || (!macOs && event.ctrlKey)) {\n prefix.push('mod');\n }\n\n if (event.shiftKey) {\n prefix.push('shift');\n }\n\n if (prefix.length > 0) {\n keyCode = `${prefix.join('-')}-${getLatinKey(keyCode, event.code)}`;\n }\n\n return keyCode;\n};\n\nexport const CORE_HOTKEYS = new Set([\n 'escape',\n 'mod-c',\n 'mod-d',\n 'mod-z',\n 'mod-y',\n 'mod-shift-z',\n 'mod-v',\n 'delete',\n 'mod-g',\n 'mod-p',\n 'mod-s',\n]);\n","import { LOCAL_ENDPOINT, PROD_ENDPOINT } from './routes';\nimport {\n EditorMenu,\n ExitParams,\n OnInitParams,\n OpenGalleryParams,\n Handlers,\n PluginConfig,\n SaveParams,\n TemplateJSON,\n UploadImageParams,\n ViewMode,\n HandlerParams,\n} from './types';\nimport {\n getImageParamsFromFileUrl,\n constructKeyCode,\n CORE_HOTKEYS,\n} from './utils';\nimport pkg from '../package.json';\n\nconst getDeployLink = () => {\n const regex = new RegExp(`(^| )seplugin-dev=([^;]+)`);\n const match = document.cookie.match(regex);\n const value = match?.[2].toLowerCase?.();\n\n if (value === 'true') {\n return LOCAL_ENDPOINT;\n }\n\n if (value?.startsWith('https://')) {\n return value;\n }\n\n const [major, mid] = pkg.version.split('.');\n\n return `${PROD_ENDPOINT}/v${major}.${mid}`;\n};\n\nconst verifyConfig = ({ token, pluginId, apiUrl }: PluginConfig) => {\n if (!token) {\n throw new Error('No [token] was provided');\n }\n\n if (!pluginId) {\n throw new Error('No [pluginId] was provided');\n }\n\n if (!apiUrl) {\n throw new Error('No [apiUrl] was provided');\n }\n};\n\nconst createIframe = () => {\n const iframe = document.createElement('iframe');\n iframe.src = getDeployLink();\n iframe.setAttribute(\n 'style',\n 'height:100%;width:100%;min-width:960px;border:0px',\n );\n iframe.setAttribute('allow', 'clipboard-read; clipboard-write');\n iframe.setAttribute(\n 'sandbox',\n 'allow-scripts allow-same-origin allow-forms allow-popups',\n );\n\n return iframe;\n};\n\nexport class PluginInstance {\n public iframe: HTMLIFrameElement | null = null;\n private hotkeysAttached = false;\n constructor(public config: PluginConfig) {}\n\n private captureHotkeysEnabled() {\n return this.config.disableHotkeysPassing !== true;\n }\n\n private onHostHotkey = (event: KeyboardEvent) => {\n if (!this.captureHotkeysEnabled() || !this.iframe?.contentWindow) {\n return;\n }\n\n const keyCode = constructKeyCode(event);\n\n if (!CORE_HOTKEYS.has(keyCode)) {\n return;\n }\n\n const target = event.target as HTMLElement | null;\n\n if (\n target &&\n (target.isContentEditable ||\n ['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName))\n ) {\n return;\n }\n\n event.preventDefault();\n\n const { key, ctrlKey, metaKey, shiftKey, altKey } = event;\n\n this.postEvent('hostHotkey', {\n key,\n code: event.code,\n metaKey,\n ctrlKey,\n shiftKey,\n altKey,\n keyCode,\n });\n };\n\n private promisedIframeMethod<T>(eventName: string) {\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n const res = new Promise<T>((resolve, reject) => {\n const onEvent = (\n e: MessageEvent<{ source: string; event: keyof PluginConfig['on'] }>,\n ) => {\n const {\n data: { source, event, ...data },\n } = e;\n if (source === 'DraftPlugin' && event === eventName) {\n e.stopPropagation();\n\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n resolve(data as T);\n window.removeEventListener('message', onEvent, true);\n }\n };\n\n window.addEventListener('message', onEvent, true);\n\n timer = setTimeout(() => {\n window.removeEventListener('message', onEvent, true);\n reject('Request timed out');\n timer = null;\n }, 2000);\n });\n\n this.postEvent(eventName);\n\n return res;\n }\n\n private postEvent(event: string, data: object = {}) {\n if (this.iframe && this.iframe.contentWindow) {\n this.iframe.contentWindow.postMessage(\n {\n ...data,\n event,\n source: 'DraftPlugin',\n },\n '*',\n );\n }\n }\n\n private onImageUpload = async ({\n id,\n ...data\n }: UploadImageParams & { id: string }) => {\n try {\n const url = await this.config.on.uploadImage?.(data);\n let params = {};\n\n if (url) {\n params = await getImageParamsFromFileUrl(url);\n }\n\n this.postEvent('imageUploaded', { id, img: { ...params, url } });\n } catch (e) {\n this.postEvent('imageUploaded', { id });\n }\n };\n\n private onLoadPersonalization = async () => {\n try {\n if (!this.config.on.loadPersonalization) {\n throw new Error('No personalization loader provided');\n }\n\n const personalizationDictionary =\n await this.config.on.loadPersonalization();\n\n this.postEvent('loadPersonalization', {\n items: personalizationDictionary,\n });\n } catch (e) {\n this.postEvent('loadPersonalization', {});\n }\n };\n\n private onGalleryOpen = async ({ id }: { id: string }) => {\n const applyImage = async (url?: string) => {\n const imgParams = { url };\n\n if (url) {\n const params = await getImageParamsFromFileUrl(url);\n Object.assign(imgParams, params);\n }\n\n this.postEvent('imageUploaded', {\n id,\n img: imgParams,\n });\n };\n\n this.config.on.openGallery?.(applyImage);\n };\n\n private triggerEvent<H extends CallableFunction | undefined>(\n handler: H,\n params: HandlerParams<H>,\n ) {\n if (!handler) {\n return;\n }\n\n return handler(params);\n }\n\n private onMessage = (\n ev: MessageEvent<{ source: string; event: keyof Handlers }>,\n ) => {\n const {\n data: { source, event, ...data },\n } = ev;\n\n if (source === 'DraftPlugin') {\n if (event === 'openGallery') {\n this.onGalleryOpen(data as OpenGalleryParams);\n } else if (event === 'uploadImage') {\n this.onImageUpload(data as UploadImageParams & { id: string });\n } else if (event === 'loadPersonalization') {\n this.onLoadPersonalization();\n } else {\n this.triggerEvent(\n this.config.on[event],\n data as HandlerParams<Handlers[typeof event]>,\n );\n }\n }\n };\n\n start({\n template,\n templateName,\n uid,\n }: {\n template: string | TemplateJSON;\n uid: string;\n templateName?: string;\n }) {\n const containerEl = document.querySelector(this.config.container);\n\n if (!containerEl) {\n throw new Error('Specified container not found');\n } else {\n const onInit = ({ data: { source, event } }: OnInitParams) => {\n if (source === 'DraftPlugin' && event === 'loaded') {\n const {\n on,\n container,\n locale,\n autosave,\n token,\n apiUrl,\n pluginId,\n __config,\n } = this.config;\n\n verifyConfig(this.config);\n\n if (this.iframe && this.iframe.contentWindow) {\n this.postEvent('init', {\n container,\n locale,\n uid,\n autosave,\n token,\n pluginId,\n apiUrl,\n __config,\n enabledListeners: Object.keys(on),\n template,\n templateName,\n });\n }\n\n window.addEventListener('message', this.onMessage);\n window.removeEventListener('message', onInit);\n }\n };\n\n this.iframe = createIframe();\n window.addEventListener('message', onInit);\n containerEl.appendChild(this.iframe);\n\n if (this.captureHotkeysEnabled() && !this.hotkeysAttached) {\n window.addEventListener('keydown', this.onHostHotkey);\n this.hotkeysAttached = true;\n }\n }\n }\n\n destroy = () => {\n this.iframe?.remove();\n this.iframe = null;\n window.removeEventListener('message', this.onMessage);\n\n if (this.hotkeysAttached) {\n window.removeEventListener('keydown', this.onHostHotkey);\n this.hotkeysAttached = false;\n }\n };\n\n changeTemplate(\n template: string | TemplateJSON,\n options: {\n templateName?: string;\n uid?: string;\n } = {},\n ) {\n this.postEvent('changeTemplate', { ...options, template });\n }\n\n toggleGrid(state?: boolean) {\n this.postEvent('toggleGrid', { state });\n }\n\n togglePreview(state?: boolean) {\n this.postEvent('togglePreview', { state });\n }\n\n toggleMenu(menu: EditorMenu | null = null) {\n this.postEvent('toggleMenu', { menu });\n }\n\n toggleViewMode(viewMode: ViewMode) {\n this.postEvent('toggleViewMode', { viewMode });\n }\n\n undo() {\n this.postEvent('undo');\n }\n\n redo() {\n this.postEvent('redo');\n }\n\n save() {\n return this.promisedIframeMethod<SaveParams>('saveAction');\n }\n\n exit() {\n return this.promisedIframeMethod<ExitParams>('exitAction');\n }\n\n exportContent() {\n return this.promisedIframeMethod<SaveParams>('exportContent');\n }\n}\n","export type EventHandler<T> = (data: T) => void;\n\nexport type AsyncEventHandler<P, R> = (params: P) => Promise<R>;\n\nexport interface SaveParams {\n json: TemplateJSON;\n html: string;\n}\n\nexport type OnInitParams = MessageEvent<{\n source: string;\n event: 'loaded' | unknown;\n}>;\n\nexport enum EditorMenu {\n Audit = 'audit',\n Guide = 'guide',\n Style = 'style',\n Blocks = 'blocks',\n}\n\nexport enum ViewMode {\n Desktop = 'desktop',\n Mobile = 'mobile',\n}\n\nexport interface ReadyParams extends SaveParams {\n lastSavedTemplate?: {\n template: TemplateJSON;\n date: Date;\n };\n}\n\nexport interface ErrorParams {\n message: string;\n code?: string;\n}\n\nexport interface ExitParams extends SaveParams {}\n\nexport interface NotificationParams {\n intent: 'error' | 'info' | 'success' | 'warning';\n errorDetails?: object;\n message?: string;\n title: string;\n}\n\nexport interface OpenGalleryParams {\n id: string;\n}\n\nexport interface UploadImageParams {\n file: string;\n name: string;\n}\n\nexport interface ImageParams {\n url: string;\n originalWidth: number;\n originalHeight: number;\n ratio: number;\n fileSize: number;\n}\n\nexport interface AutosaveParams {\n json: TemplateJSON;\n}\n\ninterface ToggleParams {\n state: boolean;\n}\n\nexport interface ToggleGridParams extends ToggleParams {}\n\nexport interface TogglePreviewParams extends ToggleParams {\n json: TemplateJSON;\n html: string;\n darkHTML: string;\n}\n\nexport interface ToggleViewModeParams {\n mode: ViewMode;\n}\n\nexport interface ToggleMenuParams {\n menu: EditorMenu | null;\n}\n\nexport interface HistoryParams {\n hasUndos: boolean;\n hasRedos: boolean;\n currentStep: number;\n}\n\nexport type TemplateJSON = Record<string, any>;\n\nexport type PersonalizationDictionary = Array<\n | { name: string; value: string }\n | { groupName: string; items: Array<{ name: string; value: string }> }\n>;\n\nexport type ToolbarActionName =\n | 'duplicate'\n | 'destroy'\n | 'edit'\n | 'up'\n | 'down';\nexport type HotkeyContext = 'hotkey';\nexport type OverlayContext = 'overlay-click' | 'overlay-double-click';\nexport type ToolbarContext = 'toolbar';\nexport type UnitSettingsContext = 'unit-settings';\nexport type BlockType = 'system' | 'user';\nexport type DndDragContext = 'canvas' | 'list' | 'palette';\nexport type DndDropContext = 'dropline' | 'placeholder' | 'empty-placeholder';\nexport type DndDropTarget = 'root' | 'section' | 'column' | 'element';\n\nexport interface DuplicateEvent {\n name: 'duplicate';\n context: HotkeyContext | ToolbarContext | UnitSettingsContext;\n unitType: string;\n}\n\nexport interface DestroyEvent {\n name: 'destroy';\n context: HotkeyContext | ToolbarContext | UnitSettingsContext;\n unitType: string;\n}\n\nexport interface EditEvent {\n name: 'edit';\n context: OverlayContext | ToolbarContext;\n unitType: string;\n}\n\nexport interface HistoryEvent {\n name: 'history';\n type: 'undo' | 'redo';\n context: HotkeyContext;\n}\n\nexport interface PreviewEvent {\n name: 'preview';\n context: HotkeyContext;\n}\n\nexport interface ToolbarMoveEvent {\n name: 'up' | 'down';\n context: ToolbarContext;\n unitType: string;\n}\n\nexport interface BlockInsertEvent {\n name: 'block-insert';\n context: 'double-click';\n blockType: BlockType;\n blockName: string;\n blockCategory: string | number;\n blockId: string | number;\n}\n\nexport interface BlockSaveEvent {\n name: 'block-save';\n blockType: 'user';\n blockName: string;\n blockCategory: string | number;\n blockId: string | number;\n elements: Record<string, number> & { sum: number };\n}\n\nexport interface BlockDestroyEvent {\n name: 'block-destroy';\n}\n\nexport interface DropEventDragMeta {\n context?: DndDragContext;\n layer?: 'element' | 'section' | 'column' | 'root';\n type?: string | string[];\n blockCategory?: string | number;\n blockId?: string | number;\n blockName?: string;\n blockType?: BlockType;\n alt?: boolean;\n dropKind?: 'create' | 'move';\n}\n\nexport interface DropEventDropzoneMeta {\n context?: DndDropContext;\n dropTarget?: DndDropTarget;\n}\n\nexport interface DropEvent {\n name: 'drop';\n drag?: DropEventDragMeta;\n dropzone?: DropEventDropzoneMeta;\n}\n\nexport type AnalyticsParams =\n | DuplicateEvent\n | DestroyEvent\n | EditEvent\n | HistoryEvent\n | PreviewEvent\n | ToolbarMoveEvent\n | BlockInsertEvent\n | BlockSaveEvent\n | BlockDestroyEvent\n | DropEvent;\n\nexport interface Handlers {\n ready: EventHandler<ReadyParams>;\n error: EventHandler<ErrorParams>;\n save: EventHandler<SaveParams>;\n exit: EventHandler<ExitParams>;\n notification: EventHandler<NotificationParams>;\n autosave: EventHandler<AutosaveParams>;\n toggleGrid: EventHandler<ToggleGridParams>;\n togglePreview: EventHandler<TogglePreviewParams>;\n toggleViewMode: EventHandler<ToggleViewModeParams>;\n toggleMenu: EventHandler<ToggleMenuParams>;\n history: EventHandler<HistoryParams>;\n analytics: EventHandler<AnalyticsParams>;\n openGallery: EventHandler<(url?: string) => Promise<void>>;\n uploadImage: AsyncEventHandler<UploadImageParams, string>;\n loadPersonalization: AsyncEventHandler<void, PersonalizationDictionary>;\n}\n\nexport type HandlerParams<H> = H extends\n | EventHandler<infer P>\n | AsyncEventHandler<infer P, unknown>\n ? P\n : never;\n\nexport interface PluginConfig {\n container: string;\n locale?: string;\n autosave?:\n | boolean\n | {\n interval: number;\n };\n token: string;\n pluginId: string;\n apiUrl: string;\n disableHotkeysPassing?: boolean;\n __config?: object;\n on: Partial<Handlers>;\n}\n","import { PluginInstance } from './plugin';\nimport { PluginConfig } from './types';\n\nconst DEFAULT_CONFIG: Partial<PluginConfig> = {\n container: '#draft-plugin-container',\n disableHotkeysPassing: false,\n locale: 'ru',\n on: {},\n};\n\nclass PluginWrapper {\n create(config: PluginConfig) {\n return new PluginInstance({\n ...DEFAULT_CONFIG,\n ...config,\n });\n }\n}\n\nconst DraftPlugin = new PluginWrapper();\n\ndeclare global {\n interface Window {\n DraftPlugin: PluginWrapper;\n }\n}\n\nwindow.DraftPlugin = DraftPlugin;\n\nexport default DraftPlugin;\nexport * from './types';\n"],"names":["LOCAL_ENDPOINT","PROD_ENDPOINT","getImageFileSize","imageUrl","response","contentLength","getImageParamsFromFileUrl","imgSrc","resolve","reject","img","fileSize","error","getLatinKey","key","code","constructKeyCode","event","keyCode","macOs","prefix","CORE_HOTKEYS","getDeployLink","_a","_b","regex","match","value","major","mid","pkg","verifyConfig","token","pluginId","apiUrl","createIframe","iframe","PluginInstance","config","__publicField","target","ctrlKey","metaKey","shiftKey","altKey","id","data","url","params","personalizationDictionary","applyImage","imgParams","ev","source","eventName","timer","res","onEvent","e","handler","template","templateName","uid","containerEl","onInit","on","container","locale","autosave","__config","options","state","menu","viewMode","EditorMenu","ViewMode","DEFAULT_CONFIG","PluginWrapper","DraftPlugin"],"mappings":";;;AAAO,MAAMA,IAAiB,yBACjBC,IAAgB,+BCCvBC,IAAmB,OAAOC,MAAqB;AACnD,MAAI;AACF,UAAMC,IAAW,MAAM,MAAMD,GAAU,EAAE,QAAQ,QAAQ;AAEzD,QAAI,CAACC,EAAS;AACZ,aAAO;AAGT,UAAMC,IAAgBD,EAAS,QAAQ,IAAI,gBAAgB;AAE3D,WAAIC,IACK,SAASA,GAAe,EAAE,IAE1B;AAAA,EAEX,QAAgB;AACd,WAAO;AAAA,EACT;AACF,GAEaC,IAA4B,CAACC,MACxC,IAAI,QAAkC,CAACC,GAASC,MAAW;AACzD,QAAMC,IAAM,IAAI,MAAA;AAEhB,EAAAA,EAAI,SAAS,YAAY;AACvB,UAAMC,IAAY,MAAMT,EAAiBK,CAAM,KAAM;AAErD,IAAAC,EAAQ;AAAA,MACN,eAAeE,EAAI;AAAA,MACnB,gBAAgBA,EAAI;AAAA,MACpB,OAAOA,EAAI,QAAQA,EAAI;AAAA,MACvB,UAAAC;AAAA,IAAA,CACD;AAAA,EACH,GAEAD,EAAI,UAAU,CAACE,MAAU;AACvB,IAAAH,EAAOG,CAAK;AAAA,EACd,GAEAF,EAAI,MAAMH;AACZ,CAAC,GAEGM,IAAc,CAACC,GAAaC,MAAiB;AACjD,MAAID,EAAI,WAAW;AACjB,WAAOA;AAMT,MAFmBA,EAAI,WAAW,CAAC,KADX,KAGR;AACd,QAAIC,EAAK,QAAQ,KAAK,MAAM,KAAKA,EAAK,WAAW;AAC/C,aAAOA,EAAK,OAAO,CAAC;AAGtB,QAAIA,EAAK,QAAQ,OAAO,MAAM,KAAKA,EAAK,WAAW;AACjD,aAAOA,EAAK,OAAO,CAAC;AAAA,EAExB;AAEA,SAAOD;AACT,GAEaE,IAAmB,CAACC,MAAyB;AACxD,MAAIC,IACF,GAAGL,EAAYI,EAAM,KAAKA,EAAM,IAAI,CAAC,GAAG,YAAA,KAAiBA,EAAM;AACjE,QAAME,IAAQ,UAAU,UAAU,SAAS,QAAQ;AAEnD,EAAID,MAAY,eAAeC,MAC7BD,IAAU;AAGZ,QAAME,IAAS,CAAA;AAEf,UAAKD,KAASF,EAAM,WAAa,CAACE,KAASF,EAAM,YAC/CG,EAAO,KAAK,KAAK,GAGfH,EAAM,YACRG,EAAO,KAAK,OAAO,GAGjBA,EAAO,SAAS,MAClBF,IAAU,GAAGE,EAAO,KAAK,GAAG,CAAC,IAAIP,EAAYK,GAASD,EAAM,IAAI,CAAC,KAG5DC;AACT,GAEaG,wBAAmB,IAAI;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;;GClFKC,IAAgB,MAAM;AFrBrB,MAAAC,GAAAC;AEsBL,QAAMC,IAAQ,IAAI,OAAO,2BAA2B,GAC9CC,IAAQ,SAAS,OAAO,MAAMD,CAAK,GACnCE,KAAQH,IAAAE,KAAA,iBAAAH,IAAAG,EAAQ,IAAG,gBAAX,gBAAAF,EAAA,KAAAD;AAEd,MAAII,MAAU;AACZ,WAAO3B;AAGT,MAAI2B,KAAA,QAAAA,EAAO,WAAW;AACpB,WAAOA;AAGT,QAAM,CAACC,GAAOC,CAAG,IAAIC,EAAI,QAAQ,MAAM,GAAG;AAE1C,SAAO,GAAG7B,CAAa,KAAK2B,CAAK,IAAIC,CAAG;AAC1C,GAEME,IAAe,CAAC,EAAE,OAAAC,GAAO,UAAAC,GAAU,QAAAC,QAA2B;AAClE,MAAI,CAACF;AACH,UAAM,IAAI,MAAM,yBAAyB;AAG3C,MAAI,CAACC;AACH,UAAM,IAAI,MAAM,4BAA4B;AAG9C,MAAI,CAACC;AACH,UAAM,IAAI,MAAM,0BAA0B;AAE9C,GAEMC,IAAe,MAAM;AACzB,QAAMC,IAAS,SAAS,cAAc,QAAQ;AAC9C,SAAAA,EAAO,MAAMd,EAAA,GACbc,EAAO;AAAA,IACL;AAAA,IACA;AAAA,EAAA,GAEFA,EAAO,aAAa,SAAS,iCAAiC,GAC9DA,EAAO;AAAA,IACL;AAAA,IACA;AAAA,EAAA,GAGKA;AACT;AAEO,MAAMC,EAAe;AAAA,EAG1B,YAAmBC,GAAsB;AAFlC,IAAAC,EAAA,gBAAmC;AAClC,IAAAA,EAAA,yBAAkB;AAOlB,IAAAA,EAAA,sBAAe,CAACtB,MAAyB;AF9E5C,UAAAM;AE+EH,UAAI,CAAC,KAAK,sBAAA,KAA2B,GAACA,IAAA,KAAK,WAAL,QAAAA,EAAa;AACjD;AAGF,YAAML,IAAUF,EAAiBC,CAAK;AAEtC,UAAI,CAACI,EAAa,IAAIH,CAAO;AAC3B;AAGF,YAAMsB,IAASvB,EAAM;AAErB,UACEuB,MACCA,EAAO,qBACN,CAAC,SAAS,YAAY,QAAQ,EAAE,SAASA,EAAO,OAAO;AAEzD;AAGF,MAAAvB,EAAM,eAAA;AAEN,YAAM,EAAE,KAAAH,GAAK,SAAA2B,GAAS,SAAAC,GAAS,UAAAC,GAAU,QAAAC,MAAW3B;AAEpD,WAAK,UAAU,cAAc;AAAA,QAC3B,KAAAH;AAAA,QACA,MAAMG,EAAM;AAAA,QACZ,SAAAyB;AAAA,QACA,SAAAD;AAAA,QACA,UAAAE;AAAA,QACA,QAAAC;AAAA,QACA,SAAA1B;AAAA,MAAA,CACD;AAAA,IACH;AAmDQ,IAAAqB,EAAA,uBAAgB,OAAO;AAAA,MAC7B,IAAAM;AAAA,MACA,GAAGC;AAAA,IAAA,MACqC;AFtKrC,UAAAvB,GAAAC;AEuKH,UAAI;AACF,cAAMuB,IAAM,QAAMvB,KAAAD,IAAA,KAAK,OAAO,IAAG,gBAAf,gBAAAC,EAAA,KAAAD,GAA6BuB;AAC/C,YAAIE,IAAS,CAAA;AAEb,QAAID,MACFC,IAAS,MAAM1C,EAA0ByC,CAAG,IAG9C,KAAK,UAAU,iBAAiB,EAAE,IAAAF,GAAI,KAAK,EAAE,GAAGG,GAAQ,KAAAD,EAAA,GAAO;AAAA,MACjE,QAAY;AACV,aAAK,UAAU,iBAAiB,EAAE,IAAAF,EAAA,CAAI;AAAA,MACxC;AAAA,IACF;AAEQ,IAAAN,EAAA,+BAAwB,YAAY;AAC1C,UAAI;AACF,YAAI,CAAC,KAAK,OAAO,GAAG;AAClB,gBAAM,IAAI,MAAM,oCAAoC;AAGtD,cAAMU,IACJ,MAAM,KAAK,OAAO,GAAG,oBAAA;AAEvB,aAAK,UAAU,uBAAuB;AAAA,UACpC,OAAOA;AAAA,QAAA,CACR;AAAA,MACH,QAAY;AACV,aAAK,UAAU,uBAAuB,EAAE;AAAA,MAC1C;AAAA,IACF;AAEQ,IAAAV,EAAA,uBAAgB,OAAO,EAAE,IAAAM,QAAyB;AFtMrD,UAAAtB,GAAAC;AEuMH,YAAM0B,IAAa,OAAOH,MAAiB;AACzC,cAAMI,IAAY,EAAE,KAAAJ,EAAA;AAEpB,YAAIA,GAAK;AACP,gBAAMC,IAAS,MAAM1C,EAA0ByC,CAAG;AAClD,iBAAO,OAAOI,GAAWH,CAAM;AAAA,QACjC;AAEA,aAAK,UAAU,iBAAiB;AAAA,UAC9B,IAAAH;AAAA,UACA,KAAKM;AAAA,QAAA,CACN;AAAA,MACH;AAEA,OAAA3B,KAAAD,IAAA,KAAK,OAAO,IAAG,gBAAf,QAAAC,EAAA,KAAAD,GAA6B2B;AAAA,IAC/B;AAaQ,IAAAX,EAAA,mBAAY,CAClBa,MACG;AACH,YAAM;AAAA,QACJ,MAAM,EAAE,QAAAC,GAAQ,OAAApC,GAAO,GAAG6B,EAAA;AAAA,MAAK,IAC7BM;AAEJ,MAAIC,MAAW,kBACTpC,MAAU,gBACZ,KAAK,cAAc6B,CAAyB,IACnC7B,MAAU,gBACnB,KAAK,cAAc6B,CAA0C,IACpD7B,MAAU,wBACnB,KAAK,sBAAA,IAEL,KAAK;AAAA,QACH,KAAK,OAAO,GAAGA,CAAK;AAAA,QACpB6B;AAAA,MAAA;AAAA,IAIR;AA+DA,IAAAP,EAAA,iBAAU,MAAM;AFvTX,UAAAhB;AEwTH,OAAAA,IAAA,KAAK,WAAL,QAAAA,EAAa,UACb,KAAK,SAAS,MACd,OAAO,oBAAoB,WAAW,KAAK,SAAS,GAEhD,KAAK,oBACP,OAAO,oBAAoB,WAAW,KAAK,YAAY,GACvD,KAAK,kBAAkB;AAAA,IAE3B;AAxPmB,SAAA,SAAAe;AAAA,EAAuB;AAAA,EAElC,wBAAwB;AAC9B,WAAO,KAAK,OAAO,0BAA0B;AAAA,EAC/C;AAAA,EAsCQ,qBAAwBgB,GAAmB;AACjD,QAAIC,IAA8C;AAElD,UAAMC,IAAM,IAAI,QAAW,CAAChD,GAASC,MAAW;AAC9C,YAAMgD,IAAU,CACdC,MACG;AACH,cAAM;AAAA,UACJ,MAAM,EAAE,QAAAL,GAAQ,OAAApC,GAAO,GAAG6B,EAAA;AAAA,QAAK,IAC7BY;AACJ,QAAIL,MAAW,iBAAiBpC,MAAUqC,MACxCI,EAAE,gBAAA,GAEEH,MACF,aAAaA,CAAK,GAClBA,IAAQ,OAEV/C,EAAQsC,CAAS,GACjB,OAAO,oBAAoB,WAAWW,GAAS,EAAI;AAAA,MAEvD;AAEA,aAAO,iBAAiB,WAAWA,GAAS,EAAI,GAEhDF,IAAQ,WAAW,MAAM;AACvB,eAAO,oBAAoB,WAAWE,GAAS,EAAI,GACnDhD,EAAO,mBAAmB,GAC1B8C,IAAQ;AAAA,MACV,GAAG,GAAI;AAAA,IACT,CAAC;AAED,gBAAK,UAAUD,CAAS,GAEjBE;AAAA,EACT;AAAA,EAEQ,UAAUvC,GAAe6B,IAAe,IAAI;AAClD,IAAI,KAAK,UAAU,KAAK,OAAO,iBAC7B,KAAK,OAAO,cAAc;AAAA,MACxB;AAAA,QACE,GAAGA;AAAA,QACH,OAAA7B;AAAA,QACA,QAAQ;AAAA,MAAA;AAAA,MAEV;AAAA,IAAA;AAAA,EAGN;AAAA,EAuDQ,aACN0C,GACAX,GACA;AACA,QAAKW;AAIL,aAAOA,EAAQX,CAAM;AAAA,EACvB;AAAA,EAyBA,MAAM;AAAA,IACJ,UAAAY;AAAA,IACA,cAAAC;AAAA,IACA,KAAAC;AAAA,EAAA,GAKC;AACD,UAAMC,IAAc,SAAS,cAAc,KAAK,OAAO,SAAS;AAEhE,QAAKA,GAEE;AACL,YAAMC,IAAS,CAAC,EAAE,MAAM,EAAE,QAAAX,GAAQ,OAAApC,EAAA,QAA4B;AAC5D,YAAIoC,MAAW,iBAAiBpC,MAAU,UAAU;AAClD,gBAAM;AAAA,YACJ,IAAAgD;AAAA,YACA,WAAAC;AAAA,YACA,QAAAC;AAAA,YACA,UAAAC;AAAA,YACA,OAAApC;AAAA,YACA,QAAAE;AAAA,YACA,UAAAD;AAAA,YACA,UAAAoC;AAAA,UAAA,IACE,KAAK;AAET,UAAAtC,EAAa,KAAK,MAAM,GAEpB,KAAK,UAAU,KAAK,OAAO,iBAC7B,KAAK,UAAU,QAAQ;AAAA,YACrB,WAAAmC;AAAA,YACA,QAAAC;AAAA,YACA,KAAAL;AAAA,YACA,UAAAM;AAAA,YACA,OAAApC;AAAA,YACA,UAAAC;AAAA,YACA,QAAAC;AAAA,YACA,UAAAmC;AAAA,YACA,kBAAkB,OAAO,KAAKJ,CAAE;AAAA,YAChC,UAAAL;AAAA,YACA,cAAAC;AAAA,UAAA,CACD,GAGH,OAAO,iBAAiB,WAAW,KAAK,SAAS,GACjD,OAAO,oBAAoB,WAAWG,CAAM;AAAA,QAC9C;AAAA,MACF;AAEA,WAAK,SAAS7B,EAAA,GACd,OAAO,iBAAiB,WAAW6B,CAAM,GACzCD,EAAY,YAAY,KAAK,MAAM,GAE/B,KAAK,sBAAA,KAA2B,CAAC,KAAK,oBACxC,OAAO,iBAAiB,WAAW,KAAK,YAAY,GACpD,KAAK,kBAAkB;AAAA,IAE3B;AA9CE,YAAM,IAAI,MAAM,+BAA+B;AAAA,EA+CnD;AAAA,EAaA,eACEH,GACAU,IAGI,IACJ;AACA,SAAK,UAAU,kBAAkB,EAAE,GAAGA,GAAS,UAAAV,GAAU;AAAA,EAC3D;AAAA,EAEA,WAAWW,GAAiB;AAC1B,SAAK,UAAU,cAAc,EAAE,OAAAA,EAAA,CAAO;AAAA,EACxC;AAAA,EAEA,cAAcA,GAAiB;AAC7B,SAAK,UAAU,iBAAiB,EAAE,OAAAA,EAAA,CAAO;AAAA,EAC3C;AAAA,EAEA,WAAWC,IAA0B,MAAM;AACzC,SAAK,UAAU,cAAc,EAAE,MAAAA,EAAA,CAAM;AAAA,EACvC;AAAA,EAEA,eAAeC,GAAoB;AACjC,SAAK,UAAU,kBAAkB,EAAE,UAAAA,EAAA,CAAU;AAAA,EAC/C;AAAA,EAEA,OAAO;AACL,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA,EAEA,OAAO;AACL,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA,EAEA,OAAO;AACL,WAAO,KAAK,qBAAiC,YAAY;AAAA,EAC3D;AAAA,EAEA,OAAO;AACL,WAAO,KAAK,qBAAiC,YAAY;AAAA,EAC3D;AAAA,EAEA,gBAAgB;AACd,WAAO,KAAK,qBAAiC,eAAe;AAAA,EAC9D;AACF;ACjWO,IAAKC,sBAAAA,OACVA,EAAA,QAAQ,SACRA,EAAA,QAAQ,SACRA,EAAA,QAAQ,SACRA,EAAA,SAAS,UAJCA,IAAAA,KAAA,CAAA,CAAA,GAOAC,sBAAAA,OACVA,EAAA,UAAU,WACVA,EAAA,SAAS,UAFCA,IAAAA,KAAA,CAAA,CAAA;AClBZ,MAAMC,IAAwC;AAAA,EAC5C,WAAW;AAAA,EACX,uBAAuB;AAAA,EACvB,QAAQ;AAAA,EACR,IAAI,CAAA;AACN;AAEA,MAAMC,EAAc;AAAA,EAClB,OAAOvC,GAAsB;AAC3B,WAAO,IAAID,EAAe;AAAA,MACxB,GAAGuC;AAAA,MACH,GAAGtC;AAAA,IAAA,CACJ;AAAA,EACH;AACF;AAEA,MAAMwC,IAAc,IAAID,EAAA;AAQxB,OAAO,cAAcC;"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/routes.ts","../src/types.ts","../src/utils.ts","../src/plugin.ts","../src/index.ts"],"sourcesContent":["export const LOCAL_ENDPOINT = 'http://localhost:5174';\nexport const PROD_ENDPOINT = 'https://seplugin.sendsay.ru';\n","export type EventHandler<T> = (data: T) => void;\n\nexport type AsyncEventHandler<P, R> = (params: P) => Promise<R>;\n\nexport class DraftError extends Error {\n public readonly code: string;\n\n constructor(code: string, message: string) {\n super(message);\n this.name = 'DraftError';\n this.code = code;\n }\n}\n\nexport type MessageData = {\n source: string;\n event: string;\n ok?: boolean;\n code?: string;\n message?: string;\n action?: string;\n};\n\nexport interface ExportAsFileParams {\n blob: Blob;\n fileName: string;\n}\n\nexport interface SaveParams {\n json: TemplateJSON;\n html: string;\n}\n\nexport type OnInitParams = MessageEvent<{\n source: string;\n event: 'loaded' | unknown;\n}>;\n\nexport enum EditorMenu {\n Audit = 'audit',\n Guide = 'guide',\n Style = 'style',\n Blocks = 'blocks',\n}\n\nexport enum ViewMode {\n Desktop = 'desktop',\n Mobile = 'mobile',\n}\n\nexport interface ReadyParams extends SaveParams {\n lastSavedTemplate?: {\n template: TemplateJSON;\n date: Date;\n };\n}\n\nexport interface ErrorParams {\n message: string;\n code?: string;\n details?: unknown;\n}\n\nexport interface ExitParams extends SaveParams {}\n\nexport interface NotificationParams {\n intent: 'error' | 'info' | 'success' | 'warning';\n errorDetails?: object;\n message?: string;\n title: string;\n}\n\nexport interface OpenGalleryParams {\n id: string;\n}\n\nexport interface UploadImageParams {\n file: string;\n name: string;\n}\n\nexport interface ImageParams {\n url: string;\n originalWidth: number;\n originalHeight: number;\n ratio: number;\n fileSize: number;\n}\n\nexport interface AutosaveParams {\n json: TemplateJSON;\n}\n\ninterface ToggleParams {\n state: boolean;\n}\n\nexport interface ToggleGridParams extends ToggleParams {}\n\nexport interface TogglePreviewParams extends ToggleParams {\n json: TemplateJSON;\n html: string;\n darkHTML: string;\n}\n\nexport interface ToggleViewModeParams {\n mode: ViewMode;\n}\n\nexport interface ToggleMenuParams {\n menu: EditorMenu | null;\n}\n\nexport interface HistoryParams {\n hasUndos: boolean;\n hasRedos: boolean;\n currentStep: number;\n}\n\nexport type TemplateJSON = Record<string, any>;\n\nexport type PersonalizationDictionary = Array<\n | { name: string; value: string }\n | { groupName: string; items: Array<{ name: string; value: string }> }\n>;\n\nexport type ToolbarActionName =\n | 'duplicate'\n | 'destroy'\n | 'edit'\n | 'up'\n | 'down';\nexport type HotkeyContext = 'hotkey';\nexport type OverlayContext = 'overlay-click' | 'overlay-double-click';\nexport type ToolbarContext = 'toolbar';\nexport type UnitSettingsContext = 'unit-settings';\nexport type BlockType = 'system' | 'user';\nexport type DndDragContext = 'canvas' | 'list' | 'palette';\nexport type DndDropContext = 'dropline' | 'placeholder' | 'empty-placeholder';\nexport type DndDropTarget = 'root' | 'section' | 'column' | 'element';\n\nexport interface DuplicateEvent {\n name: 'duplicate';\n context: HotkeyContext | ToolbarContext | UnitSettingsContext;\n unitType: string;\n}\n\nexport interface DestroyEvent {\n name: 'destroy';\n context: HotkeyContext | ToolbarContext | UnitSettingsContext;\n unitType: string;\n}\n\nexport interface EditEvent {\n name: 'edit';\n context: OverlayContext | ToolbarContext;\n unitType: string;\n}\n\nexport interface HistoryEvent {\n name: 'history';\n type: 'undo' | 'redo';\n context: HotkeyContext;\n}\n\nexport interface PreviewEvent {\n name: 'preview';\n context: HotkeyContext;\n}\n\nexport interface ToolbarMoveEvent {\n name: 'up' | 'down';\n context: ToolbarContext;\n unitType: string;\n}\n\nexport interface BlockInsertEvent {\n name: 'block-insert';\n context: 'double-click';\n blockType: BlockType;\n blockName: string;\n blockCategory: string | number;\n blockId: string | number;\n}\n\nexport interface BlockSaveEvent {\n name: 'block-save';\n blockType: 'user';\n blockName: string;\n blockCategory: string | number;\n blockId: string | number;\n elements: Record<string, number> & { sum: number };\n}\n\nexport interface BlockDestroyEvent {\n name: 'block-destroy';\n}\n\nexport interface DropEventDragMeta {\n context?: DndDragContext;\n layer?: 'element' | 'section' | 'column' | 'root';\n type?: string | string[];\n blockCategory?: string | number;\n blockId?: string | number;\n blockName?: string;\n blockType?: BlockType;\n alt?: boolean;\n dropKind?: 'create' | 'move';\n}\n\nexport interface DropEventDropzoneMeta {\n context?: DndDropContext;\n dropTarget?: DndDropTarget;\n}\n\nexport interface DropEvent {\n name: 'drop';\n drag?: DropEventDragMeta;\n dropzone?: DropEventDropzoneMeta;\n}\n\nexport type AnalyticsParams =\n | DuplicateEvent\n | DestroyEvent\n | EditEvent\n | HistoryEvent\n | PreviewEvent\n | ToolbarMoveEvent\n | BlockInsertEvent\n | BlockSaveEvent\n | BlockDestroyEvent\n | DropEvent;\n\nexport interface Handlers {\n ready: EventHandler<ReadyParams>;\n error: EventHandler<ErrorParams>;\n save: EventHandler<SaveParams>;\n exit: EventHandler<ExitParams>;\n notification: EventHandler<NotificationParams>;\n autosave: EventHandler<AutosaveParams>;\n toggleGrid: EventHandler<ToggleGridParams>;\n togglePreview: EventHandler<TogglePreviewParams>;\n toggleViewMode: EventHandler<ToggleViewModeParams>;\n toggleMenu: EventHandler<ToggleMenuParams>;\n history: EventHandler<HistoryParams>;\n analytics: EventHandler<AnalyticsParams>;\n openGallery: EventHandler<(url?: string) => Promise<void>>;\n uploadImage: AsyncEventHandler<UploadImageParams, string>;\n loadPersonalization: AsyncEventHandler<void, PersonalizationDictionary>;\n}\n\nexport type HandlerParams<H> = H extends\n | EventHandler<infer P>\n | AsyncEventHandler<infer P, unknown>\n ? P\n : never;\n\nexport interface PluginConfig {\n container: string;\n locale?: string;\n autosave?:\n | boolean\n | {\n interval: number;\n };\n token: string;\n authData?: {\n orgId: number;\n projectId?: number;\n };\n pluginId: string;\n apiUrl: string;\n disableHotkeysPassing?: boolean;\n __config?: object;\n on: Partial<Handlers>;\n}\n","import { ImageParams } from './types';\n\nconst getImageFileSize = async (imageUrl: string) => {\n try {\n const response = await fetch(imageUrl, { method: 'HEAD' });\n\n if (!response.ok) {\n return null;\n }\n\n const contentLength = response.headers.get('Content-Length');\n\n if (contentLength) {\n return parseInt(contentLength, 10);\n } else {\n return null;\n }\n } catch (error) {\n return null;\n }\n};\n\nexport const getImageParamsFromFileUrl = (imgSrc: string) =>\n new Promise<Omit<ImageParams, 'url'>>((resolve, reject) => {\n const img = new Image();\n\n img.onload = async () => {\n const fileSize = (await getImageFileSize(imgSrc)) ?? 0;\n\n resolve({\n originalWidth: img.width,\n originalHeight: img.height,\n ratio: img.width / img.height,\n fileSize,\n });\n };\n\n img.onerror = (error) => {\n reject(error);\n };\n\n img.src = imgSrc;\n });\n\nconst getLatinKey = (key: string, code: string) => {\n if (key.length !== 1) {\n return key;\n }\n\n const capitalHetaCode = 880;\n const isNonLatin = key.charCodeAt(0) >= capitalHetaCode;\n\n if (isNonLatin) {\n if (code.indexOf('Key') === 0 && code.length === 4) {\n return code.charAt(3);\n }\n\n if (code.indexOf('Digit') === 0 && code.length === 6) {\n return code.charAt(5);\n }\n }\n\n return key;\n};\n\nexport const constructKeyCode = (event: KeyboardEvent) => {\n let keyCode =\n `${getLatinKey(event.key, event.code)}`.toLowerCase() || event.key;\n const macOs = navigator.userAgent.includes('Mac OS');\n\n if (keyCode === 'backspace' && macOs) {\n keyCode = 'delete';\n }\n\n const prefix = [];\n\n if ((macOs && event.metaKey) || (!macOs && event.ctrlKey)) {\n prefix.push('mod');\n }\n\n if (event.shiftKey) {\n prefix.push('shift');\n }\n\n if (prefix.length > 0) {\n keyCode = `${prefix.join('-')}-${getLatinKey(keyCode, event.code)}`;\n }\n\n return keyCode;\n};\n\nexport const CORE_HOTKEYS = new Set([\n 'escape',\n 'mod-c',\n 'mod-d',\n 'mod-z',\n 'mod-y',\n 'mod-shift-z',\n 'mod-v',\n 'delete',\n 'mod-g',\n 'mod-p',\n 'mod-s',\n]);\n","import { LOCAL_ENDPOINT, PROD_ENDPOINT } from './routes';\nimport {\n DraftError,\n EditorMenu,\n ExitParams,\n OnInitParams,\n OpenGalleryParams,\n Handlers,\n PluginConfig,\n SaveParams,\n TemplateJSON,\n UploadImageParams,\n ViewMode,\n HandlerParams,\n MessageData,\n ExportAsFileParams,\n} from './types';\nimport {\n getImageParamsFromFileUrl,\n constructKeyCode,\n CORE_HOTKEYS,\n} from './utils';\nimport pkg from '../package.json';\n\nconst getDeployLink = () => {\n const regex = new RegExp(`(^| )seplugin-dev=([^;]+)`);\n const match = document.cookie.match(regex);\n const value = match?.[2].toLowerCase?.();\n\n if (value === 'true') {\n return LOCAL_ENDPOINT;\n }\n\n if (value?.startsWith('https://')) {\n return value;\n }\n\n const [major, mid] = pkg.version.split('.');\n\n return `${PROD_ENDPOINT}/v${major}.${mid}`;\n};\n\nconst verifyConfig = ({ token, pluginId, apiUrl }: PluginConfig) => {\n if (!token) {\n throw new Error('No [token] was provided');\n }\n\n if (!pluginId) {\n throw new Error('No [pluginId] was provided');\n }\n\n if (!apiUrl) {\n throw new Error('No [apiUrl] was provided');\n }\n};\n\nconst createIframe = (parentOrigin: string) => {\n const iframe = document.createElement('iframe');\n const url = new URL(getDeployLink());\n url.searchParams.set('parentOrigin', parentOrigin);\n iframe.src = url.toString();\n iframe.setAttribute(\n 'style',\n 'height:100%;width:100%;min-width:960px;border:0px;',\n );\n iframe.setAttribute('allow', 'clipboard-read; clipboard-write');\n iframe.setAttribute(\n 'sandbox',\n 'allow-scripts allow-same-origin allow-forms allow-popups allow-downloads',\n );\n\n return iframe;\n};\n\nexport class PluginInstance {\n public iframe: HTMLIFrameElement | null = null;\n private hotkeysAttached = false;\n private iframeOrigin: string | null = null;\n constructor(public config: PluginConfig) {}\n\n private captureHotkeysEnabled() {\n return this.config.disableHotkeysPassing !== true;\n }\n\n private onHostHotkey = (event: KeyboardEvent) => {\n if (!this.captureHotkeysEnabled() || !this.iframe?.contentWindow) {\n return;\n }\n\n const keyCode = constructKeyCode(event);\n\n if (!CORE_HOTKEYS.has(keyCode)) {\n return;\n }\n\n const target = event.target as HTMLElement | null;\n\n if (\n target &&\n (target.isContentEditable ||\n ['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName))\n ) {\n return;\n }\n\n event.preventDefault();\n\n const { key, ctrlKey, metaKey, shiftKey, altKey } = event;\n\n this.postEvent('hostHotkey', {\n key,\n code: event.code,\n metaKey,\n ctrlKey,\n shiftKey,\n altKey,\n keyCode,\n });\n };\n\n private static HEARTBEAT_TIMEOUT = 4000;\n\n private promisedIframeMethod<T>(eventName: string) {\n let timer: ReturnType<typeof setTimeout> | null = null;\n let listener: ((e: MessageEvent<MessageData>) => void) | null = null;\n\n const cleanup = () => {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n\n if (listener) {\n window.removeEventListener('message', listener, true);\n listener = null;\n }\n };\n\n const res = new Promise<T>((resolve, reject) => {\n const resetTimer = () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n cleanup();\n reject(\n new DraftError('timeout_error', `Action \"${eventName}\" timed out`),\n );\n }, PluginInstance.HEARTBEAT_TIMEOUT);\n };\n\n listener = (e: MessageEvent<MessageData>) => {\n if (e.source !== this.iframe?.contentWindow) return;\n\n const { data } = e;\n if (data.source !== 'DraftPlugin') return;\n\n if (data.event === 'actionPing' && data.action === eventName) {\n e.stopPropagation();\n resetTimer();\n\n return;\n }\n\n if (data.event === eventName) {\n e.stopPropagation();\n cleanup();\n\n const { source: _1, event: _2, ok, code, message, ...rest } = data;\n\n if (ok === false) {\n reject(\n new DraftError(\n code || 'unknown_error',\n message || 'Unknown error',\n ),\n );\n } else {\n resolve(rest as T);\n }\n }\n };\n\n window.addEventListener('message', listener, true);\n resetTimer();\n });\n\n this.postEvent(eventName);\n\n return res;\n }\n\n private postEvent(event: string, data: object = {}) {\n if (this.iframe && this.iframe.contentWindow && this.iframeOrigin) {\n this.iframe.contentWindow.postMessage(\n {\n ...data,\n event,\n source: 'DraftPlugin',\n },\n this.iframeOrigin,\n );\n } else if (!this.iframeOrigin) {\n throw new Error('Iframe origin is not initialized');\n }\n }\n\n private onImageUpload = async ({\n id,\n ...data\n }: UploadImageParams & { id: string }) => {\n try {\n const url = await this.config.on.uploadImage?.(data);\n let params = {};\n\n if (url) {\n params = await getImageParamsFromFileUrl(url);\n }\n\n this.postEvent('imageUploaded', { id, img: { ...params, url } });\n } catch (e) {\n this.postEvent('imageUploaded', { id });\n }\n };\n\n private onLoadPersonalization = async () => {\n try {\n if (!this.config.on.loadPersonalization) {\n throw new Error('No personalization loader provided');\n }\n\n const personalizationDictionary =\n await this.config.on.loadPersonalization();\n\n this.postEvent('loadPersonalization', {\n items: personalizationDictionary,\n });\n } catch (e) {\n this.postEvent('loadPersonalization', {});\n }\n };\n\n private onGalleryOpen = async ({ id }: { id: string }) => {\n const applyImage = async (url?: string) => {\n const imgParams = { url };\n\n if (url) {\n const params = await getImageParamsFromFileUrl(url);\n Object.assign(imgParams, params);\n }\n\n this.postEvent('imageUploaded', {\n id,\n img: imgParams,\n });\n };\n\n this.config.on.openGallery?.(applyImage);\n };\n\n private triggerEvent<H extends CallableFunction | undefined>(\n handler: H,\n params: HandlerParams<H>,\n ) {\n if (!handler) {\n return;\n }\n\n return handler(params);\n }\n\n private onMessage = (\n ev: MessageEvent<{ source: string; event: keyof Handlers }>,\n ) => {\n if (ev.source !== this.iframe?.contentWindow) {\n return;\n }\n\n const {\n data: { source, event, ...data },\n } = ev;\n\n if (source === 'DraftPlugin') {\n if (event === 'openGallery') {\n this.onGalleryOpen(data as OpenGalleryParams);\n } else if (event === 'uploadImage') {\n this.onImageUpload(data as UploadImageParams & { id: string });\n } else if (event === 'loadPersonalization') {\n this.onLoadPersonalization();\n } else {\n this.triggerEvent(\n this.config.on[event],\n data as HandlerParams<Handlers[typeof event]>,\n );\n }\n }\n };\n\n start({\n template,\n templateName,\n uid,\n }: {\n template: string | TemplateJSON;\n uid: string | number;\n templateName?: string;\n }) {\n const containerEl = document.querySelector(this.config.container);\n\n if (!containerEl) {\n throw new Error('Specified container not found');\n } else {\n const onInit = (msg: OnInitParams) => {\n const {\n data: { source, event },\n } = msg;\n if (source === 'DraftPlugin' && event === 'loaded') {\n if (msg.source !== this.iframe?.contentWindow) return;\n\n this.iframeOrigin = msg.origin;\n\n const {\n on,\n container,\n locale,\n autosave,\n token,\n apiUrl,\n pluginId,\n authData,\n __config,\n } = this.config;\n\n verifyConfig(this.config);\n\n if (this.iframe && this.iframe.contentWindow) {\n this.postEvent('init', {\n container,\n locale,\n uid,\n autosave,\n token,\n pluginId,\n authData,\n apiUrl,\n __config,\n enabledListeners: Object.keys(on),\n template,\n templateName,\n });\n }\n\n window.addEventListener('message', this.onMessage);\n window.removeEventListener('message', onInit);\n }\n };\n\n this.iframe = createIframe(window.location.origin);\n window.addEventListener('message', onInit);\n containerEl.appendChild(this.iframe);\n\n if (this.captureHotkeysEnabled() && !this.hotkeysAttached) {\n window.addEventListener('keydown', this.onHostHotkey);\n this.hotkeysAttached = true;\n }\n }\n }\n\n destroy = () => {\n this.iframe?.remove();\n this.iframe = null;\n window.removeEventListener('message', this.onMessage);\n\n if (this.hotkeysAttached) {\n window.removeEventListener('keydown', this.onHostHotkey);\n this.hotkeysAttached = false;\n }\n };\n\n changeTemplate(\n template: string | TemplateJSON,\n options: {\n templateName?: string;\n uid?: string;\n } = {},\n ) {\n this.postEvent('changeTemplate', { ...options, template });\n }\n\n toggleGrid(state?: boolean) {\n this.postEvent('toggleGrid', { state });\n }\n\n togglePreview(state?: boolean) {\n this.postEvent('togglePreview', { state });\n }\n\n toggleMenu(menu: EditorMenu | null = null) {\n this.postEvent('toggleMenu', { menu });\n }\n\n toggleViewMode(viewMode: ViewMode) {\n this.postEvent('toggleViewMode', { viewMode });\n }\n\n undo() {\n this.postEvent('undo');\n }\n\n redo() {\n this.postEvent('redo');\n }\n\n save() {\n return this.promisedIframeMethod<SaveParams>('saveAction');\n }\n\n exit() {\n return this.promisedIframeMethod<ExitParams>('exitAction');\n }\n\n exportContent() {\n return this.promisedIframeMethod<SaveParams>('exportContent');\n }\n\n exportAsFile() {\n return this.promisedIframeMethod<ExportAsFileParams>('exportAsFile');\n }\n}\n","import { PluginInstance } from './plugin';\nimport { PluginConfig } from './types';\nimport { version } from '../package.json';\n\nconst DEFAULT_CONFIG: Partial<PluginConfig> = {\n container: '#draft-plugin-container',\n disableHotkeysPassing: false,\n locale: 'ru',\n on: {},\n};\n\nclass PluginWrapper {\n public version = version;\n\n create(config: PluginConfig) {\n return new PluginInstance({\n ...DEFAULT_CONFIG,\n ...config,\n });\n }\n}\n\nconst DraftPlugin = new PluginWrapper();\n\ndeclare global {\n interface Window {\n DraftPlugin: PluginWrapper;\n }\n}\n\nwindow.DraftPlugin = DraftPlugin;\n\nexport default DraftPlugin;\nexport * from './types';\n"],"names":["LOCAL_ENDPOINT","PROD_ENDPOINT","DraftError","code","message","__publicField","EditorMenu","ViewMode","getImageFileSize","imageUrl","response","contentLength","getImageParamsFromFileUrl","imgSrc","resolve","reject","img","fileSize","error","getLatinKey","key","constructKeyCode","event","keyCode","macOs","prefix","CORE_HOTKEYS","getDeployLink","_a","_b","regex","match","value","major","mid","pkg","verifyConfig","token","pluginId","apiUrl","createIframe","parentOrigin","iframe","url","_PluginInstance","config","target","ctrlKey","metaKey","shiftKey","altKey","id","data","params","personalizationDictionary","applyImage","imgParams","ev","source","eventName","timer","listener","cleanup","res","resetTimer","e","_1","_2","ok","rest","handler","template","templateName","uid","containerEl","onInit","msg","on","container","locale","autosave","authData","__config","options","state","menu","viewMode","PluginInstance","DEFAULT_CONFIG","PluginWrapper","version","DraftPlugin"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ var G=Object.defineProperty;var F=(l,d,f)=>d in l?G(l,d,{enumerable:!0,configurable:!0,writable:!0,value:f}):l[d]=f;var a=(l,d,f)=>F(l,typeof d!="symbol"?d+"":d,f);var DraftPlugin=(function(l){"use strict";const d="http://localhost:5174",f="https://seplugin.sendsay.ru";class w extends Error{constructor(t,o){super(o);a(this,"code");this.name="DraftError",this.code=t}}var A=(i=>(i.Audit="audit",i.Guide="guide",i.Style="style",i.Blocks="blocks",i))(A||{}),L=(i=>(i.Desktop="desktop",i.Mobile="mobile",i))(L||{});const C=async i=>{try{const e=await fetch(i,{method:"HEAD"});if(!e.ok)return null;const t=e.headers.get("Content-Length");return t?parseInt(t,10):null}catch{return null}},O=i=>new Promise((e,t)=>{const o=new Image;o.onload=async()=>{const n=await C(i)??0;e({originalWidth:o.width,originalHeight:o.height,ratio:o.width/o.height,fileSize:n})},o.onerror=n=>{t(n)},o.src=i}),I=(i,e)=>{if(i.length!==1)return i;if(i.charCodeAt(0)>=880){if(e.indexOf("Key")===0&&e.length===4)return e.charAt(3);if(e.indexOf("Digit")===0&&e.length===6)return e.charAt(5)}return i},M=i=>{let e=`${I(i.key,i.code)}`.toLowerCase()||i.key;const t=navigator.userAgent.includes("Mac OS");e==="backspace"&&t&&(e="delete");const o=[];return(t&&i.metaKey||!t&&i.ctrlKey)&&o.push("mod"),i.shiftKey&&o.push("shift"),o.length>0&&(e=`${o.join("-")}-${I(e,i.code)}`),e},z=new Set(["escape","mod-c","mod-d","mod-z","mod-y","mod-shift-z","mod-v","delete","mod-g","mod-p","mod-s"]),T="1.15.0",U={version:T},_=()=>{var r,s;const i=new RegExp("(^| )seplugin-dev=([^;]+)"),e=document.cookie.match(i),t=(s=e==null?void 0:(r=e[2]).toLowerCase)==null?void 0:s.call(r);if(t==="true")return d;if(t!=null&&t.startsWith("https://"))return t;const[o,n]=U.version.split(".");return`${f}/v${o}.${n}`},K=({token:i,pluginId:e,apiUrl:t})=>{if(!i)throw new Error("No [token] was provided");if(!e)throw new Error("No [pluginId] was provided");if(!t)throw new Error("No [apiUrl] was provided")},S=i=>{const e=document.createElement("iframe"),t=new URL(_());return t.searchParams.set("parentOrigin",i),e.src=t.toString(),e.setAttribute("style","height:100%;width:100%;min-width:960px;border:0px;"),e.setAttribute("allow","clipboard-read; clipboard-write"),e.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups allow-downloads"),e},m=class m{constructor(e){a(this,"iframe",null);a(this,"hotkeysAttached",!1);a(this,"iframeOrigin",null);a(this,"onHostHotkey",e=>{var c;if(!this.captureHotkeysEnabled()||!((c=this.iframe)!=null&&c.contentWindow))return;const t=M(e);if(!z.has(t))return;const o=e.target;if(o&&(o.isContentEditable||["INPUT","TEXTAREA","SELECT"].includes(o.tagName)))return;e.preventDefault();const{key:n,ctrlKey:r,metaKey:s,shiftKey:h,altKey:g}=e;this.postEvent("hostHotkey",{key:n,code:e.code,metaKey:s,ctrlKey:r,shiftKey:h,altKey:g,keyCode:t})});a(this,"onImageUpload",async({id:e,...t})=>{var o,n;try{const r=await((n=(o=this.config.on).uploadImage)==null?void 0:n.call(o,t));let s={};r&&(s=await O(r)),this.postEvent("imageUploaded",{id:e,img:{...s,url:r}})}catch{this.postEvent("imageUploaded",{id:e})}});a(this,"onLoadPersonalization",async()=>{try{if(!this.config.on.loadPersonalization)throw new Error("No personalization loader provided");const e=await this.config.on.loadPersonalization();this.postEvent("loadPersonalization",{items:e})}catch{this.postEvent("loadPersonalization",{})}});a(this,"onGalleryOpen",async({id:e})=>{var o,n;const t=async r=>{const s={url:r};if(r){const h=await O(r);Object.assign(s,h)}this.postEvent("imageUploaded",{id:e,img:s})};(n=(o=this.config.on).openGallery)==null||n.call(o,t)});a(this,"onMessage",e=>{var r;if(e.source!==((r=this.iframe)==null?void 0:r.contentWindow))return;const{data:{source:t,event:o,...n}}=e;t==="DraftPlugin"&&(o==="openGallery"?this.onGalleryOpen(n):o==="uploadImage"?this.onImageUpload(n):o==="loadPersonalization"?this.onLoadPersonalization():this.triggerEvent(this.config.on[o],n))});a(this,"destroy",()=>{var e;(e=this.iframe)==null||e.remove(),this.iframe=null,window.removeEventListener("message",this.onMessage),this.hotkeysAttached&&(window.removeEventListener("keydown",this.onHostHotkey),this.hotkeysAttached=!1)});this.config=e}captureHotkeysEnabled(){return this.config.disableHotkeysPassing!==!0}promisedIframeMethod(e){let t=null,o=null;const n=()=>{t&&(clearTimeout(t),t=null),o&&(window.removeEventListener("message",o,!0),o=null)},r=new Promise((s,h)=>{const g=()=>{t&&clearTimeout(t),t=setTimeout(()=>{n(),h(new w("timeout_error",`Action "${e}" timed out`))},m.HEARTBEAT_TIMEOUT)};o=c=>{var p;if(c.source!==((p=this.iframe)==null?void 0:p.contentWindow))return;const{data:u}=c;if(u.source==="DraftPlugin"){if(u.event==="actionPing"&&u.action===e){c.stopPropagation(),g();return}if(u.event===e){c.stopPropagation(),n();const{source:D,event:H,ok:y,code:v,message:k,...P}=u;y===!1?h(new w(v||"unknown_error",k||"Unknown error")):s(P)}}},window.addEventListener("message",o,!0),g()});return this.postEvent(e),r}postEvent(e,t={}){if(this.iframe&&this.iframe.contentWindow&&this.iframeOrigin)this.iframe.contentWindow.postMessage({...t,event:e,source:"DraftPlugin"},this.iframeOrigin);else if(!this.iframeOrigin)throw new Error("Iframe origin is not initialized")}triggerEvent(e,t){if(e)return e(t)}start({template:e,templateName:t,uid:o}){const n=document.querySelector(this.config.container);if(n){const r=s=>{var c;const{data:{source:h,event:g}}=s;if(h==="DraftPlugin"&&g==="loaded"){if(s.source!==((c=this.iframe)==null?void 0:c.contentWindow))return;this.iframeOrigin=s.origin;const{on:u,container:p,locale:D,autosave:H,token:y,apiUrl:v,pluginId:k,authData:P,__config:W}=this.config;K(this.config),this.iframe&&this.iframe.contentWindow&&this.postEvent("init",{container:p,locale:D,uid:o,autosave:H,token:y,pluginId:k,authData:P,apiUrl:v,__config:W,enabledListeners:Object.keys(u),template:e,templateName:t}),window.addEventListener("message",this.onMessage),window.removeEventListener("message",r)}};this.iframe=S(window.location.origin),window.addEventListener("message",r),n.appendChild(this.iframe),this.captureHotkeysEnabled()&&!this.hotkeysAttached&&(window.addEventListener("keydown",this.onHostHotkey),this.hotkeysAttached=!0)}else throw new Error("Specified container not found")}changeTemplate(e,t={}){this.postEvent("changeTemplate",{...t,template:e})}toggleGrid(e){this.postEvent("toggleGrid",{state:e})}togglePreview(e){this.postEvent("togglePreview",{state:e})}toggleMenu(e=null){this.postEvent("toggleMenu",{menu:e})}toggleViewMode(e){this.postEvent("toggleViewMode",{viewMode:e})}undo(){this.postEvent("undo")}redo(){this.postEvent("redo")}save(){return this.promisedIframeMethod("saveAction")}exit(){return this.promisedIframeMethod("exitAction")}exportContent(){return this.promisedIframeMethod("exportContent")}exportAsFile(){return this.promisedIframeMethod("exportAsFile")}};a(m,"HEARTBEAT_TIMEOUT",4e3);let E=m;const x={container:"#draft-plugin-container",disableHotkeysPassing:!1,locale:"ru",on:{}};class N{constructor(){a(this,"version",T)}create(e){return new E({...x,...e})}}const b=new N;return window.DraftPlugin=b,l.DraftError=w,l.EditorMenu=A,l.ViewMode=L,l.default=b,Object.defineProperties(l,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}}),l})({});
2
+ //# sourceMappingURL=index.iife.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.iife.js","sources":["../src/routes.ts","../src/types.ts","../src/utils.ts","../src/plugin.ts","../src/index.ts"],"sourcesContent":["export const LOCAL_ENDPOINT = 'http://localhost:5174';\nexport const PROD_ENDPOINT = 'https://seplugin.sendsay.ru';\n","export type EventHandler<T> = (data: T) => void;\n\nexport type AsyncEventHandler<P, R> = (params: P) => Promise<R>;\n\nexport class DraftError extends Error {\n public readonly code: string;\n\n constructor(code: string, message: string) {\n super(message);\n this.name = 'DraftError';\n this.code = code;\n }\n}\n\nexport type MessageData = {\n source: string;\n event: string;\n ok?: boolean;\n code?: string;\n message?: string;\n action?: string;\n};\n\nexport interface ExportAsFileParams {\n blob: Blob;\n fileName: string;\n}\n\nexport interface SaveParams {\n json: TemplateJSON;\n html: string;\n}\n\nexport type OnInitParams = MessageEvent<{\n source: string;\n event: 'loaded' | unknown;\n}>;\n\nexport enum EditorMenu {\n Audit = 'audit',\n Guide = 'guide',\n Style = 'style',\n Blocks = 'blocks',\n}\n\nexport enum ViewMode {\n Desktop = 'desktop',\n Mobile = 'mobile',\n}\n\nexport interface ReadyParams extends SaveParams {\n lastSavedTemplate?: {\n template: TemplateJSON;\n date: Date;\n };\n}\n\nexport interface ErrorParams {\n message: string;\n code?: string;\n details?: unknown;\n}\n\nexport interface ExitParams extends SaveParams {}\n\nexport interface NotificationParams {\n intent: 'error' | 'info' | 'success' | 'warning';\n errorDetails?: object;\n message?: string;\n title: string;\n}\n\nexport interface OpenGalleryParams {\n id: string;\n}\n\nexport interface UploadImageParams {\n file: string;\n name: string;\n}\n\nexport interface ImageParams {\n url: string;\n originalWidth: number;\n originalHeight: number;\n ratio: number;\n fileSize: number;\n}\n\nexport interface AutosaveParams {\n json: TemplateJSON;\n}\n\ninterface ToggleParams {\n state: boolean;\n}\n\nexport interface ToggleGridParams extends ToggleParams {}\n\nexport interface TogglePreviewParams extends ToggleParams {\n json: TemplateJSON;\n html: string;\n darkHTML: string;\n}\n\nexport interface ToggleViewModeParams {\n mode: ViewMode;\n}\n\nexport interface ToggleMenuParams {\n menu: EditorMenu | null;\n}\n\nexport interface HistoryParams {\n hasUndos: boolean;\n hasRedos: boolean;\n currentStep: number;\n}\n\nexport type TemplateJSON = Record<string, any>;\n\nexport type PersonalizationDictionary = Array<\n | { name: string; value: string }\n | { groupName: string; items: Array<{ name: string; value: string }> }\n>;\n\nexport type ToolbarActionName =\n | 'duplicate'\n | 'destroy'\n | 'edit'\n | 'up'\n | 'down';\nexport type HotkeyContext = 'hotkey';\nexport type OverlayContext = 'overlay-click' | 'overlay-double-click';\nexport type ToolbarContext = 'toolbar';\nexport type UnitSettingsContext = 'unit-settings';\nexport type BlockType = 'system' | 'user';\nexport type DndDragContext = 'canvas' | 'list' | 'palette';\nexport type DndDropContext = 'dropline' | 'placeholder' | 'empty-placeholder';\nexport type DndDropTarget = 'root' | 'section' | 'column' | 'element';\n\nexport interface DuplicateEvent {\n name: 'duplicate';\n context: HotkeyContext | ToolbarContext | UnitSettingsContext;\n unitType: string;\n}\n\nexport interface DestroyEvent {\n name: 'destroy';\n context: HotkeyContext | ToolbarContext | UnitSettingsContext;\n unitType: string;\n}\n\nexport interface EditEvent {\n name: 'edit';\n context: OverlayContext | ToolbarContext;\n unitType: string;\n}\n\nexport interface HistoryEvent {\n name: 'history';\n type: 'undo' | 'redo';\n context: HotkeyContext;\n}\n\nexport interface PreviewEvent {\n name: 'preview';\n context: HotkeyContext;\n}\n\nexport interface ToolbarMoveEvent {\n name: 'up' | 'down';\n context: ToolbarContext;\n unitType: string;\n}\n\nexport interface BlockInsertEvent {\n name: 'block-insert';\n context: 'double-click';\n blockType: BlockType;\n blockName: string;\n blockCategory: string | number;\n blockId: string | number;\n}\n\nexport interface BlockSaveEvent {\n name: 'block-save';\n blockType: 'user';\n blockName: string;\n blockCategory: string | number;\n blockId: string | number;\n elements: Record<string, number> & { sum: number };\n}\n\nexport interface BlockDestroyEvent {\n name: 'block-destroy';\n}\n\nexport interface DropEventDragMeta {\n context?: DndDragContext;\n layer?: 'element' | 'section' | 'column' | 'root';\n type?: string | string[];\n blockCategory?: string | number;\n blockId?: string | number;\n blockName?: string;\n blockType?: BlockType;\n alt?: boolean;\n dropKind?: 'create' | 'move';\n}\n\nexport interface DropEventDropzoneMeta {\n context?: DndDropContext;\n dropTarget?: DndDropTarget;\n}\n\nexport interface DropEvent {\n name: 'drop';\n drag?: DropEventDragMeta;\n dropzone?: DropEventDropzoneMeta;\n}\n\nexport type AnalyticsParams =\n | DuplicateEvent\n | DestroyEvent\n | EditEvent\n | HistoryEvent\n | PreviewEvent\n | ToolbarMoveEvent\n | BlockInsertEvent\n | BlockSaveEvent\n | BlockDestroyEvent\n | DropEvent;\n\nexport interface Handlers {\n ready: EventHandler<ReadyParams>;\n error: EventHandler<ErrorParams>;\n save: EventHandler<SaveParams>;\n exit: EventHandler<ExitParams>;\n notification: EventHandler<NotificationParams>;\n autosave: EventHandler<AutosaveParams>;\n toggleGrid: EventHandler<ToggleGridParams>;\n togglePreview: EventHandler<TogglePreviewParams>;\n toggleViewMode: EventHandler<ToggleViewModeParams>;\n toggleMenu: EventHandler<ToggleMenuParams>;\n history: EventHandler<HistoryParams>;\n analytics: EventHandler<AnalyticsParams>;\n openGallery: EventHandler<(url?: string) => Promise<void>>;\n uploadImage: AsyncEventHandler<UploadImageParams, string>;\n loadPersonalization: AsyncEventHandler<void, PersonalizationDictionary>;\n}\n\nexport type HandlerParams<H> = H extends\n | EventHandler<infer P>\n | AsyncEventHandler<infer P, unknown>\n ? P\n : never;\n\nexport interface PluginConfig {\n container: string;\n locale?: string;\n autosave?:\n | boolean\n | {\n interval: number;\n };\n token: string;\n authData?: {\n orgId: number;\n projectId?: number;\n };\n pluginId: string;\n apiUrl: string;\n disableHotkeysPassing?: boolean;\n __config?: object;\n on: Partial<Handlers>;\n}\n","import { ImageParams } from './types';\n\nconst getImageFileSize = async (imageUrl: string) => {\n try {\n const response = await fetch(imageUrl, { method: 'HEAD' });\n\n if (!response.ok) {\n return null;\n }\n\n const contentLength = response.headers.get('Content-Length');\n\n if (contentLength) {\n return parseInt(contentLength, 10);\n } else {\n return null;\n }\n } catch (error) {\n return null;\n }\n};\n\nexport const getImageParamsFromFileUrl = (imgSrc: string) =>\n new Promise<Omit<ImageParams, 'url'>>((resolve, reject) => {\n const img = new Image();\n\n img.onload = async () => {\n const fileSize = (await getImageFileSize(imgSrc)) ?? 0;\n\n resolve({\n originalWidth: img.width,\n originalHeight: img.height,\n ratio: img.width / img.height,\n fileSize,\n });\n };\n\n img.onerror = (error) => {\n reject(error);\n };\n\n img.src = imgSrc;\n });\n\nconst getLatinKey = (key: string, code: string) => {\n if (key.length !== 1) {\n return key;\n }\n\n const capitalHetaCode = 880;\n const isNonLatin = key.charCodeAt(0) >= capitalHetaCode;\n\n if (isNonLatin) {\n if (code.indexOf('Key') === 0 && code.length === 4) {\n return code.charAt(3);\n }\n\n if (code.indexOf('Digit') === 0 && code.length === 6) {\n return code.charAt(5);\n }\n }\n\n return key;\n};\n\nexport const constructKeyCode = (event: KeyboardEvent) => {\n let keyCode =\n `${getLatinKey(event.key, event.code)}`.toLowerCase() || event.key;\n const macOs = navigator.userAgent.includes('Mac OS');\n\n if (keyCode === 'backspace' && macOs) {\n keyCode = 'delete';\n }\n\n const prefix = [];\n\n if ((macOs && event.metaKey) || (!macOs && event.ctrlKey)) {\n prefix.push('mod');\n }\n\n if (event.shiftKey) {\n prefix.push('shift');\n }\n\n if (prefix.length > 0) {\n keyCode = `${prefix.join('-')}-${getLatinKey(keyCode, event.code)}`;\n }\n\n return keyCode;\n};\n\nexport const CORE_HOTKEYS = new Set([\n 'escape',\n 'mod-c',\n 'mod-d',\n 'mod-z',\n 'mod-y',\n 'mod-shift-z',\n 'mod-v',\n 'delete',\n 'mod-g',\n 'mod-p',\n 'mod-s',\n]);\n","import { LOCAL_ENDPOINT, PROD_ENDPOINT } from './routes';\nimport {\n DraftError,\n EditorMenu,\n ExitParams,\n OnInitParams,\n OpenGalleryParams,\n Handlers,\n PluginConfig,\n SaveParams,\n TemplateJSON,\n UploadImageParams,\n ViewMode,\n HandlerParams,\n MessageData,\n ExportAsFileParams,\n} from './types';\nimport {\n getImageParamsFromFileUrl,\n constructKeyCode,\n CORE_HOTKEYS,\n} from './utils';\nimport pkg from '../package.json';\n\nconst getDeployLink = () => {\n const regex = new RegExp(`(^| )seplugin-dev=([^;]+)`);\n const match = document.cookie.match(regex);\n const value = match?.[2].toLowerCase?.();\n\n if (value === 'true') {\n return LOCAL_ENDPOINT;\n }\n\n if (value?.startsWith('https://')) {\n return value;\n }\n\n const [major, mid] = pkg.version.split('.');\n\n return `${PROD_ENDPOINT}/v${major}.${mid}`;\n};\n\nconst verifyConfig = ({ token, pluginId, apiUrl }: PluginConfig) => {\n if (!token) {\n throw new Error('No [token] was provided');\n }\n\n if (!pluginId) {\n throw new Error('No [pluginId] was provided');\n }\n\n if (!apiUrl) {\n throw new Error('No [apiUrl] was provided');\n }\n};\n\nconst createIframe = (parentOrigin: string) => {\n const iframe = document.createElement('iframe');\n const url = new URL(getDeployLink());\n url.searchParams.set('parentOrigin', parentOrigin);\n iframe.src = url.toString();\n iframe.setAttribute(\n 'style',\n 'height:100%;width:100%;min-width:960px;border:0px;',\n );\n iframe.setAttribute('allow', 'clipboard-read; clipboard-write');\n iframe.setAttribute(\n 'sandbox',\n 'allow-scripts allow-same-origin allow-forms allow-popups allow-downloads',\n );\n\n return iframe;\n};\n\nexport class PluginInstance {\n public iframe: HTMLIFrameElement | null = null;\n private hotkeysAttached = false;\n private iframeOrigin: string | null = null;\n constructor(public config: PluginConfig) {}\n\n private captureHotkeysEnabled() {\n return this.config.disableHotkeysPassing !== true;\n }\n\n private onHostHotkey = (event: KeyboardEvent) => {\n if (!this.captureHotkeysEnabled() || !this.iframe?.contentWindow) {\n return;\n }\n\n const keyCode = constructKeyCode(event);\n\n if (!CORE_HOTKEYS.has(keyCode)) {\n return;\n }\n\n const target = event.target as HTMLElement | null;\n\n if (\n target &&\n (target.isContentEditable ||\n ['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName))\n ) {\n return;\n }\n\n event.preventDefault();\n\n const { key, ctrlKey, metaKey, shiftKey, altKey } = event;\n\n this.postEvent('hostHotkey', {\n key,\n code: event.code,\n metaKey,\n ctrlKey,\n shiftKey,\n altKey,\n keyCode,\n });\n };\n\n private static HEARTBEAT_TIMEOUT = 4000;\n\n private promisedIframeMethod<T>(eventName: string) {\n let timer: ReturnType<typeof setTimeout> | null = null;\n let listener: ((e: MessageEvent<MessageData>) => void) | null = null;\n\n const cleanup = () => {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n\n if (listener) {\n window.removeEventListener('message', listener, true);\n listener = null;\n }\n };\n\n const res = new Promise<T>((resolve, reject) => {\n const resetTimer = () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n cleanup();\n reject(\n new DraftError('timeout_error', `Action \"${eventName}\" timed out`),\n );\n }, PluginInstance.HEARTBEAT_TIMEOUT);\n };\n\n listener = (e: MessageEvent<MessageData>) => {\n if (e.source !== this.iframe?.contentWindow) return;\n\n const { data } = e;\n if (data.source !== 'DraftPlugin') return;\n\n if (data.event === 'actionPing' && data.action === eventName) {\n e.stopPropagation();\n resetTimer();\n\n return;\n }\n\n if (data.event === eventName) {\n e.stopPropagation();\n cleanup();\n\n const { source: _1, event: _2, ok, code, message, ...rest } = data;\n\n if (ok === false) {\n reject(\n new DraftError(\n code || 'unknown_error',\n message || 'Unknown error',\n ),\n );\n } else {\n resolve(rest as T);\n }\n }\n };\n\n window.addEventListener('message', listener, true);\n resetTimer();\n });\n\n this.postEvent(eventName);\n\n return res;\n }\n\n private postEvent(event: string, data: object = {}) {\n if (this.iframe && this.iframe.contentWindow && this.iframeOrigin) {\n this.iframe.contentWindow.postMessage(\n {\n ...data,\n event,\n source: 'DraftPlugin',\n },\n this.iframeOrigin,\n );\n } else if (!this.iframeOrigin) {\n throw new Error('Iframe origin is not initialized');\n }\n }\n\n private onImageUpload = async ({\n id,\n ...data\n }: UploadImageParams & { id: string }) => {\n try {\n const url = await this.config.on.uploadImage?.(data);\n let params = {};\n\n if (url) {\n params = await getImageParamsFromFileUrl(url);\n }\n\n this.postEvent('imageUploaded', { id, img: { ...params, url } });\n } catch (e) {\n this.postEvent('imageUploaded', { id });\n }\n };\n\n private onLoadPersonalization = async () => {\n try {\n if (!this.config.on.loadPersonalization) {\n throw new Error('No personalization loader provided');\n }\n\n const personalizationDictionary =\n await this.config.on.loadPersonalization();\n\n this.postEvent('loadPersonalization', {\n items: personalizationDictionary,\n });\n } catch (e) {\n this.postEvent('loadPersonalization', {});\n }\n };\n\n private onGalleryOpen = async ({ id }: { id: string }) => {\n const applyImage = async (url?: string) => {\n const imgParams = { url };\n\n if (url) {\n const params = await getImageParamsFromFileUrl(url);\n Object.assign(imgParams, params);\n }\n\n this.postEvent('imageUploaded', {\n id,\n img: imgParams,\n });\n };\n\n this.config.on.openGallery?.(applyImage);\n };\n\n private triggerEvent<H extends CallableFunction | undefined>(\n handler: H,\n params: HandlerParams<H>,\n ) {\n if (!handler) {\n return;\n }\n\n return handler(params);\n }\n\n private onMessage = (\n ev: MessageEvent<{ source: string; event: keyof Handlers }>,\n ) => {\n if (ev.source !== this.iframe?.contentWindow) {\n return;\n }\n\n const {\n data: { source, event, ...data },\n } = ev;\n\n if (source === 'DraftPlugin') {\n if (event === 'openGallery') {\n this.onGalleryOpen(data as OpenGalleryParams);\n } else if (event === 'uploadImage') {\n this.onImageUpload(data as UploadImageParams & { id: string });\n } else if (event === 'loadPersonalization') {\n this.onLoadPersonalization();\n } else {\n this.triggerEvent(\n this.config.on[event],\n data as HandlerParams<Handlers[typeof event]>,\n );\n }\n }\n };\n\n start({\n template,\n templateName,\n uid,\n }: {\n template: string | TemplateJSON;\n uid: string | number;\n templateName?: string;\n }) {\n const containerEl = document.querySelector(this.config.container);\n\n if (!containerEl) {\n throw new Error('Specified container not found');\n } else {\n const onInit = (msg: OnInitParams) => {\n const {\n data: { source, event },\n } = msg;\n if (source === 'DraftPlugin' && event === 'loaded') {\n if (msg.source !== this.iframe?.contentWindow) return;\n\n this.iframeOrigin = msg.origin;\n\n const {\n on,\n container,\n locale,\n autosave,\n token,\n apiUrl,\n pluginId,\n authData,\n __config,\n } = this.config;\n\n verifyConfig(this.config);\n\n if (this.iframe && this.iframe.contentWindow) {\n this.postEvent('init', {\n container,\n locale,\n uid,\n autosave,\n token,\n pluginId,\n authData,\n apiUrl,\n __config,\n enabledListeners: Object.keys(on),\n template,\n templateName,\n });\n }\n\n window.addEventListener('message', this.onMessage);\n window.removeEventListener('message', onInit);\n }\n };\n\n this.iframe = createIframe(window.location.origin);\n window.addEventListener('message', onInit);\n containerEl.appendChild(this.iframe);\n\n if (this.captureHotkeysEnabled() && !this.hotkeysAttached) {\n window.addEventListener('keydown', this.onHostHotkey);\n this.hotkeysAttached = true;\n }\n }\n }\n\n destroy = () => {\n this.iframe?.remove();\n this.iframe = null;\n window.removeEventListener('message', this.onMessage);\n\n if (this.hotkeysAttached) {\n window.removeEventListener('keydown', this.onHostHotkey);\n this.hotkeysAttached = false;\n }\n };\n\n changeTemplate(\n template: string | TemplateJSON,\n options: {\n templateName?: string;\n uid?: string;\n } = {},\n ) {\n this.postEvent('changeTemplate', { ...options, template });\n }\n\n toggleGrid(state?: boolean) {\n this.postEvent('toggleGrid', { state });\n }\n\n togglePreview(state?: boolean) {\n this.postEvent('togglePreview', { state });\n }\n\n toggleMenu(menu: EditorMenu | null = null) {\n this.postEvent('toggleMenu', { menu });\n }\n\n toggleViewMode(viewMode: ViewMode) {\n this.postEvent('toggleViewMode', { viewMode });\n }\n\n undo() {\n this.postEvent('undo');\n }\n\n redo() {\n this.postEvent('redo');\n }\n\n save() {\n return this.promisedIframeMethod<SaveParams>('saveAction');\n }\n\n exit() {\n return this.promisedIframeMethod<ExitParams>('exitAction');\n }\n\n exportContent() {\n return this.promisedIframeMethod<SaveParams>('exportContent');\n }\n\n exportAsFile() {\n return this.promisedIframeMethod<ExportAsFileParams>('exportAsFile');\n }\n}\n","import { PluginInstance } from './plugin';\nimport { PluginConfig } from './types';\nimport { version } from '../package.json';\n\nconst DEFAULT_CONFIG: Partial<PluginConfig> = {\n container: '#draft-plugin-container',\n disableHotkeysPassing: false,\n locale: 'ru',\n on: {},\n};\n\nclass PluginWrapper {\n public version = version;\n\n create(config: PluginConfig) {\n return new PluginInstance({\n ...DEFAULT_CONFIG,\n ...config,\n });\n }\n}\n\nconst DraftPlugin = new PluginWrapper();\n\ndeclare global {\n interface Window {\n DraftPlugin: PluginWrapper;\n }\n}\n\nwindow.DraftPlugin = DraftPlugin;\n\nexport default DraftPlugin;\nexport * from './types';\n"],"names":["LOCAL_ENDPOINT","PROD_ENDPOINT","DraftError","code","message","__publicField","EditorMenu","ViewMode","getImageFileSize","imageUrl","response","contentLength","getImageParamsFromFileUrl","imgSrc","resolve","reject","img","fileSize","error","getLatinKey","key","constructKeyCode","event","keyCode","macOs","prefix","CORE_HOTKEYS","getDeployLink","regex","match","value","_b","_a","major","mid","pkg","verifyConfig","token","pluginId","apiUrl","createIframe","parentOrigin","iframe","url","_PluginInstance","config","target","ctrlKey","metaKey","shiftKey","altKey","id","data","params","personalizationDictionary","applyImage","imgParams","ev","source","eventName","timer","listener","cleanup","res","resetTimer","e","_1","_2","ok","rest","handler","template","templateName","uid","containerEl","onInit","msg","on","container","locale","autosave","authData","__config","options","state","menu","viewMode","PluginInstance","DEFAULT_CONFIG","PluginWrapper","version","DraftPlugin"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { PluginInstance } from './plugin';
2
2
  import { PluginConfig } from './types';
3
3
  declare class PluginWrapper {
4
+ version: string;
4
5
  create(config: PluginConfig): PluginInstance;
5
6
  }
6
7
  declare const DraftPlugin: PluginWrapper;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AASvC,cAAM,aAAa;IACjB,MAAM,CAAC,MAAM,EAAE,YAAY;CAM5B;AAED,QAAA,MAAM,WAAW,eAAsB,CAAC;AAExC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,WAAW,EAAE,aAAa,CAAC;KAC5B;CACF;AAID,eAAe,WAAW,CAAC;AAC3B,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAUvC,cAAM,aAAa;IACV,OAAO,SAAW;IAEzB,MAAM,CAAC,MAAM,EAAE,YAAY;CAM5B;AAED,QAAA,MAAM,WAAW,eAAsB,CAAC;AAExC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,WAAW,EAAE,aAAa,CAAC;KAC5B;CACF;AAID,eAAe,WAAW,CAAC;AAC3B,cAAc,SAAS,CAAC"}
@@ -1,11 +1,13 @@
1
- import { EditorMenu, ExitParams, PluginConfig, SaveParams, TemplateJSON, ViewMode } from './types';
1
+ import { EditorMenu, ExitParams, PluginConfig, SaveParams, TemplateJSON, ViewMode, ExportAsFileParams } from './types';
2
2
  export declare class PluginInstance {
3
3
  config: PluginConfig;
4
4
  iframe: HTMLIFrameElement | null;
5
5
  private hotkeysAttached;
6
+ private iframeOrigin;
6
7
  constructor(config: PluginConfig);
7
8
  private captureHotkeysEnabled;
8
9
  private onHostHotkey;
10
+ private static HEARTBEAT_TIMEOUT;
9
11
  private promisedIframeMethod;
10
12
  private postEvent;
11
13
  private onImageUpload;
@@ -15,7 +17,7 @@ export declare class PluginInstance {
15
17
  private onMessage;
16
18
  start({ template, templateName, uid, }: {
17
19
  template: string | TemplateJSON;
18
- uid: string;
20
+ uid: string | number;
19
21
  templateName?: string;
20
22
  }): void;
21
23
  destroy: () => void;
@@ -32,5 +34,6 @@ export declare class PluginInstance {
32
34
  save(): Promise<SaveParams>;
33
35
  exit(): Promise<ExitParams>;
34
36
  exportContent(): Promise<SaveParams>;
37
+ exportAsFile(): Promise<ExportAsFileParams>;
35
38
  }
36
39
  //# sourceMappingURL=plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EACV,UAAU,EAIV,YAAY,EACZ,UAAU,EACV,YAAY,EAEZ,QAAQ,EAET,MAAM,SAAS,CAAC;AAwDjB,qBAAa,cAAc;IAGN,MAAM,EAAE,YAAY;IAFhC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAC/C,OAAO,CAAC,eAAe,CAAS;gBACb,MAAM,EAAE,YAAY;IAEvC,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,YAAY,CAkClB;IAEF,OAAO,CAAC,oBAAoB;IAoC5B,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,aAAa,CAgBnB;IAEF,OAAO,CAAC,qBAAqB,CAe3B;IAEF,OAAO,CAAC,aAAa,CAgBnB;IAEF,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,SAAS,CAqBf;IAEF,KAAK,CAAC,EACJ,QAAQ,EACR,YAAY,EACZ,GAAG,GACJ,EAAE;QACD,QAAQ,EAAE,MAAM,GAAG,YAAY,CAAC;QAChC,GAAG,EAAE,MAAM,CAAC;QACZ,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;IAqDD,OAAO,aASL;IAEF,cAAc,CACZ,QAAQ,EAAE,MAAM,GAAG,YAAY,EAC/B,OAAO,GAAE;QACP,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,GAAG,CAAC,EAAE,MAAM,CAAC;KACT;IAKR,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO;IAI1B,aAAa,CAAC,KAAK,CAAC,EAAE,OAAO;IAI7B,UAAU,CAAC,IAAI,GAAE,UAAU,GAAG,IAAW;IAIzC,cAAc,CAAC,QAAQ,EAAE,QAAQ;IAIjC,IAAI;IAIJ,IAAI;IAIJ,IAAI;IAIJ,IAAI;IAIJ,aAAa;CAGd"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,UAAU,EACV,UAAU,EAIV,YAAY,EACZ,UAAU,EACV,YAAY,EAEZ,QAAQ,EAGR,kBAAkB,EACnB,MAAM,SAAS,CAAC;AA0DjB,qBAAa,cAAc;IAIN,MAAM,EAAE,YAAY;IAHhC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAC/C,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,YAAY,CAAuB;gBACxB,MAAM,EAAE,YAAY;IAEvC,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,YAAY,CAkClB;IAEF,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAQ;IAExC,OAAO,CAAC,oBAAoB;IAoE5B,OAAO,CAAC,SAAS;IAejB,OAAO,CAAC,aAAa,CAgBnB;IAEF,OAAO,CAAC,qBAAqB,CAe3B;IAEF,OAAO,CAAC,aAAa,CAgBnB;IAEF,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,SAAS,CAyBf;IAEF,KAAK,CAAC,EACJ,QAAQ,EACR,YAAY,EACZ,GAAG,GACJ,EAAE;QACD,QAAQ,EAAE,MAAM,GAAG,YAAY,CAAC;QAChC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;IA8DD,OAAO,aASL;IAEF,cAAc,CACZ,QAAQ,EAAE,MAAM,GAAG,YAAY,EAC/B,OAAO,GAAE;QACP,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,GAAG,CAAC,EAAE,MAAM,CAAC;KACT;IAKR,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO;IAI1B,aAAa,CAAC,KAAK,CAAC,EAAE,OAAO;IAI7B,UAAU,CAAC,IAAI,GAAE,UAAU,GAAG,IAAW;IAIzC,cAAc,CAAC,QAAQ,EAAE,QAAQ;IAIjC,IAAI;IAIJ,IAAI;IAIJ,IAAI;IAIJ,IAAI;IAIJ,aAAa;IAIb,YAAY;CAGb"}
@@ -1,5 +1,21 @@
1
1
  export type EventHandler<T> = (data: T) => void;
2
2
  export type AsyncEventHandler<P, R> = (params: P) => Promise<R>;
3
+ export declare class DraftError extends Error {
4
+ readonly code: string;
5
+ constructor(code: string, message: string);
6
+ }
7
+ export type MessageData = {
8
+ source: string;
9
+ event: string;
10
+ ok?: boolean;
11
+ code?: string;
12
+ message?: string;
13
+ action?: string;
14
+ };
15
+ export interface ExportAsFileParams {
16
+ blob: Blob;
17
+ fileName: string;
18
+ }
3
19
  export interface SaveParams {
4
20
  json: TemplateJSON;
5
21
  html: string;
@@ -27,6 +43,7 @@ export interface ReadyParams extends SaveParams {
27
43
  export interface ErrorParams {
28
44
  message: string;
29
45
  code?: string;
46
+ details?: unknown;
30
47
  }
31
48
  export interface ExitParams extends SaveParams {
32
49
  }
@@ -190,6 +207,10 @@ export interface PluginConfig {
190
207
  interval: number;
191
208
  };
192
209
  token: string;
210
+ authData?: {
211
+ orgId: number;
212
+ projectId?: number;
213
+ };
193
214
  pluginId: string;
194
215
  apiUrl: string;
195
216
  disableHotkeysPassing?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAsBtC,eAAO,MAAM,yBAAyB,WAAY,MAAM,sCAoBpD,CAAC;AAuBL,eAAO,MAAM,gBAAgB,UAAW,aAAa,WAwBpD,CAAC;AAEF,eAAO,MAAM,YAAY,aAYvB,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAsBtC,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,sCAoBpD,CAAC;AAuBL,eAAO,MAAM,gBAAgB,GAAI,OAAO,aAAa,WAwBpD,CAAC;AAEF,eAAO,MAAM,YAAY,aAYvB,CAAC"}
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@getdraft/plugin",
3
- "version": "1.14.0",
3
+ "version": "1.15.0",
4
4
  "main": "dist/index.cjs.js",
5
5
  "module": "dist/index.es.js",
6
+ "browser": "dist/index.iife.js",
6
7
  "types": "src",
7
8
  "dependencies": {},
8
9
  "devDependencies": {
@@ -10,9 +11,9 @@
10
11
  "rollup": "4.22.4",
11
12
  "terser": "5.31.3",
12
13
  "rollup-plugin-dts": "6.1.1",
13
- "@types/letty": "^1.0.0",
14
- "@letty/eslint-config-ts": "^1.0.0",
15
- "@letty/prettier": "^1.0.0"
14
+ "@getdraft/prettier": "^1.0.0",
15
+ "@types/getdraft": "^1.0.0",
16
+ "@getdraft/eslint-config-ts": "^1.0.0"
16
17
  },
17
18
  "license": "MIT",
18
19
  "scripts": {
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { PluginInstance } from './plugin';
2
2
  import { PluginConfig } from './types';
3
+ import { version } from '../package.json';
3
4
 
4
5
  const DEFAULT_CONFIG: Partial<PluginConfig> = {
5
6
  container: '#draft-plugin-container',
@@ -9,6 +10,8 @@ const DEFAULT_CONFIG: Partial<PluginConfig> = {
9
10
  };
10
11
 
11
12
  class PluginWrapper {
13
+ public version = version;
14
+
12
15
  create(config: PluginConfig) {
13
16
  return new PluginInstance({
14
17
  ...DEFAULT_CONFIG,
package/src/plugin.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { LOCAL_ENDPOINT, PROD_ENDPOINT } from './routes';
2
2
  import {
3
+ DraftError,
3
4
  EditorMenu,
4
5
  ExitParams,
5
6
  OnInitParams,
@@ -11,6 +12,8 @@ import {
11
12
  UploadImageParams,
12
13
  ViewMode,
13
14
  HandlerParams,
15
+ MessageData,
16
+ ExportAsFileParams,
14
17
  } from './types';
15
18
  import {
16
19
  getImageParamsFromFileUrl,
@@ -51,17 +54,19 @@ const verifyConfig = ({ token, pluginId, apiUrl }: PluginConfig) => {
51
54
  }
52
55
  };
53
56
 
54
- const createIframe = () => {
57
+ const createIframe = (parentOrigin: string) => {
55
58
  const iframe = document.createElement('iframe');
56
- iframe.src = getDeployLink();
59
+ const url = new URL(getDeployLink());
60
+ url.searchParams.set('parentOrigin', parentOrigin);
61
+ iframe.src = url.toString();
57
62
  iframe.setAttribute(
58
63
  'style',
59
- 'height:100%;width:100%;min-width:960px;border:0px',
64
+ 'height:100%;width:100%;min-width:960px;border:0px;',
60
65
  );
61
66
  iframe.setAttribute('allow', 'clipboard-read; clipboard-write');
62
67
  iframe.setAttribute(
63
68
  'sandbox',
64
- 'allow-scripts allow-same-origin allow-forms allow-popups',
69
+ 'allow-scripts allow-same-origin allow-forms allow-popups allow-downloads',
65
70
  );
66
71
 
67
72
  return iframe;
@@ -70,6 +75,7 @@ const createIframe = () => {
70
75
  export class PluginInstance {
71
76
  public iframe: HTMLIFrameElement | null = null;
72
77
  private hotkeysAttached = false;
78
+ private iframeOrigin: string | null = null;
73
79
  constructor(public config: PluginConfig) {}
74
80
 
75
81
  private captureHotkeysEnabled() {
@@ -112,35 +118,69 @@ export class PluginInstance {
112
118
  });
113
119
  };
114
120
 
121
+ private static HEARTBEAT_TIMEOUT = 4000;
122
+
115
123
  private promisedIframeMethod<T>(eventName: string) {
116
124
  let timer: ReturnType<typeof setTimeout> | null = null;
125
+ let listener: ((e: MessageEvent<MessageData>) => void) | null = null;
126
+
127
+ const cleanup = () => {
128
+ if (timer) {
129
+ clearTimeout(timer);
130
+ timer = null;
131
+ }
132
+
133
+ if (listener) {
134
+ window.removeEventListener('message', listener, true);
135
+ listener = null;
136
+ }
137
+ };
117
138
 
118
139
  const res = new Promise<T>((resolve, reject) => {
119
- const onEvent = (
120
- e: MessageEvent<{ source: string; event: keyof PluginConfig['on'] }>,
121
- ) => {
122
- const {
123
- data: { source, event, ...data },
124
- } = e;
125
- if (source === 'DraftPlugin' && event === eventName) {
140
+ const resetTimer = () => {
141
+ if (timer) clearTimeout(timer);
142
+ timer = setTimeout(() => {
143
+ cleanup();
144
+ reject(
145
+ new DraftError('timeout_error', `Action "${eventName}" timed out`),
146
+ );
147
+ }, PluginInstance.HEARTBEAT_TIMEOUT);
148
+ };
149
+
150
+ listener = (e: MessageEvent<MessageData>) => {
151
+ if (e.source !== this.iframe?.contentWindow) return;
152
+
153
+ const { data } = e;
154
+ if (data.source !== 'DraftPlugin') return;
155
+
156
+ if (data.event === 'actionPing' && data.action === eventName) {
126
157
  e.stopPropagation();
158
+ resetTimer();
127
159
 
128
- if (timer) {
129
- clearTimeout(timer);
130
- timer = null;
160
+ return;
161
+ }
162
+
163
+ if (data.event === eventName) {
164
+ e.stopPropagation();
165
+ cleanup();
166
+
167
+ const { source: _1, event: _2, ok, code, message, ...rest } = data;
168
+
169
+ if (ok === false) {
170
+ reject(
171
+ new DraftError(
172
+ code || 'unknown_error',
173
+ message || 'Unknown error',
174
+ ),
175
+ );
176
+ } else {
177
+ resolve(rest as T);
131
178
  }
132
- resolve(data as T);
133
- window.removeEventListener('message', onEvent, true);
134
179
  }
135
180
  };
136
181
 
137
- window.addEventListener('message', onEvent, true);
138
-
139
- timer = setTimeout(() => {
140
- window.removeEventListener('message', onEvent, true);
141
- reject('Request timed out');
142
- timer = null;
143
- }, 2000);
182
+ window.addEventListener('message', listener, true);
183
+ resetTimer();
144
184
  });
145
185
 
146
186
  this.postEvent(eventName);
@@ -149,15 +189,17 @@ export class PluginInstance {
149
189
  }
150
190
 
151
191
  private postEvent(event: string, data: object = {}) {
152
- if (this.iframe && this.iframe.contentWindow) {
192
+ if (this.iframe && this.iframe.contentWindow && this.iframeOrigin) {
153
193
  this.iframe.contentWindow.postMessage(
154
194
  {
155
195
  ...data,
156
196
  event,
157
197
  source: 'DraftPlugin',
158
198
  },
159
- '*',
199
+ this.iframeOrigin,
160
200
  );
201
+ } else if (!this.iframeOrigin) {
202
+ throw new Error('Iframe origin is not initialized');
161
203
  }
162
204
  }
163
205
 
@@ -228,6 +270,10 @@ export class PluginInstance {
228
270
  private onMessage = (
229
271
  ev: MessageEvent<{ source: string; event: keyof Handlers }>,
230
272
  ) => {
273
+ if (ev.source !== this.iframe?.contentWindow) {
274
+ return;
275
+ }
276
+
231
277
  const {
232
278
  data: { source, event, ...data },
233
279
  } = ev;
@@ -254,7 +300,7 @@ export class PluginInstance {
254
300
  uid,
255
301
  }: {
256
302
  template: string | TemplateJSON;
257
- uid: string;
303
+ uid: string | number;
258
304
  templateName?: string;
259
305
  }) {
260
306
  const containerEl = document.querySelector(this.config.container);
@@ -262,8 +308,15 @@ export class PluginInstance {
262
308
  if (!containerEl) {
263
309
  throw new Error('Specified container not found');
264
310
  } else {
265
- const onInit = ({ data: { source, event } }: OnInitParams) => {
311
+ const onInit = (msg: OnInitParams) => {
312
+ const {
313
+ data: { source, event },
314
+ } = msg;
266
315
  if (source === 'DraftPlugin' && event === 'loaded') {
316
+ if (msg.source !== this.iframe?.contentWindow) return;
317
+
318
+ this.iframeOrigin = msg.origin;
319
+
267
320
  const {
268
321
  on,
269
322
  container,
@@ -272,6 +325,7 @@ export class PluginInstance {
272
325
  token,
273
326
  apiUrl,
274
327
  pluginId,
328
+ authData,
275
329
  __config,
276
330
  } = this.config;
277
331
 
@@ -285,6 +339,7 @@ export class PluginInstance {
285
339
  autosave,
286
340
  token,
287
341
  pluginId,
342
+ authData,
288
343
  apiUrl,
289
344
  __config,
290
345
  enabledListeners: Object.keys(on),
@@ -298,7 +353,7 @@ export class PluginInstance {
298
353
  }
299
354
  };
300
355
 
301
- this.iframe = createIframe();
356
+ this.iframe = createIframe(window.location.origin);
302
357
  window.addEventListener('message', onInit);
303
358
  containerEl.appendChild(this.iframe);
304
359
 
@@ -365,4 +420,8 @@ export class PluginInstance {
365
420
  exportContent() {
366
421
  return this.promisedIframeMethod<SaveParams>('exportContent');
367
422
  }
423
+
424
+ exportAsFile() {
425
+ return this.promisedIframeMethod<ExportAsFileParams>('exportAsFile');
426
+ }
368
427
  }