editorjs-image 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,896 +0,0 @@
1
- // Class for Editor.js
2
- // Adds Block Tunes for Image Tool (ImageTool)
3
- // Supports : Image Float Left, Image float right
4
-
5
- import './image-tool-tune.css';
6
-
7
- import Cropper from './cropper.js';
8
- import './cropper.css';
9
-
10
- export default class {
11
-
12
-
13
- constructor( { api, data, config, block } ) {
14
-
15
- this.settings = [
16
- {
17
- name: 'floatLeft',
18
- icon: '<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M952 792H72c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h880c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0-632H72c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h880c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM608 660c8.8 0 16-7.2 16-16V380c0-8.8-7.2-16-16-16H96c-8.8 0-16 7.2-16 16v264c0 8.8 7.2 16 16 16h512zM152 436h400v152H152V436zm552 210c0 4.4 3.6 8 8 8h224c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H712c-4.4 0-8 3.6-8 8v56zm8-204h224c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H712c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8z"></path></svg>',
19
- label: '',
20
- group: 'align',
21
- }, {
22
- name: 'center',
23
- icon: '<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M952 792H72c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h880c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0-632H72c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h880c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM848 660c8.8 0 16-7.2 16-16V380c0-8.8-7.2-16-16-16H176c-8.8 0-16 7.2-16 16v264c0 8.8 7.2 16 16 16h672zM232 436h560v152H232V436z"></path></svg>',
24
- label: '',
25
- group: 'align',
26
- }, {
27
- name: 'floatRight',
28
- icon: '<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M952 792H72c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h880c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0-632H72c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h880c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm-24 500c8.8 0 16-7.2 16-16V380c0-8.8-7.2-16-16-16H416c-8.8 0-16 7.2-16 16v264c0 8.8 7.2 16 16 16h512zM472 436h400v152H472V436zM80 646c0 4.4 3.6 8 8 8h224c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H88c-4.4 0-8 3.6-8 8v56zm8-204h224c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H88c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8z"></path></svg>',
29
- label: '',
30
- group: 'align',
31
- },
32
- {
33
- name: 'sizeSmall',
34
- icon: '<svg stroke="currentColor" fill="none" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 6V4H20V20H12V18H8V16H4V8H8V6H12ZM14 6H18V18H14V6ZM12 8H10V16H12V8ZM8 10V14H6V10H8Z" fill="currentColor"></path></svg>',
35
- label: '50%',
36
- group: 'size',
37
- }, {
38
- name: 'sizeMiddle',
39
- icon: '<svg stroke="currentColor" fill="none" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 6V4H20V20H12V18H8V16H4V8H8V6H12ZM14 6H18V18H14V6ZM12 8H10V16H12V8ZM8 10V14H6V10H8Z" fill="currentColor"></path></svg>',
40
- label: '70%',
41
- group: 'size',
42
- }, {
43
- name: 'sizeLarge',
44
- icon: '<svg stroke="currentColor" fill="none" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 6V4H20V20H12V18H8V16H4V8H8V6H12ZM14 6H18V18H14V6ZM12 8H10V16H12V8ZM8 10V14H6V10H8Z" fill="currentColor"></path></svg>',
45
- label: '100%',
46
- group: 'size',
47
- }, {
48
- name: 'resize',
49
- icon: '<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M29 30l1 90h36V66h26V30H29zm99 0v36h72V30h-72zm108 0v36h72V30h-72zm108 0v36h72V30h-72zm102 0v78h36V30h-36zm-206 80v36h100.543l-118 118H30v218h218V289.457l118-118V272h36V110H240zm206 34v72h36v-72h-36zM30 156v72h36v-72H30zm416 96v72h36v-72h-36zm0 108v72h36v-72h-36zm-166 86v36h72v-36h-72zm108 0v36h72v-36h-72z"></path></svg>',
50
- label: '',
51
- group: 'size',
52
- }, {
53
- name: 'crop',
54
- icon: '<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M21 15h2v2h-2v-2zm0-4h2v2h-2v-2zm2 8h-2v2c1 0 2-1 2-2zM13 3h2v2h-2V3zm8 4h2v2h-2V7zm0-4v2h2c0-1-1-2-2-2zM1 7h2v2H1V7zm16-4h2v2h-2V3zm0 16h2v2h-2v-2zM3 3C2 3 1 4 1 5h2V3zm6 0h2v2H9V3zM5 3h2v2H5V3zm-4 8v8c0 1.1.9 2 2 2h12V11H1zm2 8l2.5-3.21 1.79 2.15 2.5-3.22L13 19H3z"></path></svg>',
55
- label: '',
56
- group: 'size',
57
- }
58
- ];
59
-
60
- this.api = api;
61
- this.block = block;
62
- this.config = config;
63
- this.data = {
64
- floatLeft: data !== undefined && data.floatLeft !== undefined ? data.floatLeft : false,
65
- floatRight: data !== undefined && data.floatRight !== undefined ? data.floatRight : false,
66
- center: data !== undefined && data.center !== undefined ? data.center : false,
67
- sizeSmall: data !== undefined && data.sizeSmall !== undefined ? data.sizeSmall : false,
68
- sizeMiddle: data !== undefined && data.sizeMiddle !== undefined ? data.sizeMiddle : false,
69
- sizeLarge: data !== undefined && data.sizeLarge !== undefined ? data.sizeLarge : false,
70
- resize: data !== undefined && data.resize !== undefined ? data.resize : false,
71
- resizeSize: data !== undefined && data.resizeSize !== undefined ? data.resizeSize : 0,
72
- crop: data !== undefined && data.crop !== undefined ? data.crop : false,
73
- cropperFrameHeight: data !== undefined && data.cropperFrameHeight !== undefined ? data.cropperFrameHeight : 0,
74
- cropperFrameWidth: data !== undefined && data.cropperFrameWidth !== undefined ? data.cropperFrameWidth : 0,
75
- cropperFrameLeft: data !== undefined && data.cropperFrameLeft !== undefined ? data.cropperFrameLeft : 0,
76
- cropperFrameTop: data !== undefined && data.cropperFrameTop !== undefined ? data.cropperFrameTop : 0,
77
- cropperImageHeight: data !== undefined && data.cropperImageHeight !== undefined ? data.cropperImageHeight : 0,
78
- cropperImageWidth: data !== undefined && data.cropperImageWidth !== undefined ? data.cropperImageWidth : 0,
79
- cropperInterface: undefined,
80
- };
81
- this.wrapper = undefined;
82
-
83
- this.buttons = [];
84
-
85
- }
86
-
87
- static get isTune() {
88
- return true;
89
- }
90
-
91
- static get sanitize() {
92
- return {
93
- floatLeft: {},
94
- floatRight: {},
95
- center: {},
96
- sizeSmall: {},
97
- sizeMiddle: {},
98
- sizeLarge: {},
99
- resize: {},
100
- resizeSize: {},
101
- crop: {},
102
- cropperFrameHeight: {},
103
- cropperFrameWidth: {},
104
- cropperFrameLeft: {},
105
- cropperFrameTop: {},
106
- cropperImageHeight: {},
107
- cropperImageWidth: {},
108
- cropperInterface: {},
109
- };
110
- }
111
-
112
- /**
113
- * CSS classes
114
- * @return {object}
115
- * @constructor
116
- * @property {string} CSS.wrapper - wrapper for buttons
117
- * @property {string} CSS.button - button
118
- * @property {string} CSS.buttonActive - active button
119
- * @property {string} CSS.buttonModifier - button with modifier
120
- * @property {string} CSS.buttonModifierActive - active button with modifier
121
- */
122
- get CSS() {
123
- return {
124
- wrapper: 'cdx-image-tool-tune',
125
- button: this.api.styles.settingsButton,
126
- buttonActive: this.api.styles.settingsButtonActive,
127
- buttonModifier: this.api.styles.settingsButtonModifier,
128
- buttonModifierActive: this.api.styles.settingsButtonModifierActive,
129
- isFloatLeft: 'cdx-image-tool-tune--floatLeft',
130
- isFloatRight: 'cdx-image-tool-tune--floatRight',
131
- isCenter: 'cdx-image-tool-tune--center',
132
- isSizeSmall: 'cdx-image-tool-tune--sizeSmall',
133
- isSizeMiddle: 'cdx-image-tool-tune--sizeMiddle',
134
- isSizeLarge: 'cdx-image-tool-tune--sizeLarge',
135
- isResize: 'cdx-image-tool-tune--resize',
136
- isCrop: 'cdx-image-tool-tune--crop',
137
- };
138
- }
139
-
140
- /**
141
- *
142
- * @return {HTMLElement}
143
- * @public
144
- * @readonly
145
- * @property {HTMLElement} wrapper - tune buttons wrapper
146
- */
147
- get view() {
148
- if ( !this.wrapper ) {
149
- this.wrapper = this.createView();
150
- }
151
-
152
- return this.wrapper;
153
- }
154
-
155
- /**
156
- * Clicks to one of the tunes
157
- * @param {MouseEvent} e - click
158
- * @param {HTMLElement} tune - clicked tune button
159
- * @private
160
- * @return {void}
161
- * */
162
- tuneClicked( e, tune ) {
163
- e.preventDefault();
164
- e.stopPropagation();
165
-
166
-
167
- let tuneName = tune.dataset.tune;
168
-
169
- let tuneGroup = this.settings.find( tune => tune.name === tuneName ).group;
170
-
171
-
172
- this.buttons.forEach( button => {
173
-
174
- //if is the same group
175
- if ( this.settings.find( tune => tune.name === button.dataset.tune ).group === tuneGroup ) {
176
- if ( button !== tune ) {
177
- button.classList.remove( this.CSS.buttonActive );
178
- }
179
- }
180
- } );
181
-
182
- tune.classList.toggle( this.CSS.buttonActive );
183
-
184
-
185
- this.setTune( tune.dataset.tune );
186
- }
187
-
188
- /**
189
- * Styles the image with a tune
190
- * @param {string} tune - tune name
191
- * @private
192
- * @return {void}
193
- * */
194
- setTune( tune ) {
195
- switch ( tune ) {
196
- case 'floatLeft':
197
- this.data.floatLeft = !this.data.floatLeft;
198
- this.data.floatRight = false;
199
- this.data.center = false;
200
- break;
201
- case 'floatRight':
202
- this.data.floatLeft = false;
203
- this.data.floatRight = !this.data.floatRight;
204
- this.data.center = false;
205
- break;
206
- case 'center':
207
- this.data.center = !this.data.center;
208
- this.data.floatLeft = false;
209
- this.data.floatRight = false;
210
- break;
211
- case 'sizeSmall':
212
- this.data.sizeSmall = !this.data.sizeSmall;
213
- this.data.sizeMiddle = false;
214
- this.data.sizeLarge = false;
215
- this.data.resize = false;
216
- this.data.crop = false;
217
- break;
218
- case 'sizeMiddle':
219
- this.data.sizeSmall = false;
220
- this.data.sizeMiddle = !this.data.sizeMiddle;
221
- this.data.sizeLarge = false;
222
- this.data.resize = false;
223
- this.data.crop = false;
224
- break;
225
- case 'sizeLarge':
226
- this.data.sizeSmall = false;
227
- this.data.sizeMiddle = false;
228
- this.data.sizeLarge = !this.data.sizeLarge;
229
- this.data.resize = false;
230
- this.data.crop = false;
231
- break;
232
- case 'resize':
233
- this.data.sizeSmall = false;
234
- this.data.sizeMiddle = false;
235
- this.data.sizeLarge = false;
236
- this.data.resize = !this.data.resize;
237
- this.data.crop = false;
238
- break;
239
- case 'crop':
240
- this.data.crop = !this.data.crop;
241
- this.data.sizeSmall = false;
242
- this.data.sizeMiddle = false;
243
- this.data.sizeLarge = false;
244
- this.data.resize = false;
245
- this.data.resizeSize = 0;
246
- break;
247
- default:
248
- this.data.floatLeft = false;
249
- this.data.floatRight = false;
250
- this.data.sizeSmall = false;
251
- this.data.sizeMiddle = false;
252
- this.data.sizeLarge = false;
253
- this.data.resize = false;
254
- this.data.crop = false;
255
- break;
256
- }
257
-
258
- if ( !this.data.resize ) {
259
- this.data.resizeSize = 0;
260
- }
261
-
262
- if ( !this.data.crop ) {
263
- this.data.cropperFrameHeight = 0;
264
- this.data.cropperFrameWidth = 0;
265
- this.data.cropperFrameLeft = 0;
266
- this.data.cropperFrameTop = 0;
267
- this.data.cropperImageHeight = 0;
268
- this.data.cropperImageWidth = 0;
269
- }
270
-
271
- const blockContent = this.block.holder.querySelector( '.ce-block__content' );
272
-
273
- this.apply( blockContent );
274
-
275
- this.block.dispatchChange();
276
-
277
-
278
-
279
- }
280
-
281
-
282
- /**
283
- * Append class to block by tune data
284
- * @param {HTMLElement} blockContent - wrapper for block content
285
- * @public
286
- * @return {void}
287
- * */
288
- apply( blockContent ) {
289
-
290
-
291
- if ( this.data.floatLeft ) {
292
- blockContent.classList.add( this.CSS.isFloatLeft );
293
- } else {
294
- blockContent.classList.remove( this.CSS.isFloatLeft );
295
- }
296
-
297
- if ( this.data.floatRight ) {
298
- blockContent.classList.add( this.CSS.isFloatRight );
299
- } else {
300
- blockContent.classList.remove( this.CSS.isFloatRight );
301
- }
302
-
303
- if ( this.data.center ) {
304
- blockContent.classList.add( this.CSS.isCenter );
305
- } else {
306
- blockContent.classList.remove( this.CSS.isCenter );
307
- }
308
-
309
- if ( this.data.sizeSmall ) {
310
- blockContent.classList.add( this.CSS.isSizeSmall );
311
- } else {
312
- blockContent.classList.remove( this.CSS.isSizeSmall );
313
- }
314
-
315
- if ( this.data.sizeMiddle ) {
316
- blockContent.classList.add( this.CSS.isSizeMiddle );
317
- } else {
318
- blockContent.classList.remove( this.CSS.isSizeMiddle );
319
- }
320
-
321
- if ( this.data.sizeLarge ) {
322
- blockContent.classList.add( this.CSS.isSizeLarge );
323
- } else {
324
- blockContent.classList.remove( this.CSS.isSizeLarge );
325
- }
326
-
327
- if ( this.data.resize ) {
328
- blockContent.classList.add( this.CSS.isResize );
329
-
330
- if ( this.data.resizeSize > 0 ) {
331
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].style.width = this.data.resizeSize + 'px';
332
- }
333
-
334
- this.resize( blockContent );
335
- } else {
336
- blockContent.classList.remove( this.CSS.isResize );
337
- this.unresize( blockContent );
338
- }
339
-
340
- if ( this.data.crop ) {
341
- blockContent.classList.add( this.CSS.isCrop );
342
-
343
- this.crop( blockContent );
344
- if ( this.data.cropperFrameHeight > 0 && this.data.cropperFrameWidth > 0 ) {
345
- this.applyCrop( blockContent );
346
- }
347
-
348
-
349
- } else {
350
- blockContent.classList.remove( this.CSS.isCrop );
351
- this.uncrop( blockContent );
352
- }
353
-
354
-
355
-
356
-
357
- }
358
-
359
-
360
-
361
-
362
- /**
363
- * Add crop handles to image
364
- * @param {HTMLCollection} images - images in block
365
- * @public
366
- * @return {void}
367
- */
368
- crop( blockContent ) {
369
-
370
- //this.appendCrop( blockContent );
371
-
372
-
373
-
374
- //add append crop button to image-tool__image
375
- const image = blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ];
376
- const cropBtn = document.createElement( 'div' );
377
- cropBtn.classList.add( 'crop-btn', 'btn-crop-action' );
378
- cropBtn.innerHTML = 'Crop';
379
-
380
- cropBtn.addEventListener( 'click', e => {
381
- //remove crop button
382
- image.removeChild( cropBtn );
383
- this.appendCrop( blockContent );
384
- }
385
- );
386
-
387
- image.appendChild( cropBtn );
388
-
389
- }
390
-
391
-
392
- appendCrop( blockContent ) {
393
- this.uncrop( blockContent );
394
- const image = blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].getElementsByTagName( 'img' )[ 0 ];
395
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].classList.add( 'isCropping' );
396
- this.cropperInterface = new Cropper( image, {
397
- crop( event ) {
398
- console.log( event.detail.x );
399
- console.log( event.detail.y );
400
- console.log( event.detail.width );
401
- console.log( event.detail.height );
402
- console.log( event.detail.scaleX );
403
- console.log( event.detail.scaleY );
404
-
405
-
406
- },
407
- } );
408
-
409
-
410
- //append save crop button
411
- const cropSaveBtn = document.createElement( 'div' );
412
- cropSaveBtn.classList.add( 'crop-save', 'btn-crop-action' );
413
-
414
- cropSaveBtn.innerHTML = 'Apply';
415
-
416
- cropSaveBtn.addEventListener( 'click', e => {
417
-
418
- console.log( this.cropperInterface.getCropBoxData() );
419
- console.log( this.cropperInterface.getImageData() );
420
- console.log( this.cropperInterface.getCanvasData() );
421
-
422
-
423
- this.data.cropperFrameHeight = this.cropperInterface.getCropBoxData().height;
424
- this.data.cropperFrameWidth = this.cropperInterface.getCropBoxData().width;
425
- this.data.cropperFrameLeft = this.cropperInterface.getCanvasData().left - this.cropperInterface.getCropBoxData().left;
426
- this.data.cropperFrameTop = this.cropperInterface.getCanvasData().top - this.cropperInterface.getCropBoxData().top;
427
- this.data.cropperImageHeight = this.cropperInterface.getImageData().height;
428
- this.data.cropperImageWidth = this.cropperInterface.getImageData().width;
429
-
430
- this.applyCrop( blockContent );
431
-
432
- }
433
- );
434
-
435
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].appendChild( cropSaveBtn );
436
-
437
- //add temporary style to block content so that it comes in front of every other block
438
- blockContent.classList.add( 'isCropping' );
439
-
440
- }
441
-
442
-
443
- applyCrop( blockContent ) {
444
-
445
- //apply data to image and remove cropper interface and save button, add crop button
446
-
447
- const image = blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].getElementsByTagName( 'img' )[ 0 ];
448
-
449
-
450
-
451
-
452
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].style.minWidth = this.data.cropperFrameWidth + 'px';
453
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].style.maxWidth = this.data.cropperFrameWidth + 'px';
454
-
455
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].style.width = this.data.cropperFrameWidth + 'px';
456
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].style.height = this.data.cropperFrameHeight + 'px';
457
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].getElementsByTagName( 'img' )[ 0 ].style.left = this.data.cropperFrameLeft + 'px';
458
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].getElementsByTagName( 'img' )[ 0 ].style.top = this.data.cropperFrameTop + 'px';
459
-
460
- image.style.width = this.data.cropperImageWidth + 'px';
461
- image.style.height = this.data.cropperImageHeight + 'px';
462
-
463
-
464
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].getElementsByTagName( 'img' )[ 0 ].classList.add( 'isCropped' );
465
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].classList.remove( 'isCropping' );
466
-
467
-
468
- const cropSaveBtn = blockContent.getElementsByClassName( 'btn-crop-action' )[ 0 ];
469
- if ( cropSaveBtn ) {
470
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].removeChild( cropSaveBtn );
471
- }
472
-
473
-
474
-
475
- //remove cropper interface
476
- if ( this.cropperInterface ) {
477
- this.cropperInterface.destroy();
478
- }
479
-
480
-
481
-
482
-
483
- //add crop button
484
-
485
- const cropBtn = document.createElement( 'div' );
486
- cropBtn.classList.add( 'crop-btn', 'btn-crop-action' );
487
- cropBtn.innerHTML = 'Crop';
488
-
489
- cropBtn.addEventListener( 'click', e => {
490
- //remove crop button
491
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].removeChild( cropBtn );
492
- this.appendCrop( blockContent );
493
- }
494
- );
495
-
496
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].appendChild( cropBtn );
497
-
498
- blockContent.classList.remove( 'isCropping' );
499
-
500
- this.block.dispatchChange();
501
-
502
- }
503
-
504
-
505
- uncrop( blockContent ) {
506
-
507
- //remove crop and save button
508
- const cropSaveBtn = blockContent.getElementsByClassName( 'btn-crop-action' )[ 0 ];
509
- if ( cropSaveBtn ) {
510
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].removeChild( cropSaveBtn );
511
- }
512
-
513
-
514
- //remove crop button
515
- const cropBtn = blockContent.getElementsByClassName( 'btn-crop-action' )[ 0 ];
516
- if ( cropBtn ) {
517
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].removeChild( cropBtn );
518
- }
519
-
520
- //remove isCropped class
521
-
522
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].getElementsByTagName( 'img' )[ 0 ].classList.remove( 'isCropped' );
523
-
524
- //remove isCropping class
525
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].classList.remove( 'isCropping' );
526
-
527
- //remove min and max width
528
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].style.minWidth = '';
529
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].style.maxWidth = '';
530
-
531
- //remove image width and height
532
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].style.width = '';
533
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].style.height = '';
534
-
535
- //remove image left and top
536
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].getElementsByTagName( 'img' )[ 0 ].style.left = '';
537
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].getElementsByTagName( 'img' )[ 0 ].style.top = '';
538
-
539
- //remove image width and height
540
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].getElementsByTagName( 'img' )[ 0 ].style.width = '';
541
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].getElementsByTagName( 'img' )[ 0 ].style.height = '';
542
-
543
-
544
-
545
- blockContent.classList.remove( 'isCropping' );
546
-
547
-
548
-
549
- //remove cropper interface
550
- if ( this.cropperInterface ) {
551
- this.cropperInterface.destroy();
552
- }
553
-
554
- //remove crop data
555
- this.data.cropperFrameHeight = 0;
556
- this.data.cropperFrameWidth = 0;
557
- this.data.cropperFrameLeft = 0;
558
- this.data.cropperFrameTop = 0;
559
- this.data.cropperImageHeight = 0;
560
- this.data.cropperImageWidth = 0;
561
-
562
- this.block.dispatchChange();
563
-
564
- }
565
-
566
-
567
-
568
-
569
-
570
- /**
571
- * Add resize handles to block
572
- * @param {HTMLElement} blockContent - wrapper for block content
573
- * @public
574
- * @return {void}
575
- * */
576
- resize( blockContent ) {
577
-
578
-
579
- const resizable = document.createElement( 'div' );
580
- resizable.classList.add( 'resizable' );
581
-
582
- console.log( resizable );
583
-
584
-
585
- const resizers = document.createElement( 'div' );
586
- resizers.classList.add( 'resizers' );
587
-
588
- const resizerTopLeft = document.createElement( 'div' );
589
- resizerTopLeft.classList.add( 'resizer', 'top-left' );
590
- resizerTopLeft.addEventListener( 'mousedown', e => {
591
- this.resizeClick( blockContent.getElementsByClassName( 'cdx-block' )[ 0 ], resizerTopLeft, e );
592
- } );
593
-
594
-
595
- const resizerTopRight = document.createElement( 'div' );
596
- resizerTopRight.classList.add( 'resizer', 'top-right' );
597
- resizerTopRight.addEventListener( 'mousedown', e => {
598
- this.resizeClick( blockContent.getElementsByClassName( 'cdx-block' )[ 0 ], resizerTopRight, e );
599
- } );
600
-
601
-
602
- const resizerBottomLeft = document.createElement( 'div' );
603
- resizerBottomLeft.classList.add( 'resizer', 'bottom-left' );
604
- resizerBottomLeft.addEventListener( 'mousedown', e => {
605
- this.resizeClick( blockContent.getElementsByClassName( 'cdx-block' )[ 0 ], resizerBottomLeft, e );
606
- } );
607
-
608
- const resizerBottomRight = document.createElement( 'div' );
609
- resizerBottomRight.classList.add( 'resizer', 'bottom-right' );
610
- resizerBottomRight.addEventListener( 'mousedown', e => {
611
- this.resizeClick( blockContent.getElementsByClassName( 'cdx-block' )[ 0 ], resizerBottomRight, e );
612
- } );
613
-
614
- resizers.appendChild( resizerTopLeft );
615
- resizers.appendChild( resizerTopRight );
616
- resizers.appendChild( resizerBottomLeft );
617
- resizers.appendChild( resizerBottomRight );
618
- resizable.appendChild( resizers );
619
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].appendChild( resizable );
620
- }
621
-
622
-
623
-
624
- /**
625
- * click event to resize handles
626
- * preserve aspect ratio
627
- * prevent block from moving when dragging resize handles
628
- * max size = 100%
629
- * min size = 50px
630
- * @param {HTMLElement} blockContent - wrapper for block content
631
- * @public
632
- * @return {void}
633
- * */
634
- resizeClick( blockContent, handle, e ) {
635
-
636
- let startX = 0;
637
- let startY = 0;
638
- let startWidth = 0;
639
- let startHeight = 0;
640
-
641
- const mouseMoveHandler = e => {
642
-
643
- const dx = e.clientX - startX;
644
- const dy = e.clientY - startY;
645
-
646
- const newWidth = ( startWidth + dx );
647
-
648
- if ( newWidth > 50 ) {
649
- blockContent.style.width = newWidth + 'px';
650
- }
651
-
652
-
653
-
654
-
655
-
656
- };
657
-
658
- const mouseUpHandler = () => {
659
-
660
- let blockWidth = parseInt( document.defaultView.getComputedStyle( blockContent ).width, 10 );
661
-
662
- if ( blockWidth > 0 ) {
663
- this.data.resizeSize = blockWidth;
664
- }
665
-
666
- document.removeEventListener( 'mousemove', mouseMoveHandler );
667
- document.removeEventListener( 'mouseup', mouseUpHandler );
668
-
669
- this.block.dispatchChange();
670
-
671
- };
672
-
673
- document.addEventListener( 'mousemove', mouseMoveHandler );
674
- document.addEventListener( 'mouseup', mouseUpHandler );
675
-
676
- startX = e.clientX;
677
- startY = e.clientY;
678
-
679
- startWidth = parseInt( document.defaultView.getComputedStyle( blockContent ).width, 10 );
680
-
681
- startHeight = parseInt( document.defaultView.getComputedStyle( blockContent ).height, 10 );
682
-
683
-
684
- }
685
-
686
-
687
- /**
688
- * Remove resize handles from block
689
- * @param {HTMLElement} blockContent - wrapper for block content
690
- * @public
691
- * @return {void}
692
- */
693
- unresize( blockContent ) {
694
- const unresizable = blockContent.getElementsByClassName( 'resizable' )[ 0 ];
695
- if ( unresizable ) {
696
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].removeChild( unresizable );
697
- }
698
-
699
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].style.width = 'auto';
700
-
701
-
702
- }
703
-
704
-
705
-
706
-
707
- /**
708
- * Remove tunes from block wrapper
709
- * @param {HTMLElement} blockContent - wrapper for block content
710
- * @public
711
- * @return {HTMLElement}
712
- */
713
- unwrap( blockContent ) {
714
- console.log( 'unwrap' );
715
- //remove tunes from block
716
- this.buttons.forEach( button => {
717
- button.classList.remove( this.CSS.buttonActive );
718
- } );
719
-
720
- //remove isFloatLeft class
721
- blockContent.classList.remove( this.CSS.isFloatLeft );
722
-
723
- //remove isFloatRight class
724
- blockContent.classList.remove( this.CSS.isFloatRight );
725
-
726
- //remove isCenter class
727
- blockContent.classList.remove( this.CSS.isCenter );
728
-
729
- //remove isSizeSmall class
730
- blockContent.classList.remove( this.CSS.isSizeSmall );
731
-
732
- //remove isSizeMiddle class
733
- blockContent.classList.remove( this.CSS.isSizeMiddle );
734
-
735
- //remove isSizeLarge class
736
- blockContent.classList.remove( this.CSS.isSizeLarge );
737
-
738
- //remove isResize class
739
- blockContent.classList.remove( this.CSS.isResize );
740
-
741
- //remove isCrop class
742
- blockContent.classList.remove( this.CSS.isCrop );
743
-
744
- //remove isCropped class
745
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].getElementsByTagName( 'img' )[ 0 ].classList.remove( 'isCropped' );
746
-
747
- //remove isCropping class
748
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].classList.remove( 'isCropping' );
749
-
750
- //remove min and max width
751
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].style.minWidth = '';
752
- blockContent.getElementsByClassName( 'cdx-block' )[ 0 ].style.maxWidth = '';
753
-
754
- //remove image width and height
755
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].style.width = '';
756
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].style.height = '';
757
-
758
- //remove image left and top
759
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].getElementsByTagName( 'img' )[ 0 ].style.left = '';
760
-
761
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].getElementsByTagName( 'img' )[ 0 ].style.top = '';
762
-
763
- //remove image width and height
764
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].getElementsByTagName( 'img' )[ 0 ].style.width = '';
765
-
766
- blockContent.getElementsByClassName( 'image-tool__image' )[ 0 ].getElementsByTagName( 'img' )[ 0 ].style.height = '';
767
-
768
- //remove resize handles
769
- this.unresize( blockContent );
770
-
771
- //remove crop handles
772
- this.uncrop( blockContent );
773
-
774
- //remove cropper interface
775
- if ( this.cropperInterface ) {
776
- this.cropperInterface.destroy();
777
- }
778
-
779
- //remove crop data
780
- this.data.cropperFrameHeight = 0;
781
- this.data.cropperFrameWidth = 0;
782
- this.data.cropperFrameLeft = 0;
783
- this.data.cropperFrameTop = 0;
784
- this.data.cropperImageHeight = 0;
785
- this.data.cropperImageWidth = 0;
786
-
787
- return blockContent;
788
- }
789
-
790
-
791
-
792
- /**
793
- * Add tune to block data
794
- * @private
795
- * @return {void}
796
- * */
797
- save() {
798
- return this.data;
799
- }
800
-
801
- /**
802
- * Append tunes to block wrapper
803
- * @param {HTMLElement} blockContent - wrapper for block content
804
- * @public
805
- * @return {HTMLElement}
806
- * */
807
- wrap( blockContent ) {
808
-
809
- //createview if not exists
810
- if ( !this.wrapper ) {
811
- this.wrapper = this.createView();
812
- }
813
-
814
-
815
- this.apply( blockContent );
816
-
817
-
818
-
819
-
820
- return blockContent;
821
- }
822
-
823
-
824
- /**
825
- * Creates a view for tunes
826
- * @return {HTMLElement}
827
- * @private
828
- * */
829
- createView() {
830
- this.buttons = this.settings.map( tune => {
831
- const el = document.createElement( 'div' );
832
- const buttonIco = document.createElement( 'span' );
833
- const buttonTxt = document.createElement( 'span' );
834
- el.classList.add( this.CSS.button );
835
- buttonTxt.style.fontSize = '8px';
836
- buttonIco.innerHTML = tune.icon;
837
- buttonTxt.innerHTML = tune.label;
838
- el.appendChild( buttonIco );
839
- el.appendChild( buttonTxt );
840
- el.dataset.tune = tune.name;
841
- el.title = tune.label;
842
-
843
- el.addEventListener( 'click', e => this.tuneClicked( e, el ) );
844
-
845
- return el;
846
- } );
847
- const wrapper = document.createElement( 'div' );
848
- this.buttons.forEach( button => {
849
- wrapper.appendChild
850
- ( button );
851
- } );
852
- wrapper.classList.add( this.CSS.wrapper );
853
- return wrapper;
854
-
855
- }
856
-
857
- /**
858
- * Checks if tune is active
859
- * @param {string} tune - tune name
860
- * @return {boolean}
861
- * @private
862
- * */
863
- isTuneActive( tune ) {
864
- return !!this.data[ tune ];
865
- }
866
-
867
- /**
868
- * Makes buttons with tunes
869
- * @return {HTMLElement}
870
- * @public
871
- * */
872
- render() {
873
- //when editor is ready
874
- this.buttons.forEach( button => {
875
- button.classList.toggle( this.CSS.buttonActive, this.isTuneActive( button.dataset.tune ) );
876
- }
877
- );
878
-
879
- return this.view;
880
- }
881
-
882
-
883
- /**
884
- * Destroys the plugin
885
- * @public
886
- * @return {void}
887
- * */
888
- destroy() {
889
- this.wrapper = null;
890
- this.buttons = null;
891
- }
892
-
893
-
894
- }
895
-
896
-