@innovastudio/contentbox 1.6.204 → 1.6.205
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.
|
|
4
|
+
"version": "1.6.205",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "public/contentbox/contentbox.esm.js",
|
|
7
7
|
"types": "index.d.ts",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"ws": "^8.13.0"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@innovastudio/contentbuilder": "^1.5.
|
|
76
|
+
"@innovastudio/contentbuilder": "^1.5.223",
|
|
77
77
|
"js-beautify": "^1.14.0",
|
|
78
78
|
"marked": "^17.0.0",
|
|
79
79
|
"sortablejs": "^1.15.2"
|
|
@@ -19517,7 +19517,7 @@ class PanelIcon {
|
|
|
19517
19517
|
<button title="${out('Color')}" class="btn-color is-btn-color"></button>
|
|
19518
19518
|
</div>
|
|
19519
19519
|
|
|
19520
|
-
<div class="label">${out('Icon Size')}:</div>
|
|
19520
|
+
<div class="label label-iconsize">${out('Icon Size')}:</div>
|
|
19521
19521
|
|
|
19522
19522
|
<div role="group" aria-label="${out('Font Size')}" class="group fontsizes">
|
|
19523
19523
|
${fontSizeHtml}
|
|
@@ -19580,20 +19580,17 @@ class PanelIcon {
|
|
|
19580
19580
|
btnSizes.forEach(btn => {
|
|
19581
19581
|
btn.addEventListener('click', () => {
|
|
19582
19582
|
this.builder.editor.saveForUndo();
|
|
19583
|
-
const num = btn.getAttribute('data-value');
|
|
19584
|
-
let currentFontSize = 1;
|
|
19585
|
-
let container = this.getElm();
|
|
19583
|
+
const num = btn.getAttribute('data-value'); // Size the icon itself, as ContentBuilder's own size buttons do for an icon.
|
|
19586
19584
|
|
|
19587
|
-
|
|
19588
|
-
|
|
19585
|
+
const icon = this.builder.controlpanel.activeElement;
|
|
19586
|
+
const rte = this.builder.editor.rte;
|
|
19587
|
+
|
|
19588
|
+
if ((this.builder.editor.opts.fontSizeClassValues || []).length > 0) {
|
|
19589
|
+
rte.applyClassFontSize(icon, num);
|
|
19590
|
+
} else {
|
|
19591
|
+
rte.applyInlineFontSize(icon, num);
|
|
19589
19592
|
}
|
|
19590
19593
|
|
|
19591
|
-
this.builder.editor.dom.execCommand('font-size', currentFontSize + 1 + 'px', (ok, container) => {
|
|
19592
|
-
if (ok) {
|
|
19593
|
-
this.builder.editor.rte.applyClassFontSize(container, num);
|
|
19594
|
-
container.style.fontSize = '';
|
|
19595
|
-
}
|
|
19596
|
-
});
|
|
19597
19594
|
this.getState();
|
|
19598
19595
|
this.builder.editor.onChange();
|
|
19599
19596
|
});
|
|
@@ -19631,7 +19628,13 @@ class PanelIcon {
|
|
|
19631
19628
|
getState() {
|
|
19632
19629
|
const panel = this.panel;
|
|
19633
19630
|
let icon = this.builder.controlpanel.activeElement;
|
|
19634
|
-
const div = icon.parentNode;
|
|
19631
|
+
const div = icon.parentNode; // An icon in overlay text: its link and alignment belong to the line (the Text panel),
|
|
19632
|
+
// and its size follows the design, like the text's. Only Change icon and Color are shown.
|
|
19633
|
+
|
|
19634
|
+
const inOverlayText = !!this.builder.controlpanel.overlayIcon(icon);
|
|
19635
|
+
panel.querySelectorAll('.btn-link, .label-iconsize, .group.fontsizes, .alignicon').forEach(elm => {
|
|
19636
|
+
elm.style.display = inOverlayText ? 'none' : '';
|
|
19637
|
+
});
|
|
19635
19638
|
const btnAligns = panel.querySelectorAll('[data-align]');
|
|
19636
19639
|
btnAligns.forEach(btn => btn.classList.remove('on'));
|
|
19637
19640
|
if (div.classList.contains('text-left')) panel.querySelector('[data-align="left"]').classList.add('on');
|
|
@@ -19682,14 +19685,6 @@ class PanelIcon {
|
|
|
19682
19685
|
}
|
|
19683
19686
|
}
|
|
19684
19687
|
|
|
19685
|
-
getElm() {
|
|
19686
|
-
const selection = this.builder.win.getSelection();
|
|
19687
|
-
const anchorNode = selection.anchorNode;
|
|
19688
|
-
if (!anchorNode) return false;
|
|
19689
|
-
const container = anchorNode.nodeType !== Node.TEXT_NODE && anchorNode.nodeType !== Node.COMMENT_NODE ? anchorNode : anchorNode.parentElement;
|
|
19690
|
-
return container;
|
|
19691
|
-
}
|
|
19692
|
-
|
|
19693
19688
|
}
|
|
19694
19689
|
|
|
19695
19690
|
class PanelSvg {
|
|
@@ -33708,6 +33703,15 @@ class PanelSection {
|
|
|
33708
33703
|
<div class="accordion-content" id="sectioncontent5" aria-hidden="true">
|
|
33709
33704
|
|
|
33710
33705
|
<div class="subpanel">
|
|
33706
|
+
<div class="barstart-row">
|
|
33707
|
+
<div class="label mt-2">${out('Bar at the start')}:</div>
|
|
33708
|
+
<div role="group" aria-label="${out('Bar at the start')}" class="group sectionbar barstart">
|
|
33709
|
+
<button title="${out('Auto')}" data-barstart="">${out('Auto')}</button>
|
|
33710
|
+
<button title="${out('Light')}" data-barstart="light">${out('Light')}</button>
|
|
33711
|
+
<button title="${out('Dark')}" data-barstart="dark">${out('Dark')}</button>
|
|
33712
|
+
</div>
|
|
33713
|
+
</div>
|
|
33714
|
+
|
|
33711
33715
|
<div class="label mt-2">${out('Bar over this section')}:</div>
|
|
33712
33716
|
<div role="group" aria-label="${out('Bar over this section')}" class="group sectionbar">
|
|
33713
33717
|
<button title="${out('Default')}" data-bar="">${out('Default')}</button>
|
|
@@ -33932,6 +33936,20 @@ class PanelSection {
|
|
|
33932
33936
|
btn.classList.add('on');
|
|
33933
33937
|
this.builder.onChange();
|
|
33934
33938
|
});
|
|
33939
|
+
}); // Bar at the start: the bar's text while it rests over the top section, at the top of
|
|
33940
|
+
// the page (data-bar-start). Only the top section has it. Auto: no attribute.
|
|
33941
|
+
|
|
33942
|
+
const btnBarStarts = panel.querySelectorAll('[data-barstart]');
|
|
33943
|
+
btnBarStarts.forEach(btn => {
|
|
33944
|
+
btn.addEventListener('click', () => {
|
|
33945
|
+
this.builder.editor.saveForUndo();
|
|
33946
|
+
const section = this.builder.activeSection;
|
|
33947
|
+
const s = btn.getAttribute('data-barstart');
|
|
33948
|
+
if (s) section.setAttribute('data-bar-start', s);else section.removeAttribute('data-bar-start');
|
|
33949
|
+
btnBarStarts.forEach(btn => btn.classList.remove('on'));
|
|
33950
|
+
btn.classList.add('on');
|
|
33951
|
+
this.builder.onChange();
|
|
33952
|
+
});
|
|
33935
33953
|
});
|
|
33936
33954
|
const btnBarInk = panel.querySelector('.btn-barink');
|
|
33937
33955
|
btnBarInk.addEventListener('click', () => {
|
|
@@ -34208,7 +34226,16 @@ class PanelSection {
|
|
|
34208
34226
|
if (showBar) {
|
|
34209
34227
|
const look = activeSection.getAttribute('data-bar') || '';
|
|
34210
34228
|
panel.querySelectorAll('[data-bar]').forEach(btn => btn.classList.toggle('on', btn.getAttribute('data-bar') === look));
|
|
34211
|
-
panel.querySelector('.btn-barink').style.backgroundColor = activeSection.getAttribute('data-bar-ink') || '';
|
|
34229
|
+
panel.querySelector('.btn-barink').style.backgroundColor = activeSection.getAttribute('data-bar-ink') || ''; // Bar at the start: the top section only (the first section under the bar)
|
|
34230
|
+
|
|
34231
|
+
const top = Array.from(this.builder.wrapperEl.querySelectorAll('.is-section')).find(s => !s.closest('.is-section-navbar'));
|
|
34232
|
+
const isTop = top === activeSection;
|
|
34233
|
+
panel.querySelector('.barstart-row').style.display = isTop ? '' : 'none';
|
|
34234
|
+
|
|
34235
|
+
if (isTop) {
|
|
34236
|
+
const start = activeSection.getAttribute('data-bar-start') || '';
|
|
34237
|
+
panel.querySelectorAll('[data-barstart]').forEach(btn => btn.classList.toggle('on', btn.getAttribute('data-barstart') === start));
|
|
34238
|
+
}
|
|
34212
34239
|
}
|
|
34213
34240
|
|
|
34214
34241
|
this.realtimeVisibility(activeSection, true);
|
|
@@ -43566,6 +43593,9 @@ class ControlPanel {
|
|
|
43566
43593
|
// elmTool, whose duplicate/delete/move actions would let a user
|
|
43567
43594
|
// restructure a generated layer.
|
|
43568
43595
|
this.builder.editor.inspectedElement = overlayTarget.element;
|
|
43596
|
+
} else if (this.overlayIcon(e.target)) {
|
|
43597
|
+
// An icon in overlay text opens the Icon panel.
|
|
43598
|
+
this.builder.editor.inspectedElement = e.target;
|
|
43569
43599
|
} else {
|
|
43570
43600
|
// A plugin in the box overlay opens its own panel (Section > Box > the
|
|
43571
43601
|
// plugin), like overlay text. Its editable parts and content areas are
|
|
@@ -44154,6 +44184,8 @@ class ControlPanel {
|
|
|
44154
44184
|
if (el.closest('[data-html]')) return null; // code/module block — has its own editor
|
|
44155
44185
|
|
|
44156
44186
|
if (el.closest('[data-cb-type]')) return null; // plugin — panel-plugin owns it
|
|
44187
|
+
|
|
44188
|
+
if (this.overlayIcon(el)) return null; // icon in a text — the Icon panel owns it
|
|
44157
44189
|
// Text of an overlay layer. Resolve upward: a click can land on a
|
|
44158
44190
|
// <b>/<span> inside the region, which is not itself a region.
|
|
44159
44191
|
|
|
@@ -44394,7 +44426,7 @@ class ControlPanel {
|
|
|
44394
44426
|
activeElement = this.resolvedImage;
|
|
44395
44427
|
}
|
|
44396
44428
|
|
|
44397
|
-
if (activeElement && this.overlayTarget(activeElement)) {
|
|
44429
|
+
if (activeElement && (this.overlayTarget(activeElement) || this.overlayIcon(activeElement))) {
|
|
44398
44430
|
this.activeElement = activeElement;
|
|
44399
44431
|
this.activeColumn = null;
|
|
44400
44432
|
this.activeRow = null;
|
|
@@ -44518,7 +44550,7 @@ class ControlPanel {
|
|
|
44518
44550
|
} // Overlay content has no row/column to walk back up to.
|
|
44519
44551
|
|
|
44520
44552
|
|
|
44521
|
-
if (selection === 'element' && (this.overlayTarget(this.activeElement) || this.activeElement.closest('[data-cb-type]') && this.activeElement.closest('.is-overlay-content'))) {
|
|
44553
|
+
if (selection === 'element' && (this.overlayTarget(this.activeElement) || this.overlayIcon(this.activeElement) || this.activeElement.closest('[data-cb-type]') && this.activeElement.closest('.is-overlay-content'))) {
|
|
44522
44554
|
breadcrumbHtml = `<div>${section} ${sep} ${box} ${sep}</div>`;
|
|
44523
44555
|
}
|
|
44524
44556
|
|
|
@@ -44771,6 +44803,25 @@ class ControlPanel {
|
|
|
44771
44803
|
elm.removeAttribute('data-overlay-select');
|
|
44772
44804
|
});
|
|
44773
44805
|
if (el) el.setAttribute('data-overlay-select', '');
|
|
44806
|
+
} // A plugin placed in an overlay (eg. a header bar's Site Menu or Site Logo).
|
|
44807
|
+
// Like an overlay target it has no cell/row outline, so it gets the same mark.
|
|
44808
|
+
|
|
44809
|
+
|
|
44810
|
+
overlayPlugin(el) {
|
|
44811
|
+
if (!el || !el.closest) return null;
|
|
44812
|
+
const plugin = el.closest('[data-cb-type]');
|
|
44813
|
+
if (!plugin || !plugin.closest(this.builder.overlayEditableSelector)) return null;
|
|
44814
|
+
if (plugin.closest('.is-container')) return null;
|
|
44815
|
+
return plugin;
|
|
44816
|
+
} // An icon (<i class="bi ...">) in an overlay, eg. at the start of a chip's text. It opens the
|
|
44817
|
+
// Icon panel, so it can be changed, while a click on the words still opens the Text panel.
|
|
44818
|
+
|
|
44819
|
+
|
|
44820
|
+
overlayIcon(el) {
|
|
44821
|
+
if (!el || !el.matches || !el.matches('i.bi, i.icon') || el.innerHTML !== '') return null;
|
|
44822
|
+
if (!el.closest(this.builder.overlayEditableSelector)) return null;
|
|
44823
|
+
if (el.closest('.is-container, [data-html], [data-cb-type]')) return null;
|
|
44824
|
+
return el;
|
|
44774
44825
|
} // Is `el` (or an ancestor of it) a button?
|
|
44775
44826
|
//
|
|
44776
44827
|
// A <button> always is. An <a> is a button when it lays itself out as a
|
|
@@ -44853,7 +44904,16 @@ class ControlPanel {
|
|
|
44853
44904
|
|
|
44854
44905
|
if (what === 'element' && this.activeElement) {
|
|
44855
44906
|
const overlayNow = this.overlayTarget(this.activeElement);
|
|
44856
|
-
if (overlayNow) marked = overlayNow.element;else if (this.pictureOnlyElement(this.activeElement)) marked = this.activeElement;
|
|
44907
|
+
if (overlayNow) marked = overlayNow.element;else if (this.pictureOnlyElement(this.activeElement)) marked = this.activeElement;else marked = this.overlayPlugin(this.activeElement) || this.overlayIcon(this.activeElement);
|
|
44908
|
+
} // An overlay icon stays the editor's active icon only while it is selected; otherwise
|
|
44909
|
+
// a later icon insert would replace it.
|
|
44910
|
+
|
|
44911
|
+
|
|
44912
|
+
const activeIcon = this.builder.editor.activeIcon;
|
|
44913
|
+
|
|
44914
|
+
if (activeIcon && activeIcon !== marked && this.overlayIcon(activeIcon)) {
|
|
44915
|
+
activeIcon.classList.remove('icon-active');
|
|
44916
|
+
this.builder.editor.activeIcon = null;
|
|
44857
44917
|
}
|
|
44858
44918
|
|
|
44859
44919
|
this.markOverlaySelection(marked);
|
|
@@ -45004,6 +45064,9 @@ class ControlPanel {
|
|
|
45004
45064
|
this.panelIframe.classList.add('active');
|
|
45005
45065
|
this.objPanelIframe.getState();
|
|
45006
45066
|
} else if (element.tagName.toLowerCase() === 'i' && (element.classList.contains('icon') || element.classList.contains('bi'))) {
|
|
45067
|
+
// In a container ContentBuilder's click makes it the active icon; an overlay
|
|
45068
|
+
// icon gets no such click, so name it here (Change icon replaces this one).
|
|
45069
|
+
if (this.overlayIcon(element)) this.builder.editor.activeIcon = element;
|
|
45007
45070
|
let titleHtml = out('Icon');
|
|
45008
45071
|
this.title.innerHTML = titleHtml;
|
|
45009
45072
|
this.panelIcon.classList.add('active');
|
|
@@ -45136,8 +45199,10 @@ class ControlPanel {
|
|
|
45136
45199
|
// should animate exposes that as its own setting.
|
|
45137
45200
|
|
|
45138
45201
|
|
|
45139
|
-
const isPlugin = what === 'element' && !!pluginOf(this.activeElement);
|
|
45140
|
-
|
|
45202
|
+
const isPlugin = what === 'element' && !!pluginOf(this.activeElement); // An icon in overlay text moves with its line; only the line has Motion.
|
|
45203
|
+
|
|
45204
|
+
const isOverlayIcon = what === 'element' && !!this.overlayIcon(this.activeElement);
|
|
45205
|
+
const canMotion = !isPlugin && !isOverlayIcon && (what === 'element' || what === 'column' || what === 'row' || what === 'container' || what === 'block' || what === 'box' || what === 'section');
|
|
45141
45206
|
|
|
45142
45207
|
if (canMotion) {
|
|
45143
45208
|
if (this.tab === 'motion') {
|
|
@@ -176896,6 +176961,9 @@ Add an image for each feature.`, 'Create a new block showcasing a photo gallery
|
|
|
176896
176961
|
}
|
|
176897
176962
|
|
|
176898
176963
|
i.bi, i.icon { display: inline-flex; }
|
|
176964
|
+
/* As a flex box an icon ignores Bootstrap Icons' own vertical-align (on its ::before) and
|
|
176965
|
+
sits higher than the text beside it. Put the same offset on the icon itself. */
|
|
176966
|
+
i.bi { vertical-align: -.125em; }
|
|
176899
176967
|
|
|
176900
176968
|
</style>`); // i.bi, i.icon { display: inline-flex; } => this makes icons more cursor friendly
|
|
176901
176969
|
|