@innovastudio/contentbox 1.6.195 → 1.6.196

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/contentbox",
4
- "version": "1.6.195",
4
+ "version": "1.6.196",
5
5
  "description": "",
6
6
  "main": "public/contentbox/contentbox.esm.js",
7
7
  "types": "index.d.ts",
@@ -67,7 +67,7 @@
67
67
  "ws": "^8.13.0"
68
68
  },
69
69
  "dependencies": {
70
- "@innovastudio/contentbuilder": "^1.5.213",
70
+ "@innovastudio/contentbuilder": "^1.5.214",
71
71
  "js-beautify": "^1.14.0",
72
72
  "marked": "^17.0.0",
73
73
  "sortablejs": "^1.15.2"
@@ -46429,11 +46429,13 @@ class Dom {
46429
46429
  // source: https://stackoverflow.com/questions/2871081/jquery-setting-cursor-position-in-contenteditable-div
46430
46430
  moveCursorToElement(element) {
46431
46431
  var sel, range;
46432
- if (window.getSelection && this.builder.doc.createRange) {
46432
+ if (this.builder.win.getSelection && this.builder.doc.createRange) {
46433
46433
  range = this.builder.doc.createRange();
46434
46434
  range.selectNodeContents(element);
46435
46435
  range.collapse(false);
46436
- sel = window.getSelection();
46436
+ // The CONTENT window's selection — with the editor in an iframe the
46437
+ // global one belongs to the host page, so the caret never moved.
46438
+ sel = this.builder.win.getSelection();
46437
46439
  sel.removeAllRanges();
46438
46440
  sel.addRange(range);
46439
46441
  } else if (this.builder.doc.body.createTextRange) {
@@ -122499,20 +122501,6 @@ class ContentBuilder {
122499
122501
  // force (and the option itself) disappears at the final step.
122500
122502
  this.opts.engine = 'inscribe';
122501
122503
  this.engine = 'inscribe';
122502
- if (!this.opts.uploadFile && !this.opts.upload) {
122503
- this.opts.uploadFile = async e => {
122504
- const selectedFile = e.target.files[0];
122505
- const reader = new FileReader();
122506
- const result = await new Promise((resolve, reject) => {
122507
- reader.onload = () => resolve(reader.result);
122508
- reader.onerror = reject;
122509
- reader.readAsDataURL(selectedFile);
122510
- });
122511
- return {
122512
- url: result
122513
- };
122514
- };
122515
- }
122516
122504
  if (this.opts.uploadFile) {
122517
122505
  const uploadHandler = async e => {
122518
122506
  const data = await this.opts.uploadFile(e);
@@ -122713,6 +122701,26 @@ class ContentBuilder {
122713
122701
  this.opts.onLargerImageUpload = this.opts.onImageUpload;
122714
122702
  }
122715
122703
 
122704
+ // Last-resort uploader for a builder configured without one (the demo
122705
+ // and no-backend setups): embed the picked file as a data URL. Filled
122706
+ // in per upload type, and only where nothing else provided a handler,
122707
+ // so it can never overwrite `upload`, `uploadFile`, or a legacy
122708
+ // per-type callback — overwriting those turned every upload into a
122709
+ // silent base64 embed instead of calling the host app's uploader.
122710
+ const embedAsDataUrl = async e => {
122711
+ const selectedFile = e.target.files[0];
122712
+ const reader = new FileReader();
122713
+ const result = await new Promise((resolve, reject) => {
122714
+ reader.onload = () => resolve(reader.result);
122715
+ reader.onerror = reject;
122716
+ reader.readAsDataURL(selectedFile);
122717
+ });
122718
+ this.returnUrl(result);
122719
+ };
122720
+ ['onImageUpload', 'onLargerImageUpload', 'onVideoUpload', 'onAudioUpload', 'onMediaUpload', 'onFileUpload'].forEach(name => {
122721
+ if (!this.opts[name]) this.opts[name] = embedAsDataUrl;
122722
+ });
122723
+
122716
122724
  // useButtonPlugin
122717
122725
  if (this.opts.emailMode) {
122718
122726
  this.useButtonPlugin = true;
@@ -128215,7 +128223,11 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
128215
128223
  handleCellKeydown(col, e) {
128216
128224
  if (e.which === 46 || e.which === 8) {
128217
128225
  //delete or backspace
128218
- if (this.activeIcon) {
128226
+ // Only when the selected icon is still live AND belongs to THIS
128227
+ // column: a stale activeIcon (already deleted, or left over from
128228
+ // another column) would otherwise swallow the key — cancelling the
128229
+ // delete without removing anything, or throwing on a detached node.
128230
+ if (this.activeIcon && this.activeIcon.isConnected && col.contains(this.activeIcon)) {
128219
128231
  // Delete icon
128220
128232
  if (this.activeIcon.parentNode.tagName.toLowerCase() === 'a' && this.activeIcon.parentNode.innerText.trim() === '') {
128221
128233
  let link = this.activeIcon.parentNode;
@@ -128303,46 +128315,56 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
128303
128315
  }
128304
128316
  }
128305
128317
  }
128306
- if (e.keyCode === 46) {
128307
- // console.log("delete");
128308
- let curr;
128318
+
128319
+ // LEGACY empty-block guards for Delete/Backspace (module/custom-code
128320
+ // columns only). Inscribe owns block joining in its regions
128321
+ // (_joinBack/_joinFwd + ensureBlocks), so running these there is both
128322
+ // unnecessary and harmful: the Delete branch mutates the DOM behind
128323
+ // Inscribe's back (bypassing its history) and the Backspace branch
128324
+ // cancels the key outright.
128325
+ //
128326
+ // Both read the caret from `this.win` — the CONTENT window — not the
128327
+ // global `window`, and only act when the caret really is inside this
128328
+ // column. Reading the global selection was the cause of "Backspace
128329
+ // stopped working": with the editor in an iframe (or after a click
128330
+ // landed a caret in the editor UI), the global selection points at
128331
+ // some unrelated node whose textContent is '' and which has no
128332
+ // previousElementSibling, so EVERY Backspace was preventDefault()ed —
128333
+ // typing kept working, and only a page reload cleared it.
128334
+ const legacyDeleteGuard = !this.inscribeRegionAt(col, e.target);
128335
+ if (legacyDeleteGuard && (e.keyCode === 46 || e.keyCode === 8)) {
128336
+ let curr = null;
128309
128337
  try {
128310
- if (window.getSelection) {
128311
- curr = window.getSelection().getRangeAt(0).commonAncestorContainer;
128312
- } else if (document.selection) {
128313
- curr = document.selection.createRange();
128314
- }
128315
- if (curr.innerHTML === '<br>') {
128316
- let next = curr.nextElementSibling;
128317
- if (next) {
128318
- curr.parentNode.removeChild(curr); //without this, empty P, H1, H2 (contains only <br />) cannot be deleted (when there is another P below)
128319
- // Of course, we can backspace from the P below, but the formatting will change.
128320
- e.preventDefault();
128338
+ const sel = this.win.getSelection ? this.win.getSelection() : null;
128339
+ if (sel && sel.rangeCount) curr = sel.getRangeAt(0).commonAncestorContainer;
128340
+ } catch (err) {
128341
+ curr = null;
128342
+ }
128343
+ if (curr && col.contains(curr)) {
128344
+ if (e.keyCode === 46) {
128345
+ if (curr.innerHTML === '<br>') {
128346
+ let next = curr.nextElementSibling;
128347
+ if (next) {
128348
+ curr.parentNode.removeChild(curr); //without this, empty P, H1, H2 (contains only <br />) cannot be deleted (when there is another P below)
128349
+ // Of course, we can backspace from the P below, but the formatting will change.
128350
+ e.preventDefault();
128351
+ }
128321
128352
  }
128322
128353
  }
128323
- } catch (e) {
128324
- // Do Nothing
128325
- }
128326
- }
128327
- if (e.keyCode === 8) {
128328
- // delete on Mac
128329
- let curr;
128330
- try {
128331
- if (window.getSelection) {
128332
- curr = window.getSelection().getRangeAt(0).commonAncestorContainer;
128333
- } else if (document.selection) {
128334
- curr = document.selection.createRange();
128335
- }
128336
- if (curr.textContent === '') {
128337
- let prev = curr.previousElementSibling;
128338
- if (!prev) {
128339
- e.preventDefault(); //Without this, empty P, H1, H2 (that doesn't have prev element) will be lost => can make empty column.
128354
+ if (e.keyCode === 8) {
128355
+ // delete on Mac
128356
+ // Element nodes only: a text node has no previousElementSibling,
128357
+ // so an empty text node under the caret would always cancel the key.
128358
+ if (curr.nodeType === 1 && curr.textContent === '') {
128359
+ let prev = curr.previousElementSibling;
128360
+ if (!prev) {
128361
+ e.preventDefault(); //Without this, empty P, H1, H2 (that doesn't have prev element) will be lost => can make empty column.
128362
+ }
128340
128363
  }
128341
128364
  }
128342
- } catch (e) {
128343
- // Do Nothing
128344
128365
  }
128345
128366
  }
128367
+
128346
128368
  if (e.which === 9 && !e.shiftKey) {
128347
128369
  // tab key pressed
128348
128370
  const activeCol = this.activeCol;
@@ -128353,7 +128375,7 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
128353
128375
  if (target) target.click();
128354
128376
  // if(target.firstElementChild) target.firstElementChild.click();
128355
128377
 
128356
- let selection = window.getSelection();
128378
+ let selection = this.win.getSelection();
128357
128379
  let range = this.createRange(target, {
128358
128380
  count: 0
128359
128381
  });
@@ -128377,7 +128399,7 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
128377
128399
  if (firstCol) firstCol.click();
128378
128400
  // if(firstCol.firstElementChild) firstCol.firstElementChild.click();
128379
128401
 
128380
- let selection = window.getSelection();
128402
+ let selection = this.win.getSelection();
128381
128403
  let range = this.createRange(firstCol, {
128382
128404
  count: 0
128383
128405
  });
@@ -128406,7 +128428,7 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
128406
128428
  const target = activeCol.previousElementSibling;
128407
128429
  if (target) target.click();
128408
128430
  if (target.firstElementChild) target.firstElementChild.click();
128409
- let selection = window.getSelection();
128431
+ let selection = this.win.getSelection();
128410
128432
  let range = this.createRange(target, {
128411
128433
  count: 0
128412
128434
  });
@@ -128429,7 +128451,7 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
128429
128451
  const target = divs[divs.length - 1];
128430
128452
  if (target) target.click();
128431
128453
  if (target.firstElementChild) target.firstElementChild.click();
128432
- let selection = window.getSelection();
128454
+ let selection = this.win.getSelection();
128433
128455
  let range = this.createRange(target, {
128434
128456
  count: 0
128435
128457
  });
@@ -128498,7 +128520,7 @@ Please obtain a license at: https://innovastudio.com/contentbox`);
128498
128520
  }
128499
128521
  createRange(node, chars, range) {
128500
128522
  if (!range) {
128501
- range = document.createRange();
128523
+ range = this.doc.createRange();
128502
128524
  range.selectNode(node);
128503
128525
  range.setStart(node, 0);
128504
128526
  }
@@ -161222,6 +161244,7 @@ Add an image for each feature.`, 'Create a new block showcasing a photo gallery
161222
161244
  videoHandler: this.settings.videoHandler,
161223
161245
  audioHandler: this.settings.audioHandler,
161224
161246
  fileHandler: this.settings.fileHandler,
161247
+ upload: this.settings.upload,
161225
161248
  uploadFile: this.settings.uploadFile,
161226
161249
  onVideoUpload: this.settings.onVideoUpload,
161227
161250
  onAudioUpload: this.settings.onAudioUpload,