@getdraft/plugin 1.13.0-beta.0 → 1.14.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.
- package/README.md +30 -39
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +101 -127
- package/dist/index.es.js.map +1 -1
- package/dist/src/plugin.d.ts.map +1 -1
- package/dist/src/utils.d.ts +2 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/package.json +15 -15
- package/src/plugin.ts +7 -68
- package/src/utils.ts +61 -0
package/README.md
CHANGED
|
@@ -11,18 +11,20 @@
|
|
|
11
11
|
#### npm
|
|
12
12
|
|
|
13
13
|
```
|
|
14
|
-
npm i @
|
|
14
|
+
npm i @draft-email/plugin -E
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
#### yarn
|
|
18
18
|
|
|
19
19
|
```
|
|
20
|
-
yarn add @
|
|
20
|
+
yarn add @draft-email/plugin --exact
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### HTML-script
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
```
|
|
26
|
+
<script src="https://eimage.sendsay.ru/app/se/draft-plugin-v1.12.1.js"></script>
|
|
27
|
+
```
|
|
26
28
|
|
|
27
29
|
## Инициализация
|
|
28
30
|
|
|
@@ -31,7 +33,7 @@ _**Coming soon**_
|
|
|
31
33
|
Если используете npm-пакет
|
|
32
34
|
|
|
33
35
|
```javascript
|
|
34
|
-
import DraftPlugin from '@
|
|
36
|
+
import DraftPlugin from '@draft-email/plugin';
|
|
35
37
|
```
|
|
36
38
|
|
|
37
39
|
в случае встраивания плагина напрямую в html используйте объект `window`
|
|
@@ -42,21 +44,21 @@ const DraftPlugin = window.DraftPlugin;
|
|
|
42
44
|
|
|
43
45
|
### **Шаг 2. Создание контейнера**
|
|
44
46
|
|
|
45
|
-
Чтобы редактор отобразился на вашей странице необходимо создать div-элемент с id `
|
|
47
|
+
Чтобы редактор отобразился на вашей странице необходимо создать div-элемент с id `draft-plugin-container`
|
|
46
48
|
|
|
47
49
|
```html
|
|
48
|
-
<div id="
|
|
50
|
+
<div id="draft-plugin-container"></div>
|
|
49
51
|
```
|
|
50
52
|
|
|
51
53
|
### **Шаг 3. Аутентификация**
|
|
52
54
|
|
|
53
|
-
Endpoint URL:
|
|
55
|
+
Endpoint URL: Ваш endpoint из ЛК
|
|
54
56
|
|
|
55
57
|
- **Основной пользователь**
|
|
56
58
|
|
|
57
59
|
- **Первый вход**
|
|
58
60
|
|
|
59
|
-
1.
|
|
61
|
+
1. Авторизуйтесь через `POST` `v1/login` используя админ-логин и пароль
|
|
60
62
|
|
|
61
63
|
```JSON
|
|
62
64
|
{
|
|
@@ -65,7 +67,11 @@ Endpoint URL: `https://api.kvilla.ru`
|
|
|
65
67
|
}
|
|
66
68
|
```
|
|
67
69
|
|
|
68
|
-
|
|
70
|
+
и получите сессионный токен.
|
|
71
|
+
|
|
72
|
+
Для последующих запросов в Headers нужно выставить Authorization = полученный токен в этом шаге.
|
|
73
|
+
|
|
74
|
+
2. Зарегистрируйте пользователя через `POST` `v1/users`
|
|
69
75
|
|
|
70
76
|
```JSON
|
|
71
77
|
{
|
|
@@ -74,8 +80,6 @@ Endpoint URL: `https://api.kvilla.ru`
|
|
|
74
80
|
}
|
|
75
81
|
```
|
|
76
82
|
|
|
77
|
-
и получите сессионную куку.
|
|
78
|
-
|
|
79
83
|
3. Создайте организацию через `POST` `v1/organizations` с параметрами:
|
|
80
84
|
|
|
81
85
|
```JSON
|
|
@@ -86,40 +90,26 @@ Endpoint URL: `https://api.kvilla.ru`
|
|
|
86
90
|
}
|
|
87
91
|
```
|
|
88
92
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
4. Создайте постоянный токен (API key) для организации: `POST` `/v1/organizations/{organizationID}/tokens`.
|
|
93
|
+
4. Добавьте в эту организацию пользователя `POST` `/v1/organizations/{organizationID}/users`:
|
|
92
94
|
|
|
93
95
|
```JSON
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
{
|
|
97
|
+
"user_id": "ID созданного юзера",
|
|
98
|
+
"role_id": 1,
|
|
99
|
+
}
|
|
98
100
|
```
|
|
99
101
|
|
|
100
|
-
5.
|
|
101
|
-
6. Передайте ключ в редактор.
|
|
102
|
-
|
|
103
|
-
- **Саблогин**
|
|
102
|
+
5. Создайте постоянный токен (API key) для организации: `POST` `/v1/organizations/{organizationID}/users/{userID}/tokens`.
|
|
104
103
|
|
|
105
|
-
- **Первый вход**
|
|
106
|
-
1. Если основной логин ещё не создан или не заходил — выполните шаги 1–5 для основного пользователя.
|
|
107
|
-
2. Зарегистрируйте саблогин проделав шаги 1-2 для саблогина.
|
|
108
|
-
3. Под авторизацией основного пользователя добавьте саблогин в организацию основного пользователя аккаунта: `POST` `/v1/organizations/{organizationID}/users`.
|
|
109
|
-
```JSON
|
|
110
|
-
{
|
|
111
|
-
"user_id": "ID саблогина",
|
|
112
|
-
"role_id": 1
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
4. Создайте токен для пользователя: `POST` `/v1/organizations/{organizationID}/users/{userID}/tokens`.
|
|
116
104
|
```JSON
|
|
117
105
|
{
|
|
118
106
|
"name": "string",
|
|
119
107
|
"expires_at": "2025-08-26T00:16:54.409Z"
|
|
120
108
|
}
|
|
121
109
|
```
|
|
122
|
-
|
|
110
|
+
|
|
111
|
+
6. Сохраните API key у себя на бэкенде.
|
|
112
|
+
7. Передайте ключ в редактор.
|
|
123
113
|
|
|
124
114
|
- **Повторный вход**
|
|
125
115
|
|
|
@@ -131,22 +121,23 @@ Endpoint URL: `https://api.kvilla.ru`
|
|
|
131
121
|
Инициализируйте редактор в JavaScript-коде:
|
|
132
122
|
|
|
133
123
|
```javascript
|
|
134
|
-
import DraftPlugin from '@
|
|
124
|
+
import DraftPlugin from '@draft-email/plugin'
|
|
135
125
|
|
|
136
|
-
const
|
|
126
|
+
const draft = DraftPlugin.create({
|
|
137
127
|
token: "полученный токен авторизации",
|
|
138
128
|
pluginId: "ID созданного плагина из ЛК",
|
|
139
129
|
locale: "en" либо "ru",
|
|
130
|
+
apiUrl: 'https://api.kvilla.ru',
|
|
131
|
+
on: {} // Обработчики событий от редактора
|
|
140
132
|
});
|
|
141
133
|
```
|
|
142
134
|
|
|
143
135
|
### **Шаг 5. Запуск редактора**
|
|
144
136
|
|
|
145
137
|
```javascript
|
|
146
|
-
|
|
138
|
+
draft.start({
|
|
147
139
|
template: {}, // JSON-письма
|
|
148
140
|
uid: 'Уникальный ID письма в вашей системе',
|
|
149
|
-
templateName?: 'Название письма(если используете встроенную шапку редактора)'
|
|
150
141
|
});
|
|
151
142
|
```
|
|
152
143
|
|
|
@@ -182,7 +173,7 @@ letty.start({
|
|
|
182
173
|
### **container - опциональный**
|
|
183
174
|
|
|
184
175
|
Id элемента в котором будет развернут iframe с редактором
|
|
185
|
-
По умолчанию `
|
|
176
|
+
По умолчанию `draft-plugin-container`
|
|
186
177
|
|
|
187
178
|
### **locale - опциональный**
|
|
188
179
|
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var P=Object.defineProperty;var L=(
|
|
1
|
+
"use strict";var P=Object.defineProperty;var L=(t,e,o)=>e in t?P(t,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[e]=o;var a=(t,e,o)=>L(t,typeof e!="symbol"?e+"":e,o);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const b="http://localhost:5174",I="https://seplugin.sendsay.ru",A=async t=>{try{const e=await fetch(t,{method:"HEAD"});if(!e.ok)return null;const o=e.headers.get("Content-Length");return o?parseInt(o,10):null}catch{return null}},g=t=>new Promise((e,o)=>{const n=new Image;n.onload=async()=>{const i=await A(t)??0;e({originalWidth:n.width,originalHeight:n.height,ratio:n.width/n.height,fileSize:i})},n.onerror=i=>{o(i)},n.src=t}),u=(t,e)=>{if(t.length!==1)return t;if(t.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 t},C=t=>{let e=`${u(t.key,t.code)}`.toLowerCase()||t.key;const o=navigator.userAgent.includes("Mac OS");e==="backspace"&&o&&(e="delete");const n=[];return(o&&t.metaKey||!o&&t.ctrlKey)&&n.push("mod"),t.shiftKey&&n.push("shift"),n.length>0&&(e=`${n.join("-")}-${u(e,t.code)}`),e},H=new Set(["escape","mod-c","mod-d","mod-z","mod-y","mod-shift-z","mod-v","delete","mod-g","mod-p","mod-s"]),D="1.14.0",O={version:D},M=()=>{var s,r;const t=new RegExp("(^| )seplugin-dev=([^;]+)"),e=document.cookie.match(t),o=(r=e==null?void 0:(s=e[2]).toLowerCase)==null?void 0:r.call(s);if(o==="true")return b;if(o!=null&&o.startsWith("https://"))return o;const[n,i]=O.version.split(".");return`${I}/v${n}.${i}`},z=({token:t,pluginId:e,apiUrl:o})=>{if(!t)throw new Error("No [token] was provided");if(!e)throw new Error("No [pluginId] was provided");if(!o)throw new Error("No [apiUrl] was provided")},T=()=>{const t=document.createElement("iframe");return t.src=M(),t.setAttribute("style","height:100%;width:100%;min-width:960px;border:0px"),t.setAttribute("allow","clipboard-read; clipboard-write"),t.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups"),t};class x{constructor(e){a(this,"iframe",null);a(this,"hotkeysAttached",!1);a(this,"onHostHotkey",e=>{var d;if(!this.captureHotkeysEnabled()||!((d=this.iframe)!=null&&d.contentWindow))return;const o=C(e);if(!H.has(o))return;const n=e.target;if(n&&(n.isContentEditable||["INPUT","TEXTAREA","SELECT"].includes(n.tagName)))return;e.preventDefault();const{key:i,ctrlKey:s,metaKey:r,shiftKey:l,altKey:c}=e;this.postEvent("hostHotkey",{key:i,code:e.code,metaKey:r,ctrlKey:s,shiftKey:l,altKey:c,keyCode:o})});a(this,"onImageUpload",async({id:e,...o})=>{var n,i;try{const s=await((i=(n=this.config.on).uploadImage)==null?void 0:i.call(n,o));let r={};s&&(r=await g(s)),this.postEvent("imageUploaded",{id:e,img:{...r,url:s}})}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 n,i;const o=async s=>{const r={url:s};if(s){const l=await g(s);Object.assign(r,l)}this.postEvent("imageUploaded",{id:e,img:r})};(i=(n=this.config.on).openGallery)==null||i.call(n,o)});a(this,"onMessage",e=>{const{data:{source:o,event:n,...i}}=e;o==="DraftPlugin"&&(n==="openGallery"?this.onGalleryOpen(i):n==="uploadImage"?this.onImageUpload(i):n==="loadPersonalization"?this.onLoadPersonalization():this.triggerEvent(this.config.on[n],i))});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 o=null;const n=new Promise((i,s)=>{const r=l=>{const{data:{source:c,event:d,...h}}=l;c==="DraftPlugin"&&d===e&&(l.stopPropagation(),o&&(clearTimeout(o),o=null),i(h),window.removeEventListener("message",r,!0))};window.addEventListener("message",r,!0),o=setTimeout(()=>{window.removeEventListener("message",r,!0),s("Request timed out"),o=null},2e3)});return this.postEvent(e),n}postEvent(e,o={}){this.iframe&&this.iframe.contentWindow&&this.iframe.contentWindow.postMessage({...o,event:e,source:"DraftPlugin"},"*")}triggerEvent(e,o){if(e)return e(o)}start({template:e,templateName:o,uid:n}){const i=document.querySelector(this.config.container);if(i){const s=({data:{source:r,event:l}})=>{if(r==="DraftPlugin"&&l==="loaded"){const{on:c,container:d,locale:h,autosave:w,token:y,apiUrl:E,pluginId:v,__config:k}=this.config;z(this.config),this.iframe&&this.iframe.contentWindow&&this.postEvent("init",{container:d,locale:h,uid:n,autosave:w,token:y,pluginId:v,apiUrl:E,__config:k,enabledListeners:Object.keys(c),template:e,templateName:o}),window.addEventListener("message",this.onMessage),window.removeEventListener("message",s)}};this.iframe=T(),window.addEventListener("message",s),i.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,o={}){this.postEvent("changeTemplate",{...o,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")}}var p=(t=>(t.Audit="audit",t.Guide="guide",t.Style="style",t.Blocks="blocks",t))(p||{}),f=(t=>(t.Desktop="desktop",t.Mobile="mobile",t))(f||{});const N={container:"#draft-plugin-container",disableHotkeysPassing:!1,locale:"ru",on:{}};class K{create(e){return new x({...N,...e})}}const m=new K;window.DraftPlugin=m;exports.EditorMenu=p;exports.ViewMode=f;exports.default=m;
|
|
2
2
|
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.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","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 { getImageParamsFromFileUrl } from './utils';\nimport pkg from '../package.json';\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\nconst 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\nconst 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\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 (\n value === 'stage' ||\n value?.includes('https://') ||\n window.location.pathname.includes('netlify')\n ) {\n return value?.includes('https://') ? value : `${PROD_ENDPOINT}/stage`;\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","regex","match","value","_b","_a","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":"gRAAO,MAAMA,EAAiB,wBACjBC,EAAgB,8BCCvBC,EAAmB,MAAOC,GAAqB,CAC/C,GAAA,CACF,MAAMC,EAAW,MAAM,MAAMD,EAAU,CAAE,OAAQ,OAAQ,EAErD,GAAA,CAACC,EAAS,GACL,OAAA,KAGT,MAAMC,EAAgBD,EAAS,QAAQ,IAAI,gBAAgB,EAE3D,OAAIC,EACK,SAASA,EAAe,EAAE,EAE1B,UAEK,CACP,OAAA,IACT,CACF,EAEaC,EAA6BC,GACxC,IAAI,QAAkC,CAACC,EAASC,IAAW,CACnD,MAAAC,EAAM,IAAI,MAEhBA,EAAI,OAAS,SAAY,CACvB,MAAMC,EAAY,MAAMT,EAAiBK,CAAM,GAAM,EAE7CC,EAAA,CACN,cAAeE,EAAI,MACnB,eAAgBA,EAAI,OACpB,MAAOA,EAAI,MAAQA,EAAI,OACvB,SAAAC,CAAA,CACD,CAAA,EAGCD,EAAA,QAAWE,GAAU,CACvBH,EAAOG,CAAK,CAAA,EAGdF,EAAI,IAAMH,CACZ,CAAC,gqBCzBGM,EAAc,CAACC,EAAaC,IAAiB,CAC7C,GAAAD,EAAI,SAAW,EACV,OAAAA,EAMT,GAFmBA,EAAI,WAAW,CAAC,GADX,IAGR,CACd,GAAIC,EAAK,QAAQ,KAAK,IAAM,GAAKA,EAAK,SAAW,EACxC,OAAAA,EAAK,OAAO,CAAC,EAGtB,GAAIA,EAAK,QAAQ,OAAO,IAAM,GAAKA,EAAK,SAAW,EAC1C,OAAAA,EAAK,OAAO,CAAC,CAExB,CAEO,OAAAD,CACT,EAEME,EAAoBC,GAAyB,CAC7C,IAAAC,EACF,GAAGL,EAAYI,EAAM,IAAKA,EAAM,IAAI,CAAC,GAAG,eAAiBA,EAAM,IACjE,MAAME,EAAQ,UAAU,UAAU,SAAS,QAAQ,EAE/CD,IAAY,aAAeC,IACnBD,EAAA,UAGZ,MAAME,EAAS,CAAA,EAEf,OAAKD,GAASF,EAAM,SAAa,CAACE,GAASF,EAAM,UAC/CG,EAAO,KAAK,KAAK,EAGfH,EAAM,UACRG,EAAO,KAAK,OAAO,EAGjBA,EAAO,OAAS,IACRF,EAAA,GAAGE,EAAO,KAAK,GAAG,CAAC,IAAIP,EAAYK,EAASD,EAAM,IAAI,CAAC,IAG5DC,CACT,EAEMG,MAAmB,IAAI,CAC3B,SACA,QACA,QACA,QACA,QACA,cACA,QACA,SACA,QACA,QACA,OACF,CAAC,EAEKC,EAAgB,IAAM,SACpB,MAAAC,EAAQ,IAAI,OAAO,2BAA2B,EAC9CC,EAAQ,SAAS,OAAO,MAAMD,CAAK,EACnCE,GAAQC,EAAAF,GAAA,aAAAG,EAAAH,EAAQ,IAAG,cAAX,YAAAE,EAAA,KAAAC,GAEd,GAAIF,IAAU,OACL,OAAAzB,EAIP,GAAAyB,IAAU,SACVA,GAAA,MAAAA,EAAO,SAAS,aAChB,OAAO,SAAS,SAAS,SAAS,SAAS,EAE3C,OAAOA,GAAA,MAAAA,EAAO,SAAS,YAAcA,EAAQ,GAAGxB,CAAa,SAG/D,KAAM,CAAC2B,EAAOC,CAAG,EAAIC,EAAI,QAAQ,MAAM,GAAG,EAE1C,MAAO,GAAG7B,CAAa,KAAK2B,CAAK,IAAIC,CAAG,EAC1C,EAEME,EAAe,CAAC,CAAE,MAAAC,EAAO,SAAAC,EAAU,OAAAC,KAA2B,CAClE,GAAI,CAACF,EACG,MAAA,IAAI,MAAM,yBAAyB,EAG3C,GAAI,CAACC,EACG,MAAA,IAAI,MAAM,4BAA4B,EAG9C,GAAI,CAACC,EACG,MAAA,IAAI,MAAM,0BAA0B,CAE9C,EAEMC,EAAe,IAAM,CACnB,MAAAC,EAAS,SAAS,cAAc,QAAQ,EAC9C,OAAAA,EAAO,IAAMd,IACNc,EAAA,aACL,QACA,mDAAA,EAEKA,EAAA,aAAa,QAAS,iCAAiC,EACvDA,EAAA,aACL,UACA,0DAAA,EAGKA,CACT,EAEO,MAAMC,CAAe,CAG1B,YAAmBC,EAAsB,CAFlCC,EAAA,cAAmC,MAClCA,EAAA,uBAAkB,IAOlBA,EAAA,oBAAgBtB,GAAyB,OAC/C,GAAI,CAAC,KAAK,sBAAA,GAA2B,GAACU,EAAA,KAAK,SAAL,MAAAA,EAAa,eACjD,OAGI,MAAAT,EAAUF,EAAiBC,CAAK,EAEtC,GAAI,CAACI,EAAa,IAAIH,CAAO,EAC3B,OAGF,MAAMsB,EAASvB,EAAM,OAGnB,GAAAuB,IACCA,EAAO,mBACN,CAAC,QAAS,WAAY,QAAQ,EAAE,SAASA,EAAO,OAAO,GAEzD,OAGFvB,EAAM,eAAe,EAErB,KAAM,CAAE,IAAAH,EAAK,QAAA2B,EAAS,QAAAC,EAAS,SAAAC,EAAU,OAAAC,CAAW,EAAA3B,EAEpD,KAAK,UAAU,aAAc,CAC3B,IAAAH,EACA,KAAMG,EAAM,KACZ,QAAAyB,EACA,QAAAD,EACA,SAAAE,EACA,OAAAC,EACA,QAAA1B,CAAA,CACD,CAAA,GAoDKqB,EAAA,qBAAgB,MAAO,CAC7B,GAAAM,EACA,GAAGC,CAAA,IACqC,SACpC,GAAA,CACF,MAAMC,EAAM,OAAMrB,GAAAC,EAAA,KAAK,OAAO,IAAG,cAAf,YAAAD,EAAA,KAAAC,EAA6BmB,IAC/C,IAAIE,EAAS,CAAA,EAETD,IACOC,EAAA,MAAM1C,EAA0ByC,CAAG,GAGzC,KAAA,UAAU,gBAAiB,CAAE,GAAAF,EAAI,IAAK,CAAE,GAAGG,EAAQ,IAAAD,CAAI,CAAA,CAAG,OACrD,CACV,KAAK,UAAU,gBAAiB,CAAE,GAAAF,CAAI,CAAA,CACxC,CAAA,GAGMN,EAAA,6BAAwB,SAAY,CACtC,GAAA,CACF,GAAI,CAAC,KAAK,OAAO,GAAG,oBACZ,MAAA,IAAI,MAAM,oCAAoC,EAGtD,MAAMU,EACJ,MAAM,KAAK,OAAO,GAAG,oBAAoB,EAE3C,KAAK,UAAU,sBAAuB,CACpC,MAAOA,CAAA,CACR,OACS,CACL,KAAA,UAAU,sBAAuB,CAAA,CAAE,CAC1C,CAAA,GAGMV,EAAA,qBAAgB,MAAO,CAAE,GAAAM,KAAyB,SAClD,MAAAK,EAAa,MAAOH,GAAiB,CACnC,MAAAI,EAAY,CAAE,IAAAJ,GAEpB,GAAIA,EAAK,CACD,MAAAC,EAAS,MAAM1C,EAA0ByC,CAAG,EAC3C,OAAA,OAAOI,EAAWH,CAAM,CACjC,CAEA,KAAK,UAAU,gBAAiB,CAC9B,GAAAH,EACA,IAAKM,CAAA,CACN,CAAA,GAGEzB,GAAAC,EAAA,KAAA,OAAO,IAAG,cAAV,MAAAD,EAAA,KAAAC,EAAwBuB,EAAU,GAcjCX,EAAA,iBACNa,GACG,CACG,KAAA,CACJ,KAAM,CAAE,OAAAC,EAAQ,MAAApC,EAAO,GAAG6B,CAAK,CAC7B,EAAAM,EAEAC,IAAW,gBACTpC,IAAU,cACZ,KAAK,cAAc6B,CAAyB,EACnC7B,IAAU,cACnB,KAAK,cAAc6B,CAA0C,EACpD7B,IAAU,sBACnB,KAAK,sBAAsB,EAEtB,KAAA,aACH,KAAK,OAAO,GAAGA,CAAK,EACpB6B,CAAA,EAGN,GAgEFP,EAAA,eAAU,IAAM,QACdZ,EAAA,KAAK,SAAL,MAAAA,EAAa,SACb,KAAK,OAAS,KACP,OAAA,oBAAoB,UAAW,KAAK,SAAS,EAEhD,KAAK,kBACA,OAAA,oBAAoB,UAAW,KAAK,YAAY,EACvD,KAAK,gBAAkB,GACzB,GAvPiB,KAAA,OAAAW,CAAuB,CAElC,uBAAwB,CACvB,OAAA,KAAK,OAAO,wBAA0B,EAC/C,CAsCQ,qBAAwBgB,EAAmB,CACjD,IAAIC,EAA8C,KAElD,MAAMC,EAAM,IAAI,QAAW,CAAChD,EAASC,IAAW,CACxC,MAAAgD,EACJC,GACG,CACG,KAAA,CACJ,KAAM,CAAE,OAAAL,EAAQ,MAAApC,EAAO,GAAG6B,CAAK,CAC7B,EAAAY,EACAL,IAAW,eAAiBpC,IAAUqC,IACxCI,EAAE,gBAAgB,EAEdH,IACF,aAAaA,CAAK,EACVA,EAAA,MAEV/C,EAAQsC,CAAS,EACV,OAAA,oBAAoB,UAAWW,EAAS,EAAI,EACrD,EAGK,OAAA,iBAAiB,UAAWA,EAAS,EAAI,EAEhDF,EAAQ,WAAW,IAAM,CAChB,OAAA,oBAAoB,UAAWE,EAAS,EAAI,EACnDhD,EAAO,mBAAmB,EAClB8C,EAAA,MACP,GAAI,CAAA,CACR,EAED,YAAK,UAAUD,CAAS,EAEjBE,CACT,CAEQ,UAAUvC,EAAe6B,EAAe,GAAI,CAC9C,KAAK,QAAU,KAAK,OAAO,eAC7B,KAAK,OAAO,cAAc,YACxB,CACE,GAAGA,EACH,MAAA7B,EACA,OAAQ,aACV,EACA,GAAA,CAGN,CAuDQ,aACN0C,EACAX,EACA,CACA,GAAKW,EAIL,OAAOA,EAAQX,CAAM,CACvB,CAyBA,MAAM,CACJ,SAAAY,EACA,aAAAC,EACA,IAAAC,CAAA,EAKC,CACD,MAAMC,EAAc,SAAS,cAAc,KAAK,OAAO,SAAS,EAEhE,GAAKA,EAEE,CACC,MAAAC,EAAS,CAAC,CAAE,KAAM,CAAE,OAAAX,EAAQ,MAAApC,CAAA,KAA4B,CACxD,GAAAoC,IAAW,eAAiBpC,IAAU,SAAU,CAC5C,KAAA,CACJ,GAAAgD,EACA,UAAAC,EACA,OAAAC,EACA,SAAAC,EACA,MAAApC,EACA,OAAAE,EACA,SAAAD,EACA,SAAAoC,CAAA,EACE,KAAK,OAETtC,EAAa,KAAK,MAAM,EAEpB,KAAK,QAAU,KAAK,OAAO,eAC7B,KAAK,UAAU,OAAQ,CACrB,UAAAmC,EACA,OAAAC,EACA,IAAAL,EACA,SAAAM,EACA,MAAApC,EACA,SAAAC,EACA,OAAAC,EACA,SAAAmC,EACA,iBAAkB,OAAO,KAAKJ,CAAE,EAChC,SAAAL,EACA,aAAAC,CAAA,CACD,EAGI,OAAA,iBAAiB,UAAW,KAAK,SAAS,EAC1C,OAAA,oBAAoB,UAAWG,CAAM,CAC9C,CAAA,EAGF,KAAK,OAAS7B,IACP,OAAA,iBAAiB,UAAW6B,CAAM,EAC7BD,EAAA,YAAY,KAAK,MAAM,EAE/B,KAAK,sBAAA,GAA2B,CAAC,KAAK,kBACjC,OAAA,iBAAiB,UAAW,KAAK,YAAY,EACpD,KAAK,gBAAkB,GAE3B,KA9CQ,OAAA,IAAI,MAAM,+BAA+B,CA+CnD,CAaA,eACEH,EACAU,EAGI,GACJ,CACA,KAAK,UAAU,iBAAkB,CAAE,GAAGA,EAAS,SAAAV,EAAU,CAC3D,CAEA,WAAWW,EAAiB,CAC1B,KAAK,UAAU,aAAc,CAAE,MAAAA,CAAO,CAAA,CACxC,CAEA,cAAcA,EAAiB,CAC7B,KAAK,UAAU,gBAAiB,CAAE,MAAAA,CAAO,CAAA,CAC3C,CAEA,WAAWC,EAA0B,KAAM,CACzC,KAAK,UAAU,aAAc,CAAE,KAAAA,CAAM,CAAA,CACvC,CAEA,eAAeC,EAAoB,CACjC,KAAK,UAAU,iBAAkB,CAAE,SAAAA,CAAU,CAAA,CAC/C,CAEA,MAAO,CACL,KAAK,UAAU,MAAM,CACvB,CAEA,MAAO,CACL,KAAK,UAAU,MAAM,CACvB,CAEA,MAAO,CACE,OAAA,KAAK,qBAAiC,YAAY,CAC3D,CAEA,MAAO,CACE,OAAA,KAAK,qBAAiC,YAAY,CAC3D,CAEA,eAAgB,CACP,OAAA,KAAK,qBAAiC,eAAe,CAC9D,CACF,CC9ZY,IAAAC,GAAAA,IACVA,EAAA,MAAQ,QACRA,EAAA,MAAQ,QACRA,EAAA,MAAQ,QACRA,EAAA,OAAS,SAJCA,IAAAA,GAAA,CAAA,CAAA,EAOAC,GAAAA,IACVA,EAAA,QAAU,UACVA,EAAA,OAAS,SAFCA,IAAAA,GAAA,CAAA,CAAA,EClBZ,MAAMC,EAAwC,CAC5C,UAAW,0BACX,sBAAuB,GACvB,OAAQ,KACR,GAAI,CAAC,CACP,EAEA,MAAMC,CAAc,CAClB,OAAOvC,EAAsB,CAC3B,OAAO,IAAID,EAAe,CACxB,GAAGuC,EACH,GAAGtC,CAAA,CACJ,CACH,CACF,CAEM,MAAAwC,EAAc,IAAID,EAQxB,OAAO,YAAcC"}
|
|
1
|
+
{"version":3,"file":"index.cjs.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","regex","match","value","_b","_a","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":"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"}
|
package/dist/index.es.js
CHANGED
|
@@ -1,74 +1,46 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var a = (
|
|
4
|
-
const
|
|
1
|
+
var E = Object.defineProperty;
|
|
2
|
+
var v = (t, e, o) => e in t ? E(t, e, { enumerable: !0, configurable: !0, writable: !0, value: o }) : t[e] = o;
|
|
3
|
+
var a = (t, e, o) => v(t, typeof e != "symbol" ? e + "" : e, o);
|
|
4
|
+
const k = "http://localhost:5174", P = "https://seplugin.sendsay.ru", L = async (t) => {
|
|
5
5
|
try {
|
|
6
|
-
const e = await fetch(
|
|
6
|
+
const e = await fetch(t, { method: "HEAD" });
|
|
7
7
|
if (!e.ok)
|
|
8
8
|
return null;
|
|
9
|
-
const
|
|
10
|
-
return
|
|
9
|
+
const o = e.headers.get("Content-Length");
|
|
10
|
+
return o ? parseInt(o, 10) : null;
|
|
11
11
|
} catch {
|
|
12
12
|
return null;
|
|
13
13
|
}
|
|
14
|
-
}, g = (
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
const i = await
|
|
14
|
+
}, g = (t) => new Promise((e, o) => {
|
|
15
|
+
const n = new Image();
|
|
16
|
+
n.onload = async () => {
|
|
17
|
+
const i = await L(t) ?? 0;
|
|
18
18
|
e({
|
|
19
|
-
originalWidth:
|
|
20
|
-
originalHeight:
|
|
21
|
-
ratio:
|
|
19
|
+
originalWidth: n.width,
|
|
20
|
+
originalHeight: n.height,
|
|
21
|
+
ratio: n.width / n.height,
|
|
22
22
|
fileSize: i
|
|
23
23
|
});
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
},
|
|
27
|
-
}),
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
eslint: "npx eslint src",
|
|
32
|
-
"eslint:fix": "pnpm eslint --fix",
|
|
33
|
-
prettify: "npx prettier -w ./",
|
|
34
|
-
prepublish: "pnpm build",
|
|
35
|
-
watch: "NODE_ENV=development vite build --watch",
|
|
36
|
-
start: "NODE_ENV=development npx vite"
|
|
37
|
-
}, H = {}, O = {
|
|
38
|
-
"@types/letty": "workspace:^",
|
|
39
|
-
"@vitejs/plugin-legacy": "5.4.1",
|
|
40
|
-
rollup: "4.22.4",
|
|
41
|
-
terser: "5.31.3",
|
|
42
|
-
"rollup-plugin-dts": "6.1.1",
|
|
43
|
-
"@letty/eslint-config-ts": "workspace:^",
|
|
44
|
-
"@letty/prettier": "workspace:^"
|
|
45
|
-
}, N = "MIT", z = {
|
|
46
|
-
name: L,
|
|
47
|
-
version: I,
|
|
48
|
-
main: x,
|
|
49
|
-
module: A,
|
|
50
|
-
types: D,
|
|
51
|
-
scripts: C,
|
|
52
|
-
dependencies: H,
|
|
53
|
-
devDependencies: O,
|
|
54
|
-
license: N
|
|
55
|
-
}, u = (n, e) => {
|
|
56
|
-
if (n.length !== 1)
|
|
57
|
-
return n;
|
|
58
|
-
if (n.charCodeAt(0) >= 880) {
|
|
24
|
+
}, n.onerror = (i) => {
|
|
25
|
+
o(i);
|
|
26
|
+
}, n.src = t;
|
|
27
|
+
}), p = (t, e) => {
|
|
28
|
+
if (t.length !== 1)
|
|
29
|
+
return t;
|
|
30
|
+
if (t.charCodeAt(0) >= 880) {
|
|
59
31
|
if (e.indexOf("Key") === 0 && e.length === 4)
|
|
60
32
|
return e.charAt(3);
|
|
61
33
|
if (e.indexOf("Digit") === 0 && e.length === 6)
|
|
62
34
|
return e.charAt(5);
|
|
63
35
|
}
|
|
64
|
-
return
|
|
65
|
-
},
|
|
66
|
-
let e = `${
|
|
67
|
-
const
|
|
68
|
-
e === "backspace" &&
|
|
69
|
-
const
|
|
70
|
-
return (
|
|
71
|
-
},
|
|
36
|
+
return t;
|
|
37
|
+
}, I = (t) => {
|
|
38
|
+
let e = `${p(t.key, t.code)}`.toLowerCase() || t.key;
|
|
39
|
+
const o = navigator.userAgent.includes("Mac OS");
|
|
40
|
+
e === "backspace" && o && (e = "delete");
|
|
41
|
+
const n = [];
|
|
42
|
+
return (o && t.metaKey || !o && t.ctrlKey) && n.push("mod"), t.shiftKey && n.push("shift"), n.length > 0 && (e = `${n.join("-")}-${p(e, t.code)}`), e;
|
|
43
|
+
}, b = /* @__PURE__ */ new Set([
|
|
72
44
|
"escape",
|
|
73
45
|
"mod-c",
|
|
74
46
|
"mod-d",
|
|
@@ -80,33 +52,35 @@ const P = "http://localhost:5174", h = "https://seplugin.sendsay.ru", b = async
|
|
|
80
52
|
"mod-g",
|
|
81
53
|
"mod-p",
|
|
82
54
|
"mod-s"
|
|
83
|
-
]),
|
|
55
|
+
]), A = "1.14.0", C = {
|
|
56
|
+
version: A
|
|
57
|
+
}, H = () => {
|
|
84
58
|
var s, r;
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
87
|
-
return
|
|
88
|
-
if (
|
|
89
|
-
return
|
|
90
|
-
const [
|
|
91
|
-
return `${
|
|
92
|
-
},
|
|
93
|
-
if (!
|
|
59
|
+
const t = new RegExp("(^| )seplugin-dev=([^;]+)"), e = document.cookie.match(t), o = (r = e == null ? void 0 : (s = e[2]).toLowerCase) == null ? void 0 : r.call(s);
|
|
60
|
+
if (o === "true")
|
|
61
|
+
return k;
|
|
62
|
+
if (o != null && o.startsWith("https://"))
|
|
63
|
+
return o;
|
|
64
|
+
const [n, i] = C.version.split(".");
|
|
65
|
+
return `${P}/v${n}.${i}`;
|
|
66
|
+
}, D = ({ token: t, pluginId: e, apiUrl: o }) => {
|
|
67
|
+
if (!t)
|
|
94
68
|
throw new Error("No [token] was provided");
|
|
95
69
|
if (!e)
|
|
96
70
|
throw new Error("No [pluginId] was provided");
|
|
97
|
-
if (!
|
|
71
|
+
if (!o)
|
|
98
72
|
throw new Error("No [apiUrl] was provided");
|
|
99
|
-
},
|
|
100
|
-
const
|
|
101
|
-
return
|
|
73
|
+
}, O = () => {
|
|
74
|
+
const t = document.createElement("iframe");
|
|
75
|
+
return t.src = H(), t.setAttribute(
|
|
102
76
|
"style",
|
|
103
77
|
"height:100%;width:100%;min-width:960px;border:0px"
|
|
104
|
-
),
|
|
78
|
+
), t.setAttribute("allow", "clipboard-read; clipboard-write"), t.setAttribute(
|
|
105
79
|
"sandbox",
|
|
106
80
|
"allow-scripts allow-same-origin allow-forms allow-popups"
|
|
107
|
-
),
|
|
81
|
+
), t;
|
|
108
82
|
};
|
|
109
|
-
class
|
|
83
|
+
class x {
|
|
110
84
|
constructor(e) {
|
|
111
85
|
a(this, "iframe", null);
|
|
112
86
|
a(this, "hotkeysAttached", !1);
|
|
@@ -114,11 +88,11 @@ class G {
|
|
|
114
88
|
var c;
|
|
115
89
|
if (!this.captureHotkeysEnabled() || !((c = this.iframe) != null && c.contentWindow))
|
|
116
90
|
return;
|
|
117
|
-
const
|
|
118
|
-
if (!
|
|
91
|
+
const o = I(e);
|
|
92
|
+
if (!b.has(o))
|
|
119
93
|
return;
|
|
120
|
-
const
|
|
121
|
-
if (
|
|
94
|
+
const n = e.target;
|
|
95
|
+
if (n && (n.isContentEditable || ["INPUT", "TEXTAREA", "SELECT"].includes(n.tagName)))
|
|
122
96
|
return;
|
|
123
97
|
e.preventDefault();
|
|
124
98
|
const { key: i, ctrlKey: s, metaKey: r, shiftKey: l, altKey: d } = e;
|
|
@@ -129,16 +103,16 @@ class G {
|
|
|
129
103
|
ctrlKey: s,
|
|
130
104
|
shiftKey: l,
|
|
131
105
|
altKey: d,
|
|
132
|
-
keyCode:
|
|
106
|
+
keyCode: o
|
|
133
107
|
});
|
|
134
108
|
});
|
|
135
109
|
a(this, "onImageUpload", async ({
|
|
136
110
|
id: e,
|
|
137
|
-
...
|
|
111
|
+
...o
|
|
138
112
|
}) => {
|
|
139
|
-
var
|
|
113
|
+
var n, i;
|
|
140
114
|
try {
|
|
141
|
-
const s = await ((i = (
|
|
115
|
+
const s = await ((i = (n = this.config.on).uploadImage) == null ? void 0 : i.call(n, o));
|
|
142
116
|
let r = {};
|
|
143
117
|
s && (r = await g(s)), this.postEvent("imageUploaded", { id: e, img: { ...r, url: s } });
|
|
144
118
|
} catch {
|
|
@@ -158,8 +132,8 @@ class G {
|
|
|
158
132
|
}
|
|
159
133
|
});
|
|
160
134
|
a(this, "onGalleryOpen", async ({ id: e }) => {
|
|
161
|
-
var
|
|
162
|
-
const
|
|
135
|
+
var n, i;
|
|
136
|
+
const o = async (s) => {
|
|
163
137
|
const r = { url: s };
|
|
164
138
|
if (s) {
|
|
165
139
|
const l = await g(s);
|
|
@@ -170,14 +144,14 @@ class G {
|
|
|
170
144
|
img: r
|
|
171
145
|
});
|
|
172
146
|
};
|
|
173
|
-
(i = (
|
|
147
|
+
(i = (n = this.config.on).openGallery) == null || i.call(n, o);
|
|
174
148
|
});
|
|
175
149
|
a(this, "onMessage", (e) => {
|
|
176
150
|
const {
|
|
177
|
-
data: { source:
|
|
151
|
+
data: { source: o, event: n, ...i }
|
|
178
152
|
} = e;
|
|
179
|
-
|
|
180
|
-
this.config.on[
|
|
153
|
+
o === "DraftPlugin" && (n === "openGallery" ? this.onGalleryOpen(i) : n === "uploadImage" ? this.onImageUpload(i) : n === "loadPersonalization" ? this.onLoadPersonalization() : this.triggerEvent(
|
|
154
|
+
this.config.on[n],
|
|
181
155
|
i
|
|
182
156
|
));
|
|
183
157
|
});
|
|
@@ -191,38 +165,38 @@ class G {
|
|
|
191
165
|
return this.config.disableHotkeysPassing !== !0;
|
|
192
166
|
}
|
|
193
167
|
promisedIframeMethod(e) {
|
|
194
|
-
let
|
|
195
|
-
const
|
|
168
|
+
let o = null;
|
|
169
|
+
const n = new Promise((i, s) => {
|
|
196
170
|
const r = (l) => {
|
|
197
171
|
const {
|
|
198
|
-
data: { source: d, event: c, ...
|
|
172
|
+
data: { source: d, event: c, ...h }
|
|
199
173
|
} = l;
|
|
200
|
-
d === "DraftPlugin" && c === e && (l.stopPropagation(),
|
|
174
|
+
d === "DraftPlugin" && c === e && (l.stopPropagation(), o && (clearTimeout(o), o = null), i(h), window.removeEventListener("message", r, !0));
|
|
201
175
|
};
|
|
202
|
-
window.addEventListener("message", r, !0),
|
|
203
|
-
window.removeEventListener("message", r, !0), s("Request timed out"),
|
|
176
|
+
window.addEventListener("message", r, !0), o = setTimeout(() => {
|
|
177
|
+
window.removeEventListener("message", r, !0), s("Request timed out"), o = null;
|
|
204
178
|
}, 2e3);
|
|
205
179
|
});
|
|
206
|
-
return this.postEvent(e),
|
|
180
|
+
return this.postEvent(e), n;
|
|
207
181
|
}
|
|
208
|
-
postEvent(e,
|
|
182
|
+
postEvent(e, o = {}) {
|
|
209
183
|
this.iframe && this.iframe.contentWindow && this.iframe.contentWindow.postMessage(
|
|
210
184
|
{
|
|
211
|
-
...
|
|
185
|
+
...o,
|
|
212
186
|
event: e,
|
|
213
187
|
source: "DraftPlugin"
|
|
214
188
|
},
|
|
215
189
|
"*"
|
|
216
190
|
);
|
|
217
191
|
}
|
|
218
|
-
triggerEvent(e,
|
|
192
|
+
triggerEvent(e, o) {
|
|
219
193
|
if (e)
|
|
220
|
-
return e(
|
|
194
|
+
return e(o);
|
|
221
195
|
}
|
|
222
196
|
start({
|
|
223
197
|
template: e,
|
|
224
|
-
templateName:
|
|
225
|
-
uid:
|
|
198
|
+
templateName: o,
|
|
199
|
+
uid: n
|
|
226
200
|
}) {
|
|
227
201
|
const i = document.querySelector(this.config.container);
|
|
228
202
|
if (i) {
|
|
@@ -231,34 +205,34 @@ class G {
|
|
|
231
205
|
const {
|
|
232
206
|
on: d,
|
|
233
207
|
container: c,
|
|
234
|
-
locale:
|
|
235
|
-
autosave:
|
|
208
|
+
locale: h,
|
|
209
|
+
autosave: u,
|
|
236
210
|
token: f,
|
|
237
|
-
apiUrl:
|
|
238
|
-
pluginId:
|
|
239
|
-
__config:
|
|
211
|
+
apiUrl: m,
|
|
212
|
+
pluginId: w,
|
|
213
|
+
__config: y
|
|
240
214
|
} = this.config;
|
|
241
|
-
|
|
215
|
+
D(this.config), this.iframe && this.iframe.contentWindow && this.postEvent("init", {
|
|
242
216
|
container: c,
|
|
243
|
-
locale:
|
|
244
|
-
uid:
|
|
245
|
-
autosave:
|
|
217
|
+
locale: h,
|
|
218
|
+
uid: n,
|
|
219
|
+
autosave: u,
|
|
246
220
|
token: f,
|
|
247
|
-
pluginId:
|
|
248
|
-
apiUrl:
|
|
249
|
-
__config:
|
|
221
|
+
pluginId: w,
|
|
222
|
+
apiUrl: m,
|
|
223
|
+
__config: y,
|
|
250
224
|
enabledListeners: Object.keys(d),
|
|
251
225
|
template: e,
|
|
252
|
-
templateName:
|
|
226
|
+
templateName: o
|
|
253
227
|
}), window.addEventListener("message", this.onMessage), window.removeEventListener("message", s);
|
|
254
228
|
}
|
|
255
229
|
};
|
|
256
|
-
this.iframe =
|
|
230
|
+
this.iframe = O(), window.addEventListener("message", s), i.appendChild(this.iframe), this.captureHotkeysEnabled() && !this.hotkeysAttached && (window.addEventListener("keydown", this.onHostHotkey), this.hotkeysAttached = !0);
|
|
257
231
|
} else
|
|
258
232
|
throw new Error("Specified container not found");
|
|
259
233
|
}
|
|
260
|
-
changeTemplate(e,
|
|
261
|
-
this.postEvent("changeTemplate", { ...
|
|
234
|
+
changeTemplate(e, o = {}) {
|
|
235
|
+
this.postEvent("changeTemplate", { ...o, template: e });
|
|
262
236
|
}
|
|
263
237
|
toggleGrid(e) {
|
|
264
238
|
this.postEvent("toggleGrid", { state: e });
|
|
@@ -288,26 +262,26 @@ class G {
|
|
|
288
262
|
return this.promisedIframeMethod("exportContent");
|
|
289
263
|
}
|
|
290
264
|
}
|
|
291
|
-
var
|
|
292
|
-
const
|
|
265
|
+
var z = /* @__PURE__ */ ((t) => (t.Audit = "audit", t.Guide = "guide", t.Style = "style", t.Blocks = "blocks", t))(z || {}), N = /* @__PURE__ */ ((t) => (t.Desktop = "desktop", t.Mobile = "mobile", t))(N || {});
|
|
266
|
+
const T = {
|
|
293
267
|
container: "#draft-plugin-container",
|
|
294
268
|
disableHotkeysPassing: !1,
|
|
295
269
|
locale: "ru",
|
|
296
270
|
on: {}
|
|
297
271
|
};
|
|
298
|
-
class
|
|
272
|
+
class K {
|
|
299
273
|
create(e) {
|
|
300
|
-
return new
|
|
301
|
-
|
|
274
|
+
return new x({
|
|
275
|
+
...T,
|
|
302
276
|
...e
|
|
303
277
|
});
|
|
304
278
|
}
|
|
305
279
|
}
|
|
306
|
-
const
|
|
307
|
-
window.DraftPlugin =
|
|
280
|
+
const M = new K();
|
|
281
|
+
window.DraftPlugin = M;
|
|
308
282
|
export {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
283
|
+
z as EditorMenu,
|
|
284
|
+
N as ViewMode,
|
|
285
|
+
M as default
|
|
312
286
|
};
|
|
313
287
|
//# sourceMappingURL=index.es.js.map
|
package/dist/index.es.js.map
CHANGED
|
@@ -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","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 { getImageParamsFromFileUrl } from './utils';\nimport pkg from '../package.json';\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\nconst 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\nconst 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\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 (\n value === 'stage' ||\n value?.includes('https://') ||\n window.location.pathname.includes('netlify')\n ) {\n return value?.includes('https://') ? value : `${PROD_ENDPOINT}/stage`;\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":"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"}
|
|
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":"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"}
|
package/dist/src/plugin.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/src/utils.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { ImageParams } from './types';
|
|
2
2
|
export declare const getImageParamsFromFileUrl: (imgSrc: string) => Promise<Omit<ImageParams, "url">>;
|
|
3
|
+
export declare const constructKeyCode: (event: KeyboardEvent) => string;
|
|
4
|
+
export declare const CORE_HOTKEYS: Set<string>;
|
|
3
5
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/src/utils.d.ts.map
CHANGED
|
@@ -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"}
|
|
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"}
|
package/package.json
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getdraft/plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"main": "dist/index.cjs.js",
|
|
5
5
|
"module": "dist/index.es.js",
|
|
6
6
|
"types": "src",
|
|
7
|
+
"dependencies": {},
|
|
8
|
+
"devDependencies": {
|
|
9
|
+
"@vitejs/plugin-legacy": "5.4.1",
|
|
10
|
+
"rollup": "4.22.4",
|
|
11
|
+
"terser": "5.31.3",
|
|
12
|
+
"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"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
7
18
|
"scripts": {
|
|
8
19
|
"prebuild": "rm -rf dist",
|
|
9
20
|
"build": "vite build",
|
|
10
|
-
"dev-tsc": "
|
|
21
|
+
"dev-tsc": "tsc-check",
|
|
11
22
|
"eslint": "npx eslint src",
|
|
12
23
|
"eslint:fix": "pnpm eslint --fix",
|
|
13
24
|
"prettify": "npx prettier -w ./",
|
|
14
25
|
"prepublish": "pnpm build",
|
|
15
26
|
"watch": "NODE_ENV=development vite build --watch",
|
|
16
27
|
"start": "NODE_ENV=development npx vite"
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
"devDependencies": {
|
|
20
|
-
"@types/letty": "workspace:^",
|
|
21
|
-
"@vitejs/plugin-legacy": "5.4.1",
|
|
22
|
-
"rollup": "4.22.4",
|
|
23
|
-
"terser": "5.31.3",
|
|
24
|
-
"rollup-plugin-dts": "6.1.1",
|
|
25
|
-
"@letty/eslint-config-ts": "workspace:^",
|
|
26
|
-
"@letty/prettier": "workspace:^"
|
|
27
|
-
},
|
|
28
|
-
"license": "MIT"
|
|
29
|
-
}
|
|
28
|
+
}
|
|
29
|
+
}
|
package/src/plugin.ts
CHANGED
|
@@ -12,70 +12,13 @@ import {
|
|
|
12
12
|
ViewMode,
|
|
13
13
|
HandlerParams,
|
|
14
14
|
} from './types';
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
getImageParamsFromFileUrl,
|
|
17
|
+
constructKeyCode,
|
|
18
|
+
CORE_HOTKEYS,
|
|
19
|
+
} from './utils';
|
|
16
20
|
import pkg from '../package.json';
|
|
17
21
|
|
|
18
|
-
const getLatinKey = (key: string, code: string) => {
|
|
19
|
-
if (key.length !== 1) {
|
|
20
|
-
return key;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const capitalHetaCode = 880;
|
|
24
|
-
const isNonLatin = key.charCodeAt(0) >= capitalHetaCode;
|
|
25
|
-
|
|
26
|
-
if (isNonLatin) {
|
|
27
|
-
if (code.indexOf('Key') === 0 && code.length === 4) {
|
|
28
|
-
return code.charAt(3);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (code.indexOf('Digit') === 0 && code.length === 6) {
|
|
32
|
-
return code.charAt(5);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return key;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const constructKeyCode = (event: KeyboardEvent) => {
|
|
40
|
-
let keyCode =
|
|
41
|
-
`${getLatinKey(event.key, event.code)}`.toLowerCase() || event.key;
|
|
42
|
-
const macOs = navigator.userAgent.includes('Mac OS');
|
|
43
|
-
|
|
44
|
-
if (keyCode === 'backspace' && macOs) {
|
|
45
|
-
keyCode = 'delete';
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const prefix = [];
|
|
49
|
-
|
|
50
|
-
if ((macOs && event.metaKey) || (!macOs && event.ctrlKey)) {
|
|
51
|
-
prefix.push('mod');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (event.shiftKey) {
|
|
55
|
-
prefix.push('shift');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (prefix.length > 0) {
|
|
59
|
-
keyCode = `${prefix.join('-')}-${getLatinKey(keyCode, event.code)}`;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return keyCode;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const CORE_HOTKEYS = new Set([
|
|
66
|
-
'escape',
|
|
67
|
-
'mod-c',
|
|
68
|
-
'mod-d',
|
|
69
|
-
'mod-z',
|
|
70
|
-
'mod-y',
|
|
71
|
-
'mod-shift-z',
|
|
72
|
-
'mod-v',
|
|
73
|
-
'delete',
|
|
74
|
-
'mod-g',
|
|
75
|
-
'mod-p',
|
|
76
|
-
'mod-s',
|
|
77
|
-
]);
|
|
78
|
-
|
|
79
22
|
const getDeployLink = () => {
|
|
80
23
|
const regex = new RegExp(`(^| )seplugin-dev=([^;]+)`);
|
|
81
24
|
const match = document.cookie.match(regex);
|
|
@@ -85,12 +28,8 @@ const getDeployLink = () => {
|
|
|
85
28
|
return LOCAL_ENDPOINT;
|
|
86
29
|
}
|
|
87
30
|
|
|
88
|
-
if (
|
|
89
|
-
value
|
|
90
|
-
value?.includes('https://') ||
|
|
91
|
-
window.location.pathname.includes('netlify')
|
|
92
|
-
) {
|
|
93
|
-
return value?.includes('https://') ? value : `${PROD_ENDPOINT}/stage`;
|
|
31
|
+
if (value?.startsWith('https://')) {
|
|
32
|
+
return value;
|
|
94
33
|
}
|
|
95
34
|
|
|
96
35
|
const [major, mid] = pkg.version.split('.');
|
package/src/utils.ts
CHANGED
|
@@ -41,3 +41,64 @@ export const getImageParamsFromFileUrl = (imgSrc: string) =>
|
|
|
41
41
|
|
|
42
42
|
img.src = imgSrc;
|
|
43
43
|
});
|
|
44
|
+
|
|
45
|
+
const getLatinKey = (key: string, code: string) => {
|
|
46
|
+
if (key.length !== 1) {
|
|
47
|
+
return key;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const capitalHetaCode = 880;
|
|
51
|
+
const isNonLatin = key.charCodeAt(0) >= capitalHetaCode;
|
|
52
|
+
|
|
53
|
+
if (isNonLatin) {
|
|
54
|
+
if (code.indexOf('Key') === 0 && code.length === 4) {
|
|
55
|
+
return code.charAt(3);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (code.indexOf('Digit') === 0 && code.length === 6) {
|
|
59
|
+
return code.charAt(5);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return key;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const constructKeyCode = (event: KeyboardEvent) => {
|
|
67
|
+
let keyCode =
|
|
68
|
+
`${getLatinKey(event.key, event.code)}`.toLowerCase() || event.key;
|
|
69
|
+
const macOs = navigator.userAgent.includes('Mac OS');
|
|
70
|
+
|
|
71
|
+
if (keyCode === 'backspace' && macOs) {
|
|
72
|
+
keyCode = 'delete';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const prefix = [];
|
|
76
|
+
|
|
77
|
+
if ((macOs && event.metaKey) || (!macOs && event.ctrlKey)) {
|
|
78
|
+
prefix.push('mod');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (event.shiftKey) {
|
|
82
|
+
prefix.push('shift');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (prefix.length > 0) {
|
|
86
|
+
keyCode = `${prefix.join('-')}-${getLatinKey(keyCode, event.code)}`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return keyCode;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const CORE_HOTKEYS = new Set([
|
|
93
|
+
'escape',
|
|
94
|
+
'mod-c',
|
|
95
|
+
'mod-d',
|
|
96
|
+
'mod-z',
|
|
97
|
+
'mod-y',
|
|
98
|
+
'mod-shift-z',
|
|
99
|
+
'mod-v',
|
|
100
|
+
'delete',
|
|
101
|
+
'mod-g',
|
|
102
|
+
'mod-p',
|
|
103
|
+
'mod-s',
|
|
104
|
+
]);
|