@innovastudio/contentbuilder 1.4.146 → 1.4.148
Sign up to get free protection for your applications and to get access to all the features.
@@ -10355,6 +10355,14 @@ class HtmlUtil {
|
|
10355
10355
|
this.builder.opts.onRender();
|
10356
10356
|
}
|
10357
10357
|
if (mode === 'full') {
|
10358
|
+
// freeform
|
10359
|
+
if (this.builder.docContainer) {
|
10360
|
+
this.builder.loadHTML(html);
|
10361
|
+
util.clearControls();
|
10362
|
+
this.builder.hideModal(modal);
|
10363
|
+
return;
|
10364
|
+
}
|
10365
|
+
|
10358
10366
|
// area.innerHTML = html;
|
10359
10367
|
area.innerHTML = '';
|
10360
10368
|
// Use createContextualFragment() to make embedded script executable
|
@@ -11204,6 +11212,23 @@ class HtmlUtil {
|
|
11204
11212
|
elms = tmp.querySelectorAll('[data-html-25]');
|
11205
11213
|
dom$k.removeAttributes(elms, 'data-html-25');
|
11206
11214
|
}
|
11215
|
+
|
11216
|
+
// freeform
|
11217
|
+
elms = tmp.querySelectorAll('.is-block .handle, .is-block .rotate-handle');
|
11218
|
+
dom$k.removeElements(elms);
|
11219
|
+
elms = tmp.querySelectorAll('.is-block');
|
11220
|
+
Array.prototype.forEach.call(elms, elm => {
|
11221
|
+
dom$k.removeClass(elm, 'active');
|
11222
|
+
dom$k.removeClass(elm, 'multi');
|
11223
|
+
dom$k.removeClass(elm, 'editable');
|
11224
|
+
dom$k.removeClass(elm, 'fluid');
|
11225
|
+
dom$k.removeClass(elm, 'cloned');
|
11226
|
+
elm.removeAttribute('data-fluid-val');
|
11227
|
+
elm.removeAttribute('data-fluid');
|
11228
|
+
});
|
11229
|
+
tmp.querySelectorAll('.is-block.clone').forEach(elm => elm.parentNode.removeChild(elm));
|
11230
|
+
// tmp.querySelectorAll('.is-block.cloned').forEach(elm=>elm.classList.remove('cloned'));
|
11231
|
+
|
11207
11232
|
html = tmp.innerHTML.trim();
|
11208
11233
|
html = html.replace(/<font/g, '<span').replace(/<\/font/g, '</span');
|
11209
11234
|
}
|
@@ -13287,26 +13312,26 @@ const renderQuickAdd = builder => {
|
|
13287
13312
|
elm = quickadd.querySelector('.add-button');
|
13288
13313
|
if (elm) dom.addEventListener(elm, 'click', () => {
|
13289
13314
|
const mode = quickadd.getAttribute('data-mode');
|
13290
|
-
let html = `<div
|
13291
|
-
|
13315
|
+
let html = `<div>
|
13316
|
+
<a href="#" role="button" class="transition-all inline-block whitespace-nowrap cursor-pointer no-underline border-2 border-solid mr-2 mt-2 mb-1 py-2 size-17 px-6 text-black leading-14 rounded border-transparent hover:border-transparent font-normal tracking-wide" style="background-color: rgb(240, 240, 240);">Read More</a>
|
13292
13317
|
</div>`;
|
13293
13318
|
if (builder.opts.emailMode) {
|
13294
|
-
html = '<div
|
13319
|
+
html = '<div><a href="#" role="button" style="margin-top: ;margin-right: ;margin-bottom: ;margin-left: ;display: inline-block; text-decoration: none; transition: all 0.16s ease 0s; border-style: solid; cursor: pointer; background-color: rgb(220, 220, 220); color: rgb(0, 0, 0); border-color: rgb(220, 220, 220); border-width: 2px; border-radius: 0px; padding: 13px 28px; line-height: 21px; text-transform: uppercase; font-weight: 400; font-size: 14px; letter-spacing: 3px;">Read More</a></div>';
|
13295
13320
|
}
|
13296
13321
|
util.addContent(html, mode);
|
13297
13322
|
});
|
13298
13323
|
elm = quickadd.querySelector('.add-twobutton');
|
13299
13324
|
if (elm) dom.addEventListener(elm, 'click', () => {
|
13300
13325
|
const mode = quickadd.getAttribute('data-mode');
|
13301
|
-
let html = `<div
|
13326
|
+
let html = `<div>
|
13302
13327
|
<a href="#" role="button" class="transition-all inline-block whitespace-nowrap cursor-pointer no-underline border-2 border-solid mr-2 mt-2 mb-1 py-2 size-17 px-6 text-black leading-14 rounded border-transparent hover:border-transparent font-normal tracking-wide" style="background-color: rgb(240, 240, 240);">Read More</a>
|
13303
13328
|
<a href="#" role="button" class="transition-all inline-block whitespace-nowrap cursor-pointer no-underline border-2 border-solid mr-2 mt-2 mb-1 py-2 size-17 px-6 border-current hover:border-current font-normal leading-14 rounded tracking-wide">Get Started</a>
|
13304
13329
|
</div>`;
|
13305
13330
|
if (builder.opts.emailMode) {
|
13306
|
-
html = `<div
|
13307
|
-
|
13308
|
-
|
13309
|
-
|
13331
|
+
html = `<div>
|
13332
|
+
<a href="#" role="button" style="margin-top: ;margin-right: ;margin-bottom: ;margin-left: ;display: inline-block; text-decoration: none; transition: all 0.16s ease 0s; border-style: solid; cursor: pointer; background-color: rgb(220, 220, 220); color: rgb(0, 0, 0); border-color: rgb(220, 220, 220); border-width: 2px; border-radius: 0px; padding: 13px 28px; line-height: 21px; text-transform: uppercase; font-weight: 400; font-size: 14px; letter-spacing: 3px;">Read More</a>
|
13333
|
+
<a href="#" role="button" style="display: inline-block; text-decoration: none; transition: all 0.16s ease 0s; border-style: solid; cursor: pointer; background-color: rgba(0, 0, 0, 0); border-color: rgb(53, 53, 53); border-width: 2px; border-radius: 0px; padding: 13px 28px; line-height: 21px; text-transform: uppercase; font-weight: 600; font-size: 14px; letter-spacing: 3px; color: rgb(53, 53, 53);">Get Started</a>
|
13334
|
+
</div>`;
|
13310
13335
|
}
|
13311
13336
|
util.addContent(html, mode);
|
13312
13337
|
});
|
@@ -14530,7 +14555,7 @@ Insipred by: https://www.kirupa.com/html5/drag.htm
|
|
14530
14555
|
*/
|
14531
14556
|
|
14532
14557
|
let initialX, initialY, currentX, currentY, xOffset, yOffset, dragActive, activeDraggableBox;
|
14533
|
-
class Draggable$
|
14558
|
+
class Draggable$2 {
|
14534
14559
|
constructor(opts = {}) {
|
14535
14560
|
this.opts = opts;
|
14536
14561
|
const elms = document.querySelectorAll(this.opts.selector);
|
@@ -14694,7 +14719,7 @@ const renderGridEditor = builder => {
|
|
14694
14719
|
//<button title="${util.out('Element Tool')}" class="cell-elmtool"><svg class="is-icon-flex" style="width:12px;height:12px;"><use xlink:href="#ion-ios-gear"></use></svg></button>
|
14695
14720
|
|
14696
14721
|
dom.appendHtml(builderStuff, html);
|
14697
|
-
new Draggable$
|
14722
|
+
new Draggable$2({
|
14698
14723
|
selector: '.is-draggable'
|
14699
14724
|
});
|
14700
14725
|
const grideditor = document.querySelector('.grideditor');
|
@@ -28675,7 +28700,7 @@ function dragControlCondition(moveable, e) {
|
|
28675
28700
|
return false;
|
28676
28701
|
}
|
28677
28702
|
|
28678
|
-
var Rotatable = {
|
28703
|
+
var Rotatable$1 = {
|
28679
28704
|
name: "rotatable",
|
28680
28705
|
canPinch: true,
|
28681
28706
|
props: {
|
@@ -28814,7 +28839,7 @@ var Rotatable = {
|
|
28814
28839
|
datas.startValue = rotatation * Math.PI / 180;
|
28815
28840
|
}
|
28816
28841
|
}, fillTransformStartEvent(e)), {
|
28817
|
-
dragStart: Draggable.dragStart(moveable, new CustomGesto().dragStart([0, 0], e))
|
28842
|
+
dragStart: Draggable$1.dragStart(moveable, new CustomGesto().dragStart([0, 0], e))
|
28818
28843
|
}));
|
28819
28844
|
var result = triggerEvent(moveable, "onRotateStart", params);
|
28820
28845
|
datas.isRotate = result !== false;
|
@@ -32515,7 +32540,7 @@ var Snappable = {
|
|
32515
32540
|
* @description Draggable refers to the ability to drag and move targets.
|
32516
32541
|
*/
|
32517
32542
|
|
32518
|
-
var Draggable = {
|
32543
|
+
var Draggable$1 = {
|
32519
32544
|
name: "draggable",
|
32520
32545
|
props: {
|
32521
32546
|
draggable: Boolean,
|
@@ -33403,7 +33428,7 @@ function fillTransformEvent(moveable, nextTransform, delta, isPinch, e) {
|
|
33403
33428
|
fillOriginalTransform(e, nextTransform);
|
33404
33429
|
return {
|
33405
33430
|
transform: nextTransform,
|
33406
|
-
drag: Draggable.drag(moveable, setCustomDrag(e, moveable.state, delta, isPinch, false))
|
33431
|
+
drag: Draggable$1.drag(moveable, setCustomDrag(e, moveable.state, delta, isPinch, false))
|
33407
33432
|
};
|
33408
33433
|
}
|
33409
33434
|
|
@@ -35300,7 +35325,7 @@ var Pinchable = makeAble("pinchable", {
|
|
35300
35325
|
* @description Resizable indicates whether the target's width and height can be increased or decreased.
|
35301
35326
|
*/
|
35302
35327
|
|
35303
|
-
var Resizable = {
|
35328
|
+
var Resizable$1 = {
|
35304
35329
|
name: "resizable",
|
35305
35330
|
ableGroup: "size",
|
35306
35331
|
canPinch: true,
|
@@ -35445,7 +35470,7 @@ var Resizable = {
|
|
35445
35470
|
setOrigin: function (origin) {
|
35446
35471
|
datas.transformOrigin = origin;
|
35447
35472
|
},
|
35448
|
-
dragStart: Draggable.dragStart(moveable, new CustomGesto().dragStart([0, 0], e))
|
35473
|
+
dragStart: Draggable$1.dragStart(moveable, new CustomGesto().dragStart([0, 0], e))
|
35449
35474
|
});
|
35450
35475
|
var result = triggerEvent(moveable, "onResizeStart", params);
|
35451
35476
|
|
@@ -35630,7 +35655,7 @@ var Resizable = {
|
|
35630
35655
|
dist: [distWidth, distHeight],
|
35631
35656
|
delta: delta,
|
35632
35657
|
isPinch: !!isPinch,
|
35633
|
-
drag: Draggable.drag(moveable, setCustomDrag(e, moveable.state, inverseDelta, !!isPinch, false))
|
35658
|
+
drag: Draggable$1.drag(moveable, setCustomDrag(e, moveable.state, inverseDelta, !!isPinch, false))
|
35634
35659
|
});
|
35635
35660
|
triggerEvent(moveable, "onResize", params);
|
35636
35661
|
return params;
|
@@ -36222,7 +36247,7 @@ var Scalable = {
|
|
36222
36247
|
setRatio: setRatio,
|
36223
36248
|
setFixedDirection: setFixedDirection
|
36224
36249
|
}, fillTransformStartEvent(e)), {
|
36225
|
-
dragStart: Draggable.dragStart(moveable, new CustomGesto().dragStart([0, 0], e))
|
36250
|
+
dragStart: Draggable$1.dragStart(moveable, new CustomGesto().dragStart([0, 0], e))
|
36226
36251
|
}));
|
36227
36252
|
var result = triggerEvent(moveable, "onScaleStart", params);
|
36228
36253
|
|
@@ -39365,7 +39390,7 @@ var OriginDraggable = {
|
|
39365
39390
|
var datas = e.datas;
|
39366
39391
|
setDragStart(moveable, e);
|
39367
39392
|
var params = fillParams(moveable, e, {
|
39368
|
-
dragStart: Draggable.dragStart(moveable, new CustomGesto().dragStart([0, 0], e))
|
39393
|
+
dragStart: Draggable$1.dragStart(moveable, new CustomGesto().dragStart([0, 0], e))
|
39369
39394
|
});
|
39370
39395
|
var result = triggerEvent(moveable, "onDragOriginStart", params);
|
39371
39396
|
datas.startOrigin = moveable.state.transformOrigin;
|
@@ -39428,7 +39453,7 @@ var OriginDraggable = {
|
|
39428
39453
|
dist: dist,
|
39429
39454
|
delta: delta,
|
39430
39455
|
transformOrigin: transformOrigin,
|
39431
|
-
drag: Draggable.drag(moveable, setCustomDrag(e, moveable.state, dragDelta, !!isPinch, false))
|
39456
|
+
drag: Draggable$1.drag(moveable, setCustomDrag(e, moveable.state, dragDelta, !!isPinch, false))
|
39432
39457
|
});
|
39433
39458
|
triggerEvent(moveable, "onDragOrigin", params);
|
39434
39459
|
return params;
|
@@ -41840,13 +41865,13 @@ var edgeDraggable = makeAble("edgeDraggable", {
|
|
41840
41865
|
return hasClass(target, prefix("direction")) && hasClass(target, prefix("line"));
|
41841
41866
|
},
|
41842
41867
|
dragControlStart: function (moveable, e) {
|
41843
|
-
return Draggable.dragStart(moveable, getDraggableEvent(e));
|
41868
|
+
return Draggable$1.dragStart(moveable, getDraggableEvent(e));
|
41844
41869
|
},
|
41845
41870
|
dragControl: function (moveable, e) {
|
41846
|
-
return Draggable.drag(moveable, getDraggableEvent(e));
|
41871
|
+
return Draggable$1.drag(moveable, getDraggableEvent(e));
|
41847
41872
|
},
|
41848
41873
|
dragControlEnd: function (moveable, e) {
|
41849
|
-
return Draggable.dragEnd(moveable, getDraggableEvent(e));
|
41874
|
+
return Draggable$1.dragEnd(moveable, getDraggableEvent(e));
|
41850
41875
|
},
|
41851
41876
|
dragGroupControlCondition: function (moveable, e) {
|
41852
41877
|
if (!moveable.props.edgeDraggable || !e.inputEvent) {
|
@@ -41857,16 +41882,16 @@ var edgeDraggable = makeAble("edgeDraggable", {
|
|
41857
41882
|
return hasClass(target, prefix("direction")) && hasClass(target, prefix("line"));
|
41858
41883
|
},
|
41859
41884
|
dragGroupControlStart: function (moveable, e) {
|
41860
|
-
return Draggable.dragGroupStart(moveable, getDraggableEvent(e));
|
41885
|
+
return Draggable$1.dragGroupStart(moveable, getDraggableEvent(e));
|
41861
41886
|
},
|
41862
41887
|
dragGroupControl: function (moveable, e) {
|
41863
|
-
return Draggable.dragGroup(moveable, getDraggableEvent(e));
|
41888
|
+
return Draggable$1.dragGroup(moveable, getDraggableEvent(e));
|
41864
41889
|
},
|
41865
41890
|
dragGroupControlEnd: function (moveable, e) {
|
41866
|
-
return Draggable.dragGroupEnd(moveable, getDraggableEvent(e));
|
41891
|
+
return Draggable$1.dragGroupEnd(moveable, getDraggableEvent(e));
|
41867
41892
|
},
|
41868
41893
|
unset: function (moveable) {
|
41869
|
-
return Draggable.unset(moveable);
|
41894
|
+
return Draggable$1.unset(moveable);
|
41870
41895
|
}
|
41871
41896
|
});
|
41872
41897
|
/**
|
@@ -41890,7 +41915,7 @@ var IndividualGroupable = {
|
|
41890
41915
|
},
|
41891
41916
|
events: {}
|
41892
41917
|
};
|
41893
|
-
var MOVEABLE_ABLES = [BeforeRenderable, Default, Snappable, Pinchable, Draggable, edgeDraggable, Rotatable, Resizable, Scalable, Warpable, Scrollable, Padding, Origin, OriginDraggable, Clippable, Roundable, Groupable, IndividualGroupable, Clickable, DragArea, Renderable];
|
41918
|
+
var MOVEABLE_ABLES = [BeforeRenderable, Default, Snappable, Pinchable, Draggable$1, edgeDraggable, Rotatable$1, Resizable$1, Scalable, Warpable, Scrollable, Padding, Origin, OriginDraggable, Clippable, Roundable, Groupable, IndividualGroupable, Clickable, DragArea, Renderable];
|
41894
41919
|
var MOVEABLE_EVENTS_PROPS_MAP = /*#__PURE__*/MOVEABLE_ABLES.reduce(function (current, able) {
|
41895
41920
|
return __assign$2(__assign$2({}, current), "events" in able ? able.events : {});
|
41896
41921
|
}, {});
|
@@ -52087,7 +52112,7 @@ class ColorPicker {
|
|
52087
52112
|
});
|
52088
52113
|
};
|
52089
52114
|
setupTabKeys(pickcolor);
|
52090
|
-
new Draggable$
|
52115
|
+
new Draggable$2({
|
52091
52116
|
selector: '#' + this.id + ' .is-draggable'
|
52092
52117
|
});
|
52093
52118
|
let tmp = document.createElement('div');
|
@@ -52952,7 +52977,7 @@ class GradientPicker {
|
|
52952
52977
|
});
|
52953
52978
|
};
|
52954
52979
|
setupTabKeys(pickGradient);
|
52955
|
-
new Draggable$
|
52980
|
+
new Draggable$2({
|
52956
52981
|
selector: '#' + this.id + ' .is-draggable'
|
52957
52982
|
});
|
52958
52983
|
const colorPicker = new ColorPicker({
|
@@ -75403,7 +75428,2106 @@ class Similarity {
|
|
75403
75428
|
}
|
75404
75429
|
}
|
75405
75430
|
|
75406
|
-
|
75431
|
+
class Common {
|
75432
|
+
constructor(options) {
|
75433
|
+
this.selector = options && options.selector || '.is-block';
|
75434
|
+
this.doc = options && options.doc || document;
|
75435
|
+
this.win = options && options.win || window;
|
75436
|
+
this.onDuplicate = options && options.onDuplicate || null;
|
75437
|
+
}
|
75438
|
+
transform2d(block, x1, y1, x2, y2, x3, y3, x4, y4) {
|
75439
|
+
this.matrix3d = new Matrix3D();
|
75440
|
+
return this.matrix3d.transform2d(block, x1, y1, x2, y2, x3, y3, x4, y4);
|
75441
|
+
}
|
75442
|
+
applyPercentage(block) {
|
75443
|
+
const rect = this.getRect(block);
|
75444
|
+
const container = block.parentNode;
|
75445
|
+
let isChildBlock = false;
|
75446
|
+
if (block.parentNode.matches(this.selector)) {
|
75447
|
+
// child block
|
75448
|
+
isChildBlock = true;
|
75449
|
+
}
|
75450
|
+
|
75451
|
+
// const containerRect = container.getBoundingClientRect(); // if container has top/left
|
75452
|
+
const containerRect = this.getRect(container); // if container has top/left
|
75453
|
+
const left = (rect.left - containerRect.left) / container.offsetWidth * 100;
|
75454
|
+
const top = (rect.top - containerRect.top) / container.offsetHeight * 100;
|
75455
|
+
let isBlockFixed = block.classList.contains('block-steady');
|
75456
|
+
if (isBlockFixed) {
|
75457
|
+
let dividerTop = (container.offsetHeight - block.offsetHeight) / (rect.top - containerRect.top);
|
75458
|
+
if (isNaN(dividerTop)) {
|
75459
|
+
// there is possibility of 0/0
|
75460
|
+
dividerTop = 1;
|
75461
|
+
}
|
75462
|
+
block.style.top = `calc((100% - ${block.offsetHeight}px)/${dividerTop})`;
|
75463
|
+
if (isChildBlock) {
|
75464
|
+
block.style.top = top + '%';
|
75465
|
+
}
|
75466
|
+
let dividerLeft = (container.offsetWidth - block.offsetWidth) / (rect.left - containerRect.left);
|
75467
|
+
if (isNaN(dividerLeft)) {
|
75468
|
+
// there is possibility of 0/0
|
75469
|
+
dividerLeft = 1;
|
75470
|
+
}
|
75471
|
+
// if(rect.left-containerRect.left===0) { // dividerLeft = Infinity
|
75472
|
+
// dividerLeft=1;
|
75473
|
+
// }
|
75474
|
+
block.style.left = `calc((100% - ${block.offsetWidth}px)/${dividerLeft})`;
|
75475
|
+
if (isChildBlock) {
|
75476
|
+
block.style.left = left + '%';
|
75477
|
+
}
|
75478
|
+
} else {
|
75479
|
+
const width = block.offsetWidth / container.offsetWidth * 100;
|
75480
|
+
const height = block.offsetHeight / container.offsetHeight * 100;
|
75481
|
+
block.style.width = width + '%';
|
75482
|
+
block.style.height = height + '%';
|
75483
|
+
block.style.top = top + '%';
|
75484
|
+
block.style.left = left + '%';
|
75485
|
+
}
|
75486
|
+
}
|
75487
|
+
applyPixels(block) {
|
75488
|
+
const rect = this.getRect(block);
|
75489
|
+
const containerRect = this.getRect(block.parentNode); // if container has top/left
|
75490
|
+
block.style.left = rect.left - containerRect.left + 'px';
|
75491
|
+
block.style.top = rect.top - containerRect.top + 'px';
|
75492
|
+
block.style.width = block.offsetWidth + 'px';
|
75493
|
+
}
|
75494
|
+
updateHeight(block) {
|
75495
|
+
if (!block.parentNode) return;
|
75496
|
+
let clonedDiv = block.cloneNode(true);
|
75497
|
+
clonedDiv.style.position = 'absolute';
|
75498
|
+
clonedDiv.style.top = '-9999px';
|
75499
|
+
clonedDiv.style.left = '-9999px';
|
75500
|
+
block.parentNode.appendChild(clonedDiv);
|
75501
|
+
clonedDiv.style.height = '';
|
75502
|
+
setTimeout(() => {
|
75503
|
+
let clonedDivHeight = clonedDiv.offsetHeight;
|
75504
|
+
if (block.offsetHeight <= clonedDivHeight) {
|
75505
|
+
block.style.height = clonedDivHeight + 'px';
|
75506
|
+
setTimeout(() => {
|
75507
|
+
block.parentNode.removeChild(clonedDiv);
|
75508
|
+
}, 10);
|
75509
|
+
} else {
|
75510
|
+
block.parentNode.removeChild(clonedDiv);
|
75511
|
+
}
|
75512
|
+
}, 10);
|
75513
|
+
}
|
75514
|
+
duplicate() {
|
75515
|
+
const block = this.doc.querySelector(this.selector + '.active');
|
75516
|
+
if (!block) return;
|
75517
|
+
if (this.onDuplicate) this.onDuplicate(block);
|
75518
|
+
}
|
75519
|
+
getRect(element) {
|
75520
|
+
let group = element.parentNode.closest(this.selector);
|
75521
|
+
if (element.closest(this.selector) && group) {
|
75522
|
+
let transform = group.style.transform;
|
75523
|
+
if (transform.includes('rotate')) {
|
75524
|
+
// Create a temporary element with the same dimensions and position
|
75525
|
+
const tempGroup = this.doc.createElement('div');
|
75526
|
+
tempGroup.style.position = 'absolute';
|
75527
|
+
tempGroup.style.width = group.offsetWidth + 'px';
|
75528
|
+
tempGroup.style.height = group.offsetHeight + 'px';
|
75529
|
+
tempGroup.style.left = group.style.left;
|
75530
|
+
tempGroup.style.top = group.style.top;
|
75531
|
+
// tempGroup.style.border ='red 1px solid';
|
75532
|
+
group.parentNode.appendChild(tempGroup);
|
75533
|
+
// const wrapperRect = tempGroup.getBoundingClientRect(); // Get the unrotated position
|
75534
|
+
|
75535
|
+
// Create a temporary element with the same dimensions and position
|
75536
|
+
const tempElement = this.doc.createElement('div');
|
75537
|
+
tempElement.style.position = 'absolute';
|
75538
|
+
tempElement.style.width = element.offsetWidth + 'px';
|
75539
|
+
tempElement.style.height = element.offsetHeight + 'px';
|
75540
|
+
tempElement.style.left = element.style.left;
|
75541
|
+
tempElement.style.top = element.style.top;
|
75542
|
+
// tempElement.style.border ='green 1px solid';
|
75543
|
+
tempGroup.appendChild(tempElement);
|
75544
|
+
const tempRect = tempElement.getBoundingClientRect(); // Get the unrotated position
|
75545
|
+
|
75546
|
+
// let top = tempRect.top - wrapperRect.top;
|
75547
|
+
// let left = tempRect.left - wrapperRect.left;
|
75548
|
+
|
75549
|
+
setTimeout(() => {
|
75550
|
+
tempElement.parentNode.removeChild(tempElement);
|
75551
|
+
tempGroup.parentNode.removeChild(tempGroup);
|
75552
|
+
}, 0);
|
75553
|
+
return tempRect;
|
75554
|
+
}
|
75555
|
+
}
|
75556
|
+
const rect = element.getBoundingClientRect();
|
75557
|
+
const transform = this.win.getComputedStyle(element).getPropertyValue('transform');
|
75558
|
+
if (transform !== 'none') {
|
75559
|
+
// Create a temporary element with the same dimensions and position
|
75560
|
+
const tempElement = this.doc.createElement('div');
|
75561
|
+
tempElement.style.position = 'absolute';
|
75562
|
+
tempElement.style.width = element.offsetWidth + 'px';
|
75563
|
+
tempElement.style.height = element.offsetHeight + 'px';
|
75564
|
+
tempElement.style.left = element.style.left;
|
75565
|
+
tempElement.style.top = element.style.top;
|
75566
|
+
// tempElement.style.border ='green 1px solid';
|
75567
|
+
element.parentNode.appendChild(tempElement);
|
75568
|
+
|
75569
|
+
// Get the unrotated position of the temporary element
|
75570
|
+
const tempRect = tempElement.getBoundingClientRect();
|
75571
|
+
setTimeout(() => {
|
75572
|
+
tempElement.parentNode.removeChild(tempElement);
|
75573
|
+
}, 1);
|
75574
|
+
return tempRect;
|
75575
|
+
} else {
|
75576
|
+
return rect;
|
75577
|
+
}
|
75578
|
+
}
|
75579
|
+
getTranslateValues(transformString) {
|
75580
|
+
// Regular expression to match the translate values in the transform string
|
75581
|
+
const regex = /translate\((-?\d+\.?\d*)px, (-?\d+\.?\d*)px\)/;
|
75582
|
+
|
75583
|
+
// Use the regular expression to extract x and y values
|
75584
|
+
const match = transformString.match(regex);
|
75585
|
+
|
75586
|
+
// If there's a match, return an object with x and y values
|
75587
|
+
if (match) {
|
75588
|
+
const [, x, y] = match.map(parseFloat);
|
75589
|
+
return {
|
75590
|
+
x,
|
75591
|
+
y
|
75592
|
+
};
|
75593
|
+
}
|
75594
|
+
|
75595
|
+
// If no match, return null or handle it as needed
|
75596
|
+
return null;
|
75597
|
+
}
|
75598
|
+
group(className = 'is-block', groupClassName = 'is-group') {
|
75599
|
+
let top = Infinity;
|
75600
|
+
let left = Infinity;
|
75601
|
+
let bottom = -Infinity;
|
75602
|
+
let right = -Infinity;
|
75603
|
+
|
75604
|
+
// Check group
|
75605
|
+
let blocks = Array.from(this.doc.querySelectorAll(this.selector)).filter(elm => elm.classList.contains('active'));
|
75606
|
+
if (blocks.length <= 1) return;
|
75607
|
+
|
75608
|
+
// Check if there is selected block that is part of other group
|
75609
|
+
let ok = true;
|
75610
|
+
blocks.forEach(block => {
|
75611
|
+
if (block.parentNode.matches(this.selector)) {
|
75612
|
+
// TODO: detach block
|
75613
|
+
alert('One or more blocks belong to another group.');
|
75614
|
+
ok = false;
|
75615
|
+
}
|
75616
|
+
});
|
75617
|
+
if (!ok) return;
|
75618
|
+
blocks.forEach(block => {
|
75619
|
+
let elms = block.querySelectorAll(this.selector);
|
75620
|
+
if (elms.length > 0) {
|
75621
|
+
elms.forEach(elm => elm.classList.add('active'));
|
75622
|
+
this.unGroup(block);
|
75623
|
+
}
|
75624
|
+
});
|
75625
|
+
blocks = Array.from(this.doc.querySelectorAll(this.selector)).filter(elm => elm.classList.contains('active'));
|
75626
|
+
blocks.forEach(block => {
|
75627
|
+
if (!block.parentNode.matches(this.selector)) {
|
75628
|
+
const rect = this.getRect(block);
|
75629
|
+
let blockTop = rect.top;
|
75630
|
+
let blockLeft = rect.left;
|
75631
|
+
let blockWidth = block.offsetWidth;
|
75632
|
+
let blockHeight = block.offsetHeight;
|
75633
|
+
top = Math.min(top, blockTop);
|
75634
|
+
left = Math.min(left, blockLeft);
|
75635
|
+
bottom = Math.max(bottom, blockTop + blockHeight);
|
75636
|
+
right = Math.max(right, blockLeft + blockWidth);
|
75637
|
+
}
|
75638
|
+
});
|
75639
|
+
const group = this.doc.createElement('div');
|
75640
|
+
group.classList.add(className);
|
75641
|
+
group.classList.add(groupClassName);
|
75642
|
+
group.classList.add('block-steady');
|
75643
|
+
group.style.top = top + 'px';
|
75644
|
+
group.style.left = left + 'px';
|
75645
|
+
group.style.width = right + 1 - left + 'px';
|
75646
|
+
group.style.height = bottom + 1 - top + 'px';
|
75647
|
+
const container = blocks[0].parentNode;
|
75648
|
+
container.appendChild(group);
|
75649
|
+
blocks.forEach(block => {
|
75650
|
+
if (!block.parentNode.matches(this.selector)) {
|
75651
|
+
this.applyPixels(block);
|
75652
|
+
let blockTop = parseFloat(block.style.top) || 0;
|
75653
|
+
let blockLeft = parseFloat(block.style.left) || 0;
|
75654
|
+
|
75655
|
+
// Adjust position relative to the group div
|
75656
|
+
block.style.top = blockTop - top + 'px';
|
75657
|
+
block.style.left = blockLeft - left + 'px';
|
75658
|
+
group.appendChild(block);
|
75659
|
+
this.applyPercentage(block);
|
75660
|
+
}
|
75661
|
+
});
|
75662
|
+
this.applyPercentage(group);
|
75663
|
+
blocks.forEach(block => {
|
75664
|
+
block.classList.remove('active');
|
75665
|
+
});
|
75666
|
+
group.classList.add('active');
|
75667
|
+
blocks = group.querySelectorAll(this.selector);
|
75668
|
+
blocks.forEach(target => {
|
75669
|
+
// Remove all breakpoints
|
75670
|
+
let attributesToRemove = [];
|
75671
|
+
const attributes = target.attributes;
|
75672
|
+
for (let i = 0; i < attributes.length; i++) {
|
75673
|
+
const attributeName = attributes[i].name;
|
75674
|
+
if (attributeName.includes('data--y-') || attributeName.includes('data--x-') || attributeName.includes('data--w-') || attributeName.includes('data--h-')) {
|
75675
|
+
attributesToRemove.push(attributeName);
|
75676
|
+
}
|
75677
|
+
}
|
75678
|
+
attributesToRemove.forEach(attr => {
|
75679
|
+
target.removeAttribute(attr);
|
75680
|
+
});
|
75681
|
+
|
75682
|
+
// Make/save current inline style as default
|
75683
|
+
target.removeAttribute('data-breakpoint');
|
75684
|
+
target.setAttribute('data--y', target.style.top);
|
75685
|
+
target.setAttribute('data--x', target.style.left);
|
75686
|
+
target.setAttribute('data--w', target.style.width);
|
75687
|
+
target.setAttribute('data--h', target.style.height);
|
75688
|
+
});
|
75689
|
+
return group;
|
75690
|
+
}
|
75691
|
+
unGroup(element) {
|
75692
|
+
let group;
|
75693
|
+
if (element) group = element;else {
|
75694
|
+
let blocks = Array.from(this.doc.querySelectorAll(this.selector)).filter(elm => elm.classList.contains('active'));
|
75695
|
+
blocks.forEach(block => {
|
75696
|
+
if (block.querySelector(this.selector)) {
|
75697
|
+
// this block is a group
|
75698
|
+
this.unGroup(block);
|
75699
|
+
}
|
75700
|
+
});
|
75701
|
+
return;
|
75702
|
+
}
|
75703
|
+
if (!group) return;
|
75704
|
+
if (!group.querySelector(this.selector)) return;
|
75705
|
+
this.applyPixels(group);
|
75706
|
+
const rect = this.getRect(group);
|
75707
|
+
const top = rect.top;
|
75708
|
+
const left = rect.left;
|
75709
|
+
const container = group.parentNode;
|
75710
|
+
group.querySelectorAll(this.selector).forEach(block => {
|
75711
|
+
this.applyPixels(block);
|
75712
|
+
let blockTop = parseFloat(block.style.top) || 0;
|
75713
|
+
let blockLeft = parseFloat(block.style.left) || 0;
|
75714
|
+
|
75715
|
+
// Adjust position relative to the group div
|
75716
|
+
block.style.top = blockTop + top + 'px';
|
75717
|
+
block.style.left = blockLeft + left + 'px';
|
75718
|
+
container.appendChild(block);
|
75719
|
+
|
75720
|
+
// Remove all breakpoints
|
75721
|
+
let attributesToRemove = [];
|
75722
|
+
const attributes = block.attributes;
|
75723
|
+
for (let i = 0; i < attributes.length; i++) {
|
75724
|
+
const attributeName = attributes[i].name;
|
75725
|
+
if (attributeName.includes('data--y-') || attributeName.includes('data--x-') || attributeName.includes('data--w-') || attributeName.includes('data--h-')) {
|
75726
|
+
attributesToRemove.push(attributeName);
|
75727
|
+
}
|
75728
|
+
}
|
75729
|
+
attributesToRemove.forEach(attr => {
|
75730
|
+
block.removeAttribute(attr);
|
75731
|
+
});
|
75732
|
+
// Make/save current inline style as default
|
75733
|
+
block.removeAttribute('data-breakpoint');
|
75734
|
+
block.setAttribute('data--y', block.style.top);
|
75735
|
+
block.setAttribute('data--x', block.style.left);
|
75736
|
+
block.setAttribute('data--w', block.style.width);
|
75737
|
+
block.setAttribute('data--h', block.style.height);
|
75738
|
+
this.applyPercentage(block);
|
75739
|
+
});
|
75740
|
+
group.parentElement.removeChild(group);
|
75741
|
+
}
|
75742
|
+
addBreakpoint() {
|
75743
|
+
const viewportWidth = this.win.innerWidth;
|
75744
|
+
this.doc.body.setAttribute('data-breakpoint', viewportWidth);
|
75745
|
+
}
|
75746
|
+
|
75747
|
+
/*
|
75748
|
+
clearBreakpoint(target) {
|
75749
|
+
let breakpoint = target.getAttribute('data-breakpoint');
|
75750
|
+
if(!breakpoint) return;
|
75751
|
+
if(target.hasAttribute('data--y-'+breakpoint)) {
|
75752
|
+
target.removeAttribute('data--y-'+breakpoint);
|
75753
|
+
let top = target.getAttribute('data--y');
|
75754
|
+
if(top) target.style.top = top;
|
75755
|
+
}
|
75756
|
+
if(target.hasAttribute('data--x-'+breakpoint)) {
|
75757
|
+
target.removeAttribute('data--x-'+breakpoint);
|
75758
|
+
let left = target.getAttribute('data--x');
|
75759
|
+
if(left) target.style.left = left;
|
75760
|
+
}
|
75761
|
+
if(target.hasAttribute('data--w-'+breakpoint)) {
|
75762
|
+
target.removeAttribute('data--w-'+breakpoint);
|
75763
|
+
let width = target.getAttribute('data--w');
|
75764
|
+
if(width) target.style.width = width;
|
75765
|
+
}
|
75766
|
+
if(target.hasAttribute('data--h-'+breakpoint)) {
|
75767
|
+
target.removeAttribute('data--h-'+breakpoint);
|
75768
|
+
let height = target.getAttribute('data--h');
|
75769
|
+
if(height) target.style.height = height;
|
75770
|
+
}
|
75771
|
+
target.removeAttribute('data-breakpoint');
|
75772
|
+
// reset
|
75773
|
+
let top = target.getAttribute('data--y');
|
75774
|
+
if(top)target.style.top = top;
|
75775
|
+
let left = target.getAttribute('data--x');
|
75776
|
+
if(left) target.style.left = left;
|
75777
|
+
let width = target.getAttribute('data--w');
|
75778
|
+
if(width) target.style.width = width;
|
75779
|
+
let height = target.getAttribute('data--h');
|
75780
|
+
if(height) target.style.height = height;
|
75781
|
+
}
|
75782
|
+
*/
|
75783
|
+
|
75784
|
+
clearBreakpoint(target) {
|
75785
|
+
let attributesToRemove = [];
|
75786
|
+
const attributes = target.attributes;
|
75787
|
+
for (let i = 0; i < attributes.length; i++) {
|
75788
|
+
const attributeName = attributes[i].name;
|
75789
|
+
if (attributeName.includes('data--y-') || attributeName.includes('data--x-') || attributeName.includes('data--w-') || attributeName.includes('data--h-') || attributeName.includes('data--transform-') || attributeName.includes('data--matrix-')) {
|
75790
|
+
attributesToRemove.push(attributeName);
|
75791
|
+
}
|
75792
|
+
}
|
75793
|
+
attributesToRemove.forEach(attr => {
|
75794
|
+
target.removeAttribute(attr);
|
75795
|
+
});
|
75796
|
+
target.removeAttribute('data-breakpoint');
|
75797
|
+
|
75798
|
+
// reset
|
75799
|
+
let top = target.getAttribute('data--y');
|
75800
|
+
if (top) target.style.top = top;
|
75801
|
+
let left = target.getAttribute('data--x');
|
75802
|
+
if (left) target.style.left = left;
|
75803
|
+
let width = target.getAttribute('data--w');
|
75804
|
+
if (width) target.style.width = width;
|
75805
|
+
let height = target.getAttribute('data--h');
|
75806
|
+
if (height) target.style.height = height;
|
75807
|
+
}
|
75808
|
+
clearAllBreakpoints(container) {
|
75809
|
+
// REVIEW (Currently not used)
|
75810
|
+
const elements = container.querySelectorAll(this.selector);
|
75811
|
+
elements.forEach(target => {
|
75812
|
+
let attributesToRemove = [];
|
75813
|
+
const attributes = target.attributes;
|
75814
|
+
for (let i = 0; i < attributes.length; i++) {
|
75815
|
+
const attributeName = attributes[i].name;
|
75816
|
+
if (attributeName.includes('data--y-') || attributeName.includes('data--x-') || attributeName.includes('data--w-') || attributeName.includes('data--h-') || attributeName.includes('data--transform-') || attributeName.includes('data--matrix-')) {
|
75817
|
+
attributesToRemove.push(attributeName);
|
75818
|
+
}
|
75819
|
+
}
|
75820
|
+
attributesToRemove.forEach(attr => {
|
75821
|
+
target.removeAttribute(attr);
|
75822
|
+
});
|
75823
|
+
});
|
75824
|
+
elements.forEach(target => {
|
75825
|
+
let y = target.getAttribute('data--y');
|
75826
|
+
let x = target.getAttribute('data--x');
|
75827
|
+
let w = target.getAttribute('data--w');
|
75828
|
+
let h = target.getAttribute('data--h');
|
75829
|
+
if (y) target.style.top = y;
|
75830
|
+
if (x) target.style.left = x;
|
75831
|
+
if (w) target.style.width = w;
|
75832
|
+
if (h) target.style.height = h;
|
75833
|
+
});
|
75834
|
+
}
|
75835
|
+
getBreakpoints(target) {
|
75836
|
+
let breakpoints = [];
|
75837
|
+
const attributes = target.attributes;
|
75838
|
+
for (let i = 0; i < attributes.length; i++) {
|
75839
|
+
const attributeName = attributes[i].name;
|
75840
|
+
if (attributeName.includes('data--y-') || attributeName.includes('data--x-') || attributeName.includes('data--w-') || attributeName.includes('data--h-')) {
|
75841
|
+
let val = attributeName.replace('data--y-', '');
|
75842
|
+
val = val.replace('data--x-', '');
|
75843
|
+
val = val.replace('data--w-', '');
|
75844
|
+
val = val.replace('data--h-', '');
|
75845
|
+
if (!breakpoints.includes(val)) breakpoints.push(val);
|
75846
|
+
}
|
75847
|
+
}
|
75848
|
+
return breakpoints;
|
75849
|
+
}
|
75850
|
+
getSelectedBlock() {
|
75851
|
+
const blocks = Array.from(this.doc.querySelectorAll(this.selector)).filter(elm => elm.classList.contains('active') && !elm.classList.contains('cloned'));
|
75852
|
+
if (blocks.length === 1) {
|
75853
|
+
const block = blocks[0];
|
75854
|
+
return block;
|
75855
|
+
}
|
75856
|
+
return false;
|
75857
|
+
}
|
75858
|
+
checkOverlap(target) {
|
75859
|
+
const targetRect = target.getBoundingClientRect();
|
75860
|
+
const blocks = Array.from(target.parentNode.querySelectorAll(this.selector)).filter(elm => !elm.classList.contains('cloned'));
|
75861
|
+
let overlappedBlocks = [];
|
75862
|
+
for (const block of blocks) {
|
75863
|
+
if (block !== target) {
|
75864
|
+
const blockRect = block.getBoundingClientRect();
|
75865
|
+
if (targetRect.top < blockRect.bottom && targetRect.bottom > blockRect.top && targetRect.left < blockRect.right && targetRect.right > blockRect.left) {
|
75866
|
+
overlappedBlocks.push(block);
|
75867
|
+
}
|
75868
|
+
}
|
75869
|
+
}
|
75870
|
+
return overlappedBlocks;
|
75871
|
+
}
|
75872
|
+
}
|
75873
|
+
class Matrix3D {
|
75874
|
+
adj(m) {
|
75875
|
+
return [m[4] * m[8] - m[5] * m[7], m[2] * m[7] - m[1] * m[8], m[1] * m[5] - m[2] * m[4], m[5] * m[6] - m[3] * m[8], m[0] * m[8] - m[2] * m[6], m[2] * m[3] - m[0] * m[5], m[3] * m[7] - m[4] * m[6], m[1] * m[6] - m[0] * m[7], m[0] * m[4] - m[1] * m[3]];
|
75876
|
+
}
|
75877
|
+
multmm(a, b) {
|
75878
|
+
const c = Array(9);
|
75879
|
+
for (var i = 0; i != 3; ++i) {
|
75880
|
+
for (var j = 0; j != 3; ++j) {
|
75881
|
+
var cij = 0;
|
75882
|
+
for (var k = 0; k != 3; ++k) {
|
75883
|
+
cij += a[3 * i + k] * b[3 * k + j];
|
75884
|
+
}
|
75885
|
+
c[3 * i + j] = cij;
|
75886
|
+
}
|
75887
|
+
}
|
75888
|
+
return c;
|
75889
|
+
}
|
75890
|
+
multmv(m, v) {
|
75891
|
+
return [m[0] * v[0] + m[1] * v[1] + m[2] * v[2], m[3] * v[0] + m[4] * v[1] + m[5] * v[2], m[6] * v[0] + m[7] * v[1] + m[8] * v[2]];
|
75892
|
+
}
|
75893
|
+
pdbg(m, v) {
|
75894
|
+
const r = this.multmv(m, v);
|
75895
|
+
return r + ' (' + r[0] / r[2] + ', ' + r[1] / r[2] + ')';
|
75896
|
+
}
|
75897
|
+
basisToPoints(x1, y1, x2, y2, x3, y3, x4, y4) {
|
75898
|
+
const m = [x1, x2, x3, y1, y2, y3, 1, 1, 1];
|
75899
|
+
const v = this.multmv(this.adj(m), [x4, y4, 1]);
|
75900
|
+
return this.multmm(m, [v[0], 0, 0, 0, v[1], 0, 0, 0, v[2]]);
|
75901
|
+
}
|
75902
|
+
general2DProjection(x1s, y1s, x1d, y1d, x2s, y2s, x2d, y2d, x3s, y3s, x3d, y3d, x4s, y4s, x4d, y4d) {
|
75903
|
+
const s = this.basisToPoints(x1s, y1s, x2s, y2s, x3s, y3s, x4s, y4s);
|
75904
|
+
const d = this.basisToPoints(x1d, y1d, x2d, y2d, x3d, y3d, x4d, y4d);
|
75905
|
+
return this.multmm(d, this.adj(s));
|
75906
|
+
}
|
75907
|
+
project(m, x, y) {
|
75908
|
+
const v = this.multmv(m, [x, y, 1]);
|
75909
|
+
return [v[0] / v[2], v[1] / v[2]];
|
75910
|
+
}
|
75911
|
+
transform2d(element, x1, y1, x2, y2, x3, y3, x4, y4) {
|
75912
|
+
const w = element.offsetWidth,
|
75913
|
+
h = element.offsetHeight;
|
75914
|
+
let t = this.general2DProjection(0, 0, x1, y1, w, 0, x2, y2, 0, h, x3, y3, w, h, x4, y4);
|
75915
|
+
for (let i = 0; i != 9; ++i) t[i] = t[i] / t[8];
|
75916
|
+
t = [t[0], t[3], 0, t[6], t[1], t[4], 0, t[7], 0, 0, 1, 0, t[2], t[5], 0, t[8]];
|
75917
|
+
t = 'matrix3d(' + t.join(', ') + ')';
|
75918
|
+
return t;
|
75919
|
+
}
|
75920
|
+
}
|
75921
|
+
class Ruler {
|
75922
|
+
constructor(options) {
|
75923
|
+
this.selector = options && options.selector || '.is-block';
|
75924
|
+
this.doc = options && options.doc || document;
|
75925
|
+
this.win = options && options.win || window;
|
75926
|
+
const rulerHTML = `
|
75927
|
+
<div class="ruler horizontal-ruler" id="horizontal-ruler-top"></div>
|
75928
|
+
<div class="ruler horizontal-ruler" id="horizontal-ruler-bottom"></div>
|
75929
|
+
<div class="ruler horizontal-ruler" id="horizontal-ruler-middle"></div>
|
75930
|
+
<div class="ruler vertical-ruler" id="vertical-ruler-left"></div>
|
75931
|
+
<div class="ruler vertical-ruler" id="vertical-ruler-right"></div>
|
75932
|
+
<div class="ruler vertical-ruler" id="vertical-ruler-center"></div>
|
75933
|
+
`;
|
75934
|
+
if (!this.doc.getElementById('horizontal-ruler-top')) this.doc.body.insertAdjacentHTML('beforeend', rulerHTML);
|
75935
|
+
this.horizontalRulerTop = this.doc.getElementById('horizontal-ruler-top');
|
75936
|
+
this.horizontalRulerBottom = this.doc.getElementById('horizontal-ruler-bottom');
|
75937
|
+
this.horizontalRulerMiddle = this.doc.getElementById('horizontal-ruler-middle');
|
75938
|
+
this.verticalRulerLeft = this.doc.getElementById('vertical-ruler-left');
|
75939
|
+
this.verticalRulerRight = this.doc.getElementById('vertical-ruler-right');
|
75940
|
+
this.verticalRulerCenter = this.doc.getElementById('vertical-ruler-center');
|
75941
|
+
this.setup();
|
75942
|
+
}
|
75943
|
+
setup() {
|
75944
|
+
this.elements = this.doc.querySelectorAll(this.selector);
|
75945
|
+
}
|
75946
|
+
refresh() {
|
75947
|
+
this.elements = this.doc.querySelectorAll(this.selector);
|
75948
|
+
}
|
75949
|
+
destroy() {
|
75950
|
+
[this.horizontalRulerTop, this.horizontalRulerBottom, this.verticalRulerLeft, this.verticalRulerRight].forEach(elm => {
|
75951
|
+
if (elm.parentNode) elm.parentNode.removeChild(elm);
|
75952
|
+
});
|
75953
|
+
}
|
75954
|
+
hideRulers() {
|
75955
|
+
this.horizontalRulerTop.style.top = '-1000px';
|
75956
|
+
this.horizontalRulerBottom.style.top = '-1000px';
|
75957
|
+
this.horizontalRulerMiddle.style.top = '-1000px';
|
75958
|
+
this.verticalRulerLeft.style.left = '-1000px';
|
75959
|
+
this.verticalRulerRight.style.left = '-1000px';
|
75960
|
+
this.verticalRulerCenter.style.left = '-1000px';
|
75961
|
+
this.rulerTop = null;
|
75962
|
+
this.rulerLeft = null;
|
75963
|
+
this.rulerRight = null;
|
75964
|
+
}
|
75965
|
+
updateRulers(block) {
|
75966
|
+
// if(block.querySelector(this.selector)) return; // group (because updateRules also calls parent group if child block is dragged)
|
75967
|
+
|
75968
|
+
let transform = block.style.transform;
|
75969
|
+
if (transform.includes('rotate') || transform.includes('matrix3d')) return;
|
75970
|
+
let parentTransform = block.parentNode.style.transform;
|
75971
|
+
if (parentTransform.includes('rotate')) return;
|
75972
|
+
this.hideRulers();
|
75973
|
+
const rect = block.getBoundingClientRect();
|
75974
|
+
const top = rect.top;
|
75975
|
+
const bottom = top + block.offsetHeight;
|
75976
|
+
const left = rect.left;
|
75977
|
+
const right = left + block.offsetWidth;
|
75978
|
+
const center = left + block.offsetWidth / 2;
|
75979
|
+
const middle = top + block.offsetHeight / 2;
|
75980
|
+
this.rulerTop = null;
|
75981
|
+
this.rulerLeft = null;
|
75982
|
+
this.rulerRight = null;
|
75983
|
+
let containerTop = 0;
|
75984
|
+
const container = block.parentNode;
|
75985
|
+
if (container) {
|
75986
|
+
this.elements = container.querySelectorAll(this.selector);
|
75987
|
+
containerTop = this.win.scrollY;
|
75988
|
+
}
|
75989
|
+
this.elements.forEach(element => {
|
75990
|
+
if (!this.doc.body.contains(element)) return; // in case element removed (eg. unGroup, block deleted)
|
75991
|
+
|
75992
|
+
if (block.contains(element)) return; // In case of group moving
|
75993
|
+
|
75994
|
+
let transform = element.style.transform;
|
75995
|
+
let parentTransform = element.parentNode.style.transform;
|
75996
|
+
if (!transform.includes('rotate') && !parentTransform.includes('rotate') && !transform.includes('matrix3d') && !parentTransform.includes('matrix3d') && element !== block && !element.classList.contains('cloned')) {
|
75997
|
+
const rect = element.getBoundingClientRect();
|
75998
|
+
const otherTop = rect.top;
|
75999
|
+
const otherBottom = rect.top + element.offsetHeight;
|
76000
|
+
const otherLeft = rect.left;
|
76001
|
+
const otherRight = rect.left + element.offsetWidth;
|
76002
|
+
const otherMiddle = rect.top + element.offsetHeight / 2;
|
76003
|
+
const otherCenter = rect.left + element.offsetWidth / 2;
|
76004
|
+
if (otherMiddle - 4 <= middle && middle <= otherMiddle + 4) {
|
76005
|
+
this.horizontalRulerMiddle.style.top = containerTop + otherTop + (element.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
|
76006
|
+
let val = otherTop + (element.offsetHeight - block.offsetHeight) / 2;
|
76007
|
+
if (this.rulerTop === null) this.rulerTop = val;
|
76008
|
+
}
|
76009
|
+
if (otherCenter - 4 <= center && center <= otherCenter + 4) {
|
76010
|
+
this.verticalRulerCenter.style.left = otherLeft + (element.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
|
76011
|
+
this.verticalRulerCenter.style.top = containerTop + 'px'; // adj
|
76012
|
+
|
76013
|
+
let val = otherLeft + (element.offsetWidth - block.offsetWidth) / 2;
|
76014
|
+
if (this.rulerLeft === null) this.rulerLeft = val;
|
76015
|
+
}
|
76016
|
+
|
76017
|
+
// block top
|
76018
|
+
if (otherTop - 4 <= top && top <= otherTop + 4) {
|
76019
|
+
this.horizontalRulerTop.style.top = containerTop + otherTop + 'px';
|
76020
|
+
let val = otherTop;
|
76021
|
+
if (this.rulerTop === null) this.rulerTop = val;
|
76022
|
+
}
|
76023
|
+
if (otherBottom - 4 <= top && top <= otherBottom + 4) {
|
76024
|
+
this.horizontalRulerTop.style.top = containerTop + otherBottom + 'px';
|
76025
|
+
let val = otherBottom;
|
76026
|
+
if (this.rulerTop === null) this.rulerTop = val;
|
76027
|
+
}
|
76028
|
+
|
76029
|
+
// block bottom
|
76030
|
+
if (otherTop - 4 <= bottom && bottom <= otherTop + 4) {
|
76031
|
+
this.horizontalRulerBottom.style.top = containerTop + otherTop + 'px';
|
76032
|
+
let val = otherTop - block.offsetHeight;
|
76033
|
+
if (this.rulerTop === null) this.rulerTop = val;
|
76034
|
+
}
|
76035
|
+
if (otherBottom - 4 <= bottom && bottom <= otherBottom + 4) {
|
76036
|
+
this.horizontalRulerBottom.style.top = containerTop + otherBottom + 'px';
|
76037
|
+
let val = otherBottom - block.offsetHeight;
|
76038
|
+
if (this.rulerTop === null) this.rulerTop = val;
|
76039
|
+
}
|
76040
|
+
|
76041
|
+
// block left
|
76042
|
+
if (otherLeft - 4 <= left && left <= otherLeft + 4) {
|
76043
|
+
this.verticalRulerLeft.style.left = otherLeft + 'px';
|
76044
|
+
this.verticalRulerLeft.style.top = containerTop + 'px'; // adj
|
76045
|
+
|
76046
|
+
let val = otherLeft;
|
76047
|
+
if (this.rulerLeft === null) this.rulerLeft = val;
|
76048
|
+
}
|
76049
|
+
if (otherRight - 4 <= left && left <= otherRight + 4) {
|
76050
|
+
this.verticalRulerLeft.style.left = otherRight + 'px';
|
76051
|
+
this.verticalRulerLeft.style.top = containerTop + 'px'; // adj
|
76052
|
+
|
76053
|
+
let val = otherRight;
|
76054
|
+
if (this.rulerLeft === null) this.rulerLeft = val;
|
76055
|
+
}
|
76056
|
+
|
76057
|
+
// block right
|
76058
|
+
if (otherLeft - 4 <= right && right <= otherLeft + 4) {
|
76059
|
+
this.verticalRulerRight.style.left = otherLeft + 'px';
|
76060
|
+
this.verticalRulerRight.style.top = containerTop + 'px'; // adj
|
76061
|
+
|
76062
|
+
let val = otherLeft;
|
76063
|
+
if (this.rulerRight === null) this.rulerRight = val;
|
76064
|
+
}
|
76065
|
+
if (otherRight - 4 <= right && right <= otherRight + 4) {
|
76066
|
+
this.verticalRulerRight.style.left = otherRight + 'px';
|
76067
|
+
this.verticalRulerRight.style.top = containerTop + 'px'; // adj
|
76068
|
+
|
76069
|
+
let val = otherRight;
|
76070
|
+
if (this.rulerRight === null) this.rulerRight = val;
|
76071
|
+
}
|
76072
|
+
}
|
76073
|
+
});
|
76074
|
+
|
76075
|
+
// Edges
|
76076
|
+
const conRect = block.parentNode.getBoundingClientRect();
|
76077
|
+
const conTop = conRect.top;
|
76078
|
+
const conBottom = conRect.top + block.parentNode.offsetHeight;
|
76079
|
+
const conLeft = conRect.left;
|
76080
|
+
const conRight = conRect.left + block.parentNode.offsetWidth;
|
76081
|
+
const conCenter = conRect.left + block.parentNode.offsetWidth / 2;
|
76082
|
+
const conMiddle = conRect.top + block.parentNode.offsetHeight / 2;
|
76083
|
+
if (conMiddle - 4 <= middle && middle <= conMiddle + 4) {
|
76084
|
+
this.horizontalRulerMiddle.style.top = containerTop + conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
|
76085
|
+
let val = conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2;
|
76086
|
+
if (this.rulerTop === null) this.rulerTop = val;
|
76087
|
+
}
|
76088
|
+
if (conCenter - 4 <= center && center <= conCenter + 4) {
|
76089
|
+
this.verticalRulerCenter.style.left = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
|
76090
|
+
this.verticalRulerCenter.style.top = containerTop + 'px';
|
76091
|
+
let val = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2;
|
76092
|
+
if (this.rulerLeft === null) this.rulerLeft = val;
|
76093
|
+
}
|
76094
|
+
|
76095
|
+
// block top
|
76096
|
+
if (conTop - 4 <= top && top <= conTop + 4) {
|
76097
|
+
this.horizontalRulerTop.style.top = containerTop + conTop + 'px';
|
76098
|
+
let val = conTop;
|
76099
|
+
if (this.rulerTop === null) this.rulerTop = val;
|
76100
|
+
}
|
76101
|
+
// block bottom
|
76102
|
+
if (conBottom - 4 <= bottom && bottom <= conBottom + 4) {
|
76103
|
+
this.horizontalRulerBottom.style.top = containerTop + conBottom - 3 + 'px'; // -3 is an adjustment to make the line visible
|
76104
|
+
|
76105
|
+
let val = conBottom - block.offsetHeight;
|
76106
|
+
if (this.rulerTop === null) this.rulerTop = val;
|
76107
|
+
}
|
76108
|
+
// block left
|
76109
|
+
if (conLeft - 4 <= left && left <= conLeft + 4) {
|
76110
|
+
this.verticalRulerLeft.style.left = conLeft + 2 + 'px'; // +3 is an adjustment
|
76111
|
+
this.verticalRulerLeft.style.top = containerTop + 'px';
|
76112
|
+
let val = conLeft;
|
76113
|
+
if (this.rulerLeft === null) this.rulerLeft = val;
|
76114
|
+
}
|
76115
|
+
// block right
|
76116
|
+
if (conRight - 4 <= right && right <= conRight + 4) {
|
76117
|
+
this.verticalRulerRight.style.left = conRight - 2 + 'px'; // -2 is an adjustment
|
76118
|
+
this.verticalRulerRight.style.top = containerTop + 'px';
|
76119
|
+
let val = conRight;
|
76120
|
+
if (this.rulerRight === null) this.rulerRight = val;
|
76121
|
+
}
|
76122
|
+
}
|
76123
|
+
}
|
76124
|
+
class Rotatable {
|
76125
|
+
constructor(options) {
|
76126
|
+
this.selector = options && options.selector || '.is-block';
|
76127
|
+
this.doc = options && options.doc || document;
|
76128
|
+
this.win = options && options.win || window;
|
76129
|
+
this.onBeforeChange = options && options.onBeforeChange || null;
|
76130
|
+
this.onChange = options && options.onChange || null;
|
76131
|
+
this.disableOnMobile = options && options.disableOnMobile || 0;
|
76132
|
+
this.centerX = 0;
|
76133
|
+
this.centerY = 0;
|
76134
|
+
this.initialRotation = 0;
|
76135
|
+
this.handleRotateStart = this.handleRotateStart.bind(this);
|
76136
|
+
this.handleDblClick = this.handleDblClick.bind(this);
|
76137
|
+
this.handleRotateMove = this.handleRotateMove.bind(this);
|
76138
|
+
this.handleRotateEnd = this.handleRotateEnd.bind(this);
|
76139
|
+
this.setup();
|
76140
|
+
this.common = new Common({
|
76141
|
+
selector: this.selector
|
76142
|
+
});
|
76143
|
+
}
|
76144
|
+
setup() {
|
76145
|
+
this.elements = this.doc.querySelectorAll(this.selector);
|
76146
|
+
this.elements.forEach(element => {
|
76147
|
+
element.querySelectorAll('.rotate-handle').forEach(elm => elm.parentNode.removeChild(elm));
|
76148
|
+
const handleHTML = '<div class="rotate-handle" contentEditable="false"><div></div></div>';
|
76149
|
+
element.insertAdjacentHTML('afterbegin', handleHTML);
|
76150
|
+
const handles = Array.from(element.querySelectorAll('.rotate-handle')).filter(handle => handle.parentElement === element);
|
76151
|
+
handles.forEach(handle => {
|
76152
|
+
handle.addEventListener('mousedown', this.handleRotateStart);
|
76153
|
+
handle.addEventListener('touchstart', this.handleRotateStart, {
|
76154
|
+
passive: false
|
76155
|
+
});
|
76156
|
+
handle.addEventListener('dblclick', this.handleDblClick);
|
76157
|
+
});
|
76158
|
+
});
|
76159
|
+
}
|
76160
|
+
refresh() {
|
76161
|
+
this.elements = this.doc.querySelectorAll(this.selector);
|
76162
|
+
this.elements.forEach(element => {
|
76163
|
+
let handles = Array.from(element.querySelectorAll('.rotate-handle')).filter(handle => handle.parentElement === element); // only one handle
|
76164
|
+
handles.forEach(handle => {
|
76165
|
+
handle.removeEventListener('mousedown', this.handleRotateStart);
|
76166
|
+
handle.removeEventListener('touchstart', this.handleRotateStart);
|
76167
|
+
handle.removeEventListener('dblclick', this.handleDblClick);
|
76168
|
+
handle.parentNode.removeChild(handle);
|
76169
|
+
});
|
76170
|
+
const handleHTML = '<div class="rotate-handle" contentEditable="false"><div></div></div>';
|
76171
|
+
element.insertAdjacentHTML('afterbegin', handleHTML);
|
76172
|
+
handles = Array.from(element.querySelectorAll('.rotate-handle')).filter(handle => handle.parentElement === element); // only one handle
|
76173
|
+
handles.forEach(handle => {
|
76174
|
+
handle.addEventListener('mousedown', this.handleRotateStart);
|
76175
|
+
handle.addEventListener('touchstart', this.handleRotateStart, {
|
76176
|
+
passive: false
|
76177
|
+
});
|
76178
|
+
handle.addEventListener('dblclick', this.handleDblClick);
|
76179
|
+
});
|
76180
|
+
});
|
76181
|
+
}
|
76182
|
+
destroy(block) {
|
76183
|
+
if (block) {
|
76184
|
+
this.elements = this.doc.querySelectorAll(this.selector);
|
76185
|
+
this.elements.forEach(element => {
|
76186
|
+
if (element === block) {
|
76187
|
+
const handles = Array.from(element.querySelectorAll('.rotate-handle')).filter(handle => handle.parentElement === element);
|
76188
|
+
handles.forEach(handle => {
|
76189
|
+
handle.removeEventListener('mousedown', this.handleRotateStart);
|
76190
|
+
handle.removeEventListener('touchstart', this.handleRotateStart);
|
76191
|
+
handle.removeEventListener('dblclick', this.handleDblClick);
|
76192
|
+
handle.parentNode.removeChild(handle);
|
76193
|
+
});
|
76194
|
+
}
|
76195
|
+
});
|
76196
|
+
} else {
|
76197
|
+
this.elements = this.doc.querySelectorAll(this.selector);
|
76198
|
+
this.elements.forEach(element => {
|
76199
|
+
const handles = Array.from(element.querySelectorAll('.rotate-handle')).filter(handle => handle.parentElement === element);
|
76200
|
+
handles.forEach(handle => {
|
76201
|
+
handle.removeEventListener('mousedown', this.handleRotateStart);
|
76202
|
+
handle.removeEventListener('touchstart', this.handleRotateStart);
|
76203
|
+
handle.removeEventListener('dblclick', this.handleDblClick);
|
76204
|
+
handle.parentNode.removeChild(handle);
|
76205
|
+
});
|
76206
|
+
});
|
76207
|
+
}
|
76208
|
+
}
|
76209
|
+
handleDblClick(event) {
|
76210
|
+
if (this.onBeforeChange) this.onBeforeChange();
|
76211
|
+
event.preventDefault();
|
76212
|
+
event.stopImmediatePropagation();
|
76213
|
+
const block = event.target.parentNode;
|
76214
|
+
const transform = block.style.transform;
|
76215
|
+
if (transform.includes('rotate')) block.style.transform = '';
|
76216
|
+
this.clonedTarget = this.doc.querySelector(this.selector + '.cloned');
|
76217
|
+
if (this.clonedTarget) this.clonedTarget.style.transform = '';
|
76218
|
+
if (this.onChange) this.onChange();
|
76219
|
+
}
|
76220
|
+
handleRotateStart(event) {
|
76221
|
+
const viewportWidth = this.win.innerWidth;
|
76222
|
+
if (viewportWidth <= this.disableOnMobile) return;
|
76223
|
+
if (event.type === 'touchstart' && event.touches.length !== 1) {
|
76224
|
+
return; // Do nothing if more than one touch point is detected
|
76225
|
+
}
|
76226
|
+
|
76227
|
+
if (event.type === 'mousedown' && event.button !== 0) {
|
76228
|
+
return; // Do nothing if the right mouse button is clicked
|
76229
|
+
}
|
76230
|
+
|
76231
|
+
event.preventDefault();
|
76232
|
+
this.target = event.target.parentNode; // block
|
76233
|
+
|
76234
|
+
this.clonedTarget = this.doc.querySelector(this.selector + '.cloned');
|
76235
|
+
this.dragStartTimeout = setTimeout(() => {
|
76236
|
+
// Set a timeout before starting the drag (to differentiate from click)
|
76237
|
+
|
76238
|
+
if (event.type === 'mousedown') {
|
76239
|
+
this.startRotation(event.clientX, event.clientY);
|
76240
|
+
} else if (event.type === 'touchstart') {
|
76241
|
+
const touch = event.touches[0];
|
76242
|
+
this.startRotation(touch.clientX, touch.clientY);
|
76243
|
+
}
|
76244
|
+
this.doc.addEventListener('mousemove', this.handleRotateMove);
|
76245
|
+
this.doc.addEventListener('touchmove', this.handleRotateMove);
|
76246
|
+
}, 120);
|
76247
|
+
this.doc.addEventListener('mouseup', this.handleRotateEnd);
|
76248
|
+
this.doc.addEventListener('touchend', this.handleRotateEnd);
|
76249
|
+
}
|
76250
|
+
handleRotateMove() {
|
76251
|
+
let clientX, clientY;
|
76252
|
+
if (event.type === 'mousemove') {
|
76253
|
+
clientX = event.clientX;
|
76254
|
+
clientY = event.clientY;
|
76255
|
+
} else if (event.type === 'touchmove') {
|
76256
|
+
const touch = event.touches[0];
|
76257
|
+
clientX = touch.clientX;
|
76258
|
+
clientY = touch.clientY;
|
76259
|
+
}
|
76260
|
+
this.updateRotation(clientX, clientY);
|
76261
|
+
}
|
76262
|
+
handleRotateEnd() {
|
76263
|
+
clearTimeout(this.dragStartTimeout);
|
76264
|
+
this.doc.removeEventListener('mousemove', this.handleRotateMove);
|
76265
|
+
this.doc.removeEventListener('touchmove', this.handleRotateMove);
|
76266
|
+
this.doc.removeEventListener('mouseup', this.handleRotateEnd);
|
76267
|
+
this.doc.removeEventListener('touchend', this.handleRotateEnd);
|
76268
|
+
if (this.onChange) this.onChange();
|
76269
|
+
}
|
76270
|
+
getCurrentRotation(transform) {
|
76271
|
+
const match = transform.match(/rotate\(([-+]?\d*\.?\d*)deg\)/);
|
76272
|
+
return match ? parseFloat(match[1]) : 0;
|
76273
|
+
}
|
76274
|
+
startRotation() {
|
76275
|
+
if (this.onBeforeChange) this.onBeforeChange();
|
76276
|
+
const target = this.target;
|
76277
|
+
const rect = target.getBoundingClientRect();
|
76278
|
+
this.centerX = rect.left + rect.width / 2;
|
76279
|
+
this.centerY = rect.top + rect.height / 2;
|
76280
|
+
|
76281
|
+
// Store the initial rotation
|
76282
|
+
if (target.parentNode.matches(this.selector)) {
|
76283
|
+
const currentTransform = target.style.transform;
|
76284
|
+
let currentRotation = this.getCurrentRotation(currentTransform);
|
76285
|
+
this.initialRotation = currentRotation;
|
76286
|
+
const parentTransform = target.parentNode.style.transform;
|
76287
|
+
let parentRotation = this.getCurrentRotation(parentTransform);
|
76288
|
+
if (parentRotation) {
|
76289
|
+
this.initialRotation = parentRotation;
|
76290
|
+
}
|
76291
|
+
} else {
|
76292
|
+
this.initialRotation = 0; // If no child blocks
|
76293
|
+
}
|
76294
|
+
}
|
76295
|
+
|
76296
|
+
updateRotation(x, y) {
|
76297
|
+
const target = this.target;
|
76298
|
+
const angle = Math.atan2(y - this.centerY, x - this.centerX);
|
76299
|
+
const degrees = angle * (180 / Math.PI);
|
76300
|
+
const initialRotation = this.initialRotation || 0;
|
76301
|
+
target.style.transform = `rotate(${degrees - initialRotation}deg)`;
|
76302
|
+
if (this.clonedTarget) this.clonedTarget.style.transform = `rotate(${degrees - initialRotation}deg)`;
|
76303
|
+
}
|
76304
|
+
}
|
76305
|
+
class Resizable {
|
76306
|
+
constructor(options) {
|
76307
|
+
this.selector = options && options.selector || '.is-block';
|
76308
|
+
this.doc = options && options.doc || document;
|
76309
|
+
this.win = options && options.win || window;
|
76310
|
+
this.onBeforeChange = options && options.onBeforeChange || null;
|
76311
|
+
this.onChange = options && options.onChange || null;
|
76312
|
+
this.disableOnMobile = options && options.disableOnMobile || 0;
|
76313
|
+
this.isResizing = false;
|
76314
|
+
this.resizeHandle = null;
|
76315
|
+
this.startX = 0;
|
76316
|
+
this.startY = 0;
|
76317
|
+
this.elements = this.doc.querySelectorAll(this.selector);
|
76318
|
+
this.startResizing = this.startResizing.bind(this);
|
76319
|
+
this.handleResizeMove = this.handleResizeMove.bind(this);
|
76320
|
+
this.handleResizeEnd = this.handleResizeEnd.bind(this);
|
76321
|
+
this.setup();
|
76322
|
+
this.ruler = new Ruler({
|
76323
|
+
selector: this.selector,
|
76324
|
+
doc: this.doc,
|
76325
|
+
win: this.win
|
76326
|
+
});
|
76327
|
+
this.common = new Common({
|
76328
|
+
selector: this.selector,
|
76329
|
+
doc: this.doc,
|
76330
|
+
win: this.win
|
76331
|
+
});
|
76332
|
+
}
|
76333
|
+
setup() {
|
76334
|
+
this.elements.forEach(element => {
|
76335
|
+
element.querySelectorAll('.handle').forEach(elm => elm.parentNode.removeChild(elm));
|
76336
|
+
const handleHTML = `
|
76337
|
+
<div class="handle top-left"></div>
|
76338
|
+
<div class="handle top-right"></div>
|
76339
|
+
<div class="handle bottom-left"></div>
|
76340
|
+
<div class="handle bottom-right"></div>
|
76341
|
+
|
76342
|
+
<div class="handle top"></div>
|
76343
|
+
<div class="handle bottom"></div>
|
76344
|
+
<div class="handle left"></div>
|
76345
|
+
<div class="handle right"></div>`;
|
76346
|
+
element.insertAdjacentHTML('afterbegin', handleHTML);
|
76347
|
+
const handles = Array.from(element.querySelectorAll('.handle')).filter(handle => handle.parentElement === element);
|
76348
|
+
handles.forEach(handle => {
|
76349
|
+
handle.addEventListener('mousedown', this.startResizing);
|
76350
|
+
handle.addEventListener('touchstart', this.startResizing, {
|
76351
|
+
passive: false
|
76352
|
+
});
|
76353
|
+
});
|
76354
|
+
});
|
76355
|
+
}
|
76356
|
+
refresh() {
|
76357
|
+
this.elements = this.doc.querySelectorAll(this.selector);
|
76358
|
+
this.elements.forEach(element => {
|
76359
|
+
let handles = Array.from(element.querySelectorAll('.handle')).filter(handle => handle.parentElement === element);
|
76360
|
+
handles.forEach(handle => {
|
76361
|
+
handle.removeEventListener('mousedown', this.startResizing);
|
76362
|
+
handle.removeEventListener('touchstart', this.startResizing);
|
76363
|
+
handle.parentNode.removeChild(handle);
|
76364
|
+
});
|
76365
|
+
const handleHTML = `
|
76366
|
+
<div class="handle top-left"></div>
|
76367
|
+
<div class="handle top-right"></div>
|
76368
|
+
<div class="handle bottom-left"></div>
|
76369
|
+
<div class="handle bottom-right"></div>
|
76370
|
+
|
76371
|
+
<div class="handle top"></div>
|
76372
|
+
<div class="handle bottom"></div>
|
76373
|
+
<div class="handle left"></div>
|
76374
|
+
<div class="handle right"></div>`;
|
76375
|
+
element.insertAdjacentHTML('afterbegin', handleHTML);
|
76376
|
+
handles = Array.from(element.querySelectorAll('.handle')).filter(handle => handle.parentElement === element);
|
76377
|
+
handles.forEach(handle => {
|
76378
|
+
handle.addEventListener('mousedown', this.startResizing);
|
76379
|
+
handle.addEventListener('touchstart', this.startResizing, {
|
76380
|
+
passive: false
|
76381
|
+
});
|
76382
|
+
});
|
76383
|
+
});
|
76384
|
+
this.ruler.refresh();
|
76385
|
+
}
|
76386
|
+
destroy(block) {
|
76387
|
+
if (block) {
|
76388
|
+
const handles = Array.from(block.querySelectorAll('.handle')).filter(handle => handle.parentElement === block);
|
76389
|
+
handles.forEach(handle => {
|
76390
|
+
handle.removeEventListener('mousedown', this.startResizing);
|
76391
|
+
handle.removeEventListener('touchstart', this.startResizing);
|
76392
|
+
handle.parentNode.removeChild(handle);
|
76393
|
+
});
|
76394
|
+
} else {
|
76395
|
+
const handles = this.doc.querySelectorAll('.handle');
|
76396
|
+
handles.forEach(handle => {
|
76397
|
+
handle.removeEventListener('mousedown', this.startResizing);
|
76398
|
+
handle.removeEventListener('touchstart', this.startResizing);
|
76399
|
+
handle.parentNode.removeChild(handle);
|
76400
|
+
});
|
76401
|
+
this.ruler.destroy();
|
76402
|
+
}
|
76403
|
+
}
|
76404
|
+
startResizing(event) {
|
76405
|
+
const viewportWidth = this.win.innerWidth;
|
76406
|
+
if (viewportWidth <= this.disableOnMobile) return;
|
76407
|
+
if (event.type === 'touchstart' && event.touches.length !== 1) {
|
76408
|
+
return; // Do nothing if more than one touch point is detected
|
76409
|
+
}
|
76410
|
+
|
76411
|
+
if (event.type === 'mousedown' && event.button !== 0) {
|
76412
|
+
return; // Do nothing if the right mouse button is clicked
|
76413
|
+
}
|
76414
|
+
|
76415
|
+
this.target = event.target.parentNode; // block
|
76416
|
+
|
76417
|
+
this.clonedTarget = this.doc.querySelector(this.selector + '.cloned');
|
76418
|
+
event.preventDefault();
|
76419
|
+
event.stopPropagation();
|
76420
|
+
this.dragStartTimeout = setTimeout(() => {
|
76421
|
+
// Set a timeout before starting the drag (to differentiate from click)
|
76422
|
+
|
76423
|
+
if (this.onBeforeChange) this.onBeforeChange();
|
76424
|
+
const handle = event.target.closest('.handle');
|
76425
|
+
this.isResizing = true;
|
76426
|
+
this.resizeHandle = handle.classList[1];
|
76427
|
+
if (event.type === 'mousedown') {
|
76428
|
+
this.startX = event.clientX;
|
76429
|
+
this.startY = event.clientY;
|
76430
|
+
} else if (event.type === 'touchstart') {
|
76431
|
+
const touch = event.touches[0];
|
76432
|
+
this.startX = touch.clientX;
|
76433
|
+
this.startY = touch.clientY;
|
76434
|
+
}
|
76435
|
+
|
76436
|
+
//Initial
|
76437
|
+
this.initialWidth = parseFloat(getComputedStyle(this.target).width);
|
76438
|
+
this.initialHeight = parseFloat(getComputedStyle(this.target).height);
|
76439
|
+
const containerRect = this.common.getRect(this.target.parentNode);
|
76440
|
+
const rect = this.common.getRect(this.target);
|
76441
|
+
this.initialLeft = rect.left - containerRect.left;
|
76442
|
+
this.initialTop = rect.top - containerRect.top;
|
76443
|
+
this.common.applyPixels(this.target);
|
76444
|
+
}, 120);
|
76445
|
+
this.doc.addEventListener('mousemove', this.handleResizeMove);
|
76446
|
+
this.doc.addEventListener('mouseup', this.handleResizeEnd);
|
76447
|
+
this.doc.addEventListener('touchmove', this.handleResizeMove);
|
76448
|
+
this.doc.addEventListener('touchend', this.handleResizeEnd);
|
76449
|
+
}
|
76450
|
+
handleResizeMove(event) {
|
76451
|
+
if (this.isResizing) {
|
76452
|
+
let deltaX, deltaY;
|
76453
|
+
if (event.type === 'mousemove') {
|
76454
|
+
deltaX = event.clientX - this.startX;
|
76455
|
+
deltaY = event.clientY - this.startY;
|
76456
|
+
} else if (event.type === 'touchmove') {
|
76457
|
+
const touch = event.touches[0];
|
76458
|
+
deltaX = touch.clientX - this.startX;
|
76459
|
+
deltaY = touch.clientY - this.startY;
|
76460
|
+
}
|
76461
|
+
this.target.style.minWidth = ''; // to ensure no resize limit
|
76462
|
+
if (this.clonedTarget) this.clonedTarget.style.minWidth = '';
|
76463
|
+
switch (this.resizeHandle) {
|
76464
|
+
case 'top-left':
|
76465
|
+
this.resizeTopLeft(deltaX, deltaY);
|
76466
|
+
break;
|
76467
|
+
case 'top-right':
|
76468
|
+
this.resizeTopRight(deltaX, deltaY);
|
76469
|
+
break;
|
76470
|
+
case 'bottom-left':
|
76471
|
+
this.resizeBottomLeft(deltaX, deltaY);
|
76472
|
+
break;
|
76473
|
+
case 'bottom-right':
|
76474
|
+
this.resizeBottomRight(deltaX, deltaY);
|
76475
|
+
break;
|
76476
|
+
case 'top':
|
76477
|
+
this.resizeTop(deltaY);
|
76478
|
+
break;
|
76479
|
+
case 'left':
|
76480
|
+
this.resizeLeft(deltaX);
|
76481
|
+
break;
|
76482
|
+
case 'bottom':
|
76483
|
+
this.resizeBottom(deltaY);
|
76484
|
+
break;
|
76485
|
+
case 'right':
|
76486
|
+
this.resizeRight(deltaX);
|
76487
|
+
break;
|
76488
|
+
}
|
76489
|
+
this.ruler.updateRulers(this.target);
|
76490
|
+
}
|
76491
|
+
}
|
76492
|
+
handleResizeEnd() {
|
76493
|
+
clearTimeout(this.dragStartTimeout);
|
76494
|
+
this.stopResizing();
|
76495
|
+
this.doc.removeEventListener('mousemove', this.handleResizeMove);
|
76496
|
+
this.doc.removeEventListener('mouseup', this.handleResizeEnd);
|
76497
|
+
this.doc.removeEventListener('touchmove', this.handleResizeMove);
|
76498
|
+
this.doc.removeEventListener('touchend', this.handleResizeEnd);
|
76499
|
+
this.ruler.hideRulers();
|
76500
|
+
}
|
76501
|
+
resizeTopLeft(deltaX, deltaY) {
|
76502
|
+
this.target.style.left = this.initialLeft + deltaX + 'px';
|
76503
|
+
this.target.style.top = this.initialTop + deltaY + 'px';
|
76504
|
+
this.target.style.width = this.initialWidth - deltaX + 'px';
|
76505
|
+
this.target.style.height = this.initialHeight - deltaY + 'px';
|
76506
|
+
if (this.clonedTarget) {
|
76507
|
+
this.clonedTarget.style.left = this.initialLeft + deltaX + 'px';
|
76508
|
+
this.clonedTarget.style.top = this.initialTop + deltaY + 'px';
|
76509
|
+
this.clonedTarget.style.width = this.initialWidth - deltaX + 'px';
|
76510
|
+
this.clonedTarget.style.height = this.initialHeight - deltaY + 'px';
|
76511
|
+
}
|
76512
|
+
}
|
76513
|
+
resizeTopRight(deltaX, deltaY) {
|
76514
|
+
this.target.style.width = this.initialWidth + deltaX + 'px';
|
76515
|
+
this.target.style.top = this.initialTop + deltaY + 'px';
|
76516
|
+
this.target.style.height = this.initialHeight - deltaY + 'px';
|
76517
|
+
if (this.clonedTarget) {
|
76518
|
+
this.clonedTarget.style.width = this.initialWidth + deltaX + 'px';
|
76519
|
+
this.clonedTarget.style.top = this.initialTop + deltaY + 'px';
|
76520
|
+
this.clonedTarget.style.height = this.initialHeight - deltaY + 'px';
|
76521
|
+
}
|
76522
|
+
}
|
76523
|
+
resizeBottomLeft(deltaX, deltaY) {
|
76524
|
+
this.target.style.width = this.initialWidth - deltaX + 'px';
|
76525
|
+
this.target.style.height = this.initialHeight + deltaY + 'px';
|
76526
|
+
this.target.style.left = this.initialLeft + deltaX + 'px';
|
76527
|
+
if (this.clonedTarget) {
|
76528
|
+
this.clonedTarget.style.width = this.initialWidth - deltaX + 'px';
|
76529
|
+
this.clonedTarget.style.height = this.initialHeight + deltaY + 'px';
|
76530
|
+
this.clonedTarget.style.left = this.initialLeft + deltaX + 'px';
|
76531
|
+
}
|
76532
|
+
}
|
76533
|
+
resizeBottomRight(deltaX, deltaY) {
|
76534
|
+
this.target.style.width = this.initialWidth + deltaX + 'px';
|
76535
|
+
this.target.style.height = this.initialHeight + deltaY + 'px';
|
76536
|
+
if (this.clonedTarget) {
|
76537
|
+
this.clonedTarget.style.width = this.initialWidth + deltaX + 'px';
|
76538
|
+
this.clonedTarget.style.height = this.initialHeight + deltaY + 'px';
|
76539
|
+
}
|
76540
|
+
}
|
76541
|
+
resizeTop(deltaY) {
|
76542
|
+
this.target.style.top = this.initialTop + deltaY + 'px';
|
76543
|
+
this.target.style.height = this.initialHeight - deltaY + 'px';
|
76544
|
+
if (this.clonedTarget) {
|
76545
|
+
this.clonedTarget.style.top = this.initialTop + deltaY + 'px';
|
76546
|
+
this.clonedTarget.style.height = this.initialHeight - deltaY + 'px';
|
76547
|
+
}
|
76548
|
+
}
|
76549
|
+
resizeBottom(deltaY) {
|
76550
|
+
this.target.style.height = this.initialHeight + deltaY + 'px';
|
76551
|
+
if (this.clonedTarget) {
|
76552
|
+
this.clonedTarget.style.height = this.initialHeight + deltaY + 'px';
|
76553
|
+
}
|
76554
|
+
}
|
76555
|
+
resizeLeft(deltaX) {
|
76556
|
+
this.target.style.width = this.initialWidth - deltaX + 'px';
|
76557
|
+
this.target.style.left = this.initialLeft + deltaX + 'px';
|
76558
|
+
if (this.clonedTarget) {
|
76559
|
+
this.clonedTarget.style.width = this.initialWidth - deltaX + 'px';
|
76560
|
+
this.clonedTarget.style.left = this.initialLeft + deltaX + 'px';
|
76561
|
+
}
|
76562
|
+
}
|
76563
|
+
resizeRight(deltaX) {
|
76564
|
+
this.target.style.width = this.initialWidth + deltaX + 'px';
|
76565
|
+
if (this.clonedTarget) {
|
76566
|
+
this.clonedTarget.style.width = this.initialWidth + deltaX + 'px';
|
76567
|
+
}
|
76568
|
+
}
|
76569
|
+
stopResizing() {
|
76570
|
+
if (this.isResizing) {
|
76571
|
+
if (this.target) {
|
76572
|
+
this.updateBlockStyle(this.target);
|
76573
|
+
if (this.clonedTarget) this.updateBlockStyle(this.clonedTarget);
|
76574
|
+
}
|
76575
|
+
this.isResizing = false;
|
76576
|
+
}
|
76577
|
+
}
|
76578
|
+
updateBlockStyle(target) {
|
76579
|
+
if (target.querySelector(this.selector)) ; else {
|
76580
|
+
// this.common.updateHeight(target);
|
76581
|
+
if (target.classList.contains('height-auto')) target.style.height = '';
|
76582
|
+
}
|
76583
|
+
|
76584
|
+
// Replace with ruler's alignment
|
76585
|
+
if (this.ruler.rulerTop !== null) {
|
76586
|
+
target.style.top = this.ruler.rulerTop + 'px';
|
76587
|
+
// if container has top/left
|
76588
|
+
if (target.parentNode.matches(this.selector)) {
|
76589
|
+
const containerRect = target.parentNode.getBoundingClientRect();
|
76590
|
+
target.style.top = this.ruler.rulerTop - containerRect.top + 'px';
|
76591
|
+
}
|
76592
|
+
}
|
76593
|
+
|
76594
|
+
// If resizing by dragging the right corners (top or bottom)
|
76595
|
+
if (this.resizeHandle === 'top-right' || this.resizeHandle === 'bottom-right' || this.resizeHandle === 'right') {
|
76596
|
+
// Check if vertical right ruler visible (has value)
|
76597
|
+
if (this.ruler.rulerRight !== null) {
|
76598
|
+
// If so, keep the left position
|
76599
|
+
// target.style.left = newLeft + 'px';
|
76600
|
+
|
76601
|
+
// And update the width to align with vertical right ruler
|
76602
|
+
const rect = target.getBoundingClientRect();
|
76603
|
+
target.style.width = this.ruler.rulerRight - rect.left + 'px';
|
76604
|
+
}
|
76605
|
+
} else if (this.resizeHandle === 'top-left' || this.resizeHandle === 'bottom-left' || this.resizeHandle === 'left') {
|
76606
|
+
if (this.ruler.rulerLeft !== null) {
|
76607
|
+
const currentRight = this.initialLeft + this.initialWidth;
|
76608
|
+
|
76609
|
+
// if container has top/left
|
76610
|
+
const containerRect = target.parentNode.getBoundingClientRect();
|
76611
|
+
this.ruler.rulerLeft = this.ruler.rulerLeft - containerRect.left;
|
76612
|
+
|
76613
|
+
// And update the width to align with vertical left ruler
|
76614
|
+
target.style.left = this.ruler.rulerLeft + 'px';
|
76615
|
+
let newWidth = currentRight - this.ruler.rulerLeft;
|
76616
|
+
target.style.width = newWidth + 'px';
|
76617
|
+
}
|
76618
|
+
}
|
76619
|
+
|
76620
|
+
// Convert px to %
|
76621
|
+
this.common.applyPercentage(target);
|
76622
|
+
setTimeout(() => {
|
76623
|
+
const breakpoint = this.doc.body.getAttribute('data-breakpoint');
|
76624
|
+
|
76625
|
+
// const screenWidth = window.innerWidth;
|
76626
|
+
// let defaultPoint;
|
76627
|
+
// if(screenWidth<=1920) {
|
76628
|
+
// defaultPoint = 1366;
|
76629
|
+
// } else {
|
76630
|
+
// defaultPoint = 1900;
|
76631
|
+
// }
|
76632
|
+
|
76633
|
+
if (breakpoint && breakpoint < 1920) {
|
76634
|
+
target.setAttribute('data--y-' + breakpoint, target.style.top);
|
76635
|
+
target.setAttribute('data--x-' + breakpoint, target.style.left);
|
76636
|
+
target.setAttribute('data--w-' + breakpoint, target.style.width);
|
76637
|
+
target.setAttribute('data--h-' + breakpoint, target.style.height);
|
76638
|
+
} else {
|
76639
|
+
target.setAttribute('data--y', target.style.top);
|
76640
|
+
target.setAttribute('data--x', target.style.left);
|
76641
|
+
target.setAttribute('data--w', target.style.width);
|
76642
|
+
target.setAttribute('data--h', target.style.height);
|
76643
|
+
}
|
76644
|
+
target.removeAttribute('data-prev'); // reset
|
76645
|
+
target.removeAttribute('data-fluid');
|
76646
|
+
}, 30); // delay needed since we use updateHeight() previously that has 20ms process
|
76647
|
+
|
76648
|
+
if (this.onChange) this.onChange();
|
76649
|
+
}
|
76650
|
+
}
|
76651
|
+
class Draggable {
|
76652
|
+
constructor(options) {
|
76653
|
+
this.selector = options && options.selector || '.is-block';
|
76654
|
+
this.doc = options && options.doc || document;
|
76655
|
+
this.win = options && options.win || window;
|
76656
|
+
this.onDelete = options && options.onDelete || null;
|
76657
|
+
this.onBeforeChange = options && options.onBeforeChange || null;
|
76658
|
+
this.onChange = options && options.onChange || null;
|
76659
|
+
this.onSelectStart = options && options.onSelectStart || null;
|
76660
|
+
this.onSelectClear = options && options.onSelectClear || null;
|
76661
|
+
this.disableOnMobile = options && options.disableOnMobile || 0;
|
76662
|
+
this.onMultipleSelect = options && options.onMultipleSelect || null;
|
76663
|
+
this.onSelectBlock = options && options.onSelectBlock || null;
|
76664
|
+
this.isDragging = false;
|
76665
|
+
this.startX = 0;
|
76666
|
+
this.startY = 0;
|
76667
|
+
this.handleDragStart = this.handleDragStart.bind(this);
|
76668
|
+
this.handleDragMove = this.handleDragMove.bind(this);
|
76669
|
+
this.handleDragEnd = this.handleDragEnd.bind(this);
|
76670
|
+
this.handleSelect = this.handleSelect.bind(this);
|
76671
|
+
this.handleKeyDown = this.handleKeyDown.bind(this);
|
76672
|
+
this.setup();
|
76673
|
+
this.ruler = new Ruler({
|
76674
|
+
selector: this.selector,
|
76675
|
+
doc: this.doc,
|
76676
|
+
win: this.win
|
76677
|
+
});
|
76678
|
+
this.common = new Common({
|
76679
|
+
selector: this.selector,
|
76680
|
+
doc: this.doc,
|
76681
|
+
win: this.win
|
76682
|
+
});
|
76683
|
+
}
|
76684
|
+
setup() {
|
76685
|
+
this.elements = this.doc.querySelectorAll(this.selector);
|
76686
|
+
this.elements.forEach(element => {
|
76687
|
+
element.addEventListener('mousedown', this.handleDragStart);
|
76688
|
+
element.addEventListener('touchstart', this.handleDragStart, {
|
76689
|
+
passive: false
|
76690
|
+
});
|
76691
|
+
});
|
76692
|
+
this.doc.addEventListener('mousedown', this.handleSelect);
|
76693
|
+
this.doc.addEventListener('touchstart', this.handleSelect, {
|
76694
|
+
passive: false
|
76695
|
+
});
|
76696
|
+
this.doc.addEventListener('keydown', this.handleKeyDown);
|
76697
|
+
}
|
76698
|
+
refresh() {
|
76699
|
+
this.elements = this.doc.querySelectorAll(this.selector);
|
76700
|
+
this.elements.forEach(element => {
|
76701
|
+
element.removeEventListener('mousedown', this.handleDragStart);
|
76702
|
+
element.removeEventListener('touchstart', this.handleDragStart);
|
76703
|
+
});
|
76704
|
+
this.elements.forEach(element => {
|
76705
|
+
element.addEventListener('mousedown', this.handleDragStart);
|
76706
|
+
element.addEventListener('touchstart', this.handleDragStart, {
|
76707
|
+
passive: false
|
76708
|
+
});
|
76709
|
+
});
|
76710
|
+
this.ruler.refresh();
|
76711
|
+
}
|
76712
|
+
destroy() {
|
76713
|
+
this.ruler.destroy();
|
76714
|
+
this.elements.forEach(element => {
|
76715
|
+
element.removeEventListener('mousedown', this.handleDragStart);
|
76716
|
+
element.removeEventListener('touchstart', this.handleDragStart);
|
76717
|
+
});
|
76718
|
+
this.doc.removeEventListener('mousedown', this.handleSelect);
|
76719
|
+
this.doc.removeEventListener('touchstart', this.handleSelect);
|
76720
|
+
this.doc.removeEventListener('keydown', this.handleKeyDown);
|
76721
|
+
const blocks = this.doc.querySelectorAll(this.selector);
|
76722
|
+
blocks.forEach(elm => elm.classList.remove('active'));
|
76723
|
+
}
|
76724
|
+
disableDrag(block) {
|
76725
|
+
this.elements.forEach(element => {
|
76726
|
+
if (block === element) {
|
76727
|
+
element.removeEventListener('mousedown', this.handleDragStart);
|
76728
|
+
element.removeEventListener('touchstart', this.handleDragStart);
|
76729
|
+
}
|
76730
|
+
});
|
76731
|
+
}
|
76732
|
+
enableDrag(block) {
|
76733
|
+
this.elements.forEach(element => {
|
76734
|
+
if (block === element) {
|
76735
|
+
element.addEventListener('mousedown', this.handleDragStart);
|
76736
|
+
element.addEventListener('touchstart', this.handleDragStart, {
|
76737
|
+
passive: false
|
76738
|
+
});
|
76739
|
+
}
|
76740
|
+
});
|
76741
|
+
}
|
76742
|
+
handleDragStart(event) {
|
76743
|
+
const viewportWidth = this.win.innerWidth;
|
76744
|
+
if (viewportWidth <= this.disableOnMobile) return;
|
76745
|
+
if (event.target.classList.contains('rotate-handle')) return;
|
76746
|
+
if (event.type === 'touchstart' && event.touches.length !== 1) {
|
76747
|
+
return; // Do nothing if more than one touch point is detected
|
76748
|
+
}
|
76749
|
+
|
76750
|
+
if (event.type === 'mousedown' && event.button !== 0) {
|
76751
|
+
return; // Do nothing if the right mouse button is clicked
|
76752
|
+
}
|
76753
|
+
|
76754
|
+
const currentTarget = event.currentTarget;
|
76755
|
+
const clickedBlock = event.target.closest(this.selector);
|
76756
|
+
if (currentTarget !== clickedBlock) {
|
76757
|
+
// Triggered Group click by child block click
|
76758
|
+
return; // Return here, so that when block events are working, group events won't
|
76759
|
+
}
|
76760
|
+
|
76761
|
+
this.clickedBlock = clickedBlock;
|
76762
|
+
this.dragStartTimeout = setTimeout(() => {
|
76763
|
+
// Set a timeout before starting the drag (to differentiate from click)
|
76764
|
+
|
76765
|
+
if (event.type === 'mousedown') {
|
76766
|
+
this.startDragging(event.clientX, event.clientY, currentTarget);
|
76767
|
+
} else if (event.type === 'touchstart') {
|
76768
|
+
const touch = event.touches[0];
|
76769
|
+
this.startDragging(touch.clientX, touch.clientY, currentTarget);
|
76770
|
+
}
|
76771
|
+
this.doc.addEventListener('mousemove', this.handleDragMove);
|
76772
|
+
this.doc.addEventListener('touchmove', this.handleDragMove);
|
76773
|
+
}, 120);
|
76774
|
+
this.doc.addEventListener('mouseup', this.handleDragEnd);
|
76775
|
+
this.doc.addEventListener('touchend', this.handleDragEnd);
|
76776
|
+
}
|
76777
|
+
startDragging(startX, startY) {
|
76778
|
+
if (this.onBeforeChange) this.onBeforeChange();
|
76779
|
+
this.isDragging = true;
|
76780
|
+
const blocks = this.doc.querySelectorAll(this.selector + '.active');
|
76781
|
+
blocks.forEach(target => {
|
76782
|
+
// const containerRect = target.parentNode.getBoundingClientRect(); // if container has top/left
|
76783
|
+
const containerRect = this.common.getRect(target.parentNode); // if container has top/left
|
76784
|
+
const rect = this.common.getRect(target);
|
76785
|
+
const x = startX - rect.left + containerRect.left;
|
76786
|
+
const y = startY - rect.top + containerRect.top;
|
76787
|
+
target.setAttribute('data-startx', x);
|
76788
|
+
target.setAttribute('data-starty', y);
|
76789
|
+
this.common.applyPixels(target);
|
76790
|
+
});
|
76791
|
+
this.clickedBlock = this.common.getSelectedBlock();
|
76792
|
+
}
|
76793
|
+
handleDragMove(event) {
|
76794
|
+
let clientX, clientY;
|
76795
|
+
if (event.type === 'mousemove') {
|
76796
|
+
clientX = event.clientX;
|
76797
|
+
clientY = event.clientY;
|
76798
|
+
} else if (event.type === 'touchmove') {
|
76799
|
+
const touch = event.touches[0];
|
76800
|
+
clientX = touch.clientX;
|
76801
|
+
clientY = touch.clientY;
|
76802
|
+
}
|
76803
|
+
if (this.isDragging) {
|
76804
|
+
// Allows dragging multiple selected blocks
|
76805
|
+
|
76806
|
+
let blocks = this.doc.querySelectorAll(this.selector + '.active');
|
76807
|
+
blocks.forEach(target => {
|
76808
|
+
this.updatePosition(clientX, clientY, target);
|
76809
|
+
});
|
76810
|
+
|
76811
|
+
// Ruler works for single block selection only
|
76812
|
+
if (this.clickedBlock) this.ruler.updateRulers(this.clickedBlock);
|
76813
|
+
}
|
76814
|
+
event.preventDefault();
|
76815
|
+
event.stopImmediatePropagation();
|
76816
|
+
}
|
76817
|
+
updatePosition(x, y, target) {
|
76818
|
+
if (this.isDragging) {
|
76819
|
+
const startX = target.getAttribute('data-startx');
|
76820
|
+
const startY = target.getAttribute('data-starty');
|
76821
|
+
const newX = x - startX;
|
76822
|
+
const newY = y - startY;
|
76823
|
+
target.style.left = newX + 'px';
|
76824
|
+
target.style.top = newY + 'px';
|
76825
|
+
}
|
76826
|
+
}
|
76827
|
+
handleDragEnd() {
|
76828
|
+
clearTimeout(this.dragStartTimeout);
|
76829
|
+
if (this.isDragging) {
|
76830
|
+
this.doc.removeEventListener('mousemove', this.handleDragMove);
|
76831
|
+
this.doc.removeEventListener('touchmove', this.handleDragMove);
|
76832
|
+
}
|
76833
|
+
this.doc.removeEventListener('mouseup', this.handleDragEnd);
|
76834
|
+
this.doc.removeEventListener('touchend', this.handleDragEnd);
|
76835
|
+
this.stopDragging();
|
76836
|
+
this.ruler.hideRulers();
|
76837
|
+
let blocks = Array.from(this.doc.querySelectorAll(this.selector)).filter(elm => elm.classList.contains('active') && !elm.classList.contains('multi'));
|
76838
|
+
if (blocks.length === 1) {
|
76839
|
+
const block = blocks[0];
|
76840
|
+
if (this.onSelectStart) this.onSelectStart(block); // on first block select (before clone)
|
76841
|
+
}
|
76842
|
+
}
|
76843
|
+
|
76844
|
+
stopDragging() {
|
76845
|
+
if (this.isDragging) {
|
76846
|
+
const blocks = this.doc.querySelectorAll(this.selector + '.active');
|
76847
|
+
blocks.forEach(target => {
|
76848
|
+
this.updateBlockStyle(target);
|
76849
|
+
});
|
76850
|
+
this.isDragging = false;
|
76851
|
+
}
|
76852
|
+
}
|
76853
|
+
updateBlockStyle(target) {
|
76854
|
+
// Replace with ruler's alignment
|
76855
|
+
const containerRect = this.common.getRect(target.parentNode); // if container has top/left
|
76856
|
+
const initialWidth = parseFloat(getComputedStyle(target).width);
|
76857
|
+
if (this.ruler.rulerTop !== null) target.style.top = this.ruler.rulerTop - containerRect.top + 'px';
|
76858
|
+
if (this.ruler.rulerLeft !== null) target.style.left = this.ruler.rulerLeft - containerRect.left + 'px';else if (this.ruler.rulerRight !== null) target.style.left = this.ruler.rulerRight - initialWidth - containerRect.left + 'px';
|
76859
|
+
this.doc.querySelectorAll('[data-startx]').forEach(elm => elm.removeAttribute('data-startx'));
|
76860
|
+
this.doc.querySelectorAll('[data-starty]').forEach(elm => elm.removeAttribute('data-starty'));
|
76861
|
+
this.common.applyPercentage(target);
|
76862
|
+
const breakpoint = this.doc.body.getAttribute('data-breakpoint');
|
76863
|
+
|
76864
|
+
// const screenWidth = window.innerWidth;
|
76865
|
+
// let defaultPoint;
|
76866
|
+
// if(screenWidth<=1920) {
|
76867
|
+
// defaultPoint = 1366;
|
76868
|
+
// } else {
|
76869
|
+
// defaultPoint = 1900;
|
76870
|
+
// }
|
76871
|
+
|
76872
|
+
if (breakpoint && breakpoint < 1920) {
|
76873
|
+
target.setAttribute('data--y-' + breakpoint, target.style.top);
|
76874
|
+
target.setAttribute('data--x-' + breakpoint, target.style.left);
|
76875
|
+
target.setAttribute('data--w-' + breakpoint, target.style.width);
|
76876
|
+
target.setAttribute('data--h-' + breakpoint, target.style.height);
|
76877
|
+
} else {
|
76878
|
+
target.setAttribute('data--y', target.style.top);
|
76879
|
+
target.setAttribute('data--x', target.style.left);
|
76880
|
+
target.setAttribute('data--w', target.style.width);
|
76881
|
+
target.setAttribute('data--h', target.style.height);
|
76882
|
+
}
|
76883
|
+
target.removeAttribute('data-prev'); // reset
|
76884
|
+
target.removeAttribute('data-fluid');
|
76885
|
+
if (this.onChange) this.onChange();
|
76886
|
+
}
|
76887
|
+
handleSelect(event) {
|
76888
|
+
const element = event.target;
|
76889
|
+
if (element.classList.contains('rotate-handle')) return;
|
76890
|
+
const block = element.closest(this.selector);
|
76891
|
+
if (block) {
|
76892
|
+
if (block.classList.contains('active')) {
|
76893
|
+
let actualBlock = block.classList.contains('clone') ? this.doc.querySelector(this.selector + '.cloned') : null;
|
76894
|
+
if (!actualBlock) actualBlock = block;
|
76895
|
+
if (this.onSelectBlock) this.onSelectBlock(actualBlock);
|
76896
|
+
return; // if clicked block is active
|
76897
|
+
}
|
76898
|
+
// if(block.parentNode.classList.contains('active')) return; // if group is active
|
76899
|
+
|
76900
|
+
if (block.matches(this.selector) && block.querySelector(this.selector)) {
|
76901
|
+
// if group is clicked, remove active childe's blocks
|
76902
|
+
block.querySelectorAll(this.selector).forEach(elm => elm.classList.remove('active'));
|
76903
|
+
}
|
76904
|
+
if (event.shiftKey || this.doc.body.classList.contains('multi-select')) {
|
76905
|
+
// multi select
|
76906
|
+
block.classList.add('active');
|
76907
|
+
if (this.onMultipleSelect) this.onMultipleSelect();
|
76908
|
+
} else {
|
76909
|
+
if (this.onSelectClear) this.onSelectClear();
|
76910
|
+
this.doc.querySelectorAll(this.selector + '.active').forEach(elm => elm.classList.remove('active'));
|
76911
|
+
block.classList.add('active');
|
76912
|
+
let actualBlock = block.classList.contains('clone') ? this.doc.querySelector(this.selector + '.cloned') : null;
|
76913
|
+
if (!actualBlock) actualBlock = block;
|
76914
|
+
if (this.onSelectBlock) this.onSelectBlock(actualBlock);
|
76915
|
+
}
|
76916
|
+
if (!block.parentNode) return; // just in case
|
76917
|
+
|
76918
|
+
// Higlight parent group if current child block is clicked
|
76919
|
+
if (block.parentNode.matches(this.selector)) {
|
76920
|
+
block.parentNode.classList.add('block-active');
|
76921
|
+
} else {
|
76922
|
+
this.doc.querySelectorAll('.block-active').forEach(elm => elm.classList.remove('block-active'));
|
76923
|
+
}
|
76924
|
+
} else {
|
76925
|
+
if (event.target.closest('.keep-selection')) return;
|
76926
|
+
|
76927
|
+
// // Make empty height set with value
|
76928
|
+
// // if(this.clickedBlock) this.common.updateHeight(this.clickedBlock);
|
76929
|
+
// // Check
|
76930
|
+
// if(this.clickedBlock && !this.clickedBlock.classList.contains('clone')) {
|
76931
|
+
// this.common.updateHeight(this.clickedBlock);
|
76932
|
+
// }
|
76933
|
+
|
76934
|
+
this.doc.querySelectorAll(this.selector + '.active').forEach(elm => elm.classList.remove('active'));
|
76935
|
+
this.doc.querySelectorAll('.block-active').forEach(elm => elm.classList.remove('block-active'));
|
76936
|
+
if (this.onSelectClear) this.onSelectClear();
|
76937
|
+
}
|
76938
|
+
|
76939
|
+
// Check if multiple selection occurs. If so, add 'multi' class to hide all the handles
|
76940
|
+
let blocks = Array.from(this.doc.querySelectorAll(this.selector)).filter(elm => elm.classList.contains('active') && !elm.classList.contains('clone'));
|
76941
|
+
if (blocks.length > 1) {
|
76942
|
+
blocks.forEach(block => {
|
76943
|
+
block.classList.add('multi');
|
76944
|
+
});
|
76945
|
+
} else {
|
76946
|
+
const elms = this.doc.querySelectorAll('.multi');
|
76947
|
+
elms.forEach(elm => elm.classList.remove('multi'));
|
76948
|
+
}
|
76949
|
+
}
|
76950
|
+
delete() {
|
76951
|
+
let blocks = Array.from(this.doc.querySelectorAll(this.selector)).filter(elm => elm.classList.contains('active') && elm.classList.contains('editable'));
|
76952
|
+
if (blocks.length > 0) return;
|
76953
|
+
if (this.onBeforeChange) this.onBeforeChange();
|
76954
|
+
blocks = Array.from(this.doc.querySelectorAll(this.selector)).filter(elm => elm.classList.contains('active'));
|
76955
|
+
blocks.forEach(element => {
|
76956
|
+
element.removeEventListener('mousedown', this.handleDragStart);
|
76957
|
+
element.removeEventListener('touchstart', this.handleDragStart);
|
76958
|
+
if (this.onDelete) this.onDelete(element);
|
76959
|
+
element.parentNode.removeChild(element);
|
76960
|
+
});
|
76961
|
+
if (this.onChange) this.onChange();
|
76962
|
+
}
|
76963
|
+
handleKeyDown(event) {
|
76964
|
+
if (event.key === 'Delete' || event.key === 'Backspace' || event.keyCode === 46) {
|
76965
|
+
this.delete();
|
76966
|
+
}
|
76967
|
+
}
|
76968
|
+
}
|
76969
|
+
class Editable {
|
76970
|
+
constructor(options) {
|
76971
|
+
this.selector = options && options.selector || '.is-block';
|
76972
|
+
this.controlSelector = options && options.controlSelector || null;
|
76973
|
+
this.onEditStart = options && options.onEditStart || null;
|
76974
|
+
this.onEditEnd = options && options.onEditEnd || null;
|
76975
|
+
this.doc = options && options.doc || document;
|
76976
|
+
this.win = options && options.win || window;
|
76977
|
+
this.onContentClick = options && options.onContentClick || null;
|
76978
|
+
this.elements = this.doc.querySelectorAll(this.selector);
|
76979
|
+
this.handleEditStart = this.handleEditStart.bind(this);
|
76980
|
+
this.handleMouseClick = this.handleMouseClick.bind(this);
|
76981
|
+
this.handleTouchStart = this.handleTouchStart.bind(this);
|
76982
|
+
this.setup();
|
76983
|
+
}
|
76984
|
+
setup() {
|
76985
|
+
this.elements.forEach(element => {
|
76986
|
+
element.addEventListener('dblclick', this.handleEditStart);
|
76987
|
+
element.addEventListener('touchstart', this.handleTouchStart, {
|
76988
|
+
passive: false
|
76989
|
+
});
|
76990
|
+
});
|
76991
|
+
}
|
76992
|
+
refresh() {
|
76993
|
+
this.elements = this.doc.querySelectorAll(this.selector);
|
76994
|
+
this.elements.forEach(element => {
|
76995
|
+
element.removeEventListener('dblclick', this.handleEditStart);
|
76996
|
+
element.removeEventListener('touchstart', this.handleTouchStart);
|
76997
|
+
});
|
76998
|
+
this.elements.forEach(element => {
|
76999
|
+
element.addEventListener('dblclick', this.handleEditStart);
|
77000
|
+
element.addEventListener('touchstart', this.handleTouchStart, {
|
77001
|
+
passive: false
|
77002
|
+
});
|
77003
|
+
});
|
77004
|
+
}
|
77005
|
+
destroy(element) {
|
77006
|
+
if (element) {
|
77007
|
+
element.removeEventListener('dblclick', this.handleEditStart);
|
77008
|
+
element.removeEventListener('touchstart', this.handleTouchStart);
|
77009
|
+
} else {
|
77010
|
+
this.elements = this.doc.querySelectorAll(this.selector);
|
77011
|
+
this.elements.forEach(element => {
|
77012
|
+
element.removeEventListener('dblclick', this.handleEditStart);
|
77013
|
+
element.removeEventListener('touchstart', this.handleTouchStart);
|
77014
|
+
});
|
77015
|
+
}
|
77016
|
+
}
|
77017
|
+
handleEditStart(event) {
|
77018
|
+
const currentTarget = event.currentTarget;
|
77019
|
+
if (currentTarget.querySelector(this.selector)) {
|
77020
|
+
// if group, no edit needed
|
77021
|
+
return;
|
77022
|
+
}
|
77023
|
+
const block = event.target.closest(this.selector);
|
77024
|
+
if (currentTarget !== block) {
|
77025
|
+
// Triggered Group click by child block click
|
77026
|
+
return; // Return here, so that when block events are working, group events won't
|
77027
|
+
}
|
77028
|
+
|
77029
|
+
if (block.parentNode.matches(this.selector) && block.parentNode.classList.contains('active')) {
|
77030
|
+
// if group is active, no edit needed
|
77031
|
+
return;
|
77032
|
+
}
|
77033
|
+
this.clickedBlock = currentTarget;
|
77034
|
+
|
77035
|
+
// currentTarget.classList.add('editable');
|
77036
|
+
// currentTarget.setAttribute('contentEditable', true);
|
77037
|
+
// currentTarget.style.cursor = 'auto'; // Change cursor to normal
|
77038
|
+
// currentTarget.focus();
|
77039
|
+
// this.placeCursorAtEnd(currentTarget);
|
77040
|
+
|
77041
|
+
this.elements.forEach(element => {
|
77042
|
+
if (currentTarget === element) {
|
77043
|
+
element.removeEventListener('dblclick', this.handleEditStart);
|
77044
|
+
element.removeEventListener('touchstart', this.handleTouchStart);
|
77045
|
+
const clonedTarget = this.doc.querySelector(this.selector + '.cloned');
|
77046
|
+
if (clonedTarget) {
|
77047
|
+
clonedTarget.removeEventListener('dblclick', this.handleEditStart);
|
77048
|
+
clonedTarget.removeEventListener('touchstart', this.handleTouchStart);
|
77049
|
+
this.clickedBlock = clonedTarget;
|
77050
|
+
}
|
77051
|
+
}
|
77052
|
+
});
|
77053
|
+
this.doc.addEventListener('mousedown', this.handleMouseClick);
|
77054
|
+
this.doc.addEventListener('touchstart', this.handleMouseClick, {
|
77055
|
+
passive: false
|
77056
|
+
});
|
77057
|
+
if (this.onEditStart) this.onEditStart(currentTarget);
|
77058
|
+
}
|
77059
|
+
handleTouchStart(event) {
|
77060
|
+
// Handle Double Tab
|
77061
|
+
if (event.touches.length === 1) {
|
77062
|
+
const now = new Date().getTime();
|
77063
|
+
const lastTouchTime = this.lastTouchTime || now;
|
77064
|
+
const timeDiff = now - lastTouchTime;
|
77065
|
+
if (timeDiff < 300 && timeDiff > 0) {
|
77066
|
+
// Less than 300ms since the last touch, consider it a double-tap
|
77067
|
+
this.handleDoubleTap(event);
|
77068
|
+
}
|
77069
|
+
this.lastTouchTime = now;
|
77070
|
+
}
|
77071
|
+
}
|
77072
|
+
handleDoubleTap(event) {
|
77073
|
+
this.handleEditStart(event);
|
77074
|
+
}
|
77075
|
+
handleMouseClick(event) {
|
77076
|
+
const element = event.target;
|
77077
|
+
if (element.closest(this.selector) === this.clickedBlock || this.controlSelector && element.closest(this.controlSelector)) {
|
77078
|
+
// Do Nothing
|
77079
|
+
// Continue editing
|
77080
|
+
if (element.parentNode.matches(this.selector)) {
|
77081
|
+
if (this.onContentClick) this.onContentClick(event);
|
77082
|
+
// this.doc.querySelectorAll('.elm-active').forEach(elm=>elm.classList.remove('elm-active'));
|
77083
|
+
// element.classList.add('elm-active');
|
77084
|
+
}
|
77085
|
+
} else {
|
77086
|
+
let clickedBlock = this.clickedBlock;
|
77087
|
+
|
77088
|
+
// currentTarget.classList.remove('editable');
|
77089
|
+
// clickedBlock.removeAttribute('contentEditable');
|
77090
|
+
// clickedBlock.style.cursor = '';
|
77091
|
+
|
77092
|
+
if (this.onEditEnd) this.onEditEnd(this.clickedBlock);
|
77093
|
+
this.elements.forEach(element => {
|
77094
|
+
if (clickedBlock === element) {
|
77095
|
+
element.addEventListener('dblclick', this.handleEditStart);
|
77096
|
+
element.addEventListener('touchstart', this.handleTouchStart, {
|
77097
|
+
passive: false
|
77098
|
+
});
|
77099
|
+
}
|
77100
|
+
});
|
77101
|
+
this.doc.removeEventListener('mousedown', this.handleMouseClick);
|
77102
|
+
this.doc.removeEventListener('touchstart', this.handleMouseClick);
|
77103
|
+
|
77104
|
+
// this.doc.querySelectorAll('.elm-active').forEach(elm=>elm.classList.remove('elm-active'));
|
77105
|
+
}
|
77106
|
+
}
|
77107
|
+
|
77108
|
+
quitEditable(block) {
|
77109
|
+
if (this.onEditEnd) this.onEditEnd(block);
|
77110
|
+
block.addEventListener('dblclick', this.handleEditStart);
|
77111
|
+
block.addEventListener('touchstart', this.handleTouchStart, {
|
77112
|
+
passive: false
|
77113
|
+
});
|
77114
|
+
this.doc.removeEventListener('mousedown', this.handleMouseClick);
|
77115
|
+
this.doc.removeEventListener('touchstart', this.handleMouseClick);
|
77116
|
+
}
|
77117
|
+
placeCursorAtEnd(element) {
|
77118
|
+
const range = this.doc.createRange();
|
77119
|
+
const sel = this.win.getSelection();
|
77120
|
+
range.setStart(element, element.childNodes.length);
|
77121
|
+
range.collapse(true);
|
77122
|
+
sel.removeAllRanges();
|
77123
|
+
sel.addRange(range);
|
77124
|
+
}
|
77125
|
+
}
|
77126
|
+
class BlockSelector {
|
77127
|
+
constructor(options) {
|
77128
|
+
this.selector = options && options.selector || '.is-block';
|
77129
|
+
this.parentSelector = options && options.parentSelector || 'body';
|
77130
|
+
this.doc = options && options.doc || document;
|
77131
|
+
this.win = options && options.win || window;
|
77132
|
+
this.disableOnMobile = options && options.disableOnMobile || 0;
|
77133
|
+
this.onMultipleSelect = options && options.onMultipleSelect || null;
|
77134
|
+
this.isDragging = false;
|
77135
|
+
this.startCoords = {
|
77136
|
+
x: 0,
|
77137
|
+
y: 0
|
77138
|
+
};
|
77139
|
+
const handleHTML = `
|
77140
|
+
<div class="selection-rectangle"></div>`;
|
77141
|
+
this.doc.body.insertAdjacentHTML('afterbegin', handleHTML);
|
77142
|
+
this.selectionRect = this.doc.querySelector('.selection-rectangle');
|
77143
|
+
const styleHTML = `
|
77144
|
+
<style id="styleSelector">
|
77145
|
+
.selection-rectangle {
|
77146
|
+
position: absolute;
|
77147
|
+
border: 1px solid #c2e2ff;
|
77148
|
+
pointer-events: none;
|
77149
|
+
display: none;
|
77150
|
+
background-color: #a9c4e442;
|
77151
|
+
z-index:1
|
77152
|
+
}
|
77153
|
+
<style>
|
77154
|
+
`;
|
77155
|
+
const elmStyle = this.doc.querySelector('#styleSelector');
|
77156
|
+
if (!elmStyle) this.doc.head.insertAdjacentHTML('beforeend', styleHTML);
|
77157
|
+
this.handleDragStart = this.handleDragStart.bind(this);
|
77158
|
+
this.handleDragMove = this.handleDragMove.bind(this);
|
77159
|
+
this.handleDragEnd = this.handleDragEnd.bind(this);
|
77160
|
+
this.doc.addEventListener('mousedown', this.handleDragStart);
|
77161
|
+
this.doc.addEventListener('touchstart', this.handleDragStart, {
|
77162
|
+
passive: false
|
77163
|
+
});
|
77164
|
+
}
|
77165
|
+
destroy() {
|
77166
|
+
const elmStyle = this.doc.querySelector('#styleSelector');
|
77167
|
+
if (elmStyle) elmStyle.parentNode.removeChild(elmStyle);
|
77168
|
+
const selectionRect = this.doc.querySelector('.selection-rectangle');
|
77169
|
+
if (selectionRect) selectionRect.parentNode.removeChild(selectionRect);
|
77170
|
+
this.doc.removeEventListener('mousedown', this.handleDragStart);
|
77171
|
+
this.doc.removeEventListener('touchstart', this.handleDragStart);
|
77172
|
+
}
|
77173
|
+
handleDragStart(event) {
|
77174
|
+
const viewportWidth = this.win.innerWidth;
|
77175
|
+
if (viewportWidth <= this.disableOnMobile) return;
|
77176
|
+
if (event.type === 'touchstart' && event.touches.length !== 1) {
|
77177
|
+
return; // Do nothing if more than one touch point is detected
|
77178
|
+
}
|
77179
|
+
|
77180
|
+
if (event.type === 'mousedown' && event.button !== 0) {
|
77181
|
+
return; // Do nothing if the right mouse button is clicked
|
77182
|
+
}
|
77183
|
+
|
77184
|
+
if (event.target.closest(this.selector)) return;
|
77185
|
+
if (!event.target.closest(this.parentSelector)) return;
|
77186
|
+
if (event.target.closest('.keep-selection')) return;
|
77187
|
+
this.dragStartTimeout = setTimeout(() => {
|
77188
|
+
// Set a timeout before starting the drag (to differentiate from click)
|
77189
|
+
|
77190
|
+
this.isDragging = true;
|
77191
|
+
let clientX, clientY;
|
77192
|
+
if (event.type === 'mousedown') {
|
77193
|
+
clientX = event.clientX;
|
77194
|
+
clientY = event.clientY;
|
77195
|
+
} else if (event.type === 'touchstart') {
|
77196
|
+
const touch = event.touches[0];
|
77197
|
+
clientX = touch.clientX;
|
77198
|
+
clientY = touch.clientY;
|
77199
|
+
}
|
77200
|
+
this.startCoords = {
|
77201
|
+
x: clientX,
|
77202
|
+
y: clientY
|
77203
|
+
};
|
77204
|
+
this.updateSelectionRect(this.startCoords, this.startCoords);
|
77205
|
+
this.doc.addEventListener('mousemove', this.handleDragMove);
|
77206
|
+
this.doc.addEventListener('touchmove', this.handleDragMove);
|
77207
|
+
this.doc.body.style.userSelect = 'none';
|
77208
|
+
}, 100);
|
77209
|
+
this.doc.addEventListener('mouseup', this.handleDragEnd);
|
77210
|
+
this.doc.addEventListener('touchend', this.handleDragEnd);
|
77211
|
+
}
|
77212
|
+
handleDragMove(event) {
|
77213
|
+
if (!this.isDragging) return;
|
77214
|
+
if (event.target.closest('.keep-selection')) return;
|
77215
|
+
let clientX, clientY;
|
77216
|
+
if (event.type === 'mousemove') {
|
77217
|
+
clientX = event.clientX;
|
77218
|
+
clientY = event.clientY;
|
77219
|
+
} else if (event.type === 'touchmove') {
|
77220
|
+
const touch = event.touches[0];
|
77221
|
+
clientX = touch.clientX;
|
77222
|
+
clientY = touch.clientY;
|
77223
|
+
}
|
77224
|
+
this.updateSelectionRect(this.startCoords, {
|
77225
|
+
x: clientX,
|
77226
|
+
y: clientY
|
77227
|
+
});
|
77228
|
+
this.selectBlocksInArea(this.startCoords, {
|
77229
|
+
x: clientX,
|
77230
|
+
y: clientY
|
77231
|
+
});
|
77232
|
+
}
|
77233
|
+
handleDragEnd() {
|
77234
|
+
clearTimeout(this.dragStartTimeout);
|
77235
|
+
this.isDragging = false;
|
77236
|
+
this.selectionRect.style.display = 'none';
|
77237
|
+
this.doc.removeEventListener('mousemove', this.handleDragMove);
|
77238
|
+
this.doc.removeEventListener('touchmove', this.handleDragMove);
|
77239
|
+
this.doc.removeEventListener('mouseup', this.handleDragEnd);
|
77240
|
+
this.doc.removeEventListener('touchend', this.handleDragEnd);
|
77241
|
+
this.doc.body.style.userSelect = '';
|
77242
|
+
const elms = this.doc.querySelectorAll(this.selector + '.active');
|
77243
|
+
if (elms.length > 1) this.onMultipleSelect();
|
77244
|
+
}
|
77245
|
+
updateSelectionRect(start, end) {
|
77246
|
+
const minX = Math.min(start.x, end.x);
|
77247
|
+
const minY = Math.min(start.y, end.y) + this.win.scrollY;
|
77248
|
+
const width = Math.abs(start.x - end.x);
|
77249
|
+
const height = Math.abs(start.y - end.y);
|
77250
|
+
this.selectionRect.style.left = `${minX}px`;
|
77251
|
+
this.selectionRect.style.top = `${minY}px`;
|
77252
|
+
this.selectionRect.style.width = `${width}px`;
|
77253
|
+
this.selectionRect.style.height = `${height}px`;
|
77254
|
+
this.selectionRect.style.display = 'block';
|
77255
|
+
}
|
77256
|
+
selectBlocksInArea(start, end) {
|
77257
|
+
const blocks = this.doc.querySelectorAll(this.selector);
|
77258
|
+
blocks.forEach(block => {
|
77259
|
+
const rect = block.getBoundingClientRect();
|
77260
|
+
if (rect.left < Math.max(start.x, end.x) && rect.right > Math.min(start.x, end.x) && rect.top < Math.max(start.y, end.y) && rect.bottom > Math.min(start.y, end.y)) {
|
77261
|
+
if (block.parentNode.matches(this.selector)) ; else {
|
77262
|
+
block.classList.add('active');
|
77263
|
+
let elms = Array.from(this.doc.querySelectorAll(this.selector)).filter(elm => elm.classList.contains('active') && !elm.classList.contains('clone'));
|
77264
|
+
if (elms.length > 1) block.classList.add('multi');
|
77265
|
+
}
|
77266
|
+
} else {
|
77267
|
+
block.classList.remove('active');
|
77268
|
+
block.classList.remove('multi');
|
77269
|
+
}
|
77270
|
+
});
|
77271
|
+
}
|
77272
|
+
unSelect() {
|
77273
|
+
const blocks = this.doc.querySelectorAll(this.selector);
|
77274
|
+
blocks.forEach(elm => elm.classList.remove('active'));
|
77275
|
+
}
|
77276
|
+
}
|
77277
|
+
class EditableBlocks {
|
77278
|
+
constructor(options = {}) {
|
77279
|
+
const defaults = {
|
77280
|
+
selector: '.is-block',
|
77281
|
+
parentSelector: 'body',
|
77282
|
+
// controlSelector: '.is-tool',
|
77283
|
+
doc: document,
|
77284
|
+
win: window,
|
77285
|
+
// onBeforeChange: () => {},
|
77286
|
+
// onChange: () => {},
|
77287
|
+
// onContentClick: () => {},
|
77288
|
+
// onEditStart: () => {},
|
77289
|
+
// onEditEnd: () => {},
|
77290
|
+
// onDuplicate: () => {},
|
77291
|
+
// onSelectBlock: (block) => {},
|
77292
|
+
// onUnSelectBlock: () => {},
|
77293
|
+
// onMultipleSelect: () => {},
|
77294
|
+
disableOnMobile: 0,
|
77295
|
+
rotate: true,
|
77296
|
+
clone: true
|
77297
|
+
// onDelete: () = {}
|
77298
|
+
};
|
77299
|
+
|
77300
|
+
Object.assign(this, defaults, options);
|
77301
|
+
this.init();
|
77302
|
+
}
|
77303
|
+
checkOverlap(target) {
|
77304
|
+
return this.common.checkOverlap(target);
|
77305
|
+
}
|
77306
|
+
forward(target) {
|
77307
|
+
let newZIndex;
|
77308
|
+
if (!target.style.zIndex) {
|
77309
|
+
newZIndex = 1;
|
77310
|
+
} else {
|
77311
|
+
newZIndex = parseInt(target.style.zIndex) + 1;
|
77312
|
+
}
|
77313
|
+
target.style.zIndex = newZIndex;
|
77314
|
+
}
|
77315
|
+
backward(target) {
|
77316
|
+
let newZIndex;
|
77317
|
+
if (!target.style.zIndex) {
|
77318
|
+
newZIndex = 0;
|
77319
|
+
} else {
|
77320
|
+
if (parseInt(target.style.zIndex) - 1 < 0) newZIndex = 0;else newZIndex = parseInt(target.style.zIndex) - 1;
|
77321
|
+
}
|
77322
|
+
target.style.zIndex = newZIndex;
|
77323
|
+
}
|
77324
|
+
selectStart(block) {
|
77325
|
+
if (block.classList.contains('is-shape')) return; // do not clone if block is shape
|
77326
|
+
|
77327
|
+
if (!this.clone) return;
|
77328
|
+
const viewportWidth = this.win.innerWidth;
|
77329
|
+
if (block.closest('.autolayout') && viewportWidth <= 760) {
|
77330
|
+
return;
|
77331
|
+
}
|
77332
|
+
if (block.classList.contains('is-group')) return; // do not clone if block is shape
|
77333
|
+
|
77334
|
+
if (!block.classList.contains('clone')) {
|
77335
|
+
let clonedDiv = block.cloneNode(true);
|
77336
|
+
clonedDiv.classList.add('clone');
|
77337
|
+
block.parentNode.appendChild(clonedDiv);
|
77338
|
+
block.classList.add('cloned');
|
77339
|
+
this.refresh();
|
77340
|
+
}
|
77341
|
+
}
|
77342
|
+
selectClear() {
|
77343
|
+
this.doc.querySelectorAll('.clone').forEach(elm => elm.parentNode.removeChild(elm));
|
77344
|
+
this.doc.querySelectorAll('.cloned').forEach(elm => elm.classList.remove('cloned'));
|
77345
|
+
}
|
77346
|
+
setMultiSelect(multiSelect) {
|
77347
|
+
if (multiSelect) this.doc.body.classList.add('multi-select');else this.doc.body.classList.remove('multi-select');
|
77348
|
+
}
|
77349
|
+
init() {
|
77350
|
+
this.doc.body.classList.add('editableblocks');
|
77351
|
+
this.draggable = new Draggable({
|
77352
|
+
selector: this.selector,
|
77353
|
+
disableOnMobile: this.disableOnMobile,
|
77354
|
+
doc: this.doc,
|
77355
|
+
win: this.win,
|
77356
|
+
onDelete: element => {
|
77357
|
+
if (this.rotatable) this.rotatable.destroy(element);
|
77358
|
+
this.resizable.destroy(element);
|
77359
|
+
this.editable.destroy(element);
|
77360
|
+
if (this.onDelete) this.onDelete();
|
77361
|
+
},
|
77362
|
+
onBeforeChange: () => {
|
77363
|
+
if (this.onBeforeChange) this.onBeforeChange();
|
77364
|
+
},
|
77365
|
+
onChange: () => {
|
77366
|
+
if (this.onChange) this.onChange();
|
77367
|
+
},
|
77368
|
+
onMultipleSelect: this.onMultipleSelect,
|
77369
|
+
onSelectStart: block => {
|
77370
|
+
// for cloning
|
77371
|
+
this.selectStart(block);
|
77372
|
+
},
|
77373
|
+
onSelectClear: () => {
|
77374
|
+
// for removing clones
|
77375
|
+
this.selectClear();
|
77376
|
+
if (this.onUnselectBlock) this.onUnselectBlock();
|
77377
|
+
},
|
77378
|
+
onSelectBlock: this.onSelectBlock
|
77379
|
+
});
|
77380
|
+
this.resizable = new Resizable({
|
77381
|
+
selector: this.selector,
|
77382
|
+
disableOnMobile: this.disableOnMobile,
|
77383
|
+
doc: this.doc,
|
77384
|
+
win: this.win,
|
77385
|
+
onBeforeChange: () => {
|
77386
|
+
if (this.onBeforeChange) this.onBeforeChange();
|
77387
|
+
},
|
77388
|
+
onChange: () => {
|
77389
|
+
if (this.onChange) this.onChange();
|
77390
|
+
}
|
77391
|
+
});
|
77392
|
+
if (this.rotate) {
|
77393
|
+
this.rotatable = new Rotatable({
|
77394
|
+
selector: this.selector,
|
77395
|
+
disableOnMobile: this.disableOnMobile,
|
77396
|
+
doc: this.doc,
|
77397
|
+
win: this.win,
|
77398
|
+
onBeforeChange: () => {
|
77399
|
+
if (this.onBeforeChange) this.onBeforeChange();
|
77400
|
+
},
|
77401
|
+
onChange: () => {
|
77402
|
+
if (this.onChange) this.onChange();
|
77403
|
+
}
|
77404
|
+
});
|
77405
|
+
}
|
77406
|
+
this.editable = new Editable({
|
77407
|
+
selector: this.selector,
|
77408
|
+
controlSelector: this.controlSelector,
|
77409
|
+
doc: this.doc,
|
77410
|
+
win: this.win,
|
77411
|
+
onContentClick: this.onContentClick,
|
77412
|
+
onEditStart: block => {
|
77413
|
+
if (block.classList.contains('clone')) {
|
77414
|
+
const clonedTarget = this.doc.querySelector(this.selector + '.cloned');
|
77415
|
+
this.onEditStart(clonedTarget);
|
77416
|
+
this.selectClear();
|
77417
|
+
|
77418
|
+
// Disable drag during editing
|
77419
|
+
if (!this.draggable) return;
|
77420
|
+
this.draggable.disableDrag(clonedTarget);
|
77421
|
+
return;
|
77422
|
+
}
|
77423
|
+
this.onEditStart(block);
|
77424
|
+
|
77425
|
+
// Disable drag during editing
|
77426
|
+
if (!this.draggable) return;
|
77427
|
+
this.draggable.disableDrag(block);
|
77428
|
+
},
|
77429
|
+
onEditEnd: block => {
|
77430
|
+
this.onEditEnd(block);
|
77431
|
+
|
77432
|
+
// Enable drag
|
77433
|
+
if (!this.draggable) return;
|
77434
|
+
this.draggable.enableDrag(block);
|
77435
|
+
}
|
77436
|
+
});
|
77437
|
+
this.blockSelector = new BlockSelector({
|
77438
|
+
selector: this.selector,
|
77439
|
+
parentSelector: this.parentSelector,
|
77440
|
+
disableOnMobile: this.disableOnMobile,
|
77441
|
+
onMultipleSelect: this.onMultipleSelect,
|
77442
|
+
doc: this.doc,
|
77443
|
+
win: this.win
|
77444
|
+
});
|
77445
|
+
this.common = new Common({
|
77446
|
+
selector: this.selector,
|
77447
|
+
doc: this.doc,
|
77448
|
+
win: this.win,
|
77449
|
+
onDuplicate: this.onDuplicate
|
77450
|
+
});
|
77451
|
+
}
|
77452
|
+
duplicate() {
|
77453
|
+
this.common.duplicate();
|
77454
|
+
this.refresh();
|
77455
|
+
}
|
77456
|
+
delete() {
|
77457
|
+
this.draggable.delete();
|
77458
|
+
}
|
77459
|
+
getBreakpoints(block) {
|
77460
|
+
return this.common.getBreakpoints(block);
|
77461
|
+
}
|
77462
|
+
placeCursorAtEnd(block) {
|
77463
|
+
this.editable.placeCursorAtEnd(block);
|
77464
|
+
}
|
77465
|
+
quitEditable(block) {
|
77466
|
+
this.editable.quitEditable(block);
|
77467
|
+
}
|
77468
|
+
destroy() {
|
77469
|
+
if (!this.draggable) return;
|
77470
|
+
this.draggable.destroy();
|
77471
|
+
this.resizable.destroy();
|
77472
|
+
if (this.rotatable) this.rotatable.destroy();
|
77473
|
+
this.editable.destroy();
|
77474
|
+
this.blockSelector.destroy();
|
77475
|
+
this.draggable = null;
|
77476
|
+
this.doc.body.classList.remove('editableblocks');
|
77477
|
+
}
|
77478
|
+
refresh() {
|
77479
|
+
// Call refresh() whenever blocks are added
|
77480
|
+
this.draggable.refresh();
|
77481
|
+
this.resizable.refresh();
|
77482
|
+
if (this.rotatable) this.rotatable.refresh();
|
77483
|
+
this.editable.refresh();
|
77484
|
+
}
|
77485
|
+
addBlock(html, container) {
|
77486
|
+
this.selectClear(); // clear clones
|
77487
|
+
this.blockSelector.unSelect(); // clear active
|
77488
|
+
|
77489
|
+
const parser = new DOMParser();
|
77490
|
+
let doc = parser.parseFromString(html, 'text/html');
|
77491
|
+
const block = doc.querySelector('.is-block');
|
77492
|
+
block.classList.add('block-dummy');
|
77493
|
+
html = doc.body.innerHTML;
|
77494
|
+
container.insertAdjacentHTML('beforeend', html);
|
77495
|
+
const newBlock = document.querySelector('.block-dummy');
|
77496
|
+
if (newBlock) {
|
77497
|
+
newBlock.classList.remove('block-dummy');
|
77498
|
+
if (this.onAddBlock) this.onAddBlock(newBlock);
|
77499
|
+
newBlock.classList.add('active');
|
77500
|
+
}
|
77501
|
+
this.refresh();
|
77502
|
+
}
|
77503
|
+
group() {
|
77504
|
+
const group = this.common.group('is-block', 'is-group');
|
77505
|
+
this.refresh();
|
77506
|
+
return group;
|
77507
|
+
}
|
77508
|
+
unGroup() {
|
77509
|
+
this.common.unGroup();
|
77510
|
+
}
|
77511
|
+
addBreakpoint() {
|
77512
|
+
this.common.addBreakpoint();
|
77513
|
+
}
|
77514
|
+
clearBreakpoint(target) {
|
77515
|
+
this.common.clearBreakpoint(target);
|
77516
|
+
if (target.classList.contains('cloned')) {
|
77517
|
+
const cloneTarget = this.doc.querySelector(this.selector + '.clone');
|
77518
|
+
this.common.clearBreakpoint(cloneTarget);
|
77519
|
+
}
|
77520
|
+
}
|
77521
|
+
clearAllBreakpoints(container) {
|
77522
|
+
this.common.clearAllBreakpoints(container);
|
77523
|
+
}
|
77524
|
+
isMultiSelect() {
|
77525
|
+
// Check if multiple selection occurs. If so, add 'multi' class to hide all the handles
|
77526
|
+
let blocks = Array.from(this.doc.querySelectorAll(this.selector)).filter(elm => elm.classList.contains('active') && !elm.classList.contains('clone'));
|
77527
|
+
if (blocks.length > 1) return true;
|
77528
|
+
return false;
|
77529
|
+
}
|
77530
|
+
}
|
75407
77531
|
|
75408
77532
|
class ContentBuilder {
|
75409
77533
|
constructor(opts = {}) {
|
@@ -75644,9 +77768,11 @@ class ContentBuilder {
|
|
75644
77768
|
defaultEmailSnippetCategory: 14,
|
75645
77769
|
undoRedoStyles: false,
|
75646
77770
|
// specialElementClasses: ['sl-wrapper', 'sl-overlay'] // specify elements that when clicked will not affect the builder interface (active selection). Usefull for external code, ex lightbox, etc.
|
75647
|
-
// onUndo: function () { },
|
75648
|
-
// onRedo: function () { }
|
75649
77771
|
|
77772
|
+
// freeform
|
77773
|
+
onUndo: function () {},
|
77774
|
+
onRedo: function () {},
|
77775
|
+
onBlockCanvasAdd: function () {},
|
75650
77776
|
/*
|
75651
77777
|
Deprecated:
|
75652
77778
|
snippetSampleImage: '',
|
@@ -76528,6 +78654,26 @@ class ContentBuilder {
|
|
76528
78654
|
this.colTool.lockIndicator.style.display = '';
|
76529
78655
|
return ret;
|
76530
78656
|
};
|
78657
|
+
|
78658
|
+
// freeform
|
78659
|
+
let oldOnBlockCanvasAdd = this.opts.onBlockCanvasAdd;
|
78660
|
+
this.opts.onBlockCanvasAdd = () => {
|
78661
|
+
let ret = oldOnBlockCanvasAdd.apply(this, arguments);
|
78662
|
+
if (this.eb) this.eb.refresh();
|
78663
|
+
return ret;
|
78664
|
+
};
|
78665
|
+
let oldOnUndo = this.opts.onUndo;
|
78666
|
+
this.opts.onUndo = () => {
|
78667
|
+
let ret = oldOnUndo.apply(this, arguments);
|
78668
|
+
if (this.eb) this.eb.refresh();
|
78669
|
+
return ret;
|
78670
|
+
};
|
78671
|
+
let oldOnRedo = this.opts.onRedo;
|
78672
|
+
this.opts.onRedo = () => {
|
78673
|
+
let ret = oldOnRedo.apply(this, arguments);
|
78674
|
+
if (this.eb) this.eb.refresh();
|
78675
|
+
return ret;
|
78676
|
+
};
|
76531
78677
|
this.elmTool = new ElementTool(this); // Render Element Tool
|
76532
78678
|
|
76533
78679
|
// Render controls or behavior for handling element editing
|
@@ -76595,6 +78741,68 @@ class ContentBuilder {
|
|
76595
78741
|
}
|
76596
78742
|
*/
|
76597
78743
|
|
78744
|
+
// freeform
|
78745
|
+
if (this.canvas) this.eb = new EditableBlocks({
|
78746
|
+
doc: this.doc,
|
78747
|
+
win: this.win,
|
78748
|
+
selector: '.is-block',
|
78749
|
+
controlSelector: '.is-tool,.is-pop,.is-modal,#divImageResizer,.is-rte-tool,is-elementrte-tool,.is-rte-pop,.keep-selection',
|
78750
|
+
parentSelector: '.box-canvas',
|
78751
|
+
rotate: true,
|
78752
|
+
// disableOnMobile: 760,
|
78753
|
+
onBeforeChange: () => {
|
78754
|
+
this.uo.saveForUndo();
|
78755
|
+
},
|
78756
|
+
onChange: () => {
|
78757
|
+
this.opts.onChange();
|
78758
|
+
},
|
78759
|
+
onEditStart: block => {
|
78760
|
+
block.classList.add('editable');
|
78761
|
+
const cols = block.querySelectorAll('[data-click="true"]'); // or [contentEditable="true"]
|
78762
|
+
if (cols.length > 0) {
|
78763
|
+
let col = cols[cols.length - 1];
|
78764
|
+
if (col.lastElementChild) col.lastElementChild.click();
|
78765
|
+
}
|
78766
|
+
},
|
78767
|
+
onEditEnd: block => {
|
78768
|
+
block.classList.remove('editable');
|
78769
|
+
this.util.clearActiveCell();
|
78770
|
+
this.util.clearPops();
|
78771
|
+
this.hideElementTools();
|
78772
|
+
},
|
78773
|
+
onDuplicate: block => {
|
78774
|
+
const builder = block.querySelector(this.container);
|
78775
|
+
let html = '';
|
78776
|
+
if (builder) {
|
78777
|
+
html = this.readHtml(builder);
|
78778
|
+
}
|
78779
|
+
let clonedDiv = block.cloneNode(true);
|
78780
|
+
clonedDiv.style.top = '20%';
|
78781
|
+
clonedDiv.style.left = '20%';
|
78782
|
+
if (builder) {
|
78783
|
+
const cloneBuilder = clonedDiv.querySelector(this.container);
|
78784
|
+
cloneBuilder.innerHTML = '';
|
78785
|
+
block.parentNode.appendChild(clonedDiv);
|
78786
|
+
const range = document.createRange();
|
78787
|
+
cloneBuilder.appendChild(range.createContextualFragment(html));
|
78788
|
+
this.applyBehaviorOn(cloneBuilder);
|
78789
|
+
cloneBuilder.click();
|
78790
|
+
} else {
|
78791
|
+
block.parentNode.appendChild(clonedDiv);
|
78792
|
+
}
|
78793
|
+
block.classList.remove('active');
|
78794
|
+
this.doc.querySelectorAll('.clone').forEach(elm => elm.parentNode.removeChild(elm));
|
78795
|
+
this.doc.querySelectorAll('.cloned').forEach(elm => elm.classList.remove('cloned'));
|
78796
|
+
},
|
78797
|
+
onAddBlock: block => {
|
78798
|
+
const builder = block.querySelector(this.container);
|
78799
|
+
this.applyBehaviorOn(builder);
|
78800
|
+
},
|
78801
|
+
onMultipleSelect: this.onMultipleSelect,
|
78802
|
+
onDelete: this.onDelete,
|
78803
|
+
onSelectBlock: this.onSelectBlock,
|
78804
|
+
onUnselectBlock: this.onUnselectBlock
|
78805
|
+
});
|
76598
78806
|
if (this.iframe) {
|
76599
78807
|
this.win.addEventListener('scroll', this.doWindowScroll = () => {
|
76600
78808
|
this.util.hidePops();
|
@@ -77415,6 +79623,13 @@ class ContentBuilder {
|
|
77415
79623
|
this.setZoomOnControl(builder);
|
77416
79624
|
}
|
77417
79625
|
html(area) {
|
79626
|
+
if (this.docContainer) {
|
79627
|
+
// freeform
|
79628
|
+
|
79629
|
+
const docContainer = this.doc.querySelector(this.docContainer);
|
79630
|
+
const html = this.readHtml(docContainer, false, true);
|
79631
|
+
return html;
|
79632
|
+
}
|
77418
79633
|
const util = this.util;
|
77419
79634
|
const htmlutil = new HtmlUtil(this);
|
77420
79635
|
if (area) ; else {
|
@@ -77481,7 +79696,87 @@ class ContentBuilder {
|
|
77481
79696
|
simpleColorPicker(onPick, mode) {
|
77482
79697
|
return this.colorClassPicker.open(onPick, mode);
|
77483
79698
|
}
|
79699
|
+
|
79700
|
+
// freeform
|
79701
|
+
refresh() {
|
79702
|
+
if (this.eb) this.eb.refresh();
|
79703
|
+
}
|
79704
|
+
group() {
|
79705
|
+
if (!this.eb) return;
|
79706
|
+
this.uo.saveForUndo();
|
79707
|
+
this.eb.group();
|
79708
|
+
this.opts.onChange();
|
79709
|
+
}
|
79710
|
+
unGroup() {
|
79711
|
+
if (!this.eb) return;
|
79712
|
+
this.uo.saveForUndo();
|
79713
|
+
this.eb.unGroup();
|
79714
|
+
this.opts.onChange();
|
79715
|
+
}
|
79716
|
+
delete() {
|
79717
|
+
if (!this.eb) return;
|
79718
|
+
this.uo.saveForUndo();
|
79719
|
+
this.eb.delete();
|
79720
|
+
this.opts.onChange();
|
79721
|
+
}
|
79722
|
+
forward(target) {
|
79723
|
+
if (!this.eb) return;
|
79724
|
+
this.uo.saveForUndo();
|
79725
|
+
this.eb.forward(target);
|
79726
|
+
this.opts.onChange();
|
79727
|
+
}
|
79728
|
+
backward(target) {
|
79729
|
+
if (!this.eb) return;
|
79730
|
+
this.uo.saveForUndo();
|
79731
|
+
this.eb.backward(target);
|
79732
|
+
this.opts.onChange();
|
79733
|
+
}
|
79734
|
+
enableShape() {
|
79735
|
+
if (!this.eb) return;
|
79736
|
+
this.uo.saveForUndo();
|
79737
|
+
this.eb.enableShape();
|
79738
|
+
this.opts.onChange();
|
79739
|
+
}
|
79740
|
+
removeShape() {
|
79741
|
+
if (!this.eb) return;
|
79742
|
+
this.uo.saveForUndo();
|
79743
|
+
this.eb.removeShape();
|
79744
|
+
this.opts.onChange();
|
79745
|
+
}
|
79746
|
+
addBlock(html, blockContainer) {
|
79747
|
+
if (!this.eb) return;
|
79748
|
+
this.uo.saveForUndo();
|
79749
|
+
this.eb.addBlock(html, blockContainer);
|
79750
|
+
this.opts.onChange();
|
79751
|
+
this.opts.onRender();
|
79752
|
+
}
|
79753
|
+
duplicate() {
|
79754
|
+
if (!this.eb) return;
|
79755
|
+
this.uo.saveForUndo();
|
79756
|
+
this.eb.duplicate();
|
79757
|
+
this.opts.onChange();
|
79758
|
+
this.opts.onRender();
|
79759
|
+
}
|
79760
|
+
addBreakpoint() {
|
79761
|
+
if (!this.eb) return;
|
79762
|
+
this.eb.addBreakpoint();
|
79763
|
+
}
|
79764
|
+
getBreakpoints(target) {
|
79765
|
+
if (!this.eb) return;
|
79766
|
+
return this.eb.getBreakpoints(target);
|
79767
|
+
}
|
79768
|
+
clearBreakpoint(target) {
|
79769
|
+
if (!this.eb) return;
|
79770
|
+
this.uo.saveForUndo();
|
79771
|
+
this.eb.clearBreakpoint(target);
|
79772
|
+
this.opts.onChange();
|
79773
|
+
}
|
79774
|
+
quitEditable(target) {
|
79775
|
+
if (!this.eb) return;
|
79776
|
+
this.eb.quitEditable(target);
|
79777
|
+
}
|
77484
79778
|
destroy() {
|
79779
|
+
if (this.eb) this.eb.destroy();
|
77485
79780
|
this.doc.body.classList.remove('data-editor');
|
77486
79781
|
document.removeEventListener('click', this.doDocumentClick, false);
|
77487
79782
|
document.removeEventListener('keydown', this.doDocumentKeydown, false);
|
@@ -78103,7 +80398,7 @@ class ContentBuilder {
|
|
78103
80398
|
this.opts.onPluginsLoaded();
|
78104
80399
|
}
|
78105
80400
|
this.tooltip.setAll();
|
78106
|
-
new Draggable$
|
80401
|
+
new Draggable$2({
|
78107
80402
|
selector: '.is-draggable'
|
78108
80403
|
}); //draggable for plugins
|
78109
80404
|
|
@@ -78164,7 +80459,7 @@ class ContentBuilder {
|
|
78164
80459
|
this.opts.onPluginsLoaded();
|
78165
80460
|
}
|
78166
80461
|
this.tooltip.setAll();
|
78167
|
-
new Draggable$
|
80462
|
+
new Draggable$2({
|
78168
80463
|
selector: '.is-draggable'
|
78169
80464
|
}); //draggable for plugins
|
78170
80465
|
|
@@ -78320,7 +80615,7 @@ class ContentBuilder {
|
|
78320
80615
|
}
|
78321
80616
|
|
78322
80617
|
draggable(selector) {
|
78323
|
-
new Draggable$
|
80618
|
+
new Draggable$2({
|
78324
80619
|
selector: selector
|
78325
80620
|
});
|
78326
80621
|
}
|
@@ -78331,7 +80626,7 @@ class ContentBuilder {
|
|
78331
80626
|
embeddedModal = this.builderStuff.querySelector(selector);
|
78332
80627
|
}
|
78333
80628
|
this.showModal(embeddedModal, overlayStay, cancelCallback, animated, overflowHidden);
|
78334
|
-
new Draggable$
|
80629
|
+
new Draggable$2({
|
78335
80630
|
selector: '.is-draggable'
|
78336
80631
|
});
|
78337
80632
|
return embeddedModal;
|
@@ -78457,6 +80752,10 @@ class ContentBuilder {
|
|
78457
80752
|
// /Plugins related
|
78458
80753
|
|
78459
80754
|
viewHtml(area) {
|
80755
|
+
if (this.docContainer) {
|
80756
|
+
// freeform
|
80757
|
+
area = this.doc.querySelector(this.docContainer);
|
80758
|
+
}
|
78460
80759
|
const htmlutil = new HtmlUtil(this);
|
78461
80760
|
htmlutil.view('full', area);
|
78462
80761
|
}
|
@@ -78503,6 +80802,20 @@ class ContentBuilder {
|
|
78503
80802
|
return false;
|
78504
80803
|
}
|
78505
80804
|
loadHtml(html, area) {
|
80805
|
+
if (this.docContainer) {
|
80806
|
+
// freeform
|
80807
|
+
const docContainer = this.doc.querySelector(this.docContainer);
|
80808
|
+
let range = this.doc.createRange();
|
80809
|
+
docContainer.innerHTML = '';
|
80810
|
+
docContainer.appendChild(range.createContextualFragment(html)); // We use createContextualFragment so that embedded javascript code (code block) will be executed
|
80811
|
+
|
80812
|
+
const builders = docContainer.querySelectorAll(this.container);
|
80813
|
+
builders.forEach(builder => {
|
80814
|
+
this.applyBehaviorOn(builder);
|
80815
|
+
});
|
80816
|
+
this.refresh();
|
80817
|
+
return;
|
80818
|
+
}
|
78506
80819
|
const util = this.util;
|
78507
80820
|
if (area) ; else {
|
78508
80821
|
const builders = this.doc.querySelectorAll(this.opts.container);
|
@@ -78561,6 +80874,7 @@ class ContentBuilder {
|
|
78561
80874
|
// }
|
78562
80875
|
loadHTML(html) {
|
78563
80876
|
//backward
|
80877
|
+
|
78564
80878
|
this.loadHtml(html);
|
78565
80879
|
}
|
78566
80880
|
async setUIColor(mode, csslink) {
|