@innovastudio/contentbox 1.6.164 → 1.6.166
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@innovastudio/contentbox",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.6.
|
|
4
|
+
"version": "1.6.166",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "public/contentbox/contentbox.esm.js",
|
|
7
7
|
"types": "index.d.ts",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"ws": "^8.13.0"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@innovastudio/contentbuilder": "^1.5.
|
|
62
|
+
"@innovastudio/contentbuilder": "^1.5.164",
|
|
63
63
|
"js-beautify": "^1.14.0",
|
|
64
64
|
"sortablejs": "^1.15.2"
|
|
65
65
|
}
|
|
@@ -12326,7 +12326,7 @@ class SettingsUIGenerator$1 {
|
|
|
12326
12326
|
const plugin = this.runtime.getPlugin(pluginName);
|
|
12327
12327
|
|
|
12328
12328
|
if (!plugin || !plugin.settings) {
|
|
12329
|
-
console.warn(`Plugin "${pluginName}" has no settings schema`);
|
|
12329
|
+
// console.warn(`Plugin "${pluginName}" has no settings schema`);
|
|
12330
12330
|
return this.createEmptyForm();
|
|
12331
12331
|
}
|
|
12332
12332
|
|
|
@@ -12625,6 +12625,45 @@ class SettingsUIGenerator$1 {
|
|
|
12625
12625
|
return label;
|
|
12626
12626
|
}
|
|
12627
12627
|
|
|
12628
|
+
hexToRgba(color) {
|
|
12629
|
+
// If it's already rgba() or rgb(), just return as-is
|
|
12630
|
+
if (/^rgba?\(/i.test(color)) {
|
|
12631
|
+
return color;
|
|
12632
|
+
} // Otherwise assume hex
|
|
12633
|
+
|
|
12634
|
+
|
|
12635
|
+
color = color.replace(/^#/, ''); // Expand shorthand hex (#rgb or #rgba)
|
|
12636
|
+
|
|
12637
|
+
if (color.length === 3 || color.length === 4) {
|
|
12638
|
+
color = color.split('').map(ch => ch + ch).join('');
|
|
12639
|
+
} // Parse r, g, b, a
|
|
12640
|
+
|
|
12641
|
+
|
|
12642
|
+
const r = parseInt(color.substring(0, 2), 16);
|
|
12643
|
+
const g = parseInt(color.substring(2, 4), 16);
|
|
12644
|
+
const b = parseInt(color.substring(4, 6), 16);
|
|
12645
|
+
const a = color.length === 8 ? parseInt(color.substring(6, 8), 16) / 255 : 1;
|
|
12646
|
+
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
12647
|
+
}
|
|
12648
|
+
|
|
12649
|
+
toHex(colorStr) {
|
|
12650
|
+
const ctx = document.createElement('canvas').getContext('2d');
|
|
12651
|
+
ctx.fillStyle = colorStr;
|
|
12652
|
+
const computed = ctx.fillStyle; // browser-normalized color
|
|
12653
|
+
// If already hex and 7 or 9 chars long (#rrggbb or #rrggbbaa), return as-is
|
|
12654
|
+
|
|
12655
|
+
if (computed.startsWith('#')) return computed; // Parse rgba(...) or rgb(...)
|
|
12656
|
+
|
|
12657
|
+
const rgba = computed.match(/\d+(\.\d+)?/g).map(Number);
|
|
12658
|
+
const [r, g, b, a = 1] = rgba; // default alpha = 1
|
|
12659
|
+
// Convert RGB and Alpha to hex (2 digits each)
|
|
12660
|
+
|
|
12661
|
+
const rgbHex = [r, g, b].map(v => v.toString(16).padStart(2, '0')).join('');
|
|
12662
|
+
const alphaHex = Math.round(a * 255).toString(16).padStart(2, '0'); // Only include alpha if it's not fully opaque
|
|
12663
|
+
|
|
12664
|
+
return a < 1 ? `#${rgbHex}${alphaHex}` : `#${rgbHex}`;
|
|
12665
|
+
}
|
|
12666
|
+
|
|
12628
12667
|
createColorInput(name, config, value) {
|
|
12629
12668
|
const container = document.createElement('div');
|
|
12630
12669
|
const label = document.createElement('label');
|
|
@@ -12645,13 +12684,15 @@ class SettingsUIGenerator$1 {
|
|
|
12645
12684
|
colorBtn.type = 'button';
|
|
12646
12685
|
colorBtn.title = config.label || 'Color';
|
|
12647
12686
|
colorBtn.className = 'btn-color is-btn-color';
|
|
12648
|
-
colorBtn.style.backgroundColor = input.value;
|
|
12687
|
+
colorBtn.style.backgroundColor = this.hexToRgba(input.value);
|
|
12649
12688
|
colorBtn.setAttribute('aria-label', `Choose color for ${config.label || name}`);
|
|
12650
12689
|
|
|
12651
12690
|
const openPicker = e => {
|
|
12652
12691
|
e.preventDefault();
|
|
12653
12692
|
this.builder.openColorPicker(input.value, color => {
|
|
12654
|
-
input.value = color;
|
|
12693
|
+
// input.value = color;
|
|
12694
|
+
const hex = this.toHex(color);
|
|
12695
|
+
input.value = hex;
|
|
12655
12696
|
colorBtn.style.backgroundColor = color;
|
|
12656
12697
|
input.dispatchEvent(new Event('change', {
|
|
12657
12698
|
bubbles: true
|
|
@@ -12717,10 +12758,10 @@ class SettingsUIGenerator$1 {
|
|
|
12717
12758
|
input.type = 'range';
|
|
12718
12759
|
input.className = 'is-rangeslider';
|
|
12719
12760
|
input.name = name;
|
|
12720
|
-
input.value = currentVal;
|
|
12721
12761
|
if (config.min !== undefined) input.min = config.min;
|
|
12722
12762
|
if (config.max !== undefined) input.max = config.max;
|
|
12723
12763
|
if (config.step !== undefined) input.step = config.step;
|
|
12764
|
+
input.value = currentVal;
|
|
12724
12765
|
input.addEventListener('input', () => {
|
|
12725
12766
|
labelText.textContent = (config.label || name) + ': ' + input.value + (config.unit || '');
|
|
12726
12767
|
});
|
|
@@ -12853,7 +12894,23 @@ class PanelPlugin {
|
|
|
12853
12894
|
const originalElement = editableClone.cloneNode(false); // Let plugin handle everything - pass the editable clone
|
|
12854
12895
|
|
|
12855
12896
|
const editorUI = plugin.editor.openContentEditor(editableClone, this.builder, async () => {
|
|
12856
|
-
this.builder.editor.saveForUndo(); //
|
|
12897
|
+
this.builder.editor.saveForUndo(); // Add index for sortable grid (for easy reorder)
|
|
12898
|
+
|
|
12899
|
+
let grid = editableClone.querySelector('.grid-sortable');
|
|
12900
|
+
|
|
12901
|
+
if (!grid) {
|
|
12902
|
+
if (currentElement.classList.contains('grid-sortable')) {
|
|
12903
|
+
grid = editableClone;
|
|
12904
|
+
}
|
|
12905
|
+
}
|
|
12906
|
+
|
|
12907
|
+
if (grid) {
|
|
12908
|
+
Array.from(grid.children).forEach((child, index) => {
|
|
12909
|
+
if (child.nodeType === 1 && child.tagName !== 'STYLE' && child.tagName !== 'SCRIPT') child.setAttribute('data-index', index);
|
|
12910
|
+
});
|
|
12911
|
+
} //----
|
|
12912
|
+
// Store edited content from clone
|
|
12913
|
+
|
|
12857
12914
|
|
|
12858
12915
|
currentElement.setAttribute('data-cb-original-content', editableClone.innerHTML); // Also performs similar value updates like the applyChanges()
|
|
12859
12916
|
// currentElement.setAttribute('data-cb-content', editableClone.getAttribute('data-cb-content'));
|
|
@@ -12884,6 +12941,8 @@ class PanelPlugin {
|
|
|
12884
12941
|
|
|
12885
12942
|
await runtime.reinitialize(currentElement.parentElement);
|
|
12886
12943
|
this.builder.onChange();
|
|
12944
|
+
this.builder.editor.hideElementTools();
|
|
12945
|
+
this.builder.makeSortable(currentElement.parentElement);
|
|
12887
12946
|
});
|
|
12888
12947
|
div.appendChild(editorUI);
|
|
12889
12948
|
} // Generate form
|
|
@@ -12906,6 +12965,8 @@ class PanelPlugin {
|
|
|
12906
12965
|
const container = this.currentElement.parentElement || this.currentElement.closest('.is-wrapper');
|
|
12907
12966
|
await runtime.reinitialize(container);
|
|
12908
12967
|
this.builder.onChange(); // console.log('Settings applied and component reinitialized');
|
|
12968
|
+
|
|
12969
|
+
this.builder.makeSortable(container);
|
|
12909
12970
|
}
|
|
12910
12971
|
|
|
12911
12972
|
}
|
|
@@ -26934,6 +26995,7 @@ class ControlPanel {
|
|
|
26934
26995
|
}
|
|
26935
26996
|
|
|
26936
26997
|
const plugin = runtime.getPlugin(pluginName);
|
|
26998
|
+
if (!plugin) return;
|
|
26937
26999
|
let titleHtml = out(plugin.displayName || plugin.name);
|
|
26938
27000
|
this.title.innerHTML = titleHtml; // this.title.style.cssText = 'margin-bottom: 0';
|
|
26939
27001
|
|
|
@@ -32643,18 +32705,21 @@ class Util$1 {
|
|
|
32643
32705
|
let builderActive = this.builder.doc.querySelector('.builder-active');
|
|
32644
32706
|
if (builderActive) this.builder.applyBehaviorOn(builderActive);
|
|
32645
32707
|
this.fixLayout(row);
|
|
32646
|
-
|
|
32647
|
-
|
|
32648
|
-
|
|
32649
|
-
|
|
32708
|
+
try {
|
|
32709
|
+
// cellElement.click(); //change active block to the newly created
|
|
32710
|
+
if (element && element.tagName.toLowerCase() === 'img') {
|
|
32711
|
+
element.onload = () => {
|
|
32712
|
+
element.click();
|
|
32713
|
+
element.onload = null;
|
|
32714
|
+
setTimeout(() => {
|
|
32715
|
+
this.builder.element.image.repositionImageTool();
|
|
32716
|
+
}, 100);
|
|
32717
|
+
};
|
|
32718
|
+
} else if (element) {
|
|
32650
32719
|
element.click();
|
|
32651
|
-
|
|
32652
|
-
|
|
32653
|
-
|
|
32654
|
-
}, 100);
|
|
32655
|
-
};
|
|
32656
|
-
} else if (element) {
|
|
32657
|
-
element.click();
|
|
32720
|
+
}
|
|
32721
|
+
} catch (e) {
|
|
32722
|
+
// Do Nothing
|
|
32658
32723
|
}
|
|
32659
32724
|
}
|
|
32660
32725
|
if (mode === 'row') {
|
|
@@ -32772,6 +32837,10 @@ class Util$1 {
|
|
|
32772
32837
|
|
|
32773
32838
|
//Trigger Render event
|
|
32774
32839
|
this.builder.opts.onRender();
|
|
32840
|
+
|
|
32841
|
+
// Reinit after drag drop block
|
|
32842
|
+
if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize();
|
|
32843
|
+
this.builder.makeSortable(this.builder.doc);
|
|
32775
32844
|
}
|
|
32776
32845
|
|
|
32777
32846
|
// https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro
|
|
@@ -32864,6 +32933,7 @@ class Util$1 {
|
|
|
32864
32933
|
|
|
32865
32934
|
//Hide Column tool (new!)
|
|
32866
32935
|
this.builder.util.hideColumnTool();
|
|
32936
|
+
this.builder.makeSortable(rowElement);
|
|
32867
32937
|
} else if (bSnippet) {
|
|
32868
32938
|
if (noedit) {
|
|
32869
32939
|
this.addContent(html, mode, 'data-noedit');
|
|
@@ -33037,6 +33107,7 @@ class Util$1 {
|
|
|
33037
33107
|
this.builder.doc.querySelectorAll('.dummy-module').forEach(module => {
|
|
33038
33108
|
module.classList.remove('dummy-module');
|
|
33039
33109
|
});
|
|
33110
|
+
this.builder.makeSortable(this.builder.doc);
|
|
33040
33111
|
|
|
33041
33112
|
// Change to row selection
|
|
33042
33113
|
rowElement.className = rowElement.className.replace('row-outline', '');
|
|
@@ -33054,6 +33125,9 @@ class Util$1 {
|
|
|
33054
33125
|
|
|
33055
33126
|
//Trigger Render event
|
|
33056
33127
|
this.builder.opts.onRender();
|
|
33128
|
+
|
|
33129
|
+
// Reinit after drag drop block
|
|
33130
|
+
if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize();
|
|
33057
33131
|
}
|
|
33058
33132
|
clearActiveCell() {
|
|
33059
33133
|
// this.builder.lastActiveCol = this.cellSelected(); // get active cell before cleared (will be used by snippets dialog)
|
|
@@ -41660,6 +41734,7 @@ class HtmlUtil {
|
|
|
41660
41734
|
// Re-init plugins
|
|
41661
41735
|
if (this.builder.win.builderRuntime) await this.builder.win.builderRuntime.reinitialize();
|
|
41662
41736
|
this.builder.hideModal(modal);
|
|
41737
|
+
this.builder.makeSortable(this.builder.doc);
|
|
41663
41738
|
}
|
|
41664
41739
|
viewHtmlExternal() {
|
|
41665
41740
|
const util = this.builder.util;
|
|
@@ -42232,6 +42307,25 @@ class HtmlUtil {
|
|
|
42232
42307
|
element.classList.remove(`cb-${type}`);
|
|
42233
42308
|
}
|
|
42234
42309
|
element.removeAttribute('data-cb-loaded');
|
|
42310
|
+
let grid;
|
|
42311
|
+
if (element.classList.contains('grid-sortable')) {
|
|
42312
|
+
grid = element;
|
|
42313
|
+
}
|
|
42314
|
+
if (element.querySelector('.grid-sortable')) {
|
|
42315
|
+
grid = element.querySelector('.grid-sortable');
|
|
42316
|
+
}
|
|
42317
|
+
element.removeAttribute('id');
|
|
42318
|
+
if (grid) {
|
|
42319
|
+
Array.from(grid.children).forEach(elm => {
|
|
42320
|
+
elm.removeAttribute('data-index');
|
|
42321
|
+
elm.removeAttribute('data-item-id');
|
|
42322
|
+
});
|
|
42323
|
+
}
|
|
42324
|
+
const elms = element.querySelectorAll('[data-scroll], [data-scroll-once]');
|
|
42325
|
+
elms.forEach(elm => {
|
|
42326
|
+
elm.removeAttribute('data-scroll');
|
|
42327
|
+
elm.removeAttribute('data-scroll-once');
|
|
42328
|
+
});
|
|
42235
42329
|
});
|
|
42236
42330
|
html = '';
|
|
42237
42331
|
if (multiple) {
|
|
@@ -43364,6 +43458,9 @@ class Grid {
|
|
|
43364
43458
|
this.builder.hideTools();
|
|
43365
43459
|
cell.parentElement.insertBefore(cell, cell.previousElementSibling);
|
|
43366
43460
|
this.builder.opts.onChange(true);
|
|
43461
|
+
|
|
43462
|
+
// Re-init plugins
|
|
43463
|
+
if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(cell);
|
|
43367
43464
|
}
|
|
43368
43465
|
}
|
|
43369
43466
|
moveColumnNext() {
|
|
@@ -43376,6 +43473,9 @@ class Grid {
|
|
|
43376
43473
|
this.builder.hideTools();
|
|
43377
43474
|
cell.parentElement.insertBefore(cellnext, cell);
|
|
43378
43475
|
this.builder.opts.onChange(true);
|
|
43476
|
+
|
|
43477
|
+
// Re-init plugins
|
|
43478
|
+
if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(cell);
|
|
43379
43479
|
}
|
|
43380
43480
|
}
|
|
43381
43481
|
moveColumnUp() {
|
|
@@ -43405,6 +43505,9 @@ class Grid {
|
|
|
43405
43505
|
//Move row up
|
|
43406
43506
|
row.parentNode.insertBefore(row, row.previousElementSibling);
|
|
43407
43507
|
this.builder.opts.onChange(true);
|
|
43508
|
+
|
|
43509
|
+
// Re-init plugins
|
|
43510
|
+
if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
|
|
43408
43511
|
return;
|
|
43409
43512
|
} else {
|
|
43410
43513
|
this.builder.uo.saveForUndo();
|
|
@@ -43455,6 +43558,9 @@ class Grid {
|
|
|
43455
43558
|
row = cell.parentNode; //update active row
|
|
43456
43559
|
util.fixLayout(row);
|
|
43457
43560
|
if (row.nextElementSibling) util.fixLayout(row.nextElementSibling);
|
|
43561
|
+
|
|
43562
|
+
// Re-init plugins
|
|
43563
|
+
if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
|
|
43458
43564
|
}
|
|
43459
43565
|
moveColumnDown() {
|
|
43460
43566
|
let builder = this.builder;
|
|
@@ -43485,6 +43591,9 @@ class Grid {
|
|
|
43485
43591
|
//Move row down
|
|
43486
43592
|
row.parentNode.insertBefore(row.nextElementSibling, row);
|
|
43487
43593
|
this.builder.opts.onChange(true);
|
|
43594
|
+
|
|
43595
|
+
// Re-init plugins
|
|
43596
|
+
if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
|
|
43488
43597
|
return;
|
|
43489
43598
|
} else {
|
|
43490
43599
|
this.builder.uo.saveForUndo();
|
|
@@ -43535,6 +43644,9 @@ class Grid {
|
|
|
43535
43644
|
row = cell.parentNode; //update active row
|
|
43536
43645
|
util.fixLayout(row);
|
|
43537
43646
|
if (row.previousElementSibling) util.fixLayout(row.previousElementSibling);
|
|
43647
|
+
|
|
43648
|
+
// Re-init plugins
|
|
43649
|
+
if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
|
|
43538
43650
|
}
|
|
43539
43651
|
duplicateColumn() {
|
|
43540
43652
|
let builder = this.builder;
|
|
@@ -44238,6 +44350,9 @@ class Grid {
|
|
|
44238
44350
|
row.parentNode.insertBefore(row, row.previousElementSibling);
|
|
44239
44351
|
this.rowTool.position(row);
|
|
44240
44352
|
this.builder.opts.onChange();
|
|
44353
|
+
|
|
44354
|
+
// Re-init plugins
|
|
44355
|
+
if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
|
|
44241
44356
|
} else {
|
|
44242
44357
|
// Move to previous container
|
|
44243
44358
|
|
|
@@ -44282,6 +44397,9 @@ class Grid {
|
|
|
44282
44397
|
row.parentNode.insertBefore(row.nextElementSibling, row);
|
|
44283
44398
|
this.rowTool.position(row);
|
|
44284
44399
|
this.builder.opts.onChange();
|
|
44400
|
+
|
|
44401
|
+
// Re-init plugins
|
|
44402
|
+
if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
|
|
44285
44403
|
} else {
|
|
44286
44404
|
// Move to next container
|
|
44287
44405
|
|
|
@@ -123185,6 +123303,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
|
|
|
123185
123303
|
}
|
|
123186
123304
|
});
|
|
123187
123305
|
});
|
|
123306
|
+
this.makeSortable(this.doc);
|
|
123188
123307
|
}
|
|
123189
123308
|
|
|
123190
123309
|
// Load plugins
|
|
@@ -125053,6 +125172,9 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
|
|
|
125053
125172
|
|
|
125054
125173
|
// After snippet has been added, re-apply behavior on builder areas
|
|
125055
125174
|
this.applyBehaviorOn(builder);
|
|
125175
|
+
|
|
125176
|
+
// Reinit after drag drop block
|
|
125177
|
+
if (this.win.builderRuntime) this.win.builderRuntime.reinitialize(builder);
|
|
125056
125178
|
if (newRows.length > 0) {
|
|
125057
125179
|
let newRow = newRows[0]; // get first added row
|
|
125058
125180
|
if (newRow.children.length > 0) {
|
|
@@ -125125,8 +125247,9 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
|
|
|
125125
125247
|
this.setZoomOnControl(builder);
|
|
125126
125248
|
|
|
125127
125249
|
// Re-init plugins
|
|
125128
|
-
if
|
|
125250
|
+
// if(this.win.builderRuntime) this.win.builderRuntime.reinitialize(builder);
|
|
125129
125251
|
}
|
|
125252
|
+
|
|
125130
125253
|
applySortableGrid() {
|
|
125131
125254
|
if (this.iframe) {
|
|
125132
125255
|
const oldCss = this.contentStuff.querySelector('#css-scale');
|
|
@@ -125158,6 +125281,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
|
|
|
125158
125281
|
});
|
|
125159
125282
|
});
|
|
125160
125283
|
});
|
|
125284
|
+
this.makeSortable(this.doc);
|
|
125161
125285
|
this.doc.querySelectorAll('.dummy-module').forEach(module => {
|
|
125162
125286
|
module.classList.remove('dummy-module');
|
|
125163
125287
|
});
|
|
@@ -126945,24 +127069,7 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
|
|
|
126945
127069
|
});
|
|
126946
127070
|
|
|
126947
127071
|
// On Load HTML
|
|
126948
|
-
|
|
126949
|
-
grids.forEach(grid => {
|
|
126950
|
-
if (grid.closest('.is-builder')) new Sortable$1(grid, {
|
|
126951
|
-
animation: 600,
|
|
126952
|
-
dragClass: 'hide-drag-class',
|
|
126953
|
-
onStart: () => {
|
|
126954
|
-
this.uo.saveForUndo(true);
|
|
126955
|
-
},
|
|
126956
|
-
onSort: () => {
|
|
126957
|
-
if (grid.closest('[data-html]')) {
|
|
126958
|
-
const moduleElm = grid.closest('[data-html]');
|
|
126959
|
-
const encodedHtml = encodeURIComponent(moduleElm.innerHTML);
|
|
126960
|
-
moduleElm.setAttribute('data-html', encodedHtml);
|
|
126961
|
-
this.opts.onChange();
|
|
126962
|
-
}
|
|
126963
|
-
}
|
|
126964
|
-
});
|
|
126965
|
-
});
|
|
127072
|
+
this.makeSortable(this.doc, true);
|
|
126966
127073
|
this.refresh();
|
|
126967
127074
|
if (this.win.Block) {
|
|
126968
127075
|
this.win.Block.render();
|
|
@@ -127002,24 +127109,7 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
|
|
|
127002
127109
|
this.applyBehavior();
|
|
127003
127110
|
|
|
127004
127111
|
// On Load HTML
|
|
127005
|
-
|
|
127006
|
-
grids.forEach(grid => {
|
|
127007
|
-
if (grid.closest('.is-builder')) new Sortable$1(grid, {
|
|
127008
|
-
animation: 600,
|
|
127009
|
-
dragClass: 'hide-drag-class',
|
|
127010
|
-
onStart: () => {
|
|
127011
|
-
this.uo.saveForUndo(true);
|
|
127012
|
-
},
|
|
127013
|
-
onSort: () => {
|
|
127014
|
-
if (grid.closest('[data-html]')) {
|
|
127015
|
-
const moduleElm = grid.closest('[data-html]');
|
|
127016
|
-
const encodedHtml = encodeURIComponent(moduleElm.innerHTML);
|
|
127017
|
-
moduleElm.setAttribute('data-html', encodedHtml);
|
|
127018
|
-
this.opts.onChange();
|
|
127019
|
-
}
|
|
127020
|
-
}
|
|
127021
|
-
});
|
|
127022
|
-
});
|
|
127112
|
+
this.makeSortable(this.doc, true);
|
|
127023
127113
|
|
|
127024
127114
|
// this.uo.saveForUndo(); //First time
|
|
127025
127115
|
|
|
@@ -129538,6 +129628,9 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
|
|
|
129538
129628
|
|
|
129539
129629
|
// // Hide element tool
|
|
129540
129630
|
// this.elmTool.hide();
|
|
129631
|
+
|
|
129632
|
+
// Reinit after drag drop block
|
|
129633
|
+
if (this.win.builderRuntime) this.win.builderRuntime.reinitialize();
|
|
129541
129634
|
}
|
|
129542
129635
|
|
|
129543
129636
|
// this.sortableOnPage.option('draggable', '.dummy');
|
|
@@ -129615,6 +129708,86 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
|
|
|
129615
129708
|
// this.doc.querySelectorAll('.elm-inspected').forEach(elm => elm.classList.remove('elm-inspected'));
|
|
129616
129709
|
// this.doc.querySelectorAll('.elm-active').forEach(elm => elm.classList.remove('elm-active'));
|
|
129617
129710
|
}
|
|
129711
|
+
|
|
129712
|
+
// Make list inside plugin element sortable
|
|
129713
|
+
makeSortable(container, module) {
|
|
129714
|
+
const grids = container.querySelectorAll('.grid-sortable');
|
|
129715
|
+
grids.forEach(grid => {
|
|
129716
|
+
const sortable = new Sortable$1(grid, {
|
|
129717
|
+
animation: 600,
|
|
129718
|
+
onStart: () => {
|
|
129719
|
+
this.uo.saveForUndo(true);
|
|
129720
|
+
},
|
|
129721
|
+
onSort: async () => {
|
|
129722
|
+
if (module) if (grid.closest('[data-html]')) {
|
|
129723
|
+
const moduleElm = grid.closest('[data-html]');
|
|
129724
|
+
const encodedHtml = encodeURIComponent(moduleElm.innerHTML);
|
|
129725
|
+
moduleElm.setAttribute('data-html', encodedHtml);
|
|
129726
|
+
this.onChange();
|
|
129727
|
+
}
|
|
129728
|
+
let plugin = grid.closest('[data-cb-original-content]');
|
|
129729
|
+
if (plugin) {
|
|
129730
|
+
// grid.setAttribute('data-cb-original-content', plugin.innerHTML); // don't do this!
|
|
129731
|
+
this.updateCleanContentOrder(grid); // use this!
|
|
129732
|
+
|
|
129733
|
+
this.onChange();
|
|
129734
|
+
grid.click();
|
|
129735
|
+
}
|
|
129736
|
+
}
|
|
129737
|
+
});
|
|
129738
|
+
// Store instance for later access
|
|
129739
|
+
grid._sortable = sortable;
|
|
129740
|
+
});
|
|
129741
|
+
}
|
|
129742
|
+
async updateCleanContentOrder(grid) {
|
|
129743
|
+
if (!grid) return;
|
|
129744
|
+
const plugin = grid.closest('[data-cb-original-content]');
|
|
129745
|
+
if (!plugin) return;
|
|
129746
|
+
|
|
129747
|
+
// 1. Get the current visual order of data-index from the actual DOM
|
|
129748
|
+
const newIndexOrder = Array.from(grid.children).map(child => child.dataset.index).filter(index => index !== undefined); // in case some lack data-index
|
|
129749
|
+
|
|
129750
|
+
// 2. Parse the *original clean* HTML
|
|
129751
|
+
const cleanHtml = plugin.dataset.cbOriginalContent;
|
|
129752
|
+
const parser = new DOMParser();
|
|
129753
|
+
const doc = parser.parseFromString(cleanHtml, 'text/html');
|
|
129754
|
+
let cleanGrid = doc.querySelector('.grid-sortable');
|
|
129755
|
+
let pluginIsSortableRoot = false;
|
|
129756
|
+
if (!cleanGrid) {
|
|
129757
|
+
// console.log('[step] .grid-sortable not found inside parsed clean HTML — creating wrapper from body children');
|
|
129758
|
+
cleanGrid = doc.createElement('div');
|
|
129759
|
+
cleanGrid.classList.add('grid-sortable');
|
|
129760
|
+
Array.from(doc.body.children).forEach(child => {
|
|
129761
|
+
if (child.nodeType === 1) cleanGrid.appendChild(child);
|
|
129762
|
+
});
|
|
129763
|
+
doc.body.innerHTML = '';
|
|
129764
|
+
doc.body.appendChild(cleanGrid);
|
|
129765
|
+
pluginIsSortableRoot = true;
|
|
129766
|
+
}
|
|
129767
|
+
const cleanItems = Array.from(cleanGrid.children).filter(el => el.nodeType === 1);
|
|
129768
|
+
|
|
129769
|
+
// 3. Build a map: data-index → clean node
|
|
129770
|
+
const cleanItemMap = new Map();
|
|
129771
|
+
cleanItems.forEach(item => {
|
|
129772
|
+
const idx = item.dataset.index;
|
|
129773
|
+
if (idx !== undefined) cleanItemMap.set(idx, item);
|
|
129774
|
+
});
|
|
129775
|
+
|
|
129776
|
+
// 4. Reorder clean items to match newIndexOrder
|
|
129777
|
+
const reorderedCleanItems = newIndexOrder.map(idx => cleanItemMap.get(idx)).filter(Boolean); // skip missing
|
|
129778
|
+
|
|
129779
|
+
// 5. Serialize back to HTML string
|
|
129780
|
+
const newCleanHtml = reorderedCleanItems.map(item => item.outerHTML).join('');
|
|
129781
|
+
|
|
129782
|
+
// 6. Update the clean source
|
|
129783
|
+
if (pluginIsSortableRoot) {
|
|
129784
|
+
plugin.setAttribute('data-cb-original-content', newCleanHtml);
|
|
129785
|
+
} else {
|
|
129786
|
+
cleanGrid.innerHTML = newCleanHtml;
|
|
129787
|
+
const newHTML = doc.body.innerHTML;
|
|
129788
|
+
plugin.setAttribute('data-cb-original-content', newHTML);
|
|
129789
|
+
}
|
|
129790
|
+
}
|
|
129618
129791
|
}
|
|
129619
129792
|
|
|
129620
129793
|
class ContentStuff {
|
|
@@ -165276,23 +165449,7 @@ Add an image for each feature.`, 'Create a new block showcasing a photo gallery
|
|
|
165276
165449
|
activeModule.appendChild(range.createContextualFragment(html)); // We use createContextualFragment so that embedded javascript code (code block) will be executed
|
|
165277
165450
|
|
|
165278
165451
|
this.settings.onRender();
|
|
165279
|
-
|
|
165280
|
-
grids.forEach(grid => {
|
|
165281
|
-
new Sortable(grid, {
|
|
165282
|
-
animation: 600,
|
|
165283
|
-
onStart: () => {
|
|
165284
|
-
this.editor.saveForUndo(true);
|
|
165285
|
-
},
|
|
165286
|
-
onSort: () => {
|
|
165287
|
-
if (grid.closest('[data-html]')) {
|
|
165288
|
-
const moduleElm = grid.closest('[data-html]');
|
|
165289
|
-
const encodedHtml = encodeURIComponent(moduleElm.innerHTML);
|
|
165290
|
-
moduleElm.setAttribute('data-html', encodedHtml);
|
|
165291
|
-
this.onChange();
|
|
165292
|
-
}
|
|
165293
|
-
}
|
|
165294
|
-
});
|
|
165295
|
-
});
|
|
165452
|
+
this.makeSortable(activeModule);
|
|
165296
165453
|
this.settings.onChange();
|
|
165297
165454
|
this.hideModal(modalEditModule);
|
|
165298
165455
|
});
|
|
@@ -166359,27 +166516,89 @@ Add an image for each feature.`, 'Create a new block showcasing a photo gallery
|
|
|
166359
166516
|
const typePanel = document.querySelector('#divSidebarTypography');
|
|
166360
166517
|
if (typePanel.classList.contains('active')) this.sidebar.selectType();
|
|
166361
166518
|
});
|
|
166362
|
-
|
|
166363
|
-
|
|
166519
|
+
this.makeSortable(box, true);
|
|
166520
|
+
} // boxSetup
|
|
166521
|
+
// Make list inside plugin element sortable
|
|
166522
|
+
|
|
166364
166523
|
|
|
166524
|
+
makeSortable(container, module) {
|
|
166525
|
+
const grids = container.querySelectorAll('.grid-sortable');
|
|
166365
166526
|
grids.forEach(grid => {
|
|
166366
|
-
new Sortable(grid, {
|
|
166527
|
+
const sortable = new Sortable(grid, {
|
|
166367
166528
|
animation: 600,
|
|
166368
166529
|
onStart: () => {
|
|
166369
166530
|
this.editor.saveForUndo(true);
|
|
166370
166531
|
},
|
|
166371
|
-
onSort: () => {
|
|
166372
|
-
if (grid.closest('[data-html]')) {
|
|
166532
|
+
onSort: async () => {
|
|
166533
|
+
if (module) if (grid.closest('[data-html]')) {
|
|
166373
166534
|
const moduleElm = grid.closest('[data-html]');
|
|
166374
166535
|
const encodedHtml = encodeURIComponent(moduleElm.innerHTML);
|
|
166375
166536
|
moduleElm.setAttribute('data-html', encodedHtml);
|
|
166376
166537
|
this.onChange();
|
|
166377
166538
|
}
|
|
166539
|
+
let plugin = grid.closest('[data-cb-original-content]');
|
|
166540
|
+
|
|
166541
|
+
if (plugin) {
|
|
166542
|
+
// grid.setAttribute('data-cb-original-content', plugin.innerHTML); // don't do this!
|
|
166543
|
+
this.updateCleanContentOrder(grid); // use this!
|
|
166544
|
+
|
|
166545
|
+
this.onChange();
|
|
166546
|
+
grid.click();
|
|
166547
|
+
}
|
|
166378
166548
|
}
|
|
166379
|
-
});
|
|
166549
|
+
}); // Store instance for later access
|
|
166550
|
+
|
|
166551
|
+
grid._sortable = sortable;
|
|
166380
166552
|
});
|
|
166381
|
-
}
|
|
166553
|
+
}
|
|
166554
|
+
|
|
166555
|
+
async updateCleanContentOrder(grid) {
|
|
166556
|
+
if (!grid) return;
|
|
166557
|
+
const plugin = grid.closest('[data-cb-original-content]');
|
|
166558
|
+
if (!plugin) return; // 1. Get the current visual order of data-index from the actual DOM
|
|
166559
|
+
|
|
166560
|
+
const newIndexOrder = Array.from(grid.children).map(child => child.dataset.index).filter(index => index !== undefined); // in case some lack data-index
|
|
166561
|
+
// 2. Parse the *original clean* HTML
|
|
166562
|
+
|
|
166563
|
+
const cleanHtml = plugin.dataset.cbOriginalContent;
|
|
166564
|
+
const parser = new DOMParser();
|
|
166565
|
+
const doc = parser.parseFromString(cleanHtml, 'text/html');
|
|
166566
|
+
let cleanGrid = doc.querySelector('.grid-sortable');
|
|
166567
|
+
let pluginIsSortableRoot = false;
|
|
166382
166568
|
|
|
166569
|
+
if (!cleanGrid) {
|
|
166570
|
+
// console.log('[step] .grid-sortable not found inside parsed clean HTML — creating wrapper from body children');
|
|
166571
|
+
cleanGrid = doc.createElement('div');
|
|
166572
|
+
cleanGrid.classList.add('grid-sortable');
|
|
166573
|
+
Array.from(doc.body.children).forEach(child => {
|
|
166574
|
+
if (child.nodeType === 1) cleanGrid.appendChild(child);
|
|
166575
|
+
});
|
|
166576
|
+
doc.body.innerHTML = '';
|
|
166577
|
+
doc.body.appendChild(cleanGrid);
|
|
166578
|
+
pluginIsSortableRoot = true;
|
|
166579
|
+
}
|
|
166580
|
+
|
|
166581
|
+
const cleanItems = Array.from(cleanGrid.children).filter(el => el.nodeType === 1); // 3. Build a map: data-index → clean node
|
|
166582
|
+
|
|
166583
|
+
const cleanItemMap = new Map();
|
|
166584
|
+
cleanItems.forEach(item => {
|
|
166585
|
+
const idx = item.dataset.index;
|
|
166586
|
+
if (idx !== undefined) cleanItemMap.set(idx, item);
|
|
166587
|
+
}); // 4. Reorder clean items to match newIndexOrder
|
|
166588
|
+
|
|
166589
|
+
const reorderedCleanItems = newIndexOrder.map(idx => cleanItemMap.get(idx)).filter(Boolean); // skip missing
|
|
166590
|
+
// 5. Serialize back to HTML string
|
|
166591
|
+
|
|
166592
|
+
const newCleanHtml = reorderedCleanItems.map(item => item.outerHTML).join(''); // 6. Update the clean source
|
|
166593
|
+
|
|
166594
|
+
if (pluginIsSortableRoot) {
|
|
166595
|
+
plugin.setAttribute('data-cb-original-content', newCleanHtml);
|
|
166596
|
+
} else {
|
|
166597
|
+
cleanGrid.innerHTML = newCleanHtml;
|
|
166598
|
+
const newHTML = doc.body.innerHTML;
|
|
166599
|
+
plugin.setAttribute('data-cb-original-content', newHTML);
|
|
166600
|
+
}
|
|
166601
|
+
}
|
|
166383
166602
|
|
|
166384
166603
|
addSection(html, contentCss) {
|
|
166385
166604
|
let newSection = this.addIdea(html);
|