@innovastudio/contentbuilder 1.5.219 → 1.5.220

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
  "type": "module",
3
3
  "name": "@innovastudio/contentbuilder",
4
- "version": "1.5.219",
4
+ "version": "1.5.220",
5
5
  "description": "",
6
6
  "main": "public/contentbuilder/contentbuilder.esm.js",
7
7
  "types": "index.d.ts",
@@ -29561,10 +29561,10 @@ class Image$1 {
29561
29561
 
29562
29562
  <div class="cb-field">
29563
29563
  <label class="label-checkbox">
29564
- <input class="input-newwindow" id="__input_newwindow2" type="checkbox" /> ${util.out('Open new window')}
29564
+ <input class="input-newwindow" id="__input_newwindow2" type="checkbox" /> ${util.out('Open in new tab')}
29565
29565
  </label>
29566
29566
  <label class="label-checkbox mt-1" id="lblImageLinkOpenLightbox" style="${this.builder.useLightbox ? '' : 'display:none'}">
29567
- <input class="input-openlightbox" id="__input_openlightbox2" type="checkbox" /> ${util.out('Open in a lightbox (for image, video or Youtube)')}
29567
+ <input class="input-openlightbox" id="__input_openlightbox2" type="checkbox" /> ${util.out('Open in a lightbox')}
29568
29568
  </label>
29569
29569
  </div>
29570
29570
 
@@ -30644,9 +30644,22 @@ class ButtonEditor {
30644
30644
  if (cmd === 'href') setHref(el, value);else if (cmd === 'newtab') setNewTab(el, value);else if (cmd === 'fontsize') setFontSize(el, value === '' ? '' : parseInt(value, 10));else if (cmd === 'tracking') {
30645
30645
  if (value !== '') setTracking(el, parseInt(value, 10));
30646
30646
  } else if (cmd === 'margin') setMargin(el, side, value === '' ? 0 : parseInt(value, 10));
30647
+ if (cmd === 'href' || cmd === 'newtab') this.syncLinkDialog(el);
30647
30648
  this.builder.opts.onChange();
30648
30649
  this.realtime();
30649
30650
  }
30651
+
30652
+ // The link dialog edits the same href/target and can be open alongside this
30653
+ // panel. Its fields are read when it opens, so without this its Ok would
30654
+ // write back the link as it was before the panel touched it.
30655
+ syncLinkDialog(el) {
30656
+ const modal = this.builderStuff.querySelector('.is-modal.createlink');
30657
+ if (!modal || !this.dom.hasClass(modal, 'active')) return;
30658
+ const url = modal.querySelector('.input-url');
30659
+ if (url && document.activeElement !== url) url.value = el.getAttribute('href') || '';
30660
+ const newwindow = modal.querySelector('.input-newwindow');
30661
+ if (newwindow) newwindow.checked = el.getAttribute('target') === '_blank';
30662
+ }
30650
30663
  openColor(cmd, btn) {
30651
30664
  const el = this.getButton();
30652
30665
  if (!el) return;
@@ -30965,6 +30978,23 @@ class Hyperlink {
30965
30978
  this.buttonEditor = new ButtonEditor(this.builder);
30966
30979
  }
30967
30980
  }
30981
+
30982
+ // The link dialog and a button UI can be open at the same time and both
30983
+ // show the link's href and target. After the dialog writes to the link,
30984
+ // the button UI has to re-read it, or it keeps showing (and writing back)
30985
+ // the old values. The host can own that UI instead (onButtonEdit).
30986
+ syncButtonUI(link) {
30987
+ if (!link || !link.isConnected) return;
30988
+ if (this.builder.opts.onButtonEdit) {
30989
+ if (link === this.builder.activeLinkButton) this.builder.opts.onButtonEdit(link);
30990
+ return;
30991
+ }
30992
+ const dom = this.builder.dom;
30993
+ const buttonModal = this.builder.builderStuff.querySelector('.is-modal.buttoneditor');
30994
+ if (!buttonModal || !dom.hasClass(buttonModal, 'active')) return;
30995
+ if (!this.buttonEditor) this.buttonEditor = new ButtonEditor(this.builder);
30996
+ this.buttonEditor.realtime();
30997
+ }
30968
30998
  renderPanel() {
30969
30999
  const builderStuff = this.builder.builderStuff;
30970
31000
  const util = this.builder.util;
@@ -30996,10 +31026,10 @@ class Hyperlink {
30996
31026
  </div>
30997
31027
  <div class="cb-field">
30998
31028
  <label class="label-checkbox">
30999
- <input class="input-newwindow" id="__input_newwindow" type="checkbox" /> ${util.out('Open new window')}
31029
+ <input class="input-newwindow" id="__input_newwindow" type="checkbox" /> ${util.out('Open in new tab')}
31000
31030
  </label>
31001
- <label class="label-checkbox" id="lblOpenLightbox" style="${this.builder.useLightbox ? '' : 'display:none'}">
31002
- <input class="input-openlightbox" id="__input_openlightbox" type="checkbox" /> ${util.out('Open in a lightbox (for image, video or Youtube)')}
31031
+ <label class="label-checkbox mt-1" id="lblOpenLightbox" style="${this.builder.useLightbox ? '' : 'display:none'}">
31032
+ <input class="input-openlightbox" id="__input_openlightbox" type="checkbox" /> ${util.out('Open in a lightbox')}
31003
31033
  </label>
31004
31034
  </div>
31005
31035
  <div class="cb-field">
@@ -31042,6 +31072,7 @@ class Hyperlink {
31042
31072
  let inputOk = modal.querySelector('.input-ok');
31043
31073
  dom.addEventListener(inputOk, 'click', () => {
31044
31074
  this.builder.uo.saveForUndo();
31075
+ let editedLink = null;
31045
31076
  let link = this.builder.activeLink;
31046
31077
  if (link) {
31047
31078
  // Edit Existing Link
@@ -31051,35 +31082,19 @@ class Hyperlink {
31051
31082
  let linktext = modal.querySelector('.input-text').value;
31052
31083
  if (linktext === '') linktext = url;
31053
31084
 
31054
- // Engine seam: edit / unlink an existing link via Inscribe.
31055
- // A cleared URL means UNLINK. Icon links stay legacy.
31056
- if (this.builder.opts.engine === 'inscribe' && !this.builder.activeIcon) {
31085
+ // Engine seam: only UNLINK (a cleared URL) goes through
31086
+ // Inscribe. An edit is applied in place below: region.link()
31087
+ // re-wraps the selection in a NEW plain <a>, which dropped
31088
+ // the link's classes and inline styles, so changing a
31089
+ // button's URL stripped the button. Icon links stay legacy.
31090
+ if (url === '' && this.builder.opts.engine === 'inscribe' && !this.builder.activeIcon) {
31057
31091
  const region = this.builder.editingEngine.active;
31058
31092
  if (region && link.isConnected) {
31059
31093
  dom.selectElementContents(link); // target the link
31060
- if (url !== '') {
31061
- const attrs = {
31062
- target: modal.querySelector('.input-newwindow').checked ? '_blank' : '',
31063
- title: title || '',
31064
- class: modal.querySelector('.input-openlightbox').checked ? 'is-lightbox' : ''
31065
- };
31066
- const created = region.link(url, attrs); // re-wraps, returns <a>
31067
- if (created && linktext && created.textContent !== linktext) {
31068
- created.textContent = linktext;
31069
- }
31070
- this.builder.opts.onChange();
31071
- util.hideModal(modal);
31072
- if (created && created.isConnected) {
31073
- region.focus();
31074
- dom.selectElementContents(created);
31075
- util.saveSelection();
31076
- }
31077
- } else {
31078
- region.unlink();
31079
- this.hideTool();
31080
- this.builder.opts.onChange();
31081
- util.hideModal(modal);
31082
- }
31094
+ region.unlink();
31095
+ this.hideTool();
31096
+ this.builder.opts.onChange();
31097
+ util.hideModal(modal);
31083
31098
  return;
31084
31099
  }
31085
31100
  }
@@ -31087,6 +31102,7 @@ class Hyperlink {
31087
31102
  link.setAttribute('href', url);
31088
31103
  if (modal.querySelector('.input-newwindow').checked) {
31089
31104
  link.setAttribute('target', '_blank');
31105
+ if (!link.getAttribute('rel')) link.setAttribute('rel', 'noopener noreferrer');
31090
31106
  } else {
31091
31107
  link.removeAttribute('target');
31092
31108
  }
@@ -31098,7 +31114,14 @@ class Hyperlink {
31098
31114
  if (this.builder.activeIcon) ; else {
31099
31115
  link.innerHTML = linktext;
31100
31116
  }
31101
- link.setAttribute('title', title);
31117
+ if (title) link.setAttribute('title', title);else link.removeAttribute('title');
31118
+
31119
+ // A button UI (this editor's Button panel, or the
31120
+ // host's own) shows the same link and can be open at
31121
+ // the same time as this dialog, so it has to re-read
31122
+ // what was just written.
31123
+ this.syncButtonUI(link);
31124
+ editedLink = link;
31102
31125
  } else {
31103
31126
  // link.outerHTML = link.innerHTML;
31104
31127
  this.hideTool();
@@ -31256,6 +31279,17 @@ class Hyperlink {
31256
31279
  this.builder.opts.onRender();
31257
31280
  }
31258
31281
  util.hideModal(modal);
31282
+
31283
+ // hideModal() blurs, so the caret goes back on the edited link
31284
+ // afterwards: the dialog can be reopened straight away.
31285
+ if (editedLink && editedLink.isConnected && !this.builder.activeIcon) {
31286
+ const region = this.builder.editingEngine.active;
31287
+ if (region) {
31288
+ region.focus();
31289
+ dom.selectElementContents(editedLink);
31290
+ util.saveSelection();
31291
+ }
31292
+ }
31259
31293
  });
31260
31294
  let inputCancel = modal.querySelector('.input-cancel');
31261
31295
  dom.addEventListener(inputCancel, 'click', () => {
@@ -31401,7 +31435,10 @@ class Hyperlink {
31401
31435
  }
31402
31436
 
31403
31437
  // Button Stuff
31404
- if (this.builder.useButtonPlugin) {
31438
+ // A host with its own button UI (onButtonEdit) already opens it by
31439
+ // selecting the button, so the pencil is a second route to the same
31440
+ // panel and is left out.
31441
+ if (this.builder.useButtonPlugin || this.builder.opts.onButtonEdit) {
31405
31442
  linkTool.querySelector('.link-button-edit').style.display = 'none';
31406
31443
  } else {
31407
31444
  if (link && this.builder.activeLinkButton) linkTool.querySelector('.link-button-edit').style.display = 'block';else linkTool.querySelector('.link-button-edit').style.display = 'none';
@@ -31705,6 +31742,11 @@ class Button {
31705
31742
  this.buttonEditor.realtime();
31706
31743
  }
31707
31744
  const buttonTool = this.buttonTool;
31745
+
31746
+ // A host with its own button UI (onButtonEdit) already opens it by
31747
+ // selecting the button, so the pencil is a second route to the same
31748
+ // panel and is left out.
31749
+ buttonTool.querySelector('.button-edit').style.display = this.builder.opts.onButtonEdit ? 'none' : '';
31708
31750
  let top = activeButton.getBoundingClientRect().top + this.builder.win.pageYOffset;
31709
31751
  let left = activeButton.getBoundingClientRect().left;
31710
31752
  buttonTool.style.display = 'flex';