@innovastudio/contentbox 1.6.166 → 1.6.167

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.166",
4
+ "version": "1.6.167",
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.164",
62
+ "@innovastudio/contentbuilder": "^1.5.165",
63
63
  "js-beautify": "^1.14.0",
64
64
  "sortablejs": "^1.15.2"
65
65
  }
@@ -12381,7 +12381,7 @@ class SettingsUIGenerator$1 {
12381
12381
  groupElement.className = 'cb-settings-group';
12382
12382
  const groupTitle = document.createElement('h3');
12383
12383
  groupTitle.className = 'cb-settings-group-title';
12384
- groupTitle.style.cssText = 'font-size: 17px;font-weight: 500;';
12384
+ groupTitle.style.cssText = 'font-size: 16px;font-weight: 400;';
12385
12385
  groupTitle.textContent = group.label;
12386
12386
  groupElement.appendChild(groupTitle);
12387
12387
  group.fields.forEach(fieldKey => {
@@ -13886,6 +13886,12 @@ class PanelBox {
13886
13886
 
13887
13887
  </div>
13888
13888
 
13889
+ <div class="submain box-plugin-settings">
13890
+
13891
+ <hr style="width: 100%;border-bottom: #ededed 2px solid;margin-top: 20px;">
13892
+
13893
+ </div>
13894
+
13889
13895
  <button class="accordion-item btn-accordion-content" aria-expanded="false" aria-controls="boxcontent1">
13890
13896
  ${out('Content')}
13891
13897
  <span><svg><use xlink:href="#icon-chevron-down"></use></svg></span>
@@ -15264,9 +15270,134 @@ class PanelBox {
15264
15270
  chkAutoLayout.checked = true;
15265
15271
  } else {
15266
15272
  chkAutoLayout.checked = false;
15273
+ } // PLUGIN SETTINGS
15274
+
15275
+
15276
+ const divPluginSettings = panel.querySelector('.box-plugin-settings');
15277
+ this.divPluginSettings = divPluginSettings;
15278
+ const runtime = this.builder.win.builderRuntime;
15279
+
15280
+ if (overlayContent && runtime) {
15281
+ const currentElement = overlayContent.querySelector('[data-cb-type]');
15282
+
15283
+ if (currentElement) {
15284
+ divPluginSettings.style.display = '';
15285
+ this.renderPluginSettings(currentElement);
15286
+ } else {
15287
+ divPluginSettings.style.display = 'none';
15288
+ }
15267
15289
  }
15268
15290
  }
15269
15291
 
15292
+ renderPluginSettings(currentElement) {
15293
+ this.currentElement = currentElement;
15294
+ this.generator = null;
15295
+ this.currentForm = null;
15296
+ const divPluginSettings = this.divPluginSettings;
15297
+ divPluginSettings.innerHTML = '';
15298
+ const runtime = this.builder.win.builderRuntime;
15299
+ const pluginName = currentElement.getAttribute('data-cb-type');
15300
+ const plugin = runtime.getPlugin(pluginName);
15301
+ if (!plugin) return;
15302
+ let displayName = out(plugin.displayName || plugin.name);
15303
+ const divTitle = document.createElement('h3');
15304
+ divTitle.style.cssText = 'font-family: sans-serif;font-weight: 300;font-size: 20px;margin: 0 0 12px;';
15305
+ divTitle.innerText = displayName;
15306
+ divPluginSettings.appendChild(divTitle);
15307
+ this.generator = new SettingsUIGenerator$1(runtime, this.builder);
15308
+ const hasContentEditor = plugin && plugin.editor && plugin.editor.openContentEditor;
15309
+
15310
+ if (hasContentEditor) {
15311
+ // Get original content for the editor to work with
15312
+ const originalContent = currentElement.getAttribute('data-cb-original-content'); // Create a temporary element for editing (so editor can manipulate it)
15313
+
15314
+ let editableClone = document.querySelector('.editable-clone');
15315
+ if (editableClone) editableClone.remove(); // editableClone = document.createElement('div');
15316
+
15317
+ editableClone = currentElement.cloneNode(false);
15318
+ editableClone.innerHTML = originalContent;
15319
+ editableClone.className = 'editable-clone';
15320
+ editableClone.style.display = 'none'; // Hidden, just for editing
15321
+
15322
+ document.body.appendChild(editableClone);
15323
+ const originalElement = editableClone.cloneNode(false); // Let plugin handle everything - pass the editable clone
15324
+
15325
+ const editorUI = plugin.editor.openContentEditor(editableClone, this.builder, async () => {
15326
+ this.builder.editor.saveForUndo(); // Add index for sortable grid (for easy reorder)
15327
+
15328
+ let grid = editableClone.querySelector('.grid-sortable');
15329
+
15330
+ if (!grid) {
15331
+ if (currentElement.classList.contains('grid-sortable')) {
15332
+ grid = editableClone;
15333
+ }
15334
+ }
15335
+
15336
+ if (grid) {
15337
+ Array.from(grid.children).forEach((child, index) => {
15338
+ if (child.nodeType === 1 && child.tagName !== 'STYLE' && child.tagName !== 'SCRIPT') child.setAttribute('data-index', index);
15339
+ });
15340
+ } //----
15341
+ // Store edited content from clone
15342
+
15343
+
15344
+ currentElement.setAttribute('data-cb-original-content', editableClone.innerHTML); // Also performs similar value updates like the applyChanges()
15345
+ // currentElement.setAttribute('data-cb-content', editableClone.getAttribute('data-cb-content'));
15346
+
15347
+ const getChangedDataAttributes = (el1, el2) => {
15348
+ const changed = [];
15349
+
15350
+ for (const key of Object.keys(el1.dataset)) {
15351
+ if (key in el2.dataset && el1.dataset[key] !== el2.dataset[key]) {
15352
+ changed.push(key);
15353
+ }
15354
+ }
15355
+
15356
+ return changed;
15357
+ };
15358
+
15359
+ const changedAttributes = getChangedDataAttributes(originalElement, editableClone);
15360
+ changedAttributes.forEach(attrName => {
15361
+ // console.log(attrName)
15362
+ // console.log(editableClone.dataset[attrName])
15363
+ currentElement.dataset[attrName] = editableClone.dataset[attrName];
15364
+ }); // -------
15365
+
15366
+ currentElement.innerHTML = editableClone.innerHTML; // Update current content
15367
+ // Remove temporary clone
15368
+
15369
+ editableClone.remove(); // Reinitialize plugin with new content
15370
+
15371
+ await runtime.reinitialize(currentElement.parentElement);
15372
+ this.builder.onChange();
15373
+ this.builder.editor.hideElementTools();
15374
+ this.builder.makeSortable(currentElement.parentElement);
15375
+ });
15376
+ divPluginSettings.appendChild(editorUI);
15377
+ } // Generate form
15378
+
15379
+
15380
+ this.currentForm = this.generator.generateForm(pluginName, currentElement, () => {
15381
+ this.builder.editor.saveForUndo();
15382
+ this.applyChanges(runtime);
15383
+ });
15384
+ divPluginSettings.appendChild(this.currentForm);
15385
+ }
15386
+
15387
+ async applyChanges(runtime) {
15388
+ if (!this.currentElement || !this.currentForm) return; // 1. Get form values
15389
+
15390
+ const values = this.generator.getFormValues(this.currentForm); // 2. Apply to element attributes
15391
+
15392
+ this.generator.applyValues(this.currentElement, values); // 3. Reinitialize component
15393
+
15394
+ const container = this.currentElement.parentElement || this.currentElement.closest('.is-wrapper');
15395
+ await runtime.reinitialize(container);
15396
+ this.builder.onChange(); // console.log('Settings applied and component reinitialized');
15397
+
15398
+ this.builder.makeSortable(container);
15399
+ }
15400
+
15270
15401
  getStateTargeted() {
15271
15402
  let activeBox = this.builder.controlpanel.activeBox;
15272
15403
  if (!activeBox) return;
@@ -26271,8 +26402,14 @@ class ControlPanel {
26271
26402
 
26272
26403
  this.builder.onPageContentClick = e => {
26273
26404
  if (old) old.call(this);
26274
- if (this.builder.controlPanel && !document.body.classList.contains('controlpanel')) this.open();
26275
- if (document.body.classList.contains('controlpanel')) this.clickContent(e);
26405
+
26406
+ if (this.builder.controlPanel && !document.body.classList.contains('controlpanel')) {
26407
+ //if previously close, open
26408
+ this.open();
26409
+ } else {
26410
+ // if already open
26411
+ if (document.body.classList.contains('controlpanel')) this.clickContent(e);
26412
+ }
26276
26413
  };
26277
26414
 
26278
26415
  const btnClose = controlPanel.querySelector('.btn-close');
@@ -32840,7 +32977,9 @@ class Util$1 {
32840
32977
 
32841
32978
  // Reinit after drag drop block
32842
32979
  if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize();
32843
- this.builder.makeSortable(this.builder.doc);
32980
+ setTimeout(() => {
32981
+ this.builder.makeSortable(this.builder.doc);
32982
+ }, 400);
32844
32983
  }
32845
32984
 
32846
32985
  // https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro
@@ -32933,7 +33072,11 @@ class Util$1 {
32933
33072
 
32934
33073
  //Hide Column tool (new!)
32935
33074
  this.builder.util.hideColumnTool();
32936
- this.builder.makeSortable(rowElement);
33075
+
33076
+ // this.builder.makeSortable(rowElement); // cause other sortable not working
33077
+ setTimeout(() => {
33078
+ this.builder.makeSortable(this.builder.doc);
33079
+ }, 400);
32937
33080
  } else if (bSnippet) {
32938
33081
  if (noedit) {
32939
33082
  this.addContent(html, mode, 'data-noedit');
@@ -33107,7 +33250,9 @@ class Util$1 {
33107
33250
  this.builder.doc.querySelectorAll('.dummy-module').forEach(module => {
33108
33251
  module.classList.remove('dummy-module');
33109
33252
  });
33110
- this.builder.makeSortable(this.builder.doc);
33253
+ setTimeout(() => {
33254
+ this.builder.makeSortable(this.builder.doc);
33255
+ }, 400);
33111
33256
 
33112
33257
  // Change to row selection
33113
33258
  rowElement.className = rowElement.className.replace('row-outline', '');
@@ -33325,6 +33470,11 @@ class Util$1 {
33325
33470
  }
33326
33471
  }
33327
33472
 
33473
+ clearModals() {
33474
+ const builderStuff = this.builder.builderStuff;
33475
+ let modal = builderStuff.querySelector('.pluginsettings.active');
33476
+ this.hideModal(modal);
33477
+ }
33328
33478
  clearControls() {
33329
33479
  const dom = this.dom;
33330
33480
  const builderStuff = this.builder.builderStuff;
@@ -43688,6 +43838,7 @@ class Grid {
43688
43838
 
43689
43839
  // Re-init plugins
43690
43840
  if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(cellElement);
43841
+ this.builder.makeSortable(cellElement);
43691
43842
  }
43692
43843
  removeColumn() {
43693
43844
  let util = this.util;
@@ -44470,6 +44621,7 @@ class Grid {
44470
44621
 
44471
44622
  // Re-init plugins
44472
44623
  if (this.builder.win.builderRuntime) this.builder.win.builderRuntime.reinitialize(rowElement);
44624
+ this.builder.makeSortable(rowElement);
44473
44625
  }
44474
44626
  }
44475
44627
  class RowTool$1 {
@@ -81188,6 +81340,7 @@ class RowTool {
81188
81340
  const grid = new Grid(this.builder);
81189
81341
  grid.removeColumn();
81190
81342
  util.clearControls();
81343
+ util.clearModals();
81191
81344
  if (this.builder.onSelectChange) this.builder.onSelectChange();
81192
81345
  });
81193
81346
  let btnGridEditor = rowtool.querySelector('.row-grideditor');
@@ -81298,6 +81451,7 @@ class RowTool {
81298
81451
  if (elm) dom.addEventListener(elm, 'click', () => {
81299
81452
  this.grid.removeRow();
81300
81453
  util.clearControls();
81454
+ util.clearModals();
81301
81455
  if (this.builder.onSelectChange) this.builder.onSelectChange();
81302
81456
  });
81303
81457
  }
@@ -120695,6 +120849,9 @@ class BlockModal {
120695
120849
  new Tabs({
120696
120850
  element: modal
120697
120851
  });
120852
+ new Draggable$2({
120853
+ selector: '.is-modal.editblock .is-draggable'
120854
+ });
120698
120855
  } // constructor
120699
120856
 
120700
120857
  getPage() {
@@ -125179,8 +125336,16 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
125179
125336
  let newRow = newRows[0]; // get first added row
125180
125337
  if (newRow.children.length > 0) {
125181
125338
  const newCol = newRow.children[0];
125339
+ const isPlugin = newCol.querySelector('[data-cb-type]');
125182
125340
  if (newCol.children.length > 0) {
125183
- newCol.children[0].click(); // Focus on first element
125341
+ if (isPlugin) {
125342
+ setTimeout(() => {
125343
+ // give time for plugin to render (apply style) => for correct elm tool position
125344
+ newCol.children[0].click();
125345
+ }, 400);
125346
+ } else {
125347
+ newCol.children[0].click(); // Focus on first element
125348
+ }
125184
125349
  }
125185
125350
  }
125186
125351
  }
@@ -125281,7 +125446,9 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
125281
125446
  });
125282
125447
  });
125283
125448
  });
125284
- this.makeSortable(this.doc);
125449
+ setTimeout(() => {
125450
+ this.makeSortable(this.doc);
125451
+ }, 400);
125285
125452
  this.doc.querySelectorAll('.dummy-module').forEach(module => {
125286
125453
  module.classList.remove('dummy-module');
125287
125454
  });
@@ -126946,6 +127113,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
126946
127113
  this.rte.viewZoom();
126947
127114
  }
126948
127115
  async loadSnippets(source, snippetOpen) {
127116
+ this.snippetUrl = source;
126949
127117
  if (this.preview) return;
126950
127118
  if (this.opts.snippetList === '#divSnippetList') {
126951
127119
  let snippetPanel = document.querySelector(this.opts.snippetList);