@innovastudio/contentbox 1.6.108 → 1.6.110
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11531,34 +11531,38 @@ class PanelImage {
|
|
11531
11531
|
|
11532
11532
|
let html = `
|
11533
11533
|
<div class="submain">
|
11534
|
-
<div class="asset-preview"></div>
|
11535
11534
|
|
11536
|
-
<
|
11537
|
-
<div>${out('Source')}:</div>
|
11538
|
-
<input type="text" class="inp-src" id="_inp_src_${this.random()}">
|
11539
|
-
</label>
|
11535
|
+
<div class="div-image-settings">
|
11540
11536
|
|
11541
|
-
|
11542
|
-
<input class="inp-file" type="file" accept="image/*" style="display:none"/>
|
11543
|
-
<button title="${out('Upload')}" class="btn-upload"><svg><use xlink:href="#icon-upload"></use></svg></button>
|
11544
|
-
<button title="${out('Select')}" class="btn-asset"><svg><use xlink:href="#icon-folder"></use></svg></button>
|
11545
|
-
<button title="${out('Link')}" class="btn-link"><svg style="transform:rotate(45deg)"><use xlink:href="#icon-link"></use></svg></button>
|
11546
|
-
<button title="${out('Edit')}" class="btn-edit"><svg><use xlink:href="#icon-pencil"></use></svg></button>
|
11547
|
-
</div>
|
11537
|
+
<div class="asset-preview"></div>
|
11548
11538
|
|
11549
|
-
|
11550
|
-
|
11551
|
-
|
11552
|
-
|
11553
|
-
<button title="${out('Align Right')}" data-align="right"><svg style="width:13px;height:13px;"><use xlink:href="#icon-align-right"></use></svg></button>
|
11554
|
-
<button title="${out('Align Full')}" data-align="justify"><svg style="width:13px;height:13px;"><use xlink:href="#icon-align-full"></use></svg></button>
|
11555
|
-
</div>
|
11556
|
-
-->
|
11539
|
+
<label class="label mt-3">
|
11540
|
+
<div>${out('Source')}:</div>
|
11541
|
+
<input type="text" class="inp-src" id="_inp_src_${this.random()}">
|
11542
|
+
</label>
|
11557
11543
|
|
11558
|
-
|
11559
|
-
|
11560
|
-
|
11561
|
-
|
11544
|
+
<div class="group mt-4">
|
11545
|
+
<input class="inp-file" type="file" accept="image/*" style="display:none"/>
|
11546
|
+
<button title="${out('Upload')}" class="btn-upload"><svg><use xlink:href="#icon-upload"></use></svg></button>
|
11547
|
+
<button title="${out('Select')}" class="btn-asset"><svg><use xlink:href="#icon-folder"></use></svg></button>
|
11548
|
+
<button title="${out('Link')}" class="btn-link"><svg style="transform:rotate(45deg)"><use xlink:href="#icon-link"></use></svg></button>
|
11549
|
+
<button title="${out('Edit')}" class="btn-edit"><svg><use xlink:href="#icon-pencil"></use></svg></button>
|
11550
|
+
</div>
|
11551
|
+
|
11552
|
+
<!--
|
11553
|
+
<div class="group">
|
11554
|
+
<button title="${out('Align Left')}" data-align="left"><svg style="width:13px;height:13px;"><use xlink:href="#icon-align-left"></use></svg></button>
|
11555
|
+
<button title="${out('Align Center')}" data-align="center"><svg style="width:13px;height:13px;"><use xlink:href="#icon-align-center"></use></svg></button>
|
11556
|
+
<button title="${out('Align Right')}" data-align="right"><svg style="width:13px;height:13px;"><use xlink:href="#icon-align-right"></use></svg></button>
|
11557
|
+
<button title="${out('Align Full')}" data-align="justify"><svg style="width:13px;height:13px;"><use xlink:href="#icon-align-full"></use></svg></button>
|
11558
|
+
</div>
|
11559
|
+
-->
|
11560
|
+
|
11561
|
+
<label class="label mt-2">
|
11562
|
+
<div>${out('Title')}:</div>
|
11563
|
+
<input type="text" class="inp-title" id="_inp_title_${this.random()}">
|
11564
|
+
</label>
|
11565
|
+
</div>
|
11562
11566
|
</div>
|
11563
11567
|
`;
|
11564
11568
|
panel.insertAdjacentHTML('beforeend', html);
|
@@ -11667,6 +11671,14 @@ class PanelImage {
|
|
11667
11671
|
inpSrc.value = 'image/jpeg (base64)';
|
11668
11672
|
}
|
11669
11673
|
|
11674
|
+
const divSettings = panel.querySelector('.div-image-settings');
|
11675
|
+
|
11676
|
+
if (img.closest('[data-html]')) {
|
11677
|
+
divSettings.style.display = 'none';
|
11678
|
+
} else {
|
11679
|
+
divSettings.style.display = '';
|
11680
|
+
}
|
11681
|
+
|
11670
11682
|
const inpTitle = panel.querySelector('.inp-title');
|
11671
11683
|
inpTitle.value = alt;
|
11672
11684
|
}
|
@@ -11713,28 +11725,32 @@ class PanelVideo {
|
|
11713
11725
|
this.builder = builder;
|
11714
11726
|
let html = `
|
11715
11727
|
<div class="submain">
|
11716
|
-
<div class="asset-preview"></div>
|
11717
11728
|
|
11718
|
-
<
|
11719
|
-
<div>${out('Source')}:</div>
|
11720
|
-
<input type="text" class="inp-src">
|
11721
|
-
</label>
|
11729
|
+
<div class="div-video-settings">
|
11722
11730
|
|
11723
|
-
|
11724
|
-
|
11725
|
-
<
|
11726
|
-
|
11727
|
-
|
11731
|
+
<div class="asset-preview"></div>
|
11732
|
+
|
11733
|
+
<label class="label mt-3">
|
11734
|
+
<div>${out('Source')}:</div>
|
11735
|
+
<input type="text" class="inp-src">
|
11736
|
+
</label>
|
11728
11737
|
|
11729
|
-
|
11730
|
-
|
11731
|
-
|
11732
|
-
|
11733
|
-
|
11734
|
-
|
11735
|
-
|
11736
|
-
|
11737
|
-
|
11738
|
+
<div class="group mt-4">
|
11739
|
+
<input class="inp-file" type="file" accept="video/mp4" style="display:none"/>
|
11740
|
+
<button title="${out('Upload')}" class="btn-upload"><svg><use xlink:href="#icon-upload"></use></svg></button>
|
11741
|
+
<button title="${out('Select')}" class="btn-asset"><svg><use xlink:href="#icon-folder"></use></svg></button>
|
11742
|
+
</div>
|
11743
|
+
|
11744
|
+
<label class="label checkbox mt-4">
|
11745
|
+
<input class="inp-video-controls" type="checkbox" /> <span>${out('Show Controls')}</span>
|
11746
|
+
</label>
|
11747
|
+
<label class="label checkbox mt-2">
|
11748
|
+
<input class="inp-video-loop" type="checkbox" /> <span>${out('Loop')}</span>
|
11749
|
+
</label>
|
11750
|
+
<label class="label checkbox mt-2">
|
11751
|
+
<input class="inp-video-autoplay" type="checkbox" /> <span>${out('Autoplay')}</span>
|
11752
|
+
</label>
|
11753
|
+
</div>
|
11738
11754
|
|
11739
11755
|
</div>
|
11740
11756
|
`;
|
@@ -11839,7 +11855,22 @@ class PanelVideo {
|
|
11839
11855
|
const src = source ? source.getAttribute('src') : '';
|
11840
11856
|
this.updatePreview(src);
|
11841
11857
|
const inpSrc = panel.querySelector('.inp-src');
|
11842
|
-
|
11858
|
+
|
11859
|
+
if (src.indexOf('base64') === -1) {
|
11860
|
+
inpSrc.value = src;
|
11861
|
+
} else {
|
11862
|
+
// inpSrc.value = '[Image Data]';
|
11863
|
+
inpSrc.value = 'video/mp4 (base64)';
|
11864
|
+
}
|
11865
|
+
|
11866
|
+
const divSettings = panel.querySelector('.div-video-settings');
|
11867
|
+
|
11868
|
+
if (video.closest('[data-html]')) {
|
11869
|
+
divSettings.style.display = 'none';
|
11870
|
+
} else {
|
11871
|
+
divSettings.style.display = '';
|
11872
|
+
}
|
11873
|
+
|
11843
11874
|
const inpShowControls = panel.querySelector('.inp-video-controls');
|
11844
11875
|
|
11845
11876
|
if (video.hasAttribute('controls')) {
|
@@ -12673,7 +12704,7 @@ class PanelCode {
|
|
12673
12704
|
</button>
|
12674
12705
|
</div>
|
12675
12706
|
|
12676
|
-
<div class="group flex">
|
12707
|
+
<div class="group flex" style="width:100%">
|
12677
12708
|
<button title="${out('Configure')}" class="btn-editmodule">
|
12678
12709
|
<svg><use xlink:href="#icon-settings"></use></svg>
|
12679
12710
|
<span>${out('Configure')}</span>
|
@@ -27271,6 +27302,14 @@ class Snippets {
|
|
27271
27302
|
// }
|
27272
27303
|
|
27273
27304
|
}
|
27305
|
+
|
27306
|
+
|
27307
|
+
if(!(parent._cb.win.FormViewer)){
|
27308
|
+
const result = snippets.filter((item)=>{
|
27309
|
+
return !(item.type === 'form');
|
27310
|
+
});
|
27311
|
+
snippets = [...result];
|
27312
|
+
}
|
27274
27313
|
|
27275
27314
|
|
27276
27315
|
for (let i = 0; i <snippets.length; i++) {
|
@@ -42499,6 +42538,12 @@ const prepareSvgIcons = builder => {
|
|
42499
42538
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
42500
42539
|
<path d="M5 12l14 0"></path>
|
42501
42540
|
</symbol>
|
42541
|
+
<symbol id="icon-upload" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
42542
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
42543
|
+
<path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2"></path>
|
42544
|
+
<path d="M7 9l5 -5l5 5"></path>
|
42545
|
+
<path d="M12 4l0 12"></path>
|
42546
|
+
</symbol>
|
42502
42547
|
</svg>`;
|
42503
42548
|
builder.dom.appendHtml(builder.builderStuff, html);
|
42504
42549
|
};
|
@@ -44430,6 +44475,15 @@ const renderSnippetPanel = (builder, snippetOpen) => {
|
|
44430
44475
|
|
44431
44476
|
builder.opts.snippetJSON.snippets = [...snippets];
|
44432
44477
|
}
|
44478
|
+
|
44479
|
+
// Exclude form snippet if FormViewer not found.
|
44480
|
+
if (!builder.win.FormViewer) {
|
44481
|
+
const result = snippets.filter(item => {
|
44482
|
+
return !(item.type === 'form');
|
44483
|
+
});
|
44484
|
+
snippets = [...result];
|
44485
|
+
}
|
44486
|
+
builder.opts.snippetJSON.snippets = [...snippets];
|
44433
44487
|
let index = 1;
|
44434
44488
|
if (builder.opts.emailMode) {
|
44435
44489
|
builder.opts.snippetJSON.snippets.forEach(item => {
|
@@ -71888,6 +71942,106 @@ var loadImageOrientation = {exports: {}};
|
|
71888
71942
|
|
71889
71943
|
var js$2 = loadImage.exports;
|
71890
71944
|
|
71945
|
+
class DragDropImageUploader {
|
71946
|
+
constructor(element, builder) {
|
71947
|
+
this.element = element;
|
71948
|
+
this.builder = builder;
|
71949
|
+
this.targetImage = null;
|
71950
|
+
this.isAttached = false;
|
71951
|
+
this._onDragOver = this._onDragOver.bind(this);
|
71952
|
+
this._onDragLeave = this._onDragLeave.bind(this);
|
71953
|
+
this._onDrop = this._onDrop.bind(this);
|
71954
|
+
}
|
71955
|
+
attach() {
|
71956
|
+
if (this.isAttached) return; // Prevent duplicate attachment
|
71957
|
+
|
71958
|
+
this.element.addEventListener('dragover', this._onDragOver);
|
71959
|
+
this.element.addEventListener('dragleave', this._onDragLeave);
|
71960
|
+
this.element.addEventListener('drop', this._onDrop);
|
71961
|
+
this.isAttached = true;
|
71962
|
+
}
|
71963
|
+
detach() {
|
71964
|
+
if (!this.isAttached) return;
|
71965
|
+
this.element.removeEventListener('dragover', this._onDragOver);
|
71966
|
+
this.element.removeEventListener('dragleave', this._onDragLeave);
|
71967
|
+
this.element.removeEventListener('drop', this._onDrop);
|
71968
|
+
this.isAttached = false;
|
71969
|
+
}
|
71970
|
+
_getImageUnderCursor(e) {
|
71971
|
+
const doc = this.element.ownerDocument || document;
|
71972
|
+
const range = doc.caretRangeFromPoint ? doc.caretRangeFromPoint(e.clientX, e.clientY) : doc.caretPositionFromPoint(e.clientX, e.clientY);
|
71973
|
+
if (!range) return null;
|
71974
|
+
const node = range.startContainer.nodeType === 1 ? range.startContainer : range.startContainer.parentElement;
|
71975
|
+
if (this.element.getAttribute('id') === 'divImageResizer') {
|
71976
|
+
return this.builder.activeImage;
|
71977
|
+
}
|
71978
|
+
return node.tagName === 'IMG' ? node : node.querySelector && node.querySelector('img');
|
71979
|
+
}
|
71980
|
+
async _onDrop(e) {
|
71981
|
+
e.preventDefault();
|
71982
|
+
if (this.targetImage) {
|
71983
|
+
this.targetImage.classList.remove('drag-over-image');
|
71984
|
+
}
|
71985
|
+
const files = e.dataTransfer.files;
|
71986
|
+
if (files && files.length > 0 && files[0].type.startsWith('image/')) {
|
71987
|
+
const file = files[0];
|
71988
|
+
const result = await this._onUpload(file);
|
71989
|
+
if (result && this.targetImage) {
|
71990
|
+
this.targetImage.setAttribute('src', result.url);
|
71991
|
+
|
71992
|
+
// finished steps:
|
71993
|
+
|
71994
|
+
// let imageProgress = document.querySelector('#divImageProgress');
|
71995
|
+
// if(imageProgress) imageProgress.style.display = 'none';
|
71996
|
+
|
71997
|
+
//Check if image is part of module snippet. If so, refresh the (active) module (hide imageTool). If not, refresh imageTool position
|
71998
|
+
this.builder.element.image.refreshIfIsModule(this.targetImage);
|
71999
|
+
this.builder.element.image.startImageMonitor(this.targetImage);
|
72000
|
+
|
72001
|
+
//Trigger Change event
|
72002
|
+
this.builder.opts.onChange();
|
72003
|
+
this.builder.elmTool.refresh();
|
72004
|
+
if (this.builder.onImageChange) this.builder.onImageChange();
|
72005
|
+
}
|
72006
|
+
}
|
72007
|
+
this.targetImage = null;
|
72008
|
+
}
|
72009
|
+
_onDragOver(e) {
|
72010
|
+
e.preventDefault();
|
72011
|
+
const img = this._getImageUnderCursor(e);
|
72012
|
+
if (img) {
|
72013
|
+
if (this.targetImage && this.targetImage !== img) {
|
72014
|
+
this.targetImage.classList.remove('drag-over-image');
|
72015
|
+
}
|
72016
|
+
this.targetImage = img;
|
72017
|
+
this.targetImage.classList.add('drag-over-image');
|
72018
|
+
}
|
72019
|
+
}
|
72020
|
+
_onDragLeave() {
|
72021
|
+
if (this.targetImage) {
|
72022
|
+
this.targetImage.classList.remove('drag-over-image');
|
72023
|
+
this.targetImage = null;
|
72024
|
+
}
|
72025
|
+
}
|
72026
|
+
_onUpload(file) {
|
72027
|
+
return new Promise(resolve => {
|
72028
|
+
this.builder.opts.onAssetUpload = url => {
|
72029
|
+
resolve({
|
72030
|
+
url: url,
|
72031
|
+
name: file.name,
|
72032
|
+
size: file.size
|
72033
|
+
});
|
72034
|
+
};
|
72035
|
+
const fakeEvent = {
|
72036
|
+
target: {
|
72037
|
+
files: [file]
|
72038
|
+
}
|
72039
|
+
};
|
72040
|
+
this.builder.opts.onImageUpload(fakeEvent);
|
72041
|
+
});
|
72042
|
+
}
|
72043
|
+
}
|
72044
|
+
|
71891
72045
|
class Image$1 {
|
71892
72046
|
constructor(builder) {
|
71893
72047
|
this.builder = builder;
|
@@ -71929,6 +72083,15 @@ class Image$1 {
|
|
71929
72083
|
this.imageTool = imageTool;
|
71930
72084
|
imageResizer = document.querySelector('#divImageResizer');
|
71931
72085
|
this.imageResizer = imageResizer;
|
72086
|
+
|
72087
|
+
// upload
|
72088
|
+
if (this.builder.opts.onImageUpload) {
|
72089
|
+
if (!imageResizer._dragDropUploaderAttached) {
|
72090
|
+
imageResizer._dragDropUploaderAttached = true;
|
72091
|
+
const uploader = new DragDropImageUploader(imageResizer, this.builder);
|
72092
|
+
uploader.attach();
|
72093
|
+
}
|
72094
|
+
}
|
71932
72095
|
imageResizer.addEventListener('wheel', () => {
|
71933
72096
|
this.hideImageResizer();
|
71934
72097
|
}, {
|
@@ -72072,20 +72235,70 @@ class Image$1 {
|
|
72072
72235
|
|
72073
72236
|
// Browse local image
|
72074
72237
|
let elm = imageTool.querySelector('#fileEmbedImage');
|
72075
|
-
dom.addEventListener(elm, 'change', e => {
|
72238
|
+
dom.addEventListener(elm, 'change', async e => {
|
72076
72239
|
this.builder.uo.saveForUndo();
|
72077
72240
|
var input = e.target;
|
72078
72241
|
let img = this.builder.activeImage;
|
72242
|
+
|
72243
|
+
// content scaling
|
72244
|
+
let scale = 1;
|
72245
|
+
const contentView = document.querySelector('.is-content-view');
|
72246
|
+
if (contentView) {
|
72247
|
+
const style = window.getComputedStyle(contentView);
|
72248
|
+
const transform = style.transform;
|
72249
|
+
if (transform.startsWith('matrix(')) {
|
72250
|
+
const matrix = new DOMMatrix(transform);
|
72251
|
+
if (matrix.b === 0 && matrix.c === 0 && matrix.a === matrix.d) {
|
72252
|
+
scale = matrix.a; // only if pure scale()
|
72253
|
+
}
|
72254
|
+
}
|
72255
|
+
}
|
72256
|
+
|
72079
72257
|
let imageProgress = builderStuff.querySelector('#divImageProgress');
|
72080
72258
|
imageProgress.style.display = 'table';
|
72081
|
-
imageProgress.style.width = img.offsetWidth * this.builder.opts.zoom + 'px';
|
72082
|
-
imageProgress.style.height = img.offsetHeight * this.builder.opts.zoom + 'px';
|
72259
|
+
imageProgress.style.width = img.offsetWidth * this.builder.opts.zoom * scale + 'px';
|
72260
|
+
imageProgress.style.height = img.offsetHeight * this.builder.opts.zoom * scale + 'px';
|
72083
72261
|
const newPos = this.builder.util.getElementPosition(img);
|
72084
72262
|
let top = newPos.top + window.pageYOffset;
|
72085
72263
|
let left = newPos.left + window.pageXOffset;
|
72086
72264
|
imageProgress.style.top = top + 'px';
|
72087
72265
|
imageProgress.style.left = left + 'px';
|
72088
72266
|
|
72267
|
+
// upload
|
72268
|
+
const onUpload = async e => {
|
72269
|
+
let file = e.target.files[0];
|
72270
|
+
return new Promise(resolve => {
|
72271
|
+
this.builder.opts.onAssetUpload = url => {
|
72272
|
+
resolve({
|
72273
|
+
url: url,
|
72274
|
+
name: file.name,
|
72275
|
+
size: file.size
|
72276
|
+
});
|
72277
|
+
};
|
72278
|
+
this.builder.opts.onImageUpload(e);
|
72279
|
+
});
|
72280
|
+
};
|
72281
|
+
if (this.builder.opts.onImageUpload) {
|
72282
|
+
const result = await onUpload(e);
|
72283
|
+
img.setAttribute('src', result.url);
|
72284
|
+
|
72285
|
+
// finished steps:
|
72286
|
+
|
72287
|
+
imageProgress.style.display = 'none';
|
72288
|
+
elm = imageTool.querySelector('#fileEmbedImage');
|
72289
|
+
elm.value = ''; //clear input
|
72290
|
+
|
72291
|
+
//Check if image is part of module snippet. If so, refresh the (active) module (hide imageTool). If not, refresh imageTool position
|
72292
|
+
this.refreshIfIsModule(img);
|
72293
|
+
this.startImageMonitor(img);
|
72294
|
+
|
72295
|
+
//Trigger Change event
|
72296
|
+
this.builder.opts.onChange();
|
72297
|
+
this.builder.elmTool.refresh();
|
72298
|
+
if (this.builder.onImageChange) this.builder.onImageChange();
|
72299
|
+
return;
|
72300
|
+
}
|
72301
|
+
|
72089
72302
|
//The #fileEmbedImage triggered 2 times in IE (because of clearInputs below). This makes input.files[0].name returns error on 2nd trigger. Just add try{}!
|
72090
72303
|
try {
|
72091
72304
|
img.setAttribute('data-filename', input.files[0].name); //needed for saveimage.js |
|
@@ -72302,7 +72515,7 @@ class Image$1 {
|
|
72302
72515
|
<div class="image-larger1 is-btn classic" style="position:relative;flex:none;box-shadow: 0px 3px 6px -6px rgba(0, 0, 0, 0.32);">
|
72303
72516
|
<form class="form-upload-larger" target="frameTargetImageUpload" method="post" action="${this.builder.opts.largerImageHandler}" enctype="multipart/form-data" style="border-radius:1px;position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;">
|
72304
72517
|
<input id="hidRefId1" name="hidRefId" type="hidden" value="" />
|
72305
|
-
<svg
|
72518
|
+
<svg style="width:16px;height:16px;"><use xlink:href="#icon-upload"></use></svg>
|
72306
72519
|
<input onclick="blur()" title="${util.out('Select')}" id="fileImage1" name="fileImage" type="file" accept="image/*" style="position:absolute;top:-30px;left:0;width:100%;height:80px;opacity: 0;cursor: pointer;">
|
72307
72520
|
</form>
|
72308
72521
|
|
@@ -72325,7 +72538,7 @@ class Image$1 {
|
|
72325
72538
|
<div class="image-larger2 is-btn classic" style="position:relative;flex:none;box-shadow: 0px 3px 6px -6px rgba(0, 0, 0, 0.32);">
|
72326
72539
|
<form class="form-upload-larger" target="frameTargetImageUpload" method="post" action="${this.builder.opts.fileHandler ? this.builder.opts.fileHandler : this.builder.opts.largerImageHandler}" enctype="multipart/form-data" style="border-radius:1px;position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;">
|
72327
72540
|
<input id="hidRefId2" name="hidRefId" type="hidden" value="" />
|
72328
|
-
<svg
|
72541
|
+
<svg style="width:16px;height:16px;"><use xlink:href="#icon-upload"></use></svg>
|
72329
72542
|
<input onclick="blur()" title="${util.out('Select')}" id="fileImage2" name="fileImage" type="file" accept="*" style="position:absolute;top:-30px;left:0;width:100%;height:80px;opacity: 0;cursor: pointer;">
|
72330
72543
|
</form>
|
72331
72544
|
</div>
|
@@ -72607,9 +72820,113 @@ class Image$1 {
|
|
72607
72820
|
|
72608
72821
|
// Apply (crop) image
|
72609
72822
|
elm = modalImageEdit.querySelector('.input-ok');
|
72610
|
-
dom.addEventListener(elm, 'click', () => {
|
72823
|
+
dom.addEventListener(elm, 'click', async () => {
|
72611
72824
|
this.builder.uo.saveForUndo();
|
72612
72825
|
let img = this.builder.activeImage;
|
72826
|
+
if (this.builder.opts.onImageUpload) {
|
72827
|
+
let basename, extension, newname, newfilename;
|
72828
|
+
let src = img.getAttribute('src');
|
72829
|
+
if (src.indexOf('base64') === -1) {
|
72830
|
+
let filename = src.substring(src.lastIndexOf('/') + 1);
|
72831
|
+
basename = dom.baseName(filename);
|
72832
|
+
extension = filename.substr(filename.lastIndexOf('.') + 1).toLowerCase();
|
72833
|
+
} else if (img.getAttribute('data-filename')) {
|
72834
|
+
let attr = img.getAttribute('data-filename');
|
72835
|
+
basename = dom.baseName(attr);
|
72836
|
+
extension = attr.substr(attr.lastIndexOf('.') + 1).toLowerCase();
|
72837
|
+
} else {
|
72838
|
+
basename = util.makeId();
|
72839
|
+
extension = 'png';
|
72840
|
+
const match = src.match(/^data:image\/(.*?);base64,/);
|
72841
|
+
if (match) {
|
72842
|
+
extension = match[1]; // e.g., "png", "jpeg", "gif"
|
72843
|
+
}
|
72844
|
+
}
|
72845
|
+
|
72846
|
+
if (basename.indexOf('-edit') !== -1) {
|
72847
|
+
basename = basename.substr(0, basename.indexOf('-edit'));
|
72848
|
+
}
|
72849
|
+
newname = basename + '-edit' + util.makeId();
|
72850
|
+
newname = newname.replaceAll('%20', '-'); // fix 404 error after file upload
|
72851
|
+
|
72852
|
+
newfilename = newname + '.' + extension;
|
72853
|
+
let base64;
|
72854
|
+
if (extension === 'jpg' || extension === 'jpeg' || extension === 'webm' || extension === 'webp') {
|
72855
|
+
base64 = this.cropper.getCroppedCanvas({
|
72856
|
+
fillColor: '#fff',
|
72857
|
+
imageSmoothingEnabled: true,
|
72858
|
+
imageSmoothingQuality: 'high'
|
72859
|
+
}).toDataURL('image/jpeg');
|
72860
|
+
} else {
|
72861
|
+
base64 = this.cropper.getCroppedCanvas({}).toDataURL();
|
72862
|
+
}
|
72863
|
+
|
72864
|
+
// await this.builder.opts.onBase64Upload(img, base64, newfilename);
|
72865
|
+
const getMimeTypeFromFilename = filename => {
|
72866
|
+
const ext = filename.split('.').pop().toLowerCase();
|
72867
|
+
const mimeTypes = {
|
72868
|
+
jpg: 'image/jpeg',
|
72869
|
+
jpeg: 'image/jpeg',
|
72870
|
+
png: 'image/png',
|
72871
|
+
gif: 'image/gif',
|
72872
|
+
webp: 'image/webp',
|
72873
|
+
svg: 'image/svg+xml',
|
72874
|
+
pdf: 'application/pdf',
|
72875
|
+
txt: 'text/plain',
|
72876
|
+
mp3: 'audio/mpeg',
|
72877
|
+
mp4: 'video/mp4',
|
72878
|
+
mov: 'video/quicktime',
|
72879
|
+
wav: 'audio/wav',
|
72880
|
+
json: 'application/json'
|
72881
|
+
// add more as needed
|
72882
|
+
};
|
72883
|
+
|
72884
|
+
return mimeTypes[ext] || 'application/octet-stream';
|
72885
|
+
};
|
72886
|
+
const base64ToFile = (base64, filename) => {
|
72887
|
+
const mimeType = getMimeTypeFromFilename(filename);
|
72888
|
+
const byteString = atob(base64.split(',')[1]);
|
72889
|
+
const byteArray = new Uint8Array(byteString.length);
|
72890
|
+
for (let i = 0; i < byteString.length; i++) {
|
72891
|
+
byteArray[i] = byteString.charCodeAt(i);
|
72892
|
+
}
|
72893
|
+
return new File([byteArray], filename, {
|
72894
|
+
type: mimeType
|
72895
|
+
});
|
72896
|
+
};
|
72897
|
+
const onUpload = file => {
|
72898
|
+
return new Promise(resolve => {
|
72899
|
+
this.builder.opts.onAssetUpload = url => {
|
72900
|
+
resolve({
|
72901
|
+
url: url,
|
72902
|
+
name: file.name,
|
72903
|
+
size: file.size
|
72904
|
+
});
|
72905
|
+
};
|
72906
|
+
const fakeEvent = {
|
72907
|
+
target: {
|
72908
|
+
files: [file]
|
72909
|
+
}
|
72910
|
+
};
|
72911
|
+
this.builder.opts.onImageUpload(fakeEvent);
|
72912
|
+
});
|
72913
|
+
};
|
72914
|
+
const file = base64ToFile(base64, newfilename);
|
72915
|
+
const result = await onUpload(file);
|
72916
|
+
img.setAttribute('src', result.url);
|
72917
|
+
|
72918
|
+
// finished steps:
|
72919
|
+
|
72920
|
+
//Check if image is part of module snippet. If so, refresh the (active) module (hide imageTool). If not, refresh imageTool position
|
72921
|
+
this.refreshIfIsModule(img);
|
72922
|
+
|
72923
|
+
//Trigger Change event
|
72924
|
+
this.builder.opts.onChange();
|
72925
|
+
util.hideModal(modalImageEdit);
|
72926
|
+
this.builder.elmTool.refresh();
|
72927
|
+
if (this.builder.onImageChange) this.builder.onImageChange();
|
72928
|
+
return;
|
72929
|
+
}
|
72613
72930
|
let attr = img.getAttribute('data-filename');
|
72614
72931
|
let extension = 'jpg';
|
72615
72932
|
if (attr) {
|
@@ -75360,7 +75677,7 @@ class Hyperlink {
|
|
75360
75677
|
<div class="div-anyfile-upload is-btn classic" style="position: relative; flex: 0 0 auto; width: 50px; height: 43px; box-shadow: rgba(0, 0, 0, 0.32) 0px 3px 6px -6px;">
|
75361
75678
|
<form class="form-upload-larger" target="frameTargetAnyfileUpload" method="post" action="${this.builder.opts.fileHandler}" enctype="multipart/form-data" style="overflow:hidden;position:absolute;top:0;left:0;width:100%;height:100%;border-radius:1px;display:flex;align-items: center;justify-content: center;">
|
75362
75679
|
<input class="input-anyfile-customval" name="hidRefId" type="hidden" value="${this.builder.customval}" />
|
75363
|
-
<svg
|
75680
|
+
<svg style="width:16px;height:16px;"><use xlink:href="#icon-upload"></use></svg>
|
75364
75681
|
<input type="file" onclick="blur()" tabindex="0" class="input-anyfile-upload" name="fileImage" accept="*" style="position:absolute;top:-30px;left:0;width:100%;height:80px;opacity: 0;cursor: pointer;"/>
|
75365
75682
|
</form>
|
75366
75683
|
<iframe tabindex="-1" id="frameTargetAnyfileUpload" name="frameTargetAnyfileUpload" src="about:blank" style="width:1px;height:1px;position:absolute;top:0;right:-100000px"></iframe>
|
@@ -76357,6 +76674,9 @@ class Module {
|
|
76357
76674
|
let result = await fetch(this.builder.opts.modulePath + modulename + '.html');
|
76358
76675
|
result = await result.text();
|
76359
76676
|
result = result.replace(/<script>/g, `${this.builder.nonce ? `<script nonce="${this.builder.nonce}">` : '<script>'}`);
|
76677
|
+
|
76678
|
+
// Replace assets path
|
76679
|
+
result = result.replace(/="assets\//g, '="' + this.builder.settings.assetPath);
|
76360
76680
|
iframe.srcdoc = result;
|
76361
76681
|
setTimeout(() => {
|
76362
76682
|
iframe.style.opacity = '';
|
@@ -77346,7 +77666,7 @@ class Video {
|
|
77346
77666
|
<div class="video-larger1 input-upload is-btn classic" style="position:relative;flex:none;box-shadow: 0px 3px 6px -6px rgba(0, 0, 0, 0.32);">
|
77347
77667
|
<form class="form-upload-larger" target="frameTargetVideoUpload" method="post" action="${this.builder.opts.videoHandler}" enctype="multipart/form-data" style="position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%;">
|
77348
77668
|
<input id="hidRefId5" name="hidRefId" type="hidden" value="" />
|
77349
|
-
<svg
|
77669
|
+
<svg style="width:16px;height:16px;"><use xlink:href="#icon-upload"></use></svg>
|
77350
77670
|
<input title="${util.out('Select')}" id="fileVideo1" name="fileImage" type="file" accept="video/mp4" style="position:absolute;top:-30px;left:0;width:100%;height:80px;opacity: 0;cursor: pointer;">
|
77351
77671
|
</form>
|
77352
77672
|
|
@@ -77579,7 +77899,7 @@ class Audio {
|
|
77579
77899
|
<div class="audio-file-upload input-upload is-btn classic" style="position:relative;flex:none;box-shadow: 0px 3px 6px -6px rgba(0, 0, 0, 0.32);">
|
77580
77900
|
<form class="form-upload-larger" target="frameTargetAudioUpload" method="post" action="${this.builder.opts.audioHandler}" enctype="multipart/form-data" style="position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%;">
|
77581
77901
|
<input id="hidRefAudio" name="hidRefId" type="hidden" value="" />
|
77582
|
-
<svg
|
77902
|
+
<svg style="width:16px;height:16px;"><use xlink:href="#icon-upload"></use></svg>
|
77583
77903
|
<input title="${util.out('Select')}" id="fileAudio1" name="fileImage" type="file" accept="audio/mp3" style="position:absolute;top:-30px;left:0;width:100%;height:80px;opacity: 0;cursor: pointer;">
|
77584
77904
|
</form>
|
77585
77905
|
|
@@ -79599,7 +79919,7 @@ class ColumnTool {
|
|
79599
79919
|
<div class="image-larger3 input-upload" style="position: relative; flex: 0 0 auto;box-shadow: rgba(0, 0, 0, 0.32) 0px 3px 6px -6px;">
|
79600
79920
|
<form class="form-upload-larger" target="frameTargetCellImageUpload" method="post" action="${this.builder.opts.largerImageHandler}" enctype="multipart/form-data" style="position:absolute;display:flex;justify-content: center;align-items: center;top:0;left:0;width:100%;height:100%;">
|
79601
79921
|
<input id="hidRefId3" name="hidRefId" type="hidden" value="">
|
79602
|
-
<svg
|
79922
|
+
<svg style="width:16px;height:16px;"><use xlink:href="#icon-upload"></use></svg>
|
79603
79923
|
<input onclick="blur()" title="${util.out('Select')}" id="fileImage3" name="fileImage" type="file" accept="image/*" style="position:absolute;top:-30px;left:0;width:100%;height:80px;opacity: 0;cursor: pointer;">
|
79604
79924
|
</form>
|
79605
79925
|
|
@@ -80455,7 +80775,9 @@ class ColumnTool {
|
|
80455
80775
|
<div class="image-larger4 is-btn classic" style="position: relative; flex: 0 0 auto; width: 40px; height: 38px; box-shadow: rgba(0, 0, 0, 0.32) 0px 3px 6px -6px;">
|
80456
80776
|
<form class="form-upload-larger" target="frameTargetLinkUpload" method="post" action="${this.builder.opts.largerImageHandler}" enctype="multipart/form-data" style="position:absolute;top:0;left:0;width:100%;height:100%;border-radius:1px;display:flex;align-items: center;justify-content: center;">
|
80457
80777
|
<input id="hidRefId4" name="hidRefId" type="hidden" value="">
|
80458
|
-
|
80778
|
+
|
80779
|
+
<svg style="width:16px;height:16px;"><use xlink:href="#icon-upload"></use></svg>
|
80780
|
+
|
80459
80781
|
<input onclick="blur()" title="${util.out('Select')}" id="fileImage4" name="fileImage" type="file" accept="image/*,video/mp4" style="position:absolute;top:-30px;left:0;width:100%;height:68px;opacity: 0;cursor: pointer;">
|
80460
80782
|
</form>
|
80461
80783
|
|
@@ -94378,7 +94700,7 @@ class Rte {
|
|
94378
94700
|
});
|
94379
94701
|
|
94380
94702
|
const btnInsertImageOk = modalInsertImage.querySelector('.input-ok');
|
94381
|
-
dom.addEventListener(btnInsertImageOk, 'click', () => {
|
94703
|
+
dom.addEventListener(btnInsertImageOk, 'click', async () => {
|
94382
94704
|
if (!this.builder.activeCol) {
|
94383
94705
|
util.hideModal(modalInsertImage);
|
94384
94706
|
return;
|
@@ -94394,7 +94716,76 @@ class Rte {
|
|
94394
94716
|
}
|
94395
94717
|
if (val === '') return;
|
94396
94718
|
let fileToInsert = modalInsertImage.querySelector('#imgInsertImagePreview').getAttribute('data-filename');
|
94397
|
-
|
94719
|
+
if (this.builder.opts.onImageUpload && val.indexOf('base64') !== -1) {
|
94720
|
+
let basename, extension, newname, newfilename;
|
94721
|
+
basename = dom.baseName(fileToInsert);
|
94722
|
+
extension = fileToInsert.substr(fileToInsert.lastIndexOf('.') + 1).toLowerCase();
|
94723
|
+
if (basename.indexOf('-edit') !== -1) {
|
94724
|
+
basename = basename.substr(0, basename.indexOf('-edit'));
|
94725
|
+
}
|
94726
|
+
newname = basename + '-edit' + util.makeId();
|
94727
|
+
newname = newname.replaceAll('%20', '-'); // fix 404 error after file upload
|
94728
|
+
|
94729
|
+
newfilename = newname + '.' + extension;
|
94730
|
+
let base64 = val;
|
94731
|
+
|
94732
|
+
// await this.builder.opts.onBase64Upload(img, base64, newfilename);
|
94733
|
+
const getMimeTypeFromFilename = filename => {
|
94734
|
+
const ext = filename.split('.').pop().toLowerCase();
|
94735
|
+
const mimeTypes = {
|
94736
|
+
jpg: 'image/jpeg',
|
94737
|
+
jpeg: 'image/jpeg',
|
94738
|
+
png: 'image/png',
|
94739
|
+
gif: 'image/gif',
|
94740
|
+
webp: 'image/webp',
|
94741
|
+
svg: 'image/svg+xml',
|
94742
|
+
pdf: 'application/pdf',
|
94743
|
+
txt: 'text/plain',
|
94744
|
+
mp3: 'audio/mpeg',
|
94745
|
+
mp4: 'video/mp4',
|
94746
|
+
mov: 'video/quicktime',
|
94747
|
+
wav: 'audio/wav',
|
94748
|
+
json: 'application/json'
|
94749
|
+
// add more as needed
|
94750
|
+
};
|
94751
|
+
|
94752
|
+
return mimeTypes[ext] || 'application/octet-stream';
|
94753
|
+
};
|
94754
|
+
const base64ToFile = (base64, filename) => {
|
94755
|
+
const mimeType = getMimeTypeFromFilename(filename);
|
94756
|
+
const byteString = atob(base64.split(',')[1]);
|
94757
|
+
const byteArray = new Uint8Array(byteString.length);
|
94758
|
+
for (let i = 0; i < byteString.length; i++) {
|
94759
|
+
byteArray[i] = byteString.charCodeAt(i);
|
94760
|
+
}
|
94761
|
+
return new File([byteArray], filename, {
|
94762
|
+
type: mimeType
|
94763
|
+
});
|
94764
|
+
};
|
94765
|
+
const onUpload = file => {
|
94766
|
+
return new Promise(resolve => {
|
94767
|
+
this.builder.opts.onAssetUpload = url => {
|
94768
|
+
resolve({
|
94769
|
+
url: url,
|
94770
|
+
name: file.name,
|
94771
|
+
size: file.size
|
94772
|
+
});
|
94773
|
+
};
|
94774
|
+
const fakeEvent = {
|
94775
|
+
target: {
|
94776
|
+
files: [file]
|
94777
|
+
}
|
94778
|
+
};
|
94779
|
+
this.builder.opts.onImageUpload(fakeEvent);
|
94780
|
+
});
|
94781
|
+
};
|
94782
|
+
const file = base64ToFile(base64, newfilename);
|
94783
|
+
const result = await onUpload(file);
|
94784
|
+
val = result.url;
|
94785
|
+
}
|
94786
|
+
|
94787
|
+
// util.pasteHtmlAtCaret('<img data-filename="' + fileToInsert + '" src="' + val + '" alt="" />', false);
|
94788
|
+
util.pasteHtmlAtCaret('<img src="' + val + '" alt="" />', false);
|
94398
94789
|
util.hideModal(modalInsertImage);
|
94399
94790
|
let builderActive = this.builder.doc.querySelector('.builder-active');
|
94400
94791
|
if (builderActive) this.builder.applyBehaviorOn(builderActive);
|
@@ -100793,7 +101184,7 @@ class SaveImages {
|
|
100793
101184
|
const images = area.querySelectorAll('img');
|
100794
101185
|
Array.prototype.forEach.call(images, img => {
|
100795
101186
|
let src = img.getAttribute('src');
|
100796
|
-
if (typeof src !== typeof undefined && src !== false) {
|
101187
|
+
if (typeof src !== typeof undefined && src !== false && img.getAttribute('data-filename')) {
|
100797
101188
|
if (src.indexOf('base64') !== -1) {
|
100798
101189
|
// let customcode = false;
|
100799
101190
|
// if(dom.parentsHasAttribute(img, 'data-html')){
|
@@ -106506,7 +106897,7 @@ class MediaPicker {
|
|
106506
106897
|
<div class="input-upload" style="position: relative; flex: 0 0 auto;box-shadow: rgba(0, 0, 0, 0.32) 0px 3px 6px -6px;">
|
106507
106898
|
<form class="form-upload-larger" target="frameTarget${this.id}" method="post" action="${this.builder.opts.largerImageHandler}" enctype="multipart/form-data" style="position:absolute;display:flex;justify-content: center;align-items: center;top:0;left:0;width:100%;height:100%;">
|
106508
106899
|
<input name="hidRefId" class="input-ref-id" type="hidden" value="">
|
106509
|
-
<svg
|
106900
|
+
<svg style="width:16px;height:16px;"><use xlink:href="#icon-upload"></use></svg>
|
106510
106901
|
<input title="${util.out('Select')}" name="fileImage" class="input-file-select" type="file" accept="image/*,video/mp4" style="position:absolute;top:-30px;left:0;width:100%;height:80px;opacity: 0;cursor: pointer;">
|
106511
106902
|
</form>
|
106512
106903
|
<iframe tabIndex="0" id="frameTarget${this.id}" name="frameTarget${this.id}" src="about:blank" style="width:1px;height:1px;position:absolute;top:0;right:-100000px"></iframe>
|
@@ -109466,6 +109857,9 @@ class Dictation {
|
|
109466
109857
|
this.modalConfig = modalConfig;
|
109467
109858
|
const btnConfig = builderStuff.querySelector('.cmd-command-config');
|
109468
109859
|
const btnDictation = builderStuff.querySelector('.cmd-enable-dictation');
|
109860
|
+
if (!this.builder.settings.enableDictation) {
|
109861
|
+
btnDictation.style.display = 'none';
|
109862
|
+
}
|
109469
109863
|
const btnClear = builderStuff.querySelector('.cmd-clear-command');
|
109470
109864
|
const chkAutoSend = builderStuff.querySelector('#chkAutoSendCommand');
|
109471
109865
|
const btnCommandList = builderStuff.querySelector('.cmd-command-list');
|
@@ -118475,7 +118869,7 @@ class ContentBuilder {
|
|
118475
118869
|
// Option for self-hosted fonts:
|
118476
118870
|
// fontPath: 'assets/cssfonts/', // If set, will be used
|
118477
118871
|
|
118478
|
-
snippetModal:
|
118872
|
+
snippetModal: true,
|
118479
118873
|
snippetModalLeft: false,
|
118480
118874
|
snippetData: 'assets/minimalist-blocks/snippetlist.html',
|
118481
118875
|
// Deprecated
|
@@ -118755,7 +119149,7 @@ class ContentBuilder {
|
|
118755
119149
|
maxEmbedImageWidth: 1600,
|
118756
119150
|
//set -1 for no max (use original image width)
|
118757
119151
|
zoom: 1,
|
118758
|
-
useLightbox:
|
119152
|
+
useLightbox: true,
|
118759
119153
|
lightboxArrow: true,
|
118760
119154
|
imageRenameOnEdit: true,
|
118761
119155
|
disableAutoEmbedVideo: false,
|
@@ -119144,6 +119538,7 @@ class ContentBuilder {
|
|
119144
119538
|
sendCommandUrl: '',
|
119145
119539
|
// http://localhost:8081/answer
|
119146
119540
|
// speechTranscribeUrl: 'http://192.168.1.7:8081',
|
119541
|
+
enableDictation: false,
|
119147
119542
|
onlineDemo: false,
|
119148
119543
|
autoSendDelay: 4000,
|
119149
119544
|
autoEditBlock: false,
|
@@ -119549,6 +119944,10 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
|
|
119549
119944
|
}
|
119550
119945
|
this.settings = this.opts; // Backward compatible
|
119551
119946
|
|
119947
|
+
if (this.isContentBox) {
|
119948
|
+
this.settings.snippetModal = false;
|
119949
|
+
}
|
119950
|
+
|
119552
119951
|
// freeform
|
119553
119952
|
if (this.canvas && !this.isContentBox) {
|
119554
119953
|
/*
|
@@ -121281,6 +121680,15 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
|
|
121281
121680
|
applyBehaviorOn(builder) {
|
121282
121681
|
const util = this.util;
|
121283
121682
|
|
121683
|
+
// upload
|
121684
|
+
if (this.opts.onImageUpload) {
|
121685
|
+
if (!builder._dragDropUploaderAttached) {
|
121686
|
+
builder._dragDropUploaderAttached = true;
|
121687
|
+
const uploader = new DragDropImageUploader(builder, this);
|
121688
|
+
uploader.attach();
|
121689
|
+
}
|
121690
|
+
}
|
121691
|
+
|
121284
121692
|
//Make absolute
|
121285
121693
|
if (this.opts.absolutePath) {
|
121286
121694
|
let links = builder.querySelectorAll('a');
|
@@ -156153,8 +156561,26 @@ class ContentBox {
|
|
156153
156561
|
designPathReplace: ['assets/', 'https://.../assets/'], // Only if needed
|
156154
156562
|
*/
|
156155
156563
|
// New Template System: => this will replace the previous approach (designUrl1, designUrl2, designPath, designPathReplace & defaultDesignCategory)
|
156156
|
-
templates: [],
|
156157
|
-
|
156564
|
+
// templates: [], // ver.5.3
|
156565
|
+
templates: [{
|
156566
|
+
url: 'assets/templates-simple/templates.js',
|
156567
|
+
path: 'assets/templates-simple/',
|
156568
|
+
pathReplace: [],
|
156569
|
+
numbering: true,
|
156570
|
+
showNumberOnHover: true
|
156571
|
+
}, {
|
156572
|
+
url: 'assets/templates-quick/templates.js',
|
156573
|
+
path: 'assets/templates-quick/',
|
156574
|
+
pathReplace: [],
|
156575
|
+
numbering: true,
|
156576
|
+
showNumberOnHover: true
|
156577
|
+
}, {
|
156578
|
+
url: 'assets/templates-animated/templates.js',
|
156579
|
+
path: 'assets/templates-animated/',
|
156580
|
+
pathReplace: [],
|
156581
|
+
numbering: true,
|
156582
|
+
showNumberOnHover: true
|
156583
|
+
}],
|
156158
156584
|
|
156159
156585
|
/*
|
156160
156586
|
Example:
|
@@ -156348,7 +156774,7 @@ class ContentBox {
|
|
156348
156774
|
blockCodeEditorHeight: '45vh',
|
156349
156775
|
blockCodeEditorMaxWidth: '960px',
|
156350
156776
|
assetRefresh: false,
|
156351
|
-
slider: '',
|
156777
|
+
slider: 'glide',
|
156352
156778
|
navbar: false,
|
156353
156779
|
screenMode: 'fullview',
|
156354
156780
|
onRender: function () {},
|
@@ -160232,6 +160658,10 @@ Add an image for each feature.`, 'Create a new block showcasing a photo gallery
|
|
160232
160658
|
z-index: 2;
|
160233
160659
|
}
|
160234
160660
|
|
160661
|
+
.is-wrapper .drag-over-image {
|
160662
|
+
outline: #a2f0ce 3px solid;
|
160663
|
+
}
|
160664
|
+
|
160235
160665
|
/*
|
160236
160666
|
.is-wrapper.is-edit {
|
160237
160667
|
min-height: 100vh;
|