resize-quill-image 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +352 -212
- package/dist/index.cjs.js +1 -3
- package/dist/index.d.ts +31 -24
- package/dist/index.es.js +317 -255
- package/dist/index.iife.js +1 -3
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,212 +1,352 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img src="images/logo-main.png" alt="Logo" />
|
|
3
|
-
</p>
|
|
4
|
-
<p align="center"> <h1 align="center">resize-quill-image</h1> </p>
|
|
5
|
-
<p align="center">
|
|
6
|
-
<img src="https://img.shields.io/npm/v/resize-quill-image" alt="version" />
|
|
7
|
-
<img src="https://img.shields.io/bundlephobia/minzip/resize-quill-image?style=flat" alt="size" />
|
|
8
|
-
<img src="https://img.shields.io/npm/l/resize-quill-image?style=flat" alt="license" />
|
|
9
|
-
<img src="https://img.shields.io/npm/dt/resize-quill-image?style=flat&color=blue&cacheSeconds=3600" alt="downloads" />
|
|
10
|
-
<img src="https://img.shields.io/badge/Quill_compatible-2.0.3-blue?style=flat&cacheSeconds=3600" alt="Quill compatible 2.0.3" />
|
|
11
|
-
<a href="https://resize-quill-image.vercel.app/">
|
|
12
|
-
<img src="https://img.shields.io/badge/Live-Demo-00c7b7?logo=vercel&logoColor=white&style=flat-square" alt="Live Demo" />
|
|
13
|
-
</a>
|
|
14
|
-
</p>
|
|
15
|
-
|
|
16
|
-
`resize-quill-image` is a lightweight Quill module that enables image resizing inside the editor.
|
|
17
|
-
|
|
18
|
-
This module was originally created because we needed a working image resize solution for our own project.
|
|
19
|
-
Most existing Quill modules were either deprecated or not updated for the latest Quill versions.
|
|
20
|
-
While there are a few small issues, they
|
|
21
|
-
You can find these cases and their solutions in the [Problems](#problems) section.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
- [Demo](#demo)
|
|
25
|
-
- [Installation](#installation)
|
|
26
|
-
- [
|
|
27
|
-
- [
|
|
28
|
-
|
|
29
|
-
- [
|
|
30
|
-
- [
|
|
31
|
-
- [
|
|
32
|
-
- [
|
|
33
|
-
- [
|
|
34
|
-
- [
|
|
35
|
-
|
|
36
|
-
- [
|
|
37
|
-
|
|
38
|
-
- [
|
|
39
|
-
- [
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
[
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
```js
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
**
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="images/logo-main.png" alt="Logo" />
|
|
3
|
+
</p>
|
|
4
|
+
<p align="center"> <h1 align="center">resize-quill-image</h1> </p>
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="https://img.shields.io/npm/v/resize-quill-image" alt="version" />
|
|
7
|
+
<img src="https://img.shields.io/bundlephobia/minzip/resize-quill-image?style=flat" alt="size" />
|
|
8
|
+
<img src="https://img.shields.io/npm/l/resize-quill-image?style=flat" alt="license" />
|
|
9
|
+
<img src="https://img.shields.io/npm/dt/resize-quill-image?style=flat&color=blue&cacheSeconds=3600" alt="downloads" />
|
|
10
|
+
<img src="https://img.shields.io/badge/Quill_compatible-2.0.3-blue?style=flat&cacheSeconds=3600" alt="Quill compatible 2.0.3" />
|
|
11
|
+
<a href="https://resize-quill-image.vercel.app/">
|
|
12
|
+
<img src="https://img.shields.io/badge/Live-Demo-00c7b7?logo=vercel&logoColor=white&style=flat-square" alt="Live Demo" />
|
|
13
|
+
</a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
`resize-quill-image` is a lightweight Quill module that enables image resizing inside the editor.
|
|
17
|
+
|
|
18
|
+
This module was originally created because we needed a working image resize solution for our own project.
|
|
19
|
+
Most existing Quill modules were either deprecated or not updated for the latest Quill versions.
|
|
20
|
+
While there are a few small issues, they're usually project-specific and not caused by the module itself.
|
|
21
|
+
You can find these cases and their solutions in the [Problems](#problems) section.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
- [Demo](#demo)
|
|
25
|
+
- [Installation](#installation)
|
|
26
|
+
- [npm](#npm)
|
|
27
|
+
- [CDN](#cdn)
|
|
28
|
+
- [Usage](#usage)
|
|
29
|
+
- [Import the module](#1-import-the-module)
|
|
30
|
+
- [Register the module with Quill](#2-register-the-module-with-quill)
|
|
31
|
+
- [Configure the Quill editor](#3-configure-the-quill-editor)
|
|
32
|
+
- [Options](#options)
|
|
33
|
+
- [Option Descriptions](#option-descriptions)
|
|
34
|
+
- [Style Options](#style-options)
|
|
35
|
+
- [Keyboard Shortcuts](#keyboard-shortcuts)
|
|
36
|
+
- [TypeScript](#typescript)
|
|
37
|
+
- [Cleanup / Destroy](#cleanup--destroy)
|
|
38
|
+
- [Usage](#usage-1)
|
|
39
|
+
- [When to use](#when-to-use)
|
|
40
|
+
- [Example with unmount](#example-with-unmount)
|
|
41
|
+
- [Problems](#problems)
|
|
42
|
+
- [Resize overlay goes outside the editor](#problem-resize-overlay-goes-outside-the-editor)
|
|
43
|
+
- [Image resize handles and border do not appear](#problem-image-resize-handles-and-border-do-not-appear)
|
|
44
|
+
- [License](#license)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
## [Demo](#demo)
|
|
48
|
+
### Live
|
|
49
|
+
[Check out the live demo](https://resize-quill-image.vercel.app/)
|
|
50
|
+
### GIF
|
|
51
|
+

|
|
52
|
+
|
|
53
|
+
## [Installation](#installation)
|
|
54
|
+
|
|
55
|
+
### [npm](#npm)
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm install resize-quill-image
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### [CDN](#cdn)
|
|
62
|
+
|
|
63
|
+
Load Quill first, then the module. The module exposes a global `ImageResize` variable.
|
|
64
|
+
|
|
65
|
+
**unpkg:**
|
|
66
|
+
```html
|
|
67
|
+
<link href="https://unpkg.com/quill@2.0.3/dist/quill.snow.css" rel="stylesheet">
|
|
68
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
69
|
+
<script src="https://unpkg.com/quill@2.0.3/dist/quill.js"></script>
|
|
70
|
+
<script src="https://unpkg.com/resize-quill-image/dist/index.iife.js"></script>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**jsDelivr:**
|
|
74
|
+
```html
|
|
75
|
+
<link href="https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.snow.css" rel="stylesheet">
|
|
76
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
77
|
+
<script src="https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.js"></script>
|
|
78
|
+
<script src="https://cdn.jsdelivr.net/npm/resize-quill-image/dist/index.iife.js"></script>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
You can pin to a specific version:
|
|
82
|
+
```html
|
|
83
|
+
<script src="https://unpkg.com/resize-quill-image@1.0.10/dist/index.iife.js"></script>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Then register and use it:
|
|
87
|
+
```html
|
|
88
|
+
<script>
|
|
89
|
+
Quill.register('modules/imageResize', ImageResize);
|
|
90
|
+
|
|
91
|
+
const quill = new Quill('#editor', {
|
|
92
|
+
theme: 'snow',
|
|
93
|
+
modules: {
|
|
94
|
+
toolbar: [['bold', 'italic'], ['image']],
|
|
95
|
+
imageResize: {}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
</script>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
> **Note:** Quill must be loaded before `resize-quill-image`. The IIFE build reads `Quill` from the global scope at load time.
|
|
102
|
+
|
|
103
|
+
> **Note:** Quill 2.x CDN support requires **`resize-quill-image@1.0.10`** or later. Earlier versions will throw an error when used with Quill 2.x via CDN.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## [Usage](#usage)
|
|
108
|
+
|
|
109
|
+
### 1. Import the module
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
import ImageResize from 'resize-quill-image';
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 2. Register the module with Quill
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
Quill.register('modules/imageResize', ImageResize);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 3. Configure the Quill editor
|
|
122
|
+
|
|
123
|
+
```js
|
|
124
|
+
const quill = new Quill(editorContainer, {
|
|
125
|
+
modules: {
|
|
126
|
+
syntax: true,
|
|
127
|
+
toolbar: toolbarOptions,
|
|
128
|
+
imageResize: true
|
|
129
|
+
},
|
|
130
|
+
placeholder: 'Compose an epic...',
|
|
131
|
+
theme: 'snow'
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## [Options](#options)
|
|
138
|
+
|
|
139
|
+
You can configure the behavior of `resize-quill-image` by passing options inside your Quill config:
|
|
140
|
+
|
|
141
|
+
```js
|
|
142
|
+
imageResize: {
|
|
143
|
+
helpIcon: true,
|
|
144
|
+
displaySize: true,
|
|
145
|
+
styleSelection: true
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### [Option Descriptions](#option-descriptions)
|
|
150
|
+
|
|
151
|
+
| Option | Type | Default | Description |
|
|
152
|
+
|--------------------|-----------|-------------------|-------------|
|
|
153
|
+
| `helpIcon` | `boolean` | `true` | Shows a `?` icon on the image overlay. Describes keyboard shortcuts:<br>• `Shift` → vertical<br>• `Alt` → horizontal<br>• `Ctrl` → custom/free resize <br>  |
|
|
154
|
+
| `displaySize` | `boolean` | `true` | Displays current image width and height as a badge while resizing. <br>  |
|
|
155
|
+
| `styleSelection` | `boolean` | `true` | Disables the blue selection overlay. To keep default behavior: `imageResize: { styleSelection: false }` <br>  |
|
|
156
|
+
| `minWidth` | `number` | `16` | Minimum image width in pixels. |
|
|
157
|
+
| `minHeight` | `number` | `16` | Minimum image height in pixels. |
|
|
158
|
+
| `positions` | `array` | 4 corners | Array of handle position objects that control where resize handles appear on the image. Each object takes `{ top?, left?, right?, bottom?, clipPath? }`. |
|
|
159
|
+
|
|
160
|
+
### [Style Options](#style-options)
|
|
161
|
+
|
|
162
|
+
You can customize three visual elements. All style options accept a plain object of CSS properties (camelCase keys, string or number values). Your values are **merged with the defaults** — you only need to pass what you want to override.
|
|
163
|
+
|
|
164
|
+
| Option | Customizes |
|
|
165
|
+
|---------------------|------------|
|
|
166
|
+
| `overlayStyles` | The dashed border that appears around the selected image. |
|
|
167
|
+
| `handleStyles` | The corner resize handles. |
|
|
168
|
+
| `displaySizeStyles` | The width × height badge shown while resizing. |
|
|
169
|
+
|
|
170
|
+
**Example:**
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
const quill = new Quill(editorContainer, {
|
|
174
|
+
modules: {
|
|
175
|
+
toolbar: toolbarOptions,
|
|
176
|
+
imageResize: {
|
|
177
|
+
helpIcon: true,
|
|
178
|
+
displaySize: true,
|
|
179
|
+
styleSelection: true,
|
|
180
|
+
minWidth: 20,
|
|
181
|
+
minHeight: 20,
|
|
182
|
+
overlayStyles: {
|
|
183
|
+
border: '2px solid red',
|
|
184
|
+
},
|
|
185
|
+
handleStyles: {
|
|
186
|
+
backgroundColor: '#ff0000',
|
|
187
|
+
width: '12px',
|
|
188
|
+
height: '12px',
|
|
189
|
+
},
|
|
190
|
+
displaySizeStyles: {
|
|
191
|
+
backgroundColor: '#000',
|
|
192
|
+
color: '#fff',
|
|
193
|
+
},
|
|
194
|
+
positions: [
|
|
195
|
+
{ top: 0, left: 0, clipPath: 'polygon(0% 0%, 100% 0%, 0% 100%)' },
|
|
196
|
+
{ top: 0, right: 0, clipPath: 'polygon(100% 0%, 0% 0%, 100% 100%)' },
|
|
197
|
+
{ bottom: 0, left: 0, clipPath: 'polygon(0% 100%, 100% 100%, 0% 0%)' },
|
|
198
|
+
{ bottom: 0, right: 0, clipPath: 'polygon(100% 100%, 0% 100%, 100% 0%)' },
|
|
199
|
+
],
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
theme: 'snow',
|
|
203
|
+
});
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## [Keyboard Shortcuts](#keyboard-shortcuts)
|
|
209
|
+
|
|
210
|
+
While dragging a resize handle, hold a modifier key to change resize behavior:
|
|
211
|
+
|
|
212
|
+
| Key | Behavior |
|
|
213
|
+
|---------|-----------|
|
|
214
|
+
| *(none)* | Proportional resize — maintains aspect ratio |
|
|
215
|
+
| `Shift` | Vertical only — changes height, width is unchanged |
|
|
216
|
+
| `Alt` | Horizontal only — changes width, height is unchanged |
|
|
217
|
+
| `Ctrl` | Free resize — width and height change independently |
|
|
218
|
+
|
|
219
|
+
These shortcuts are also shown in the `?` tooltip on the overlay when `helpIcon: true`.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## [TypeScript](#typescript)
|
|
224
|
+
|
|
225
|
+
This package ships TypeScript definitions. All option interfaces are exported for use in your own types:
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
import ImageResize from 'resize-quill-image';
|
|
229
|
+
import type { ImageResizeOptions, HandlePosition, CSSStyles } from 'resize-quill-image';
|
|
230
|
+
|
|
231
|
+
const options: ImageResizeOptions = {
|
|
232
|
+
helpIcon: true,
|
|
233
|
+
displaySize: true,
|
|
234
|
+
minWidth: 20,
|
|
235
|
+
overlayStyles: { border: '2px dashed #999' },
|
|
236
|
+
handleStyles: { backgroundColor: '#ff0000' },
|
|
237
|
+
};
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## [Cleanup / Destroy](#cleanup--destroy)
|
|
243
|
+
|
|
244
|
+
If you're dynamically mounting and unmounting the Quill editor (for example in a Single Page Application or during route changes), it's important to properly **clean up** the `resize-quill-image` module to avoid memory leaks or event duplication.
|
|
245
|
+
|
|
246
|
+
This module provides a `destroy()` method that you can call when tearing down your Quill instance.
|
|
247
|
+
|
|
248
|
+
### [Usage](#usage-1)
|
|
249
|
+
|
|
250
|
+
Call `destroy()` **before** clearing the DOM:
|
|
251
|
+
|
|
252
|
+
```js
|
|
253
|
+
const imageResizeModule = quill.getModule('imageResize');
|
|
254
|
+
|
|
255
|
+
if (imageResizeModule?.destroy) {
|
|
256
|
+
imageResizeModule.destroy();
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
container.innerHTML = '';
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
> **Important:** Always call `destroy()` before removing the editor from the DOM. Clearing the DOM first can cause errors inside `destroy()` as it tries to clean up elements that no longer exist.
|
|
263
|
+
|
|
264
|
+
This will:
|
|
265
|
+
|
|
266
|
+
- Remove all event listeners (`click`, `selection-change`, `text-change`)
|
|
267
|
+
- Remove any visible resize overlays or handles
|
|
268
|
+
- Clean up drag and tooltip controllers
|
|
269
|
+
- Reset internal references for garbage collection
|
|
270
|
+
|
|
271
|
+
### [When to use](#when-to-use)
|
|
272
|
+
|
|
273
|
+
- If you're unmounting your editor component
|
|
274
|
+
- If you're switching pages in an SPA
|
|
275
|
+
- If you're reinitializing Quill manually
|
|
276
|
+
|
|
277
|
+
### [Example with unmount](#example-with-unmount)
|
|
278
|
+
|
|
279
|
+
```js
|
|
280
|
+
useEffect(() => {
|
|
281
|
+
const quill = new Quill(editorRef.current, { ... });
|
|
282
|
+
|
|
283
|
+
return () => {
|
|
284
|
+
const module = quill.getModule('imageResize');
|
|
285
|
+
if (module?.destroy) module.destroy();
|
|
286
|
+
editorRef.current.innerHTML = '';
|
|
287
|
+
};
|
|
288
|
+
}, []);
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
This helps ensure your editor stays clean and efficient across mounts.
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## [Problems](#problems)
|
|
296
|
+
|
|
297
|
+
### <ins>Problem: Resize overlay goes outside the editor</ins>
|
|
298
|
+
|
|
299
|
+
If your `.ql-container` has a fixed height like this:
|
|
300
|
+
|
|
301
|
+
```css
|
|
302
|
+
.ql-container {
|
|
303
|
+
height: 500px;
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Then the resize overlay may appear cut off or outside the bounds of the editor when the image goes beyond the height.
|
|
308
|
+
|
|
309
|
+
**Solution:**
|
|
310
|
+
|
|
311
|
+
Instead of a fixed height, use `min-height` and `max-height`:
|
|
312
|
+
|
|
313
|
+
```css
|
|
314
|
+
.ql-container {
|
|
315
|
+
min-height: 500px;
|
|
316
|
+
max-height: 500px;
|
|
317
|
+
overflow: auto;
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
This keeps the resize functionality working correctly and fully visible.
|
|
322
|
+
|
|
323
|
+
### <ins>Problem: Image resize handles and border do not appear</ins>
|
|
324
|
+
|
|
325
|
+
If you don't see the image resize handles or overlay border, make sure you’ve included `highlight.js`.
|
|
326
|
+
Quill’s `syntax` module depends on it, and without it, modules like `imageResize` may silently fail to render overlays.
|
|
327
|
+
|
|
328
|
+
Add this to your HTML:
|
|
329
|
+
|
|
330
|
+
```html
|
|
331
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
More info in the Quill docs for newer highlight.js cdn version:
|
|
335
|
+
https://quilljs.com/docs/modules/syntax#syntax-highlighter-module
|
|
336
|
+
|
|
337
|
+
## [License](#license)
|
|
338
|
+
|
|
339
|
+
MIT License
|
|
340
|
+
Free for personal and commercial use.
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
> [!NOTE]
|
|
344
|
+
> If you encounter any bugs, memory leaks, or unexpected behavior, feel free to open an issue on the [GitHub repository](https://github.com/littlenines/resize-quill-image/issues).
|
|
345
|
+
> Your feedback helps make the module better for everyone.
|
|
346
|
+
> If you want to contribute to the project — whether it's fixing a bug or improving performance — your contributions are welcome and appreciated.
|
|
347
|
+
|
|
348
|
+
> [!TIP]
|
|
349
|
+
> If you just want the code and prefer to build your own module on top of it, you're free to do that.
|
|
350
|
+
> Everything is located in the `/src` directory for full access and customization.
|
|
351
|
+
|
|
352
|
+
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,3 +1 @@
|
|
|
1
|
-
"use strict";const y=require("quill"),r="#AED2FF",f="#687EFF",c="#fff",h={minWidth:16,minHeight:16,noSelectionClass:"no-selection",handleStyles:{position:"absolute",width:"15px",height:"15px",backgroundColor:r,border:`1px solid ${f}`},overlayStyles:{position:"absolute",boxSizing:"border-box",border:"1px dashed #777",zIndex:8},positions:[{top:0,left:0,clipPath:"polygon(0% 0%, 100% 0%, 0% 100%)"},{top:0,right:0,clipPath:"polygon(100% 0%, 0% 0%, 100% 100%)"},{bottom:0,left:0,clipPath:"polygon(0% 100%, 100% 100%, 0% 0%)"},{bottom:0,right:0,clipPath:"polygon(100% 100%, 0% 100%, 100% 0%)"}],displaySizeStyles:{position:"absolute",fontSize:"12px",backgroundColor:r,color:c,padding:"2px 4px",borderRadius:"4px",userSelect:"none",pointerEvents:"none"},displaySizePositionStyles:{right:"20px",bottom:"5px",left:"auto"},tooltip:{iconStyles:{position:"absolute",top:"8px",right:"8px",width:"20px",height:"20px",background:r,color:c,borderRadius:"50%",textAlign:"center",lineHeight:"20px",fontSize:"14px",cursor:"pointer",userSelect:"none"},textStyles:{position:"absolute",background:r,color:c,padding:"6px 8px",borderRadius:"4px",display:"none",pointerEvents:"none",fontSize:"12px",whiteSpace:"pre"}}};class v{constructor(t,e){this.parent=t,this.styles=e,this.overlay=null}create(){this.overlay=document.createElement("div"),Object.assign(this.overlay.style,this.styles),this.parent.appendChild(this.overlay)}remove(){this.overlay&&(this.overlay.remove(),this.overlay=null)}reposition(t){if(!this.overlay)return;const e=t.getBoundingClientRect(),i=this.parent.getBoundingClientRect();Object.assign(this.overlay.style,{left:`${e.left-i.left-1+this.parent.scrollLeft}px`,top:`${e.top-i.top+this.parent.scrollTop}px`,width:`${e.width}px`,height:`${e.height}px`})}}class M{constructor(t,e,i,n){this.overlay=t,this.positions=e,this.handleStyles=i,this.mousedownCallback=n,this.boxes=[]}createHandles(){this.positions.forEach((t,e)=>{const i=document.createElement("div");Object.assign(i.style,this.handleStyles,t),i.style.clipPath=t.clipPath,e===0||e===3?i.style.cursor="nwse-resize":(e===1||e===2)&&(i.style.cursor="nesw-resize"),i.addEventListener("mousedown",this.mousedownCallback,!1),i.addEventListener("touchstart",this.mousedownCallback,{passive:!1}),this.overlay.appendChild(i),this.boxes.push(i)})}removeHandles(){this.boxes.forEach(t=>{t.removeEventListener("mousedown",this.mousedownCallback),t.removeEventListener("touchstart",this.mousedownCallback),t.onmousedown=null,t.ontouchstart=null,t.remove()}),this.boxes=[],this.overlay=null,this.positions=null,this.handleStyles=null,this.mousedownCallback=null}}class S{constructor(t,e,i,n,a){this.minWidth=t,this.minHeight=e,this.overlayManager=i,this.displaySizeManager=n,this.tooltipInfoManager=a,this.img=null,this.dragBox=null,this.startX=0,this.startY=0,this.startWidth=0,this.startHeight=0,this.handleDrag=this.handleDrag.bind(this),this.handleMouseup=this.handleMouseup.bind(this)}setDisplaySizeManager(t){this.displaySizeManager=t}setTooltipInfoManager(t){this.tooltipInfoManager=t}addEventListeners(){document.addEventListener("mousemove",this.handleDrag),document.addEventListener("touchmove",this.handleDrag,{passive:!1}),document.addEventListener("mouseup",this.handleMouseup,!0),document.addEventListener("touchend",this.handleMouseup,!0),document.addEventListener("touchcancel",this.handleMouseup,!0)}removeEventListeners(){document.removeEventListener("mousemove",this.handleDrag),document.removeEventListener("touchmove",this.handleDrag),document.removeEventListener("mouseup",this.handleMouseup,!0),document.removeEventListener("touchend",this.handleMouseup,!0),document.removeEventListener("touchcancel",this.handleMouseup,!0)}startDragging(t,e,i){t.preventDefault(),this.img=e,this.dragBox=i,t.type==="touchstart"?(this.startX=t.changedTouches[0].clientX,this.startY=t.changedTouches[0].clientY):(this.startX=t.clientX,this.startY=t.clientY),this.startWidth=e.width||e.naturalWidth,this.startHeight=e.height||e.naturalHeight,this.addEventListeners()}handleDrag(t){if(!this.img)return;let e,i;t.type==="touchmove"?(e=t.changedTouches[0].clientX,i=t.changedTouches[0].clientY):(e=t.clientX,i=t.clientY);let n=e-this.startX,a=i-this.startY,u=this.startWidth/this.startHeight;const p=t.ctrlKey,g=t.shiftKey,m=t.altKey;if(p){let s=this.startWidth+n,o=this.startHeight+a;s=Math.max(s,this.minWidth),o=Math.max(o,this.minHeight),this.img.width=Math.round(s),this.img.height=Math.round(o)}else if(g){let s=this.startHeight+a;s=Math.max(s,this.minHeight),this.img.height=Math.round(s)}else if(m){let s=this.startWidth+n;s=Math.max(s,this.minWidth),this.img.width=Math.round(s)}else{const s=Math.abs(n)>Math.abs(a)?n:a;let o=this.startWidth+s,d=o/u;o=Math.max(o,this.minWidth),d=Math.max(d,this.minHeight),this.img.width=Math.round(o),this.img.height=Math.round(d)}this.overlayManager&&this.overlayManager.reposition(this.img),this.displaySizeManager&&this.displaySizeManager.update(),this.tooltipInfoManager&&this.tooltipInfoManager.update(),this.startX=e,this.startY=i,this.startWidth=this.img.offsetWidth,this.startHeight=this.img.offsetHeight}handleMouseup(){this.removeEventListeners(),this.img=null,this.dragBox=null}destroy(){this.removeEventListeners(),this.img=null,this.dragBox=null,this.overlayManager=null,this.displaySizeManager=null,this.tooltipInfoManager=null}}class x{constructor(t,e){this.overlay=t,this.img=e,this.display=null}create(){this.display=document.createElement("div"),Object.assign(this.display.style,h.displaySizeStyles),this.overlay.appendChild(this.display),this.update()}update(){if(!this.display||!this.img)return;const t=this.img.offsetWidth,e=this.img.offsetHeight;this.display.innerHTML=`${t} × ${e}`;const i=this.display.getBoundingClientRect();t>120&&e>30?Object.assign(this.display.style,h.displaySizePositionStyles):Object.assign(this.display.style,{right:`-${i.width+4}px`,bottom:"0",left:"auto"})}remove(){this.display&&(this.display.remove(),this.display=null,this.overlay=null,this.img=null)}}class b{constructor(t){this.overlay=t,this.icon=null,this.tooltip=null,this.handleMouseEnter=this.handleMouseEnter.bind(this),this.handleMouseLeave=this.handleMouseLeave.bind(this)}create(){this.icon=document.createElement("div"),this.icon.textContent="?",Object.assign(this.icon.style,h.tooltip.iconStyles),this.tooltip=document.createElement("div"),this.tooltip.textContent=`Shift for vertical
|
|
2
|
-
Ctrl for custom
|
|
3
|
-
Alt for horizontal`,Object.assign(this.tooltip.style,{...h.tooltip.textStyles}),this.icon.addEventListener("mouseenter",this.handleMouseEnter),this.icon.addEventListener("mouseleave",this.handleMouseLeave),this.overlay.appendChild(this.icon),this.overlay.appendChild(this.tooltip),this.update()}handleMouseEnter(){this.tooltip&&(this.tooltip.style.display="block")}handleMouseLeave(){this.tooltip&&(this.tooltip.style.display="none")}update(){if(!this.icon||!this.tooltip)return;const t=this.icon.getBoundingClientRect(),e=this.icon.offsetTop+25,i=t.left-100;Object.assign(this.tooltip.style,{top:`${e}px`,left:`${i}px`})}remove(){!this.icon&&!this.tooltip||(this.icon&&(this.icon.removeEventListener("mouseenter",this.handleMouseEnter),this.icon.removeEventListener("mouseleave",this.handleMouseLeave),this.icon.remove(),this.icon=null),this.tooltip&&(this.tooltip.remove(),this.tooltip=null),this.overlay=null)}}const C=".no-selection::selection{background:transparent!important}",E=l=>{if(typeof document>"u")return;const t=document.createElement("style");t.textContent=l,document.head.appendChild(t)};E(C);class L extends y.Module{constructor(t,e={}){super(t,e),this.quill=t,this.options={helpIcon:!0,displaySize:!0,styleSelection:!0,...h,...e},this.img=null,this.overlayManager=new v(this.quill.root.parentNode,this.options.overlayStyles),this.dragController=new S(this.options.minWidth,this.options.minHeight,this.overlayManager,null,null),this.imageFormat=this.quill.constructor.import("formats/image"),this.bindHandlers(),this.addEventListeners()}bindHandlers(){this.handleClick=this.handleClick.bind(this),this.handleSelectionChange=this.handleSelectionChange.bind(this),this.handleTextChange=this.handleTextChange.bind(this),this.handleMousedown=this.handleMousedown.bind(this)}addEventListeners(){this.quill.root.addEventListener("click",this.handleClick),this.quill.on("selection-change",this.handleSelectionChange),this.quill.on("text-change",this.handleTextChange)}removeEventListeners(){this.quill.root.removeEventListener("click",this.handleClick),this.quill.off("selection-change",this.handleSelectionChange),this.quill.off("text-change",this.handleTextChange)}handleClick(t){if(t.target instanceof HTMLImageElement){const e=this.quill.constructor.find(t.target);e&&(this.quill.setSelection(e.offset(this.quill.scroll),e.length(),"silent"),this.show(t.target),this.disableTextSelection())}}handleSelectionChange(t){if(!t)return this.hide();const[e]=this.quill.scroll.descendant(this.quill.constructor.import("formats/image"),t.index);e&&e.domNode instanceof HTMLImageElement?(this.disableTextSelection(),this.show(e.domNode)):(this.enableTextSelection(),this.hide())}disableTextSelection(){this.options.styleSelection&&this.quill.root.classList.add(this.options.noSelectionClass)}enableTextSelection(){this.options.styleSelection&&this.quill.root.classList.remove(this.options.noSelectionClass)}handleTextChange(){this.img&&(this.quill.root.contains(this.img)?(this.overlayManager.reposition(this.img),this.displaySizeManager&&this.displaySizeManager.update(),this.tooltipInfoManager&&this.tooltipInfoManager.update()):(this.hide(),this.enableTextSelection()))}show(t){this.img!==t&&(!t||!(t instanceof HTMLImageElement)||(this.hide(),this.img=t,this.overlayManager.overlay||this.overlayManager.create(),this.handleManager=new M(this.overlayManager.overlay,this.options.positions,this.options.handleStyles,this.handleMousedown),this.handleManager.createHandles(),this.overlayManager.reposition(this.img),this.options.displaySize&&(this.displaySizeManager=new x(this.overlayManager.overlay,this.img),this.displaySizeManager.create(),this.dragController.setDisplaySizeManager(this.displaySizeManager)),this.options.helpIcon&&(this.tooltipInfoManager=new b(this.overlayManager.overlay),this.tooltipInfoManager.create(),this.dragController.setTooltipInfoManager(this.tooltipInfoManager))))}hide(){this.dragController.setDisplaySizeManager(null),this.dragController.setTooltipInfoManager(null),this.handleManager&&this.handleManager.removeHandles(),this.overlayManager.remove(),this.displaySizeManager&&this.displaySizeManager.remove(),this.displaySizeManager=null,this.tooltipInfoManager&&(this.tooltipInfoManager.remove(),this.tooltipInfoManager=null),this.img=null}handleMousedown(t){t.target instanceof HTMLElement&&this.dragController.startDragging(t,this.img,t.target)}destroy(){this.removeEventListeners(),this.hide(),this.dragController?.destroy(),this.dragController=null}}module.exports=L;
|
|
1
|
+
let e=require(`quill`);var t=`#AED2FF`,n=`#687EFF`,r=`#fff`,i={minWidth:16,minHeight:16,noSelectionClass:`no-selection`,handleStyles:{position:`absolute`,width:`15px`,height:`15px`,backgroundColor:t,border:`1px solid ${n}`},overlayStyles:{position:`absolute`,boxSizing:`border-box`,border:`1px dashed #777`,zIndex:8},positions:[{top:0,left:0,clipPath:`polygon(0% 0%, 100% 0%, 0% 100%)`},{top:0,right:0,clipPath:`polygon(100% 0%, 0% 0%, 100% 100%)`},{bottom:0,left:0,clipPath:`polygon(0% 100%, 100% 100%, 0% 0%)`},{bottom:0,right:0,clipPath:`polygon(100% 100%, 0% 100%, 100% 0%)`}],displaySizeStyles:{position:`absolute`,fontSize:`12px`,backgroundColor:t,color:r,padding:`2px 4px`,borderRadius:`4px`,userSelect:`none`,pointerEvents:`none`},displaySizePositionStyles:{right:`20px`,bottom:`5px`,left:`auto`},tooltip:{iconStyles:{position:`absolute`,top:`8px`,right:`8px`,width:`20px`,height:`20px`,background:t,color:r,borderRadius:`50%`,textAlign:`center`,lineHeight:`20px`,fontSize:`14px`,cursor:`pointer`,userSelect:`none`},textStyles:{position:`absolute`,background:t,color:r,padding:`6px 8px`,borderRadius:`4px`,display:`none`,pointerEvents:`none`,fontSize:`12px`,whiteSpace:`pre`}}},a=class{constructor(e,t){this.parent=e,this.styles=t,this.overlay=null}create(){this.overlay=document.createElement(`div`),Object.assign(this.overlay.style,this.styles),this.parent.appendChild(this.overlay)}remove(){this.overlay&&=(this.overlay.remove(),null)}reposition(e){if(!this.overlay)return;let t=e.getBoundingClientRect(),n=this.overlay.offsetParent||this.parent,r=n.getBoundingClientRect();Object.assign(this.overlay.style,{left:`${t.left-r.left-1+n.scrollLeft}px`,top:`${t.top-r.top+n.scrollTop}px`,width:`${t.width}px`,height:`${t.height}px`})}},o=class{constructor(e,t,n,r){this.overlay=e,this.positions=t,this.handleStyles=n,this.mousedownCallback=r,this.boxes=[]}createHandles(){this.positions.forEach(e=>{let t=document.createElement(`div`);Object.assign(t.style,this.handleStyles,e),t.style.clipPath=e.clipPath;let n=e.top!==void 0&&e.left!==void 0||e.bottom!==void 0&&e.right!==void 0;t.style.cursor=n?`nwse-resize`:`nesw-resize`,t.addEventListener(`mousedown`,this.mousedownCallback,!1),t.addEventListener(`touchstart`,this.mousedownCallback,{passive:!1}),this.overlay.appendChild(t),this.boxes.push(t)})}removeHandles(){this.boxes.forEach(e=>{e.removeEventListener(`mousedown`,this.mousedownCallback),e.removeEventListener(`touchstart`,this.mousedownCallback),e.onmousedown=null,e.ontouchstart=null,e.remove()}),this.boxes=[],this.overlay=null,this.positions=null,this.handleStyles=null,this.mousedownCallback=null}},s=class{constructor(e,t,n,r,i){this.minWidth=e,this.minHeight=t,this.overlayManager=n,this.displaySizeManager=r,this.tooltipInfoManager=i,this.img=null,this.dragBox=null,this.startX=0,this.startY=0,this.startWidth=0,this.startHeight=0,this.handleDrag=this.handleDrag.bind(this),this.handleMouseup=this.handleMouseup.bind(this)}setDisplaySizeManager(e){this.displaySizeManager=e}setTooltipInfoManager(e){this.tooltipInfoManager=e}addEventListeners(){document.addEventListener(`mousemove`,this.handleDrag),document.addEventListener(`touchmove`,this.handleDrag,{passive:!1}),document.addEventListener(`mouseup`,this.handleMouseup,!0),document.addEventListener(`touchend`,this.handleMouseup,!0),document.addEventListener(`touchcancel`,this.handleMouseup,!0)}removeEventListeners(){document.removeEventListener(`mousemove`,this.handleDrag),document.removeEventListener(`touchmove`,this.handleDrag),document.removeEventListener(`mouseup`,this.handleMouseup,!0),document.removeEventListener(`touchend`,this.handleMouseup,!0),document.removeEventListener(`touchcancel`,this.handleMouseup,!0)}startDragging(e,t,n){if(e.preventDefault(),this.img=t,this.dragBox=n,e.type===`touchstart`){if(!e.changedTouches.length)return;this.startX=e.changedTouches[0].clientX,this.startY=e.changedTouches[0].clientY}else this.startX=e.clientX,this.startY=e.clientY;this.startWidth=t.width||t.naturalWidth,this.startHeight=t.height||t.naturalHeight,this.addEventListeners()}handleDrag(e){if(!this.img)return;let t,n;if(e.type===`touchmove`){if(!e.changedTouches.length)return;t=e.changedTouches[0].clientX,n=e.changedTouches[0].clientY}else t=e.clientX,n=e.clientY;let r=t-this.startX,i=n-this.startY,a=this.startHeight===0?1:this.startWidth/this.startHeight,o=e.ctrlKey,s=e.shiftKey,c=e.altKey;if(o){let e=this.startWidth+r,t=this.startHeight+i;e=Math.max(e,this.minWidth),t=Math.max(t,this.minHeight),this.img.width=Math.round(e),this.img.height=Math.round(t)}else if(s){let e=this.startHeight+i;e=Math.max(e,this.minHeight),this.img.height=Math.round(e)}else if(c){let e=this.startWidth+r;e=Math.max(e,this.minWidth),this.img.width=Math.round(e)}else{let e=Math.abs(r)>Math.abs(i)?r:i,t=this.startWidth+e,n=t/a;t=Math.max(t,this.minWidth),n=Math.max(n,this.minHeight),this.img.width=Math.round(t),this.img.height=Math.round(n)}this.overlayManager&&this.overlayManager.reposition(this.img),this.displaySizeManager&&this.displaySizeManager.update(),this.tooltipInfoManager&&this.tooltipInfoManager.update(),this.startX=t,this.startY=n,this.startWidth=this.img.offsetWidth,this.startHeight=this.img.offsetHeight}handleMouseup(){this.removeEventListeners(),this.img=null,this.dragBox=null}destroy(){this.removeEventListeners(),this.img=null,this.dragBox=null,this.overlayManager=null,this.displaySizeManager=null,this.tooltipInfoManager=null}},c=class{constructor(e,t,n){this.overlay=e,this.img=t,this.displaySizeStyles=n,this.display=null}create(){this.display=document.createElement(`div`),Object.assign(this.display.style,this.displaySizeStyles),this.overlay.appendChild(this.display),this.update()}update(){if(!this.display||!this.img)return;let e=this.img.offsetWidth,t=this.img.offsetHeight;this.display.textContent=`${e} × ${t}`;let n=this.display.getBoundingClientRect();e>120&&t>30?Object.assign(this.display.style,i.displaySizePositionStyles):Object.assign(this.display.style,{right:`-${n.width+4}px`,bottom:`0`,left:`auto`})}remove(){this.display&&(this.display.remove(),this.display=null,this.overlay=null,this.img=null)}},l=class{constructor(e){this.overlay=e,this.icon=null,this.tooltip=null,this.handleMouseEnter=this.handleMouseEnter.bind(this),this.handleMouseLeave=this.handleMouseLeave.bind(this)}create(){this.icon=document.createElement(`div`),this.icon.textContent=`?`,Object.assign(this.icon.style,i.tooltip.iconStyles),this.tooltip=document.createElement(`div`);let e=this.tooltip;[`Shift for vertical`,`Ctrl for custom`,`Alt for horizontal`].forEach(t=>{let n=document.createElement(`span`);n.textContent=t,n.style.display=`block`,e.appendChild(n)}),Object.assign(this.tooltip.style,i.tooltip.textStyles),this.icon.addEventListener(`mouseenter`,this.handleMouseEnter),this.icon.addEventListener(`mouseleave`,this.handleMouseLeave),this.overlay.appendChild(this.icon),this.overlay.appendChild(this.tooltip),this.update()}handleMouseEnter(){this.tooltip&&(this.tooltip.style.display=`block`)}handleMouseLeave(){this.tooltip&&(this.tooltip.style.display=`none`)}update(){if(!this.icon||!this.tooltip)return;let e=this.icon.offsetTop+25,t=this.icon.offsetLeft-100;Object.assign(this.tooltip.style,{top:`${e}px`,left:`${t}px`})}remove(){!this.icon&&!this.tooltip||(this.icon&&=(this.icon.removeEventListener(`mouseenter`,this.handleMouseEnter),this.icon.removeEventListener(`mouseleave`,this.handleMouseLeave),this.icon.remove(),null),this.tooltip&&=(this.tooltip.remove(),null),this.overlay=null)}},u=class{constructor(e,t){this.options=t,this.img=null,this._showing=!1,this.overlayManager=new a(e,t.overlayStyles),this.dragController=new s(t.minWidth,t.minHeight,this.overlayManager,null,null),this.handleMousedown=this.handleMousedown.bind(this)}show(e){this.img!==e&&(!e||!(e instanceof HTMLImageElement)||(this._showing||=(this._showing=!0,this.hide(),this.img=e,this.overlayManager?.overlay||this.overlayManager?.create(),this.handleManager=new o(this.overlayManager?.overlay,this.options.positions,this.options.handleStyles,this.handleMousedown),this.handleManager.createHandles(),this.overlayManager?.reposition(this.img),this.options.displaySize&&(this.displaySizeManager=new c(this.overlayManager?.overlay,this.img,this.options.displaySizeStyles),this.displaySizeManager.create(),this.dragController?.setDisplaySizeManager(this.displaySizeManager)),this.options.helpIcon&&(this.tooltipInfoManager=new l(this.overlayManager?.overlay),this.tooltipInfoManager.create(),this.dragController?.setTooltipInfoManager(this.tooltipInfoManager)),!1)))}hide(){this.dragController?.setDisplaySizeManager(null),this.dragController?.setTooltipInfoManager(null),this.handleManager&&this.handleManager.removeHandles(),this.overlayManager?.remove(),this.displaySizeManager&&this.displaySizeManager.remove(),this.displaySizeManager=null,this.tooltipInfoManager&&=(this.tooltipInfoManager.remove(),null),this.img=null}update(){this.overlayManager?.reposition(this.img),this.displaySizeManager&&this.displaySizeManager.update(),this.tooltipInfoManager&&this.tooltipInfoManager.update()}handleMousedown(e){e.target instanceof HTMLElement&&this.dragController?.startDragging(e,this.img,e.target)}destroy(){this.hide(),this.dragController?.destroy(),this.dragController=null,this.overlayManager=null}};(()=>{if(typeof document>`u`)return;let e=document.createElement(`style`);e.textContent=`.no-selection::selection { background: transparent !important; }`,document.head.appendChild(e)})();var d=class extends e.Module{constructor(e,t={}){super(e,t),this.quill=e,this.options={helpIcon:!0,displaySize:!0,styleSelection:!0,...i,...t,overlayStyles:{...i.overlayStyles,...t.overlayStyles},handleStyles:{...i.handleStyles,...t.handleStyles},displaySizeStyles:{...i.displaySizeStyles,...t.displaySizeStyles}};let n=this.quill.root.parentNode;if(!n)throw Error(`ImageResize: quill.root has no parentNode`);this.uiController=new u(n,this.options),this.bindHandlers(),this.addEventListeners()}bindHandlers(){this.handleClick=this.handleClick.bind(this),this.handleSelectionChange=this.handleSelectionChange.bind(this),this.handleTextChange=this.handleTextChange.bind(this)}addEventListeners(){this.quill.root.addEventListener(`click`,this.handleClick),this.quill.on(`selection-change`,this.handleSelectionChange),this.quill.on(`text-change`,this.handleTextChange)}removeEventListeners(){this.quill.root.removeEventListener(`click`,this.handleClick),this.quill.off(`selection-change`,this.handleSelectionChange),this.quill.off(`text-change`,this.handleTextChange)}handleClick(e){if(e.target instanceof HTMLImageElement){let t=this.quill.constructor.find(e.target);t&&(this.quill.setSelection(t.offset(this.quill.scroll),t.length(),`silent`),this.show(e.target),this.disableTextSelection())}}handleSelectionChange(e){if(!e)return this.hide();let[t]=this.quill.scroll.descendant(this.quill.constructor.import(`formats/image`),e.index);t&&t.domNode instanceof HTMLImageElement?(this.disableTextSelection(),this.show(t.domNode)):(this.enableTextSelection(),this.hide())}handleTextChange(){let e=this.uiController?.img;e&&(e&&!this.quill.root.contains(e)?(this.hide(),this.enableTextSelection()):this.uiController?.update())}disableTextSelection(){this.options.styleSelection&&this.quill.root.classList.add(this.options.noSelectionClass)}enableTextSelection(){this.options.styleSelection&&this.quill.root.classList.remove(this.options.noSelectionClass)}show(e){this.uiController?.show(e)}hide(){this.uiController?.hide()}destroy(){this.removeEventListeners(),this.uiController?.destroy(),this.uiController=null,this.quill=null}};module.exports=d;
|