@innovastudio/contentbox 1.6.196 → 1.6.198

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.196",
4
+ "version": "1.6.198",
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.214",
70
+ "@innovastudio/contentbuilder": "^1.5.216",
71
71
  "js-beautify": "^1.14.0",
72
72
  "marked": "^17.0.0",
73
73
  "sortablejs": "^1.15.2"
@@ -25956,9 +25956,11 @@ function convertSection(section, win) {
25956
25956
  if (isLegacyAttr(a.name)) el.removeAttribute(a.name);
25957
25957
  });
25958
25958
  LEGACY_CLASSES.forEach(c => el.classList && el.classList.remove(c));
25959
- byPct.forEach(f => el.setAttribute(`data-fx-${f.pct}`, toFxValue(f.props)));
25960
- el.setAttribute('data-fx-ease', 'linear'); // skrollrr interpolates linearly
25959
+ byPct.forEach(f => el.setAttribute(`data-fx-${f.pct}`, toFxValue(f.props))); // Linear is correct: lax interpolated linearly (it only eases when
25960
+ // options.easing is passed, and skrollrr never passed it). Legacy's
25961
+ // visible softness was NOT keyframe easing — see the scrub note below.
25961
25962
 
25963
+ el.setAttribute('data-fx-ease', 'linear');
25962
25964
  el.style.transform = '';
25963
25965
  el.style.opacity = '';
25964
25966
  });
@@ -25985,10 +25987,24 @@ function convertSection(section, win) {
25985
25987
  } else {
25986
25988
  // legacy anchors span in -> out, i.e. the whole crossing
25987
25989
  section.setAttribute('data-fx-end', 'bottom top');
25988
- } // ~0.1s matches the old CSS 'transition: all .3s ease-out' softness
25990
+ }
25991
+ /* Legacy's smoothness came from `transition: all .3s ease-out` on each
25992
+ * element — a TIME lag on top of linear keyframes, not a keyframe shape.
25993
+ * The scrub is the Motion equivalent, so it carries that lag across.
25994
+ *
25995
+ * 0.1 was the original guess and it is about HALF the real softness:
25996
+ * kinetra's scrub advances by dt/scrub per frame (kinetra.js ~965), so at
25997
+ * 60fps scrub=0.1 gives a per-frame gain of ~0.167, while a 0.3s ease-out
25998
+ * restarted each frame gives ~0.086 — which corresponds to scrub ~0.19.
25999
+ * Converted sections rendered with 0.1 start and stop noticeably abruptly.
26000
+ *
26001
+ * The same wrong constant was in the runtime's legacy path; it was fixed
26002
+ * there by restoring the CSS transition outright (skrollrr-kinetra.js,
26003
+ * `animationTransition`). Converted content has no legacy attributes left,
26004
+ * so the scrub is the only lever here — 0.2 is the matching value. */
25989
26005
 
25990
26006
 
25991
- section.setAttribute('data-fx-scrub', hardScrub ? '0' : '0.1');
26007
+ section.setAttribute('data-fx-scrub', hardScrub ? '0' : '0.4');
25992
26008
  return {
25993
26009
  converted: plans.length,
25994
26010
  droppedVariants,
@@ -44954,6 +44970,17 @@ class Util$1 {
44954
44970
  hidePops() {
44955
44971
  const dom = this.dom;
44956
44972
  const builderStuff = this.builder.builderStuff;
44973
+
44974
+ /* Fast path. This runs on every scroll event (see the window 'scroll'
44975
+ * handler in contentbuilder.js — its 10ms debounce is shorter than the
44976
+ * ~16ms gap between scroll events, so it does not coalesce them), which
44977
+ * meant two full querySelectorAll sweeps plus their loops ~60x/second
44978
+ * even with nothing open. When nothing is showing, the loops below are
44979
+ * no-ops, so skip straight to the image handles. */
44980
+ if (!builderStuff.querySelector('.is-tool.active, .is-tool[style*="display"], .is-pop.active')) {
44981
+ if (this.builder.editingEngine) this.builder.editingEngine.hideImageHandles();
44982
+ return;
44983
+ }
44957
44984
  let tools = builderStuff.querySelectorAll('.is-tool');
44958
44985
  Array.prototype.forEach.call(tools, tool => {
44959
44986
  // if(tool.classList.contains('is-row-tool')||
@@ -69763,11 +69790,23 @@ class Plugin {
69763
69790
  }
69764
69791
  };
69765
69792
  if (!this.builder.handlePluginClick_) {
69766
- document.addEventListener('click', handlePluginClick);
69767
- if (this.builder.iframeDocument) {
69768
- this.builder.doc.addEventListener('click', handlePluginClick);
69769
- }
69770
69793
  this.builder.handlePluginClick_ = true;
69794
+ // Register on the NEXT task, not now. showPluginEditor() can be
69795
+ // reached from a microtask inside the very click that opens the
69796
+ // panel: the RTE button runs convertSelectionToPlugin(), whose
69797
+ // runtime.reinitialize().then() resolves while that click is still
69798
+ // propagating towards document. A listener added mid-propagation
69799
+ // still receives that same click, so the panel was closed the
69800
+ // instant it opened — and only on a first open, because afterwards
69801
+ // the previous listener had already fired and removed itself.
69802
+ // Deferring means this listener can never see the click that
69803
+ // created it, whichever toolbar or panel opened the panel.
69804
+ setTimeout(() => {
69805
+ document.addEventListener('click', handlePluginClick);
69806
+ if (this.builder.iframeDocument) {
69807
+ this.builder.doc.addEventListener('click', handlePluginClick);
69808
+ }
69809
+ }, 0);
69771
69810
  }
69772
69811
  }
69773
69812
  hidePluginEditor() {
@@ -107083,16 +107122,42 @@ class Resize {
107083
107122
  enable() {
107084
107123
  const col = this.element;
107085
107124
  const row = col.parentNode;
107125
+
107126
+ // The builder injects its own elements into a row — tools, the add-row
107127
+ // bar, and the row overlay that appears once the row is selected in the
107128
+ // side panel. They are not columns, and measuring them as columns makes
107129
+ // the totals below nonsense. Filter them out in ONE place so a new
107130
+ // injected element can never silently break the maths again.
107131
+ const isBuilderUI = item => item.nodeType !== 1 || item.classList.contains('is-tool') || item.classList.contains('is-row-tool') || item.classList.contains('is-col-tool') || item.classList.contains('is-rowadd-tool') || item.classList.contains('is-row-overlay');
107132
+ const columnsOf = parent => Array.from(parent.children).filter(item => !isBuilderUI(item));
107133
+
107134
+ // A column width is only ever stored as a percentage; pixels are used
107135
+ // purely while a drag is in progress. resizeEnd normally converts them
107136
+ // back, but it does not run if the drag is interrupted — and pixel
107137
+ // widths saved into the page push content off screen on smaller
107138
+ // devices. This is the backstop for that: whatever happens to the drag,
107139
+ // a leftover pixel width is converted on the next tick. Capture phase,
107140
+ // so it still runs if something stops the event bubbling.
107141
+ const normalizeToPercent = () => {
107142
+ setTimeout(() => {
107143
+ if (!col.style.width || col.style.width.indexOf('px') === -1) return;
107144
+ const parent = col.parentNode;
107145
+ if (!parent || !parent.offsetWidth) return;
107146
+ const pct = col.offsetWidth / parent.offsetWidth * 100;
107147
+ if (isFinite(pct) && pct > 0) col.style.width = pct + '%';
107148
+ }, 0);
107149
+ };
107150
+ this.normalizeToPercent = normalizeToPercent;
107151
+ this.eventTarget = col.ownerDocument;
107152
+ this.eventTarget.addEventListener('mouseup', normalizeToPercent, true);
107153
+ this.eventTarget.addEventListener('touchend', normalizeToPercent, true);
107086
107154
  this.resize = new Resizeable({
107087
107155
  pane: col,
107088
107156
  resizeHeight: this.builder.resizeHeight,
107089
107157
  onResize: (width, height) => {
107090
107158
  this.builder.util.hideControls();
107091
107159
  let numOfCols = 1;
107092
- Array.from(col.parentNode.children).map(item => {
107093
- if (item.classList.contains('is-row-tool')) return;
107094
- if (item.classList.contains('is-rowadd-tool')) return;
107095
- if (item.classList.contains('is-col-tool')) return;
107160
+ columnsOf(col.parentNode).map(item => {
107096
107161
  if (item === col) return;
107097
107162
  numOfCols++;
107098
107163
  });
@@ -107103,10 +107168,7 @@ class Resize {
107103
107168
  // adjust others
107104
107169
  const maxWidth = () => {
107105
107170
  let otherWidth = 0;
107106
- Array.from(col.parentNode.children).map(item => {
107107
- if (item.classList.contains('is-row-tool')) return;
107108
- if (item.classList.contains('is-rowadd-tool')) return;
107109
- if (item.classList.contains('is-col-tool')) return;
107171
+ columnsOf(col.parentNode).map(item => {
107110
107172
  // if(this.opts.filterSibling) if(item.classList.contains(this.opts.filterSibling)) return;
107111
107173
 
107112
107174
  if (item === col) return;
@@ -107120,10 +107182,7 @@ class Resize {
107120
107182
  // percentage = (max / row.offsetWidth) * 100;
107121
107183
  // Or make others auto
107122
107184
 
107123
- Array.from(col.parentNode.children).map(item => {
107124
- if (item.classList.contains('is-row-tool')) return;
107125
- if (item.classList.contains('is-rowadd-tool')) return;
107126
- if (item.classList.contains('is-col-tool')) return;
107185
+ columnsOf(col.parentNode).map(item => {
107127
107186
  // if(this.opts.filterSibling) if(item.classList.contains(this.opts.filterSibling)) return;
107128
107187
 
107129
107188
  if (item === col) return;
@@ -107161,10 +107220,7 @@ class Resize {
107161
107220
  }
107162
107221
  } else {
107163
107222
  // New: if other cols has no width, set to 100%
107164
- Array.from(col.parentNode.children).map(item => {
107165
- if (item.classList.contains('is-row-tool')) return;
107166
- if (item.classList.contains('is-rowadd-tool')) return;
107167
- if (item.classList.contains('is-col-tool')) return;
107223
+ columnsOf(col.parentNode).map(item => {
107168
107224
  // if(this.opts.filterSibling) if(item.classList.contains(this.opts.filterSibling)) return;
107169
107225
 
107170
107226
  if (item === col) return;
@@ -107194,10 +107250,7 @@ class Resize {
107194
107250
  },
107195
107251
  resizeEnd: () => {
107196
107252
  let numOfCols = 1;
107197
- Array.from(col.parentNode.children).map(item => {
107198
- if (item.classList.contains('is-row-tool')) return;
107199
- if (item.classList.contains('is-rowadd-tool')) return;
107200
- if (item.classList.contains('is-col-tool')) return;
107253
+ columnsOf(col.parentNode).map(item => {
107201
107254
  if (item === col) return;
107202
107255
  numOfCols++;
107203
107256
  });
@@ -107209,13 +107262,9 @@ class Resize {
107209
107262
  // adjust others
107210
107263
  const maxWidth = () => {
107211
107264
  let otherWidth = 0;
107212
- Array.from(col.parentNode.children).map(item => {
107213
- if (item.classList.contains('is-row-tool')) return;
107214
- if (item.classList.contains('is-rowadd-tool')) return;
107215
- if (item.classList.contains('is-col-tool')) return;
107265
+ columnsOf(col.parentNode).map(item => {
107216
107266
  // if(this.opts.filterSibling) if(item.classList.contains(this.opts.filterSibling)) return;
107217
107267
 
107218
- if (item.classList.contains('row-tool')) return;
107219
107268
  if (item === col) return;
107220
107269
  otherWidth += item.offsetWidth;
107221
107270
  });
@@ -107227,10 +107276,7 @@ class Resize {
107227
107276
  // percentage = (max / row.offsetWidth) * 100;
107228
107277
  // Or make others auto
107229
107278
 
107230
- Array.from(col.parentNode.children).map(item => {
107231
- if (item.classList.contains('is-row-tool')) return;
107232
- if (item.classList.contains('is-rowadd-tool')) return;
107233
- if (item.classList.contains('is-col-tool')) return;
107279
+ columnsOf(col.parentNode).map(item => {
107234
107280
  // if(this.opts.filterSibling) if(item.classList.contains(this.opts.filterSibling)) return;
107235
107281
 
107236
107282
  if (item === col) return;
@@ -107260,10 +107306,7 @@ class Resize {
107260
107306
  // New: Final fix (if column resized exceeds its max)
107261
107307
  let othersWidth = 0;
107262
107308
  let activeColumnWidth = 0;
107263
- Array.from(col.parentNode.children).map(item => {
107264
- if (item.classList.contains('is-row-tool')) return;
107265
- if (item.classList.contains('is-rowadd-tool')) return;
107266
- if (item.classList.contains('is-col-tool')) return;
107309
+ columnsOf(col.parentNode).map(item => {
107267
107310
  // if(this.opts.filterSibling) if(item.classList.contains(this.opts.filterSibling)) return;
107268
107311
 
107269
107312
  // // Refresh Module
@@ -107281,13 +107324,23 @@ class Resize {
107281
107324
  if (activeColumnWidth > maxResult) {
107282
107325
  percentage = maxResult / row.offsetWidth * 100;
107283
107326
  }
107284
- col.style.width = percentage + '%';
107327
+
107328
+ // The column is carrying a pixel width at this point (set
107329
+ // just above, to measure it). A width is only ever stored as
107330
+ // a percentage, so if the maths produced something CSS will
107331
+ // reject — negative, zero, NaN, Infinity — the assignment
107332
+ // would silently fail and leave those pixels behind, which
107333
+ // then breaks the layout on smaller screens. Fall back to
107334
+ // the column's real share of the row instead.
107335
+ if (!isFinite(percentage) || percentage <= 0) {
107336
+ percentage = col.offsetWidth / row.offsetWidth * 100;
107337
+ }
107338
+ if (isFinite(percentage) && percentage > 0) {
107339
+ col.style.width = percentage + '%';
107340
+ }
107285
107341
 
107286
107342
  // Refresh Module
107287
- Array.from(col.parentNode.children).map(item => {
107288
- if (item.classList.contains('is-row-tool')) return;
107289
- if (item.classList.contains('is-rowadd-tool')) return;
107290
- if (item.classList.contains('is-col-tool')) return;
107343
+ columnsOf(col.parentNode).map(item => {
107291
107344
  if (item.getAttribute('data-html')) {
107292
107345
  let moduleWidth = item.offsetWidth / row.offsetWidth * 100;
107293
107346
  item.style.width = moduleWidth + '%';
@@ -107299,10 +107352,7 @@ class Resize {
107299
107352
  if (col.style.height) {
107300
107353
  col.style.minHeight = col.style.height;
107301
107354
  col.style.height = '';
107302
- Array.from(col.parentNode.children).map(item => {
107303
- if (item.classList.contains('is-row-tool')) return;
107304
- if (item.classList.contains('is-rowadd-tool')) return;
107305
- if (item.classList.contains('is-col-tool')) return;
107355
+ columnsOf(col.parentNode).map(item => {
107306
107356
  // if(this.opts.filterSibling) if(item.classList.contains(this.opts.filterSibling)) return;
107307
107357
 
107308
107358
  if (item === col) return;
@@ -107322,6 +107372,10 @@ class Resize {
107322
107372
  });
107323
107373
  }
107324
107374
  destroy() {
107375
+ if (this.eventTarget && this.normalizeToPercent) {
107376
+ this.eventTarget.removeEventListener('mouseup', this.normalizeToPercent, true);
107377
+ this.eventTarget.removeEventListener('touchend', this.normalizeToPercent, true);
107378
+ }
107325
107379
  this.resize.destroy();
107326
107380
  }
107327
107381
  }