@cocreate/resize 1.18.0 → 1.20.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/src/index.js CHANGED
@@ -3,9 +3,9 @@ import observer from "@cocreate/observer";
3
3
  import "./index.css";
4
4
 
5
5
  const EVENTS = [
6
- "mousemove touchmove",
7
- "mousedown touchstart",
8
- "mouseup touchend"
6
+ "mousemove touchmove",
7
+ "mousedown touchstart",
8
+ "mouseup touchend"
9
9
  ];
10
10
  const DIRECTIONS = ["left", "right", "top", "bottom"];
11
11
 
@@ -15,702 +15,684 @@ document.head.appendChild(styleEl);
15
15
  const styleSheet = styleEl.sheet;
16
16
 
17
17
  const coCreateResize = {
18
- selector: "", //'.resize',
19
- resizers: [],
20
- resizeWidgets: [],
21
-
22
- init: function (handleObj) {
23
- for (var handleKey in handleObj)
24
- if (handleObj.hasOwnProperty(handleKey) && handleKey == "selector")
25
- this.selector = handleObj[handleKey];
26
-
27
- this.resizers = document.querySelectorAll(this.selector);
28
- var _this = this;
29
- this.resizers.forEach(function (resize, idx) {
30
- let resizeWidget = new CoCreateResize(resize, handleObj);
31
- _this.resizeWidgets[idx] = resizeWidget;
32
- });
33
- },
34
-
35
- initElement: function (target) {
36
- let resizeWidget = new CoCreateResize(target, {
37
- dragLeft: "[resize='left']",
38
- dragRight: "[resize='right']",
39
- dragTop: "[resize='top']",
40
- dragBottom: "[resize='bottom']"
41
- });
42
- this.resizeWidgets[0] = resizeWidget;
43
- }
18
+ selector: "", //'.resize',
19
+ resizers: [],
20
+ resizeWidgets: [],
21
+
22
+ init: function (handleObj) {
23
+ for (var handleKey in handleObj)
24
+ if (handleObj.hasOwnProperty(handleKey) && handleKey == "selector")
25
+ this.selector = handleObj[handleKey];
26
+
27
+ this.resizers = document.querySelectorAll(this.selector);
28
+ var _this = this;
29
+ this.resizers.forEach(function (resize, idx) {
30
+ let resizeWidget = new CoCreateResize(resize, handleObj);
31
+ _this.resizeWidgets[idx] = resizeWidget;
32
+ });
33
+ },
34
+
35
+ initElement: function (target) {
36
+ let resizeWidget = new CoCreateResize(target, {
37
+ dragLeft: "[resize='left']",
38
+ dragRight: "[resize='right']",
39
+ dragTop: "[resize='top']",
40
+ dragBottom: "[resize='bottom']"
41
+ });
42
+ this.resizeWidgets[0] = resizeWidget;
43
+ }
44
44
  };
45
45
 
46
46
  function CoCreateResize(resizer, options) {
47
- this.resizeWidget = resizer;
48
- this.cornerSize = 10;
49
- this.init(options);
47
+ this.resizeWidget = resizer;
48
+ this.cornerSize = 10;
49
+ this.init(options);
50
50
  }
51
51
 
52
52
  CoCreateResize.prototype = {
53
- init: function (handleObj) {
54
- if (this.resizeWidget) {
55
- this.initDrags = [];
56
- this.checkCorners = [];
57
- this.doDrags = [];
58
- this.Drags = [];
59
-
60
- //this is for grid
61
- this.isGrid = this.detectGrid();
62
- this.gridWidth = 0;
63
- this.gridHeight = 0;
64
- this.limitSpan = 0;
65
- this.widthSpan = 0;
66
- this.heightSpan = 0;
67
- this.originClassAttribute = this.resizeWidget.getAttribute("class");
68
-
69
- DIRECTIONS.map((d) => {
70
- this.Drags[d] = this.resizeWidget.querySelector(
71
- handleObj["drag" + d.charAt(0).toUpperCase() + d.slice(1)]
72
- );
73
- });
74
-
75
- this.bindListeners();
76
- this.initResize();
77
-
78
- //this is just for grid system
79
- this.getGridProperty();
80
- window.addEventListener("resize", this.checkGridColumns.bind(this));
81
- }
82
- },
83
-
84
- getGridProperty: function () {
85
- if (!this.resizeWidget.parentNode) return;
86
- let compStyles = window.getComputedStyle(this.resizeWidget.parentNode);
87
- let gridColumns = compStyles.gridTemplateColumns;
88
- let height = compStyles.gridAutoRows;
89
-
90
- if (gridColumns !== "none") {
91
- let width = gridColumns.split(" ");
92
- this.limitSpan = width.length;
93
- this.gridColumnGap = Number.parseInt(compStyles.gridColumnGap);
94
- this.gridRowGap = Number.parseInt(compStyles.gridRowGap);
95
- this.gridWidth = Number.parseFloat(width[0]);
96
- this.gridHeight = Number.parseInt(height);
97
- }
98
- },
99
-
100
- checkGridColumns: function () {
101
- if (
102
- typeof this.resizeWidget !== "undefined" &&
103
- this.resizeWidget.parentNode
104
- ) {
105
- let compStylesOfParent = window.getComputedStyle(
106
- this.resizeWidget.parentNode
107
- );
108
- let spans = 0;
109
- let gridColumns = compStylesOfParent.gridTemplateColumns.split(" ");
110
- let temp = gridColumns[0];
111
- gridColumns.map((v) => {
112
- if (v == temp) spans++;
113
- });
114
- this.limitSpan = spans;
115
- if (this.resizeWidget.style["grid-column-end"]) {
116
- let curClassAttributes = this.resizeWidget
117
- .getAttribute("class")
118
- .split(" ");
119
- let prevColumnState =
120
- curClassAttributes[curClassAttributes.length - 1].split(
121
- "_"
122
- );
123
- let prevSpan = Number.parseInt(prevColumnState[1]);
124
- let curColumnState =
125
- this.resizeWidget.style["grid-column-end"].split(" ");
126
- let curSpan = Number.parseInt(curColumnState[1]);
127
-
128
- let span = 0;
129
- if (this.limitSpan >= prevSpan) span = prevSpan;
130
- else if (prevSpan > this.limitSpan) span = this.limitSpan;
131
- else span = Math.min(curSpan, this.limitSpan);
132
-
133
- this.resizeWidget.style["grid-column-end"] = "span " + span;
134
- }
135
- }
136
- },
137
-
138
- initResize: function () {
139
- DIRECTIONS.map((d) => {
140
- if (this.Drags[d])
141
- this.addListenerMulti(
142
- this.Drags[d],
143
- EVENTS[0],
144
- this.checkCorners[d]
145
- );
146
- });
147
- },
148
-
149
- checkDragImplementation: function (e, from, to, offset, fcur, scur) {
150
- if (e.touches) e = e.touches[0];
151
- let other;
152
- if (to == "top") other = "bottom";
153
- else if (to == "bottom") other = "top";
154
- else if (to == "left") other = "right";
155
- else if (to == "right") other = "left";
156
- this.removeListenerMulti(
157
- this.Drags[from],
158
- EVENTS[1],
159
- this.initDrags[from]
160
- );
161
- this.removeListenerMulti(
162
- this.Drags[from],
163
- EVENTS[1],
164
- this.initDrags[to]
165
- );
166
- this.removeListenerMulti(
167
- this.Drags[from],
168
- EVENTS[1],
169
- this.initDrags[other]
170
- );
171
- this.addListenerMulti(
172
- this.Drags[from],
173
- EVENTS[1],
174
- this.initDrags[from]
175
- );
176
-
177
- if (offset < this.cornerSize && this.Drags[to]) {
178
- this.Drags[from].style.cursor = fcur;
179
- this.addListenerMulti(
180
- this.Drags[from],
181
- EVENTS[1],
182
- this.initDrags[to]
183
- );
184
- } else {
185
- this.Drags[from].style.cursor = scur;
186
- }
187
- },
188
-
189
- initDrag: function (e, idx) {
190
- e.preventDefault();
191
-
192
- if (!this.resizeWidget.hasAttribute("resizing")) {
193
- this.resizeWidget.setAttribute("resizing", "");
194
- }
195
-
196
- let selector = document.defaultView.getComputedStyle(this.resizeWidget);
197
- styleSheet.insertRule("iframe {pointer-events: none}", 0);
198
-
199
- if (idx == "top" || idx == "bottom") {
200
- this.startTop = parseInt(selector.top, 10);
201
- this.startHeight = parseInt(selector.height, 10);
202
-
203
- if (e.touches) this.startY = e.touches[0].clientY;
204
- else this.startY = e.clientY;
205
- } else {
206
- this.startLeft = parseInt(selector.left, 10);
207
- this.startRight = parseInt(selector.right, 10);
208
- this.startWidth = parseInt(selector.width, 10);
209
-
210
- if (e.touches) this.startX = e.touches[0].clientX;
211
- else this.startX = e.clientX;
212
- }
213
-
214
- this.addListenerMulti(
215
- document.documentElement,
216
- EVENTS[0],
217
- this.doDrags[idx]
218
- );
219
- this.addListenerMulti(
220
- document.documentElement,
221
- EVENTS[2],
222
- this.stopDrag
223
- );
224
- },
225
-
226
- initTopDrag: function (e) {
227
- this.initDrag(e, "top");
228
- },
229
- initBottomDrag: function (e) {
230
- this.initDrag(e, "bottom");
231
- },
232
- initLeftDrag: function (e) {
233
- this.initDrag(e, "left");
234
- },
235
- initRightDrag: function (e) {
236
- this.initDrag(e, "right");
237
- },
238
-
239
- //this is just for grid system
240
- setRowEnd: function (height) {
241
- if (this.gridHeight) {
242
- this.heightSpan = Math.ceil(
243
- (height - (this.heightSpan - 1) * this.gridRowGap) /
244
- this.gridHeight
245
- );
246
- this.resizeWidget.style["grid-row-end"] = "span " + this.heightSpan;
247
- this.collaborate({ rowEnd: this.heightSpan });
248
- }
249
- },
250
-
251
- doTopDrag: function (e) {
252
- let top, height;
253
-
254
- if (e.touches) e = e.touches[0];
255
- top = this.startTop + e.clientY - this.startY;
256
- height = this.startHeight - e.clientY + this.startY;
257
-
258
- if (height < 10) return;
259
- if (!this.isGrid) {
260
- this.resizeWidget.style.top = top + "px";
261
- this.collaborate({ top, height });
262
- }
263
- this.resizeWidget.style.height = height + "px";
264
- this.setRowEnd(height);
265
- },
266
-
267
- doBottomDrag: function (e) {
268
- let height;
269
-
270
- if (e.touches) e = e.touches[0];
271
-
272
- height = this.startHeight + e.clientY - this.startY;
273
-
274
- if (height < 10) return;
275
- if (!this.isGrid) this.collaborate({ height });
276
-
277
- this.resizeWidget.style.height = height + "px";
278
- this.setRowEnd(height);
279
- },
280
-
281
- //this is just for grid system
282
- setColumnEnd: function (width) {
283
- if (this.gridWidth) {
284
- let spans = Math.ceil(
285
- (width - (this.widthSpan - 1) * this.gridColumnGap) /
286
- this.gridWidth
287
- );
288
- this.widthSpan = spans > this.limitSpan ? this.limitSpan : spans;
289
- this.resizeWidget.style["grid-column-end"] =
290
- "span " + this.widthSpan;
291
- this.collaborate({ columnEnd: this.widthSpan });
292
- }
293
- },
294
-
295
- doLeftDrag: function (e) {
296
- let left, right, width;
297
- if (e.touches) e = e.touches[0];
298
- left = this.startLeft + e.clientX - this.startX;
299
- right = this.startRight;
300
- width = this.startWidth - e.clientX + this.startX;
301
-
302
- if (width < 10) return;
303
- if (!this.isGrid) {
304
- this.resizeWidget.style.left = "";
305
- this.resizeWidget.style.right = right + "px";
306
- this.collaborate({ left, width });
307
- }
308
-
309
- this.resizeWidget.style.width = width + "px";
310
- this.setColumnEnd(width);
311
- },
312
-
313
- doRightDrag: function (e) {
314
- let width;
315
- if (e.touches) e = e.touches[0];
316
- width = this.startWidth + e.clientX - this.startX;
317
- if (width < 10) return;
318
-
319
- if (!this.isGrid) this.collaborate({ width });
320
-
321
- this.resizeWidget.style.width = width + "px";
322
- this.setColumnEnd(width);
323
- },
324
-
325
- detectGrid: function () {
326
- let isGrid = false;
327
- if (this.resizeWidget.parentNode) {
328
- let compStyles = window.getComputedStyle(
329
- this.resizeWidget.parentNode
330
- );
331
- isGrid = compStyles.display === "grid";
332
- }
333
- this.isGrid = isGrid;
334
- return isGrid;
335
- },
336
-
337
- stopDrag: function (e) {
338
- styleSheet.deleteRule(0);
339
- if (this.resizeWidget.hasAttribute("resizing")) {
340
- this.resizeWidget.removeAttribute("resizing", "");
341
- }
342
-
343
- //this is just for grid system
344
- if (this.detectGrid()) {
345
- this.resizeWidget.style.width = null;
346
- this.resizeWidget.style.height = null;
347
- this.resizeWidget.style.left = null;
348
- this.resizeWidget.style.top = null;
349
-
350
- if (this.widthSpan)
351
- this.resizeWidget.setAttribute(
352
- "class",
353
- this.originClassAttribute +
354
- " grid-column-end:span_" +
355
- this.widthSpan
356
- );
357
- if (this.heightSpan)
358
- this.resizeWidget.setAttribute(
359
- "class",
360
- this.originClassAttribute +
361
- " grid-row-end:span_" +
362
- this.heightSpan
363
- );
364
- }
365
-
366
- DIRECTIONS.map((d) => {
367
- this.removeListenerMulti(
368
- document.documentElement,
369
- EVENTS[0],
370
- this.doDrags[d]
371
- );
372
- });
373
- this.removeListenerMulti(
374
- document.documentElement,
375
- EVENTS[2],
376
- this.stopDrag
377
- );
378
- },
379
- checkLeftCorners: function (e) {
380
- let offset =
381
- e.clientY -
382
- this.getDistance(this.Drags["left"], true) +
383
- document.documentElement.scrollTop;
384
- if (offset > 10) {
385
- offset =
386
- this.getDistance(this.Drags["left"], true) +
387
- this.Drags["left"].clientHeight -
388
- e.clientY -
389
- document.documentElement.scrollTop;
390
- this.checkDragImplementation(
391
- e,
392
- "left",
393
- "bottom",
394
- offset,
395
- "ne-resize",
396
- "e-resize"
397
- );
398
- } else {
399
- this.checkDragImplementation(
400
- e,
401
- "left",
402
- "top",
403
- offset,
404
- "se-resize",
405
- "e-resize"
406
- );
407
- }
408
- },
409
- checkTopCorners: function (e) {
410
- let offset =
411
- e.clientX -
412
- this.getDistance(this.Drags["top"], false) +
413
- document.documentElement.scrollTop;
414
- if (offset > 10) {
415
- offset =
416
- this.getDistance(this.Drags["top"], false) +
417
- this.Drags["top"].clientWidth -
418
- e.clientX -
419
- document.documentElement.scrollLeft;
420
- this.checkDragImplementation(
421
- e,
422
- "top",
423
- "right",
424
- offset,
425
- "ne-resize",
426
- "s-resize"
427
- );
428
- } else {
429
- this.checkDragImplementation(
430
- e,
431
- "top",
432
- "left",
433
- offset,
434
- "se-resize",
435
- "s-resize"
436
- );
437
- }
438
- },
439
- checkBottomCorners: function (e) {
440
- let offset =
441
- e.clientX -
442
- this.getDistance(this.Drags["bottom"], false) +
443
- document.documentElement.scrollTop;
444
- if (offset > 10) {
445
- offset =
446
- this.getDistance(this.Drags["bottom"], false) +
447
- this.Drags["bottom"].clientWidth -
448
- e.clientX -
449
- document.documentElement.scrollLeft;
450
- this.checkDragImplementation(
451
- e,
452
- "bottom",
453
- "right",
454
- offset,
455
- "se-resize",
456
- "s-resize"
457
- );
458
- } else {
459
- this.checkDragImplementation(
460
- e,
461
- "bottom",
462
- "left",
463
- offset,
464
- "ne-resize",
465
- "s-resize"
466
- );
467
- }
468
- },
469
- checkRightCorners: function (e) {
470
- let offset =
471
- e.clientY -
472
- this.getDistance(this.Drags["right"], true) +
473
- document.documentElement.scrollTop;
474
- if (offset > 10) {
475
- offset =
476
- this.getDistance(this.Drags["right"], true) +
477
- this.Drags["right"].clientHeight -
478
- e.clientY -
479
- document.documentElement.scrollTop;
480
- this.checkDragImplementation(
481
- e,
482
- "right",
483
- "bottom",
484
- offset,
485
- "se-resize",
486
- "e-resize"
487
- );
488
- } else {
489
- this.checkDragImplementation(
490
- e,
491
- "right",
492
- "top",
493
- offset,
494
- "ne-resize",
495
- "e-resize"
496
- );
497
- }
498
- },
499
-
500
- bindListeners: function () {
501
- this.doDrags["left"] = this.doLeftDrag.bind(this);
502
- this.doDrags["top"] = this.doTopDrag.bind(this);
503
- this.doDrags["right"] = this.doRightDrag.bind(this);
504
- this.doDrags["bottom"] = this.doBottomDrag.bind(this);
505
-
506
- this.stopDrag = this.stopDrag.bind(this);
507
-
508
- this.checkCorners["left"] = this.checkLeftCorners.bind(this);
509
- this.checkCorners["top"] = this.checkTopCorners.bind(this);
510
- this.checkCorners["bottom"] = this.checkBottomCorners.bind(this);
511
- this.checkCorners["right"] = this.checkRightCorners.bind(this);
512
-
513
- this.initDrags["top"] = this.initTopDrag.bind(this);
514
- this.initDrags["left"] = this.initLeftDrag.bind(this);
515
- this.initDrags["bottom"] = this.initBottomDrag.bind(this);
516
- this.initDrags["right"] = this.initRightDrag.bind(this);
517
- },
518
-
519
- getDistance: function (elem, flag) {
520
- var location = 0;
521
- if (!elem) return;
522
- if (elem.offsetParent) {
523
- do {
524
- location += flag ? elem.offsetTop : elem.offsetLeft;
525
- elem = elem.offsetParent;
526
- } while (elem);
527
- }
528
- return location >= 0 ? location : 0;
529
- },
530
-
531
- // Bind multiiple events to a listener
532
- addListenerMulti: function (element, eventNames, listener) {
533
- var events = eventNames.split(" ");
534
- for (var i = 0, iLen = events.length; i < iLen; i++) {
535
- element.addEventListener(events[i], listener, { passive: false });
536
- }
537
- },
538
-
539
- // Remove multiiple events from a listener
540
- removeListenerMulti: function (element, eventNames, listener) {
541
- var events = eventNames.split(" ");
542
- for (var i = 0, iLen = events.length; i < iLen; i++) {
543
- element.removeEventListener(events[i], listener, {
544
- passive: false
545
- });
546
- }
547
- },
548
-
549
- collaborate: function ({ left, top, width, height, rowEnd, columnEnd }) {
550
- if (window.CoCreate && window.CoCreate.text) {
551
- let domTextEditor = this.resizeWidget.closest("[contenteditable]");
552
- if (domTextEditor) {
553
- if (left)
554
- CoCreate.text.setStyle({
555
- domTextEditor,
556
- target: this.resizeWidget,
557
- property: "left",
558
- value: left + "px"
559
- });
560
- if (top)
561
- CoCreate.text.setStyle({
562
- domTextEditor,
563
- target: this.resizeWidget,
564
- property: "top",
565
- value: top + "px"
566
- });
567
- if (width)
568
- CoCreate.text.setStyle({
569
- domTextEditor,
570
- target: this.resizeWidget,
571
- property: "width",
572
- value: width + "px"
573
- });
574
- if (height)
575
- CoCreate.text.setStyle({
576
- domTextEditor,
577
- target: this.resizeWidget,
578
- property: "height",
579
- value: height + "px"
580
- });
581
- if (rowEnd)
582
- CoCreate.text.setStyle({
583
- domTextEditor,
584
- target: this.resizeWidget,
585
- property: "grid-row-end",
586
- value: "span " + rowEnd
587
- });
588
- if (columnEnd)
589
- CoCreate.text.setStyle({
590
- domTextEditor,
591
- target: this.resizeWidget,
592
- property: "grid-column-end",
593
- value: "span " + columnEnd
594
- });
595
- }
596
- }
597
- }
53
+ init: function (handleObj) {
54
+ if (this.resizeWidget) {
55
+ this.initDrags = [];
56
+ this.checkCorners = [];
57
+ this.doDrags = [];
58
+ this.Drags = [];
59
+
60
+ //this is for grid
61
+ this.isGrid = this.detectGrid();
62
+ this.gridWidth = 0;
63
+ this.gridHeight = 0;
64
+ this.limitSpan = 0;
65
+ this.widthSpan = 0;
66
+ this.heightSpan = 0;
67
+ this.originClassAttribute = this.resizeWidget.getAttribute("class");
68
+
69
+ DIRECTIONS.map((d) => {
70
+ this.Drags[d] = this.resizeWidget.querySelector(
71
+ handleObj["drag" + d.charAt(0).toUpperCase() + d.slice(1)]
72
+ );
73
+ });
74
+
75
+ this.bindListeners();
76
+ this.initResize();
77
+
78
+ //this is just for grid system
79
+ this.getGridProperty();
80
+ window.addEventListener("resize", this.checkGridColumns.bind(this));
81
+ }
82
+ },
83
+
84
+ getGridProperty: function () {
85
+ if (!this.resizeWidget.parentNode) return;
86
+ let compStyles = window.getComputedStyle(this.resizeWidget.parentNode);
87
+ let gridColumns = compStyles.gridTemplateColumns;
88
+ let height = compStyles.gridAutoRows;
89
+
90
+ if (gridColumns !== "none") {
91
+ let width = gridColumns.split(" ");
92
+ this.limitSpan = width.length;
93
+ this.gridColumnGap = Number.parseInt(compStyles.gridColumnGap);
94
+ this.gridRowGap = Number.parseInt(compStyles.gridRowGap);
95
+ this.gridWidth = Number.parseFloat(width[0]);
96
+ this.gridHeight = Number.parseInt(height);
97
+ }
98
+ },
99
+
100
+ checkGridColumns: function () {
101
+ if (
102
+ typeof this.resizeWidget !== "undefined" &&
103
+ this.resizeWidget.parentNode
104
+ ) {
105
+ let compStylesOfParent = window.getComputedStyle(
106
+ this.resizeWidget.parentNode
107
+ );
108
+ let spans = 0;
109
+ let gridColumns = compStylesOfParent.gridTemplateColumns.split(" ");
110
+ let temp = gridColumns[0];
111
+ gridColumns.map((v) => {
112
+ if (v == temp) spans++;
113
+ });
114
+ this.limitSpan = spans;
115
+ if (this.resizeWidget.style["grid-column-end"]) {
116
+ let curClassAttributes = this.resizeWidget
117
+ .getAttribute("class")
118
+ .split(" ");
119
+ let prevColumnState =
120
+ curClassAttributes[curClassAttributes.length - 1].split(
121
+ "_"
122
+ );
123
+ let prevSpan = Number.parseInt(prevColumnState[1]);
124
+ let curColumnState =
125
+ this.resizeWidget.style["grid-column-end"].split(" ");
126
+ let curSpan = Number.parseInt(curColumnState[1]);
127
+
128
+ let span = 0;
129
+ if (this.limitSpan >= prevSpan) span = prevSpan;
130
+ else if (prevSpan > this.limitSpan) span = this.limitSpan;
131
+ else span = Math.min(curSpan, this.limitSpan);
132
+
133
+ this.resizeWidget.style["grid-column-end"] = "span " + span;
134
+ }
135
+ }
136
+ },
137
+
138
+ initResize: function () {
139
+ DIRECTIONS.map((d) => {
140
+ if (this.Drags[d])
141
+ this.addListenerMulti(
142
+ this.Drags[d],
143
+ EVENTS[0],
144
+ this.checkCorners[d]
145
+ );
146
+ });
147
+ },
148
+
149
+ checkDragImplementation: function (e, from, to, offset, fcur, scur) {
150
+ if (e.touches) e = e.touches[0];
151
+ let other;
152
+ if (to == "top") other = "bottom";
153
+ else if (to == "bottom") other = "top";
154
+ else if (to == "left") other = "right";
155
+ else if (to == "right") other = "left";
156
+ this.removeListenerMulti(
157
+ this.Drags[from],
158
+ EVENTS[1],
159
+ this.initDrags[from]
160
+ );
161
+ this.removeListenerMulti(
162
+ this.Drags[from],
163
+ EVENTS[1],
164
+ this.initDrags[to]
165
+ );
166
+ this.removeListenerMulti(
167
+ this.Drags[from],
168
+ EVENTS[1],
169
+ this.initDrags[other]
170
+ );
171
+ this.addListenerMulti(
172
+ this.Drags[from],
173
+ EVENTS[1],
174
+ this.initDrags[from]
175
+ );
176
+
177
+ if (offset < this.cornerSize && this.Drags[to]) {
178
+ this.Drags[from].style.cursor = fcur;
179
+ this.addListenerMulti(
180
+ this.Drags[from],
181
+ EVENTS[1],
182
+ this.initDrags[to]
183
+ );
184
+ } else {
185
+ this.Drags[from].style.cursor = scur;
186
+ }
187
+ },
188
+
189
+ initDrag: function (e, idx) {
190
+ e.preventDefault();
191
+
192
+ if (!this.resizeWidget.hasAttribute("resizing")) {
193
+ this.resizeWidget.setAttribute("resizing", "");
194
+ }
195
+
196
+ let selector = document.defaultView.getComputedStyle(this.resizeWidget);
197
+ styleSheet.insertRule("iframe {pointer-events: none}", 0);
198
+
199
+ if (idx == "top" || idx == "bottom") {
200
+ this.startTop = parseInt(selector.top, 10);
201
+ this.startHeight = parseInt(selector.height, 10);
202
+
203
+ if (e.touches) this.startY = e.touches[0].clientY;
204
+ else this.startY = e.clientY;
205
+ } else {
206
+ this.startLeft = parseInt(selector.left, 10);
207
+ this.startRight = parseInt(selector.right, 10);
208
+ this.startWidth = parseInt(selector.width, 10);
209
+
210
+ if (e.touches) this.startX = e.touches[0].clientX;
211
+ else this.startX = e.clientX;
212
+ }
213
+
214
+ this.addListenerMulti(
215
+ document.documentElement,
216
+ EVENTS[0],
217
+ this.doDrags[idx]
218
+ );
219
+ this.addListenerMulti(
220
+ document.documentElement,
221
+ EVENTS[2],
222
+ this.stopDrag
223
+ );
224
+ },
225
+
226
+ initTopDrag: function (e) {
227
+ this.initDrag(e, "top");
228
+ },
229
+ initBottomDrag: function (e) {
230
+ this.initDrag(e, "bottom");
231
+ },
232
+ initLeftDrag: function (e) {
233
+ this.initDrag(e, "left");
234
+ },
235
+ initRightDrag: function (e) {
236
+ this.initDrag(e, "right");
237
+ },
238
+
239
+ //this is just for grid system
240
+ setRowEnd: function (height) {
241
+ if (this.gridHeight) {
242
+ this.heightSpan = Math.ceil(
243
+ (height - (this.heightSpan - 1) * this.gridRowGap) /
244
+ this.gridHeight
245
+ );
246
+ this.resizeWidget.style["grid-row-end"] = "span " + this.heightSpan;
247
+ this.collaborate({ rowEnd: this.heightSpan });
248
+ }
249
+ },
250
+
251
+ doTopDrag: function (e) {
252
+ let top, height;
253
+
254
+ if (e.touches) e = e.touches[0];
255
+ top = this.startTop + e.clientY - this.startY;
256
+ height = this.startHeight - e.clientY + this.startY;
257
+
258
+ if (height < 10) return;
259
+ if (!this.isGrid) {
260
+ this.resizeWidget.style.top = top + "px";
261
+ this.collaborate({ top, height });
262
+ }
263
+ this.resizeWidget.style.height = height + "px";
264
+ this.setRowEnd(height);
265
+ },
266
+
267
+ doBottomDrag: function (e) {
268
+ let height;
269
+
270
+ if (e.touches) e = e.touches[0];
271
+
272
+ height = this.startHeight + e.clientY - this.startY;
273
+
274
+ if (height < 10) return;
275
+ if (!this.isGrid) this.collaborate({ height });
276
+
277
+ this.resizeWidget.style.height = height + "px";
278
+ this.setRowEnd(height);
279
+ },
280
+
281
+ //this is just for grid system
282
+ setColumnEnd: function (width) {
283
+ if (this.gridWidth) {
284
+ let spans = Math.ceil(
285
+ (width - (this.widthSpan - 1) * this.gridColumnGap) /
286
+ this.gridWidth
287
+ );
288
+ this.widthSpan = spans > this.limitSpan ? this.limitSpan : spans;
289
+ this.resizeWidget.style["grid-column-end"] =
290
+ "span " + this.widthSpan;
291
+ this.collaborate({ columnEnd: this.widthSpan });
292
+ }
293
+ },
294
+
295
+ doLeftDrag: function (e) {
296
+ let left, right, width;
297
+ if (e.touches) e = e.touches[0];
298
+ left = this.startLeft + e.clientX - this.startX;
299
+ right = this.startRight;
300
+ width = this.startWidth - e.clientX + this.startX;
301
+
302
+ if (width < 10) return;
303
+ if (!this.isGrid) {
304
+ this.resizeWidget.style.left = "";
305
+ this.resizeWidget.style.right = right + "px";
306
+ this.collaborate({ left, width });
307
+ }
308
+
309
+ this.resizeWidget.style.width = width + "px";
310
+ this.setColumnEnd(width);
311
+ },
312
+
313
+ doRightDrag: function (e) {
314
+ let width;
315
+ if (e.touches) e = e.touches[0];
316
+ width = this.startWidth + e.clientX - this.startX;
317
+ if (width < 10) return;
318
+
319
+ if (!this.isGrid) this.collaborate({ width });
320
+
321
+ this.resizeWidget.style.width = width + "px";
322
+ this.setColumnEnd(width);
323
+ },
324
+
325
+ detectGrid: function () {
326
+ let isGrid = false;
327
+ if (this.resizeWidget.parentNode) {
328
+ let compStyles = window.getComputedStyle(
329
+ this.resizeWidget.parentNode
330
+ );
331
+ isGrid = compStyles.display === "grid";
332
+ }
333
+ this.isGrid = isGrid;
334
+ return isGrid;
335
+ },
336
+
337
+ stopDrag: function (e) {
338
+ styleSheet.deleteRule(0);
339
+ if (this.resizeWidget.hasAttribute("resizing")) {
340
+ this.resizeWidget.removeAttribute("resizing", "");
341
+ }
342
+
343
+ //this is just for grid system
344
+ if (this.detectGrid()) {
345
+ this.resizeWidget.style.width = null;
346
+ this.resizeWidget.style.height = null;
347
+ this.resizeWidget.style.left = null;
348
+ this.resizeWidget.style.top = null;
349
+
350
+ if (this.widthSpan)
351
+ this.resizeWidget.setAttribute(
352
+ "class",
353
+ this.originClassAttribute +
354
+ " grid-column-end:span_" +
355
+ this.widthSpan
356
+ );
357
+ if (this.heightSpan)
358
+ this.resizeWidget.setAttribute(
359
+ "class",
360
+ this.originClassAttribute +
361
+ " grid-row-end:span_" +
362
+ this.heightSpan
363
+ );
364
+ }
365
+
366
+ DIRECTIONS.map((d) => {
367
+ this.removeListenerMulti(
368
+ document.documentElement,
369
+ EVENTS[0],
370
+ this.doDrags[d]
371
+ );
372
+ });
373
+ this.removeListenerMulti(
374
+ document.documentElement,
375
+ EVENTS[2],
376
+ this.stopDrag
377
+ );
378
+ },
379
+ checkLeftCorners: function (e) {
380
+ let offset =
381
+ e.clientY -
382
+ this.getDistance(this.Drags["left"], true) +
383
+ document.documentElement.scrollTop;
384
+ if (offset > 10) {
385
+ offset =
386
+ this.getDistance(this.Drags["left"], true) +
387
+ this.Drags["left"].clientHeight -
388
+ e.clientY -
389
+ document.documentElement.scrollTop;
390
+ this.checkDragImplementation(
391
+ e,
392
+ "left",
393
+ "bottom",
394
+ offset,
395
+ "ne-resize",
396
+ "e-resize"
397
+ );
398
+ } else {
399
+ this.checkDragImplementation(
400
+ e,
401
+ "left",
402
+ "top",
403
+ offset,
404
+ "se-resize",
405
+ "e-resize"
406
+ );
407
+ }
408
+ },
409
+ checkTopCorners: function (e) {
410
+ let offset =
411
+ e.clientX -
412
+ this.getDistance(this.Drags["top"], false) +
413
+ document.documentElement.scrollTop;
414
+ if (offset > 10) {
415
+ offset =
416
+ this.getDistance(this.Drags["top"], false) +
417
+ this.Drags["top"].clientWidth -
418
+ e.clientX -
419
+ document.documentElement.scrollLeft;
420
+ this.checkDragImplementation(
421
+ e,
422
+ "top",
423
+ "right",
424
+ offset,
425
+ "ne-resize",
426
+ "s-resize"
427
+ );
428
+ } else {
429
+ this.checkDragImplementation(
430
+ e,
431
+ "top",
432
+ "left",
433
+ offset,
434
+ "se-resize",
435
+ "s-resize"
436
+ );
437
+ }
438
+ },
439
+ checkBottomCorners: function (e) {
440
+ let offset =
441
+ e.clientX -
442
+ this.getDistance(this.Drags["bottom"], false) +
443
+ document.documentElement.scrollTop;
444
+ if (offset > 10) {
445
+ offset =
446
+ this.getDistance(this.Drags["bottom"], false) +
447
+ this.Drags["bottom"].clientWidth -
448
+ e.clientX -
449
+ document.documentElement.scrollLeft;
450
+ this.checkDragImplementation(
451
+ e,
452
+ "bottom",
453
+ "right",
454
+ offset,
455
+ "se-resize",
456
+ "s-resize"
457
+ );
458
+ } else {
459
+ this.checkDragImplementation(
460
+ e,
461
+ "bottom",
462
+ "left",
463
+ offset,
464
+ "ne-resize",
465
+ "s-resize"
466
+ );
467
+ }
468
+ },
469
+ checkRightCorners: function (e) {
470
+ let offset =
471
+ e.clientY -
472
+ this.getDistance(this.Drags["right"], true) +
473
+ document.documentElement.scrollTop;
474
+ if (offset > 10) {
475
+ offset =
476
+ this.getDistance(this.Drags["right"], true) +
477
+ this.Drags["right"].clientHeight -
478
+ e.clientY -
479
+ document.documentElement.scrollTop;
480
+ this.checkDragImplementation(
481
+ e,
482
+ "right",
483
+ "bottom",
484
+ offset,
485
+ "se-resize",
486
+ "e-resize"
487
+ );
488
+ } else {
489
+ this.checkDragImplementation(
490
+ e,
491
+ "right",
492
+ "top",
493
+ offset,
494
+ "ne-resize",
495
+ "e-resize"
496
+ );
497
+ }
498
+ },
499
+
500
+ bindListeners: function () {
501
+ this.doDrags["left"] = this.doLeftDrag.bind(this);
502
+ this.doDrags["top"] = this.doTopDrag.bind(this);
503
+ this.doDrags["right"] = this.doRightDrag.bind(this);
504
+ this.doDrags["bottom"] = this.doBottomDrag.bind(this);
505
+
506
+ this.stopDrag = this.stopDrag.bind(this);
507
+
508
+ this.checkCorners["left"] = this.checkLeftCorners.bind(this);
509
+ this.checkCorners["top"] = this.checkTopCorners.bind(this);
510
+ this.checkCorners["bottom"] = this.checkBottomCorners.bind(this);
511
+ this.checkCorners["right"] = this.checkRightCorners.bind(this);
512
+
513
+ this.initDrags["top"] = this.initTopDrag.bind(this);
514
+ this.initDrags["left"] = this.initLeftDrag.bind(this);
515
+ this.initDrags["bottom"] = this.initBottomDrag.bind(this);
516
+ this.initDrags["right"] = this.initRightDrag.bind(this);
517
+ },
518
+
519
+ getDistance: function (elem, flag) {
520
+ var location = 0;
521
+ if (!elem) return;
522
+ if (elem.offsetParent) {
523
+ do {
524
+ location += flag ? elem.offsetTop : elem.offsetLeft;
525
+ elem = elem.offsetParent;
526
+ } while (elem);
527
+ }
528
+ return location >= 0 ? location : 0;
529
+ },
530
+
531
+ // Bind multiiple events to a listener
532
+ addListenerMulti: function (element, eventNames, listener) {
533
+ var events = eventNames.split(" ");
534
+ for (var i = 0, iLen = events.length; i < iLen; i++) {
535
+ element.addEventListener(events[i], listener, { passive: false });
536
+ }
537
+ },
538
+
539
+ // Remove multiiple events from a listener
540
+ removeListenerMulti: function (element, eventNames, listener) {
541
+ var events = eventNames.split(" ");
542
+ for (var i = 0, iLen = events.length; i < iLen; i++) {
543
+ element.removeEventListener(events[i], listener, {
544
+ passive: false
545
+ });
546
+ }
547
+ },
548
+
549
+ collaborate: function ({ left, top, width, height, rowEnd, columnEnd }) {
550
+ if (window.CoCreate && window.CoCreate.text) {
551
+ let domTextEditor = this.resizeWidget.closest("[contenteditable]");
552
+ if (domTextEditor) {
553
+ if (left)
554
+ CoCreate.text.setStyle({
555
+ domTextEditor,
556
+ target: this.resizeWidget,
557
+ property: "left",
558
+ value: left + "px"
559
+ });
560
+ if (top)
561
+ CoCreate.text.setStyle({
562
+ domTextEditor,
563
+ target: this.resizeWidget,
564
+ property: "top",
565
+ value: top + "px"
566
+ });
567
+ if (width)
568
+ CoCreate.text.setStyle({
569
+ domTextEditor,
570
+ target: this.resizeWidget,
571
+ property: "width",
572
+ value: width + "px"
573
+ });
574
+ if (height)
575
+ CoCreate.text.setStyle({
576
+ domTextEditor,
577
+ target: this.resizeWidget,
578
+ property: "height",
579
+ value: height + "px"
580
+ });
581
+ if (rowEnd)
582
+ CoCreate.text.setStyle({
583
+ domTextEditor,
584
+ target: this.resizeWidget,
585
+ property: "grid-row-end",
586
+ value: "span " + rowEnd
587
+ });
588
+ if (columnEnd)
589
+ CoCreate.text.setStyle({
590
+ domTextEditor,
591
+ target: this.resizeWidget,
592
+ property: "grid-column-end",
593
+ value: "span " + columnEnd
594
+ });
595
+ }
596
+ }
597
+ }
598
598
  };
599
599
 
600
600
  // Function to auto-resize the element based on its content
601
601
  function autoResizeElement(element) {
602
- if (!element) return;
603
-
604
- if (element.tagName === "TEXTAREA") {
605
- element.style.height = "auto";
606
-
607
- let scrollHeight;
608
- if (element.contentDocument) {
609
- scrollHeight = element.contentDocument.body.scrollHeight;
610
- } else {
611
- // For other elements, get scrollHeight directly
612
- scrollHeight = element.scrollHeight;
613
- }
614
-
615
- // Set the height of the element to the calculated scrollHeight
616
- element.style.height = scrollHeight + "px";
617
- } else if (element.tagName === "SELECT" && element.multiple) {
618
- element.size = Math.max(element.options.length, 1); // Ensure at least 1 visible option
619
- }
602
+ if (!element) return;
603
+
604
+ if (element.tagName === "TEXTAREA") {
605
+ element.style.height = "auto";
606
+
607
+ const style = getComputedStyle(element);
608
+ const padding = parseFloat(style.paddingTop) + parseFloat(style.paddingBottom);
609
+ const border = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);
610
+ // scrollHeight includes padding, but not borders.
611
+ const height = element.scrollHeight +
612
+ (style.boxSizing === "border-box" ? border : -padding);
613
+ element.style.height = Math.max(0, height) + "px";
614
+ } else if (element.tagName === "SELECT" && element.multiple) {
615
+ element.size = Math.max(element.options.length, 1); // Ensure at least 1 visible option
616
+ }
620
617
  }
621
618
 
622
619
  // Observe the resize of the element
623
620
  function observeElementResize(element) {
624
- const resizeObserver = new ResizeObserver(() => {
625
- autoResizeElement(element);
626
- });
621
+ const resizeObserver = new ResizeObserver(() => {
622
+ autoResizeElement(element);
623
+ });
627
624
 
628
- resizeObserver.observe(element);
625
+ resizeObserver.observe(element);
629
626
  }
630
627
 
631
628
  // Listen for input events on the entire document
632
629
  function initAutoHeight(element) {
633
- if (
634
- element &&
635
- !(element instanceof HTMLCollection) &&
636
- !(element instanceof NodeList) &&
637
- !Array.isArray(element)
638
- ) {
639
- element = [element];
640
- } else if (!element) {
641
- element = document.querySelectorAll('[height="auto"]');
642
-
643
- // Add event listener for iframes on load
644
- document.addEventListener(
645
- "input",
646
- function (event) {
647
- // Check if the target element has height="auto"
648
- if (event.target.getAttribute("height") === "auto") {
649
- autoResizeElement(event.target);
650
- }
651
- },
652
- false
653
- );
654
-
655
- // if (element.contentDocument) {
656
- // // Create a MutationObserver for changes within the iframe's body
657
- // const observer = new MutationObserver(autoResizeElement);
658
- // observer.observe(iframeDocument.body, {
659
- // childList: true,
660
- // subtree: true
661
- // });
662
-
663
- // // Handle iframe document changes (e.g., if src or srcdoc is modified)
664
- // element.addEventListener("load", () => {
665
- // observer.disconnect(); // Disconnect the previous observer
666
- // observeIframeContent(); // Reinitialize the observer on new document
667
- // });
668
- // }
669
- }
670
-
671
- for (let i = 0; i < element.length; i++) {
672
- if (element[i].tagName === "TEXTAREA") {
673
- element[i].rows = 1;
674
- }
675
- autoResizeElement(element[i]);
676
- observeElementResize(element[i]); // Observe resize changes.
677
- }
630
+ if (
631
+ element &&
632
+ !(element instanceof HTMLCollection) &&
633
+ !(element instanceof NodeList) &&
634
+ !Array.isArray(element)
635
+ ) {
636
+ element = [element];
637
+ } else if (!element) {
638
+ element = document.querySelectorAll('[height="auto"]');
639
+
640
+ // Add event listener for iframes on load
641
+ document.addEventListener(
642
+ "input",
643
+ function (event) {
644
+ // Check if the target element has height="auto"
645
+ if (event.target.getAttribute("height") === "auto") {
646
+ autoResizeElement(event.target);
647
+ }
648
+ },
649
+ false
650
+ );
651
+ }
652
+
653
+ for (let i = 0; i < element.length; i++) {
654
+ if (element[i].tagName === "TEXTAREA") {
655
+ element[i].rows = 1;
656
+ }
657
+ autoResizeElement(element[i]);
658
+ observeElementResize(element[i]); // Observe resize changes.
659
+ }
678
660
  }
679
661
 
680
662
  initAutoHeight();
681
663
 
682
664
  observer.init({
683
- name: "CoCreateResize",
684
- types: ["addedNodes"],
685
- selector: "[resizable]:not([resizable='false'])",
686
- callback: function (mutation) {
687
- coCreateResize.initElement(mutation.target);
688
- }
665
+ name: "CoCreateResize",
666
+ types: ["addedNodes"],
667
+ selector: "[resizable]:not([resizable='false'])",
668
+ callback: function (mutation) {
669
+ coCreateResize.initElement(mutation.target);
670
+ }
689
671
  });
690
672
 
691
673
  observer.init({
692
- name: "CoCreateResize",
693
- types: ["addedNodes"],
694
- selector: "[height='auto']",
695
- callback: function (mutation) {
696
- initAutoHeight(mutation.target);
697
- }
674
+ name: "CoCreateAutoResize",
675
+ types: ["addedNodes"],
676
+ selector: "[height='auto']",
677
+ callback: function (mutation) {
678
+ initAutoHeight(mutation.target);
679
+ }
698
680
  });
699
681
 
700
682
  observer.init({
701
- name: "CoCreateResize",
702
- types: ["addedNodes"],
703
- selector: "[height='auto'] option",
704
- callback: function (mutation) {
705
- autoResizeElement(mutation.target.parentElement);
706
- }
683
+ name: "CoCreateAutoResizeOptions",
684
+ types: ["addedNodes"],
685
+ selector: "[height='auto'] option",
686
+ callback: function (mutation) {
687
+ autoResizeElement(mutation.target.parentElement);
688
+ }
707
689
  });
708
690
 
709
691
  coCreateResize.init({
710
- selector: "[resizable]:not([resizable='false'])",
711
- dragLeft: "[resize='left']",
712
- dragRight: "[resize='right']",
713
- dragTop: "[resize='top']",
714
- dragBottom: "[resize='bottom']"
692
+ selector: "[resizable]:not([resizable='false'])",
693
+ dragLeft: "[resize='left']",
694
+ dragRight: "[resize='right']",
695
+ dragTop: "[resize='top']",
696
+ dragBottom: "[resize='bottom']"
715
697
  });
716
698
  export default coCreateResize;