@innovastudio/contentbuilder 1.5.162 → 1.5.164

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/contentbuilder",
3
3
  "type": "module",
4
- "version": "1.5.162",
4
+ "version": "1.5.164",
5
5
  "description": "",
6
6
  "main": "public/contentbuilder/contentbuilder.esm.js",
7
7
  "types": "index.d.ts",
@@ -5469,18 +5469,21 @@ class Util {
5469
5469
  let builderActive = this.builder.doc.querySelector('.builder-active');
5470
5470
  if (builderActive) this.builder.applyBehaviorOn(builderActive);
5471
5471
  this.fixLayout(row);
5472
-
5473
- // cellElement.click(); //change active block to the newly created
5474
- if (element && element.tagName.toLowerCase() === 'img') {
5475
- element.onload = () => {
5472
+ try {
5473
+ // cellElement.click(); //change active block to the newly created
5474
+ if (element && element.tagName.toLowerCase() === 'img') {
5475
+ element.onload = () => {
5476
+ element.click();
5477
+ element.onload = null;
5478
+ setTimeout(() => {
5479
+ this.builder.element.image.repositionImageTool();
5480
+ }, 100);
5481
+ };
5482
+ } else if (element) {
5476
5483
  element.click();
5477
- element.onload = null;
5478
- setTimeout(() => {
5479
- this.builder.element.image.repositionImageTool();
5480
- }, 100);
5481
- };
5482
- } else if (element) {
5483
- element.click();
5484
+ }
5485
+ } catch (e) {
5486
+ // Do Nothing
5484
5487
  }
5485
5488
  }
5486
5489
  if (mode === 'row') {
@@ -5598,6 +5601,10 @@ class Util {
5598
5601
 
5599
5602
  //Trigger Render event
5600
5603
  this.builder.opts.onRender();
5604
+
5605
+ // Reinit after drag drop block
5606
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize();
5607
+ this.builder.makeSortable(this.builder.doc);
5601
5608
  }
5602
5609
 
5603
5610
  // https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro
@@ -5690,6 +5697,7 @@ class Util {
5690
5697
 
5691
5698
  //Hide Column tool (new!)
5692
5699
  this.builder.util.hideColumnTool();
5700
+ this.builder.makeSortable(rowElement);
5693
5701
  } else if (bSnippet) {
5694
5702
  if (noedit) {
5695
5703
  this.addContent(html, mode, 'data-noedit');
@@ -5863,6 +5871,7 @@ class Util {
5863
5871
  this.builder.doc.querySelectorAll('.dummy-module').forEach(module => {
5864
5872
  module.classList.remove('dummy-module');
5865
5873
  });
5874
+ this.builder.makeSortable(this.builder.doc);
5866
5875
 
5867
5876
  // Change to row selection
5868
5877
  rowElement.className = rowElement.className.replace('row-outline', '');
@@ -5880,6 +5889,9 @@ class Util {
5880
5889
 
5881
5890
  //Trigger Render event
5882
5891
  this.builder.opts.onRender();
5892
+
5893
+ // Reinit after drag drop block
5894
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize();
5883
5895
  }
5884
5896
  clearActiveCell() {
5885
5897
  // this.builder.lastActiveCol = this.cellSelected(); // get active cell before cleared (will be used by snippets dialog)
@@ -14486,6 +14498,7 @@ class HtmlUtil {
14486
14498
  // Re-init plugins
14487
14499
  if (this.builder.win.builderRuntime) await this.builder.win.builderRuntime.reinitialize();
14488
14500
  this.builder.hideModal(modal);
14501
+ this.builder.makeSortable(this.builder.doc);
14489
14502
  }
14490
14503
  viewHtmlExternal() {
14491
14504
  const util = this.builder.util;
@@ -15058,6 +15071,25 @@ class HtmlUtil {
15058
15071
  element.classList.remove(`cb-${type}`);
15059
15072
  }
15060
15073
  element.removeAttribute('data-cb-loaded');
15074
+ let grid;
15075
+ if (element.classList.contains('grid-sortable')) {
15076
+ grid = element;
15077
+ }
15078
+ if (element.querySelector('.grid-sortable')) {
15079
+ grid = element.querySelector('.grid-sortable');
15080
+ }
15081
+ element.removeAttribute('id');
15082
+ if (grid) {
15083
+ Array.from(grid.children).forEach(elm => {
15084
+ elm.removeAttribute('data-index');
15085
+ elm.removeAttribute('data-item-id');
15086
+ });
15087
+ }
15088
+ const elms = element.querySelectorAll('[data-scroll], [data-scroll-once]');
15089
+ elms.forEach(elm => {
15090
+ elm.removeAttribute('data-scroll');
15091
+ elm.removeAttribute('data-scroll-once');
15092
+ });
15061
15093
  });
15062
15094
  html = '';
15063
15095
  if (multiple) {
@@ -16190,6 +16222,9 @@ class Grid {
16190
16222
  this.builder.hideTools();
16191
16223
  cell.parentElement.insertBefore(cell, cell.previousElementSibling);
16192
16224
  this.builder.opts.onChange(true);
16225
+
16226
+ // Re-init plugins
16227
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(cell);
16193
16228
  }
16194
16229
  }
16195
16230
  moveColumnNext() {
@@ -16202,6 +16237,9 @@ class Grid {
16202
16237
  this.builder.hideTools();
16203
16238
  cell.parentElement.insertBefore(cellnext, cell);
16204
16239
  this.builder.opts.onChange(true);
16240
+
16241
+ // Re-init plugins
16242
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(cell);
16205
16243
  }
16206
16244
  }
16207
16245
  moveColumnUp() {
@@ -16231,6 +16269,9 @@ class Grid {
16231
16269
  //Move row up
16232
16270
  row.parentNode.insertBefore(row, row.previousElementSibling);
16233
16271
  this.builder.opts.onChange(true);
16272
+
16273
+ // Re-init plugins
16274
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
16234
16275
  return;
16235
16276
  } else {
16236
16277
  this.builder.uo.saveForUndo();
@@ -16281,6 +16322,9 @@ class Grid {
16281
16322
  row = cell.parentNode; //update active row
16282
16323
  util.fixLayout(row);
16283
16324
  if (row.nextElementSibling) util.fixLayout(row.nextElementSibling);
16325
+
16326
+ // Re-init plugins
16327
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
16284
16328
  }
16285
16329
  moveColumnDown() {
16286
16330
  let builder = this.builder;
@@ -16311,6 +16355,9 @@ class Grid {
16311
16355
  //Move row down
16312
16356
  row.parentNode.insertBefore(row.nextElementSibling, row);
16313
16357
  this.builder.opts.onChange(true);
16358
+
16359
+ // Re-init plugins
16360
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
16314
16361
  return;
16315
16362
  } else {
16316
16363
  this.builder.uo.saveForUndo();
@@ -16361,6 +16408,9 @@ class Grid {
16361
16408
  row = cell.parentNode; //update active row
16362
16409
  util.fixLayout(row);
16363
16410
  if (row.previousElementSibling) util.fixLayout(row.previousElementSibling);
16411
+
16412
+ // Re-init plugins
16413
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
16364
16414
  }
16365
16415
  duplicateColumn() {
16366
16416
  let builder = this.builder;
@@ -17064,6 +17114,9 @@ class Grid {
17064
17114
  row.parentNode.insertBefore(row, row.previousElementSibling);
17065
17115
  this.rowTool.position(row);
17066
17116
  this.builder.opts.onChange();
17117
+
17118
+ // Re-init plugins
17119
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
17067
17120
  } else {
17068
17121
  // Move to previous container
17069
17122
 
@@ -17108,6 +17161,9 @@ class Grid {
17108
17161
  row.parentNode.insertBefore(row.nextElementSibling, row);
17109
17162
  this.rowTool.position(row);
17110
17163
  this.builder.opts.onChange();
17164
+
17165
+ // Re-init plugins
17166
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
17111
17167
  } else {
17112
17168
  // Move to next container
17113
17169
 
@@ -96011,6 +96067,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
96011
96067
  }
96012
96068
  });
96013
96069
  });
96070
+ this.makeSortable(this.doc);
96014
96071
  }
96015
96072
 
96016
96073
  // Load plugins
@@ -97879,6 +97936,9 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
97879
97936
 
97880
97937
  // After snippet has been added, re-apply behavior on builder areas
97881
97938
  this.applyBehaviorOn(builder);
97939
+
97940
+ // Reinit after drag drop block
97941
+ if (this.win.builderRuntime) this.win.builderRuntime.reinitialize(builder);
97882
97942
  if (newRows.length > 0) {
97883
97943
  let newRow = newRows[0]; // get first added row
97884
97944
  if (newRow.children.length > 0) {
@@ -97951,8 +98011,9 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
97951
98011
  this.setZoomOnControl(builder);
97952
98012
 
97953
98013
  // Re-init plugins
97954
- if (this.win.builderRuntime) this.win.builderRuntime.reinitialize(builder);
98014
+ // if(this.win.builderRuntime) this.win.builderRuntime.reinitialize(builder);
97955
98015
  }
98016
+
97956
98017
  applySortableGrid() {
97957
98018
  if (this.iframe) {
97958
98019
  const oldCss = this.contentStuff.querySelector('#css-scale');
@@ -97984,6 +98045,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
97984
98045
  });
97985
98046
  });
97986
98047
  });
98048
+ this.makeSortable(this.doc);
97987
98049
  this.doc.querySelectorAll('.dummy-module').forEach(module => {
97988
98050
  module.classList.remove('dummy-module');
97989
98051
  });
@@ -99771,24 +99833,7 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
99771
99833
  });
99772
99834
 
99773
99835
  // On Load HTML
99774
- const grids = this.doc.querySelectorAll('.grid-sortable');
99775
- grids.forEach(grid => {
99776
- if (grid.closest('.is-builder')) new Sortable(grid, {
99777
- animation: 600,
99778
- dragClass: 'hide-drag-class',
99779
- onStart: () => {
99780
- this.uo.saveForUndo(true);
99781
- },
99782
- onSort: () => {
99783
- if (grid.closest('[data-html]')) {
99784
- const moduleElm = grid.closest('[data-html]');
99785
- const encodedHtml = encodeURIComponent(moduleElm.innerHTML);
99786
- moduleElm.setAttribute('data-html', encodedHtml);
99787
- this.opts.onChange();
99788
- }
99789
- }
99790
- });
99791
- });
99836
+ this.makeSortable(this.doc, true);
99792
99837
  this.refresh();
99793
99838
  if (this.win.Block) {
99794
99839
  this.win.Block.render();
@@ -99828,24 +99873,7 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
99828
99873
  this.applyBehavior();
99829
99874
 
99830
99875
  // On Load HTML
99831
- const grids = this.doc.querySelectorAll('.grid-sortable');
99832
- grids.forEach(grid => {
99833
- if (grid.closest('.is-builder')) new Sortable(grid, {
99834
- animation: 600,
99835
- dragClass: 'hide-drag-class',
99836
- onStart: () => {
99837
- this.uo.saveForUndo(true);
99838
- },
99839
- onSort: () => {
99840
- if (grid.closest('[data-html]')) {
99841
- const moduleElm = grid.closest('[data-html]');
99842
- const encodedHtml = encodeURIComponent(moduleElm.innerHTML);
99843
- moduleElm.setAttribute('data-html', encodedHtml);
99844
- this.opts.onChange();
99845
- }
99846
- }
99847
- });
99848
- });
99876
+ this.makeSortable(this.doc, true);
99849
99877
 
99850
99878
  // this.uo.saveForUndo(); //First time
99851
99879
 
@@ -102364,6 +102392,9 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
102364
102392
 
102365
102393
  // // Hide element tool
102366
102394
  // this.elmTool.hide();
102395
+
102396
+ // Reinit after drag drop block
102397
+ if (this.win.builderRuntime) this.win.builderRuntime.reinitialize();
102367
102398
  }
102368
102399
 
102369
102400
  // this.sortableOnPage.option('draggable', '.dummy');
@@ -102441,6 +102472,86 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
102441
102472
  // this.doc.querySelectorAll('.elm-inspected').forEach(elm => elm.classList.remove('elm-inspected'));
102442
102473
  // this.doc.querySelectorAll('.elm-active').forEach(elm => elm.classList.remove('elm-active'));
102443
102474
  }
102475
+
102476
+ // Make list inside plugin element sortable
102477
+ makeSortable(container, module) {
102478
+ const grids = container.querySelectorAll('.grid-sortable');
102479
+ grids.forEach(grid => {
102480
+ const sortable = new Sortable(grid, {
102481
+ animation: 600,
102482
+ onStart: () => {
102483
+ this.uo.saveForUndo(true);
102484
+ },
102485
+ onSort: async () => {
102486
+ if (module) if (grid.closest('[data-html]')) {
102487
+ const moduleElm = grid.closest('[data-html]');
102488
+ const encodedHtml = encodeURIComponent(moduleElm.innerHTML);
102489
+ moduleElm.setAttribute('data-html', encodedHtml);
102490
+ this.onChange();
102491
+ }
102492
+ let plugin = grid.closest('[data-cb-original-content]');
102493
+ if (plugin) {
102494
+ // grid.setAttribute('data-cb-original-content', plugin.innerHTML); // don't do this!
102495
+ this.updateCleanContentOrder(grid); // use this!
102496
+
102497
+ this.onChange();
102498
+ grid.click();
102499
+ }
102500
+ }
102501
+ });
102502
+ // Store instance for later access
102503
+ grid._sortable = sortable;
102504
+ });
102505
+ }
102506
+ async updateCleanContentOrder(grid) {
102507
+ if (!grid) return;
102508
+ const plugin = grid.closest('[data-cb-original-content]');
102509
+ if (!plugin) return;
102510
+
102511
+ // 1. Get the current visual order of data-index from the actual DOM
102512
+ const newIndexOrder = Array.from(grid.children).map(child => child.dataset.index).filter(index => index !== undefined); // in case some lack data-index
102513
+
102514
+ // 2. Parse the *original clean* HTML
102515
+ const cleanHtml = plugin.dataset.cbOriginalContent;
102516
+ const parser = new DOMParser();
102517
+ const doc = parser.parseFromString(cleanHtml, 'text/html');
102518
+ let cleanGrid = doc.querySelector('.grid-sortable');
102519
+ let pluginIsSortableRoot = false;
102520
+ if (!cleanGrid) {
102521
+ // console.log('[step] .grid-sortable not found inside parsed clean HTML — creating wrapper from body children');
102522
+ cleanGrid = doc.createElement('div');
102523
+ cleanGrid.classList.add('grid-sortable');
102524
+ Array.from(doc.body.children).forEach(child => {
102525
+ if (child.nodeType === 1) cleanGrid.appendChild(child);
102526
+ });
102527
+ doc.body.innerHTML = '';
102528
+ doc.body.appendChild(cleanGrid);
102529
+ pluginIsSortableRoot = true;
102530
+ }
102531
+ const cleanItems = Array.from(cleanGrid.children).filter(el => el.nodeType === 1);
102532
+
102533
+ // 3. Build a map: data-index → clean node
102534
+ const cleanItemMap = new Map();
102535
+ cleanItems.forEach(item => {
102536
+ const idx = item.dataset.index;
102537
+ if (idx !== undefined) cleanItemMap.set(idx, item);
102538
+ });
102539
+
102540
+ // 4. Reorder clean items to match newIndexOrder
102541
+ const reorderedCleanItems = newIndexOrder.map(idx => cleanItemMap.get(idx)).filter(Boolean); // skip missing
102542
+
102543
+ // 5. Serialize back to HTML string
102544
+ const newCleanHtml = reorderedCleanItems.map(item => item.outerHTML).join('');
102545
+
102546
+ // 6. Update the clean source
102547
+ if (pluginIsSortableRoot) {
102548
+ plugin.setAttribute('data-cb-original-content', newCleanHtml);
102549
+ } else {
102550
+ cleanGrid.innerHTML = newCleanHtml;
102551
+ const newHTML = doc.body.innerHTML;
102552
+ plugin.setAttribute('data-cb-original-content', newHTML);
102553
+ }
102554
+ }
102444
102555
  }
102445
102556
 
102446
102557
  export { ContentBuilder as default };