tinymce-rails 8.1.2 → 8.2.1
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 +686 -450
- data/lib/tinymce/rails/version.rb +2 -2
- data/vendor/assets/javascripts/tinymce/models/dom/model.js +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/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/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/preview/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/quickbars/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/visualchars/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 +5 -2
- data/vendor/assets/javascripts/tinymce/tinymce.js +2 -2
- metadata +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* TinyMCE version 8.1
|
|
2
|
+
* TinyMCE version 8.2.1 (2025-11-06)
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
(function () {
|
|
@@ -93,13 +93,12 @@
|
|
|
93
93
|
/* eslint-disable @typescript-eslint/no-wrapper-object-types */
|
|
94
94
|
const getPrototypeOf$2 = Object.getPrototypeOf;
|
|
95
95
|
const hasProto = (v, constructor, predicate) => {
|
|
96
|
-
var _a;
|
|
97
96
|
if (predicate(v, constructor.prototype)) {
|
|
98
97
|
return true;
|
|
99
98
|
}
|
|
100
99
|
else {
|
|
101
100
|
// String-based fallback time
|
|
102
|
-
return
|
|
101
|
+
return v.constructor?.name === constructor.name;
|
|
103
102
|
}
|
|
104
103
|
};
|
|
105
104
|
const typeOf = (x) => {
|
|
@@ -201,6 +200,11 @@
|
|
|
201
200
|
* strict-null-checks
|
|
202
201
|
*/
|
|
203
202
|
class Optional {
|
|
203
|
+
tag;
|
|
204
|
+
value;
|
|
205
|
+
// Sneaky optimisation: every instance of Optional.none is identical, so just
|
|
206
|
+
// reuse the same object
|
|
207
|
+
static singletonNone = new Optional(false);
|
|
204
208
|
// The internal representation has a `tag` and a `value`, but both are
|
|
205
209
|
// private: able to be console.logged, but not able to be accessed by code
|
|
206
210
|
constructor(tag, value) {
|
|
@@ -368,7 +372,7 @@
|
|
|
368
372
|
*/
|
|
369
373
|
getOrDie(message) {
|
|
370
374
|
if (!this.tag) {
|
|
371
|
-
throw new Error(message
|
|
375
|
+
throw new Error(message ?? 'Called getOrDie on None');
|
|
372
376
|
}
|
|
373
377
|
else {
|
|
374
378
|
return this.value;
|
|
@@ -432,9 +436,6 @@
|
|
|
432
436
|
return this.tag ? `some(${this.value})` : 'none()';
|
|
433
437
|
}
|
|
434
438
|
}
|
|
435
|
-
// Sneaky optimisation: every instance of Optional.none is identical, so just
|
|
436
|
-
// reuse the same object
|
|
437
|
-
Optional.singletonNone = new Optional(false);
|
|
438
439
|
|
|
439
440
|
const nativeSlice = Array.prototype.slice;
|
|
440
441
|
const nativeIndexOf = Array.prototype.indexOf;
|
|
@@ -1370,7 +1371,7 @@
|
|
|
1370
1371
|
const detectBrowser$1 = (browsers, userAgentData) => {
|
|
1371
1372
|
return findMap(userAgentData.brands, (uaBrand) => {
|
|
1372
1373
|
const lcBrand = uaBrand.brand.toLowerCase();
|
|
1373
|
-
return find$2(browsers, (browser) =>
|
|
1374
|
+
return find$2(browsers, (browser) => lcBrand === browser.brand?.toLowerCase())
|
|
1374
1375
|
.map((info) => ({
|
|
1375
1376
|
current: info.name,
|
|
1376
1377
|
version: Version.nu(parseInt(uaBrand.version, 10), 0)
|
|
@@ -2734,8 +2735,8 @@
|
|
|
2734
2735
|
if (body === element.dom) {
|
|
2735
2736
|
return SugarPosition(body.offsetLeft, body.offsetTop);
|
|
2736
2737
|
}
|
|
2737
|
-
const scrollTop = firstDefinedOrZero(win
|
|
2738
|
-
const scrollLeft = firstDefinedOrZero(win
|
|
2738
|
+
const scrollTop = firstDefinedOrZero(win?.pageYOffset, html.scrollTop);
|
|
2739
|
+
const scrollLeft = firstDefinedOrZero(win?.pageXOffset, html.scrollLeft);
|
|
2739
2740
|
const clientTop = firstDefinedOrZero(html.clientTop, body.clientTop);
|
|
2740
2741
|
const clientLeft = firstDefinedOrZero(html.clientLeft, body.clientLeft);
|
|
2741
2742
|
return viewport(element).translate(scrollLeft - clientLeft, scrollTop - clientTop);
|
|
@@ -3123,21 +3124,18 @@
|
|
|
3123
3124
|
range
|
|
3124
3125
|
};
|
|
3125
3126
|
|
|
3126
|
-
const caretPositionFromPoint = (doc, x, y) =>
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
});
|
|
3139
|
-
};
|
|
3140
|
-
const caretRangeFromPoint = (doc, x, y) => { var _a; return Optional.from((_a = doc.caretRangeFromPoint) === null || _a === void 0 ? void 0 : _a.call(doc, x, y)); };
|
|
3127
|
+
const caretPositionFromPoint = (doc, x, y) => Optional.from(doc.caretPositionFromPoint?.(x, y))
|
|
3128
|
+
.bind((pos) => {
|
|
3129
|
+
// It turns out that Firefox can return null for pos.offsetNode
|
|
3130
|
+
if (pos.offsetNode === null) {
|
|
3131
|
+
return Optional.none();
|
|
3132
|
+
}
|
|
3133
|
+
const r = doc.createRange();
|
|
3134
|
+
r.setStart(pos.offsetNode, pos.offset);
|
|
3135
|
+
r.collapse();
|
|
3136
|
+
return Optional.some(r);
|
|
3137
|
+
});
|
|
3138
|
+
const caretRangeFromPoint = (doc, x, y) => Optional.from(doc.caretRangeFromPoint?.(x, y));
|
|
3141
3139
|
const availableSearch = (doc, x, y) => {
|
|
3142
3140
|
if (doc.caretPositionFromPoint) {
|
|
3143
3141
|
return caretPositionFromPoint(doc, x, y); // defined standard, firefox only
|
|
@@ -3248,6 +3246,8 @@
|
|
|
3248
3246
|
* } while (walker.next());
|
|
3249
3247
|
*/
|
|
3250
3248
|
class DomTreeWalker {
|
|
3249
|
+
rootNode;
|
|
3250
|
+
node;
|
|
3251
3251
|
constructor(startNode, rootNode) {
|
|
3252
3252
|
this.node = startNode;
|
|
3253
3253
|
this.rootNode = rootNode;
|
|
@@ -3465,6 +3465,8 @@
|
|
|
3465
3465
|
const isListItem$3 = matchNodeName$1('li');
|
|
3466
3466
|
const isDetails = matchNodeName$1('details');
|
|
3467
3467
|
const isSummary$1 = matchNodeName$1('summary');
|
|
3468
|
+
const ucVideoNodeName = 'uc-video';
|
|
3469
|
+
const isUcVideo = (el) => el.nodeName.toLowerCase() === ucVideoNodeName;
|
|
3468
3470
|
|
|
3469
3471
|
const defaultOptionValues = {
|
|
3470
3472
|
skipBogus: true,
|
|
@@ -3610,11 +3612,10 @@
|
|
|
3610
3612
|
return filter$5(scope.querySelectorAll(transparentSelector), (transparent) => updateTransparent(blocksSelector, transparent));
|
|
3611
3613
|
};
|
|
3612
3614
|
const trimEdge = (schema, el, leftSide) => {
|
|
3613
|
-
var _a;
|
|
3614
3615
|
const childPropertyName = leftSide ? 'lastChild' : 'firstChild';
|
|
3615
3616
|
for (let child = el[childPropertyName]; child; child = child[childPropertyName]) {
|
|
3616
3617
|
if (isEmptyNode(schema, child, { checkRootAsContent: true })) {
|
|
3617
|
-
|
|
3618
|
+
child.parentNode?.removeChild(child);
|
|
3618
3619
|
return;
|
|
3619
3620
|
}
|
|
3620
3621
|
}
|
|
@@ -4002,7 +4003,6 @@
|
|
|
4002
4003
|
// this function will then trim off empty edges and produce:
|
|
4003
4004
|
// <p>text 1</p><b>CHOP</b><p>text 2</p>
|
|
4004
4005
|
const trimNode = (dom, node, schema, root) => {
|
|
4005
|
-
var _a;
|
|
4006
4006
|
const rootNode = root || node;
|
|
4007
4007
|
if (isElement$7(node) && isBookmarkNode$2(node)) {
|
|
4008
4008
|
return node;
|
|
@@ -4015,7 +4015,7 @@
|
|
|
4015
4015
|
if (isElement$7(node)) {
|
|
4016
4016
|
const currentChildren = node.childNodes;
|
|
4017
4017
|
if (currentChildren.length === 1 && isBookmarkNode$2(currentChildren[0])) {
|
|
4018
|
-
|
|
4018
|
+
node.parentNode?.insertBefore(currentChildren[0], node);
|
|
4019
4019
|
}
|
|
4020
4020
|
}
|
|
4021
4021
|
// Remove any empty nodes
|
|
@@ -4433,7 +4433,7 @@
|
|
|
4433
4433
|
add('title hr noscript br');
|
|
4434
4434
|
add('base', 'href target');
|
|
4435
4435
|
add('link', 'href rel media hreflang type sizes hreflang');
|
|
4436
|
-
add('meta', 'name http-equiv content charset');
|
|
4436
|
+
add('meta', 'name http-equiv content charset property'); // Property is an RDFa spec attribute.
|
|
4437
4437
|
add('style', 'media type scoped');
|
|
4438
4438
|
add('script', 'src async defer type charset');
|
|
4439
4439
|
add('body', 'onafterprint onbeforeprint onbeforeunload onblur onerror onfocus ' +
|
|
@@ -4486,6 +4486,7 @@
|
|
|
4486
4486
|
add('canvas', 'width height', flowContent);
|
|
4487
4487
|
add('data', 'value', phrasingContent);
|
|
4488
4488
|
add('video', 'src crossorigin poster preload autoplay mediagroup loop ' +
|
|
4489
|
+
'controlslist disablepictureinpicture disableremoteplayback playsinline ' +
|
|
4489
4490
|
'muted controls width height buffered', [flowContent, 'track source'].join(' '));
|
|
4490
4491
|
add('audio', 'src crossorigin preload autoplay mediagroup loop muted controls ' +
|
|
4491
4492
|
'buffered volume', [flowContent, 'track source'].join(' '));
|
|
@@ -4760,12 +4761,12 @@
|
|
|
4760
4761
|
}
|
|
4761
4762
|
};
|
|
4762
4763
|
const Schema = (settings = {}) => {
|
|
4763
|
-
var _a;
|
|
4764
4764
|
const elements = {};
|
|
4765
4765
|
const children = {};
|
|
4766
4766
|
let patternElements = [];
|
|
4767
4767
|
const customElementsMap = {};
|
|
4768
4768
|
const specialElements = {};
|
|
4769
|
+
const componentUrls = {};
|
|
4769
4770
|
// Creates an lookup table map object for the specified option or the default value
|
|
4770
4771
|
const createLookupTable = (option, defaultValue, extendWith) => {
|
|
4771
4772
|
const value = settings[option];
|
|
@@ -4783,7 +4784,7 @@
|
|
|
4783
4784
|
return makeMap$2(value, /[, ]/, makeMap$2(value.toUpperCase(), /[, ]/));
|
|
4784
4785
|
}
|
|
4785
4786
|
};
|
|
4786
|
-
const schemaType =
|
|
4787
|
+
const schemaType = settings.schema ?? 'html5';
|
|
4787
4788
|
const schemaItems = makeSchema(schemaType);
|
|
4788
4789
|
// Allow all elements and attributes if verify_html is set to false
|
|
4789
4790
|
if (settings.verify_html === false) {
|
|
@@ -4820,7 +4821,7 @@
|
|
|
4820
4821
|
const addValidElements = (validElements) => {
|
|
4821
4822
|
const globalElement = Optional.from(elements['@']);
|
|
4822
4823
|
const hasPatternsRegExp = /[*?+]/;
|
|
4823
|
-
each$e(parseValidElementsRules(globalElement, validElements
|
|
4824
|
+
each$e(parseValidElementsRules(globalElement, validElements ?? ''), ({ name, element, aliasName }) => {
|
|
4824
4825
|
if (aliasName) {
|
|
4825
4826
|
elements[aliasName] = element;
|
|
4826
4827
|
}
|
|
@@ -4845,14 +4846,13 @@
|
|
|
4845
4846
|
addValidElements(validElements);
|
|
4846
4847
|
};
|
|
4847
4848
|
const addCustomElement = (name, spec) => {
|
|
4848
|
-
var _a, _b;
|
|
4849
4849
|
// Flush cached items since we are altering the default maps
|
|
4850
4850
|
delete mapCache.text_block_elements;
|
|
4851
4851
|
delete mapCache.block_elements;
|
|
4852
4852
|
const inline = spec.extends ? !isBlock(spec.extends) : false;
|
|
4853
4853
|
const cloneName = spec.extends;
|
|
4854
4854
|
children[name] = cloneName ? children[cloneName] : {};
|
|
4855
|
-
customElementsMap[name] = cloneName
|
|
4855
|
+
customElementsMap[name] = cloneName ?? name;
|
|
4856
4856
|
// Treat all custom elements as being non-empty by default
|
|
4857
4857
|
nonEmptyElementsMap[name.toUpperCase()] = {};
|
|
4858
4858
|
nonEmptyElementsMap[name] = {};
|
|
@@ -4877,7 +4877,7 @@
|
|
|
4877
4877
|
customRule.attributesOrder.push(name);
|
|
4878
4878
|
customRule.attributes[name] = {};
|
|
4879
4879
|
};
|
|
4880
|
-
const customRule =
|
|
4880
|
+
const customRule = elements[name] ?? {};
|
|
4881
4881
|
delete customRule.attributesDefault;
|
|
4882
4882
|
delete customRule.attributesForced;
|
|
4883
4883
|
delete customRule.attributePatterns;
|
|
@@ -4901,7 +4901,7 @@
|
|
|
4901
4901
|
}
|
|
4902
4902
|
// Add custom pad empty rule
|
|
4903
4903
|
if (isBoolean(spec.padEmpty)) {
|
|
4904
|
-
const customRule =
|
|
4904
|
+
const customRule = elements[name] ?? {};
|
|
4905
4905
|
customRule.paddEmpty = spec.padEmpty;
|
|
4906
4906
|
elements[name] = customRule;
|
|
4907
4907
|
}
|
|
@@ -4939,13 +4939,22 @@
|
|
|
4939
4939
|
}
|
|
4940
4940
|
};
|
|
4941
4941
|
const addCustomElementsFromString = (customElements) => {
|
|
4942
|
-
each$e(parseCustomElementsRules(customElements
|
|
4942
|
+
each$e(parseCustomElementsRules(customElements ?? ''), ({ name, cloneName }) => {
|
|
4943
4943
|
addCustomElement(name, { extends: cloneName });
|
|
4944
4944
|
});
|
|
4945
4945
|
};
|
|
4946
|
+
const addComponentUrl = (elementName, componentUrl) => {
|
|
4947
|
+
componentUrls[elementName] = componentUrl;
|
|
4948
|
+
};
|
|
4946
4949
|
const addCustomElements = (customElements) => {
|
|
4947
4950
|
if (isObject(customElements)) {
|
|
4948
|
-
each$d(customElements, (spec, name) =>
|
|
4951
|
+
each$d(customElements, (spec, name) => {
|
|
4952
|
+
const componentUrl = spec.componentUrl;
|
|
4953
|
+
if (isString(componentUrl)) {
|
|
4954
|
+
addComponentUrl(name, componentUrl);
|
|
4955
|
+
}
|
|
4956
|
+
addCustomElement(name, spec);
|
|
4957
|
+
});
|
|
4949
4958
|
}
|
|
4950
4959
|
else if (isString(customElements)) {
|
|
4951
4960
|
addCustomElementsFromString(customElements);
|
|
@@ -4953,7 +4962,7 @@
|
|
|
4953
4962
|
};
|
|
4954
4963
|
// Adds valid children to the schema object
|
|
4955
4964
|
const addValidChildren = (validChildren) => {
|
|
4956
|
-
each$e(parseValidChildrenRules(validChildren
|
|
4965
|
+
each$e(parseValidChildrenRules(validChildren ?? ''), ({ operation, name, validChildren }) => {
|
|
4957
4966
|
const parent = operation === 'replace' ? { '#comment': {} } : children[name];
|
|
4958
4967
|
const processNodeName = (name) => {
|
|
4959
4968
|
if (operation === 'remove') {
|
|
@@ -5301,6 +5310,13 @@
|
|
|
5301
5310
|
* @method addValidChildren
|
|
5302
5311
|
* @param {String} valid_children Valid children elements string to parse
|
|
5303
5312
|
*/
|
|
5313
|
+
/**
|
|
5314
|
+
* Returns an object of all custom elements that have component URLs.
|
|
5315
|
+
*
|
|
5316
|
+
* @method getComponentUrls
|
|
5317
|
+
* @return {Object} Object with where key is the component and the value is the url for that component.
|
|
5318
|
+
*/
|
|
5319
|
+
const getComponentUrls = constant(componentUrls);
|
|
5304
5320
|
setup();
|
|
5305
5321
|
return {
|
|
5306
5322
|
type: schemaType,
|
|
@@ -5321,6 +5337,7 @@
|
|
|
5321
5337
|
getWhitespaceElements,
|
|
5322
5338
|
getTransparentElements,
|
|
5323
5339
|
getSpecialElements,
|
|
5340
|
+
getComponentUrls,
|
|
5324
5341
|
isValidChild,
|
|
5325
5342
|
isValid,
|
|
5326
5343
|
isBlock,
|
|
@@ -5330,7 +5347,7 @@
|
|
|
5330
5347
|
addValidElements,
|
|
5331
5348
|
setValidElements,
|
|
5332
5349
|
addCustomElements,
|
|
5333
|
-
addValidChildren
|
|
5350
|
+
addValidChildren,
|
|
5334
5351
|
};
|
|
5335
5352
|
};
|
|
5336
5353
|
|
|
@@ -5697,7 +5714,7 @@
|
|
|
5697
5714
|
// An event needs normalizing if it doesn't have the prevent default function or if it's a native event
|
|
5698
5715
|
const needsNormalizing = (event) => isNullable(event.preventDefault) || isNativeEvent(event);
|
|
5699
5716
|
const clone$2 = (originalEvent, data) => {
|
|
5700
|
-
const event = data
|
|
5717
|
+
const event = data ?? {};
|
|
5701
5718
|
// Copy all properties from the original event
|
|
5702
5719
|
for (const name in originalEvent) {
|
|
5703
5720
|
// Some properties are deprecated and produces a warning so don't include them
|
|
@@ -5723,12 +5740,11 @@
|
|
|
5723
5740
|
return event;
|
|
5724
5741
|
};
|
|
5725
5742
|
const normalize$3 = (type, originalEvent, fallbackTarget, data) => {
|
|
5726
|
-
var _a;
|
|
5727
5743
|
const event = clone$2(originalEvent, data);
|
|
5728
5744
|
event.type = type;
|
|
5729
5745
|
// Normalize target IE uses srcElement
|
|
5730
5746
|
if (isNullable(event.target)) {
|
|
5731
|
-
event.target =
|
|
5747
|
+
event.target = event.srcElement ?? fallbackTarget;
|
|
5732
5748
|
}
|
|
5733
5749
|
if (needsNormalizing(originalEvent)) {
|
|
5734
5750
|
// Add preventDefault method
|
|
@@ -5843,11 +5859,14 @@
|
|
|
5843
5859
|
* This class enables you to bind/unbind native events to elements and normalize it's behavior across browsers.
|
|
5844
5860
|
*/
|
|
5845
5861
|
class EventUtils {
|
|
5862
|
+
static Event = new EventUtils();
|
|
5863
|
+
// State if the DOMContentLoaded was executed or not
|
|
5864
|
+
domLoaded = false;
|
|
5865
|
+
events = {};
|
|
5866
|
+
expando;
|
|
5867
|
+
hasFocusIn;
|
|
5868
|
+
count = 1;
|
|
5846
5869
|
constructor() {
|
|
5847
|
-
// State if the DOMContentLoaded was executed or not
|
|
5848
|
-
this.domLoaded = false;
|
|
5849
|
-
this.events = {};
|
|
5850
|
-
this.count = 1;
|
|
5851
5870
|
this.expando = eventExpandoPrefix + (+new Date()).toString(32);
|
|
5852
5871
|
this.hasFocusIn = 'onfocusin' in document.documentElement;
|
|
5853
5872
|
this.count = 1;
|
|
@@ -5995,7 +6014,7 @@
|
|
|
5995
6014
|
// IE will fail here since it can't delete properties from window
|
|
5996
6015
|
delete target[this.expando];
|
|
5997
6016
|
}
|
|
5998
|
-
catch
|
|
6017
|
+
catch {
|
|
5999
6018
|
// IE will set it to null
|
|
6000
6019
|
target[this.expando] = null;
|
|
6001
6020
|
}
|
|
@@ -6118,7 +6137,6 @@
|
|
|
6118
6137
|
}
|
|
6119
6138
|
}
|
|
6120
6139
|
}
|
|
6121
|
-
EventUtils.Event = new EventUtils();
|
|
6122
6140
|
|
|
6123
6141
|
/**
|
|
6124
6142
|
* Utility class for various DOM manipulation and retrieval functions.
|
|
@@ -6477,12 +6495,11 @@
|
|
|
6477
6495
|
const getPrev = (node, selector) => _findSib(node, selector, 'previousSibling');
|
|
6478
6496
|
const isParentNode = (node) => isFunction(node.querySelectorAll);
|
|
6479
6497
|
const select = (selector, scope) => {
|
|
6480
|
-
|
|
6481
|
-
const elm = (_b = (_a = get(scope)) !== null && _a !== void 0 ? _a : settings.root_element) !== null && _b !== void 0 ? _b : doc;
|
|
6498
|
+
const elm = get(scope) ?? settings.root_element ?? doc;
|
|
6482
6499
|
return isParentNode(elm) ? from(elm.querySelectorAll(selector)) : [];
|
|
6483
6500
|
};
|
|
6484
6501
|
const run = function (elm, func, scope) {
|
|
6485
|
-
const context = scope
|
|
6502
|
+
const context = scope ?? this;
|
|
6486
6503
|
if (isArray$1(elm)) {
|
|
6487
6504
|
const result = [];
|
|
6488
6505
|
each$a(elm, (e, i) => {
|
|
@@ -6687,8 +6704,8 @@
|
|
|
6687
6704
|
const insertAfter = (node, reference) => {
|
|
6688
6705
|
const referenceNode = get(reference);
|
|
6689
6706
|
return run(node, (node) => {
|
|
6690
|
-
const parent = referenceNode
|
|
6691
|
-
const nextSibling = referenceNode
|
|
6707
|
+
const parent = referenceNode?.parentNode;
|
|
6708
|
+
const nextSibling = referenceNode?.nextSibling;
|
|
6692
6709
|
if (parent) {
|
|
6693
6710
|
if (nextSibling) {
|
|
6694
6711
|
parent.insertBefore(node, nextSibling);
|
|
@@ -6701,14 +6718,13 @@
|
|
|
6701
6718
|
});
|
|
6702
6719
|
};
|
|
6703
6720
|
const replace = (newElm, oldElm, keepChildren) => run(oldElm, (elm) => {
|
|
6704
|
-
var _a;
|
|
6705
6721
|
const replacee = isArray$1(oldElm) ? newElm.cloneNode(true) : newElm;
|
|
6706
6722
|
if (keepChildren) {
|
|
6707
6723
|
each$a(grep(elm.childNodes), (node) => {
|
|
6708
6724
|
replacee.appendChild(node);
|
|
6709
6725
|
});
|
|
6710
6726
|
}
|
|
6711
|
-
|
|
6727
|
+
elm.parentNode?.replaceChild(replacee, elm);
|
|
6712
6728
|
return elm;
|
|
6713
6729
|
});
|
|
6714
6730
|
const rename = (elm, name) => {
|
|
@@ -7572,12 +7588,14 @@
|
|
|
7572
7588
|
const LOADED = 2;
|
|
7573
7589
|
const FAILED = 3;
|
|
7574
7590
|
class ScriptLoader {
|
|
7591
|
+
static ScriptLoader = new ScriptLoader();
|
|
7592
|
+
settings;
|
|
7593
|
+
states = {};
|
|
7594
|
+
queue = [];
|
|
7595
|
+
scriptLoadedCallbacks = {};
|
|
7596
|
+
queueLoadedCallbacks = [];
|
|
7597
|
+
loading = false;
|
|
7575
7598
|
constructor(settings = {}) {
|
|
7576
|
-
this.states = {};
|
|
7577
|
-
this.queue = [];
|
|
7578
|
-
this.scriptLoadedCallbacks = {};
|
|
7579
|
-
this.queueLoadedCallbacks = [];
|
|
7580
|
-
this.loading = false;
|
|
7581
7599
|
this.settings = settings;
|
|
7582
7600
|
}
|
|
7583
7601
|
_setReferrerPolicy(referrerPolicy) {
|
|
@@ -7596,6 +7614,7 @@
|
|
|
7596
7614
|
loadScript(url) {
|
|
7597
7615
|
return new Promise((resolve, reject) => {
|
|
7598
7616
|
const dom = DOM$e;
|
|
7617
|
+
const doc = document;
|
|
7599
7618
|
let elm;
|
|
7600
7619
|
const cleanup = () => {
|
|
7601
7620
|
dom.remove(id);
|
|
@@ -7617,7 +7636,7 @@
|
|
|
7617
7636
|
};
|
|
7618
7637
|
const id = dom.uniqueId();
|
|
7619
7638
|
// Create new script element
|
|
7620
|
-
elm =
|
|
7639
|
+
elm = doc.createElement('script');
|
|
7621
7640
|
elm.id = id;
|
|
7622
7641
|
elm.type = 'text/javascript';
|
|
7623
7642
|
elm.src = Tools._addCacheSuffix(url);
|
|
@@ -7636,7 +7655,7 @@
|
|
|
7636
7655
|
// Add onerror event will get fired on some browsers but not all of them
|
|
7637
7656
|
elm.onerror = error;
|
|
7638
7657
|
// Add script to document
|
|
7639
|
-
(
|
|
7658
|
+
(doc.head || doc.body).appendChild(elm);
|
|
7640
7659
|
});
|
|
7641
7660
|
}
|
|
7642
7661
|
/**
|
|
@@ -7784,8 +7803,28 @@
|
|
|
7784
7803
|
return processQueue(uniqueScripts);
|
|
7785
7804
|
}
|
|
7786
7805
|
}
|
|
7806
|
+
/**
|
|
7807
|
+
* Returns the attributes that should be added to a script tag when loading the specified URL.
|
|
7808
|
+
*
|
|
7809
|
+
* @method getScriptAttributes
|
|
7810
|
+
* @param {String} url Url to get attributes for.
|
|
7811
|
+
* @return {Object} Object with attributes to add to the script tag.
|
|
7812
|
+
*/
|
|
7813
|
+
getScriptAttributes(url) {
|
|
7814
|
+
const attrs = {};
|
|
7815
|
+
if (this.settings.referrerPolicy) {
|
|
7816
|
+
attrs.referrerpolicy = this.settings.referrerPolicy;
|
|
7817
|
+
}
|
|
7818
|
+
const crossOrigin = this.settings.crossOrigin;
|
|
7819
|
+
if (isFunction(crossOrigin)) {
|
|
7820
|
+
const resultCrossOrigin = crossOrigin(url);
|
|
7821
|
+
if (isString(resultCrossOrigin)) {
|
|
7822
|
+
attrs.crossorigin = resultCrossOrigin;
|
|
7823
|
+
}
|
|
7824
|
+
}
|
|
7825
|
+
return attrs;
|
|
7826
|
+
}
|
|
7787
7827
|
}
|
|
7788
|
-
ScriptLoader.ScriptLoader = new ScriptLoader();
|
|
7789
7828
|
|
|
7790
7829
|
const isDuplicated = (items, item) => {
|
|
7791
7830
|
const firstIndex = items.indexOf(item);
|
|
@@ -8226,14 +8265,13 @@
|
|
|
8226
8265
|
const dataAnnotation$1 = dataAnnotation();
|
|
8227
8266
|
const identifyParserNode = (node) => Optional.from(node.attr(dataAnnotation$1)).bind(registry.lookup);
|
|
8228
8267
|
const removeDirectAnnotation = (node) => {
|
|
8229
|
-
var _a, _b;
|
|
8230
8268
|
node.attr(dataAnnotationId(), null);
|
|
8231
8269
|
node.attr(dataAnnotation(), null);
|
|
8232
8270
|
node.attr(dataAnnotationActive(), null);
|
|
8233
8271
|
const customAttrNames = Optional.from(node.attr(dataAnnotationAttributes())).map((names) => names.split(',')).getOr([]);
|
|
8234
8272
|
const customClasses = Optional.from(node.attr(dataAnnotationClasses())).map((names) => names.split(',')).getOr([]);
|
|
8235
8273
|
each$e(customAttrNames, (name) => node.attr(name, null));
|
|
8236
|
-
const classList =
|
|
8274
|
+
const classList = node.attr('class')?.split(' ') ?? [];
|
|
8237
8275
|
const newClassList = difference(classList, [annotation()].concat(customClasses));
|
|
8238
8276
|
node.attr('class', newClassList.length > 0 ? newClassList.join(' ') : null);
|
|
8239
8277
|
node.attr(dataAnnotationClasses(), null);
|
|
@@ -8335,7 +8373,7 @@
|
|
|
8335
8373
|
* @return {Object} An object containing the matched text node and offset. If no match is found, null will be returned.
|
|
8336
8374
|
*/
|
|
8337
8375
|
const backwards = (node, offset, process, root) => {
|
|
8338
|
-
const walker = TextWalker(node, root
|
|
8376
|
+
const walker = TextWalker(node, root ?? dom.getRoot(), isBlockBoundary);
|
|
8339
8377
|
return walk(node, offset, () => walker.prev().map((prev) => ({ container: prev, offset: prev.length })), process).getOrNull();
|
|
8340
8378
|
};
|
|
8341
8379
|
/**
|
|
@@ -8349,7 +8387,7 @@
|
|
|
8349
8387
|
* @return {Object} An object containing the matched text node and offset. If no match is found, null will be returned.
|
|
8350
8388
|
*/
|
|
8351
8389
|
const forwards = (node, offset, process, root) => {
|
|
8352
|
-
const walker = TextWalker(node, root
|
|
8390
|
+
const walker = TextWalker(node, root ?? dom.getRoot(), isBlockBoundary);
|
|
8353
8391
|
return walk(node, offset, () => walker.next().map((next) => ({ container: next, offset: 0 })), process).getOrNull();
|
|
8354
8392
|
};
|
|
8355
8393
|
return {
|
|
@@ -8455,8 +8493,7 @@
|
|
|
8455
8493
|
const isCaretContainer$2 = (node) => isCaretContainerBlock$1(node) || isCaretContainerInline(node);
|
|
8456
8494
|
const hasContent = (node) => node.firstChild !== node.lastChild || !isBr$7(node.firstChild);
|
|
8457
8495
|
const insertInline$1 = (node, before) => {
|
|
8458
|
-
|
|
8459
|
-
const doc = (_a = node.ownerDocument) !== null && _a !== void 0 ? _a : document;
|
|
8496
|
+
const doc = node.ownerDocument ?? document;
|
|
8460
8497
|
const textNode = doc.createTextNode(ZWSP$1);
|
|
8461
8498
|
const parentNode = node.parentNode;
|
|
8462
8499
|
if (!before) {
|
|
@@ -8471,10 +8508,10 @@
|
|
|
8471
8508
|
}
|
|
8472
8509
|
}
|
|
8473
8510
|
if (node.nextSibling) {
|
|
8474
|
-
parentNode
|
|
8511
|
+
parentNode?.insertBefore(textNode, node.nextSibling);
|
|
8475
8512
|
}
|
|
8476
8513
|
else {
|
|
8477
|
-
parentNode
|
|
8514
|
+
parentNode?.appendChild(textNode);
|
|
8478
8515
|
}
|
|
8479
8516
|
}
|
|
8480
8517
|
else {
|
|
@@ -8487,7 +8524,7 @@
|
|
|
8487
8524
|
return sibling.splitText(sibling.data.length - 1);
|
|
8488
8525
|
}
|
|
8489
8526
|
}
|
|
8490
|
-
parentNode
|
|
8527
|
+
parentNode?.insertBefore(textNode, node);
|
|
8491
8528
|
}
|
|
8492
8529
|
return textNode;
|
|
8493
8530
|
};
|
|
@@ -8508,8 +8545,7 @@
|
|
|
8508
8545
|
return container.data.charAt(pos.offset() - 1) === ZWSP$1 || pos.isAtEnd() && isCaretContainerInline(container.nextSibling);
|
|
8509
8546
|
};
|
|
8510
8547
|
const insertBlock = (blockName, node, before) => {
|
|
8511
|
-
|
|
8512
|
-
const doc = (_a = node.ownerDocument) !== null && _a !== void 0 ? _a : document;
|
|
8548
|
+
const doc = node.ownerDocument ?? document;
|
|
8513
8549
|
const blockNode = doc.createElement(blockName);
|
|
8514
8550
|
blockNode.setAttribute('data-mce-caret', before ? 'before' : 'after');
|
|
8515
8551
|
blockNode.setAttribute('data-mce-bogus', 'all');
|
|
@@ -8517,25 +8553,24 @@
|
|
|
8517
8553
|
const parentNode = node.parentNode;
|
|
8518
8554
|
if (!before) {
|
|
8519
8555
|
if (node.nextSibling) {
|
|
8520
|
-
parentNode
|
|
8556
|
+
parentNode?.insertBefore(blockNode, node.nextSibling);
|
|
8521
8557
|
}
|
|
8522
8558
|
else {
|
|
8523
|
-
parentNode
|
|
8559
|
+
parentNode?.appendChild(blockNode);
|
|
8524
8560
|
}
|
|
8525
8561
|
}
|
|
8526
8562
|
else {
|
|
8527
|
-
parentNode
|
|
8563
|
+
parentNode?.insertBefore(blockNode, node);
|
|
8528
8564
|
}
|
|
8529
8565
|
return blockNode;
|
|
8530
8566
|
};
|
|
8531
8567
|
const startsWithCaretContainer$1 = (node) => isText$9(node) && node.data[0] === ZWSP$1;
|
|
8532
8568
|
const endsWithCaretContainer$1 = (node) => isText$9(node) && node.data[node.data.length - 1] === ZWSP$1;
|
|
8533
8569
|
const trimBogusBr = (elm) => {
|
|
8534
|
-
var _a;
|
|
8535
8570
|
const brs = elm.getElementsByTagName('br');
|
|
8536
8571
|
const lastBr = brs[brs.length - 1];
|
|
8537
8572
|
if (isBogus$1(lastBr)) {
|
|
8538
|
-
|
|
8573
|
+
lastBr.parentNode?.removeChild(lastBr);
|
|
8539
8574
|
}
|
|
8540
8575
|
};
|
|
8541
8576
|
const showCaretContainerBlock = (caretContainer) => {
|
|
@@ -8828,7 +8863,6 @@
|
|
|
8828
8863
|
};
|
|
8829
8864
|
const isZeroRect = (r) => r.left === 0 && r.right === 0 && r.top === 0 && r.bottom === 0;
|
|
8830
8865
|
const getBoundingClientRect$1 = (item) => {
|
|
8831
|
-
var _a;
|
|
8832
8866
|
let clientRect;
|
|
8833
8867
|
const clientRects = item.getClientRects();
|
|
8834
8868
|
if (clientRects.length > 0) {
|
|
@@ -8841,7 +8875,7 @@
|
|
|
8841
8875
|
return getBrClientRect(item);
|
|
8842
8876
|
}
|
|
8843
8877
|
if (isZeroRect(clientRect) && isRange(item)) {
|
|
8844
|
-
return
|
|
8878
|
+
return getBoundingClientRectWebKitText(item) ?? clientRect;
|
|
8845
8879
|
}
|
|
8846
8880
|
return clientRect;
|
|
8847
8881
|
};
|
|
@@ -9473,7 +9507,6 @@
|
|
|
9473
9507
|
const isBlockPattern = (pattern) => pattern.type === 'block-command' || pattern.type === 'block-format';
|
|
9474
9508
|
const hasBlockTrigger = (pattern, trigger) => (pattern.type === 'block-command' || pattern.type === 'block-format') && pattern.trigger === trigger;
|
|
9475
9509
|
const normalizePattern = (pattern) => {
|
|
9476
|
-
var _a;
|
|
9477
9510
|
const err = (message) => Result.error({ message, pattern });
|
|
9478
9511
|
const formatOrCmd = (name, onFormat, onCommand) => {
|
|
9479
9512
|
if (pattern.format !== undefined) {
|
|
@@ -9543,7 +9576,7 @@
|
|
|
9543
9576
|
}
|
|
9544
9577
|
else {
|
|
9545
9578
|
// block pattern
|
|
9546
|
-
const trigger =
|
|
9579
|
+
const trigger = pattern.trigger ?? 'space';
|
|
9547
9580
|
if (pattern.start.length === 0) {
|
|
9548
9581
|
return err('Block pattern has empty `start` parameter');
|
|
9549
9582
|
}
|
|
@@ -10667,7 +10700,6 @@
|
|
|
10667
10700
|
return clientRect;
|
|
10668
10701
|
};
|
|
10669
10702
|
const trimInlineCaretContainers = (root) => {
|
|
10670
|
-
var _a, _b;
|
|
10671
10703
|
const fakeCaretTargetNodes = descendants(SugarElement.fromDom(root), inlineFakeCaretSelector);
|
|
10672
10704
|
for (let i = 0; i < fakeCaretTargetNodes.length; i++) {
|
|
10673
10705
|
const node = fakeCaretTargetNodes[i].dom;
|
|
@@ -10675,7 +10707,7 @@
|
|
|
10675
10707
|
if (endsWithCaretContainer$1(sibling)) {
|
|
10676
10708
|
const data = sibling.data;
|
|
10677
10709
|
if (data.length === 1) {
|
|
10678
|
-
|
|
10710
|
+
sibling.parentNode?.removeChild(sibling);
|
|
10679
10711
|
}
|
|
10680
10712
|
else {
|
|
10681
10713
|
sibling.deleteData(data.length - 1, 1);
|
|
@@ -10685,7 +10717,7 @@
|
|
|
10685
10717
|
if (startsWithCaretContainer$1(sibling)) {
|
|
10686
10718
|
const data = sibling.data;
|
|
10687
10719
|
if (data.length === 1) {
|
|
10688
|
-
|
|
10720
|
+
sibling.parentNode?.removeChild(sibling);
|
|
10689
10721
|
}
|
|
10690
10722
|
else {
|
|
10691
10723
|
sibling.deleteData(0, 1);
|
|
@@ -10864,9 +10896,14 @@
|
|
|
10864
10896
|
.map((elm) => elm.dom)
|
|
10865
10897
|
.getOr(rootNode);
|
|
10866
10898
|
};
|
|
10899
|
+
const isAbsPositionedElement = (node) => isElement$7(node) && get$7(SugarElement.fromDom(node), 'position') === 'absolute';
|
|
10900
|
+
const isInlineBlock = (node, rootNode) => node.parentNode !== rootNode;
|
|
10901
|
+
const isInlineAbsPositionedCEF = (node, rootNode) => isContentEditableFalse$6(node) && isAbsPositionedElement(node) && isInlineBlock(node, rootNode);
|
|
10867
10902
|
const getParentBlock$3 = (node, rootNode) => {
|
|
10868
10903
|
while (node && node !== rootNode) {
|
|
10869
|
-
|
|
10904
|
+
// Exclude inline absolutely positioned CEF elements since they have 'display: block'
|
|
10905
|
+
// Created TINY-12922 to improve handling non CEF elements
|
|
10906
|
+
if (isBlockLike(node) && !isInlineAbsPositionedCEF(node, rootNode)) {
|
|
10870
10907
|
return node;
|
|
10871
10908
|
}
|
|
10872
10909
|
node = node.parentNode;
|
|
@@ -10886,8 +10923,7 @@
|
|
|
10886
10923
|
return Optional.from(container.childNodes[offset + relativeOffset]);
|
|
10887
10924
|
};
|
|
10888
10925
|
const beforeAfter = (before, node) => {
|
|
10889
|
-
|
|
10890
|
-
const doc = (_a = node.ownerDocument) !== null && _a !== void 0 ? _a : document;
|
|
10926
|
+
const doc = node.ownerDocument ?? document;
|
|
10891
10927
|
const range = doc.createRange();
|
|
10892
10928
|
if (before) {
|
|
10893
10929
|
range.setStartBefore(node);
|
|
@@ -11334,8 +11370,7 @@
|
|
|
11334
11370
|
});
|
|
11335
11371
|
};
|
|
11336
11372
|
const insertZwsp = (node, rng) => {
|
|
11337
|
-
|
|
11338
|
-
const doc = (_a = node.ownerDocument) !== null && _a !== void 0 ? _a : document;
|
|
11373
|
+
const doc = node.ownerDocument ?? document;
|
|
11339
11374
|
const textNode = doc.createTextNode(ZWSP$1);
|
|
11340
11375
|
node.appendChild(textNode);
|
|
11341
11376
|
rng.setStart(textNode, 0);
|
|
@@ -11399,7 +11434,7 @@
|
|
|
11399
11434
|
const isValidTextNode = (node) => isText$b(node) && node.data.length > 0;
|
|
11400
11435
|
const restoreEndPoint$1 = (dom, suffix, bookmark) => {
|
|
11401
11436
|
const marker = dom.get(bookmark.id + '_' + suffix);
|
|
11402
|
-
const markerParent = marker
|
|
11437
|
+
const markerParent = marker?.parentNode;
|
|
11403
11438
|
const keep = bookmark.keep;
|
|
11404
11439
|
if (marker && markerParent) {
|
|
11405
11440
|
let container;
|
|
@@ -11689,7 +11724,7 @@
|
|
|
11689
11724
|
const isSelectionOverWholeTextNode = (range) => isSelectionOverWholeNode(range, isText$b);
|
|
11690
11725
|
const isSelectionOverWholeAnchor = (range) => isSelectionOverWholeNode(range, isAnchor);
|
|
11691
11726
|
|
|
11692
|
-
const isNode = (node) => isNumber(node
|
|
11727
|
+
const isNode = (node) => isNumber(node?.nodeType);
|
|
11693
11728
|
const isElementNode$1 = (node) => isElement$7(node) && !isBookmarkNode$1(node) && !isCaretNode(node) && !isBogus$1(node);
|
|
11694
11729
|
// In TinyMCE, directly selected elements are indicated with the data-mce-selected attribute
|
|
11695
11730
|
// Elements that can be directly selected include control elements such as img, media elements, noneditable elements and others
|
|
@@ -11725,7 +11760,6 @@
|
|
|
11725
11760
|
};
|
|
11726
11761
|
// Note: The reason why we only care about moving the start is because MatchFormat and its function use the start of the selection to determine if a selection has a given format or not
|
|
11727
11762
|
const moveStartToNearestText = (dom, selection) => {
|
|
11728
|
-
var _a, _b;
|
|
11729
11763
|
const rng = selection.getRng();
|
|
11730
11764
|
const { startContainer, startOffset } = rng;
|
|
11731
11765
|
const selectedNode = selection.getNode();
|
|
@@ -11739,11 +11773,11 @@
|
|
|
11739
11773
|
let walker;
|
|
11740
11774
|
if (startOffset < nodes.length) {
|
|
11741
11775
|
const startNode = nodes[startOffset];
|
|
11742
|
-
walker = new DomTreeWalker(startNode,
|
|
11776
|
+
walker = new DomTreeWalker(startNode, dom.getParent(startNode, dom.isBlock) ?? root);
|
|
11743
11777
|
}
|
|
11744
11778
|
else {
|
|
11745
11779
|
const startNode = nodes[nodes.length - 1];
|
|
11746
|
-
walker = new DomTreeWalker(startNode,
|
|
11780
|
+
walker = new DomTreeWalker(startNode, dom.getParent(startNode, dom.isBlock) ?? root);
|
|
11747
11781
|
walker.next(true);
|
|
11748
11782
|
}
|
|
11749
11783
|
for (let node = walker.current(); node; node = walker.next()) {
|
|
@@ -12031,7 +12065,6 @@
|
|
|
12031
12065
|
return container;
|
|
12032
12066
|
};
|
|
12033
12067
|
const findBlockEndPoint = (dom, formatList, container, siblingName) => {
|
|
12034
|
-
var _a;
|
|
12035
12068
|
let node = container;
|
|
12036
12069
|
const root = dom.getRoot();
|
|
12037
12070
|
const format = formatList[0];
|
|
@@ -12041,7 +12074,7 @@
|
|
|
12041
12074
|
}
|
|
12042
12075
|
// Expand to first wrappable block element or any block element
|
|
12043
12076
|
if (!node) {
|
|
12044
|
-
const scopeRoot =
|
|
12077
|
+
const scopeRoot = dom.getParent(container, 'LI,TD,TH,SUMMARY') ?? root;
|
|
12045
12078
|
node = dom.getParent(isText$b(container) ? container.parentNode : container,
|
|
12046
12079
|
// Fixes #6183 where it would expand to editable parent element in inline mode
|
|
12047
12080
|
(node) => node !== root && isTextBlock$1(dom.schema, node), scopeRoot);
|
|
@@ -12237,7 +12270,6 @@
|
|
|
12237
12270
|
};
|
|
12238
12271
|
|
|
12239
12272
|
const walk$3 = (dom, rng, callback) => {
|
|
12240
|
-
var _a;
|
|
12241
12273
|
const startOffset = rng.startOffset;
|
|
12242
12274
|
const startContainer = getNode$1(rng.startContainer, startOffset);
|
|
12243
12275
|
const endOffset = rng.endOffset;
|
|
@@ -12288,7 +12320,7 @@
|
|
|
12288
12320
|
return callback(exclude([startContainer]));
|
|
12289
12321
|
}
|
|
12290
12322
|
// Find common ancestor and end points
|
|
12291
|
-
const ancestor =
|
|
12323
|
+
const ancestor = dom.findCommonAncestor(startContainer, endContainer) ?? dom.getRoot();
|
|
12292
12324
|
// Process left side
|
|
12293
12325
|
if (dom.isChildOf(startContainer, endContainer)) {
|
|
12294
12326
|
return walkBoundary(startContainer, ancestor, true);
|
|
@@ -12672,7 +12704,7 @@
|
|
|
12672
12704
|
rng.setEnd(bookmark.finish.dom, bookmark.foffset);
|
|
12673
12705
|
return Optional.some(rng);
|
|
12674
12706
|
}
|
|
12675
|
-
catch
|
|
12707
|
+
catch {
|
|
12676
12708
|
return Optional.none();
|
|
12677
12709
|
}
|
|
12678
12710
|
};
|
|
@@ -12774,49 +12806,6 @@
|
|
|
12774
12806
|
}
|
|
12775
12807
|
};
|
|
12776
12808
|
|
|
12777
|
-
const walkUp = (navigation, doc) => {
|
|
12778
|
-
const frame = navigation.view(doc);
|
|
12779
|
-
return frame.fold(constant([]), (f) => {
|
|
12780
|
-
const parent = navigation.owner(f);
|
|
12781
|
-
const rest = walkUp(navigation, parent);
|
|
12782
|
-
return [f].concat(rest);
|
|
12783
|
-
});
|
|
12784
|
-
};
|
|
12785
|
-
const pathTo = (element, navigation) => {
|
|
12786
|
-
const d = navigation.owner(element);
|
|
12787
|
-
return walkUp(navigation, d);
|
|
12788
|
-
};
|
|
12789
|
-
|
|
12790
|
-
const view = (doc) => {
|
|
12791
|
-
var _a;
|
|
12792
|
-
// Only walk up to the document this script is defined in.
|
|
12793
|
-
// This prevents walking up to the parent window when the editor is in an iframe.
|
|
12794
|
-
const element = doc.dom === document ? Optional.none() : Optional.from((_a = doc.dom.defaultView) === null || _a === void 0 ? void 0 : _a.frameElement);
|
|
12795
|
-
return element.map(SugarElement.fromDom);
|
|
12796
|
-
};
|
|
12797
|
-
const owner = (element) => documentOrOwner(element);
|
|
12798
|
-
|
|
12799
|
-
var Navigation = /*#__PURE__*/Object.freeze({
|
|
12800
|
-
__proto__: null,
|
|
12801
|
-
view: view,
|
|
12802
|
-
owner: owner
|
|
12803
|
-
});
|
|
12804
|
-
|
|
12805
|
-
const find = (element) => {
|
|
12806
|
-
const doc = getDocument();
|
|
12807
|
-
const scroll = get$5(doc);
|
|
12808
|
-
const frames = pathTo(element, Navigation);
|
|
12809
|
-
const offset = viewport(element);
|
|
12810
|
-
const r = foldr(frames, (b, a) => {
|
|
12811
|
-
const loc = viewport(a);
|
|
12812
|
-
return {
|
|
12813
|
-
left: b.left + loc.left,
|
|
12814
|
-
top: b.top + loc.top
|
|
12815
|
-
};
|
|
12816
|
-
}, { left: 0, top: 0 });
|
|
12817
|
-
return SugarPosition(r.left + offset.left + scroll.left, r.top + offset.top + scroll.top);
|
|
12818
|
-
};
|
|
12819
|
-
|
|
12820
12809
|
const isManualNodeChange = (e) => {
|
|
12821
12810
|
return e.type === 'nodechange' && e.selectionChange;
|
|
12822
12811
|
};
|
|
@@ -12887,7 +12876,7 @@
|
|
|
12887
12876
|
const root = getRootNode(SugarElement.fromDom(editor.getElement()));
|
|
12888
12877
|
return active(root).fold(() => document.body, (x) => x.dom);
|
|
12889
12878
|
}
|
|
12890
|
-
catch
|
|
12879
|
+
catch {
|
|
12891
12880
|
// IE sometimes fails to get the activeElement when resizing table
|
|
12892
12881
|
// TODO: Investigate this
|
|
12893
12882
|
return document.body;
|
|
@@ -12903,18 +12892,6 @@
|
|
|
12903
12892
|
fn(contentArea, 'tox-edit-focus');
|
|
12904
12893
|
}
|
|
12905
12894
|
};
|
|
12906
|
-
const bringEditorIntoView = (editor) => {
|
|
12907
|
-
const minimumVisibility = 25;
|
|
12908
|
-
if (!editor.iframeElement) {
|
|
12909
|
-
return;
|
|
12910
|
-
}
|
|
12911
|
-
const element = SugarElement.fromDom(editor.iframeElement);
|
|
12912
|
-
const op = find(element);
|
|
12913
|
-
const viewportBounds = getBounds(window);
|
|
12914
|
-
if (op.top < viewportBounds.y || op.top > (viewportBounds.bottom - minimumVisibility)) {
|
|
12915
|
-
element.dom.scrollIntoView({ block: 'center' });
|
|
12916
|
-
}
|
|
12917
|
-
};
|
|
12918
12895
|
editor.on('focusin', () => {
|
|
12919
12896
|
const focusedEditor = editorManager.focusedEditor;
|
|
12920
12897
|
if (isEditorContentAreaElement(getActiveElement(editor))) {
|
|
@@ -12928,10 +12905,6 @@
|
|
|
12928
12905
|
editorManager.focusedEditor = editor;
|
|
12929
12906
|
editor.dispatch('focus', { blurredEditor: focusedEditor });
|
|
12930
12907
|
editor.focus(true);
|
|
12931
|
-
const browser = detect$1().browser;
|
|
12932
|
-
if (editor.inline !== true && (browser.isSafari() || browser.isChromium())) {
|
|
12933
|
-
bringEditorIntoView(editor);
|
|
12934
|
-
}
|
|
12935
12908
|
}
|
|
12936
12909
|
});
|
|
12937
12910
|
editor.on('focusout', () => {
|
|
@@ -13011,7 +12984,7 @@
|
|
|
13011
12984
|
try {
|
|
13012
12985
|
body.setActive();
|
|
13013
12986
|
}
|
|
13014
|
-
catch
|
|
12987
|
+
catch {
|
|
13015
12988
|
body.focus();
|
|
13016
12989
|
}
|
|
13017
12990
|
}
|
|
@@ -13120,7 +13093,7 @@
|
|
|
13120
13093
|
};
|
|
13121
13094
|
|
|
13122
13095
|
const elementSelectionAttr = 'data-mce-selected';
|
|
13123
|
-
const controlElmSelector =
|
|
13096
|
+
const controlElmSelector = `table,img,figure.image,hr,video,span.mce-preview-object,details,${ucVideoNodeName}`;
|
|
13124
13097
|
const abs = Math.abs;
|
|
13125
13098
|
const round$1 = Math.round;
|
|
13126
13099
|
// Details about each resize handle how to scale etc
|
|
@@ -13227,7 +13200,23 @@
|
|
|
13227
13200
|
dom.setStyle(target, name, value);
|
|
13228
13201
|
}
|
|
13229
13202
|
else {
|
|
13230
|
-
|
|
13203
|
+
if (isUcVideo(target)) {
|
|
13204
|
+
// this is needed because otherwise the ghost for `uc-video` is not correctly rendered
|
|
13205
|
+
target[name] = value;
|
|
13206
|
+
const minimumWidth = 400;
|
|
13207
|
+
if (target.width > minimumWidth && !(name === 'width' && value < minimumWidth)) {
|
|
13208
|
+
target[name] = value;
|
|
13209
|
+
dom.setAttrib(target, name, '' + value);
|
|
13210
|
+
}
|
|
13211
|
+
else {
|
|
13212
|
+
const value = name === 'height' ? minimumWidth * ratio : minimumWidth;
|
|
13213
|
+
target[name] = value;
|
|
13214
|
+
dom.setAttrib(target, name, '' + value);
|
|
13215
|
+
}
|
|
13216
|
+
}
|
|
13217
|
+
else {
|
|
13218
|
+
dom.setAttrib(target, name, '' + value);
|
|
13219
|
+
}
|
|
13231
13220
|
}
|
|
13232
13221
|
});
|
|
13233
13222
|
}
|
|
@@ -13248,7 +13237,7 @@
|
|
|
13248
13237
|
// Never scale down lower than 5 pixels
|
|
13249
13238
|
width = width < 5 ? 5 : width;
|
|
13250
13239
|
height = height < 5 ? 5 : height;
|
|
13251
|
-
if ((isImage(selectedElm) || isMedia(selectedElm)) && getResizeImgProportional(editor) !== false) {
|
|
13240
|
+
if ((isImage(selectedElm) || isMedia(selectedElm) || isUcVideo(selectedElm)) && getResizeImgProportional(editor) !== false) {
|
|
13252
13241
|
proportional = !VK.modifierPressed(e);
|
|
13253
13242
|
}
|
|
13254
13243
|
else {
|
|
@@ -13486,7 +13475,7 @@
|
|
|
13486
13475
|
// Disable object resizing on Gecko
|
|
13487
13476
|
editor.getDoc().execCommand('enableObjectResizing', false, 'false');
|
|
13488
13477
|
}
|
|
13489
|
-
catch
|
|
13478
|
+
catch {
|
|
13490
13479
|
// Ignore
|
|
13491
13480
|
}
|
|
13492
13481
|
};
|
|
@@ -13561,7 +13550,7 @@
|
|
|
13561
13550
|
}
|
|
13562
13551
|
return false;
|
|
13563
13552
|
};
|
|
13564
|
-
const isPrevNode = (node, name) =>
|
|
13553
|
+
const isPrevNode = (node, name) => node.previousSibling?.nodeName === name;
|
|
13565
13554
|
const hasContentEditableFalseParent = (root, node) => {
|
|
13566
13555
|
let currentNode = node;
|
|
13567
13556
|
while (currentNode && currentNode !== root) {
|
|
@@ -13897,6 +13886,48 @@
|
|
|
13897
13886
|
RangeUtils.getSelectedNode = getSelectedNode;
|
|
13898
13887
|
RangeUtils.getNode = getNode$1;
|
|
13899
13888
|
|
|
13889
|
+
const walkUp = (navigation, doc) => {
|
|
13890
|
+
const frame = navigation.view(doc);
|
|
13891
|
+
return frame.fold(constant([]), (f) => {
|
|
13892
|
+
const parent = navigation.owner(f);
|
|
13893
|
+
const rest = walkUp(navigation, parent);
|
|
13894
|
+
return [f].concat(rest);
|
|
13895
|
+
});
|
|
13896
|
+
};
|
|
13897
|
+
const pathTo = (element, navigation) => {
|
|
13898
|
+
const d = navigation.owner(element);
|
|
13899
|
+
return walkUp(navigation, d);
|
|
13900
|
+
};
|
|
13901
|
+
|
|
13902
|
+
const view = (doc) => {
|
|
13903
|
+
// Only walk up to the document this script is defined in.
|
|
13904
|
+
// This prevents walking up to the parent window when the editor is in an iframe.
|
|
13905
|
+
const element = doc.dom === document ? Optional.none() : Optional.from(doc.dom.defaultView?.frameElement);
|
|
13906
|
+
return element.map(SugarElement.fromDom);
|
|
13907
|
+
};
|
|
13908
|
+
const owner = (element) => documentOrOwner(element);
|
|
13909
|
+
|
|
13910
|
+
var Navigation = /*#__PURE__*/Object.freeze({
|
|
13911
|
+
__proto__: null,
|
|
13912
|
+
view: view,
|
|
13913
|
+
owner: owner
|
|
13914
|
+
});
|
|
13915
|
+
|
|
13916
|
+
const find = (element) => {
|
|
13917
|
+
const doc = getDocument();
|
|
13918
|
+
const scroll = get$5(doc);
|
|
13919
|
+
const frames = pathTo(element, Navigation);
|
|
13920
|
+
const offset = viewport(element);
|
|
13921
|
+
const r = foldr(frames, (b, a) => {
|
|
13922
|
+
const loc = viewport(a);
|
|
13923
|
+
return {
|
|
13924
|
+
left: b.left + loc.left,
|
|
13925
|
+
top: b.top + loc.top
|
|
13926
|
+
};
|
|
13927
|
+
}, { left: 0, top: 0 });
|
|
13928
|
+
return SugarPosition(r.left + offset.left + scroll.left, r.top + offset.top + scroll.top);
|
|
13929
|
+
};
|
|
13930
|
+
|
|
13900
13931
|
const excludeFromDescend = (element) => name(element) === 'textarea';
|
|
13901
13932
|
const fireScrollIntoViewEvent = (editor, data) => {
|
|
13902
13933
|
const scrollEvent = editor.dispatch('ScrollIntoView', data);
|
|
@@ -14200,8 +14231,7 @@
|
|
|
14200
14231
|
return undefined;
|
|
14201
14232
|
};
|
|
14202
14233
|
const isEmptyTextNode = (node) => {
|
|
14203
|
-
|
|
14204
|
-
const text = (_a = node.value) !== null && _a !== void 0 ? _a : '';
|
|
14234
|
+
const text = node.value ?? '';
|
|
14205
14235
|
// Non whitespace content
|
|
14206
14236
|
if (!isWhitespaceText(text)) {
|
|
14207
14237
|
return false;
|
|
@@ -14247,6 +14277,16 @@
|
|
|
14247
14277
|
}
|
|
14248
14278
|
return node;
|
|
14249
14279
|
}
|
|
14280
|
+
name;
|
|
14281
|
+
type;
|
|
14282
|
+
attributes;
|
|
14283
|
+
value;
|
|
14284
|
+
parent;
|
|
14285
|
+
firstChild;
|
|
14286
|
+
lastChild;
|
|
14287
|
+
next;
|
|
14288
|
+
prev;
|
|
14289
|
+
raw;
|
|
14250
14290
|
/**
|
|
14251
14291
|
* Constructs a new Node instance.
|
|
14252
14292
|
*
|
|
@@ -14558,7 +14598,6 @@
|
|
|
14558
14598
|
* node.isEmpty({ img: true });
|
|
14559
14599
|
*/
|
|
14560
14600
|
isEmpty(elements, whitespace = {}, predicate) {
|
|
14561
|
-
var _a;
|
|
14562
14601
|
const self = this;
|
|
14563
14602
|
let node = self.firstChild;
|
|
14564
14603
|
if (isNonEmptyElement(self)) {
|
|
@@ -14588,7 +14627,7 @@
|
|
|
14588
14627
|
return false;
|
|
14589
14628
|
}
|
|
14590
14629
|
// Keep whitespace preserve elements
|
|
14591
|
-
if (node.type === 3 && node.parent && whitespace[node.parent.name] && isWhitespaceText(
|
|
14630
|
+
if (node.type === 3 && node.parent && whitespace[node.parent.name] && isWhitespaceText(node.value ?? '')) {
|
|
14592
14631
|
return false;
|
|
14593
14632
|
}
|
|
14594
14633
|
// Predicate tells that the node is contents
|
|
@@ -14932,13 +14971,11 @@
|
|
|
14932
14971
|
const handlers = {
|
|
14933
14972
|
// #text
|
|
14934
14973
|
3: (node) => {
|
|
14935
|
-
|
|
14936
|
-
writer.text((_a = node.value) !== null && _a !== void 0 ? _a : '', node.raw);
|
|
14974
|
+
writer.text(node.value ?? '', node.raw);
|
|
14937
14975
|
},
|
|
14938
14976
|
// #comment
|
|
14939
14977
|
8: (node) => {
|
|
14940
|
-
|
|
14941
|
-
writer.comment((_a = node.value) !== null && _a !== void 0 ? _a : '');
|
|
14978
|
+
writer.comment(node.value ?? '');
|
|
14942
14979
|
},
|
|
14943
14980
|
// Processing instruction
|
|
14944
14981
|
7: (node) => {
|
|
@@ -14946,13 +14983,11 @@
|
|
|
14946
14983
|
},
|
|
14947
14984
|
// Doctype
|
|
14948
14985
|
10: (node) => {
|
|
14949
|
-
|
|
14950
|
-
writer.doctype((_a = node.value) !== null && _a !== void 0 ? _a : '');
|
|
14986
|
+
writer.doctype(node.value ?? '');
|
|
14951
14987
|
},
|
|
14952
14988
|
// CDATA
|
|
14953
14989
|
4: (node) => {
|
|
14954
|
-
|
|
14955
|
-
writer.cdata((_a = node.value) !== null && _a !== void 0 ? _a : '');
|
|
14990
|
+
writer.cdata(node.value ?? '');
|
|
14956
14991
|
},
|
|
14957
14992
|
// Document fragment
|
|
14958
14993
|
11: (node) => {
|
|
@@ -14966,7 +15001,6 @@
|
|
|
14966
15001
|
};
|
|
14967
15002
|
writer.reset();
|
|
14968
15003
|
const walk = (node) => {
|
|
14969
|
-
var _a;
|
|
14970
15004
|
const handler = handlers[node.type];
|
|
14971
15005
|
if (!handler) {
|
|
14972
15006
|
const name = node.name;
|
|
@@ -15011,7 +15045,7 @@
|
|
|
15011
15045
|
// Pre and textarea elements treat the first newline character as optional and will omit it. As such, if the content starts
|
|
15012
15046
|
// with a newline we need to add in an additional newline to prevent the current newline in the value being treated as optional
|
|
15013
15047
|
// See https://html.spec.whatwg.org/multipage/syntax.html#element-restrictions
|
|
15014
|
-
if ((name === 'pre' || name === 'textarea') && child.type === 3 &&
|
|
15048
|
+
if ((name === 'pre' || name === 'textarea') && child.type === 3 && child.value?.[0] === '\n') {
|
|
15015
15049
|
writer.text('\n', true);
|
|
15016
15050
|
}
|
|
15017
15051
|
do {
|
|
@@ -15089,9 +15123,8 @@
|
|
|
15089
15123
|
const nodeStyleProps = getStyleProps(dom, node);
|
|
15090
15124
|
const parentNodeStyleProps = getStyleProps(dom, parentNode);
|
|
15091
15125
|
const valueMismatch = (prop) => {
|
|
15092
|
-
|
|
15093
|
-
const
|
|
15094
|
-
const parentValue = (_b = dom.getStyle(parentNode, prop)) !== null && _b !== void 0 ? _b : '';
|
|
15126
|
+
const nodeValue = dom.getStyle(node, prop) ?? '';
|
|
15127
|
+
const parentValue = dom.getStyle(parentNode, prop) ?? '';
|
|
15095
15128
|
return isNotEmpty(nodeValue) && isNotEmpty(parentValue) && nodeValue !== parentValue;
|
|
15096
15129
|
};
|
|
15097
15130
|
return exists(nodeStyleProps, (nodeStyleProp) => {
|
|
@@ -15494,7 +15527,7 @@
|
|
|
15494
15527
|
const isInlineTarget = (editor, elm) => is$2(SugarElement.fromDom(elm), getInlineBoundarySelector(editor))
|
|
15495
15528
|
&& !isTransparentBlock(editor.schema, elm)
|
|
15496
15529
|
&& editor.dom.isEditable(elm);
|
|
15497
|
-
const isRtl = (element) =>
|
|
15530
|
+
const isRtl = (element) => DOMUtils.DOM.getStyle(element, 'direction', true) === 'rtl' || hasStrongRtl(element.textContent ?? '');
|
|
15498
15531
|
const findInlineParents = (isInlineTarget, rootNode, pos) => filter$5(DOMUtils.DOM.getParents(pos.container(), '*', rootNode), isInlineTarget);
|
|
15499
15532
|
const findRootInline = (isInlineTarget, rootNode, pos) => {
|
|
15500
15533
|
const parents = findInlineParents(isInlineTarget, rootNode, pos);
|
|
@@ -15583,11 +15616,10 @@
|
|
|
15583
15616
|
return child.bind(freefallRtl).orThunk(() => Optional.some(root));
|
|
15584
15617
|
};
|
|
15585
15618
|
const deleteRangeContents = (editor, rng, root, moveSelection = true) => {
|
|
15586
|
-
var _a;
|
|
15587
15619
|
rng.deleteContents();
|
|
15588
15620
|
// Pad the last block node
|
|
15589
15621
|
const lastNode = freefallRtl(root).getOr(root);
|
|
15590
|
-
const lastBlock = SugarElement.fromDom(
|
|
15622
|
+
const lastBlock = SugarElement.fromDom(editor.dom.getParent(lastNode.dom, editor.dom.isBlock) ?? root.dom);
|
|
15591
15623
|
// If the block is the editor body then we need to insert the root block as well
|
|
15592
15624
|
if (lastBlock.dom === editor.getBody()) {
|
|
15593
15625
|
paddEmptyBody(editor, moveSelection);
|
|
@@ -16113,8 +16145,7 @@
|
|
|
16113
16145
|
};
|
|
16114
16146
|
const restoreEndPoint = (container, offset) => {
|
|
16115
16147
|
const nodeIndex = (container) => {
|
|
16116
|
-
|
|
16117
|
-
let node = (_a = container.parentNode) === null || _a === void 0 ? void 0 : _a.firstChild;
|
|
16148
|
+
let node = container.parentNode?.firstChild;
|
|
16118
16149
|
let idx = 0;
|
|
16119
16150
|
while (node) {
|
|
16120
16151
|
if (node === container) {
|
|
@@ -16466,17 +16497,16 @@
|
|
|
16466
16497
|
}
|
|
16467
16498
|
};
|
|
16468
16499
|
const insertCaretContainerNode = (editor, caretContainer, formatNode) => {
|
|
16469
|
-
var _a, _b;
|
|
16470
16500
|
const dom = editor.dom;
|
|
16471
16501
|
const block = dom.getParent(formatNode, curry(isTextBlock$2, editor.schema));
|
|
16472
16502
|
if (block && dom.isEmpty(block)) {
|
|
16473
16503
|
// Replace formatNode with caretContainer when removing format from empty block like <p><b>|</b></p>
|
|
16474
|
-
|
|
16504
|
+
formatNode.parentNode?.replaceChild(caretContainer, formatNode);
|
|
16475
16505
|
}
|
|
16476
16506
|
else {
|
|
16477
16507
|
removeTrailingBr(SugarElement.fromDom(formatNode));
|
|
16478
16508
|
if (dom.isEmpty(formatNode)) {
|
|
16479
|
-
|
|
16509
|
+
formatNode.parentNode?.replaceChild(caretContainer, formatNode);
|
|
16480
16510
|
}
|
|
16481
16511
|
else {
|
|
16482
16512
|
dom.insertAfter(caretContainer, formatNode);
|
|
@@ -16488,11 +16518,10 @@
|
|
|
16488
16518
|
return node;
|
|
16489
16519
|
};
|
|
16490
16520
|
const insertFormatNodesIntoCaretContainer = (formatNodes, caretContainer) => {
|
|
16491
|
-
var _a;
|
|
16492
16521
|
const innerMostFormatNode = foldr(formatNodes, (parentNode, formatNode) => {
|
|
16493
16522
|
return appendNode(parentNode, formatNode.cloneNode(false));
|
|
16494
16523
|
}, caretContainer);
|
|
16495
|
-
const doc =
|
|
16524
|
+
const doc = innerMostFormatNode.ownerDocument ?? document;
|
|
16496
16525
|
return appendNode(innerMostFormatNode, doc.createTextNode(ZWSP));
|
|
16497
16526
|
};
|
|
16498
16527
|
const cleanFormatNode = (editor, caretContainer, formatNode, name, vars, similar) => {
|
|
@@ -16577,7 +16606,7 @@
|
|
|
16577
16606
|
}
|
|
16578
16607
|
else {
|
|
16579
16608
|
let textNode = caretContainer ? findFirstTextNode(caretContainer) : null;
|
|
16580
|
-
if (!caretContainer ||
|
|
16609
|
+
if (!caretContainer || textNode?.data !== ZWSP) {
|
|
16581
16610
|
// Need to import the node into the document on IE or we get a lovely WrongDocument exception
|
|
16582
16611
|
caretContainer = importNode(editor.getDoc(), createCaretContainer(true).dom);
|
|
16583
16612
|
textNode = caretContainer.firstChild;
|
|
@@ -16645,7 +16674,7 @@
|
|
|
16645
16674
|
const caretContainer = getParentCaretContainer(editor.getBody(), formatNode);
|
|
16646
16675
|
const parentsAfter = isNonNullable(caretContainer) ? dom.getParents(formatNode.parentNode, always, caretContainer) : [];
|
|
16647
16676
|
const newCaretContainer = createCaretContainer(false).dom;
|
|
16648
|
-
insertCaretContainerNode(editor, newCaretContainer, caretContainer
|
|
16677
|
+
insertCaretContainerNode(editor, newCaretContainer, caretContainer ?? formatNode);
|
|
16649
16678
|
const cleanedFormatNode = cleanFormatNode(editor, newCaretContainer, formatNode, name, vars, similar);
|
|
16650
16679
|
const caretTextNode = insertFormatNodesIntoCaretContainer([
|
|
16651
16680
|
...parents,
|
|
@@ -16776,12 +16805,11 @@
|
|
|
16776
16805
|
return next;
|
|
16777
16806
|
};
|
|
16778
16807
|
const mergeSiblings = (editor, format, vars, node) => {
|
|
16779
|
-
var _a;
|
|
16780
16808
|
// Merge next and previous siblings if they are similar <b>text</b><b>text</b> becomes <b>texttext</b>
|
|
16781
16809
|
// Note: mergeSiblingNodes attempts to not merge sibilings if they are noneditable
|
|
16782
16810
|
if (node && format.merge_siblings !== false) {
|
|
16783
16811
|
// Previous sibling
|
|
16784
|
-
const newNode =
|
|
16812
|
+
const newNode = mergeSiblingsNodes(editor, getNonWhiteSpaceSibling(node), node) ?? node;
|
|
16785
16813
|
// Next sibling
|
|
16786
16814
|
mergeSiblingsNodes(editor, newNode, getNonWhiteSpaceSibling(newNode, true));
|
|
16787
16815
|
}
|
|
@@ -16868,9 +16896,8 @@
|
|
|
16868
16896
|
return node;
|
|
16869
16897
|
};
|
|
16870
16898
|
const wrap$1 = (dom, node, name, attrs) => {
|
|
16871
|
-
var _a;
|
|
16872
16899
|
const wrapper = dom.create(name, attrs);
|
|
16873
|
-
|
|
16900
|
+
node.parentNode?.insertBefore(wrapper, node);
|
|
16874
16901
|
wrapper.appendChild(node);
|
|
16875
16902
|
return wrapper;
|
|
16876
16903
|
};
|
|
@@ -17111,7 +17138,6 @@
|
|
|
17111
17138
|
return editor.dom.rename(clone, newName);
|
|
17112
17139
|
}, constant(null));
|
|
17113
17140
|
const wrapAndSplit = (editor, formatList, formatRoot, container, target, split, format, vars) => {
|
|
17114
|
-
var _a, _b;
|
|
17115
17141
|
let lastClone;
|
|
17116
17142
|
let firstClone;
|
|
17117
17143
|
const dom = editor.dom;
|
|
@@ -17139,11 +17165,11 @@
|
|
|
17139
17165
|
}
|
|
17140
17166
|
// Never split block elements if the format is mixed
|
|
17141
17167
|
if (split && (!format.mixed || !dom.isBlock(formatRoot))) {
|
|
17142
|
-
container =
|
|
17168
|
+
container = dom.split(formatRoot, container) ?? container;
|
|
17143
17169
|
}
|
|
17144
17170
|
// Wrap container in cloned formats
|
|
17145
17171
|
if (lastClone && firstClone) {
|
|
17146
|
-
|
|
17172
|
+
target.parentNode?.insertBefore(lastClone, target);
|
|
17147
17173
|
firstClone.appendChild(target);
|
|
17148
17174
|
// After splitting the nodes may match with other siblings so we need to attempt to merge them
|
|
17149
17175
|
// Note: We can't use MergeFormats, as that'd create a circular dependency
|
|
@@ -17533,14 +17559,14 @@
|
|
|
17533
17559
|
node.empty().append(new AstNode('#text', 3)).value = nbsp;
|
|
17534
17560
|
}
|
|
17535
17561
|
};
|
|
17536
|
-
const isPaddedWithNbsp = (node) =>
|
|
17562
|
+
const isPaddedWithNbsp = (node) => hasOnlyChild(node, '#text') && node?.firstChild?.value === nbsp;
|
|
17537
17563
|
const hasOnlyChild = (node, name) => {
|
|
17538
|
-
const firstChild = node
|
|
17564
|
+
const firstChild = node?.firstChild;
|
|
17539
17565
|
return isNonNullable(firstChild) && firstChild === node.lastChild && firstChild.name === name;
|
|
17540
17566
|
};
|
|
17541
17567
|
const isPadded = (schema, node) => {
|
|
17542
17568
|
const rule = schema.getElementRule(node.name);
|
|
17543
|
-
return
|
|
17569
|
+
return rule?.paddEmpty === true;
|
|
17544
17570
|
};
|
|
17545
17571
|
const isEmpty$2 = (schema, nonEmptyElements, whitespaceElements, node) => node.isEmpty(nonEmptyElements, whitespaceElements, (node) => isPadded(schema, node));
|
|
17546
17572
|
const isLineBreakNode = (node, isBlock) => isNonNullable(node) && (isBlock(node) || node.name === 'br');
|
|
@@ -17724,7 +17750,7 @@
|
|
|
17724
17750
|
}
|
|
17725
17751
|
// heading element is valid if it is the only one child of summary
|
|
17726
17752
|
if (isSummary(parent) && isHeading(node)) {
|
|
17727
|
-
return !(
|
|
17753
|
+
return !(parent?.firstChild === node && parent?.lastChild === node);
|
|
17728
17754
|
}
|
|
17729
17755
|
return false;
|
|
17730
17756
|
};
|
|
@@ -17846,10 +17872,9 @@
|
|
|
17846
17872
|
});
|
|
17847
17873
|
};
|
|
17848
17874
|
const addFilters = (domParser, settings, schema) => {
|
|
17849
|
-
var _a;
|
|
17850
17875
|
const styles = Styles();
|
|
17851
17876
|
if (settings.convert_fonts_to_spans) {
|
|
17852
|
-
addFontToSpansFilter(domParser, styles, Tools.explode(
|
|
17877
|
+
addFontToSpansFilter(domParser, styles, Tools.explode(settings.font_size_legacy_values ?? ''));
|
|
17853
17878
|
}
|
|
17854
17879
|
addStrikeFilter(domParser, schema, styles);
|
|
17855
17880
|
};
|
|
@@ -17873,7 +17898,7 @@
|
|
|
17873
17898
|
try {
|
|
17874
17899
|
return decodeURIComponent(data);
|
|
17875
17900
|
}
|
|
17876
|
-
catch
|
|
17901
|
+
catch {
|
|
17877
17902
|
return data;
|
|
17878
17903
|
}
|
|
17879
17904
|
};
|
|
@@ -17902,7 +17927,7 @@
|
|
|
17902
17927
|
try {
|
|
17903
17928
|
str = atob(data);
|
|
17904
17929
|
}
|
|
17905
|
-
catch
|
|
17930
|
+
catch {
|
|
17906
17931
|
return Optional.none();
|
|
17907
17932
|
}
|
|
17908
17933
|
}
|
|
@@ -17937,8 +17962,7 @@
|
|
|
17937
17962
|
resolve(reader.result);
|
|
17938
17963
|
};
|
|
17939
17964
|
reader.onerror = () => {
|
|
17940
|
-
|
|
17941
|
-
reject((_a = reader.error) === null || _a === void 0 ? void 0 : _a.message);
|
|
17965
|
+
reject(reader.error?.message);
|
|
17942
17966
|
};
|
|
17943
17967
|
reader.readAsDataURL(blob);
|
|
17944
17968
|
});
|
|
@@ -18053,7 +18077,6 @@
|
|
|
18053
18077
|
}
|
|
18054
18078
|
};
|
|
18055
18079
|
const register$4 = (parser, settings) => {
|
|
18056
|
-
var _a, _b;
|
|
18057
18080
|
const schema = parser.schema;
|
|
18058
18081
|
parser.addAttributeFilter('href', (nodes) => {
|
|
18059
18082
|
let i = nodes.length;
|
|
@@ -18120,11 +18143,10 @@
|
|
|
18120
18143
|
const validClasses = schema.getValidClasses();
|
|
18121
18144
|
if (settings.validate && validClasses) {
|
|
18122
18145
|
parser.addAttributeFilter('class', (nodes) => {
|
|
18123
|
-
var _a;
|
|
18124
18146
|
let i = nodes.length;
|
|
18125
18147
|
while (i--) {
|
|
18126
18148
|
const node = nodes[i];
|
|
18127
|
-
const clazz =
|
|
18149
|
+
const clazz = node.attr('class') ?? '';
|
|
18128
18150
|
const classList = Tools.explode(clazz, ' ');
|
|
18129
18151
|
let classValue = '';
|
|
18130
18152
|
for (let ci = 0; ci < classList.length; ci++) {
|
|
@@ -18153,8 +18175,8 @@
|
|
|
18153
18175
|
});
|
|
18154
18176
|
}
|
|
18155
18177
|
registerBase64ImageFilter(parser, settings);
|
|
18156
|
-
const shouldSandboxIframes =
|
|
18157
|
-
const sandboxIframesExclusions = unique$1(
|
|
18178
|
+
const shouldSandboxIframes = settings.sandbox_iframes ?? false;
|
|
18179
|
+
const sandboxIframesExclusions = unique$1(settings.sandbox_iframes_exclusions ?? []);
|
|
18158
18180
|
if (settings.convert_unsafe_embeds) {
|
|
18159
18181
|
parser.addNodeFilter('object,embed', (nodes) => each$e(nodes, (node) => {
|
|
18160
18182
|
node.replace(createSafeEmbed({
|
|
@@ -19544,7 +19566,7 @@
|
|
|
19544
19566
|
// Might throw malformed URI sequence
|
|
19545
19567
|
return decodeURIComponent(encodedUri);
|
|
19546
19568
|
}
|
|
19547
|
-
catch
|
|
19569
|
+
catch {
|
|
19548
19570
|
// Fallback to non UTF-8 decoder
|
|
19549
19571
|
return unescape(encodedUri);
|
|
19550
19572
|
}
|
|
@@ -19603,11 +19625,10 @@
|
|
|
19603
19625
|
}
|
|
19604
19626
|
}
|
|
19605
19627
|
static getDocumentBaseUrl(loc) {
|
|
19606
|
-
var _a;
|
|
19607
19628
|
let baseUrl;
|
|
19608
19629
|
// Pass applewebdata:// and other non web protocols though
|
|
19609
19630
|
if (loc.protocol.indexOf('http') !== 0 && loc.protocol !== 'file:') {
|
|
19610
|
-
baseUrl =
|
|
19631
|
+
baseUrl = loc.href ?? '';
|
|
19611
19632
|
}
|
|
19612
19633
|
else {
|
|
19613
19634
|
baseUrl = loc.protocol + '//' + loc.host + loc.pathname;
|
|
@@ -19620,6 +19641,21 @@
|
|
|
19620
19641
|
}
|
|
19621
19642
|
return baseUrl;
|
|
19622
19643
|
}
|
|
19644
|
+
source;
|
|
19645
|
+
protocol;
|
|
19646
|
+
authority;
|
|
19647
|
+
userInfo;
|
|
19648
|
+
user;
|
|
19649
|
+
password;
|
|
19650
|
+
host;
|
|
19651
|
+
port;
|
|
19652
|
+
relative;
|
|
19653
|
+
path = '';
|
|
19654
|
+
directory = '';
|
|
19655
|
+
file;
|
|
19656
|
+
query;
|
|
19657
|
+
anchor;
|
|
19658
|
+
settings;
|
|
19623
19659
|
/**
|
|
19624
19660
|
* Constructs a new URI instance.
|
|
19625
19661
|
*
|
|
@@ -19629,8 +19665,6 @@
|
|
|
19629
19665
|
* @param {Object} settings Optional settings object.
|
|
19630
19666
|
*/
|
|
19631
19667
|
constructor(url, settings = {}) {
|
|
19632
|
-
this.path = '';
|
|
19633
|
-
this.directory = '';
|
|
19634
19668
|
url = trim(url);
|
|
19635
19669
|
this.settings = settings;
|
|
19636
19670
|
const baseUri = settings.base_uri;
|
|
@@ -19649,7 +19683,7 @@
|
|
|
19649
19683
|
// Relative path http:// or protocol relative //path
|
|
19650
19684
|
if (!/^[\w\-]*:?\/\//.test(url)) {
|
|
19651
19685
|
const baseUrl = baseUri ? baseUri.path : new URI(document.location.href).directory;
|
|
19652
|
-
if (
|
|
19686
|
+
if (baseUri?.protocol === '') {
|
|
19653
19687
|
url = '//mce_host' + self.toAbsPath(baseUrl, url);
|
|
19654
19688
|
}
|
|
19655
19689
|
else {
|
|
@@ -19934,19 +19968,18 @@
|
|
|
19934
19968
|
const internalElementAttr = 'data-mce-type';
|
|
19935
19969
|
let uid = 0;
|
|
19936
19970
|
const processNode = (node, settings, schema, scope, evt) => {
|
|
19937
|
-
var _a, _b, _c, _d;
|
|
19938
19971
|
const validate = settings.validate;
|
|
19939
19972
|
const specialElements = schema.getSpecialElements();
|
|
19940
19973
|
if (node.nodeType === COMMENT) {
|
|
19941
19974
|
// Pad conditional comments if they aren't allowed
|
|
19942
|
-
if (!settings.allow_conditional_comments && /^\[if/i.test(
|
|
19975
|
+
if (!settings.allow_conditional_comments && /^\[if/i.test(node.nodeValue ?? '')) {
|
|
19943
19976
|
node.nodeValue = ' ' + node.nodeValue;
|
|
19944
19977
|
}
|
|
19945
19978
|
if (settings.sanitize && settings.allow_html_in_comments && isString(node.nodeValue)) {
|
|
19946
19979
|
node.nodeValue = encodeData(node.nodeValue);
|
|
19947
19980
|
}
|
|
19948
19981
|
}
|
|
19949
|
-
const lcTagName =
|
|
19982
|
+
const lcTagName = evt?.tagName ?? node.nodeName.toLowerCase();
|
|
19950
19983
|
if (scope !== 'html' && schema.isValid(scope)) {
|
|
19951
19984
|
if (isNonNullable(evt)) {
|
|
19952
19985
|
evt.allowedTags[lcTagName] = true;
|
|
@@ -19992,10 +20025,10 @@
|
|
|
19992
20025
|
// Validate the element using the attribute rules
|
|
19993
20026
|
if (validate && rule && !isInternalElement) {
|
|
19994
20027
|
// Fix the attributes for the element, unwrapping it if we have to
|
|
19995
|
-
each$e(
|
|
20028
|
+
each$e(rule.attributesForced ?? [], (attr) => {
|
|
19996
20029
|
set$4(element, attr.name, attr.value === '{$uid}' ? `mce_${uid++}` : attr.value);
|
|
19997
20030
|
});
|
|
19998
|
-
each$e(
|
|
20031
|
+
each$e(rule.attributesDefault ?? [], (attr) => {
|
|
19999
20032
|
if (!has$1(element, attr.name)) {
|
|
20000
20033
|
set$4(element, attr.name, attr.value === '{$uid}' ? `mce_${uid++}` : attr.value);
|
|
20001
20034
|
}
|
|
@@ -20022,7 +20055,7 @@
|
|
|
20022
20055
|
evt.keepAttr = shouldKeepAttribute(settings, schema, scope, tagName, attrName, attrValue);
|
|
20023
20056
|
if (evt.keepAttr) {
|
|
20024
20057
|
evt.allowedAttributes[attrName] = true;
|
|
20025
|
-
if (
|
|
20058
|
+
if (isBooleanAttributeOfNonCustomElement(attrName, schema, ele.nodeName)) {
|
|
20026
20059
|
evt.attrValue = attrName;
|
|
20027
20060
|
}
|
|
20028
20061
|
// We need to tell DOMPurify to forcibly keep the attribute if it's an SVG data URI and svg data URIs are allowed
|
|
@@ -20044,7 +20077,7 @@
|
|
|
20044
20077
|
(!settings.validate || schema.isValid(tagName, attrName) || startsWith(attrName, 'data-') || startsWith(attrName, 'aria-'));
|
|
20045
20078
|
};
|
|
20046
20079
|
const isRequiredAttributeOfInternalElement = (ele, attrName) => ele.hasAttribute(internalElementAttr) && (attrName === 'id' || attrName === 'class' || attrName === 'style');
|
|
20047
|
-
const
|
|
20080
|
+
const isBooleanAttributeOfNonCustomElement = (attrName, schema, nodeName) => attrName in schema.getBoolAttrs() && !has$2(schema.getCustomElements(), nodeName.toLowerCase());
|
|
20048
20081
|
const filterAttributes = (ele, settings, schema, scope) => {
|
|
20049
20082
|
const { attributes } = ele;
|
|
20050
20083
|
for (let i = attributes.length - 1; i >= 0; i--) {
|
|
@@ -20054,7 +20087,7 @@
|
|
|
20054
20087
|
if (!shouldKeepAttribute(settings, schema, scope, ele.tagName.toLowerCase(), attrName, attrValue) && !isRequiredAttributeOfInternalElement(ele, attrName)) {
|
|
20055
20088
|
ele.removeAttribute(attrName);
|
|
20056
20089
|
}
|
|
20057
|
-
else if (
|
|
20090
|
+
else if (isBooleanAttributeOfNonCustomElement(attrName, schema, ele.nodeName)) {
|
|
20058
20091
|
ele.setAttribute(attrName, attrName);
|
|
20059
20092
|
}
|
|
20060
20093
|
}
|
|
@@ -20142,10 +20175,9 @@
|
|
|
20142
20175
|
}
|
|
20143
20176
|
};
|
|
20144
20177
|
purify$1.addHook('uponSanitizeElement', (node, evt) => {
|
|
20145
|
-
var _a;
|
|
20146
20178
|
// We know the node is an element as we have
|
|
20147
20179
|
// passed an element to the purify.sanitize function below
|
|
20148
|
-
const lcTagName =
|
|
20180
|
+
const lcTagName = evt.tagName ?? node.nodeName.toLowerCase();
|
|
20149
20181
|
const keepElementOpt = isValidElementOpt(node, lcTagName);
|
|
20150
20182
|
keepElementOpt.each((keepElement) => {
|
|
20151
20183
|
evt.allowedTags[lcTagName] = keepElement;
|
|
@@ -20227,7 +20259,7 @@
|
|
|
20227
20259
|
* @class tinymce.html.DomParser
|
|
20228
20260
|
* @version 3.4
|
|
20229
20261
|
*/
|
|
20230
|
-
const extraBlockLikeElements = ['script', 'style', 'template', 'param'];
|
|
20262
|
+
const extraBlockLikeElements = ['script', 'style', 'template', 'param', 'meta', 'title', 'link'];
|
|
20231
20263
|
const makeMap = Tools.makeMap, extend$1 = Tools.extend;
|
|
20232
20264
|
const transferChildren = (parent, nativeParent, specialElements, nsSanitizer, decodeComments) => {
|
|
20233
20265
|
const parentName = parent.name;
|
|
@@ -20340,11 +20372,10 @@
|
|
|
20340
20372
|
return isBlock(node.parent) && (node.parent !== root || args.isRootContent === true);
|
|
20341
20373
|
};
|
|
20342
20374
|
const preprocess = (node) => {
|
|
20343
|
-
var _a;
|
|
20344
20375
|
if (node.type === 3) {
|
|
20345
20376
|
// Remove leading whitespace here, so that all whitespace in nodes to the left of us has already been fixed
|
|
20346
20377
|
if (!hasWhitespaceParent(node)) {
|
|
20347
|
-
let text =
|
|
20378
|
+
let text = node.value ?? '';
|
|
20348
20379
|
text = text.replace(allWhiteSpaceRegExp, ' ');
|
|
20349
20380
|
if (isLineBreakNode(node.prev, isBlock) || isAtEdgeOfBlock(node, true)) {
|
|
20350
20381
|
text = text.replace(startWhiteSpaceRegExp, '');
|
|
@@ -20362,7 +20393,6 @@
|
|
|
20362
20393
|
}
|
|
20363
20394
|
};
|
|
20364
20395
|
const postprocess = (node) => {
|
|
20365
|
-
var _a;
|
|
20366
20396
|
if (node.type === 1) {
|
|
20367
20397
|
// Check for empty nodes here, because children will have been processed and (if necessary) emptied / removed already
|
|
20368
20398
|
const elementRule = schema.getElementRule(node.name);
|
|
@@ -20387,7 +20417,7 @@
|
|
|
20387
20417
|
else if (node.type === 3) {
|
|
20388
20418
|
// Removing trailing whitespace here, so that all whitespace in nodes to the right of us has already been fixed
|
|
20389
20419
|
if (!hasWhitespaceParent(node)) {
|
|
20390
|
-
let text =
|
|
20420
|
+
let text = node.value ?? '';
|
|
20391
20421
|
if (node.next && isBlock(node.next) || isAtEdgeOfBlock(node, false)) {
|
|
20392
20422
|
text = text.replace(endWhiteSpaceRegExp, '');
|
|
20393
20423
|
}
|
|
@@ -20403,8 +20433,7 @@
|
|
|
20403
20433
|
return [preprocess, postprocess];
|
|
20404
20434
|
};
|
|
20405
20435
|
const getRootBlockName = (settings, args) => {
|
|
20406
|
-
|
|
20407
|
-
const name = (_a = args.forced_root_block) !== null && _a !== void 0 ? _a : settings.forced_root_block;
|
|
20436
|
+
const name = args.forced_root_block ?? settings.forced_root_block;
|
|
20408
20437
|
if (name === false) {
|
|
20409
20438
|
return '';
|
|
20410
20439
|
}
|
|
@@ -20532,15 +20561,14 @@
|
|
|
20532
20561
|
// Removes whitespace at beginning and end of block so:
|
|
20533
20562
|
// <p> x </p> -> <p>x</p>
|
|
20534
20563
|
const trim = (rootBlock) => {
|
|
20535
|
-
var _a, _b;
|
|
20536
20564
|
if (rootBlock) {
|
|
20537
20565
|
node = rootBlock.firstChild;
|
|
20538
20566
|
if (node && node.type === 3) {
|
|
20539
|
-
node.value =
|
|
20567
|
+
node.value = node.value?.replace(startWhiteSpaceRegExp, '');
|
|
20540
20568
|
}
|
|
20541
20569
|
node = rootBlock.lastChild;
|
|
20542
20570
|
if (node && node.type === 3) {
|
|
20543
|
-
node.value =
|
|
20571
|
+
node.value = node.value?.replace(endWhiteSpaceRegExp, '');
|
|
20544
20572
|
}
|
|
20545
20573
|
}
|
|
20546
20574
|
};
|
|
@@ -20581,10 +20609,9 @@
|
|
|
20581
20609
|
* const rootNode = tinymce.html.DomParser({...}).parse('<b>text</b>');
|
|
20582
20610
|
*/
|
|
20583
20611
|
const parse = (html, args = {}) => {
|
|
20584
|
-
var _a, _b;
|
|
20585
20612
|
const validate = defaultedSettings.validate;
|
|
20586
|
-
const preferFullDocument = (
|
|
20587
|
-
const rootName =
|
|
20613
|
+
const preferFullDocument = (args.context ?? defaultedSettings.root_name) === '#document';
|
|
20614
|
+
const rootName = args.context ?? (preferFullDocument ? 'html' : defaultedSettings.root_name);
|
|
20588
20615
|
// Parse and sanitize the content
|
|
20589
20616
|
const element = parseAndSanitizeWithContext(html, rootName, args.format, preferFullDocument);
|
|
20590
20617
|
updateChildren(schema, element);
|
|
@@ -20939,7 +20966,7 @@
|
|
|
20939
20966
|
}
|
|
20940
20967
|
// Skip last child if it's an empty block
|
|
20941
20968
|
if (isEmptyFragmentElement(schema, lastChild)) {
|
|
20942
|
-
lastChild = lastChild
|
|
20969
|
+
lastChild = lastChild?.prev;
|
|
20943
20970
|
}
|
|
20944
20971
|
if (!firstChild || firstChild !== lastChild) {
|
|
20945
20972
|
return false;
|
|
@@ -20947,15 +20974,14 @@
|
|
|
20947
20974
|
return firstChild.name === 'ul' || firstChild.name === 'ol';
|
|
20948
20975
|
};
|
|
20949
20976
|
const cleanupDomFragment = (domFragment) => {
|
|
20950
|
-
var _a, _b;
|
|
20951
20977
|
const firstChild = domFragment.firstChild;
|
|
20952
20978
|
const lastChild = domFragment.lastChild;
|
|
20953
20979
|
// TODO: remove the meta tag from paste logic
|
|
20954
20980
|
if (firstChild && firstChild.nodeName === 'META') {
|
|
20955
|
-
|
|
20981
|
+
firstChild.parentNode?.removeChild(firstChild);
|
|
20956
20982
|
}
|
|
20957
20983
|
if (lastChild && lastChild.id === 'mce_marker') {
|
|
20958
|
-
|
|
20984
|
+
lastChild.parentNode?.removeChild(lastChild);
|
|
20959
20985
|
}
|
|
20960
20986
|
return domFragment;
|
|
20961
20987
|
};
|
|
@@ -20965,8 +20991,7 @@
|
|
|
20965
20991
|
return cleanupDomFragment(domFragment);
|
|
20966
20992
|
};
|
|
20967
20993
|
const listItems = (elm) => {
|
|
20968
|
-
|
|
20969
|
-
return filter$5((_a = elm === null || elm === void 0 ? void 0 : elm.childNodes) !== null && _a !== void 0 ? _a : [], (child) => {
|
|
20994
|
+
return filter$5(elm?.childNodes ?? [], (child) => {
|
|
20970
20995
|
return child.nodeName === 'LI';
|
|
20971
20996
|
});
|
|
20972
20997
|
};
|
|
@@ -20974,7 +20999,7 @@
|
|
|
20974
20999
|
return node.data === nbsp || isBr$7(node);
|
|
20975
21000
|
};
|
|
20976
21001
|
const isListItemPadded = (node) => {
|
|
20977
|
-
return isNonNullable(node
|
|
21002
|
+
return isNonNullable(node?.firstChild) && node.firstChild === node.lastChild && isPadding(node.firstChild);
|
|
20978
21003
|
};
|
|
20979
21004
|
const isEmptyOrPadded = (elm) => {
|
|
20980
21005
|
return !elm.firstChild || isListItemPadded(elm);
|
|
@@ -21047,7 +21072,7 @@
|
|
|
21047
21072
|
const caretPos = CaretPosition.fromRangeStart(rng);
|
|
21048
21073
|
const caretWalker = CaretWalker(dom.getRoot());
|
|
21049
21074
|
const newPos = location === BEGINNING ? caretWalker.prev(caretPos) : caretWalker.next(caretPos);
|
|
21050
|
-
const newPosNode = newPos
|
|
21075
|
+
const newPosNode = newPos?.getNode();
|
|
21051
21076
|
return newPosNode ? getParentLi(dom, newPosNode) !== liTarget : true;
|
|
21052
21077
|
};
|
|
21053
21078
|
if (!liTarget) {
|
|
@@ -21066,7 +21091,6 @@
|
|
|
21066
21091
|
|
|
21067
21092
|
const mergeableWrappedElements = ['pre'];
|
|
21068
21093
|
const shouldPasteContentOnly = (dom, fragment, parentNode, root) => {
|
|
21069
|
-
var _a;
|
|
21070
21094
|
const firstNode = fragment.firstChild;
|
|
21071
21095
|
const lastNode = fragment.lastChild;
|
|
21072
21096
|
const last = lastNode.attr('data-mce-type') === 'bookmark' ? lastNode.prev : lastNode;
|
|
@@ -21074,7 +21098,7 @@
|
|
|
21074
21098
|
const isWrappedElement = contains$2(mergeableWrappedElements, firstNode.name);
|
|
21075
21099
|
if (isPastingSingleElement && isWrappedElement) {
|
|
21076
21100
|
const isContentEditable = firstNode.attr('contenteditable') !== 'false';
|
|
21077
|
-
const isPastingInTheSameBlockTag =
|
|
21101
|
+
const isPastingInTheSameBlockTag = dom.getParent(parentNode, dom.isBlock)?.nodeName.toLowerCase() === firstNode.name;
|
|
21078
21102
|
const isPastingInContentEditable = Optional.from(getContentEditableRoot$1(root, parentNode)).forall(isContentEditableTrue$3);
|
|
21079
21103
|
return isContentEditable && isPastingInTheSameBlockTag && isPastingInContentEditable;
|
|
21080
21104
|
}
|
|
@@ -21102,11 +21126,10 @@
|
|
|
21102
21126
|
}
|
|
21103
21127
|
};
|
|
21104
21128
|
const validInsertion = (editor, value, parentNode) => {
|
|
21105
|
-
var _a;
|
|
21106
21129
|
// Should never insert content into bogus elements, since these can
|
|
21107
21130
|
// be resize handles or similar
|
|
21108
21131
|
if (parentNode.getAttribute('data-mce-bogus') === 'all') {
|
|
21109
|
-
|
|
21132
|
+
parentNode.parentNode?.insertBefore(editor.dom.createFragment(value), parentNode);
|
|
21110
21133
|
}
|
|
21111
21134
|
else {
|
|
21112
21135
|
if (isEditableEmptyBlock(editor.dom, parentNode)) {
|
|
@@ -21170,7 +21193,6 @@
|
|
|
21170
21193
|
return isNonNullable(node) && !editor.schema.getVoidElements()[node.nodeName];
|
|
21171
21194
|
};
|
|
21172
21195
|
const moveSelectionToMarker = (editor, marker) => {
|
|
21173
|
-
var _a, _b, _c;
|
|
21174
21196
|
let nextRng;
|
|
21175
21197
|
const dom = editor.dom;
|
|
21176
21198
|
const selection = editor.selection;
|
|
@@ -21190,11 +21212,11 @@
|
|
|
21190
21212
|
// If previous sibling is a text node set the selection to the end of that node
|
|
21191
21213
|
const node = marker.previousSibling;
|
|
21192
21214
|
if (isText$b(node)) {
|
|
21193
|
-
rng.setStart(node,
|
|
21215
|
+
rng.setStart(node, node.nodeValue?.length ?? 0);
|
|
21194
21216
|
const node2 = marker.nextSibling;
|
|
21195
21217
|
if (isText$b(node2)) {
|
|
21196
21218
|
node.appendData(node2.data);
|
|
21197
|
-
|
|
21219
|
+
node2.parentNode?.removeChild(node2);
|
|
21198
21220
|
}
|
|
21199
21221
|
}
|
|
21200
21222
|
else {
|
|
@@ -21206,7 +21228,7 @@
|
|
|
21206
21228
|
let caretPos = CaretPosition.fromRangeStart(rng);
|
|
21207
21229
|
const caretWalker = CaretWalker(editor.getBody());
|
|
21208
21230
|
caretPos = caretWalker.next(caretPos);
|
|
21209
|
-
return caretPos
|
|
21231
|
+
return caretPos?.toRange();
|
|
21210
21232
|
};
|
|
21211
21233
|
// Remove the marker node and set the new range
|
|
21212
21234
|
const parentBlock = dom.getParent(marker, dom.isBlock);
|
|
@@ -21257,11 +21279,9 @@
|
|
|
21257
21279
|
return Optional.none();
|
|
21258
21280
|
};
|
|
21259
21281
|
const notHeadingsInSummary = (dom, node, fragment) => {
|
|
21260
|
-
|
|
21261
|
-
return exists(fragment.children(), isHeading) && ((_a = dom.getParent(node, dom.isBlock)) === null || _a === void 0 ? void 0 : _a.nodeName) === 'SUMMARY';
|
|
21282
|
+
return exists(fragment.children(), isHeading) && dom.getParent(node, dom.isBlock)?.nodeName === 'SUMMARY';
|
|
21262
21283
|
};
|
|
21263
21284
|
const insertHtmlAtCaret = (editor, value, details) => {
|
|
21264
|
-
var _a;
|
|
21265
21285
|
const selection = editor.selection;
|
|
21266
21286
|
const dom = editor.dom;
|
|
21267
21287
|
// Setup parser and serializer
|
|
@@ -21310,7 +21330,7 @@
|
|
|
21310
21330
|
return value;
|
|
21311
21331
|
}
|
|
21312
21332
|
if (details.paste === true && shouldPasteContentOnly(dom, fragment, parentNode, editor.getBody())) {
|
|
21313
|
-
|
|
21333
|
+
fragment.firstChild?.unwrap();
|
|
21314
21334
|
}
|
|
21315
21335
|
markFragmentElements(fragment);
|
|
21316
21336
|
// Move the caret to a more suitable location
|
|
@@ -21852,7 +21872,7 @@
|
|
|
21852
21872
|
const fallbackElement = (editor) => editor.selection.getStart();
|
|
21853
21873
|
const matchingNode = (editor, parents, format, similar, vars) => {
|
|
21854
21874
|
const isMatchingNode = (node) => {
|
|
21855
|
-
const matchingFormat = editor.formatter.matchNode(node, format, vars
|
|
21875
|
+
const matchingFormat = editor.formatter.matchNode(node, format, vars ?? {}, similar);
|
|
21856
21876
|
return !isUndefined(matchingFormat);
|
|
21857
21877
|
};
|
|
21858
21878
|
const isUnableToMatch = (node) => {
|
|
@@ -21872,7 +21892,7 @@
|
|
|
21872
21892
|
return findUntil$1(parents, isMatchingNode, isUnableToMatch);
|
|
21873
21893
|
};
|
|
21874
21894
|
const getParents = (editor, elm) => {
|
|
21875
|
-
const element = elm
|
|
21895
|
+
const element = elm ?? fallbackElement(editor);
|
|
21876
21896
|
return filter$5(getParents$2(editor.dom, element), (node) => isElement$7(node) && !isBogus$1(node));
|
|
21877
21897
|
};
|
|
21878
21898
|
const updateAndFireChangeCallbacks = (editor, elm, registeredCallbacks) => {
|
|
@@ -22146,7 +22166,6 @@
|
|
|
22146
22166
|
};
|
|
22147
22167
|
const getContextNodeName = (parentBlockOpt) => parentBlockOpt.map((block) => block.nodeName).getOr('div').toLowerCase();
|
|
22148
22168
|
const getTextContent = (editor) => Optional.from(editor.selection.getRng()).map((rng) => {
|
|
22149
|
-
var _a;
|
|
22150
22169
|
const parentBlockOpt = Optional.from(editor.dom.getParent(rng.commonAncestorContainer, editor.dom.isBlock));
|
|
22151
22170
|
const body = editor.getBody();
|
|
22152
22171
|
const contextNodeName = getContextNodeName(parentBlockOpt);
|
|
@@ -22159,7 +22178,7 @@
|
|
|
22159
22178
|
}, rangeContentClone.dom);
|
|
22160
22179
|
const text = getInnerText(bin);
|
|
22161
22180
|
// textContent will not strip leading/trailing spaces since it doesn't consider how it'll render
|
|
22162
|
-
const nonRenderedText = trim$2(
|
|
22181
|
+
const nonRenderedText = trim$2(bin.textContent ?? '');
|
|
22163
22182
|
editor.dom.remove(bin);
|
|
22164
22183
|
if (isCollapsibleWhitespace(nonRenderedText, 0) || isCollapsibleWhitespace(nonRenderedText, nonRenderedText.length - 1)) {
|
|
22165
22184
|
// If the bin contains a trailing/leading space, then we need to inspect the parent block to see if we should include the spaces
|
|
@@ -23176,7 +23195,7 @@
|
|
|
23176
23195
|
try {
|
|
23177
23196
|
return sourceRange.compareBoundaryPoints(how, destinationRange);
|
|
23178
23197
|
}
|
|
23179
|
-
catch
|
|
23198
|
+
catch {
|
|
23180
23199
|
// Gecko throws wrong document exception if the range points
|
|
23181
23200
|
// to nodes that where removed from the dom #6690
|
|
23182
23201
|
// Browsers should mutate existing DOMRange instances so that they always point
|
|
@@ -23204,7 +23223,7 @@
|
|
|
23204
23223
|
rng = processRanges(editor, [rng])[0];
|
|
23205
23224
|
}
|
|
23206
23225
|
}
|
|
23207
|
-
catch
|
|
23226
|
+
catch {
|
|
23208
23227
|
// IE throws unspecified error here if TinyMCE is placed in a frame/iframe
|
|
23209
23228
|
}
|
|
23210
23229
|
// No range found then create an empty one
|
|
@@ -23252,7 +23271,7 @@
|
|
|
23252
23271
|
sel.removeAllRanges();
|
|
23253
23272
|
sel.addRange(rng);
|
|
23254
23273
|
}
|
|
23255
|
-
catch
|
|
23274
|
+
catch {
|
|
23256
23275
|
// IE might throw errors here if the editor is within a hidden container and selection is changed
|
|
23257
23276
|
}
|
|
23258
23277
|
// Forward is set to false and we have an extend function
|
|
@@ -23264,7 +23283,7 @@
|
|
|
23264
23283
|
selectedRange = sel.rangeCount > 0 ? sel.getRangeAt(0) : null;
|
|
23265
23284
|
}
|
|
23266
23285
|
// WebKit edge case selecting images works better using setBaseAndExtent when the image is floated
|
|
23267
|
-
if (!rng.collapsed && rng.startContainer === rng.endContainer &&
|
|
23286
|
+
if (!rng.collapsed && rng.startContainer === rng.endContainer && sel?.setBaseAndExtent) {
|
|
23268
23287
|
if (rng.endOffset - rng.startOffset < 2) {
|
|
23269
23288
|
if (rng.startContainer.hasChildNodes()) {
|
|
23270
23289
|
const node = rng.startContainer.childNodes[rng.startOffset];
|
|
@@ -23310,8 +23329,8 @@
|
|
|
23310
23329
|
const getSelectedBlocks$1 = (startElm, endElm) => getSelectedBlocks(dom, getRng$1(), startElm, endElm);
|
|
23311
23330
|
const isForward = () => {
|
|
23312
23331
|
const sel = getSel();
|
|
23313
|
-
const anchorNode = sel
|
|
23314
|
-
const focusNode = sel
|
|
23332
|
+
const anchorNode = sel?.anchorNode;
|
|
23333
|
+
const focusNode = sel?.focusNode;
|
|
23315
23334
|
// No support for selection direction then always return true
|
|
23316
23335
|
if (!sel || !anchorNode || !focusNode || isRestrictedNode(anchorNode) || isRestrictedNode(focusNode)) {
|
|
23317
23336
|
return true;
|
|
@@ -23324,7 +23343,7 @@
|
|
|
23324
23343
|
focusRange.setStart(focusNode, sel.focusOffset);
|
|
23325
23344
|
focusRange.collapse(true);
|
|
23326
23345
|
}
|
|
23327
|
-
catch
|
|
23346
|
+
catch {
|
|
23328
23347
|
// Safari can generate an invalid selection and error. Silently handle it and default to forward.
|
|
23329
23348
|
// See https://bugs.webkit.org/show_bug.cgi?id=230594.
|
|
23330
23349
|
return true;
|
|
@@ -23554,7 +23573,7 @@
|
|
|
23554
23573
|
const node = nodes[i];
|
|
23555
23574
|
if (node.attr('data-mce-type') === 'bookmark' && !args.cleanup) {
|
|
23556
23575
|
// We maybe dealing with a "filled" bookmark. If so just remove the node, otherwise unwrap it
|
|
23557
|
-
const hasChildren = Optional.from(node.firstChild).exists((firstChild) =>
|
|
23576
|
+
const hasChildren = Optional.from(node.firstChild).exists((firstChild) => !isZwsp(firstChild.value ?? ''));
|
|
23558
23577
|
if (hasChildren) {
|
|
23559
23578
|
node.unwrap();
|
|
23560
23579
|
}
|
|
@@ -23566,7 +23585,6 @@
|
|
|
23566
23585
|
});
|
|
23567
23586
|
// Force script into CDATA sections and remove the mce- prefix also add comments around styles
|
|
23568
23587
|
htmlParser.addNodeFilter('script,style', (nodes, name) => {
|
|
23569
|
-
var _a;
|
|
23570
23588
|
const trim = (value) => {
|
|
23571
23589
|
/* jshint maxlen:255 */
|
|
23572
23590
|
/* eslint max-len:0 */
|
|
@@ -23579,7 +23597,7 @@
|
|
|
23579
23597
|
while (i--) {
|
|
23580
23598
|
const node = nodes[i];
|
|
23581
23599
|
const firstChild = node.firstChild;
|
|
23582
|
-
const value =
|
|
23600
|
+
const value = firstChild?.value ?? '';
|
|
23583
23601
|
if (name === 'script') {
|
|
23584
23602
|
// Remove mce- prefix from script elements and remove default type since the user specified
|
|
23585
23603
|
// a script element without type attribute
|
|
@@ -23604,12 +23622,12 @@
|
|
|
23604
23622
|
while (i--) {
|
|
23605
23623
|
const node = nodes[i];
|
|
23606
23624
|
const value = node.value;
|
|
23607
|
-
if (settings.preserve_cdata &&
|
|
23625
|
+
if (settings.preserve_cdata && value?.indexOf('[CDATA[') === 0) {
|
|
23608
23626
|
node.name = '#cdata';
|
|
23609
23627
|
node.type = 4;
|
|
23610
23628
|
node.value = dom.decode(value.replace(/^\[CDATA\[|\]\]$/g, ''));
|
|
23611
23629
|
}
|
|
23612
|
-
else if (
|
|
23630
|
+
else if (value?.indexOf('mce:protected ') === 0) {
|
|
23613
23631
|
node.name = '#text';
|
|
23614
23632
|
node.type = 3;
|
|
23615
23633
|
node.raw = true;
|
|
@@ -23670,7 +23688,7 @@
|
|
|
23670
23688
|
*/
|
|
23671
23689
|
const trimTrailingBr = (rootNode) => {
|
|
23672
23690
|
const isBr = (node) => {
|
|
23673
|
-
return
|
|
23691
|
+
return node?.name === 'br';
|
|
23674
23692
|
};
|
|
23675
23693
|
const brNode1 = rootNode.lastChild;
|
|
23676
23694
|
if (isBr(brNode1)) {
|
|
@@ -23993,7 +24011,7 @@
|
|
|
23993
24011
|
editor.removed = true;
|
|
23994
24012
|
editor.unbindAllNativeEvents();
|
|
23995
24013
|
// Remove any hidden input
|
|
23996
|
-
if (editor.hasHiddenInput && isNonNullable(element
|
|
24014
|
+
if (editor.hasHiddenInput && isNonNullable(element?.nextSibling)) {
|
|
23997
24015
|
DOM$a.remove(element.nextSibling);
|
|
23998
24016
|
}
|
|
23999
24017
|
fireRemove(editor);
|
|
@@ -24201,9 +24219,8 @@
|
|
|
24201
24219
|
});
|
|
24202
24220
|
});
|
|
24203
24221
|
editor.on('keydown', (e) => {
|
|
24204
|
-
var _a;
|
|
24205
24222
|
// TODO: TINY-11429 Remove this once we remove the use of keycodes
|
|
24206
|
-
const isF12 =
|
|
24223
|
+
const isF12 = e.key?.toLowerCase() === 'f12' || e.keyCode === 123;
|
|
24207
24224
|
if (e.altKey && isF12) {
|
|
24208
24225
|
e.preventDefault();
|
|
24209
24226
|
getTopNotification()
|
|
@@ -24324,7 +24341,7 @@
|
|
|
24324
24341
|
const windowManagerImpl = getImplementation();
|
|
24325
24342
|
windowManagerImpl.alert(message, funcBind(scope ? scope : windowManagerImpl, () => {
|
|
24326
24343
|
restoreFocus(activeEl);
|
|
24327
|
-
callback
|
|
24344
|
+
callback?.();
|
|
24328
24345
|
}));
|
|
24329
24346
|
};
|
|
24330
24347
|
const confirm = (message, callback, scope) => {
|
|
@@ -24332,7 +24349,7 @@
|
|
|
24332
24349
|
const windowManagerImpl = getImplementation();
|
|
24333
24350
|
windowManagerImpl.confirm(message, funcBind(scope ? scope : windowManagerImpl, (state) => {
|
|
24334
24351
|
restoreFocus(activeEl);
|
|
24335
|
-
callback
|
|
24352
|
+
callback?.(state);
|
|
24336
24353
|
}));
|
|
24337
24354
|
};
|
|
24338
24355
|
const close = () => {
|
|
@@ -24447,6 +24464,9 @@
|
|
|
24447
24464
|
const licenseKeyManagerLoadError = (editor, url) => {
|
|
24448
24465
|
logError(editor, 'LicenseKeyManagerLoadError', createLoadError('license key manager', url));
|
|
24449
24466
|
};
|
|
24467
|
+
const componentLoadError = (editor, url) => {
|
|
24468
|
+
logError(editor, 'ComponentLoadError', createLoadError('component', url));
|
|
24469
|
+
};
|
|
24450
24470
|
const pluginInitError = (editor, name, err) => {
|
|
24451
24471
|
const message = I18n.translate(['Failed to initialize plugin: {0}', name]);
|
|
24452
24472
|
fireError(editor, 'PluginLoadError', { message });
|
|
@@ -24609,8 +24629,7 @@
|
|
|
24609
24629
|
return hasApiKey ? 'online' : 'offline';
|
|
24610
24630
|
};
|
|
24611
24631
|
const getLicenseKeyType = (editor) => {
|
|
24612
|
-
|
|
24613
|
-
const licenseKey = (_a = getLicenseKey(editor)) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
24632
|
+
const licenseKey = getLicenseKey(editor)?.toLowerCase();
|
|
24614
24633
|
if (licenseKey === 'gpl') {
|
|
24615
24634
|
return 'gpl';
|
|
24616
24635
|
}
|
|
@@ -24743,7 +24762,7 @@
|
|
|
24743
24762
|
// See: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand#Parameters
|
|
24744
24763
|
editor.getDoc().execCommand(cmd, false, String(state));
|
|
24745
24764
|
}
|
|
24746
|
-
catch
|
|
24765
|
+
catch {
|
|
24747
24766
|
// Ignore
|
|
24748
24767
|
}
|
|
24749
24768
|
};
|
|
@@ -25749,7 +25768,7 @@
|
|
|
25749
25768
|
remove_similar: true,
|
|
25750
25769
|
attributes: {
|
|
25751
25770
|
'lang': '%value',
|
|
25752
|
-
'data-mce-lang': (vars) =>
|
|
25771
|
+
'data-mce-lang': (vars) => vars?.customValue ?? null
|
|
25753
25772
|
}
|
|
25754
25773
|
},
|
|
25755
25774
|
removeformat: [
|
|
@@ -25898,7 +25917,7 @@
|
|
|
25898
25917
|
};
|
|
25899
25918
|
const getRequiredParent = (elm, candidate) => {
|
|
25900
25919
|
const elmRule = schema.getElementRule(elm.nodeName.toLowerCase());
|
|
25901
|
-
const parentsRequired = elmRule
|
|
25920
|
+
const parentsRequired = elmRule?.parentsRequired;
|
|
25902
25921
|
if (parentsRequired && parentsRequired.length) {
|
|
25903
25922
|
return candidate && contains$2(parentsRequired, candidate) ? candidate : parentsRequired[0];
|
|
25904
25923
|
}
|
|
@@ -26017,7 +26036,7 @@
|
|
|
26017
26036
|
return isString(val) ? val.replace(/%(\w+)/g, '') : '';
|
|
26018
26037
|
};
|
|
26019
26038
|
const getComputedStyle = (name, elm) => {
|
|
26020
|
-
return dom.getStyle(elm
|
|
26039
|
+
return dom.getStyle(elm ?? editor.getBody(), name, true);
|
|
26021
26040
|
};
|
|
26022
26041
|
// Create block/inline element to use for preview
|
|
26023
26042
|
if (isString(format)) {
|
|
@@ -26435,7 +26454,7 @@
|
|
|
26435
26454
|
*
|
|
26436
26455
|
* @method add
|
|
26437
26456
|
* @param {Object} level Optional undo level object to add.
|
|
26438
|
-
* @param {
|
|
26457
|
+
* @param {EditorEvent} event Optional event responsible for the creation of the undo level.
|
|
26439
26458
|
* @return {Object} Undo level that got added or null if a level wasn't needed.
|
|
26440
26459
|
*/
|
|
26441
26460
|
add: (level, event) => {
|
|
@@ -26607,10 +26626,9 @@
|
|
|
26607
26626
|
}
|
|
26608
26627
|
};
|
|
26609
26628
|
const setup$w = (editor) => {
|
|
26610
|
-
var _a;
|
|
26611
26629
|
const dom = editor.dom;
|
|
26612
26630
|
const rootBlock = getForcedRootBlock(editor);
|
|
26613
|
-
const placeholder =
|
|
26631
|
+
const placeholder = getPlaceholder(editor) ?? '';
|
|
26614
26632
|
const updatePlaceholder = (e, initial) => {
|
|
26615
26633
|
if (isNonTypingKeyboardEvent(e)) {
|
|
26616
26634
|
return;
|
|
@@ -26649,7 +26667,7 @@
|
|
|
26649
26667
|
const isListItemNode = matchNodeNames(/^(LI|DT|DD)$/);
|
|
26650
26668
|
const isDlItemNode = matchNodeNames(/^(DT|DD)$/);
|
|
26651
26669
|
const isBr$1 = matchNodeName('br');
|
|
26652
|
-
const isFirstChild$1 = (node) =>
|
|
26670
|
+
const isFirstChild$1 = (node) => node.parentNode?.firstChild === node;
|
|
26653
26671
|
const isTextBlock = (editor, node) => isNonNullable(node) && node.nodeName in editor.schema.getTextBlockElements();
|
|
26654
26672
|
const isBlock = (node, blockElements) => isNonNullable(node) && node.nodeName in blockElements;
|
|
26655
26673
|
const isVoid = (editor, node) => isNonNullable(node) && node.nodeName in editor.schema.getVoidElements();
|
|
@@ -27040,11 +27058,10 @@
|
|
|
27040
27058
|
};
|
|
27041
27059
|
|
|
27042
27060
|
const parseSingleItem = (depth, itemSelection, selectionState, item) => {
|
|
27043
|
-
var _a;
|
|
27044
27061
|
if (isComment$1(item)) {
|
|
27045
27062
|
return [{
|
|
27046
27063
|
depth: depth + 1,
|
|
27047
|
-
content:
|
|
27064
|
+
content: item.dom.nodeValue ?? '',
|
|
27048
27065
|
dirty: false,
|
|
27049
27066
|
isSelected: false,
|
|
27050
27067
|
isComment: true
|
|
@@ -27288,12 +27305,11 @@
|
|
|
27288
27305
|
// This way we end up including all the inline elements in the created list.
|
|
27289
27306
|
// For more info look at #TINY-6853
|
|
27290
27307
|
const findBetterContainer = (container, forward) => {
|
|
27291
|
-
var _a;
|
|
27292
27308
|
const walker = new DomTreeWalker(container, findBlockAncestor(container));
|
|
27293
27309
|
const dir = forward ? 'next' : 'prev';
|
|
27294
27310
|
let node;
|
|
27295
27311
|
while ((node = walker[dir]())) {
|
|
27296
|
-
if (!(isVoid(editor, node) || isZwsp$2(node.textContent) ||
|
|
27312
|
+
if (!(isVoid(editor, node) || isZwsp$2(node.textContent) || node.textContent?.length === 0)) {
|
|
27297
27313
|
return Optional.some(node);
|
|
27298
27314
|
}
|
|
27299
27315
|
}
|
|
@@ -27353,7 +27369,6 @@
|
|
|
27353
27369
|
}
|
|
27354
27370
|
}
|
|
27355
27371
|
Tools.each(siblings, (node) => {
|
|
27356
|
-
var _a;
|
|
27357
27372
|
if (isTextBlock(editor, node)) {
|
|
27358
27373
|
textBlocks.push(node);
|
|
27359
27374
|
block = null;
|
|
@@ -27375,7 +27390,7 @@
|
|
|
27375
27390
|
}
|
|
27376
27391
|
if (!block) {
|
|
27377
27392
|
block = dom.create('p');
|
|
27378
|
-
|
|
27393
|
+
node.parentNode?.insertBefore(block, node);
|
|
27379
27394
|
textBlocks.push(block);
|
|
27380
27395
|
}
|
|
27381
27396
|
block.appendChild(node);
|
|
@@ -27444,7 +27459,7 @@
|
|
|
27444
27459
|
editor.selection.setRng(resolveBookmark(bookmark));
|
|
27445
27460
|
};
|
|
27446
27461
|
const isValidLists = (list1, list2) => {
|
|
27447
|
-
return isListNode(list1) && list1.nodeName ===
|
|
27462
|
+
return isListNode(list1) && list1.nodeName === list2?.nodeName;
|
|
27448
27463
|
};
|
|
27449
27464
|
const hasSameListStyle = (dom, list1, list2) => {
|
|
27450
27465
|
const targetStyle = dom.getStyle(list1, 'list-style-type', true);
|
|
@@ -28261,12 +28276,11 @@
|
|
|
28261
28276
|
};
|
|
28262
28277
|
|
|
28263
28278
|
const backspaceDelete$7 = (editor, forward) => {
|
|
28264
|
-
var _a;
|
|
28265
28279
|
const dom = editor.dom;
|
|
28266
28280
|
const startBlock = dom.getParent(editor.selection.getStart(), dom.isBlock);
|
|
28267
28281
|
const endBlock = dom.getParent(editor.selection.getEnd(), dom.isBlock);
|
|
28268
28282
|
const body = editor.getBody();
|
|
28269
|
-
const startBlockName =
|
|
28283
|
+
const startBlockName = startBlock?.nodeName?.toLowerCase();
|
|
28270
28284
|
// Only act on single root div that is not empty
|
|
28271
28285
|
if (startBlockName === 'div' && startBlock && endBlock && startBlock === body.firstChild && endBlock === body.lastChild && !dom.isEmpty(body)) {
|
|
28272
28286
|
const wrapper = startBlock.cloneNode(false);
|
|
@@ -28303,12 +28317,10 @@
|
|
|
28303
28317
|
const startsWithCaretContainer = (node) => isText$2(node) && node.data[0] === ZWSP$1;
|
|
28304
28318
|
const endsWithCaretContainer = (node) => isText$2(node) && node.data[node.data.length - 1] === ZWSP$1;
|
|
28305
28319
|
const createZwsp = (node) => {
|
|
28306
|
-
|
|
28307
|
-
const doc = (_a = node.ownerDocument) !== null && _a !== void 0 ? _a : document;
|
|
28320
|
+
const doc = node.ownerDocument ?? document;
|
|
28308
28321
|
return doc.createTextNode(ZWSP$1);
|
|
28309
28322
|
};
|
|
28310
28323
|
const insertBefore$1 = (node) => {
|
|
28311
|
-
var _a;
|
|
28312
28324
|
if (isText$2(node.previousSibling)) {
|
|
28313
28325
|
if (endsWithCaretContainer(node.previousSibling)) {
|
|
28314
28326
|
return node.previousSibling;
|
|
@@ -28329,12 +28341,11 @@
|
|
|
28329
28341
|
}
|
|
28330
28342
|
else {
|
|
28331
28343
|
const newNode = createZwsp(node);
|
|
28332
|
-
|
|
28344
|
+
node.parentNode?.insertBefore(newNode, node);
|
|
28333
28345
|
return newNode;
|
|
28334
28346
|
}
|
|
28335
28347
|
};
|
|
28336
28348
|
const insertAfter$1 = (node) => {
|
|
28337
|
-
var _a, _b;
|
|
28338
28349
|
if (isText$2(node.nextSibling)) {
|
|
28339
28350
|
if (startsWithCaretContainer(node.nextSibling)) {
|
|
28340
28351
|
return node.nextSibling;
|
|
@@ -28356,10 +28367,10 @@
|
|
|
28356
28367
|
else {
|
|
28357
28368
|
const newNode = createZwsp(node);
|
|
28358
28369
|
if (node.nextSibling) {
|
|
28359
|
-
|
|
28370
|
+
node.parentNode?.insertBefore(newNode, node.nextSibling);
|
|
28360
28371
|
}
|
|
28361
28372
|
else {
|
|
28362
|
-
|
|
28373
|
+
node.parentNode?.appendChild(newNode);
|
|
28363
28374
|
}
|
|
28364
28375
|
return newNode;
|
|
28365
28376
|
}
|
|
@@ -28779,6 +28790,15 @@
|
|
|
28779
28790
|
scrollRangeIntoView(editor, editor.selection.getRng());
|
|
28780
28791
|
};
|
|
28781
28792
|
const renderRangeCaretOpt = (editor, range, scrollIntoView) => Optional.some(renderRangeCaret(editor, range, scrollIntoView));
|
|
28793
|
+
const getAbsPositionElement = (pos, direction) => {
|
|
28794
|
+
const node = pos.getNode(direction === -1 /* HDirection.Backwards */);
|
|
28795
|
+
return isNonNullable(node) && isAbsPositionedElement(node) ? Optional.some(node) : Optional.none();
|
|
28796
|
+
};
|
|
28797
|
+
const elementToRange = (editor, node) => {
|
|
28798
|
+
const rng = editor.dom.createRng();
|
|
28799
|
+
rng.selectNode(node);
|
|
28800
|
+
return rng;
|
|
28801
|
+
};
|
|
28782
28802
|
const moveHorizontally = (editor, direction, range, isBefore, isAfter, isElement) => {
|
|
28783
28803
|
const forwards = direction === 1 /* HDirection.Forwards */;
|
|
28784
28804
|
const caretWalker = CaretWalker(editor.getBody());
|
|
@@ -28787,7 +28807,13 @@
|
|
|
28787
28807
|
if (!range.collapsed) {
|
|
28788
28808
|
const node = getSelectedNode(range);
|
|
28789
28809
|
if (isElement(node)) {
|
|
28790
|
-
|
|
28810
|
+
if (isAbsPositionedElement(node)) {
|
|
28811
|
+
const caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);
|
|
28812
|
+
return Optional.from(getNextPosFn(caretPosition)).map((next) => next.toRange());
|
|
28813
|
+
}
|
|
28814
|
+
else {
|
|
28815
|
+
return showCaret(direction, editor, node, direction === -1 /* HDirection.Backwards */, false);
|
|
28816
|
+
}
|
|
28791
28817
|
}
|
|
28792
28818
|
else if (isCefAtEdgeSelected(editor)) {
|
|
28793
28819
|
const newRange = range.cloneRange();
|
|
@@ -28808,13 +28834,13 @@
|
|
|
28808
28834
|
nextCaretPosition = normalizePosition(forwards, nextCaretPosition);
|
|
28809
28835
|
}
|
|
28810
28836
|
if (isBeforeFn(nextCaretPosition)) {
|
|
28811
|
-
return showCaret(direction, editor, nextCaretPosition
|
|
28837
|
+
return getAbsPositionElement(nextCaretPosition, direction).fold(() => showCaret(direction, editor, nextCaretPosition?.getNode(!forwards), forwards, false), (el) => Optional.some(elementToRange(editor, el)));
|
|
28812
28838
|
}
|
|
28813
28839
|
// Peek ahead for handling of ab|c<span cE=false> -> abc|<span cE=false>
|
|
28814
28840
|
const peekCaretPosition = getNextPosFn(nextCaretPosition);
|
|
28815
28841
|
if (peekCaretPosition && isBeforeFn(peekCaretPosition)) {
|
|
28816
28842
|
if (isMoveInsideSameBlock(nextCaretPosition, peekCaretPosition)) {
|
|
28817
|
-
return showCaret(direction, editor, peekCaretPosition.getNode(!forwards), forwards, false);
|
|
28843
|
+
return getAbsPositionElement(nextCaretPosition, direction).fold(() => showCaret(direction, editor, peekCaretPosition.getNode(!forwards), forwards, false), (el) => Optional.some(elementToRange(editor, el)));
|
|
28818
28844
|
}
|
|
28819
28845
|
}
|
|
28820
28846
|
if (rangeIsInContainerBlock) {
|
|
@@ -29215,7 +29241,7 @@
|
|
|
29215
29241
|
|
|
29216
29242
|
const isEditable = (target) => closest$4(target, (elm) => isContentEditableTrue$3(elm.dom) || isContentEditableFalse$a(elm.dom))
|
|
29217
29243
|
.exists((elm) => isContentEditableTrue$3(elm.dom));
|
|
29218
|
-
const parseIndentValue = (value) => toInt(value
|
|
29244
|
+
const parseIndentValue = (value) => toInt(value ?? '').getOr(0);
|
|
29219
29245
|
const getIndentStyleName = (useMargin, element) => {
|
|
29220
29246
|
const indentStyleName = useMargin || isTable$1(element) ? 'margin' : 'padding';
|
|
29221
29247
|
const suffix = get$7(element, 'direction') === 'rtl' ? '-right' : '-left';
|
|
@@ -29248,13 +29274,12 @@
|
|
|
29248
29274
|
const parentIsListComponent = (el) => parent(el).exists(isListComponent);
|
|
29249
29275
|
const getBlocksToIndent = (editor) => filter$5(fromDom$1(editor.selection.getSelectedBlocks()), (el) => !isListComponent(el) && !parentIsListComponent(el) && isEditable(el));
|
|
29250
29276
|
const handle = (editor, command) => {
|
|
29251
|
-
var _a, _b;
|
|
29252
29277
|
if (editor.mode.isReadOnly()) {
|
|
29253
29278
|
return;
|
|
29254
29279
|
}
|
|
29255
29280
|
const { dom } = editor;
|
|
29256
29281
|
const indentation = getIndentation(editor);
|
|
29257
|
-
const indentUnit =
|
|
29282
|
+
const indentUnit = /[a-z%]+$/i.exec(indentation)?.[0] ?? 'px';
|
|
29258
29283
|
const indentValue = parseIndentValue(indentation);
|
|
29259
29284
|
const useMargin = shouldIndentUseMargin(editor);
|
|
29260
29285
|
each$e(getBlocksToIndent(editor), (block) => {
|
|
@@ -30689,9 +30714,8 @@
|
|
|
30689
30714
|
};
|
|
30690
30715
|
|
|
30691
30716
|
const isPreviousCharContent = (dom, leaf) => {
|
|
30692
|
-
var _a;
|
|
30693
30717
|
// If at the start of the range, then we need to look backwards one more place. Otherwise we just need to look at the current text
|
|
30694
|
-
const root =
|
|
30718
|
+
const root = dom.getParent(leaf.container, dom.isBlock) ?? dom.getRoot();
|
|
30695
30719
|
return repeatLeft(dom, leaf.container, leaf.offset, (_element, offset) => offset === 0 ? -1 : offset, root).filter((spot) => {
|
|
30696
30720
|
const char = spot.container.data.charAt(spot.offset - 1);
|
|
30697
30721
|
return !isWhitespace(char);
|
|
@@ -30708,10 +30732,9 @@
|
|
|
30708
30732
|
return getTriggerContext(editor.dom, rng, database).bind((context) => lookupWithContext(editor, getDatabase, context));
|
|
30709
30733
|
};
|
|
30710
30734
|
const lookupWithContext = (editor, getDatabase, context, fetchOptions = {}) => {
|
|
30711
|
-
var _a;
|
|
30712
30735
|
const database = getDatabase();
|
|
30713
30736
|
const rng = editor.selection.getRng();
|
|
30714
|
-
const startText =
|
|
30737
|
+
const startText = rng.startContainer.nodeValue ?? '';
|
|
30715
30738
|
const autocompleters = filter$5(database.lookupByTrigger(context.trigger), (autocompleter) => context.text.length >= autocompleter.minChars && autocompleter.matches.getOrThunk(() => isStartOfWord(editor.dom))(context.range, startText, context.text));
|
|
30716
30739
|
if (autocompleters.length === 0) {
|
|
30717
30740
|
return Optional.none();
|
|
@@ -31223,7 +31246,7 @@
|
|
|
31223
31246
|
const browser$1 = detect$1().browser;
|
|
31224
31247
|
const isSafari = browser$1.isSafari();
|
|
31225
31248
|
const emptyNodeContents = (node) => fillWithPaddingBr(SugarElement.fromDom(node));
|
|
31226
|
-
const isEntireNodeSelected = (rng, node) =>
|
|
31249
|
+
const isEntireNodeSelected = (rng, node) => rng.startOffset === 0 && rng.endOffset === node.textContent?.length;
|
|
31227
31250
|
const getParentDetailsElementAtPos = (dom, pos) => Optional.from(dom.getParent(pos.container(), 'details'));
|
|
31228
31251
|
const isInDetailsElement = (dom, pos) => getParentDetailsElementAtPos(dom, pos).isSome();
|
|
31229
31252
|
const getDetailsElements = (dom, rng) => {
|
|
@@ -31289,8 +31312,8 @@
|
|
|
31289
31312
|
const parentBlock = dom.getParent(caretPos.container(), dom.isBlock);
|
|
31290
31313
|
const parentDetailsAtCaret = getParentDetailsElementAtPos(dom, caretPos);
|
|
31291
31314
|
const inEmptyParentBlock = parentBlock && dom.isEmpty(parentBlock);
|
|
31292
|
-
const isFirstBlock = isNull(parentBlock
|
|
31293
|
-
const isLastBlock = isNull(parentBlock
|
|
31315
|
+
const isFirstBlock = isNull(parentBlock?.previousSibling);
|
|
31316
|
+
const isLastBlock = isNull(parentBlock?.nextSibling);
|
|
31294
31317
|
// Pressing backspace or delete in an first or last empty block before or after details
|
|
31295
31318
|
if (inEmptyParentBlock) {
|
|
31296
31319
|
const firstOrLast = forward ? isLastBlock : isFirstBlock;
|
|
@@ -31361,17 +31384,17 @@
|
|
|
31361
31384
|
editor.undoManager.transact(() => {
|
|
31362
31385
|
// Wrap all summary children in a temporary container to execute Backspace/Delete there, then unwrap
|
|
31363
31386
|
const sel = selection.getSel();
|
|
31364
|
-
let { anchorNode, anchorOffset, focusNode, focusOffset } = sel
|
|
31387
|
+
let { anchorNode, anchorOffset, focusNode, focusOffset } = sel ?? {};
|
|
31365
31388
|
const applySelection = () => {
|
|
31366
31389
|
if (isNonNullable(anchorNode) && isNonNullable(anchorOffset) && isNonNullable(focusNode) && isNonNullable(focusOffset)) {
|
|
31367
|
-
sel
|
|
31390
|
+
sel?.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
|
|
31368
31391
|
}
|
|
31369
31392
|
};
|
|
31370
31393
|
const updateSelection = () => {
|
|
31371
|
-
anchorNode = sel
|
|
31372
|
-
anchorOffset = sel
|
|
31373
|
-
focusNode = sel
|
|
31374
|
-
focusOffset = sel
|
|
31394
|
+
anchorNode = sel?.anchorNode;
|
|
31395
|
+
anchorOffset = sel?.anchorOffset;
|
|
31396
|
+
focusNode = sel?.focusNode;
|
|
31397
|
+
focusOffset = sel?.focusOffset;
|
|
31375
31398
|
};
|
|
31376
31399
|
const appendAllChildNodes = (from, to) => {
|
|
31377
31400
|
each$e(from.childNodes, (child) => {
|
|
@@ -31386,7 +31409,7 @@
|
|
|
31386
31409
|
applySelection();
|
|
31387
31410
|
// Manually perform deletion with modified granularities
|
|
31388
31411
|
if (granularity === 'word' || granularity === 'line') {
|
|
31389
|
-
sel
|
|
31412
|
+
sel?.modify('extend', forward ? 'right' : 'left', granularity);
|
|
31390
31413
|
}
|
|
31391
31414
|
if (!selection.isCollapsed() && isEntireNodeSelected(selection.getRng(), container)) {
|
|
31392
31415
|
emptyNodeContents(node);
|
|
@@ -31759,7 +31782,6 @@
|
|
|
31759
31782
|
editor.dom.isEmpty(element) &&
|
|
31760
31783
|
isAtDetailsEdge(editor.getBody(), element, (el) => has$2(editor.schema.getTextBlockElements(), el.nodeName.toLowerCase()));
|
|
31761
31784
|
const insertNewLine = (editor, createNewBlock, parentBlock) => {
|
|
31762
|
-
var _a, _b, _c;
|
|
31763
31785
|
const newBlock = createNewBlock(getForcedRootBlock(editor));
|
|
31764
31786
|
const root = getDetailsRoot(editor, parentBlock);
|
|
31765
31787
|
if (!root) {
|
|
@@ -31768,7 +31790,7 @@
|
|
|
31768
31790
|
editor.dom.insertAfter(newBlock, root);
|
|
31769
31791
|
moveToCaretPosition(editor, newBlock);
|
|
31770
31792
|
// TODO: This now only works with our Accordions not details with multiple root level children should we support that
|
|
31771
|
-
if ((
|
|
31793
|
+
if ((parentBlock.parentElement?.childNodes?.length ?? 0) > 1) {
|
|
31772
31794
|
editor.dom.remove(parentBlock);
|
|
31773
31795
|
}
|
|
31774
31796
|
};
|
|
@@ -31777,11 +31799,10 @@
|
|
|
31777
31799
|
return elm.firstChild && elm.firstChild.nodeName === name;
|
|
31778
31800
|
};
|
|
31779
31801
|
const isFirstChild = (elm) => {
|
|
31780
|
-
|
|
31781
|
-
return ((_a = elm.parentNode) === null || _a === void 0 ? void 0 : _a.firstChild) === elm;
|
|
31802
|
+
return elm.parentNode?.firstChild === elm;
|
|
31782
31803
|
};
|
|
31783
31804
|
const hasParent = (elm, parentName) => {
|
|
31784
|
-
const parentNode = elm
|
|
31805
|
+
const parentNode = elm?.parentNode;
|
|
31785
31806
|
return isNonNullable(parentNode) && parentNode.nodeName === parentName;
|
|
31786
31807
|
};
|
|
31787
31808
|
const isListBlock = (elm) => {
|
|
@@ -31914,7 +31935,6 @@
|
|
|
31914
31935
|
};
|
|
31915
31936
|
// Remove the first empty inline element of the block so this: <p><b><em></em></b>x</p> becomes this: <p>x</p>
|
|
31916
31937
|
const trimInlineElementsOnLeftSideOfBlock = (dom, nonEmptyElementsMap, block) => {
|
|
31917
|
-
var _a;
|
|
31918
31938
|
const firstChilds = [];
|
|
31919
31939
|
if (!block) {
|
|
31920
31940
|
return;
|
|
@@ -31932,7 +31952,7 @@
|
|
|
31932
31952
|
let i = firstChilds.length;
|
|
31933
31953
|
while (i--) {
|
|
31934
31954
|
currentNode = firstChilds[i];
|
|
31935
|
-
if (!currentNode.hasChildNodes() || (currentNode.firstChild === currentNode.lastChild &&
|
|
31955
|
+
if (!currentNode.hasChildNodes() || (currentNode.firstChild === currentNode.lastChild && currentNode.firstChild?.nodeValue === '')) {
|
|
31936
31956
|
dom.remove(currentNode);
|
|
31937
31957
|
}
|
|
31938
31958
|
else {
|
|
@@ -31971,9 +31991,8 @@
|
|
|
31971
31991
|
};
|
|
31972
31992
|
// Wraps any text nodes or inline elements in the specified forced root block name
|
|
31973
31993
|
const wrapSelfAndSiblingsInDefaultBlock = (editor, newBlockName, rng, container, offset) => {
|
|
31974
|
-
var _a, _b;
|
|
31975
31994
|
const dom = editor.dom;
|
|
31976
|
-
const editableRoot =
|
|
31995
|
+
const editableRoot = getEditableRoot(dom, container) ?? dom.getRoot();
|
|
31977
31996
|
// Not in a block element or in a table cell or caption
|
|
31978
31997
|
let parentBlock = dom.getParent(container, dom.isBlock);
|
|
31979
31998
|
if (!parentBlock || !canSplitBlock(dom, parentBlock)) {
|
|
@@ -31997,7 +32016,7 @@
|
|
|
31997
32016
|
startNode = node;
|
|
31998
32017
|
node = node.previousSibling;
|
|
31999
32018
|
}
|
|
32000
|
-
const startNodeName =
|
|
32019
|
+
const startNodeName = startNode?.parentElement?.nodeName;
|
|
32001
32020
|
if (startNode && startNodeName && editor.schema.isValidChild(startNodeName, newBlockName.toLowerCase())) {
|
|
32002
32021
|
// This should never be null since we check it above
|
|
32003
32022
|
const startNodeParent = startNode.parentNode;
|
|
@@ -32169,7 +32188,7 @@
|
|
|
32169
32188
|
}
|
|
32170
32189
|
// Find parent block and setup empty block paddings
|
|
32171
32190
|
let parentBlock = dom.getParent(container, dom.isBlock) || dom.getRoot();
|
|
32172
|
-
containerBlock = isNonNullable(parentBlock
|
|
32191
|
+
containerBlock = isNonNullable(parentBlock?.parentNode) ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;
|
|
32173
32192
|
// Setup block names
|
|
32174
32193
|
parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5
|
|
32175
32194
|
const containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5
|
|
@@ -32955,8 +32974,9 @@
|
|
|
32955
32974
|
* @private
|
|
32956
32975
|
*/
|
|
32957
32976
|
class NodeChange {
|
|
32977
|
+
editor;
|
|
32978
|
+
lastPath = [];
|
|
32958
32979
|
constructor(editor) {
|
|
32959
|
-
this.lastPath = [];
|
|
32960
32980
|
this.editor = editor;
|
|
32961
32981
|
let lastRng;
|
|
32962
32982
|
const self = this;
|
|
@@ -33460,7 +33480,7 @@
|
|
|
33460
33480
|
try { // IE11 throws exception when contentType is Files (type is present but data cannot be retrieved via getData())
|
|
33461
33481
|
items[contentType] = dataTransfer.getData(contentType);
|
|
33462
33482
|
}
|
|
33463
|
-
catch
|
|
33483
|
+
catch {
|
|
33464
33484
|
items[contentType] = ''; // useless in general, but for consistency across browsers
|
|
33465
33485
|
}
|
|
33466
33486
|
}
|
|
@@ -33489,7 +33509,7 @@
|
|
|
33489
33509
|
// TODO: Move the bulk of the cache logic to EditorUpload
|
|
33490
33510
|
const blobCache = editor.editorUpload.blobCache;
|
|
33491
33511
|
const existingBlobInfo = blobCache.getByData(base64, type);
|
|
33492
|
-
const blobInfo = existingBlobInfo
|
|
33512
|
+
const blobInfo = existingBlobInfo ?? createBlobInfo(editor, blobCache, file, base64);
|
|
33493
33513
|
pasteHtml(editor, `<img src="${blobInfo.blobUri()}">`, false, true);
|
|
33494
33514
|
});
|
|
33495
33515
|
};
|
|
@@ -33535,7 +33555,7 @@
|
|
|
33535
33555
|
return false;
|
|
33536
33556
|
};
|
|
33537
33557
|
// Chrome on Android doesn't support proper clipboard access so we have no choice but to allow the browser default behavior.
|
|
33538
|
-
const isBrokenAndroidClipboardEvent = (e) =>
|
|
33558
|
+
const isBrokenAndroidClipboardEvent = (e) => Env.os.isAndroid() && e.clipboardData?.items?.length === 0;
|
|
33539
33559
|
// Ctrl+V or Shift+Insert
|
|
33540
33560
|
const isKeyboardPasteEvent = (e) => (VK.metaKeyPressed(e) && e.keyCode === 86) || (e.shiftKey && e.keyCode === 45);
|
|
33541
33561
|
const insertClipboardContent = (editor, clipboardContent, html, plainTextMode, shouldSimulateInputEvent) => {
|
|
@@ -33619,7 +33639,7 @@
|
|
|
33619
33639
|
const registerDataImageFilter = (editor) => {
|
|
33620
33640
|
const isWebKitFakeUrl = (src) => startsWith(src, 'webkit-fake-url');
|
|
33621
33641
|
const isDataUri = (src) => startsWith(src, 'data:');
|
|
33622
|
-
const isPasteInsert = (args) =>
|
|
33642
|
+
const isPasteInsert = (args) => args.data?.paste === true;
|
|
33623
33643
|
// Remove all data images from paste for example from Gecko
|
|
33624
33644
|
// except internal images like video elements
|
|
33625
33645
|
editor.parser.addNodeFilter('img', (nodes, name, args) => {
|
|
@@ -33695,7 +33715,7 @@
|
|
|
33695
33715
|
clipboardData.setData(internalHtmlMime(), html);
|
|
33696
33716
|
return true;
|
|
33697
33717
|
}
|
|
33698
|
-
catch
|
|
33718
|
+
catch {
|
|
33699
33719
|
return false;
|
|
33700
33720
|
}
|
|
33701
33721
|
}
|
|
@@ -33775,18 +33795,18 @@
|
|
|
33775
33795
|
editor.on('copy', copy(editor));
|
|
33776
33796
|
};
|
|
33777
33797
|
|
|
33778
|
-
const getCaretRangeFromEvent = (editor, e) =>
|
|
33798
|
+
const getCaretRangeFromEvent = (editor, e) =>
|
|
33779
33799
|
// TODO: TINY-7075 Remove the "?? 0" here when agar passes valid client coords
|
|
33780
|
-
|
|
33800
|
+
RangeUtils.getCaretRangeFromPoint(e.clientX ?? 0, e.clientY ?? 0, editor.getDoc());
|
|
33781
33801
|
const isPlainTextFileUrl = (content) => {
|
|
33782
33802
|
const plainTextContent = content['text/plain'];
|
|
33783
33803
|
return plainTextContent ? plainTextContent.indexOf('file://') === 0 : false;
|
|
33784
33804
|
};
|
|
33785
33805
|
const setFocusedRange = (editor, rng) => {
|
|
33786
|
-
editor.focus();
|
|
33787
33806
|
if (rng) {
|
|
33788
33807
|
editor.selection.setRng(rng);
|
|
33789
33808
|
}
|
|
33809
|
+
editor.focus();
|
|
33790
33810
|
};
|
|
33791
33811
|
const hasImage = (dataTransfer) => exists(dataTransfer.files, (file) => /^image\//.test(file.type));
|
|
33792
33812
|
const needsCustomInternalDrop = (dom, schema, target, dropContent) => {
|
|
@@ -34189,14 +34209,13 @@
|
|
|
34189
34209
|
.map((rect) => clientInfo(rect, clientX));
|
|
34190
34210
|
|
|
34191
34211
|
const getAbsolutePosition = (elm) => {
|
|
34192
|
-
var _a, _b;
|
|
34193
34212
|
const clientRect = elm.getBoundingClientRect();
|
|
34194
34213
|
const doc = elm.ownerDocument;
|
|
34195
34214
|
const docElem = doc.documentElement;
|
|
34196
34215
|
const win = doc.defaultView;
|
|
34197
34216
|
return {
|
|
34198
|
-
top: clientRect.top + (
|
|
34199
|
-
left: clientRect.left + (
|
|
34217
|
+
top: clientRect.top + (win?.scrollY ?? 0) - docElem.clientTop,
|
|
34218
|
+
left: clientRect.left + (win?.scrollX ?? 0) - docElem.clientLeft
|
|
34200
34219
|
};
|
|
34201
34220
|
};
|
|
34202
34221
|
const getBodyPosition = (editor) => editor.inline ? getAbsolutePosition(editor.getBody()) : { left: 0, top: 0 };
|
|
@@ -34565,11 +34584,10 @@
|
|
|
34565
34584
|
};
|
|
34566
34585
|
const drop = (state, editor) => (e) => {
|
|
34567
34586
|
state.on((state) => {
|
|
34568
|
-
var _a;
|
|
34569
34587
|
state.intervalId.clear();
|
|
34570
34588
|
if (state.dragging) {
|
|
34571
34589
|
if (isValidDropTarget(editor, getRawTarget(editor.selection), state.element)) {
|
|
34572
|
-
const dropTarget =
|
|
34590
|
+
const dropTarget = editor.getDoc().elementFromPoint(e.clientX, e.clientY) ?? editor.getBody();
|
|
34573
34591
|
const args = dispatchDragEvent(editor, 'drop', dropTarget, state.dataTransfer, e);
|
|
34574
34592
|
if (!args.isDefaultPrevented()) {
|
|
34575
34593
|
editor.undoManager.transact(() => {
|
|
@@ -34936,8 +34954,22 @@
|
|
|
34936
34954
|
}
|
|
34937
34955
|
return newRange;
|
|
34938
34956
|
};
|
|
34957
|
+
const getUcVideoClone = (ucVideo) => {
|
|
34958
|
+
const newElm = editor.getDoc().createElement('div');
|
|
34959
|
+
newElm.style.width = ucVideo.style.width;
|
|
34960
|
+
newElm.style.height = ucVideo.style.height;
|
|
34961
|
+
const ucVideoWidth = ucVideo.getAttribute('width');
|
|
34962
|
+
if (ucVideoWidth) {
|
|
34963
|
+
newElm.setAttribute('width', ucVideoWidth);
|
|
34964
|
+
}
|
|
34965
|
+
const ucVideoHeight = ucVideo.getAttribute('height');
|
|
34966
|
+
if (ucVideoHeight) {
|
|
34967
|
+
newElm.setAttribute('height', ucVideoHeight);
|
|
34968
|
+
}
|
|
34969
|
+
return newElm;
|
|
34970
|
+
};
|
|
34939
34971
|
const selectElement = (elm) => {
|
|
34940
|
-
const targetClone = elm.cloneNode(true);
|
|
34972
|
+
const targetClone = isUcVideo(elm) ? getUcVideoClone(elm) : elm.cloneNode(true);
|
|
34941
34973
|
const e = editor.dispatch('ObjectSelected', { target: elm, targetClone });
|
|
34942
34974
|
if (e.isDefaultPrevented()) {
|
|
34943
34975
|
return null;
|
|
@@ -35190,8 +35222,7 @@
|
|
|
35190
35222
|
const startPattern = pattern.start;
|
|
35191
35223
|
const startSpot = repeatLeft(dom, spot.container, spot.offset, matchesPattern(startPattern), block);
|
|
35192
35224
|
return startSpot.bind((spot) => {
|
|
35193
|
-
|
|
35194
|
-
const startPatternIndex = (_b = (_a = block.textContent) === null || _a === void 0 ? void 0 : _a.indexOf(startPattern)) !== null && _b !== void 0 ? _b : -1;
|
|
35225
|
+
const startPatternIndex = block.textContent?.indexOf(startPattern) ?? -1;
|
|
35195
35226
|
const isCompleteMatch = startPatternIndex !== -1 && spot.offset >= startPatternIndex + startPattern.length;
|
|
35196
35227
|
if (isCompleteMatch) {
|
|
35197
35228
|
// Complete match
|
|
@@ -35227,12 +35258,11 @@
|
|
|
35227
35258
|
return textBefore(node, offset, block).bind((spot) => {
|
|
35228
35259
|
const start = findPatternStartFromSpot(dom, pattern, block, spot);
|
|
35229
35260
|
return start.bind((startRange) => {
|
|
35230
|
-
var _a;
|
|
35231
35261
|
if (requireGap) {
|
|
35232
35262
|
if (startRange.endContainer === spot.container && startRange.endOffset === spot.offset) {
|
|
35233
35263
|
return Optional.none();
|
|
35234
35264
|
}
|
|
35235
|
-
else if (spot.offset === 0 &&
|
|
35265
|
+
else if (spot.offset === 0 && startRange.endContainer.textContent?.length === startRange.endOffset) {
|
|
35236
35266
|
return Optional.none();
|
|
35237
35267
|
}
|
|
35238
35268
|
}
|
|
@@ -35463,9 +35493,7 @@
|
|
|
35463
35493
|
const nuText = text.replace(nbsp, ' ');
|
|
35464
35494
|
return find$2(sortedPatterns, (pattern) => predicate(pattern, text, nuText));
|
|
35465
35495
|
};
|
|
35466
|
-
const createFindPatterns = (findPattern, skipFullMatch) => (editor, block, patternSet, normalizedMatches, text) => {
|
|
35467
|
-
var _a;
|
|
35468
|
-
if (text === void 0) { text = (_a = block.textContent) !== null && _a !== void 0 ? _a : ''; }
|
|
35496
|
+
const createFindPatterns = (findPattern, skipFullMatch) => (editor, block, patternSet, normalizedMatches, text = block.textContent ?? '') => {
|
|
35469
35497
|
const dom = editor.dom;
|
|
35470
35498
|
const forcedRootBlock = getForcedRootBlock(editor);
|
|
35471
35499
|
if (!dom.is(block, forcedRootBlock)) {
|
|
@@ -35506,9 +35534,8 @@
|
|
|
35506
35534
|
const getMatches$1 = (editor, patternSet) => {
|
|
35507
35535
|
const rng = editor.selection.getRng();
|
|
35508
35536
|
return getParentBlock(editor, rng).map((block) => {
|
|
35509
|
-
var _a;
|
|
35510
35537
|
const offset = Math.max(0, rng.startOffset);
|
|
35511
|
-
const dynamicPatternSet = resolveFromDynamicPatterns(patternSet, block,
|
|
35538
|
+
const dynamicPatternSet = resolveFromDynamicPatterns(patternSet, block, block.textContent ?? '');
|
|
35512
35539
|
// IMPORTANT: We need to get normalized match results since undoing and redoing the editor state
|
|
35513
35540
|
// via undoManager.extra() will result in the DOM being normalized.
|
|
35514
35541
|
const inlineMatches = findPatterns$2(editor, block, rng.startContainer, offset, dynamicPatternSet, true);
|
|
@@ -35677,7 +35704,7 @@
|
|
|
35677
35704
|
try {
|
|
35678
35705
|
editor.getDoc().execCommand(cmd, false, String(state));
|
|
35679
35706
|
}
|
|
35680
|
-
catch
|
|
35707
|
+
catch {
|
|
35681
35708
|
// Ignore
|
|
35682
35709
|
}
|
|
35683
35710
|
};
|
|
@@ -35769,13 +35796,12 @@
|
|
|
35769
35796
|
if (!editor.inline) {
|
|
35770
35797
|
// Needs to be both down/up due to weird rendering bug on Chrome Windows
|
|
35771
35798
|
dom.bind(editor.getDoc(), 'mousedown mouseup', (e) => {
|
|
35772
|
-
var _a;
|
|
35773
35799
|
let rng;
|
|
35774
35800
|
if (e.target === editor.getDoc().documentElement) {
|
|
35775
35801
|
rng = selection.getRng();
|
|
35776
35802
|
// TINY-12245: this is needed to avoid the scroll back to the top when the content is scrolled, there is no selection and the user is clicking on a non selectable editor element
|
|
35777
35803
|
// example content scrolled by browser search and user click on the horizontal scroll bar
|
|
35778
|
-
if (
|
|
35804
|
+
if (editor.getDoc().getSelection()?.anchorNode !== null) {
|
|
35779
35805
|
editor.getBody().focus();
|
|
35780
35806
|
}
|
|
35781
35807
|
if (e.type === 'mousedown') {
|
|
@@ -35875,9 +35901,8 @@
|
|
|
35875
35901
|
const isEditableImage = (node) => node.nodeName === 'IMG' && editor.dom.isEditable(node);
|
|
35876
35902
|
editor.on('mousedown', (e) => {
|
|
35877
35903
|
lift2(Optional.from(e.clientX), Optional.from(e.clientY), (clientX, clientY) => {
|
|
35878
|
-
var _a;
|
|
35879
35904
|
const caretPos = editor.getDoc().caretPositionFromPoint(clientX, clientY);
|
|
35880
|
-
const img =
|
|
35905
|
+
const img = caretPos?.offsetNode?.childNodes[caretPos.offset - (caretPos.offset > 0 ? 1 : 0)] || caretPos?.offsetNode;
|
|
35881
35906
|
if (isNonNullable(img) && isEditableImage(img)) {
|
|
35882
35907
|
const rect = img.getBoundingClientRect();
|
|
35883
35908
|
e.preventDefault();
|
|
@@ -36014,11 +36039,10 @@
|
|
|
36014
36039
|
const currentNode = SugarElement.fromDom(editor.selection.getNode());
|
|
36015
36040
|
if (isFigcaption(currentNode) && editor.selection.isCollapsed()) {
|
|
36016
36041
|
parent(currentNode).bind((parent) => {
|
|
36017
|
-
var _a;
|
|
36018
36042
|
if (editor.selection.getRng().startOffset === 0 && e.keyCode === VK.LEFT) {
|
|
36019
36043
|
return prevSibling(parent);
|
|
36020
36044
|
}
|
|
36021
|
-
else if (editor.selection.getRng().endOffset ===
|
|
36045
|
+
else if (editor.selection.getRng().endOffset === currentNode.dom.textContent?.length && e.keyCode === VK.RIGHT) {
|
|
36022
36046
|
return nextSibling(parent);
|
|
36023
36047
|
}
|
|
36024
36048
|
else {
|
|
@@ -36059,12 +36083,11 @@
|
|
|
36059
36083
|
const addBrAfterLastLinks = () => {
|
|
36060
36084
|
const fixLinks = () => {
|
|
36061
36085
|
each(dom.select('a:not([data-mce-block])'), (node) => {
|
|
36062
|
-
var _a;
|
|
36063
36086
|
let parentNode = node.parentNode;
|
|
36064
36087
|
const root = dom.getRoot();
|
|
36065
|
-
if (
|
|
36088
|
+
if (parentNode?.lastChild === node) {
|
|
36066
36089
|
while (parentNode && !dom.isBlock(parentNode)) {
|
|
36067
|
-
if (
|
|
36090
|
+
if (parentNode.parentNode?.lastChild !== parentNode || parentNode === root) {
|
|
36068
36091
|
return;
|
|
36069
36092
|
}
|
|
36070
36093
|
parentNode = parentNode.parentNode;
|
|
@@ -36361,6 +36384,91 @@
|
|
|
36361
36384
|
};
|
|
36362
36385
|
};
|
|
36363
36386
|
|
|
36387
|
+
class ComponentLoadError extends Error {
|
|
36388
|
+
url;
|
|
36389
|
+
constructor(message, url) {
|
|
36390
|
+
super(message);
|
|
36391
|
+
this.url = url;
|
|
36392
|
+
}
|
|
36393
|
+
}
|
|
36394
|
+
const hostWindowComponentScripts = {};
|
|
36395
|
+
const loadScript = (url, doc, extraAtts) => {
|
|
36396
|
+
return new Promise((resolve, reject) => {
|
|
36397
|
+
const script = SugarElement.fromTag('script');
|
|
36398
|
+
setAll$1(script, {
|
|
36399
|
+
type: 'text/javascript',
|
|
36400
|
+
src: url,
|
|
36401
|
+
...extraAtts
|
|
36402
|
+
});
|
|
36403
|
+
const clean = () => {
|
|
36404
|
+
remove$8(script);
|
|
36405
|
+
};
|
|
36406
|
+
bind$1(script, 'load', () => {
|
|
36407
|
+
clean();
|
|
36408
|
+
resolve();
|
|
36409
|
+
});
|
|
36410
|
+
bind$1(script, 'error', () => {
|
|
36411
|
+
clean();
|
|
36412
|
+
reject(new Error(`Failed to load script url: ${url}`));
|
|
36413
|
+
});
|
|
36414
|
+
append$1(getHead(doc), script);
|
|
36415
|
+
});
|
|
36416
|
+
};
|
|
36417
|
+
const loadComponent = async (url, doc) => {
|
|
36418
|
+
const extraAtts = ScriptLoader.ScriptLoader.getScriptAttributes(url);
|
|
36419
|
+
await loadScript(url, doc, extraAtts).catch(() => Promise.reject(new ComponentLoadError(`Failed to load component url: ${url}`, url)));
|
|
36420
|
+
return url;
|
|
36421
|
+
};
|
|
36422
|
+
const loadComponentsForInlineEditor = (componentUrls) => {
|
|
36423
|
+
return mapToArray(componentUrls, (url, elementName) => {
|
|
36424
|
+
return get$a(hostWindowComponentScripts, url).getOrThunk(() => {
|
|
36425
|
+
// Only load the component if it hasn't already been loaded in inline mode the page might have already loaded it
|
|
36426
|
+
if (isNullable(window.customElements.get(elementName))) {
|
|
36427
|
+
const loadPromise = loadComponent(url, getDocument());
|
|
36428
|
+
hostWindowComponentScripts[url] = loadPromise;
|
|
36429
|
+
return loadPromise;
|
|
36430
|
+
}
|
|
36431
|
+
else {
|
|
36432
|
+
return Promise.resolve(url);
|
|
36433
|
+
}
|
|
36434
|
+
}).catch((err) => {
|
|
36435
|
+
// Remove from cache if the component failed to load so we can try again later
|
|
36436
|
+
delete hostWindowComponentScripts[url];
|
|
36437
|
+
return Promise.reject(err);
|
|
36438
|
+
});
|
|
36439
|
+
});
|
|
36440
|
+
};
|
|
36441
|
+
const loadComponentsForIframeEditor = (componentUrls, doc) => {
|
|
36442
|
+
const urls = unique$1(values(componentUrls));
|
|
36443
|
+
return map$3(urls, (url) => loadComponent(url, SugarElement.fromDom(doc)));
|
|
36444
|
+
};
|
|
36445
|
+
const loadComponentsForEditor = (editor) => {
|
|
36446
|
+
const componentUrls = editor.schema.getComponentUrls();
|
|
36447
|
+
if (editor.inline) {
|
|
36448
|
+
return loadComponentsForInlineEditor(componentUrls);
|
|
36449
|
+
}
|
|
36450
|
+
else {
|
|
36451
|
+
return loadComponentsForIframeEditor(componentUrls, editor.getDoc());
|
|
36452
|
+
}
|
|
36453
|
+
};
|
|
36454
|
+
const loadComponentsAsync = async (editor) => {
|
|
36455
|
+
const loadPromises = loadComponentsForEditor(editor);
|
|
36456
|
+
const rejected = filter$5(await Promise.allSettled(loadPromises), (r) => r.status === 'rejected');
|
|
36457
|
+
if (rejected.length > 0) {
|
|
36458
|
+
each$e(rejected, (rejection) => {
|
|
36459
|
+
if (rejection.reason instanceof ComponentLoadError) {
|
|
36460
|
+
const { url } = rejection.reason;
|
|
36461
|
+
componentLoadError(editor, url);
|
|
36462
|
+
}
|
|
36463
|
+
});
|
|
36464
|
+
}
|
|
36465
|
+
};
|
|
36466
|
+
const loadComponents = (editor) => {
|
|
36467
|
+
// Since we are handling the errors in the promise rejections inside the loadComponentsAsync we can ignore the errors here
|
|
36468
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
36469
|
+
loadComponentsAsync(editor);
|
|
36470
|
+
};
|
|
36471
|
+
|
|
36364
36472
|
const DOM$6 = DOMUtils.DOM;
|
|
36365
36473
|
const appendStyle = (editor, text) => {
|
|
36366
36474
|
const body = SugarElement.fromDom(editor.getBody());
|
|
@@ -36490,13 +36598,12 @@
|
|
|
36490
36598
|
});
|
|
36491
36599
|
if (shouldPreserveCData(editor)) {
|
|
36492
36600
|
parser.addNodeFilter('#cdata', (nodes) => {
|
|
36493
|
-
var _a;
|
|
36494
36601
|
let i = nodes.length;
|
|
36495
36602
|
while (i--) {
|
|
36496
36603
|
const node = nodes[i];
|
|
36497
36604
|
node.type = 8;
|
|
36498
36605
|
node.name = '#comment';
|
|
36499
|
-
node.value = '[CDATA[' + editor.dom.encode(
|
|
36606
|
+
node.value = '[CDATA[' + editor.dom.encode(node.value ?? '') + ']]';
|
|
36500
36607
|
}
|
|
36501
36608
|
});
|
|
36502
36609
|
}
|
|
@@ -36738,6 +36845,7 @@
|
|
|
36738
36845
|
setup$7(editor, caret);
|
|
36739
36846
|
const setupRtcThunk = setup$z(editor);
|
|
36740
36847
|
preInit(editor);
|
|
36848
|
+
loadComponents(editor);
|
|
36741
36849
|
setupRtcThunk.fold(() => {
|
|
36742
36850
|
const cancelProgress = startProgress(editor);
|
|
36743
36851
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -37252,11 +37360,10 @@
|
|
|
37252
37360
|
'#455A64', // Dark Blue Gray
|
|
37253
37361
|
];
|
|
37254
37362
|
const getFirstChar = (name) => {
|
|
37255
|
-
var _a;
|
|
37256
37363
|
if (Intl.Segmenter) {
|
|
37257
37364
|
const segmenter = new Intl.Segmenter();
|
|
37258
37365
|
const iterator = segmenter.segment(name)[Symbol.iterator]();
|
|
37259
|
-
return `${
|
|
37366
|
+
return `${iterator.next().value?.segment}`;
|
|
37260
37367
|
}
|
|
37261
37368
|
else {
|
|
37262
37369
|
return name.trim()[0];
|
|
@@ -37278,7 +37385,7 @@
|
|
|
37278
37385
|
return (hash >>> 0) % (maxValue + 1);
|
|
37279
37386
|
};
|
|
37280
37387
|
const getColor = (id) => {
|
|
37281
|
-
const colorIdx = djb2Hash(id
|
|
37388
|
+
const colorIdx = djb2Hash(id ?? '', AvatarColors.length - 1);
|
|
37282
37389
|
return AvatarColors[colorIdx];
|
|
37283
37390
|
};
|
|
37284
37391
|
const generateAvatarSvg = (content, color, size) => {
|
|
@@ -37484,8 +37591,7 @@
|
|
|
37484
37591
|
};
|
|
37485
37592
|
};
|
|
37486
37593
|
const getExternalPlugins = (overrideOptions, options) => {
|
|
37487
|
-
|
|
37488
|
-
const userDefinedExternalPlugins = (_a = options.external_plugins) !== null && _a !== void 0 ? _a : {};
|
|
37594
|
+
const userDefinedExternalPlugins = options.external_plugins ?? {};
|
|
37489
37595
|
if (overrideOptions && overrideOptions.external_plugins) {
|
|
37490
37596
|
return Tools.extend({}, overrideOptions.external_plugins, userDefinedExternalPlugins);
|
|
37491
37597
|
}
|
|
@@ -37523,9 +37629,8 @@
|
|
|
37523
37629
|
return isMobileDevice && hasSection(sectionResult, 'mobile');
|
|
37524
37630
|
};
|
|
37525
37631
|
const combineOptions = (isMobileDevice, isPhone, defaultOptions, defaultOverrideOptions, options) => {
|
|
37526
|
-
var _a;
|
|
37527
37632
|
// Use mobile mode by default on phones, so patch in the mobile override options
|
|
37528
|
-
const deviceOverrideOptions = isMobileDevice ? { mobile: getMobileOverrideOptions(
|
|
37633
|
+
const deviceOverrideOptions = isMobileDevice ? { mobile: getMobileOverrideOptions(options.mobile ?? {}, isPhone) } : {};
|
|
37529
37634
|
const sectionResult = extractSections(['mobile'], deepMerge(deviceOverrideOptions, options));
|
|
37530
37635
|
const extendedOptions = Tools.extend(
|
|
37531
37636
|
// Default options
|
|
@@ -37600,7 +37705,7 @@
|
|
|
37600
37705
|
try {
|
|
37601
37706
|
doc.execCommand(command);
|
|
37602
37707
|
}
|
|
37603
|
-
catch
|
|
37708
|
+
catch {
|
|
37604
37709
|
// Command failed
|
|
37605
37710
|
failed = true;
|
|
37606
37711
|
}
|
|
@@ -37849,8 +37954,7 @@
|
|
|
37849
37954
|
lineHeightAction(editor, value);
|
|
37850
37955
|
},
|
|
37851
37956
|
'Lang': (command, _ui, lang) => {
|
|
37852
|
-
|
|
37853
|
-
toggleFormat(command, { value: lang.code, customValue: (_a = lang.customCode) !== null && _a !== void 0 ? _a : null });
|
|
37957
|
+
toggleFormat(command, { value: lang.code, customValue: lang.customCode ?? null });
|
|
37854
37958
|
},
|
|
37855
37959
|
'RemoveFormat': (command) => {
|
|
37856
37960
|
editor.formatter.remove(command);
|
|
@@ -38038,7 +38142,7 @@
|
|
|
38038
38142
|
const registerExecCommands = (editor) => {
|
|
38039
38143
|
editor.editorCommands.addCommands({
|
|
38040
38144
|
mceRemoveNode: (_command, _ui, value) => {
|
|
38041
|
-
const node = value
|
|
38145
|
+
const node = value ?? editor.selection.getNode();
|
|
38042
38146
|
// Make sure that the body node isn't removed
|
|
38043
38147
|
if (node !== editor.getBody()) {
|
|
38044
38148
|
const bm = editor.selection.getBookmark();
|
|
@@ -38076,8 +38180,9 @@
|
|
|
38076
38180
|
const selectionSafeCommands = ['toggleview'];
|
|
38077
38181
|
const isSelectionSafeCommand = (command) => contains$2(selectionSafeCommands, command.toLowerCase());
|
|
38078
38182
|
class EditorCommands {
|
|
38183
|
+
editor;
|
|
38184
|
+
commands = { state: {}, exec: {}, value: {} };
|
|
38079
38185
|
constructor(editor) {
|
|
38080
|
-
this.commands = { state: {}, exec: {}, value: {} };
|
|
38081
38186
|
this.editor = editor;
|
|
38082
38187
|
}
|
|
38083
38188
|
/**
|
|
@@ -38094,7 +38199,7 @@
|
|
|
38094
38199
|
execCommand(command, ui = false, value, args) {
|
|
38095
38200
|
const editor = this.editor;
|
|
38096
38201
|
const lowerCaseCommand = command.toLowerCase();
|
|
38097
|
-
const skipFocus = args
|
|
38202
|
+
const skipFocus = args?.skip_focus;
|
|
38098
38203
|
if (editor.removed) {
|
|
38099
38204
|
return false;
|
|
38100
38205
|
}
|
|
@@ -38164,7 +38269,7 @@
|
|
|
38164
38269
|
}
|
|
38165
38270
|
addCommand(command, callback, scope) {
|
|
38166
38271
|
const lowerCaseCommand = command.toLowerCase();
|
|
38167
|
-
this.commands.exec[lowerCaseCommand] = (_command, ui, value, args) => callback.call(scope
|
|
38272
|
+
this.commands.exec[lowerCaseCommand] = (_command, ui, value, args) => callback.call(scope ?? this.editor, ui, value, args);
|
|
38168
38273
|
}
|
|
38169
38274
|
/**
|
|
38170
38275
|
* Returns true/false if the command is supported or not.
|
|
@@ -38183,10 +38288,10 @@
|
|
|
38183
38288
|
}
|
|
38184
38289
|
}
|
|
38185
38290
|
addQueryStateHandler(command, callback, scope) {
|
|
38186
|
-
this.commands.state[command.toLowerCase()] = () => callback.call(scope
|
|
38291
|
+
this.commands.state[command.toLowerCase()] = () => callback.call(scope ?? this.editor);
|
|
38187
38292
|
}
|
|
38188
38293
|
addQueryValueHandler(command, callback, scope) {
|
|
38189
|
-
this.commands.value[command.toLowerCase()] = () => callback.call(scope
|
|
38294
|
+
this.commands.value[command.toLowerCase()] = () => callback.call(scope ?? this.editor);
|
|
38190
38295
|
}
|
|
38191
38296
|
}
|
|
38192
38297
|
|
|
@@ -38217,8 +38322,11 @@
|
|
|
38217
38322
|
static isNative(name) {
|
|
38218
38323
|
return !!nativeEvents[name.toLowerCase()];
|
|
38219
38324
|
}
|
|
38325
|
+
settings;
|
|
38326
|
+
scope;
|
|
38327
|
+
toggleEvent;
|
|
38328
|
+
bindings = {};
|
|
38220
38329
|
constructor(settings) {
|
|
38221
|
-
this.bindings = {};
|
|
38222
38330
|
this.settings = settings || {};
|
|
38223
38331
|
this.scope = this.settings.scope || this;
|
|
38224
38332
|
this.toggleEvent = this.settings.toggleEvent || never;
|
|
@@ -38251,7 +38359,7 @@
|
|
|
38251
38359
|
*/
|
|
38252
38360
|
dispatch(name, args) {
|
|
38253
38361
|
const lcName = name.toLowerCase();
|
|
38254
|
-
const event = normalize$3(lcName, args
|
|
38362
|
+
const event = normalize$3(lcName, args ?? {}, this.scope);
|
|
38255
38363
|
if (this.settings.beforeFire) {
|
|
38256
38364
|
this.settings.beforeFire(event);
|
|
38257
38365
|
}
|
|
@@ -38476,7 +38584,7 @@
|
|
|
38476
38584
|
const self = this;
|
|
38477
38585
|
// Prevent all events except the remove/detach event after the instance has been removed
|
|
38478
38586
|
if (self.removed && name !== 'remove' && name !== 'detach') {
|
|
38479
|
-
return normalize$3(name.toLowerCase(), args
|
|
38587
|
+
return normalize$3(name.toLowerCase(), args ?? {}, self);
|
|
38480
38588
|
}
|
|
38481
38589
|
const dispatcherArgs = getEventDispatcher(self).dispatch(name, args);
|
|
38482
38590
|
// Bubble event up to parents
|
|
@@ -39120,9 +39228,10 @@
|
|
|
39120
39228
|
return shortcut;
|
|
39121
39229
|
};
|
|
39122
39230
|
class Shortcuts {
|
|
39231
|
+
editor;
|
|
39232
|
+
shortcuts = {};
|
|
39233
|
+
pendingPatterns = [];
|
|
39123
39234
|
constructor(editor) {
|
|
39124
|
-
this.shortcuts = {};
|
|
39125
|
-
this.pendingPatterns = [];
|
|
39126
39235
|
this.editor = editor;
|
|
39127
39236
|
const self = this;
|
|
39128
39237
|
editor.on('keyup keypress keydown', (e) => {
|
|
@@ -39484,6 +39593,172 @@
|
|
|
39484
39593
|
* @include ../../../../../tools/docs/tinymce.Editor.js
|
|
39485
39594
|
*/
|
|
39486
39595
|
class Editor {
|
|
39596
|
+
baseUri;
|
|
39597
|
+
/**
|
|
39598
|
+
* Editor instance id, normally the same as the div/textarea that was replaced.
|
|
39599
|
+
*
|
|
39600
|
+
* @property id
|
|
39601
|
+
* @type String
|
|
39602
|
+
*/
|
|
39603
|
+
id;
|
|
39604
|
+
/**
|
|
39605
|
+
* A uuid string to uniquely identify an editor across any page.
|
|
39606
|
+
*
|
|
39607
|
+
* @property editorUid
|
|
39608
|
+
* @type String
|
|
39609
|
+
*/
|
|
39610
|
+
editorUid;
|
|
39611
|
+
/**
|
|
39612
|
+
* Name/Value object containing plugin instances.
|
|
39613
|
+
*
|
|
39614
|
+
* @property plugins
|
|
39615
|
+
* @type Object
|
|
39616
|
+
* @example
|
|
39617
|
+
* // Execute a method inside a plugin directly
|
|
39618
|
+
* tinymce.activeEditor.plugins.someplugin.someMethod();
|
|
39619
|
+
*/
|
|
39620
|
+
plugins = {};
|
|
39621
|
+
/**
|
|
39622
|
+
* URI object to document configured for the TinyMCE instance.
|
|
39623
|
+
*
|
|
39624
|
+
* @property documentBaseURI
|
|
39625
|
+
* @type tinymce.util.URI
|
|
39626
|
+
* @example
|
|
39627
|
+
* // Get relative URL from the location of document_base_url
|
|
39628
|
+
* tinymce.activeEditor.documentBaseURI.toRelative('/somedir/somefile.htm');
|
|
39629
|
+
*
|
|
39630
|
+
* // Get absolute URL from the location of document_base_url
|
|
39631
|
+
* tinymce.activeEditor.documentBaseURI.toAbsolute('somefile.htm');
|
|
39632
|
+
*/
|
|
39633
|
+
documentBaseURI;
|
|
39634
|
+
/**
|
|
39635
|
+
* URI object to current document that holds the TinyMCE editor instance.
|
|
39636
|
+
*
|
|
39637
|
+
* @property baseURI
|
|
39638
|
+
* @type tinymce.util.URI
|
|
39639
|
+
* @example
|
|
39640
|
+
* // Get relative URL from the location of the API
|
|
39641
|
+
* tinymce.activeEditor.baseURI.toRelative('/somedir/somefile.htm');
|
|
39642
|
+
*
|
|
39643
|
+
* // Get absolute URL from the location of the API
|
|
39644
|
+
* tinymce.activeEditor.baseURI.toAbsolute('somefile.htm');
|
|
39645
|
+
*/
|
|
39646
|
+
baseURI;
|
|
39647
|
+
/**
|
|
39648
|
+
* Array with CSS files to load into the iframe.
|
|
39649
|
+
*
|
|
39650
|
+
* @property contentCSS
|
|
39651
|
+
* @type Array
|
|
39652
|
+
*/
|
|
39653
|
+
contentCSS = [];
|
|
39654
|
+
/**
|
|
39655
|
+
* Array of CSS styles to add to head of document when the editor loads.
|
|
39656
|
+
*
|
|
39657
|
+
* @property contentStyles
|
|
39658
|
+
* @type Array
|
|
39659
|
+
*/
|
|
39660
|
+
contentStyles = [];
|
|
39661
|
+
/**
|
|
39662
|
+
* Editor ui components
|
|
39663
|
+
*
|
|
39664
|
+
* @property ui
|
|
39665
|
+
* @type tinymce.editor.ui.Ui
|
|
39666
|
+
*/
|
|
39667
|
+
ui;
|
|
39668
|
+
/**
|
|
39669
|
+
* Editor mode API
|
|
39670
|
+
*
|
|
39671
|
+
* @property mode
|
|
39672
|
+
* @type tinymce.EditorMode
|
|
39673
|
+
*/
|
|
39674
|
+
mode;
|
|
39675
|
+
/**
|
|
39676
|
+
* Editor options API
|
|
39677
|
+
*
|
|
39678
|
+
* @property options
|
|
39679
|
+
* @type tinymce.EditorOptions
|
|
39680
|
+
*/
|
|
39681
|
+
options;
|
|
39682
|
+
/**
|
|
39683
|
+
* Editor upload API
|
|
39684
|
+
*
|
|
39685
|
+
* @property editorUpload
|
|
39686
|
+
* @type tinymce.EditorUpload
|
|
39687
|
+
*/
|
|
39688
|
+
editorUpload;
|
|
39689
|
+
/**
|
|
39690
|
+
* Editor user lookup API
|
|
39691
|
+
*
|
|
39692
|
+
* @property userLookup
|
|
39693
|
+
* @type tinymce.UserLookup
|
|
39694
|
+
*/
|
|
39695
|
+
userLookup;
|
|
39696
|
+
shortcuts;
|
|
39697
|
+
loadedCSS = {};
|
|
39698
|
+
editorCommands;
|
|
39699
|
+
suffix;
|
|
39700
|
+
editorManager;
|
|
39701
|
+
hidden;
|
|
39702
|
+
inline;
|
|
39703
|
+
hasVisual;
|
|
39704
|
+
isNotDirty = false;
|
|
39705
|
+
// Arguments set later, for example by InitContentBody.ts
|
|
39706
|
+
// Note that these may technically be undefined up until PreInit (or similar) has fired,
|
|
39707
|
+
// however the types are aimed at an initialised editor for ease of use.
|
|
39708
|
+
annotator;
|
|
39709
|
+
bodyElement;
|
|
39710
|
+
bookmark; // Note: Intentionally any so as to not expose Optional
|
|
39711
|
+
composing = false;
|
|
39712
|
+
container;
|
|
39713
|
+
contentAreaContainer;
|
|
39714
|
+
contentDocument;
|
|
39715
|
+
contentWindow;
|
|
39716
|
+
delegates;
|
|
39717
|
+
destroyed = false;
|
|
39718
|
+
dom;
|
|
39719
|
+
editorContainer;
|
|
39720
|
+
eventRoot;
|
|
39721
|
+
formatter;
|
|
39722
|
+
formElement;
|
|
39723
|
+
formEventDelegate;
|
|
39724
|
+
hasHiddenInput = false;
|
|
39725
|
+
iframeElement = null;
|
|
39726
|
+
iframeHTML;
|
|
39727
|
+
initialized = false;
|
|
39728
|
+
notificationManager;
|
|
39729
|
+
orgDisplay;
|
|
39730
|
+
orgVisibility;
|
|
39731
|
+
parser;
|
|
39732
|
+
quirks;
|
|
39733
|
+
readonly = false;
|
|
39734
|
+
removed = false;
|
|
39735
|
+
schema;
|
|
39736
|
+
selection;
|
|
39737
|
+
serializer;
|
|
39738
|
+
startContent = '';
|
|
39739
|
+
targetElm;
|
|
39740
|
+
theme;
|
|
39741
|
+
model;
|
|
39742
|
+
undoManager;
|
|
39743
|
+
windowManager;
|
|
39744
|
+
licenseKeyManager;
|
|
39745
|
+
_beforeUnload;
|
|
39746
|
+
_eventDispatcher;
|
|
39747
|
+
_nodeChangeDispatcher;
|
|
39748
|
+
_pendingNativeEvents = [];
|
|
39749
|
+
_selectionOverrides;
|
|
39750
|
+
_skinLoaded = false;
|
|
39751
|
+
_editableRoot = true;
|
|
39752
|
+
// EditorObservable patches
|
|
39753
|
+
bindPendingEventDelegates;
|
|
39754
|
+
toggleNativeEvent;
|
|
39755
|
+
unbindAllNativeEvents;
|
|
39756
|
+
fire;
|
|
39757
|
+
dispatch;
|
|
39758
|
+
on;
|
|
39759
|
+
off;
|
|
39760
|
+
once;
|
|
39761
|
+
hasEventListeners;
|
|
39487
39762
|
/**
|
|
39488
39763
|
* Constructs a editor instance by id.
|
|
39489
39764
|
*
|
|
@@ -39494,43 +39769,6 @@
|
|
|
39494
39769
|
* @param {tinymce.EditorManager} editorManager EditorManager instance.
|
|
39495
39770
|
*/
|
|
39496
39771
|
constructor(id, options, editorManager) {
|
|
39497
|
-
/**
|
|
39498
|
-
* Name/Value object containing plugin instances.
|
|
39499
|
-
*
|
|
39500
|
-
* @property plugins
|
|
39501
|
-
* @type Object
|
|
39502
|
-
* @example
|
|
39503
|
-
* // Execute a method inside a plugin directly
|
|
39504
|
-
* tinymce.activeEditor.plugins.someplugin.someMethod();
|
|
39505
|
-
*/
|
|
39506
|
-
this.plugins = {};
|
|
39507
|
-
/**
|
|
39508
|
-
* Array with CSS files to load into the iframe.
|
|
39509
|
-
*
|
|
39510
|
-
* @property contentCSS
|
|
39511
|
-
* @type Array
|
|
39512
|
-
*/
|
|
39513
|
-
this.contentCSS = [];
|
|
39514
|
-
/**
|
|
39515
|
-
* Array of CSS styles to add to head of document when the editor loads.
|
|
39516
|
-
*
|
|
39517
|
-
* @property contentStyles
|
|
39518
|
-
* @type Array
|
|
39519
|
-
*/
|
|
39520
|
-
this.contentStyles = [];
|
|
39521
|
-
this.loadedCSS = {};
|
|
39522
|
-
this.isNotDirty = false;
|
|
39523
|
-
this.composing = false;
|
|
39524
|
-
this.destroyed = false;
|
|
39525
|
-
this.hasHiddenInput = false;
|
|
39526
|
-
this.iframeElement = null;
|
|
39527
|
-
this.initialized = false;
|
|
39528
|
-
this.readonly = false;
|
|
39529
|
-
this.removed = false;
|
|
39530
|
-
this.startContent = '';
|
|
39531
|
-
this._pendingNativeEvents = [];
|
|
39532
|
-
this._skinLoaded = false;
|
|
39533
|
-
this._editableRoot = true;
|
|
39534
39772
|
this.editorManager = editorManager;
|
|
39535
39773
|
// Patch in the EditorObservable functions
|
|
39536
39774
|
extend(this, EditorObservable);
|
|
@@ -40113,9 +40351,8 @@
|
|
|
40113
40351
|
* @return {Element} The root element of the editable area.
|
|
40114
40352
|
*/
|
|
40115
40353
|
getBody() {
|
|
40116
|
-
var _a, _b;
|
|
40117
40354
|
const doc = this.getDoc();
|
|
40118
|
-
return
|
|
40355
|
+
return this.bodyElement ?? doc?.body ?? null;
|
|
40119
40356
|
}
|
|
40120
40357
|
/**
|
|
40121
40358
|
* URL converter function this gets executed each time a user adds an img, a or
|
|
@@ -40306,14 +40543,14 @@
|
|
|
40306
40543
|
* @property minorVersion
|
|
40307
40544
|
* @type String
|
|
40308
40545
|
*/
|
|
40309
|
-
minorVersion: '1
|
|
40546
|
+
minorVersion: '2.1',
|
|
40310
40547
|
/**
|
|
40311
40548
|
* Release date of TinyMCE build.
|
|
40312
40549
|
*
|
|
40313
40550
|
* @property releaseDate
|
|
40314
40551
|
* @type String
|
|
40315
40552
|
*/
|
|
40316
|
-
releaseDate: '
|
|
40553
|
+
releaseDate: '2025-11-06',
|
|
40317
40554
|
/**
|
|
40318
40555
|
* Collection of language pack data.
|
|
40319
40556
|
*
|
|
@@ -40723,9 +40960,8 @@
|
|
|
40723
40960
|
* @return {Boolean} true/false if the command was executed or not.
|
|
40724
40961
|
*/
|
|
40725
40962
|
execCommand(cmd, ui, value) {
|
|
40726
|
-
var _a;
|
|
40727
40963
|
const self = this;
|
|
40728
|
-
const editorId = isObject(value) ?
|
|
40964
|
+
const editorId = isObject(value) ? value.id ?? value.index : value;
|
|
40729
40965
|
// Manager commands
|
|
40730
40966
|
switch (cmd) {
|
|
40731
40967
|
case 'mceAddEditor': {
|
|
@@ -41131,7 +41367,7 @@
|
|
|
41131
41367
|
localStorage.setItem(test, test);
|
|
41132
41368
|
localStorage.removeItem(test);
|
|
41133
41369
|
}
|
|
41134
|
-
catch
|
|
41370
|
+
catch {
|
|
41135
41371
|
localStorage = create();
|
|
41136
41372
|
}
|
|
41137
41373
|
var LocalStorage = localStorage;
|
|
@@ -41228,7 +41464,7 @@
|
|
|
41228
41464
|
try {
|
|
41229
41465
|
module.exports = tinymce;
|
|
41230
41466
|
}
|
|
41231
|
-
catch
|
|
41467
|
+
catch {
|
|
41232
41468
|
// It will thrown an error when running this module
|
|
41233
41469
|
// within webpack where the module.exports object is sealed
|
|
41234
41470
|
}
|