@cocreate/resize 1.12.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/package.json +1 -1
  3. package/src/index.js +674 -432
package/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # [1.13.0](https://github.com/CoCreate-app/CoCreate-resize/compare/v1.12.0...v1.13.0) (2024-12-14)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * initAutoHeight() execution onload ([e1b8af3](https://github.com/CoCreate-app/CoCreate-resize/commit/e1b8af3b6b44beb2584791d21eea5e2ba478881d))
7
+ * removed test console.log ([6d1d5e3](https://github.com/CoCreate-app/CoCreate-resize/commit/6d1d5e3087c983d1088cc734cdad5ed62393fc60))
8
+
9
+
10
+ ### Features
11
+
12
+ * auto resize handled using height="auto" ([5156022](https://github.com/CoCreate-app/CoCreate-resize/commit/515602267b383f336e5a44adaae385f964c97ab0))
13
+
1
14
  # [1.12.0](https://github.com/CoCreate-app/CoCreate-resize/compare/v1.11.2...v1.12.0) (2024-11-04)
2
15
 
3
16
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/resize",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "A light weight resize handler make any element resizable by adding data attributes or usinng init object. Great for Customized text box or text area.",
5
5
  "keywords": [
6
6
  "resize",
package/src/index.js CHANGED
@@ -2,456 +2,698 @@
2
2
  import observer from "@cocreate/observer";
3
3
  import "./index.css";
4
4
 
5
- const EVENTS = ['mousemove touchmove', 'mousedown touchstart', 'mouseup touchend'];
6
- const DIRECTIONS = ['left', 'right', 'top', 'bottom'];
5
+ const EVENTS = [
6
+ "mousemove touchmove",
7
+ "mousedown touchstart",
8
+ "mouseup touchend"
9
+ ];
10
+ const DIRECTIONS = ["left", "right", "top", "bottom"];
7
11
 
8
12
  const styleEl = document.createElement("style");
9
- styleEl.setAttribute('component', 'resize');
13
+ styleEl.setAttribute("component", "resize");
10
14
  document.head.appendChild(styleEl);
11
15
  const styleSheet = styleEl.sheet;
12
16
 
13
17
  const coCreateResize = {
14
- selector: '', //'.resize',
15
- resizers: [],
16
- resizeWidgets: [],
17
-
18
- init: function (handleObj) {
19
- for (var handleKey in handleObj)
20
- if (handleObj.hasOwnProperty(handleKey) && handleKey == 'selector')
21
- this.selector = handleObj[handleKey];
22
-
23
- this.resizers = document.querySelectorAll(this.selector);
24
- var _this = this;
25
- this.resizers.forEach(function (resize, idx) {
26
- let resizeWidget = new CoCreateResize(resize, handleObj);
27
- _this.resizeWidgets[idx] = resizeWidget;
28
- });
29
- },
30
-
31
- initElement: function (target) {
32
- let resizeWidget = new CoCreateResize(target, {
33
- dragLeft: "[resize='left']",
34
- dragRight: "[resize='right']",
35
- dragTop: "[resize='top']",
36
- dragBottom: "[resize='bottom']"
37
- });
38
- this.resizeWidgets[0] = resizeWidget;
39
- }
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
+ }
40
44
  };
41
45
 
42
46
  function CoCreateResize(resizer, options) {
43
- this.resizeWidget = resizer;
44
- this.cornerSize = 10;
45
- this.init(options);
47
+ this.resizeWidget = resizer;
48
+ this.cornerSize = 10;
49
+ this.init(options);
46
50
  }
47
51
 
48
52
  CoCreateResize.prototype = {
49
- init: function (handleObj) {
50
- if (this.resizeWidget) {
51
- this.initDrags = [];
52
- this.checkCorners = [];
53
- this.doDrags = [];
54
- this.Drags = [];
55
-
56
- //this is for grid
57
- this.isGrid = this.detectGrid();
58
- this.gridWidth = 0;
59
- this.gridHeight = 0;
60
- this.limitSpan = 0;
61
- this.widthSpan = 0;
62
- this.heightSpan = 0;
63
- this.originClassAttribute = this.resizeWidget.getAttribute('class');
64
-
65
- DIRECTIONS.map(d => {
66
- this.Drags[d] = this.resizeWidget.querySelector(handleObj['drag' + d.charAt(0).toUpperCase() + d.slice(1)]);
67
- });
68
-
69
- this.bindListeners();
70
- this.initResize();
71
-
72
- //this is just for grid system
73
- this.getGridProperty();
74
- window.addEventListener('resize', this.checkGridColumns.bind(this));
75
- }
76
- },
77
-
78
- getGridProperty: function () {
79
- if (!this.resizeWidget.parentNode) return;
80
- let compStyles = window.getComputedStyle(this.resizeWidget.parentNode);
81
- let gridColumns = compStyles.gridTemplateColumns;
82
- let height = compStyles.gridAutoRows;
83
-
84
- if (gridColumns !== 'none') {
85
- let width = gridColumns.split(' ');
86
- this.limitSpan = width.length;
87
- this.gridColumnGap = Number.parseInt(compStyles.gridColumnGap);
88
- this.gridRowGap = Number.parseInt(compStyles.gridRowGap);
89
- this.gridWidth = Number.parseFloat(width[0]);
90
- this.gridHeight = Number.parseInt(height);
91
- }
92
- },
93
-
94
- checkGridColumns: function () {
95
- if (typeof this.resizeWidget !== 'undefined' && this.resizeWidget.parentNode) {
96
- let compStylesOfParent = window.getComputedStyle(this.resizeWidget.parentNode);
97
- let spans = 0;
98
- let gridColumns = compStylesOfParent.gridTemplateColumns.split(' ');
99
- let temp = gridColumns[0];
100
- gridColumns.map(v => {
101
- if (v == temp) spans++;
102
- });
103
- this.limitSpan = spans;
104
- if (this.resizeWidget.style['grid-column-end']) {
105
- let curClassAttributes = this.resizeWidget.getAttribute('class').split(' ');
106
- let prevColumnState = curClassAttributes[curClassAttributes.length - 1].split('_');
107
- let prevSpan = Number.parseInt(prevColumnState[1]);
108
- let curColumnState = this.resizeWidget.style['grid-column-end'].split(' ');
109
- let curSpan = Number.parseInt(curColumnState[1]);
110
-
111
- let span = 0;
112
- if (this.limitSpan >= prevSpan) span = prevSpan;
113
- else if (prevSpan > this.limitSpan) span = this.limitSpan;
114
- else span = Math.min(curSpan, this.limitSpan);
115
-
116
- this.resizeWidget.style['grid-column-end'] = 'span ' + span;
117
- }
118
- }
119
- },
120
-
121
- initResize: function () {
122
- DIRECTIONS.map(d => {
123
- if (this.Drags[d])
124
- this.addListenerMulti(this.Drags[d], EVENTS[0], this.checkCorners[d]);
125
- });
126
- },
127
-
128
- checkDragImplementation: function (e, from, to, offset, fcur, scur) {
129
- if (e.touches)
130
- e = e.touches[0];
131
- let other;
132
- if (to == 'top')
133
- other = 'bottom'
134
- else if (to == 'bottom')
135
- other = 'top'
136
- else if (to == 'left')
137
- other = 'right'
138
- else if (to == 'right')
139
- other = 'left'
140
- this.removeListenerMulti(this.Drags[from], EVENTS[1], this.initDrags[from]);
141
- this.removeListenerMulti(this.Drags[from], EVENTS[1], this.initDrags[to]);
142
- this.removeListenerMulti(this.Drags[from], EVENTS[1], this.initDrags[other]);
143
- this.addListenerMulti(this.Drags[from], EVENTS[1], this.initDrags[from]);
144
-
145
- if (offset < this.cornerSize && this.Drags[to]) {
146
- this.Drags[from].style.cursor = fcur;
147
- this.addListenerMulti(this.Drags[from], EVENTS[1], this.initDrags[to]);
148
- }
149
- else {
150
- this.Drags[from].style.cursor = scur;
151
- }
152
- },
153
-
154
- initDrag: function (e, idx) {
155
- e.preventDefault();
156
-
157
- if (!this.resizeWidget.hasAttribute('resizing')) {
158
- this.resizeWidget.setAttribute('resizing', '')
159
- }
160
-
161
- let selector = document.defaultView.getComputedStyle(this.resizeWidget);
162
- styleSheet.insertRule('iframe {pointer-events: none}', 0)
163
-
164
- if (idx == 'top' || idx == 'bottom') {
165
- this.startTop = parseInt(selector.top, 10);
166
- this.startHeight = parseInt(selector.height, 10);
167
-
168
- if (e.touches)
169
- this.startY = e.touches[0].clientY;
170
- else
171
- this.startY = e.clientY;
172
- }
173
- else {
174
- this.startLeft = parseInt(selector.left, 10);
175
- this.startRight = parseInt(selector.right, 10);
176
- this.startWidth = parseInt(selector.width, 10);
177
-
178
- if (e.touches)
179
- this.startX = e.touches[0].clientX;
180
- else
181
- this.startX = e.clientX;
182
- }
183
-
184
- this.addListenerMulti(document.documentElement, EVENTS[0], this.doDrags[idx]);
185
- this.addListenerMulti(document.documentElement, EVENTS[2], this.stopDrag);
186
- },
187
-
188
- initTopDrag: function (e) {
189
- this.initDrag(e, 'top');
190
- },
191
- initBottomDrag: function (e) {
192
- this.initDrag(e, 'bottom');
193
- },
194
- initLeftDrag: function (e) {
195
- this.initDrag(e, 'left');
196
-
197
- },
198
- initRightDrag: function (e) {
199
- this.initDrag(e, 'right');
200
- },
201
-
202
- //this is just for grid system
203
- setRowEnd: function (height) {
204
- if (this.gridHeight) {
205
- this.heightSpan = Math.ceil((height - (this.heightSpan - 1) * this.gridRowGap) / this.gridHeight);
206
- this.resizeWidget.style['grid-row-end'] = 'span ' + this.heightSpan;
207
- this.collaborate({ rowEnd: this.heightSpan })
208
- }
209
- },
210
-
211
- doTopDrag: function (e) {
212
- let top, height;
213
-
214
- if (e.touches)
215
- e = e.touches[0];
216
- top = this.startTop + e.clientY - this.startY;
217
- height = this.startHeight - e.clientY + this.startY;
218
-
219
- if (height < 10)
220
- return;
221
- if (!this.isGrid) {
222
- this.resizeWidget.style.top = top + 'px';
223
- this.collaborate({ top, height })
224
- }
225
- this.resizeWidget.style.height = height + 'px';
226
- this.setRowEnd(height);
227
- },
228
-
229
-
230
- doBottomDrag: function (e) {
231
- let height;
232
-
233
- if (e.touches)
234
- e = e.touches[0];
235
-
236
- height = this.startHeight + e.clientY - this.startY;
237
-
238
- if (height < 10)
239
- return;
240
- if (!this.isGrid)
241
- this.collaborate({ height })
242
-
243
- this.resizeWidget.style.height = height + 'px';
244
- this.setRowEnd(height);
245
- },
246
-
247
- //this is just for grid system
248
- setColumnEnd: function (width) {
249
- if (this.gridWidth) {
250
- let spans = Math.ceil((width - (this.widthSpan - 1) * this.gridColumnGap) / this.gridWidth);
251
- this.widthSpan = (spans > this.limitSpan) ? this.limitSpan : spans;
252
- this.resizeWidget.style['grid-column-end'] = 'span ' + this.widthSpan;
253
- this.collaborate({ columnEnd: this.widthSpan })
254
- }
255
- },
256
-
257
- doLeftDrag: function (e) {
258
- let left, right, width;
259
- if (e.touches)
260
- e = e.touches[0];
261
- left = this.startLeft + e.clientX - this.startX;
262
- right = this.startRight;
263
- width = this.startWidth - e.clientX + this.startX;
264
-
265
- if (width < 10)
266
- return;
267
- if (!this.isGrid) {
268
- this.resizeWidget.style.left = '';
269
- this.resizeWidget.style.right = right + 'px';
270
- this.collaborate({ left, width })
271
- }
272
-
273
- this.resizeWidget.style.width = width + 'px';
274
- this.setColumnEnd(width);
275
- },
276
-
277
-
278
- doRightDrag: function (e) {
279
- let width;
280
- if (e.touches)
281
- e = e.touches[0];
282
- width = this.startWidth + e.clientX - this.startX;
283
- if (width < 10)
284
- return;
285
-
286
- if (!this.isGrid)
287
- this.collaborate({ width })
288
-
289
- this.resizeWidget.style.width = width + 'px';
290
- this.setColumnEnd(width);
291
- },
292
-
293
- detectGrid: function () {
294
- let isGrid = false;
295
- if (this.resizeWidget.parentNode) {
296
- let compStyles = window.getComputedStyle(this.resizeWidget.parentNode);
297
- isGrid = (compStyles.display === 'grid');
298
- }
299
- this.isGrid = isGrid;
300
- return isGrid;
301
- },
302
-
303
- stopDrag: function (e) {
304
- styleSheet.deleteRule(0)
305
- if (this.resizeWidget.hasAttribute('resizing')) {
306
- this.resizeWidget.removeAttribute('resizing', '')
307
- }
308
-
309
- //this is just for grid system
310
- if (this.detectGrid()) {
311
- this.resizeWidget.style.width = null;
312
- this.resizeWidget.style.height = null;
313
- this.resizeWidget.style.left = null;
314
- this.resizeWidget.style.top = null;
315
-
316
- if (this.widthSpan) this.resizeWidget.setAttribute('class', this.originClassAttribute + ' grid-column-end:span_' + this.widthSpan);
317
- if (this.heightSpan) this.resizeWidget.setAttribute('class', this.originClassAttribute + ' grid-row-end:span_' + this.heightSpan);
318
- }
319
-
320
- DIRECTIONS.map(d => { this.removeListenerMulti(document.documentElement, EVENTS[0], this.doDrags[d]) });
321
- this.removeListenerMulti(document.documentElement, EVENTS[2], this.stopDrag);
322
- },
323
- checkLeftCorners: function (e) {
324
- let offset = e.clientY - this.getDistance(this.Drags['left'], true) + document.documentElement.scrollTop;
325
- if (offset > 10) {
326
- offset = this.getDistance(this.Drags['left'], true) + this.Drags['left'].clientHeight - e.clientY - document.documentElement.scrollTop;
327
- this.checkDragImplementation(e, 'left', 'bottom', offset, 'ne-resize', 'e-resize');
328
- } else {
329
- this.checkDragImplementation(e, 'left', 'top', offset, 'se-resize', 'e-resize');
330
- }
331
- },
332
- checkTopCorners: function (e) {
333
- let offset = e.clientX - this.getDistance(this.Drags['top'], false) + document.documentElement.scrollTop;
334
- if (offset > 10) {
335
- offset = this.getDistance(this.Drags['top'], false) + this.Drags['top'].clientWidth - e.clientX - document.documentElement.scrollLeft;
336
- this.checkDragImplementation(e, 'top', 'right', offset, 'ne-resize', 's-resize');
337
- } else {
338
- this.checkDragImplementation(e, 'top', 'left', offset, 'se-resize', 's-resize');
339
- }
340
- },
341
- checkBottomCorners: function (e) {
342
- let offset = e.clientX - this.getDistance(this.Drags['bottom'], false) + document.documentElement.scrollTop;
343
- if (offset > 10) {
344
- offset = this.getDistance(this.Drags['bottom'], false) + this.Drags['bottom'].clientWidth - e.clientX - document.documentElement.scrollLeft;
345
- this.checkDragImplementation(e, 'bottom', 'right', offset, 'se-resize', 's-resize');
346
- } else {
347
- this.checkDragImplementation(e, 'bottom', 'left', offset, 'ne-resize', 's-resize');
348
- }
349
- },
350
- checkRightCorners: function (e) {
351
- let offset = e.clientY - this.getDistance(this.Drags['right'], true) + document.documentElement.scrollTop;
352
- if (offset > 10) {
353
- offset = this.getDistance(this.Drags['right'], true) + this.Drags['right'].clientHeight - e.clientY - document.documentElement.scrollTop;
354
- this.checkDragImplementation(e, 'right', 'bottom', offset, 'se-resize', 'e-resize');
355
- } else {
356
- this.checkDragImplementation(e, 'right', 'top', offset, 'ne-resize', 'e-resize');
357
- }
358
- },
359
-
360
- bindListeners: function () {
361
- this.doDrags['left'] = this.doLeftDrag.bind(this);
362
- this.doDrags['top'] = this.doTopDrag.bind(this);
363
- this.doDrags['right'] = this.doRightDrag.bind(this);
364
- this.doDrags['bottom'] = this.doBottomDrag.bind(this);
365
-
366
- this.stopDrag = this.stopDrag.bind(this);
367
-
368
- this.checkCorners['left'] = this.checkLeftCorners.bind(this);
369
- this.checkCorners['top'] = this.checkTopCorners.bind(this);
370
- this.checkCorners['bottom'] = this.checkBottomCorners.bind(this);
371
- this.checkCorners['right'] = this.checkRightCorners.bind(this);
372
-
373
- this.initDrags['top'] = this.initTopDrag.bind(this);
374
- this.initDrags['left'] = this.initLeftDrag.bind(this);
375
- this.initDrags['bottom'] = this.initBottomDrag.bind(this);
376
- this.initDrags['right'] = this.initRightDrag.bind(this);
377
- },
378
-
379
- getDistance: function (elem, flag) {
380
- var location = 0;
381
- if (!elem) return;
382
- if (elem.offsetParent) {
383
- do {
384
- location += (flag) ? elem.offsetTop : elem.offsetLeft;
385
- elem = elem.offsetParent;
386
- } while (elem);
387
- }
388
- return location >= 0 ? location : 0;
389
- },
390
-
391
- // Bind multiiple events to a listener
392
- addListenerMulti: function (element, eventNames, listener) {
393
- var events = eventNames.split(' ');
394
- for (var i = 0, iLen = events.length; i < iLen; i++) {
395
- element.addEventListener(events[i], listener, { passive: false });
396
- }
397
- },
398
-
399
- // Remove multiiple events from a listener
400
- removeListenerMulti: function (element, eventNames, listener) {
401
- var events = eventNames.split(' ');
402
- for (var i = 0, iLen = events.length; i < iLen; i++) {
403
- element.removeEventListener(events[i], listener, { passive: false });
404
- }
405
- },
406
-
407
- collaborate: function ({ left, top, width, height, rowEnd, columnEnd }) {
408
- if (window.CoCreate && window.CoCreate.text) {
409
- let domTextEditor = this.resizeWidget.closest('[contenteditable]');
410
- if (domTextEditor) {
411
- if (left)
412
- CoCreate.text.setStyle({
413
- domTextEditor, target: this.resizeWidget, property: 'left', value: left + 'px'
414
- })
415
- if (top)
416
- CoCreate.text.setStyle({
417
- domTextEditor, target: this.resizeWidget, property: 'top', value: top + 'px'
418
- })
419
- if (width)
420
- CoCreate.text.setStyle({
421
- domTextEditor, target: this.resizeWidget, property: 'width', value: width + 'px'
422
- })
423
- if (height)
424
- CoCreate.text.setStyle({
425
- domTextEditor, target: this.resizeWidget, property: 'height', value: height + 'px'
426
- })
427
- if (rowEnd)
428
- CoCreate.text.setStyle({
429
- domTextEditor, target: this.resizeWidget, property: 'grid-row-end', value: 'span ' + rowEnd
430
- })
431
- if (columnEnd)
432
- CoCreate.text.setStyle({
433
- domTextEditor, target: this.resizeWidget, property: 'grid-column-end', value: 'span ' + columnEnd
434
- })
435
- }
436
- }
437
- }
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
+ }
438
598
  };
439
599
 
600
+ // Function to auto-resize the element based on its content
601
+ function autoResizeElement(element) {
602
+ // Reset height to auto to calculate scrollHeight correctly
603
+ element.style.height = "auto";
604
+
605
+ let scrollHeight;
606
+ if (element.contentDocument) {
607
+ scrollHeight = element.contentDocument.body.scrollHeight;
608
+ } else {
609
+ // For other elements, get scrollHeight directly
610
+ scrollHeight = element.scrollHeight;
611
+ }
612
+
613
+ // Set the height of the element to the calculated scrollHeight
614
+ element.style.height = scrollHeight + "px";
615
+ }
616
+
617
+ // Observe the resize of the element
618
+ function observeElementResize(element) {
619
+ const resizeObserver = new ResizeObserver(() => {
620
+ autoResizeElement(element);
621
+ });
622
+
623
+ resizeObserver.observe(element);
624
+ }
625
+
626
+ // Listen for input events on the entire document
627
+ function initAutoHeight(element) {
628
+ if (
629
+ element &&
630
+ !(element instanceof HTMLCollection) &&
631
+ !(element instanceof NodeList) &&
632
+ !Array.isArray(element)
633
+ )
634
+ element = [element];
635
+ else if (!element) {
636
+ element = document.querySelectorAll('[height="auto"]');
637
+
638
+ // Add event listener for iframes on load
639
+ document.addEventListener(
640
+ "input",
641
+ function (event) {
642
+ // Check if the target element has height="auto"
643
+ if (event.target.getAttribute("height") === "auto") {
644
+ autoResizeElement(event.target);
645
+ }
646
+ },
647
+ false
648
+ );
649
+
650
+ if (element.contentDocument) {
651
+ // Create a MutationObserver for changes within the iframe's body
652
+ const observer = new MutationObserver(autoResizeElement);
653
+ observer.observe(iframeDocument.body, {
654
+ childList: true,
655
+ subtree: true
656
+ });
657
+
658
+ // Handle iframe document changes (e.g., if src or srcdoc is modified)
659
+ element.addEventListener("load", () => {
660
+ observer.disconnect(); // Disconnect the previous observer
661
+ observeIframeContent(); // Reinitialize the observer on new document
662
+ });
663
+ }
664
+ }
665
+
666
+ for (let i = 0; i < element.length; i++) {
667
+ autoResizeElement(element[i]);
668
+ observeElementResize(element[i]); // Observe resize changes
669
+ }
670
+ }
671
+
672
+ initAutoHeight();
673
+
440
674
  observer.init({
441
- name: 'CoCreateResize',
442
- observe: ['addedNodes'],
443
- selector: "[resizable]:not([resizable='false'])",
444
- callback: function (mutation) {
445
- coCreateResize.initElement(mutation.target);
675
+ name: "CoCreateResize",
676
+ observe: ["addedNodes"],
677
+ selector: "[resizable]:not([resizable='false'])",
678
+ callback: function (mutation) {
679
+ coCreateResize.initElement(mutation.target);
680
+ }
681
+ });
446
682
 
447
- }
683
+ observer.init({
684
+ name: "CoCreateResize",
685
+ observe: ["addedNodes"],
686
+ selector: "[height='auto']",
687
+ callback: function (mutation) {
688
+ initAutoHeight(mutation.target);
689
+ }
448
690
  });
449
691
 
450
692
  coCreateResize.init({
451
- selector: "[resizable]:not([resizable='false'])",
452
- dragLeft: "[resize='left']",
453
- dragRight: "[resize='right']",
454
- dragTop: "[resize='top']",
455
- dragBottom: "[resize='bottom']",
693
+ selector: "[resizable]:not([resizable='false'])",
694
+ dragLeft: "[resize='left']",
695
+ dragRight: "[resize='right']",
696
+ dragTop: "[resize='top']",
697
+ dragBottom: "[resize='bottom']"
456
698
  });
457
699
  export default coCreateResize;