@innovastudio/contentbuilder 1.5.163 → 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.163",
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', '');
@@ -14489,6 +14498,7 @@ class HtmlUtil {
14489
14498
  // Re-init plugins
14490
14499
  if (this.builder.win.builderRuntime) await this.builder.win.builderRuntime.reinitialize();
14491
14500
  this.builder.hideModal(modal);
14501
+ this.builder.makeSortable(this.builder.doc);
14492
14502
  }
14493
14503
  viewHtmlExternal() {
14494
14504
  const util = this.builder.util;
@@ -15061,6 +15071,25 @@ class HtmlUtil {
15061
15071
  element.classList.remove(`cb-${type}`);
15062
15072
  }
15063
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
+ });
15064
15093
  });
15065
15094
  html = '';
15066
15095
  if (multiple) {
@@ -16193,6 +16222,9 @@ class Grid {
16193
16222
  this.builder.hideTools();
16194
16223
  cell.parentElement.insertBefore(cell, cell.previousElementSibling);
16195
16224
  this.builder.opts.onChange(true);
16225
+
16226
+ // Re-init plugins
16227
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(cell);
16196
16228
  }
16197
16229
  }
16198
16230
  moveColumnNext() {
@@ -16205,6 +16237,9 @@ class Grid {
16205
16237
  this.builder.hideTools();
16206
16238
  cell.parentElement.insertBefore(cellnext, cell);
16207
16239
  this.builder.opts.onChange(true);
16240
+
16241
+ // Re-init plugins
16242
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(cell);
16208
16243
  }
16209
16244
  }
16210
16245
  moveColumnUp() {
@@ -16234,6 +16269,9 @@ class Grid {
16234
16269
  //Move row up
16235
16270
  row.parentNode.insertBefore(row, row.previousElementSibling);
16236
16271
  this.builder.opts.onChange(true);
16272
+
16273
+ // Re-init plugins
16274
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
16237
16275
  return;
16238
16276
  } else {
16239
16277
  this.builder.uo.saveForUndo();
@@ -16284,6 +16322,9 @@ class Grid {
16284
16322
  row = cell.parentNode; //update active row
16285
16323
  util.fixLayout(row);
16286
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);
16287
16328
  }
16288
16329
  moveColumnDown() {
16289
16330
  let builder = this.builder;
@@ -16314,6 +16355,9 @@ class Grid {
16314
16355
  //Move row down
16315
16356
  row.parentNode.insertBefore(row.nextElementSibling, row);
16316
16357
  this.builder.opts.onChange(true);
16358
+
16359
+ // Re-init plugins
16360
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
16317
16361
  return;
16318
16362
  } else {
16319
16363
  this.builder.uo.saveForUndo();
@@ -16364,6 +16408,9 @@ class Grid {
16364
16408
  row = cell.parentNode; //update active row
16365
16409
  util.fixLayout(row);
16366
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);
16367
16414
  }
16368
16415
  duplicateColumn() {
16369
16416
  let builder = this.builder;
@@ -17067,6 +17114,9 @@ class Grid {
17067
17114
  row.parentNode.insertBefore(row, row.previousElementSibling);
17068
17115
  this.rowTool.position(row);
17069
17116
  this.builder.opts.onChange();
17117
+
17118
+ // Re-init plugins
17119
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
17070
17120
  } else {
17071
17121
  // Move to previous container
17072
17122
 
@@ -17111,6 +17161,9 @@ class Grid {
17111
17161
  row.parentNode.insertBefore(row.nextElementSibling, row);
17112
17162
  this.rowTool.position(row);
17113
17163
  this.builder.opts.onChange();
17164
+
17165
+ // Re-init plugins
17166
+ if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(row);
17114
17167
  } else {
17115
17168
  // Move to next container
17116
17169
 
@@ -96014,6 +96067,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
96014
96067
  }
96015
96068
  });
96016
96069
  });
96070
+ this.makeSortable(this.doc);
96017
96071
  }
96018
96072
 
96019
96073
  // Load plugins
@@ -97991,6 +98045,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
97991
98045
  });
97992
98046
  });
97993
98047
  });
98048
+ this.makeSortable(this.doc);
97994
98049
  this.doc.querySelectorAll('.dummy-module').forEach(module => {
97995
98050
  module.classList.remove('dummy-module');
97996
98051
  });
@@ -99778,24 +99833,7 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
99778
99833
  });
99779
99834
 
99780
99835
  // On Load HTML
99781
- const grids = this.doc.querySelectorAll('.grid-sortable');
99782
- grids.forEach(grid => {
99783
- if (grid.closest('.is-builder')) new Sortable(grid, {
99784
- animation: 600,
99785
- dragClass: 'hide-drag-class',
99786
- onStart: () => {
99787
- this.uo.saveForUndo(true);
99788
- },
99789
- onSort: () => {
99790
- if (grid.closest('[data-html]')) {
99791
- const moduleElm = grid.closest('[data-html]');
99792
- const encodedHtml = encodeURIComponent(moduleElm.innerHTML);
99793
- moduleElm.setAttribute('data-html', encodedHtml);
99794
- this.opts.onChange();
99795
- }
99796
- }
99797
- });
99798
- });
99836
+ this.makeSortable(this.doc, true);
99799
99837
  this.refresh();
99800
99838
  if (this.win.Block) {
99801
99839
  this.win.Block.render();
@@ -99835,24 +99873,7 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
99835
99873
  this.applyBehavior();
99836
99874
 
99837
99875
  // On Load HTML
99838
- const grids = this.doc.querySelectorAll('.grid-sortable');
99839
- grids.forEach(grid => {
99840
- if (grid.closest('.is-builder')) new Sortable(grid, {
99841
- animation: 600,
99842
- dragClass: 'hide-drag-class',
99843
- onStart: () => {
99844
- this.uo.saveForUndo(true);
99845
- },
99846
- onSort: () => {
99847
- if (grid.closest('[data-html]')) {
99848
- const moduleElm = grid.closest('[data-html]');
99849
- const encodedHtml = encodeURIComponent(moduleElm.innerHTML);
99850
- moduleElm.setAttribute('data-html', encodedHtml);
99851
- this.opts.onChange();
99852
- }
99853
- }
99854
- });
99855
- });
99876
+ this.makeSortable(this.doc, true);
99856
99877
 
99857
99878
  // this.uo.saveForUndo(); //First time
99858
99879
 
@@ -102451,6 +102472,86 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
102451
102472
  // this.doc.querySelectorAll('.elm-inspected').forEach(elm => elm.classList.remove('elm-inspected'));
102452
102473
  // this.doc.querySelectorAll('.elm-active').forEach(elm => elm.classList.remove('elm-active'));
102453
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
+ }
102454
102555
  }
102455
102556
 
102456
102557
  export { ContentBuilder as default };