@getdraft/plugin 1.13.0-beta.0 → 1.13.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/.turbo/turbo-build.log +22 -0
- package/.turbo/turbo-eslint.log +4 -0
- 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 +35 -35
- 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 +14 -14
- package/src/plugin.ts +5 -62
- package/src/utils.ts +61 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
> @letty-email/plugin@1.12.1 build /Users/nipanasovich/Documents/Work/draft/packages/plugin
|
|
3
|
+
> vite build
|
|
4
|
+
|
|
5
|
+
[33mThe CJS build of Vite's Node API is deprecated. See https://vite.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.[39m
|
|
6
|
+
vite v5.4.20 building for production...
|
|
7
|
+
transforming...
|
|
8
|
+
✓ 6 modules transformed.
|
|
9
|
+
rendering chunks...
|
|
10
|
+
|
|
11
|
+
[vite:dts] Start generate declaration files...
|
|
12
|
+
computing gzip size...
|
|
13
|
+
dist/index.es.js 7.69 kB │ gzip: 2.73 kB │ map: 21.92 kB
|
|
14
|
+
|
|
15
|
+
[vite:dts] The resolved path of type entry is not ending with '.d.ts'.
|
|
16
|
+
|
|
17
|
+
[vite:dts] Outside emitted: /Users/nipanasovich/Documents/Work/draft/packages/plugin/src.d.ts
|
|
18
|
+
[vite:dts] Declaration files built in 8574ms.
|
|
19
|
+
|
|
20
|
+
Entry module "src/index.ts" is using named and default exports together. Consumers of your bundle will have to use `seplugin.default` to access the default export, which may not be what you want. Use `output.exports: "named"` to disable this warning.
|
|
21
|
+
dist/index.cjs.js 5.69 kB │ gzip: 2.41 kB │ map: 21.10 kB
|
|
22
|
+
✓ built in 9.44s
|
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
|
|
1
|
+
"use strict";var b=Object.defineProperty;var L=(n,e,t)=>e in n?b(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var a=(n,e,t)=>L(n,typeof e!="symbol"?e+"":e,t);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const I="http://localhost:5174",h="https://seplugin.sendsay.ru",x=async n=>{try{const e=await fetch(n,{method:"HEAD"});if(!e.ok)return null;const t=e.headers.get("Content-Length");return t?parseInt(t,10):null}catch{return null}},g=n=>new Promise((e,t)=>{const o=new Image;o.onload=async()=>{const i=await x(n)??0;e({originalWidth:o.width,originalHeight:o.height,ratio:o.width/o.height,fileSize:i})},o.onerror=i=>{t(i)},o.src=n}),u=(n,e)=>{if(n.length!==1)return n;if(n.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 n},A=n=>{let e=`${u(n.key,n.code)}`.toLowerCase()||n.key;const t=navigator.userAgent.includes("Mac OS");e==="backspace"&&t&&(e="delete");const o=[];return(t&&n.metaKey||!t&&n.ctrlKey)&&o.push("mod"),n.shiftKey&&o.push("shift"),o.length>0&&(e=`${o.join("-")}-${u(e,n.code)}`),e},D=new Set(["escape","mod-c","mod-d","mod-z","mod-y","mod-shift-z","mod-v","delete","mod-g","mod-p","mod-s"]),C="@getdraft/plugin",O="1.13.0",H="dist/index.cjs.js",N="dist/index.es.js",M="src",T={prebuild:"rm -rf dist",build:"vite build","dev-tsc":"npx tsc --noEmit",eslint:"npx eslint src","eslint:fix":"pnpm eslint --fix",prettify:"npx prettier -w ./",prepublish:"pnpm build",watch:"NODE_ENV=development vite build --watch",start:"NODE_ENV=development npx vite"},z={},K={"@types/letty":"workspace:^","@vitejs/plugin-legacy":"5.4.1",rollup:"4.22.4",terser:"5.31.3","rollup-plugin-dts":"6.1.1","@letty/eslint-config-ts":"workspace:^","@letty/prettier":"workspace:^"},S="MIT",U={name:C,version:O,main:H,module:N,types:M,scripts:T,dependencies:z,devDependencies:K,license:S},_=()=>{var s,r;const n=new RegExp("(^| )seplugin-dev=([^;]+)"),e=document.cookie.match(n),t=(r=e==null?void 0:(s=e[2]).toLowerCase)==null?void 0:r.call(s);if(t==="true")return I;if(t==="stage"||t!=null&&t.includes("https://")||window.location.pathname.includes("netlify"))return t!=null&&t.includes("https://")?t:`${h}/stage`;const[o,i]=U.version.split(".");return`${h}/v${o}.${i}`},j=({token:n,pluginId:e,apiUrl:t})=>{if(!n)throw new Error("No [token] was provided");if(!e)throw new Error("No [pluginId] was provided");if(!t)throw new Error("No [apiUrl] was provided")},G=()=>{const n=document.createElement("iframe");return n.src=_(),n.setAttribute("style","height:100%;width:100%;min-width:960px;border:0px"),n.setAttribute("allow","clipboard-read; clipboard-write"),n.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups"),n};class ${constructor(e){a(this,"iframe",null);a(this,"hotkeysAttached",!1);a(this,"onHostHotkey",e=>{var c;if(!this.captureHotkeysEnabled()||!((c=this.iframe)!=null&&c.contentWindow))return;const t=A(e);if(!D.has(t))return;const o=e.target;if(o&&(o.isContentEditable||["INPUT","TEXTAREA","SELECT"].includes(o.tagName)))return;e.preventDefault();const{key:i,ctrlKey:s,metaKey:r,shiftKey:l,altKey:d}=e;this.postEvent("hostHotkey",{key:i,code:e.code,metaKey:r,ctrlKey:s,shiftKey:l,altKey:d,keyCode:t})});a(this,"onImageUpload",async({id:e,...t})=>{var o,i;try{const s=await((i=(o=this.config.on).uploadImage)==null?void 0:i.call(o,t));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 o,i;const t=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=(o=this.config.on).openGallery)==null||i.call(o,t)});a(this,"onMessage",e=>{const{data:{source:t,event:o,...i}}=e;t==="DraftPlugin"&&(o==="openGallery"?this.onGalleryOpen(i):o==="uploadImage"?this.onImageUpload(i):o==="loadPersonalization"?this.onLoadPersonalization():this.triggerEvent(this.config.on[o],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 t=null;const o=new Promise((i,s)=>{const r=l=>{const{data:{source:d,event:c,...p}}=l;d==="DraftPlugin"&&c===e&&(l.stopPropagation(),t&&(clearTimeout(t),t=null),i(p),window.removeEventListener("message",r,!0))};window.addEventListener("message",r,!0),t=setTimeout(()=>{window.removeEventListener("message",r,!0),s("Request timed out"),t=null},2e3)});return this.postEvent(e),o}postEvent(e,t={}){this.iframe&&this.iframe.contentWindow&&this.iframe.contentWindow.postMessage({...t,event:e,source:"DraftPlugin"},"*")}triggerEvent(e,t){if(e)return e(t)}start({template:e,templateName:t,uid:o}){const i=document.querySelector(this.config.container);if(i){const s=({data:{source:r,event:l}})=>{if(r==="DraftPlugin"&&l==="loaded"){const{on:d,container:c,locale:p,autosave:y,token:v,apiUrl:E,pluginId:k,__config:P}=this.config;j(this.config),this.iframe&&this.iframe.contentWindow&&this.postEvent("init",{container:c,locale:p,uid:o,autosave:y,token:v,pluginId:k,apiUrl:E,__config:P,enabledListeners:Object.keys(d),template:e,templateName:t}),window.addEventListener("message",this.onMessage),window.removeEventListener("message",s)}};this.iframe=G(),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,t={}){this.postEvent("changeTemplate",{...t,template:e})}toggleGrid(e){this.postEvent("toggleGrid",{state:e})}togglePreview(e){this.postEvent("togglePreview",{state:e})}toggleMenu(e=null){this.postEvent("toggleMenu",{menu:e})}toggleViewMode(e){this.postEvent("toggleViewMode",{viewMode:e})}undo(){this.postEvent("undo")}redo(){this.postEvent("redo")}save(){return this.promisedIframeMethod("saveAction")}exit(){return this.promisedIframeMethod("exitAction")}exportContent(){return this.promisedIframeMethod("exportContent")}}var m=(n=>(n.Audit="audit",n.Guide="guide",n.Style="style",n.Blocks="blocks",n))(m||{}),f=(n=>(n.Desktop="desktop",n.Mobile="mobile",n))(f||{});const W={container:"#draft-plugin-container",disableHotkeysPassing:!1,locale:"ru",on:{}};class F{create(e){return new $({...W,...e})}}const w=new F;window.DraftPlugin=w;exports.EditorMenu=m;exports.ViewMode=f;exports.default=w;
|
|
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":"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"}
|
|
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 (\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":"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"}
|
package/dist/index.es.js
CHANGED
|
@@ -24,35 +24,7 @@ const P = "http://localhost:5174", h = "https://seplugin.sendsay.ru", b = async
|
|
|
24
24
|
}, o.onerror = (i) => {
|
|
25
25
|
t(i);
|
|
26
26
|
}, o.src = n;
|
|
27
|
-
}),
|
|
28
|
-
prebuild: "rm -rf dist",
|
|
29
|
-
build: "vite build",
|
|
30
|
-
"dev-tsc": "npx tsc --noEmit",
|
|
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) => {
|
|
27
|
+
}), u = (n, e) => {
|
|
56
28
|
if (n.length !== 1)
|
|
57
29
|
return n;
|
|
58
30
|
if (n.charCodeAt(0) >= 880) {
|
|
@@ -62,13 +34,13 @@ const P = "http://localhost:5174", h = "https://seplugin.sendsay.ru", b = async
|
|
|
62
34
|
return e.charAt(5);
|
|
63
35
|
}
|
|
64
36
|
return n;
|
|
65
|
-
},
|
|
37
|
+
}, L = (n) => {
|
|
66
38
|
let e = `${u(n.key, n.code)}`.toLowerCase() || n.key;
|
|
67
39
|
const t = navigator.userAgent.includes("Mac OS");
|
|
68
40
|
e === "backspace" && t && (e = "delete");
|
|
69
41
|
const o = [];
|
|
70
42
|
return (t && n.metaKey || !t && n.ctrlKey) && o.push("mod"), n.shiftKey && o.push("shift"), o.length > 0 && (e = `${o.join("-")}-${u(e, n.code)}`), e;
|
|
71
|
-
},
|
|
43
|
+
}, I = /* @__PURE__ */ new Set([
|
|
72
44
|
"escape",
|
|
73
45
|
"mod-c",
|
|
74
46
|
"mod-d",
|
|
@@ -80,14 +52,42 @@ 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
|
+
]), x = "@getdraft/plugin", A = "1.13.0", D = "dist/index.cjs.js", C = "dist/index.es.js", H = "src", O = {
|
|
56
|
+
prebuild: "rm -rf dist",
|
|
57
|
+
build: "vite build",
|
|
58
|
+
"dev-tsc": "npx tsc --noEmit",
|
|
59
|
+
eslint: "npx eslint src",
|
|
60
|
+
"eslint:fix": "pnpm eslint --fix",
|
|
61
|
+
prettify: "npx prettier -w ./",
|
|
62
|
+
prepublish: "pnpm build",
|
|
63
|
+
watch: "NODE_ENV=development vite build --watch",
|
|
64
|
+
start: "NODE_ENV=development npx vite"
|
|
65
|
+
}, N = {}, z = {
|
|
66
|
+
"@types/letty": "workspace:^",
|
|
67
|
+
"@vitejs/plugin-legacy": "5.4.1",
|
|
68
|
+
rollup: "4.22.4",
|
|
69
|
+
terser: "5.31.3",
|
|
70
|
+
"rollup-plugin-dts": "6.1.1",
|
|
71
|
+
"@letty/eslint-config-ts": "workspace:^",
|
|
72
|
+
"@letty/prettier": "workspace:^"
|
|
73
|
+
}, T = "MIT", K = {
|
|
74
|
+
name: x,
|
|
75
|
+
version: A,
|
|
76
|
+
main: D,
|
|
77
|
+
module: C,
|
|
78
|
+
types: H,
|
|
79
|
+
scripts: O,
|
|
80
|
+
dependencies: N,
|
|
81
|
+
devDependencies: z,
|
|
82
|
+
license: T
|
|
83
|
+
}, M = () => {
|
|
84
84
|
var s, r;
|
|
85
85
|
const n = new RegExp("(^| )seplugin-dev=([^;]+)"), e = document.cookie.match(n), t = (r = e == null ? void 0 : (s = e[2]).toLowerCase) == null ? void 0 : r.call(s);
|
|
86
86
|
if (t === "true")
|
|
87
87
|
return P;
|
|
88
88
|
if (t === "stage" || t != null && t.includes("https://") || window.location.pathname.includes("netlify"))
|
|
89
89
|
return t != null && t.includes("https://") ? t : `${h}/stage`;
|
|
90
|
-
const [o, i] =
|
|
90
|
+
const [o, i] = K.version.split(".");
|
|
91
91
|
return `${h}/v${o}.${i}`;
|
|
92
92
|
}, U = ({ token: n, pluginId: e, apiUrl: t }) => {
|
|
93
93
|
if (!n)
|
|
@@ -114,8 +114,8 @@ class G {
|
|
|
114
114
|
var c;
|
|
115
115
|
if (!this.captureHotkeysEnabled() || !((c = this.iframe) != null && c.contentWindow))
|
|
116
116
|
return;
|
|
117
|
-
const t =
|
|
118
|
-
if (!
|
|
117
|
+
const t = L(e);
|
|
118
|
+
if (!I.has(t))
|
|
119
119
|
return;
|
|
120
120
|
const o = e.target;
|
|
121
121
|
if (o && (o.isContentEditable || ["INPUT", "TEXTAREA", "SELECT"].includes(o.tagName)))
|
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 (\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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"}
|
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;AA4DjB,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,9 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getdraft/plugin",
|
|
3
|
-
"version": "1.13.0
|
|
3
|
+
"version": "1.13.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",
|
|
@@ -14,16 +25,5 @@
|
|
|
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);
|
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
|
+
]);
|