tinymce-rails 8.3.2 → 8.4.0
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.
- checksums.yaml +4 -4
- data/app/assets/source/tinymce/tinymce.js +222 -122
- data/lib/tinymce/rails/version.rb +2 -2
- data/vendor/assets/javascripts/tinymce/icons/default/icons.js +1 -1
- data/vendor/assets/javascripts/tinymce/models/dom/model.js +1 -1
- data/vendor/assets/javascripts/tinymce/notices.txt +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/accordion/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/advlist/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/anchor/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/autolink/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/autoresize/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/autosave/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/charmap/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/code/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/codesample/plugin.js +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/directionality/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/emoticons/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/fullscreen/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/help/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/image/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/importcss/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/insertdatetime/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/link/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/lists/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/media/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/nonbreaking/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/pagebreak/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/preview/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/quickbars/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/save/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/searchreplace/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/table/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/visualblocks/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/visualchars/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/wordcount/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.inline.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.inline.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.inline.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/themes/silver/theme.js +1 -1
- data/vendor/assets/javascripts/tinymce/tinymce.d.ts +6 -0
- data/vendor/assets/javascripts/tinymce/tinymce.js +3 -3
- metadata +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* TinyMCE version 8.
|
|
2
|
+
* TinyMCE version 8.4.0 (2026-03-31)
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
(function () {
|
|
@@ -3467,7 +3467,7 @@
|
|
|
3467
3467
|
const isDetails = matchNodeName$1('details');
|
|
3468
3468
|
const isSummary$1 = matchNodeName$1('summary');
|
|
3469
3469
|
const ucVideoNodeName = 'uc-video';
|
|
3470
|
-
const isUcVideo = (
|
|
3470
|
+
const isUcVideo = matchNodeName$1(ucVideoNodeName);
|
|
3471
3471
|
|
|
3472
3472
|
const defaultOptionValues = {
|
|
3473
3473
|
skipBogus: true,
|
|
@@ -5630,7 +5630,9 @@
|
|
|
5630
5630
|
compress('border', '-style');
|
|
5631
5631
|
compress('padding', '');
|
|
5632
5632
|
compress('margin', '');
|
|
5633
|
-
|
|
5633
|
+
if (!/(#.* rgb(a?)\(.*)|(rgb(a?)\(.*\) )/.test(styles['border-color'])) {
|
|
5634
|
+
compress2('border', 'border-width', 'border-style', 'border-color');
|
|
5635
|
+
}
|
|
5634
5636
|
// Remove pointless border, IE produces these
|
|
5635
5637
|
if (styles.border === 'medium none') {
|
|
5636
5638
|
delete styles.border;
|
|
@@ -5705,7 +5707,8 @@
|
|
|
5705
5707
|
webkitMovementX: true,
|
|
5706
5708
|
webkitMovementY: true,
|
|
5707
5709
|
keyIdentifier: true,
|
|
5708
|
-
mozPressure: true
|
|
5710
|
+
mozPressure: true,
|
|
5711
|
+
mozInputSource: true,
|
|
5709
5712
|
};
|
|
5710
5713
|
// Note: We can't rely on `instanceof` here as it won't work if the event was fired from another window.
|
|
5711
5714
|
// Additionally, the constructor name might be `MouseEvent` or similar so we can't rely on the constructor name.
|
|
@@ -10605,6 +10608,10 @@
|
|
|
10605
10608
|
},
|
|
10606
10609
|
default: (_ctx) => []
|
|
10607
10610
|
});
|
|
10611
|
+
registerOption('allow_noneditable', {
|
|
10612
|
+
processor: 'boolean',
|
|
10613
|
+
default: true
|
|
10614
|
+
});
|
|
10608
10615
|
registerOption('noneditable_class', {
|
|
10609
10616
|
processor: 'string',
|
|
10610
10617
|
default: 'mceNonEditable'
|
|
@@ -10688,6 +10695,9 @@
|
|
|
10688
10695
|
processor: 'string',
|
|
10689
10696
|
default: 'Anonymous'
|
|
10690
10697
|
});
|
|
10698
|
+
registerOption('content_id', {
|
|
10699
|
+
processor: 'string',
|
|
10700
|
+
});
|
|
10691
10701
|
registerOption('fetch_users', {
|
|
10692
10702
|
processor: (value) => {
|
|
10693
10703
|
if (value === undefined) {
|
|
@@ -10837,6 +10847,7 @@
|
|
|
10837
10847
|
const shouldAllowHtmlDataUrls = option('allow_html_data_urls');
|
|
10838
10848
|
const getTextPatterns = option('text_patterns');
|
|
10839
10849
|
const getTextPatternsLookup = option('text_patterns_lookup');
|
|
10850
|
+
const shouldAllowNonEditable = option('allow_noneditable');
|
|
10840
10851
|
const getNonEditableClass = option('noneditable_class');
|
|
10841
10852
|
const getEditableClass = option('editable_class');
|
|
10842
10853
|
const getNonEditableRegExps = option('noneditable_regexp');
|
|
@@ -18468,7 +18479,7 @@
|
|
|
18468
18479
|
}
|
|
18469
18480
|
};
|
|
18470
18481
|
|
|
18471
|
-
/*! @license DOMPurify 3.2
|
|
18482
|
+
/*! @license DOMPurify 3.3.2 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.2/LICENSE */
|
|
18472
18483
|
|
|
18473
18484
|
const {
|
|
18474
18485
|
entries,
|
|
@@ -18497,12 +18508,18 @@
|
|
|
18497
18508
|
};
|
|
18498
18509
|
}
|
|
18499
18510
|
if (!apply) {
|
|
18500
|
-
apply = function apply(
|
|
18501
|
-
|
|
18511
|
+
apply = function apply(func, thisArg) {
|
|
18512
|
+
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
18513
|
+
args[_key - 2] = arguments[_key];
|
|
18514
|
+
}
|
|
18515
|
+
return func.apply(thisArg, args);
|
|
18502
18516
|
};
|
|
18503
18517
|
}
|
|
18504
18518
|
if (!construct) {
|
|
18505
|
-
construct = function construct(Func
|
|
18519
|
+
construct = function construct(Func) {
|
|
18520
|
+
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
18521
|
+
args[_key2 - 1] = arguments[_key2];
|
|
18522
|
+
}
|
|
18506
18523
|
return new Func(...args);
|
|
18507
18524
|
};
|
|
18508
18525
|
}
|
|
@@ -18531,8 +18548,8 @@
|
|
|
18531
18548
|
if (thisArg instanceof RegExp) {
|
|
18532
18549
|
thisArg.lastIndex = 0;
|
|
18533
18550
|
}
|
|
18534
|
-
for (var
|
|
18535
|
-
args[
|
|
18551
|
+
for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
|
|
18552
|
+
args[_key3 - 1] = arguments[_key3];
|
|
18536
18553
|
}
|
|
18537
18554
|
return apply(func, thisArg, args);
|
|
18538
18555
|
};
|
|
@@ -18543,12 +18560,12 @@
|
|
|
18543
18560
|
* @param func - The constructor function to be wrapped and called.
|
|
18544
18561
|
* @returns A new function that constructs an instance of the given constructor function with the provided arguments.
|
|
18545
18562
|
*/
|
|
18546
|
-
function unconstruct(
|
|
18563
|
+
function unconstruct(Func) {
|
|
18547
18564
|
return function () {
|
|
18548
|
-
for (var
|
|
18549
|
-
args[
|
|
18565
|
+
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
18566
|
+
args[_key4] = arguments[_key4];
|
|
18550
18567
|
}
|
|
18551
|
-
return construct(
|
|
18568
|
+
return construct(Func, args);
|
|
18552
18569
|
};
|
|
18553
18570
|
}
|
|
18554
18571
|
/**
|
|
@@ -18647,8 +18664,8 @@
|
|
|
18647
18664
|
return fallbackValue;
|
|
18648
18665
|
}
|
|
18649
18666
|
|
|
18650
|
-
const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
|
|
18651
|
-
const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
|
|
18667
|
+
const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'search', 'section', 'select', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
|
|
18668
|
+
const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'enterkeyhint', 'exportparts', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'inputmode', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'part', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
|
|
18652
18669
|
const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
|
|
18653
18670
|
// List of SVG elements that are disallowed by default.
|
|
18654
18671
|
// We still need to know them so that we can do namespace
|
|
@@ -18661,8 +18678,8 @@
|
|
|
18661
18678
|
const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
|
|
18662
18679
|
const text = freeze(['#text']);
|
|
18663
18680
|
|
|
18664
|
-
const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);
|
|
18665
|
-
const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
|
|
18681
|
+
const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);
|
|
18682
|
+
const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'mask-type', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
|
|
18666
18683
|
const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
|
|
18667
18684
|
const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
18668
18685
|
|
|
@@ -18769,7 +18786,7 @@
|
|
|
18769
18786
|
function createDOMPurify() {
|
|
18770
18787
|
let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
18771
18788
|
const DOMPurify = root => createDOMPurify(root);
|
|
18772
|
-
DOMPurify.version = '3.2
|
|
18789
|
+
DOMPurify.version = '3.3.2';
|
|
18773
18790
|
DOMPurify.removed = [];
|
|
18774
18791
|
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
|
|
18775
18792
|
// Not running in a browser, provide a factory function
|
|
@@ -18880,6 +18897,21 @@
|
|
|
18880
18897
|
let FORBID_TAGS = null;
|
|
18881
18898
|
/* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
|
|
18882
18899
|
let FORBID_ATTR = null;
|
|
18900
|
+
/* Config object to store ADD_TAGS/ADD_ATTR functions (when used as functions) */
|
|
18901
|
+
const EXTRA_ELEMENT_HANDLING = Object.seal(create$7(null, {
|
|
18902
|
+
tagCheck: {
|
|
18903
|
+
writable: true,
|
|
18904
|
+
configurable: false,
|
|
18905
|
+
enumerable: true,
|
|
18906
|
+
value: null
|
|
18907
|
+
},
|
|
18908
|
+
attributeCheck: {
|
|
18909
|
+
writable: true,
|
|
18910
|
+
configurable: false,
|
|
18911
|
+
enumerable: true,
|
|
18912
|
+
value: null
|
|
18913
|
+
}
|
|
18914
|
+
}));
|
|
18883
18915
|
/* Decide if ARIA attributes are okay */
|
|
18884
18916
|
let ALLOW_ARIA_ATTR = true;
|
|
18885
18917
|
/* Decide if custom data attributes are okay */
|
|
@@ -19049,7 +19081,7 @@
|
|
|
19049
19081
|
/* Parse profile info */
|
|
19050
19082
|
if (USE_PROFILES) {
|
|
19051
19083
|
ALLOWED_TAGS = addToSet({}, text);
|
|
19052
|
-
ALLOWED_ATTR =
|
|
19084
|
+
ALLOWED_ATTR = create$7(null);
|
|
19053
19085
|
if (USE_PROFILES.html === true) {
|
|
19054
19086
|
addToSet(ALLOWED_TAGS, html$1);
|
|
19055
19087
|
addToSet(ALLOWED_ATTR, html);
|
|
@@ -19070,18 +19102,33 @@
|
|
|
19070
19102
|
addToSet(ALLOWED_ATTR, xml);
|
|
19071
19103
|
}
|
|
19072
19104
|
}
|
|
19105
|
+
/* Prevent function-based ADD_ATTR / ADD_TAGS from leaking across calls */
|
|
19106
|
+
if (!objectHasOwnProperty(cfg, 'ADD_TAGS')) {
|
|
19107
|
+
EXTRA_ELEMENT_HANDLING.tagCheck = null;
|
|
19108
|
+
}
|
|
19109
|
+
if (!objectHasOwnProperty(cfg, 'ADD_ATTR')) {
|
|
19110
|
+
EXTRA_ELEMENT_HANDLING.attributeCheck = null;
|
|
19111
|
+
}
|
|
19073
19112
|
/* Merge configuration parameters */
|
|
19074
19113
|
if (cfg.ADD_TAGS) {
|
|
19075
|
-
if (
|
|
19076
|
-
|
|
19114
|
+
if (typeof cfg.ADD_TAGS === 'function') {
|
|
19115
|
+
EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
|
|
19116
|
+
} else {
|
|
19117
|
+
if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
|
|
19118
|
+
ALLOWED_TAGS = clone(ALLOWED_TAGS);
|
|
19119
|
+
}
|
|
19120
|
+
addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
|
|
19077
19121
|
}
|
|
19078
|
-
addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
|
|
19079
19122
|
}
|
|
19080
19123
|
if (cfg.ADD_ATTR) {
|
|
19081
|
-
if (
|
|
19082
|
-
|
|
19124
|
+
if (typeof cfg.ADD_ATTR === 'function') {
|
|
19125
|
+
EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
|
|
19126
|
+
} else {
|
|
19127
|
+
if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
|
|
19128
|
+
ALLOWED_ATTR = clone(ALLOWED_ATTR);
|
|
19129
|
+
}
|
|
19130
|
+
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
|
|
19083
19131
|
}
|
|
19084
|
-
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
|
|
19085
19132
|
}
|
|
19086
19133
|
if (cfg.ADD_URI_SAFE_ATTR) {
|
|
19087
19134
|
addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
|
|
@@ -19092,6 +19139,12 @@
|
|
|
19092
19139
|
}
|
|
19093
19140
|
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
|
|
19094
19141
|
}
|
|
19142
|
+
if (cfg.ADD_FORBID_CONTENTS) {
|
|
19143
|
+
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
|
|
19144
|
+
FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
19145
|
+
}
|
|
19146
|
+
addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
|
|
19147
|
+
}
|
|
19095
19148
|
/* Add #text in case KEEP_CONTENT is set to true */
|
|
19096
19149
|
if (KEEP_CONTENT) {
|
|
19097
19150
|
ALLOWED_TAGS['#text'] = true;
|
|
@@ -19389,7 +19442,7 @@
|
|
|
19389
19442
|
return true;
|
|
19390
19443
|
}
|
|
19391
19444
|
/* Remove element if anything forbids its presence */
|
|
19392
|
-
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
19445
|
+
if (!(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName])) {
|
|
19393
19446
|
/* Check if we have a custom element to handle */
|
|
19394
19447
|
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
|
|
19395
19448
|
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
|
|
@@ -19453,6 +19506,10 @@
|
|
|
19453
19506
|
*/
|
|
19454
19507
|
// eslint-disable-next-line complexity
|
|
19455
19508
|
const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
|
19509
|
+
/* FORBID_ATTR must always win, even if ADD_ATTR predicate would allow it */
|
|
19510
|
+
if (FORBID_ATTR[lcName]) {
|
|
19511
|
+
return false;
|
|
19512
|
+
}
|
|
19456
19513
|
/* Make sure attribute cannot clobber */
|
|
19457
19514
|
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
|
19458
19515
|
return false;
|
|
@@ -19461,12 +19518,12 @@
|
|
|
19461
19518
|
(https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
|
|
19462
19519
|
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
19463
19520
|
We don't need to check the value; it's always URI safe. */
|
|
19464
|
-
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
19521
|
+
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
19465
19522
|
if (
|
|
19466
19523
|
// First condition does a very basic check if a) it's basically a valid custom element tagname AND
|
|
19467
19524
|
// b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
19468
19525
|
// and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
|
|
19469
|
-
_isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) ||
|
|
19526
|
+
_isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) ||
|
|
19470
19527
|
// Alternative, second condition checks if it's an `is`-attribute, AND
|
|
19471
19528
|
// the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
19472
19529
|
lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {
|
|
@@ -19545,7 +19602,12 @@
|
|
|
19545
19602
|
value = SANITIZE_NAMED_PROPS_PREFIX + value;
|
|
19546
19603
|
}
|
|
19547
19604
|
/* Work around a security issue with comments inside attributes */
|
|
19548
|
-
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
|
|
19605
|
+
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
|
|
19606
|
+
_removeAttribute(name, currentNode);
|
|
19607
|
+
continue;
|
|
19608
|
+
}
|
|
19609
|
+
/* Make sure we cannot easily use animated hrefs, even if animations are allowed */
|
|
19610
|
+
if (lcName === 'attributename' && stringMatch(value, 'href')) {
|
|
19549
19611
|
_removeAttribute(name, currentNode);
|
|
19550
19612
|
continue;
|
|
19551
19613
|
}
|
|
@@ -25203,8 +25265,8 @@
|
|
|
25203
25265
|
};
|
|
25204
25266
|
|
|
25205
25267
|
const isContentCssSkinName = (url) => /^[a-z0-9\-]+$/i.test(url);
|
|
25206
|
-
const toContentSkinResourceName = (
|
|
25207
|
-
const isBundledCssSkinName = (
|
|
25268
|
+
const toContentSkinResourceName = (name) => 'content/' + name + '/content.css';
|
|
25269
|
+
const isBundledCssSkinName = (name) => tinymce.Resource.has(toContentSkinResourceName(name));
|
|
25208
25270
|
const getContentCssUrls = (editor) => {
|
|
25209
25271
|
return transformToUrls(editor, getContentCss(editor));
|
|
25210
25272
|
};
|
|
@@ -25217,7 +25279,7 @@
|
|
|
25217
25279
|
const contentCssFile = `content${suffix}.css`;
|
|
25218
25280
|
return map$3(cssLinks, (url) => {
|
|
25219
25281
|
if (isBundledCssSkinName(url)) {
|
|
25220
|
-
return url;
|
|
25282
|
+
return toContentSkinResourceName(url);
|
|
25221
25283
|
}
|
|
25222
25284
|
else if (isContentCssSkinName(url) && !editor.inline) {
|
|
25223
25285
|
return `${skinUrl}/${url}/${contentCssFile}`;
|
|
@@ -25405,7 +25467,7 @@
|
|
|
25405
25467
|
}
|
|
25406
25468
|
};
|
|
25407
25469
|
const toBlobInfo = (o) => {
|
|
25408
|
-
if (
|
|
25470
|
+
if (isNullable(o.blob) || isNullable(o.base64) || (o.base64 === '' && !o.allowEmptyFile)) {
|
|
25409
25471
|
throw new Error('blob and base64 representations of the image are required for BlobInfo to be created');
|
|
25410
25472
|
}
|
|
25411
25473
|
const id = o.id || uuid('blobid');
|
|
@@ -26952,6 +27014,53 @@
|
|
|
26952
27014
|
}
|
|
26953
27015
|
};
|
|
26954
27016
|
|
|
27017
|
+
const createAndFireInputEvent = (eventType) => (editor, inputType, specifics = {}) => {
|
|
27018
|
+
const target = editor.getBody();
|
|
27019
|
+
const overrides = {
|
|
27020
|
+
bubbles: true,
|
|
27021
|
+
composed: true,
|
|
27022
|
+
data: null,
|
|
27023
|
+
isComposing: false,
|
|
27024
|
+
detail: 0,
|
|
27025
|
+
view: null,
|
|
27026
|
+
target,
|
|
27027
|
+
currentTarget: target,
|
|
27028
|
+
eventPhase: Event.AT_TARGET,
|
|
27029
|
+
originalTarget: target,
|
|
27030
|
+
explicitOriginalTarget: target,
|
|
27031
|
+
isTrusted: false,
|
|
27032
|
+
srcElement: target,
|
|
27033
|
+
cancelable: false,
|
|
27034
|
+
preventDefault: noop,
|
|
27035
|
+
inputType
|
|
27036
|
+
};
|
|
27037
|
+
const input = clone$2(new InputEvent(eventType));
|
|
27038
|
+
return editor.dispatch(eventType, { ...input, ...overrides, ...specifics });
|
|
27039
|
+
};
|
|
27040
|
+
const fireInputEvent = createAndFireInputEvent('input');
|
|
27041
|
+
const fireBeforeInputEvent = createAndFireInputEvent('beforeinput');
|
|
27042
|
+
|
|
27043
|
+
const symulateDelete = (editor, isForward, deleteFun) => {
|
|
27044
|
+
// Some delete actions may prevent the input event from being fired. If we do not detect it, we fire it ourselves.
|
|
27045
|
+
let shouldFireInput = true;
|
|
27046
|
+
const inputHandler = () => shouldFireInput = false;
|
|
27047
|
+
const beforeInputEvent = fireBeforeInputEvent(editor, isForward ? 'deleteContentForward' : 'deleteContentBackward');
|
|
27048
|
+
if (beforeInputEvent.isDefaultPrevented()) {
|
|
27049
|
+
return false;
|
|
27050
|
+
}
|
|
27051
|
+
editor.on('input', inputHandler);
|
|
27052
|
+
try {
|
|
27053
|
+
deleteFun();
|
|
27054
|
+
}
|
|
27055
|
+
finally {
|
|
27056
|
+
editor.off('input', inputHandler);
|
|
27057
|
+
}
|
|
27058
|
+
if (shouldFireInput) {
|
|
27059
|
+
editor.dispatch('input');
|
|
27060
|
+
}
|
|
27061
|
+
return true;
|
|
27062
|
+
};
|
|
27063
|
+
|
|
26955
27064
|
const matchNodeName = (name) => (node) => isNonNullable(node) && node.nodeName.toLowerCase() === name;
|
|
26956
27065
|
const matchNodeNames = (regex) => (node) => isNonNullable(node) && regex.test(node.nodeName);
|
|
26957
27066
|
const isTextNode$1 = (node) => isNonNullable(node) && node.nodeType === 3;
|
|
@@ -27049,7 +27158,7 @@
|
|
|
27049
27158
|
const listSelector = listNames.join(',');
|
|
27050
27159
|
const getParentList = (editor, node) => {
|
|
27051
27160
|
const selectionStart = node || editor.selection.getStart(true);
|
|
27052
|
-
return editor.dom.getParent(selectionStart, listSelector, getClosestListHost(editor, selectionStart));
|
|
27161
|
+
return editor.dom.getParent(selectionStart, listSelector, getClosestListHost(editor, selectionStart, editor.selection.isCollapsed()));
|
|
27053
27162
|
};
|
|
27054
27163
|
const isParentListSelected = (parentList, selectedBlocks) => isNonNullable(parentList) && selectedBlocks.length === 1 && selectedBlocks[0] === parentList;
|
|
27055
27164
|
const findSubLists = (parentList) => filter$5(parentList.querySelectorAll(listSelector), isListNode);
|
|
@@ -27065,16 +27174,16 @@
|
|
|
27065
27174
|
});
|
|
27066
27175
|
}
|
|
27067
27176
|
};
|
|
27068
|
-
const findParentListItemsNodes = (editor, elms) => {
|
|
27177
|
+
const findParentListItemsNodes = (editor, elms, isCollapsed) => {
|
|
27069
27178
|
const listItemsElms = Tools.map(elms, (elm) => {
|
|
27070
|
-
const parentLi = editor.dom.getParent(elm, 'li,dd,dt', getClosestListHost(editor, elm));
|
|
27179
|
+
const parentLi = editor.dom.getParent(elm, 'li,dd,dt', getClosestListHost(editor, elm, isCollapsed));
|
|
27071
27180
|
return parentLi ? parentLi : elm;
|
|
27072
27181
|
});
|
|
27073
27182
|
return unique$1(listItemsElms);
|
|
27074
27183
|
};
|
|
27075
27184
|
const getSelectedListItems = (editor) => {
|
|
27076
27185
|
const selectedBlocks = editor.selection.getSelectedBlocks();
|
|
27077
|
-
return filter$5(findParentListItemsNodes(editor, selectedBlocks), isListItemNode);
|
|
27186
|
+
return filter$5(findParentListItemsNodes(editor, selectedBlocks, editor.selection.isCollapsed()), isListItemNode);
|
|
27078
27187
|
};
|
|
27079
27188
|
const getSelectedDlItems = (editor) => filter$5(getSelectedListItems(editor), isDlItemNode);
|
|
27080
27189
|
const getClosestEditingHost = (editor, elm) => {
|
|
@@ -27082,17 +27191,17 @@
|
|
|
27082
27191
|
return parentTableCell.length > 0 ? parentTableCell[0] : editor.getBody();
|
|
27083
27192
|
};
|
|
27084
27193
|
const isListHost = (schema, node) => !isListNode(node) && !isListItemNode(node) && exists(listNames, (listName) => schema.isValidChild(node.nodeName, listName));
|
|
27085
|
-
const getClosestListHost = (editor, elm) => {
|
|
27194
|
+
const getClosestListHost = (editor, elm, isCollapsed) => {
|
|
27086
27195
|
const parentBlocks = editor.dom.getParents(elm, editor.dom.isBlock);
|
|
27087
27196
|
const isNotForcedRootBlock = (elm) => elm.nodeName.toLowerCase() !== getForcedRootBlock(editor);
|
|
27088
|
-
const parentBlock = find$2(parentBlocks, (elm) => isNotForcedRootBlock(elm) && isListHost(editor.schema, elm));
|
|
27197
|
+
const parentBlock = find$2(parentBlocks, (elm) => (!isCollapsed || isNotForcedRootBlock(elm)) && isListHost(editor.schema, elm));
|
|
27089
27198
|
return parentBlock.getOr(editor.getBody());
|
|
27090
27199
|
};
|
|
27091
27200
|
const isListInsideAnLiWithFirstAndLastNotListElement = (list) => parent(list).exists((parent) => isListItemNode(parent.dom)
|
|
27092
27201
|
&& firstChild(parent).exists((firstChild) => !isListNode(firstChild.dom))
|
|
27093
27202
|
&& lastChild(parent).exists((lastChild) => !isListNode(lastChild.dom)));
|
|
27094
27203
|
const findLastParentListNode = (editor, elm) => {
|
|
27095
|
-
const parentLists = editor.dom.getParents(elm, 'ol,ul', getClosestListHost(editor, elm));
|
|
27204
|
+
const parentLists = editor.dom.getParents(elm, 'ol,ul', getClosestListHost(editor, elm, true));
|
|
27096
27205
|
return last$2(parentLists);
|
|
27097
27206
|
};
|
|
27098
27207
|
const getSelectedLists = (editor) => {
|
|
@@ -27102,7 +27211,7 @@
|
|
|
27102
27211
|
};
|
|
27103
27212
|
const getParentLists = (editor) => {
|
|
27104
27213
|
const elm = editor.selection.getStart();
|
|
27105
|
-
return editor.dom.getParents(elm, 'ol,ul', getClosestListHost(editor, elm));
|
|
27214
|
+
return editor.dom.getParents(elm, 'ol,ul', getClosestListHost(editor, elm, editor.selection.isCollapsed()));
|
|
27106
27215
|
};
|
|
27107
27216
|
const getSelectedListRoots = (editor) => {
|
|
27108
27217
|
const selectedLists = getSelectedLists(editor);
|
|
@@ -27715,7 +27824,7 @@
|
|
|
27715
27824
|
const applyList = (editor, listName, detail) => {
|
|
27716
27825
|
const rng = editor.selection.getRng();
|
|
27717
27826
|
let listItemName = 'LI';
|
|
27718
|
-
const root = getClosestListHost(editor, getRootSearchStart(editor, rng));
|
|
27827
|
+
const root = getClosestListHost(editor, getRootSearchStart(editor, rng), rng.collapsed);
|
|
27719
27828
|
const dom = editor.dom;
|
|
27720
27829
|
if (dom.getContentEditable(editor.selection.getNode()) === 'false') {
|
|
27721
27830
|
return;
|
|
@@ -28095,19 +28204,12 @@
|
|
|
28095
28204
|
const startListParent = editor.dom.getParent(selectionStartElm, 'LI,DT,DD', root);
|
|
28096
28205
|
return isNonNullable(startListParent) || getSelectedListItems(editor).length > 0;
|
|
28097
28206
|
};
|
|
28098
|
-
const backspaceDeleteRange$1 = (editor) => {
|
|
28207
|
+
const backspaceDeleteRange$1 = (editor, isForward) => {
|
|
28099
28208
|
if (hasListSelection(editor)) {
|
|
28100
28209
|
editor.undoManager.transact(() => {
|
|
28101
|
-
|
|
28102
|
-
|
|
28103
|
-
const inputHandler = () => shouldFireInput = false;
|
|
28104
|
-
editor.on('input', inputHandler);
|
|
28105
|
-
editor.execCommand('Delete');
|
|
28106
|
-
editor.off('input', inputHandler);
|
|
28107
|
-
if (shouldFireInput) {
|
|
28108
|
-
editor.dispatch('input');
|
|
28210
|
+
if (symulateDelete(editor, isForward, () => editor.execCommand('Delete'))) {
|
|
28211
|
+
normalizeLists(editor.dom, editor.getBody());
|
|
28109
28212
|
}
|
|
28110
|
-
normalizeLists(editor.dom, editor.getBody());
|
|
28111
28213
|
});
|
|
28112
28214
|
return true;
|
|
28113
28215
|
}
|
|
@@ -28116,7 +28218,7 @@
|
|
|
28116
28218
|
const backspaceDelete$c = (editor, isForward) => {
|
|
28117
28219
|
const selection = editor.selection;
|
|
28118
28220
|
return !isWithinNonEditableList$1(editor, selection.getNode()) && (selection.isCollapsed() ?
|
|
28119
|
-
backspaceDeleteCaret$1(editor, isForward) : backspaceDeleteRange$1(editor));
|
|
28221
|
+
backspaceDeleteCaret$1(editor, isForward) : backspaceDeleteRange$1(editor, isForward));
|
|
28120
28222
|
};
|
|
28121
28223
|
|
|
28122
28224
|
const blockPosition = (block, position) => ({
|
|
@@ -31449,32 +31551,6 @@
|
|
|
31449
31551
|
const backspaceDelete = (editor, forward, granularity) => shouldPreventDeleteAction(editor, forward, granularity) || isSafari && handleDeleteActionSafari(editor, forward, granularity)
|
|
31450
31552
|
? Optional.some(noop) : Optional.none();
|
|
31451
31553
|
|
|
31452
|
-
const createAndFireInputEvent = (eventType) => (editor, inputType, specifics = {}) => {
|
|
31453
|
-
const target = editor.getBody();
|
|
31454
|
-
const overrides = {
|
|
31455
|
-
bubbles: true,
|
|
31456
|
-
composed: true,
|
|
31457
|
-
data: null,
|
|
31458
|
-
isComposing: false,
|
|
31459
|
-
detail: 0,
|
|
31460
|
-
view: null,
|
|
31461
|
-
target,
|
|
31462
|
-
currentTarget: target,
|
|
31463
|
-
eventPhase: Event.AT_TARGET,
|
|
31464
|
-
originalTarget: target,
|
|
31465
|
-
explicitOriginalTarget: target,
|
|
31466
|
-
isTrusted: false,
|
|
31467
|
-
srcElement: target,
|
|
31468
|
-
cancelable: false,
|
|
31469
|
-
preventDefault: noop,
|
|
31470
|
-
inputType
|
|
31471
|
-
};
|
|
31472
|
-
const input = clone$2(new InputEvent(eventType));
|
|
31473
|
-
return editor.dispatch(eventType, { ...input, ...overrides, ...specifics });
|
|
31474
|
-
};
|
|
31475
|
-
const fireInputEvent = createAndFireInputEvent('input');
|
|
31476
|
-
const fireBeforeInputEvent = createAndFireInputEvent('beforeinput');
|
|
31477
|
-
|
|
31478
31554
|
const platform$2 = detect$1();
|
|
31479
31555
|
const os = platform$2.os;
|
|
31480
31556
|
const isMacOSOriOS = os.isMacOS() || os.isiOS();
|
|
@@ -31563,19 +31639,21 @@
|
|
|
31563
31639
|
// track backspace keydown state for emulating Meta + Backspace keyup detection on macOS
|
|
31564
31640
|
let isBackspaceKeydown = false;
|
|
31565
31641
|
let formatNodes = [];
|
|
31566
|
-
editor.on('
|
|
31567
|
-
|
|
31568
|
-
|
|
31569
|
-
|
|
31570
|
-
|
|
31571
|
-
|
|
31572
|
-
|
|
31573
|
-
|
|
31574
|
-
|
|
31575
|
-
|
|
31576
|
-
|
|
31577
|
-
|
|
31578
|
-
|
|
31642
|
+
editor.on('init', () => {
|
|
31643
|
+
editor.on('keydown', (evt) => {
|
|
31644
|
+
isBackspaceKeydown = evt.keyCode === VK.BACKSPACE;
|
|
31645
|
+
formatNodes = getFormatNodesAtStart(editor);
|
|
31646
|
+
if (!evt.isDefaultPrevented()) {
|
|
31647
|
+
executeKeydownOverride$3(editor, caret, evt);
|
|
31648
|
+
}
|
|
31649
|
+
});
|
|
31650
|
+
editor.on('keyup', (evt) => {
|
|
31651
|
+
if (!evt.isDefaultPrevented()) {
|
|
31652
|
+
executeKeyupOverride(editor, evt, isBackspaceKeydown, formatNodes);
|
|
31653
|
+
formatNodes.length = 0;
|
|
31654
|
+
}
|
|
31655
|
+
isBackspaceKeydown = false;
|
|
31656
|
+
});
|
|
31579
31657
|
});
|
|
31580
31658
|
};
|
|
31581
31659
|
|
|
@@ -31613,16 +31691,15 @@
|
|
|
31613
31691
|
if (!root) {
|
|
31614
31692
|
return;
|
|
31615
31693
|
}
|
|
31616
|
-
if (
|
|
31617
|
-
const
|
|
31618
|
-
const findFirstList = (e) => isList(e) ? Optional.from(e) : descendant$2(e, isList);
|
|
31694
|
+
if (isListItem$2(SugarElement.fromDom(root))) {
|
|
31695
|
+
const findFirstList = (e) => isList$1(e) ? Optional.from(e) : descendant$2(e, isList$1);
|
|
31619
31696
|
const isEmpty = (e) => dom.isEmpty(e.dom);
|
|
31620
31697
|
firstNonWhiteSpaceNodeSibling(root.firstChild).each((firstChild) => {
|
|
31621
31698
|
findFirstList(firstChild).fold(() => {
|
|
31622
31699
|
if (isEmpty(firstChild)) {
|
|
31623
31700
|
const element = toLeaf$1(firstChild, 0).element;
|
|
31624
31701
|
if (isElement$8(element) && !isBr$6(element)) {
|
|
31625
|
-
append$1(element, SugarElement.
|
|
31702
|
+
append$1(element, SugarElement.fromHtml('<br data-mce-bogus="1" />'));
|
|
31626
31703
|
}
|
|
31627
31704
|
}
|
|
31628
31705
|
}, (firstList) => {
|
|
@@ -32154,6 +32231,16 @@
|
|
|
32154
32231
|
}
|
|
32155
32232
|
return true;
|
|
32156
32233
|
};
|
|
32234
|
+
const isInsideLiBeforeAList = (newBlock) => {
|
|
32235
|
+
const nextSibling$1 = firstChild(newBlock).bind(nextSibling);
|
|
32236
|
+
return isListItem$2(newBlock) && nextSibling$1.exists(isList$1);
|
|
32237
|
+
};
|
|
32238
|
+
const trimEmptySpacesInLeftLeaf = (newBlock) => {
|
|
32239
|
+
const leaf = toLeaf$1(SugarElement.fromDom(newBlock), 0).element;
|
|
32240
|
+
if (isText$c(leaf) && dom.isEmpty(leaf.dom)) {
|
|
32241
|
+
leaf.dom.remove();
|
|
32242
|
+
}
|
|
32243
|
+
};
|
|
32157
32244
|
const insertNewBlockAfter = () => {
|
|
32158
32245
|
let block;
|
|
32159
32246
|
// If the caret is at the end of a header we produce a P tag after it similar to Word unless we are in a hgroup
|
|
@@ -32289,8 +32376,13 @@
|
|
|
32289
32376
|
else {
|
|
32290
32377
|
dom.insertAfter(fragment, parentBlock);
|
|
32291
32378
|
}
|
|
32292
|
-
|
|
32293
|
-
|
|
32379
|
+
if (!isInsideLiBeforeAList(SugarElement.fromDom(newBlock))) {
|
|
32380
|
+
trimInlineElementsOnLeftSideOfBlock(dom, nonEmptyElementsMap, newBlock);
|
|
32381
|
+
addBrToBlockIfNeeded(dom, parentBlock);
|
|
32382
|
+
}
|
|
32383
|
+
else {
|
|
32384
|
+
trimEmptySpacesInLeftLeaf(newBlock);
|
|
32385
|
+
}
|
|
32294
32386
|
if (dom.isEmpty(parentBlock)) {
|
|
32295
32387
|
emptyBlock(parentBlock);
|
|
32296
32388
|
}
|
|
@@ -32910,17 +33002,23 @@
|
|
|
32910
33002
|
};
|
|
32911
33003
|
|
|
32912
33004
|
const setup$e = (editor) => {
|
|
32913
|
-
editor.on('
|
|
32914
|
-
|
|
32915
|
-
|
|
32916
|
-
|
|
33005
|
+
editor.on('init', () => {
|
|
33006
|
+
// Init is done after the editor's setup. This places our keydown after any keydowns registered in the setup function, so they can do default prevent.
|
|
33007
|
+
editor.on('keydown', (e) => {
|
|
33008
|
+
if (e.defaultPrevented) {
|
|
33009
|
+
return;
|
|
32917
33010
|
}
|
|
32918
|
-
|
|
32919
|
-
|
|
32920
|
-
|
|
32921
|
-
|
|
33011
|
+
if (e.keyCode === VK.BACKSPACE) {
|
|
33012
|
+
if (backspaceDelete$c(editor, false)) {
|
|
33013
|
+
e.preventDefault();
|
|
33014
|
+
}
|
|
32922
33015
|
}
|
|
32923
|
-
|
|
33016
|
+
else if (e.keyCode === VK.DELETE) {
|
|
33017
|
+
if (backspaceDelete$c(editor, true)) {
|
|
33018
|
+
e.preventDefault();
|
|
33019
|
+
}
|
|
33020
|
+
}
|
|
33021
|
+
});
|
|
32924
33022
|
});
|
|
32925
33023
|
};
|
|
32926
33024
|
|
|
@@ -35780,14 +35878,14 @@
|
|
|
35780
35878
|
}
|
|
35781
35879
|
// Manually empty the editor
|
|
35782
35880
|
e.preventDefault();
|
|
35783
|
-
editor.setContent('')
|
|
35784
|
-
|
|
35785
|
-
|
|
35786
|
-
|
|
35787
|
-
|
|
35788
|
-
|
|
35881
|
+
if (symulateDelete(editor, keyCode === DELETE, () => editor.setContent(''))) {
|
|
35882
|
+
if (body.firstChild && dom.isBlock(body.firstChild)) {
|
|
35883
|
+
editor.selection.setCursorLocation(body.firstChild, 0);
|
|
35884
|
+
}
|
|
35885
|
+
else {
|
|
35886
|
+
editor.selection.setCursorLocation(body, 0);
|
|
35887
|
+
}
|
|
35789
35888
|
}
|
|
35790
|
-
editor.nodeChanged();
|
|
35791
35889
|
}
|
|
35792
35890
|
});
|
|
35793
35891
|
};
|
|
@@ -36689,11 +36787,11 @@
|
|
|
36689
36787
|
};
|
|
36690
36788
|
const getStyleSheetLoader$1 = (editor) => editor.inline ? editor.ui.styleSheetLoader : editor.dom.styleSheetLoader;
|
|
36691
36789
|
const makeStylesheetLoadingPromises = (editor, css, framedFonts) => {
|
|
36692
|
-
const { pass: bundledCss, fail: normalCss } = partition$2(css, (
|
|
36693
|
-
const bundledPromises = bundledCss.map((
|
|
36694
|
-
const css = tinymce.Resource.get(
|
|
36790
|
+
const { pass: bundledCss, fail: normalCss } = partition$2(css, (key) => tinymce.Resource.has(key));
|
|
36791
|
+
const bundledPromises = bundledCss.map((key) => {
|
|
36792
|
+
const css = tinymce.Resource.get(key);
|
|
36695
36793
|
if (isString(css)) {
|
|
36696
|
-
return Promise.resolve(getStyleSheetLoader$1(editor).loadRawCss(
|
|
36794
|
+
return Promise.resolve(getStyleSheetLoader$1(editor).loadRawCss(key, css));
|
|
36697
36795
|
}
|
|
36698
36796
|
return Promise.resolve();
|
|
36699
36797
|
});
|
|
@@ -36853,7 +36951,9 @@
|
|
|
36853
36951
|
setup$b(editor);
|
|
36854
36952
|
setup$u(editor);
|
|
36855
36953
|
setup$6(editor);
|
|
36856
|
-
|
|
36954
|
+
if (shouldAllowNonEditable(editor)) {
|
|
36955
|
+
setup$s(editor);
|
|
36956
|
+
}
|
|
36857
36957
|
if (!isRtc(editor)) {
|
|
36858
36958
|
setup$5(editor);
|
|
36859
36959
|
setup$1(editor);
|
|
@@ -40581,14 +40681,14 @@
|
|
|
40581
40681
|
* @property minorVersion
|
|
40582
40682
|
* @type String
|
|
40583
40683
|
*/
|
|
40584
|
-
minorVersion: '
|
|
40684
|
+
minorVersion: '4.0',
|
|
40585
40685
|
/**
|
|
40586
40686
|
* Release date of TinyMCE build.
|
|
40587
40687
|
*
|
|
40588
40688
|
* @property releaseDate
|
|
40589
40689
|
* @type String
|
|
40590
40690
|
*/
|
|
40591
|
-
releaseDate: '2026-
|
|
40691
|
+
releaseDate: '2026-03-31',
|
|
40592
40692
|
/**
|
|
40593
40693
|
* Collection of language pack data.
|
|
40594
40694
|
*
|