tinymce-rails 8.1.2 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/source/tinymce/tinymce.js +671 -449
- 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.
|
|
2
|
+
* TinyMCE version 8.2.0 (2025-10-23)
|
|
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;
|
|
@@ -3610,11 +3610,10 @@
|
|
|
3610
3610
|
return filter$5(scope.querySelectorAll(transparentSelector), (transparent) => updateTransparent(blocksSelector, transparent));
|
|
3611
3611
|
};
|
|
3612
3612
|
const trimEdge = (schema, el, leftSide) => {
|
|
3613
|
-
var _a;
|
|
3614
3613
|
const childPropertyName = leftSide ? 'lastChild' : 'firstChild';
|
|
3615
3614
|
for (let child = el[childPropertyName]; child; child = child[childPropertyName]) {
|
|
3616
3615
|
if (isEmptyNode(schema, child, { checkRootAsContent: true })) {
|
|
3617
|
-
|
|
3616
|
+
child.parentNode?.removeChild(child);
|
|
3618
3617
|
return;
|
|
3619
3618
|
}
|
|
3620
3619
|
}
|
|
@@ -4002,7 +4001,6 @@
|
|
|
4002
4001
|
// this function will then trim off empty edges and produce:
|
|
4003
4002
|
// <p>text 1</p><b>CHOP</b><p>text 2</p>
|
|
4004
4003
|
const trimNode = (dom, node, schema, root) => {
|
|
4005
|
-
var _a;
|
|
4006
4004
|
const rootNode = root || node;
|
|
4007
4005
|
if (isElement$7(node) && isBookmarkNode$2(node)) {
|
|
4008
4006
|
return node;
|
|
@@ -4015,7 +4013,7 @@
|
|
|
4015
4013
|
if (isElement$7(node)) {
|
|
4016
4014
|
const currentChildren = node.childNodes;
|
|
4017
4015
|
if (currentChildren.length === 1 && isBookmarkNode$2(currentChildren[0])) {
|
|
4018
|
-
|
|
4016
|
+
node.parentNode?.insertBefore(currentChildren[0], node);
|
|
4019
4017
|
}
|
|
4020
4018
|
}
|
|
4021
4019
|
// Remove any empty nodes
|
|
@@ -4433,7 +4431,7 @@
|
|
|
4433
4431
|
add('title hr noscript br');
|
|
4434
4432
|
add('base', 'href target');
|
|
4435
4433
|
add('link', 'href rel media hreflang type sizes hreflang');
|
|
4436
|
-
add('meta', 'name http-equiv content charset');
|
|
4434
|
+
add('meta', 'name http-equiv content charset property'); // Property is an RDFa spec attribute.
|
|
4437
4435
|
add('style', 'media type scoped');
|
|
4438
4436
|
add('script', 'src async defer type charset');
|
|
4439
4437
|
add('body', 'onafterprint onbeforeprint onbeforeunload onblur onerror onfocus ' +
|
|
@@ -4486,6 +4484,7 @@
|
|
|
4486
4484
|
add('canvas', 'width height', flowContent);
|
|
4487
4485
|
add('data', 'value', phrasingContent);
|
|
4488
4486
|
add('video', 'src crossorigin poster preload autoplay mediagroup loop ' +
|
|
4487
|
+
'controlslist disablepictureinpicture disableremoteplayback playsinline ' +
|
|
4489
4488
|
'muted controls width height buffered', [flowContent, 'track source'].join(' '));
|
|
4490
4489
|
add('audio', 'src crossorigin preload autoplay mediagroup loop muted controls ' +
|
|
4491
4490
|
'buffered volume', [flowContent, 'track source'].join(' '));
|
|
@@ -4760,12 +4759,12 @@
|
|
|
4760
4759
|
}
|
|
4761
4760
|
};
|
|
4762
4761
|
const Schema = (settings = {}) => {
|
|
4763
|
-
var _a;
|
|
4764
4762
|
const elements = {};
|
|
4765
4763
|
const children = {};
|
|
4766
4764
|
let patternElements = [];
|
|
4767
4765
|
const customElementsMap = {};
|
|
4768
4766
|
const specialElements = {};
|
|
4767
|
+
const componentUrls = {};
|
|
4769
4768
|
// Creates an lookup table map object for the specified option or the default value
|
|
4770
4769
|
const createLookupTable = (option, defaultValue, extendWith) => {
|
|
4771
4770
|
const value = settings[option];
|
|
@@ -4783,7 +4782,7 @@
|
|
|
4783
4782
|
return makeMap$2(value, /[, ]/, makeMap$2(value.toUpperCase(), /[, ]/));
|
|
4784
4783
|
}
|
|
4785
4784
|
};
|
|
4786
|
-
const schemaType =
|
|
4785
|
+
const schemaType = settings.schema ?? 'html5';
|
|
4787
4786
|
const schemaItems = makeSchema(schemaType);
|
|
4788
4787
|
// Allow all elements and attributes if verify_html is set to false
|
|
4789
4788
|
if (settings.verify_html === false) {
|
|
@@ -4820,7 +4819,7 @@
|
|
|
4820
4819
|
const addValidElements = (validElements) => {
|
|
4821
4820
|
const globalElement = Optional.from(elements['@']);
|
|
4822
4821
|
const hasPatternsRegExp = /[*?+]/;
|
|
4823
|
-
each$e(parseValidElementsRules(globalElement, validElements
|
|
4822
|
+
each$e(parseValidElementsRules(globalElement, validElements ?? ''), ({ name, element, aliasName }) => {
|
|
4824
4823
|
if (aliasName) {
|
|
4825
4824
|
elements[aliasName] = element;
|
|
4826
4825
|
}
|
|
@@ -4845,14 +4844,13 @@
|
|
|
4845
4844
|
addValidElements(validElements);
|
|
4846
4845
|
};
|
|
4847
4846
|
const addCustomElement = (name, spec) => {
|
|
4848
|
-
var _a, _b;
|
|
4849
4847
|
// Flush cached items since we are altering the default maps
|
|
4850
4848
|
delete mapCache.text_block_elements;
|
|
4851
4849
|
delete mapCache.block_elements;
|
|
4852
4850
|
const inline = spec.extends ? !isBlock(spec.extends) : false;
|
|
4853
4851
|
const cloneName = spec.extends;
|
|
4854
4852
|
children[name] = cloneName ? children[cloneName] : {};
|
|
4855
|
-
customElementsMap[name] = cloneName
|
|
4853
|
+
customElementsMap[name] = cloneName ?? name;
|
|
4856
4854
|
// Treat all custom elements as being non-empty by default
|
|
4857
4855
|
nonEmptyElementsMap[name.toUpperCase()] = {};
|
|
4858
4856
|
nonEmptyElementsMap[name] = {};
|
|
@@ -4877,7 +4875,7 @@
|
|
|
4877
4875
|
customRule.attributesOrder.push(name);
|
|
4878
4876
|
customRule.attributes[name] = {};
|
|
4879
4877
|
};
|
|
4880
|
-
const customRule =
|
|
4878
|
+
const customRule = elements[name] ?? {};
|
|
4881
4879
|
delete customRule.attributesDefault;
|
|
4882
4880
|
delete customRule.attributesForced;
|
|
4883
4881
|
delete customRule.attributePatterns;
|
|
@@ -4901,7 +4899,7 @@
|
|
|
4901
4899
|
}
|
|
4902
4900
|
// Add custom pad empty rule
|
|
4903
4901
|
if (isBoolean(spec.padEmpty)) {
|
|
4904
|
-
const customRule =
|
|
4902
|
+
const customRule = elements[name] ?? {};
|
|
4905
4903
|
customRule.paddEmpty = spec.padEmpty;
|
|
4906
4904
|
elements[name] = customRule;
|
|
4907
4905
|
}
|
|
@@ -4939,13 +4937,22 @@
|
|
|
4939
4937
|
}
|
|
4940
4938
|
};
|
|
4941
4939
|
const addCustomElementsFromString = (customElements) => {
|
|
4942
|
-
each$e(parseCustomElementsRules(customElements
|
|
4940
|
+
each$e(parseCustomElementsRules(customElements ?? ''), ({ name, cloneName }) => {
|
|
4943
4941
|
addCustomElement(name, { extends: cloneName });
|
|
4944
4942
|
});
|
|
4945
4943
|
};
|
|
4944
|
+
const addComponentUrl = (elementName, componentUrl) => {
|
|
4945
|
+
componentUrls[elementName] = componentUrl;
|
|
4946
|
+
};
|
|
4946
4947
|
const addCustomElements = (customElements) => {
|
|
4947
4948
|
if (isObject(customElements)) {
|
|
4948
|
-
each$d(customElements, (spec, name) =>
|
|
4949
|
+
each$d(customElements, (spec, name) => {
|
|
4950
|
+
const componentUrl = spec.componentUrl;
|
|
4951
|
+
if (isString(componentUrl)) {
|
|
4952
|
+
addComponentUrl(name, componentUrl);
|
|
4953
|
+
}
|
|
4954
|
+
addCustomElement(name, spec);
|
|
4955
|
+
});
|
|
4949
4956
|
}
|
|
4950
4957
|
else if (isString(customElements)) {
|
|
4951
4958
|
addCustomElementsFromString(customElements);
|
|
@@ -4953,7 +4960,7 @@
|
|
|
4953
4960
|
};
|
|
4954
4961
|
// Adds valid children to the schema object
|
|
4955
4962
|
const addValidChildren = (validChildren) => {
|
|
4956
|
-
each$e(parseValidChildrenRules(validChildren
|
|
4963
|
+
each$e(parseValidChildrenRules(validChildren ?? ''), ({ operation, name, validChildren }) => {
|
|
4957
4964
|
const parent = operation === 'replace' ? { '#comment': {} } : children[name];
|
|
4958
4965
|
const processNodeName = (name) => {
|
|
4959
4966
|
if (operation === 'remove') {
|
|
@@ -5301,6 +5308,13 @@
|
|
|
5301
5308
|
* @method addValidChildren
|
|
5302
5309
|
* @param {String} valid_children Valid children elements string to parse
|
|
5303
5310
|
*/
|
|
5311
|
+
/**
|
|
5312
|
+
* Returns an object of all custom elements that have component URLs.
|
|
5313
|
+
*
|
|
5314
|
+
* @method getComponentUrls
|
|
5315
|
+
* @return {Object} Object with where key is the component and the value is the url for that component.
|
|
5316
|
+
*/
|
|
5317
|
+
const getComponentUrls = constant(componentUrls);
|
|
5304
5318
|
setup();
|
|
5305
5319
|
return {
|
|
5306
5320
|
type: schemaType,
|
|
@@ -5321,6 +5335,7 @@
|
|
|
5321
5335
|
getWhitespaceElements,
|
|
5322
5336
|
getTransparentElements,
|
|
5323
5337
|
getSpecialElements,
|
|
5338
|
+
getComponentUrls,
|
|
5324
5339
|
isValidChild,
|
|
5325
5340
|
isValid,
|
|
5326
5341
|
isBlock,
|
|
@@ -5330,7 +5345,7 @@
|
|
|
5330
5345
|
addValidElements,
|
|
5331
5346
|
setValidElements,
|
|
5332
5347
|
addCustomElements,
|
|
5333
|
-
addValidChildren
|
|
5348
|
+
addValidChildren,
|
|
5334
5349
|
};
|
|
5335
5350
|
};
|
|
5336
5351
|
|
|
@@ -5697,7 +5712,7 @@
|
|
|
5697
5712
|
// An event needs normalizing if it doesn't have the prevent default function or if it's a native event
|
|
5698
5713
|
const needsNormalizing = (event) => isNullable(event.preventDefault) || isNativeEvent(event);
|
|
5699
5714
|
const clone$2 = (originalEvent, data) => {
|
|
5700
|
-
const event = data
|
|
5715
|
+
const event = data ?? {};
|
|
5701
5716
|
// Copy all properties from the original event
|
|
5702
5717
|
for (const name in originalEvent) {
|
|
5703
5718
|
// Some properties are deprecated and produces a warning so don't include them
|
|
@@ -5723,12 +5738,11 @@
|
|
|
5723
5738
|
return event;
|
|
5724
5739
|
};
|
|
5725
5740
|
const normalize$3 = (type, originalEvent, fallbackTarget, data) => {
|
|
5726
|
-
var _a;
|
|
5727
5741
|
const event = clone$2(originalEvent, data);
|
|
5728
5742
|
event.type = type;
|
|
5729
5743
|
// Normalize target IE uses srcElement
|
|
5730
5744
|
if (isNullable(event.target)) {
|
|
5731
|
-
event.target =
|
|
5745
|
+
event.target = event.srcElement ?? fallbackTarget;
|
|
5732
5746
|
}
|
|
5733
5747
|
if (needsNormalizing(originalEvent)) {
|
|
5734
5748
|
// Add preventDefault method
|
|
@@ -5843,11 +5857,14 @@
|
|
|
5843
5857
|
* This class enables you to bind/unbind native events to elements and normalize it's behavior across browsers.
|
|
5844
5858
|
*/
|
|
5845
5859
|
class EventUtils {
|
|
5860
|
+
static Event = new EventUtils();
|
|
5861
|
+
// State if the DOMContentLoaded was executed or not
|
|
5862
|
+
domLoaded = false;
|
|
5863
|
+
events = {};
|
|
5864
|
+
expando;
|
|
5865
|
+
hasFocusIn;
|
|
5866
|
+
count = 1;
|
|
5846
5867
|
constructor() {
|
|
5847
|
-
// State if the DOMContentLoaded was executed or not
|
|
5848
|
-
this.domLoaded = false;
|
|
5849
|
-
this.events = {};
|
|
5850
|
-
this.count = 1;
|
|
5851
5868
|
this.expando = eventExpandoPrefix + (+new Date()).toString(32);
|
|
5852
5869
|
this.hasFocusIn = 'onfocusin' in document.documentElement;
|
|
5853
5870
|
this.count = 1;
|
|
@@ -5995,7 +6012,7 @@
|
|
|
5995
6012
|
// IE will fail here since it can't delete properties from window
|
|
5996
6013
|
delete target[this.expando];
|
|
5997
6014
|
}
|
|
5998
|
-
catch
|
|
6015
|
+
catch {
|
|
5999
6016
|
// IE will set it to null
|
|
6000
6017
|
target[this.expando] = null;
|
|
6001
6018
|
}
|
|
@@ -6118,7 +6135,6 @@
|
|
|
6118
6135
|
}
|
|
6119
6136
|
}
|
|
6120
6137
|
}
|
|
6121
|
-
EventUtils.Event = new EventUtils();
|
|
6122
6138
|
|
|
6123
6139
|
/**
|
|
6124
6140
|
* Utility class for various DOM manipulation and retrieval functions.
|
|
@@ -6477,12 +6493,11 @@
|
|
|
6477
6493
|
const getPrev = (node, selector) => _findSib(node, selector, 'previousSibling');
|
|
6478
6494
|
const isParentNode = (node) => isFunction(node.querySelectorAll);
|
|
6479
6495
|
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;
|
|
6496
|
+
const elm = get(scope) ?? settings.root_element ?? doc;
|
|
6482
6497
|
return isParentNode(elm) ? from(elm.querySelectorAll(selector)) : [];
|
|
6483
6498
|
};
|
|
6484
6499
|
const run = function (elm, func, scope) {
|
|
6485
|
-
const context = scope
|
|
6500
|
+
const context = scope ?? this;
|
|
6486
6501
|
if (isArray$1(elm)) {
|
|
6487
6502
|
const result = [];
|
|
6488
6503
|
each$a(elm, (e, i) => {
|
|
@@ -6687,8 +6702,8 @@
|
|
|
6687
6702
|
const insertAfter = (node, reference) => {
|
|
6688
6703
|
const referenceNode = get(reference);
|
|
6689
6704
|
return run(node, (node) => {
|
|
6690
|
-
const parent = referenceNode
|
|
6691
|
-
const nextSibling = referenceNode
|
|
6705
|
+
const parent = referenceNode?.parentNode;
|
|
6706
|
+
const nextSibling = referenceNode?.nextSibling;
|
|
6692
6707
|
if (parent) {
|
|
6693
6708
|
if (nextSibling) {
|
|
6694
6709
|
parent.insertBefore(node, nextSibling);
|
|
@@ -6701,14 +6716,13 @@
|
|
|
6701
6716
|
});
|
|
6702
6717
|
};
|
|
6703
6718
|
const replace = (newElm, oldElm, keepChildren) => run(oldElm, (elm) => {
|
|
6704
|
-
var _a;
|
|
6705
6719
|
const replacee = isArray$1(oldElm) ? newElm.cloneNode(true) : newElm;
|
|
6706
6720
|
if (keepChildren) {
|
|
6707
6721
|
each$a(grep(elm.childNodes), (node) => {
|
|
6708
6722
|
replacee.appendChild(node);
|
|
6709
6723
|
});
|
|
6710
6724
|
}
|
|
6711
|
-
|
|
6725
|
+
elm.parentNode?.replaceChild(replacee, elm);
|
|
6712
6726
|
return elm;
|
|
6713
6727
|
});
|
|
6714
6728
|
const rename = (elm, name) => {
|
|
@@ -7572,12 +7586,14 @@
|
|
|
7572
7586
|
const LOADED = 2;
|
|
7573
7587
|
const FAILED = 3;
|
|
7574
7588
|
class ScriptLoader {
|
|
7589
|
+
static ScriptLoader = new ScriptLoader();
|
|
7590
|
+
settings;
|
|
7591
|
+
states = {};
|
|
7592
|
+
queue = [];
|
|
7593
|
+
scriptLoadedCallbacks = {};
|
|
7594
|
+
queueLoadedCallbacks = [];
|
|
7595
|
+
loading = false;
|
|
7575
7596
|
constructor(settings = {}) {
|
|
7576
|
-
this.states = {};
|
|
7577
|
-
this.queue = [];
|
|
7578
|
-
this.scriptLoadedCallbacks = {};
|
|
7579
|
-
this.queueLoadedCallbacks = [];
|
|
7580
|
-
this.loading = false;
|
|
7581
7597
|
this.settings = settings;
|
|
7582
7598
|
}
|
|
7583
7599
|
_setReferrerPolicy(referrerPolicy) {
|
|
@@ -7596,6 +7612,7 @@
|
|
|
7596
7612
|
loadScript(url) {
|
|
7597
7613
|
return new Promise((resolve, reject) => {
|
|
7598
7614
|
const dom = DOM$e;
|
|
7615
|
+
const doc = document;
|
|
7599
7616
|
let elm;
|
|
7600
7617
|
const cleanup = () => {
|
|
7601
7618
|
dom.remove(id);
|
|
@@ -7617,7 +7634,7 @@
|
|
|
7617
7634
|
};
|
|
7618
7635
|
const id = dom.uniqueId();
|
|
7619
7636
|
// Create new script element
|
|
7620
|
-
elm =
|
|
7637
|
+
elm = doc.createElement('script');
|
|
7621
7638
|
elm.id = id;
|
|
7622
7639
|
elm.type = 'text/javascript';
|
|
7623
7640
|
elm.src = Tools._addCacheSuffix(url);
|
|
@@ -7636,7 +7653,7 @@
|
|
|
7636
7653
|
// Add onerror event will get fired on some browsers but not all of them
|
|
7637
7654
|
elm.onerror = error;
|
|
7638
7655
|
// Add script to document
|
|
7639
|
-
(
|
|
7656
|
+
(doc.head || doc.body).appendChild(elm);
|
|
7640
7657
|
});
|
|
7641
7658
|
}
|
|
7642
7659
|
/**
|
|
@@ -7784,8 +7801,28 @@
|
|
|
7784
7801
|
return processQueue(uniqueScripts);
|
|
7785
7802
|
}
|
|
7786
7803
|
}
|
|
7804
|
+
/**
|
|
7805
|
+
* Returns the attributes that should be added to a script tag when loading the specified URL.
|
|
7806
|
+
*
|
|
7807
|
+
* @method getScriptAttributes
|
|
7808
|
+
* @param {String} url Url to get attributes for.
|
|
7809
|
+
* @return {Object} Object with attributes to add to the script tag.
|
|
7810
|
+
*/
|
|
7811
|
+
getScriptAttributes(url) {
|
|
7812
|
+
const attrs = {};
|
|
7813
|
+
if (this.settings.referrerPolicy) {
|
|
7814
|
+
attrs.referrerpolicy = this.settings.referrerPolicy;
|
|
7815
|
+
}
|
|
7816
|
+
const crossOrigin = this.settings.crossOrigin;
|
|
7817
|
+
if (isFunction(crossOrigin)) {
|
|
7818
|
+
const resultCrossOrigin = crossOrigin(url);
|
|
7819
|
+
if (isString(resultCrossOrigin)) {
|
|
7820
|
+
attrs.crossorigin = resultCrossOrigin;
|
|
7821
|
+
}
|
|
7822
|
+
}
|
|
7823
|
+
return attrs;
|
|
7824
|
+
}
|
|
7787
7825
|
}
|
|
7788
|
-
ScriptLoader.ScriptLoader = new ScriptLoader();
|
|
7789
7826
|
|
|
7790
7827
|
const isDuplicated = (items, item) => {
|
|
7791
7828
|
const firstIndex = items.indexOf(item);
|
|
@@ -8226,14 +8263,13 @@
|
|
|
8226
8263
|
const dataAnnotation$1 = dataAnnotation();
|
|
8227
8264
|
const identifyParserNode = (node) => Optional.from(node.attr(dataAnnotation$1)).bind(registry.lookup);
|
|
8228
8265
|
const removeDirectAnnotation = (node) => {
|
|
8229
|
-
var _a, _b;
|
|
8230
8266
|
node.attr(dataAnnotationId(), null);
|
|
8231
8267
|
node.attr(dataAnnotation(), null);
|
|
8232
8268
|
node.attr(dataAnnotationActive(), null);
|
|
8233
8269
|
const customAttrNames = Optional.from(node.attr(dataAnnotationAttributes())).map((names) => names.split(',')).getOr([]);
|
|
8234
8270
|
const customClasses = Optional.from(node.attr(dataAnnotationClasses())).map((names) => names.split(',')).getOr([]);
|
|
8235
8271
|
each$e(customAttrNames, (name) => node.attr(name, null));
|
|
8236
|
-
const classList =
|
|
8272
|
+
const classList = node.attr('class')?.split(' ') ?? [];
|
|
8237
8273
|
const newClassList = difference(classList, [annotation()].concat(customClasses));
|
|
8238
8274
|
node.attr('class', newClassList.length > 0 ? newClassList.join(' ') : null);
|
|
8239
8275
|
node.attr(dataAnnotationClasses(), null);
|
|
@@ -8335,7 +8371,7 @@
|
|
|
8335
8371
|
* @return {Object} An object containing the matched text node and offset. If no match is found, null will be returned.
|
|
8336
8372
|
*/
|
|
8337
8373
|
const backwards = (node, offset, process, root) => {
|
|
8338
|
-
const walker = TextWalker(node, root
|
|
8374
|
+
const walker = TextWalker(node, root ?? dom.getRoot(), isBlockBoundary);
|
|
8339
8375
|
return walk(node, offset, () => walker.prev().map((prev) => ({ container: prev, offset: prev.length })), process).getOrNull();
|
|
8340
8376
|
};
|
|
8341
8377
|
/**
|
|
@@ -8349,7 +8385,7 @@
|
|
|
8349
8385
|
* @return {Object} An object containing the matched text node and offset. If no match is found, null will be returned.
|
|
8350
8386
|
*/
|
|
8351
8387
|
const forwards = (node, offset, process, root) => {
|
|
8352
|
-
const walker = TextWalker(node, root
|
|
8388
|
+
const walker = TextWalker(node, root ?? dom.getRoot(), isBlockBoundary);
|
|
8353
8389
|
return walk(node, offset, () => walker.next().map((next) => ({ container: next, offset: 0 })), process).getOrNull();
|
|
8354
8390
|
};
|
|
8355
8391
|
return {
|
|
@@ -8455,8 +8491,7 @@
|
|
|
8455
8491
|
const isCaretContainer$2 = (node) => isCaretContainerBlock$1(node) || isCaretContainerInline(node);
|
|
8456
8492
|
const hasContent = (node) => node.firstChild !== node.lastChild || !isBr$7(node.firstChild);
|
|
8457
8493
|
const insertInline$1 = (node, before) => {
|
|
8458
|
-
|
|
8459
|
-
const doc = (_a = node.ownerDocument) !== null && _a !== void 0 ? _a : document;
|
|
8494
|
+
const doc = node.ownerDocument ?? document;
|
|
8460
8495
|
const textNode = doc.createTextNode(ZWSP$1);
|
|
8461
8496
|
const parentNode = node.parentNode;
|
|
8462
8497
|
if (!before) {
|
|
@@ -8471,10 +8506,10 @@
|
|
|
8471
8506
|
}
|
|
8472
8507
|
}
|
|
8473
8508
|
if (node.nextSibling) {
|
|
8474
|
-
parentNode
|
|
8509
|
+
parentNode?.insertBefore(textNode, node.nextSibling);
|
|
8475
8510
|
}
|
|
8476
8511
|
else {
|
|
8477
|
-
parentNode
|
|
8512
|
+
parentNode?.appendChild(textNode);
|
|
8478
8513
|
}
|
|
8479
8514
|
}
|
|
8480
8515
|
else {
|
|
@@ -8487,7 +8522,7 @@
|
|
|
8487
8522
|
return sibling.splitText(sibling.data.length - 1);
|
|
8488
8523
|
}
|
|
8489
8524
|
}
|
|
8490
|
-
parentNode
|
|
8525
|
+
parentNode?.insertBefore(textNode, node);
|
|
8491
8526
|
}
|
|
8492
8527
|
return textNode;
|
|
8493
8528
|
};
|
|
@@ -8508,8 +8543,7 @@
|
|
|
8508
8543
|
return container.data.charAt(pos.offset() - 1) === ZWSP$1 || pos.isAtEnd() && isCaretContainerInline(container.nextSibling);
|
|
8509
8544
|
};
|
|
8510
8545
|
const insertBlock = (blockName, node, before) => {
|
|
8511
|
-
|
|
8512
|
-
const doc = (_a = node.ownerDocument) !== null && _a !== void 0 ? _a : document;
|
|
8546
|
+
const doc = node.ownerDocument ?? document;
|
|
8513
8547
|
const blockNode = doc.createElement(blockName);
|
|
8514
8548
|
blockNode.setAttribute('data-mce-caret', before ? 'before' : 'after');
|
|
8515
8549
|
blockNode.setAttribute('data-mce-bogus', 'all');
|
|
@@ -8517,25 +8551,24 @@
|
|
|
8517
8551
|
const parentNode = node.parentNode;
|
|
8518
8552
|
if (!before) {
|
|
8519
8553
|
if (node.nextSibling) {
|
|
8520
|
-
parentNode
|
|
8554
|
+
parentNode?.insertBefore(blockNode, node.nextSibling);
|
|
8521
8555
|
}
|
|
8522
8556
|
else {
|
|
8523
|
-
parentNode
|
|
8557
|
+
parentNode?.appendChild(blockNode);
|
|
8524
8558
|
}
|
|
8525
8559
|
}
|
|
8526
8560
|
else {
|
|
8527
|
-
parentNode
|
|
8561
|
+
parentNode?.insertBefore(blockNode, node);
|
|
8528
8562
|
}
|
|
8529
8563
|
return blockNode;
|
|
8530
8564
|
};
|
|
8531
8565
|
const startsWithCaretContainer$1 = (node) => isText$9(node) && node.data[0] === ZWSP$1;
|
|
8532
8566
|
const endsWithCaretContainer$1 = (node) => isText$9(node) && node.data[node.data.length - 1] === ZWSP$1;
|
|
8533
8567
|
const trimBogusBr = (elm) => {
|
|
8534
|
-
var _a;
|
|
8535
8568
|
const brs = elm.getElementsByTagName('br');
|
|
8536
8569
|
const lastBr = brs[brs.length - 1];
|
|
8537
8570
|
if (isBogus$1(lastBr)) {
|
|
8538
|
-
|
|
8571
|
+
lastBr.parentNode?.removeChild(lastBr);
|
|
8539
8572
|
}
|
|
8540
8573
|
};
|
|
8541
8574
|
const showCaretContainerBlock = (caretContainer) => {
|
|
@@ -8828,7 +8861,6 @@
|
|
|
8828
8861
|
};
|
|
8829
8862
|
const isZeroRect = (r) => r.left === 0 && r.right === 0 && r.top === 0 && r.bottom === 0;
|
|
8830
8863
|
const getBoundingClientRect$1 = (item) => {
|
|
8831
|
-
var _a;
|
|
8832
8864
|
let clientRect;
|
|
8833
8865
|
const clientRects = item.getClientRects();
|
|
8834
8866
|
if (clientRects.length > 0) {
|
|
@@ -8841,7 +8873,7 @@
|
|
|
8841
8873
|
return getBrClientRect(item);
|
|
8842
8874
|
}
|
|
8843
8875
|
if (isZeroRect(clientRect) && isRange(item)) {
|
|
8844
|
-
return
|
|
8876
|
+
return getBoundingClientRectWebKitText(item) ?? clientRect;
|
|
8845
8877
|
}
|
|
8846
8878
|
return clientRect;
|
|
8847
8879
|
};
|
|
@@ -9473,7 +9505,6 @@
|
|
|
9473
9505
|
const isBlockPattern = (pattern) => pattern.type === 'block-command' || pattern.type === 'block-format';
|
|
9474
9506
|
const hasBlockTrigger = (pattern, trigger) => (pattern.type === 'block-command' || pattern.type === 'block-format') && pattern.trigger === trigger;
|
|
9475
9507
|
const normalizePattern = (pattern) => {
|
|
9476
|
-
var _a;
|
|
9477
9508
|
const err = (message) => Result.error({ message, pattern });
|
|
9478
9509
|
const formatOrCmd = (name, onFormat, onCommand) => {
|
|
9479
9510
|
if (pattern.format !== undefined) {
|
|
@@ -9543,7 +9574,7 @@
|
|
|
9543
9574
|
}
|
|
9544
9575
|
else {
|
|
9545
9576
|
// block pattern
|
|
9546
|
-
const trigger =
|
|
9577
|
+
const trigger = pattern.trigger ?? 'space';
|
|
9547
9578
|
if (pattern.start.length === 0) {
|
|
9548
9579
|
return err('Block pattern has empty `start` parameter');
|
|
9549
9580
|
}
|
|
@@ -10667,7 +10698,6 @@
|
|
|
10667
10698
|
return clientRect;
|
|
10668
10699
|
};
|
|
10669
10700
|
const trimInlineCaretContainers = (root) => {
|
|
10670
|
-
var _a, _b;
|
|
10671
10701
|
const fakeCaretTargetNodes = descendants(SugarElement.fromDom(root), inlineFakeCaretSelector);
|
|
10672
10702
|
for (let i = 0; i < fakeCaretTargetNodes.length; i++) {
|
|
10673
10703
|
const node = fakeCaretTargetNodes[i].dom;
|
|
@@ -10675,7 +10705,7 @@
|
|
|
10675
10705
|
if (endsWithCaretContainer$1(sibling)) {
|
|
10676
10706
|
const data = sibling.data;
|
|
10677
10707
|
if (data.length === 1) {
|
|
10678
|
-
|
|
10708
|
+
sibling.parentNode?.removeChild(sibling);
|
|
10679
10709
|
}
|
|
10680
10710
|
else {
|
|
10681
10711
|
sibling.deleteData(data.length - 1, 1);
|
|
@@ -10685,7 +10715,7 @@
|
|
|
10685
10715
|
if (startsWithCaretContainer$1(sibling)) {
|
|
10686
10716
|
const data = sibling.data;
|
|
10687
10717
|
if (data.length === 1) {
|
|
10688
|
-
|
|
10718
|
+
sibling.parentNode?.removeChild(sibling);
|
|
10689
10719
|
}
|
|
10690
10720
|
else {
|
|
10691
10721
|
sibling.deleteData(0, 1);
|
|
@@ -10864,9 +10894,14 @@
|
|
|
10864
10894
|
.map((elm) => elm.dom)
|
|
10865
10895
|
.getOr(rootNode);
|
|
10866
10896
|
};
|
|
10897
|
+
const isAbsPositionedElement = (node) => isElement$7(node) && get$7(SugarElement.fromDom(node), 'position') === 'absolute';
|
|
10898
|
+
const isInlineBlock = (node, rootNode) => node.parentNode !== rootNode;
|
|
10899
|
+
const isInlineAbsPositionedCEF = (node, rootNode) => isContentEditableFalse$6(node) && isAbsPositionedElement(node) && isInlineBlock(node, rootNode);
|
|
10867
10900
|
const getParentBlock$3 = (node, rootNode) => {
|
|
10868
10901
|
while (node && node !== rootNode) {
|
|
10869
|
-
|
|
10902
|
+
// Exclude inline absolutely positioned CEF elements since they have 'display: block'
|
|
10903
|
+
// Created TINY-12922 to improve handling non CEF elements
|
|
10904
|
+
if (isBlockLike(node) && !isInlineAbsPositionedCEF(node, rootNode)) {
|
|
10870
10905
|
return node;
|
|
10871
10906
|
}
|
|
10872
10907
|
node = node.parentNode;
|
|
@@ -10886,8 +10921,7 @@
|
|
|
10886
10921
|
return Optional.from(container.childNodes[offset + relativeOffset]);
|
|
10887
10922
|
};
|
|
10888
10923
|
const beforeAfter = (before, node) => {
|
|
10889
|
-
|
|
10890
|
-
const doc = (_a = node.ownerDocument) !== null && _a !== void 0 ? _a : document;
|
|
10924
|
+
const doc = node.ownerDocument ?? document;
|
|
10891
10925
|
const range = doc.createRange();
|
|
10892
10926
|
if (before) {
|
|
10893
10927
|
range.setStartBefore(node);
|
|
@@ -11334,8 +11368,7 @@
|
|
|
11334
11368
|
});
|
|
11335
11369
|
};
|
|
11336
11370
|
const insertZwsp = (node, rng) => {
|
|
11337
|
-
|
|
11338
|
-
const doc = (_a = node.ownerDocument) !== null && _a !== void 0 ? _a : document;
|
|
11371
|
+
const doc = node.ownerDocument ?? document;
|
|
11339
11372
|
const textNode = doc.createTextNode(ZWSP$1);
|
|
11340
11373
|
node.appendChild(textNode);
|
|
11341
11374
|
rng.setStart(textNode, 0);
|
|
@@ -11399,7 +11432,7 @@
|
|
|
11399
11432
|
const isValidTextNode = (node) => isText$b(node) && node.data.length > 0;
|
|
11400
11433
|
const restoreEndPoint$1 = (dom, suffix, bookmark) => {
|
|
11401
11434
|
const marker = dom.get(bookmark.id + '_' + suffix);
|
|
11402
|
-
const markerParent = marker
|
|
11435
|
+
const markerParent = marker?.parentNode;
|
|
11403
11436
|
const keep = bookmark.keep;
|
|
11404
11437
|
if (marker && markerParent) {
|
|
11405
11438
|
let container;
|
|
@@ -11689,7 +11722,7 @@
|
|
|
11689
11722
|
const isSelectionOverWholeTextNode = (range) => isSelectionOverWholeNode(range, isText$b);
|
|
11690
11723
|
const isSelectionOverWholeAnchor = (range) => isSelectionOverWholeNode(range, isAnchor);
|
|
11691
11724
|
|
|
11692
|
-
const isNode = (node) => isNumber(node
|
|
11725
|
+
const isNode = (node) => isNumber(node?.nodeType);
|
|
11693
11726
|
const isElementNode$1 = (node) => isElement$7(node) && !isBookmarkNode$1(node) && !isCaretNode(node) && !isBogus$1(node);
|
|
11694
11727
|
// In TinyMCE, directly selected elements are indicated with the data-mce-selected attribute
|
|
11695
11728
|
// Elements that can be directly selected include control elements such as img, media elements, noneditable elements and others
|
|
@@ -11725,7 +11758,6 @@
|
|
|
11725
11758
|
};
|
|
11726
11759
|
// 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
11760
|
const moveStartToNearestText = (dom, selection) => {
|
|
11728
|
-
var _a, _b;
|
|
11729
11761
|
const rng = selection.getRng();
|
|
11730
11762
|
const { startContainer, startOffset } = rng;
|
|
11731
11763
|
const selectedNode = selection.getNode();
|
|
@@ -11739,11 +11771,11 @@
|
|
|
11739
11771
|
let walker;
|
|
11740
11772
|
if (startOffset < nodes.length) {
|
|
11741
11773
|
const startNode = nodes[startOffset];
|
|
11742
|
-
walker = new DomTreeWalker(startNode,
|
|
11774
|
+
walker = new DomTreeWalker(startNode, dom.getParent(startNode, dom.isBlock) ?? root);
|
|
11743
11775
|
}
|
|
11744
11776
|
else {
|
|
11745
11777
|
const startNode = nodes[nodes.length - 1];
|
|
11746
|
-
walker = new DomTreeWalker(startNode,
|
|
11778
|
+
walker = new DomTreeWalker(startNode, dom.getParent(startNode, dom.isBlock) ?? root);
|
|
11747
11779
|
walker.next(true);
|
|
11748
11780
|
}
|
|
11749
11781
|
for (let node = walker.current(); node; node = walker.next()) {
|
|
@@ -12031,7 +12063,6 @@
|
|
|
12031
12063
|
return container;
|
|
12032
12064
|
};
|
|
12033
12065
|
const findBlockEndPoint = (dom, formatList, container, siblingName) => {
|
|
12034
|
-
var _a;
|
|
12035
12066
|
let node = container;
|
|
12036
12067
|
const root = dom.getRoot();
|
|
12037
12068
|
const format = formatList[0];
|
|
@@ -12041,7 +12072,7 @@
|
|
|
12041
12072
|
}
|
|
12042
12073
|
// Expand to first wrappable block element or any block element
|
|
12043
12074
|
if (!node) {
|
|
12044
|
-
const scopeRoot =
|
|
12075
|
+
const scopeRoot = dom.getParent(container, 'LI,TD,TH,SUMMARY') ?? root;
|
|
12045
12076
|
node = dom.getParent(isText$b(container) ? container.parentNode : container,
|
|
12046
12077
|
// Fixes #6183 where it would expand to editable parent element in inline mode
|
|
12047
12078
|
(node) => node !== root && isTextBlock$1(dom.schema, node), scopeRoot);
|
|
@@ -12237,7 +12268,6 @@
|
|
|
12237
12268
|
};
|
|
12238
12269
|
|
|
12239
12270
|
const walk$3 = (dom, rng, callback) => {
|
|
12240
|
-
var _a;
|
|
12241
12271
|
const startOffset = rng.startOffset;
|
|
12242
12272
|
const startContainer = getNode$1(rng.startContainer, startOffset);
|
|
12243
12273
|
const endOffset = rng.endOffset;
|
|
@@ -12288,7 +12318,7 @@
|
|
|
12288
12318
|
return callback(exclude([startContainer]));
|
|
12289
12319
|
}
|
|
12290
12320
|
// Find common ancestor and end points
|
|
12291
|
-
const ancestor =
|
|
12321
|
+
const ancestor = dom.findCommonAncestor(startContainer, endContainer) ?? dom.getRoot();
|
|
12292
12322
|
// Process left side
|
|
12293
12323
|
if (dom.isChildOf(startContainer, endContainer)) {
|
|
12294
12324
|
return walkBoundary(startContainer, ancestor, true);
|
|
@@ -12672,7 +12702,7 @@
|
|
|
12672
12702
|
rng.setEnd(bookmark.finish.dom, bookmark.foffset);
|
|
12673
12703
|
return Optional.some(rng);
|
|
12674
12704
|
}
|
|
12675
|
-
catch
|
|
12705
|
+
catch {
|
|
12676
12706
|
return Optional.none();
|
|
12677
12707
|
}
|
|
12678
12708
|
};
|
|
@@ -12774,49 +12804,6 @@
|
|
|
12774
12804
|
}
|
|
12775
12805
|
};
|
|
12776
12806
|
|
|
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
12807
|
const isManualNodeChange = (e) => {
|
|
12821
12808
|
return e.type === 'nodechange' && e.selectionChange;
|
|
12822
12809
|
};
|
|
@@ -12887,7 +12874,7 @@
|
|
|
12887
12874
|
const root = getRootNode(SugarElement.fromDom(editor.getElement()));
|
|
12888
12875
|
return active(root).fold(() => document.body, (x) => x.dom);
|
|
12889
12876
|
}
|
|
12890
|
-
catch
|
|
12877
|
+
catch {
|
|
12891
12878
|
// IE sometimes fails to get the activeElement when resizing table
|
|
12892
12879
|
// TODO: Investigate this
|
|
12893
12880
|
return document.body;
|
|
@@ -12903,18 +12890,6 @@
|
|
|
12903
12890
|
fn(contentArea, 'tox-edit-focus');
|
|
12904
12891
|
}
|
|
12905
12892
|
};
|
|
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
12893
|
editor.on('focusin', () => {
|
|
12919
12894
|
const focusedEditor = editorManager.focusedEditor;
|
|
12920
12895
|
if (isEditorContentAreaElement(getActiveElement(editor))) {
|
|
@@ -12928,10 +12903,6 @@
|
|
|
12928
12903
|
editorManager.focusedEditor = editor;
|
|
12929
12904
|
editor.dispatch('focus', { blurredEditor: focusedEditor });
|
|
12930
12905
|
editor.focus(true);
|
|
12931
|
-
const browser = detect$1().browser;
|
|
12932
|
-
if (editor.inline !== true && (browser.isSafari() || browser.isChromium())) {
|
|
12933
|
-
bringEditorIntoView(editor);
|
|
12934
|
-
}
|
|
12935
12906
|
}
|
|
12936
12907
|
});
|
|
12937
12908
|
editor.on('focusout', () => {
|
|
@@ -13011,7 +12982,7 @@
|
|
|
13011
12982
|
try {
|
|
13012
12983
|
body.setActive();
|
|
13013
12984
|
}
|
|
13014
|
-
catch
|
|
12985
|
+
catch {
|
|
13015
12986
|
body.focus();
|
|
13016
12987
|
}
|
|
13017
12988
|
}
|
|
@@ -13119,8 +13090,10 @@
|
|
|
13119
13090
|
}
|
|
13120
13091
|
};
|
|
13121
13092
|
|
|
13093
|
+
const ucVideoNodeName = 'uc-video';
|
|
13094
|
+
const isUcVideo = (el) => el.nodeName.toLowerCase() === ucVideoNodeName;
|
|
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(() => {
|
|
@@ -35190,8 +35208,7 @@
|
|
|
35190
35208
|
const startPattern = pattern.start;
|
|
35191
35209
|
const startSpot = repeatLeft(dom, spot.container, spot.offset, matchesPattern(startPattern), block);
|
|
35192
35210
|
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;
|
|
35211
|
+
const startPatternIndex = block.textContent?.indexOf(startPattern) ?? -1;
|
|
35195
35212
|
const isCompleteMatch = startPatternIndex !== -1 && spot.offset >= startPatternIndex + startPattern.length;
|
|
35196
35213
|
if (isCompleteMatch) {
|
|
35197
35214
|
// Complete match
|
|
@@ -35227,12 +35244,11 @@
|
|
|
35227
35244
|
return textBefore(node, offset, block).bind((spot) => {
|
|
35228
35245
|
const start = findPatternStartFromSpot(dom, pattern, block, spot);
|
|
35229
35246
|
return start.bind((startRange) => {
|
|
35230
|
-
var _a;
|
|
35231
35247
|
if (requireGap) {
|
|
35232
35248
|
if (startRange.endContainer === spot.container && startRange.endOffset === spot.offset) {
|
|
35233
35249
|
return Optional.none();
|
|
35234
35250
|
}
|
|
35235
|
-
else if (spot.offset === 0 &&
|
|
35251
|
+
else if (spot.offset === 0 && startRange.endContainer.textContent?.length === startRange.endOffset) {
|
|
35236
35252
|
return Optional.none();
|
|
35237
35253
|
}
|
|
35238
35254
|
}
|
|
@@ -35463,9 +35479,7 @@
|
|
|
35463
35479
|
const nuText = text.replace(nbsp, ' ');
|
|
35464
35480
|
return find$2(sortedPatterns, (pattern) => predicate(pattern, text, nuText));
|
|
35465
35481
|
};
|
|
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 : ''; }
|
|
35482
|
+
const createFindPatterns = (findPattern, skipFullMatch) => (editor, block, patternSet, normalizedMatches, text = block.textContent ?? '') => {
|
|
35469
35483
|
const dom = editor.dom;
|
|
35470
35484
|
const forcedRootBlock = getForcedRootBlock(editor);
|
|
35471
35485
|
if (!dom.is(block, forcedRootBlock)) {
|
|
@@ -35506,9 +35520,8 @@
|
|
|
35506
35520
|
const getMatches$1 = (editor, patternSet) => {
|
|
35507
35521
|
const rng = editor.selection.getRng();
|
|
35508
35522
|
return getParentBlock(editor, rng).map((block) => {
|
|
35509
|
-
var _a;
|
|
35510
35523
|
const offset = Math.max(0, rng.startOffset);
|
|
35511
|
-
const dynamicPatternSet = resolveFromDynamicPatterns(patternSet, block,
|
|
35524
|
+
const dynamicPatternSet = resolveFromDynamicPatterns(patternSet, block, block.textContent ?? '');
|
|
35512
35525
|
// IMPORTANT: We need to get normalized match results since undoing and redoing the editor state
|
|
35513
35526
|
// via undoManager.extra() will result in the DOM being normalized.
|
|
35514
35527
|
const inlineMatches = findPatterns$2(editor, block, rng.startContainer, offset, dynamicPatternSet, true);
|
|
@@ -35677,7 +35690,7 @@
|
|
|
35677
35690
|
try {
|
|
35678
35691
|
editor.getDoc().execCommand(cmd, false, String(state));
|
|
35679
35692
|
}
|
|
35680
|
-
catch
|
|
35693
|
+
catch {
|
|
35681
35694
|
// Ignore
|
|
35682
35695
|
}
|
|
35683
35696
|
};
|
|
@@ -35769,13 +35782,12 @@
|
|
|
35769
35782
|
if (!editor.inline) {
|
|
35770
35783
|
// Needs to be both down/up due to weird rendering bug on Chrome Windows
|
|
35771
35784
|
dom.bind(editor.getDoc(), 'mousedown mouseup', (e) => {
|
|
35772
|
-
var _a;
|
|
35773
35785
|
let rng;
|
|
35774
35786
|
if (e.target === editor.getDoc().documentElement) {
|
|
35775
35787
|
rng = selection.getRng();
|
|
35776
35788
|
// 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
35789
|
// example content scrolled by browser search and user click on the horizontal scroll bar
|
|
35778
|
-
if (
|
|
35790
|
+
if (editor.getDoc().getSelection()?.anchorNode !== null) {
|
|
35779
35791
|
editor.getBody().focus();
|
|
35780
35792
|
}
|
|
35781
35793
|
if (e.type === 'mousedown') {
|
|
@@ -35875,9 +35887,8 @@
|
|
|
35875
35887
|
const isEditableImage = (node) => node.nodeName === 'IMG' && editor.dom.isEditable(node);
|
|
35876
35888
|
editor.on('mousedown', (e) => {
|
|
35877
35889
|
lift2(Optional.from(e.clientX), Optional.from(e.clientY), (clientX, clientY) => {
|
|
35878
|
-
var _a;
|
|
35879
35890
|
const caretPos = editor.getDoc().caretPositionFromPoint(clientX, clientY);
|
|
35880
|
-
const img =
|
|
35891
|
+
const img = caretPos?.offsetNode?.childNodes[caretPos.offset - (caretPos.offset > 0 ? 1 : 0)] || caretPos?.offsetNode;
|
|
35881
35892
|
if (isNonNullable(img) && isEditableImage(img)) {
|
|
35882
35893
|
const rect = img.getBoundingClientRect();
|
|
35883
35894
|
e.preventDefault();
|
|
@@ -36014,11 +36025,10 @@
|
|
|
36014
36025
|
const currentNode = SugarElement.fromDom(editor.selection.getNode());
|
|
36015
36026
|
if (isFigcaption(currentNode) && editor.selection.isCollapsed()) {
|
|
36016
36027
|
parent(currentNode).bind((parent) => {
|
|
36017
|
-
var _a;
|
|
36018
36028
|
if (editor.selection.getRng().startOffset === 0 && e.keyCode === VK.LEFT) {
|
|
36019
36029
|
return prevSibling(parent);
|
|
36020
36030
|
}
|
|
36021
|
-
else if (editor.selection.getRng().endOffset ===
|
|
36031
|
+
else if (editor.selection.getRng().endOffset === currentNode.dom.textContent?.length && e.keyCode === VK.RIGHT) {
|
|
36022
36032
|
return nextSibling(parent);
|
|
36023
36033
|
}
|
|
36024
36034
|
else {
|
|
@@ -36059,12 +36069,11 @@
|
|
|
36059
36069
|
const addBrAfterLastLinks = () => {
|
|
36060
36070
|
const fixLinks = () => {
|
|
36061
36071
|
each(dom.select('a:not([data-mce-block])'), (node) => {
|
|
36062
|
-
var _a;
|
|
36063
36072
|
let parentNode = node.parentNode;
|
|
36064
36073
|
const root = dom.getRoot();
|
|
36065
|
-
if (
|
|
36074
|
+
if (parentNode?.lastChild === node) {
|
|
36066
36075
|
while (parentNode && !dom.isBlock(parentNode)) {
|
|
36067
|
-
if (
|
|
36076
|
+
if (parentNode.parentNode?.lastChild !== parentNode || parentNode === root) {
|
|
36068
36077
|
return;
|
|
36069
36078
|
}
|
|
36070
36079
|
parentNode = parentNode.parentNode;
|
|
@@ -36361,6 +36370,91 @@
|
|
|
36361
36370
|
};
|
|
36362
36371
|
};
|
|
36363
36372
|
|
|
36373
|
+
class ComponentLoadError extends Error {
|
|
36374
|
+
url;
|
|
36375
|
+
constructor(message, url) {
|
|
36376
|
+
super(message);
|
|
36377
|
+
this.url = url;
|
|
36378
|
+
}
|
|
36379
|
+
}
|
|
36380
|
+
const hostWindowComponentScripts = {};
|
|
36381
|
+
const loadScript = (url, doc, extraAtts) => {
|
|
36382
|
+
return new Promise((resolve, reject) => {
|
|
36383
|
+
const script = SugarElement.fromTag('script');
|
|
36384
|
+
setAll$1(script, {
|
|
36385
|
+
type: 'text/javascript',
|
|
36386
|
+
src: url,
|
|
36387
|
+
...extraAtts
|
|
36388
|
+
});
|
|
36389
|
+
const clean = () => {
|
|
36390
|
+
remove$8(script);
|
|
36391
|
+
};
|
|
36392
|
+
bind$1(script, 'load', () => {
|
|
36393
|
+
clean();
|
|
36394
|
+
resolve();
|
|
36395
|
+
});
|
|
36396
|
+
bind$1(script, 'error', () => {
|
|
36397
|
+
clean();
|
|
36398
|
+
reject(new Error(`Failed to load script url: ${url}`));
|
|
36399
|
+
});
|
|
36400
|
+
append$1(getHead(doc), script);
|
|
36401
|
+
});
|
|
36402
|
+
};
|
|
36403
|
+
const loadComponent = async (url, doc) => {
|
|
36404
|
+
const extraAtts = ScriptLoader.ScriptLoader.getScriptAttributes(url);
|
|
36405
|
+
await loadScript(url, doc, extraAtts).catch(() => Promise.reject(new ComponentLoadError(`Failed to load component url: ${url}`, url)));
|
|
36406
|
+
return url;
|
|
36407
|
+
};
|
|
36408
|
+
const loadComponentsForInlineEditor = (componentUrls) => {
|
|
36409
|
+
return mapToArray(componentUrls, (url, elementName) => {
|
|
36410
|
+
return get$a(hostWindowComponentScripts, url).getOrThunk(() => {
|
|
36411
|
+
// Only load the component if it hasn't already been loaded in inline mode the page might have already loaded it
|
|
36412
|
+
if (isNullable(window.customElements.get(elementName))) {
|
|
36413
|
+
const loadPromise = loadComponent(url, getDocument());
|
|
36414
|
+
hostWindowComponentScripts[url] = loadPromise;
|
|
36415
|
+
return loadPromise;
|
|
36416
|
+
}
|
|
36417
|
+
else {
|
|
36418
|
+
return Promise.resolve(url);
|
|
36419
|
+
}
|
|
36420
|
+
}).catch((err) => {
|
|
36421
|
+
// Remove from cache if the component failed to load so we can try again later
|
|
36422
|
+
delete hostWindowComponentScripts[url];
|
|
36423
|
+
return Promise.reject(err);
|
|
36424
|
+
});
|
|
36425
|
+
});
|
|
36426
|
+
};
|
|
36427
|
+
const loadComponentsForIframeEditor = (componentUrls, doc) => {
|
|
36428
|
+
const urls = unique$1(values(componentUrls));
|
|
36429
|
+
return map$3(urls, (url) => loadComponent(url, SugarElement.fromDom(doc)));
|
|
36430
|
+
};
|
|
36431
|
+
const loadComponentsForEditor = (editor) => {
|
|
36432
|
+
const componentUrls = editor.schema.getComponentUrls();
|
|
36433
|
+
if (editor.inline) {
|
|
36434
|
+
return loadComponentsForInlineEditor(componentUrls);
|
|
36435
|
+
}
|
|
36436
|
+
else {
|
|
36437
|
+
return loadComponentsForIframeEditor(componentUrls, editor.getDoc());
|
|
36438
|
+
}
|
|
36439
|
+
};
|
|
36440
|
+
const loadComponentsAsync = async (editor) => {
|
|
36441
|
+
const loadPromises = loadComponentsForEditor(editor);
|
|
36442
|
+
const rejected = filter$5(await Promise.allSettled(loadPromises), (r) => r.status === 'rejected');
|
|
36443
|
+
if (rejected.length > 0) {
|
|
36444
|
+
each$e(rejected, (rejection) => {
|
|
36445
|
+
if (rejection.reason instanceof ComponentLoadError) {
|
|
36446
|
+
const { url } = rejection.reason;
|
|
36447
|
+
componentLoadError(editor, url);
|
|
36448
|
+
}
|
|
36449
|
+
});
|
|
36450
|
+
}
|
|
36451
|
+
};
|
|
36452
|
+
const loadComponents = (editor) => {
|
|
36453
|
+
// Since we are handling the errors in the promise rejections inside the loadComponentsAsync we can ignore the errors here
|
|
36454
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
36455
|
+
loadComponentsAsync(editor);
|
|
36456
|
+
};
|
|
36457
|
+
|
|
36364
36458
|
const DOM$6 = DOMUtils.DOM;
|
|
36365
36459
|
const appendStyle = (editor, text) => {
|
|
36366
36460
|
const body = SugarElement.fromDom(editor.getBody());
|
|
@@ -36490,13 +36584,12 @@
|
|
|
36490
36584
|
});
|
|
36491
36585
|
if (shouldPreserveCData(editor)) {
|
|
36492
36586
|
parser.addNodeFilter('#cdata', (nodes) => {
|
|
36493
|
-
var _a;
|
|
36494
36587
|
let i = nodes.length;
|
|
36495
36588
|
while (i--) {
|
|
36496
36589
|
const node = nodes[i];
|
|
36497
36590
|
node.type = 8;
|
|
36498
36591
|
node.name = '#comment';
|
|
36499
|
-
node.value = '[CDATA[' + editor.dom.encode(
|
|
36592
|
+
node.value = '[CDATA[' + editor.dom.encode(node.value ?? '') + ']]';
|
|
36500
36593
|
}
|
|
36501
36594
|
});
|
|
36502
36595
|
}
|
|
@@ -36738,6 +36831,7 @@
|
|
|
36738
36831
|
setup$7(editor, caret);
|
|
36739
36832
|
const setupRtcThunk = setup$z(editor);
|
|
36740
36833
|
preInit(editor);
|
|
36834
|
+
loadComponents(editor);
|
|
36741
36835
|
setupRtcThunk.fold(() => {
|
|
36742
36836
|
const cancelProgress = startProgress(editor);
|
|
36743
36837
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -37252,11 +37346,10 @@
|
|
|
37252
37346
|
'#455A64', // Dark Blue Gray
|
|
37253
37347
|
];
|
|
37254
37348
|
const getFirstChar = (name) => {
|
|
37255
|
-
var _a;
|
|
37256
37349
|
if (Intl.Segmenter) {
|
|
37257
37350
|
const segmenter = new Intl.Segmenter();
|
|
37258
37351
|
const iterator = segmenter.segment(name)[Symbol.iterator]();
|
|
37259
|
-
return `${
|
|
37352
|
+
return `${iterator.next().value?.segment}`;
|
|
37260
37353
|
}
|
|
37261
37354
|
else {
|
|
37262
37355
|
return name.trim()[0];
|
|
@@ -37278,7 +37371,7 @@
|
|
|
37278
37371
|
return (hash >>> 0) % (maxValue + 1);
|
|
37279
37372
|
};
|
|
37280
37373
|
const getColor = (id) => {
|
|
37281
|
-
const colorIdx = djb2Hash(id
|
|
37374
|
+
const colorIdx = djb2Hash(id ?? '', AvatarColors.length - 1);
|
|
37282
37375
|
return AvatarColors[colorIdx];
|
|
37283
37376
|
};
|
|
37284
37377
|
const generateAvatarSvg = (content, color, size) => {
|
|
@@ -37484,8 +37577,7 @@
|
|
|
37484
37577
|
};
|
|
37485
37578
|
};
|
|
37486
37579
|
const getExternalPlugins = (overrideOptions, options) => {
|
|
37487
|
-
|
|
37488
|
-
const userDefinedExternalPlugins = (_a = options.external_plugins) !== null && _a !== void 0 ? _a : {};
|
|
37580
|
+
const userDefinedExternalPlugins = options.external_plugins ?? {};
|
|
37489
37581
|
if (overrideOptions && overrideOptions.external_plugins) {
|
|
37490
37582
|
return Tools.extend({}, overrideOptions.external_plugins, userDefinedExternalPlugins);
|
|
37491
37583
|
}
|
|
@@ -37523,9 +37615,8 @@
|
|
|
37523
37615
|
return isMobileDevice && hasSection(sectionResult, 'mobile');
|
|
37524
37616
|
};
|
|
37525
37617
|
const combineOptions = (isMobileDevice, isPhone, defaultOptions, defaultOverrideOptions, options) => {
|
|
37526
|
-
var _a;
|
|
37527
37618
|
// Use mobile mode by default on phones, so patch in the mobile override options
|
|
37528
|
-
const deviceOverrideOptions = isMobileDevice ? { mobile: getMobileOverrideOptions(
|
|
37619
|
+
const deviceOverrideOptions = isMobileDevice ? { mobile: getMobileOverrideOptions(options.mobile ?? {}, isPhone) } : {};
|
|
37529
37620
|
const sectionResult = extractSections(['mobile'], deepMerge(deviceOverrideOptions, options));
|
|
37530
37621
|
const extendedOptions = Tools.extend(
|
|
37531
37622
|
// Default options
|
|
@@ -37600,7 +37691,7 @@
|
|
|
37600
37691
|
try {
|
|
37601
37692
|
doc.execCommand(command);
|
|
37602
37693
|
}
|
|
37603
|
-
catch
|
|
37694
|
+
catch {
|
|
37604
37695
|
// Command failed
|
|
37605
37696
|
failed = true;
|
|
37606
37697
|
}
|
|
@@ -37849,8 +37940,7 @@
|
|
|
37849
37940
|
lineHeightAction(editor, value);
|
|
37850
37941
|
},
|
|
37851
37942
|
'Lang': (command, _ui, lang) => {
|
|
37852
|
-
|
|
37853
|
-
toggleFormat(command, { value: lang.code, customValue: (_a = lang.customCode) !== null && _a !== void 0 ? _a : null });
|
|
37943
|
+
toggleFormat(command, { value: lang.code, customValue: lang.customCode ?? null });
|
|
37854
37944
|
},
|
|
37855
37945
|
'RemoveFormat': (command) => {
|
|
37856
37946
|
editor.formatter.remove(command);
|
|
@@ -38038,7 +38128,7 @@
|
|
|
38038
38128
|
const registerExecCommands = (editor) => {
|
|
38039
38129
|
editor.editorCommands.addCommands({
|
|
38040
38130
|
mceRemoveNode: (_command, _ui, value) => {
|
|
38041
|
-
const node = value
|
|
38131
|
+
const node = value ?? editor.selection.getNode();
|
|
38042
38132
|
// Make sure that the body node isn't removed
|
|
38043
38133
|
if (node !== editor.getBody()) {
|
|
38044
38134
|
const bm = editor.selection.getBookmark();
|
|
@@ -38076,8 +38166,9 @@
|
|
|
38076
38166
|
const selectionSafeCommands = ['toggleview'];
|
|
38077
38167
|
const isSelectionSafeCommand = (command) => contains$2(selectionSafeCommands, command.toLowerCase());
|
|
38078
38168
|
class EditorCommands {
|
|
38169
|
+
editor;
|
|
38170
|
+
commands = { state: {}, exec: {}, value: {} };
|
|
38079
38171
|
constructor(editor) {
|
|
38080
|
-
this.commands = { state: {}, exec: {}, value: {} };
|
|
38081
38172
|
this.editor = editor;
|
|
38082
38173
|
}
|
|
38083
38174
|
/**
|
|
@@ -38094,7 +38185,7 @@
|
|
|
38094
38185
|
execCommand(command, ui = false, value, args) {
|
|
38095
38186
|
const editor = this.editor;
|
|
38096
38187
|
const lowerCaseCommand = command.toLowerCase();
|
|
38097
|
-
const skipFocus = args
|
|
38188
|
+
const skipFocus = args?.skip_focus;
|
|
38098
38189
|
if (editor.removed) {
|
|
38099
38190
|
return false;
|
|
38100
38191
|
}
|
|
@@ -38164,7 +38255,7 @@
|
|
|
38164
38255
|
}
|
|
38165
38256
|
addCommand(command, callback, scope) {
|
|
38166
38257
|
const lowerCaseCommand = command.toLowerCase();
|
|
38167
|
-
this.commands.exec[lowerCaseCommand] = (_command, ui, value, args) => callback.call(scope
|
|
38258
|
+
this.commands.exec[lowerCaseCommand] = (_command, ui, value, args) => callback.call(scope ?? this.editor, ui, value, args);
|
|
38168
38259
|
}
|
|
38169
38260
|
/**
|
|
38170
38261
|
* Returns true/false if the command is supported or not.
|
|
@@ -38183,10 +38274,10 @@
|
|
|
38183
38274
|
}
|
|
38184
38275
|
}
|
|
38185
38276
|
addQueryStateHandler(command, callback, scope) {
|
|
38186
|
-
this.commands.state[command.toLowerCase()] = () => callback.call(scope
|
|
38277
|
+
this.commands.state[command.toLowerCase()] = () => callback.call(scope ?? this.editor);
|
|
38187
38278
|
}
|
|
38188
38279
|
addQueryValueHandler(command, callback, scope) {
|
|
38189
|
-
this.commands.value[command.toLowerCase()] = () => callback.call(scope
|
|
38280
|
+
this.commands.value[command.toLowerCase()] = () => callback.call(scope ?? this.editor);
|
|
38190
38281
|
}
|
|
38191
38282
|
}
|
|
38192
38283
|
|
|
@@ -38217,8 +38308,11 @@
|
|
|
38217
38308
|
static isNative(name) {
|
|
38218
38309
|
return !!nativeEvents[name.toLowerCase()];
|
|
38219
38310
|
}
|
|
38311
|
+
settings;
|
|
38312
|
+
scope;
|
|
38313
|
+
toggleEvent;
|
|
38314
|
+
bindings = {};
|
|
38220
38315
|
constructor(settings) {
|
|
38221
|
-
this.bindings = {};
|
|
38222
38316
|
this.settings = settings || {};
|
|
38223
38317
|
this.scope = this.settings.scope || this;
|
|
38224
38318
|
this.toggleEvent = this.settings.toggleEvent || never;
|
|
@@ -38251,7 +38345,7 @@
|
|
|
38251
38345
|
*/
|
|
38252
38346
|
dispatch(name, args) {
|
|
38253
38347
|
const lcName = name.toLowerCase();
|
|
38254
|
-
const event = normalize$3(lcName, args
|
|
38348
|
+
const event = normalize$3(lcName, args ?? {}, this.scope);
|
|
38255
38349
|
if (this.settings.beforeFire) {
|
|
38256
38350
|
this.settings.beforeFire(event);
|
|
38257
38351
|
}
|
|
@@ -38476,7 +38570,7 @@
|
|
|
38476
38570
|
const self = this;
|
|
38477
38571
|
// Prevent all events except the remove/detach event after the instance has been removed
|
|
38478
38572
|
if (self.removed && name !== 'remove' && name !== 'detach') {
|
|
38479
|
-
return normalize$3(name.toLowerCase(), args
|
|
38573
|
+
return normalize$3(name.toLowerCase(), args ?? {}, self);
|
|
38480
38574
|
}
|
|
38481
38575
|
const dispatcherArgs = getEventDispatcher(self).dispatch(name, args);
|
|
38482
38576
|
// Bubble event up to parents
|
|
@@ -39120,9 +39214,10 @@
|
|
|
39120
39214
|
return shortcut;
|
|
39121
39215
|
};
|
|
39122
39216
|
class Shortcuts {
|
|
39217
|
+
editor;
|
|
39218
|
+
shortcuts = {};
|
|
39219
|
+
pendingPatterns = [];
|
|
39123
39220
|
constructor(editor) {
|
|
39124
|
-
this.shortcuts = {};
|
|
39125
|
-
this.pendingPatterns = [];
|
|
39126
39221
|
this.editor = editor;
|
|
39127
39222
|
const self = this;
|
|
39128
39223
|
editor.on('keyup keypress keydown', (e) => {
|
|
@@ -39484,6 +39579,172 @@
|
|
|
39484
39579
|
* @include ../../../../../tools/docs/tinymce.Editor.js
|
|
39485
39580
|
*/
|
|
39486
39581
|
class Editor {
|
|
39582
|
+
baseUri;
|
|
39583
|
+
/**
|
|
39584
|
+
* Editor instance id, normally the same as the div/textarea that was replaced.
|
|
39585
|
+
*
|
|
39586
|
+
* @property id
|
|
39587
|
+
* @type String
|
|
39588
|
+
*/
|
|
39589
|
+
id;
|
|
39590
|
+
/**
|
|
39591
|
+
* A uuid string to uniquely identify an editor across any page.
|
|
39592
|
+
*
|
|
39593
|
+
* @property editorUid
|
|
39594
|
+
* @type String
|
|
39595
|
+
*/
|
|
39596
|
+
editorUid;
|
|
39597
|
+
/**
|
|
39598
|
+
* Name/Value object containing plugin instances.
|
|
39599
|
+
*
|
|
39600
|
+
* @property plugins
|
|
39601
|
+
* @type Object
|
|
39602
|
+
* @example
|
|
39603
|
+
* // Execute a method inside a plugin directly
|
|
39604
|
+
* tinymce.activeEditor.plugins.someplugin.someMethod();
|
|
39605
|
+
*/
|
|
39606
|
+
plugins = {};
|
|
39607
|
+
/**
|
|
39608
|
+
* URI object to document configured for the TinyMCE instance.
|
|
39609
|
+
*
|
|
39610
|
+
* @property documentBaseURI
|
|
39611
|
+
* @type tinymce.util.URI
|
|
39612
|
+
* @example
|
|
39613
|
+
* // Get relative URL from the location of document_base_url
|
|
39614
|
+
* tinymce.activeEditor.documentBaseURI.toRelative('/somedir/somefile.htm');
|
|
39615
|
+
*
|
|
39616
|
+
* // Get absolute URL from the location of document_base_url
|
|
39617
|
+
* tinymce.activeEditor.documentBaseURI.toAbsolute('somefile.htm');
|
|
39618
|
+
*/
|
|
39619
|
+
documentBaseURI;
|
|
39620
|
+
/**
|
|
39621
|
+
* URI object to current document that holds the TinyMCE editor instance.
|
|
39622
|
+
*
|
|
39623
|
+
* @property baseURI
|
|
39624
|
+
* @type tinymce.util.URI
|
|
39625
|
+
* @example
|
|
39626
|
+
* // Get relative URL from the location of the API
|
|
39627
|
+
* tinymce.activeEditor.baseURI.toRelative('/somedir/somefile.htm');
|
|
39628
|
+
*
|
|
39629
|
+
* // Get absolute URL from the location of the API
|
|
39630
|
+
* tinymce.activeEditor.baseURI.toAbsolute('somefile.htm');
|
|
39631
|
+
*/
|
|
39632
|
+
baseURI;
|
|
39633
|
+
/**
|
|
39634
|
+
* Array with CSS files to load into the iframe.
|
|
39635
|
+
*
|
|
39636
|
+
* @property contentCSS
|
|
39637
|
+
* @type Array
|
|
39638
|
+
*/
|
|
39639
|
+
contentCSS = [];
|
|
39640
|
+
/**
|
|
39641
|
+
* Array of CSS styles to add to head of document when the editor loads.
|
|
39642
|
+
*
|
|
39643
|
+
* @property contentStyles
|
|
39644
|
+
* @type Array
|
|
39645
|
+
*/
|
|
39646
|
+
contentStyles = [];
|
|
39647
|
+
/**
|
|
39648
|
+
* Editor ui components
|
|
39649
|
+
*
|
|
39650
|
+
* @property ui
|
|
39651
|
+
* @type tinymce.editor.ui.Ui
|
|
39652
|
+
*/
|
|
39653
|
+
ui;
|
|
39654
|
+
/**
|
|
39655
|
+
* Editor mode API
|
|
39656
|
+
*
|
|
39657
|
+
* @property mode
|
|
39658
|
+
* @type tinymce.EditorMode
|
|
39659
|
+
*/
|
|
39660
|
+
mode;
|
|
39661
|
+
/**
|
|
39662
|
+
* Editor options API
|
|
39663
|
+
*
|
|
39664
|
+
* @property options
|
|
39665
|
+
* @type tinymce.EditorOptions
|
|
39666
|
+
*/
|
|
39667
|
+
options;
|
|
39668
|
+
/**
|
|
39669
|
+
* Editor upload API
|
|
39670
|
+
*
|
|
39671
|
+
* @property editorUpload
|
|
39672
|
+
* @type tinymce.EditorUpload
|
|
39673
|
+
*/
|
|
39674
|
+
editorUpload;
|
|
39675
|
+
/**
|
|
39676
|
+
* Editor user lookup API
|
|
39677
|
+
*
|
|
39678
|
+
* @property userLookup
|
|
39679
|
+
* @type tinymce.UserLookup
|
|
39680
|
+
*/
|
|
39681
|
+
userLookup;
|
|
39682
|
+
shortcuts;
|
|
39683
|
+
loadedCSS = {};
|
|
39684
|
+
editorCommands;
|
|
39685
|
+
suffix;
|
|
39686
|
+
editorManager;
|
|
39687
|
+
hidden;
|
|
39688
|
+
inline;
|
|
39689
|
+
hasVisual;
|
|
39690
|
+
isNotDirty = false;
|
|
39691
|
+
// Arguments set later, for example by InitContentBody.ts
|
|
39692
|
+
// Note that these may technically be undefined up until PreInit (or similar) has fired,
|
|
39693
|
+
// however the types are aimed at an initialised editor for ease of use.
|
|
39694
|
+
annotator;
|
|
39695
|
+
bodyElement;
|
|
39696
|
+
bookmark; // Note: Intentionally any so as to not expose Optional
|
|
39697
|
+
composing = false;
|
|
39698
|
+
container;
|
|
39699
|
+
contentAreaContainer;
|
|
39700
|
+
contentDocument;
|
|
39701
|
+
contentWindow;
|
|
39702
|
+
delegates;
|
|
39703
|
+
destroyed = false;
|
|
39704
|
+
dom;
|
|
39705
|
+
editorContainer;
|
|
39706
|
+
eventRoot;
|
|
39707
|
+
formatter;
|
|
39708
|
+
formElement;
|
|
39709
|
+
formEventDelegate;
|
|
39710
|
+
hasHiddenInput = false;
|
|
39711
|
+
iframeElement = null;
|
|
39712
|
+
iframeHTML;
|
|
39713
|
+
initialized = false;
|
|
39714
|
+
notificationManager;
|
|
39715
|
+
orgDisplay;
|
|
39716
|
+
orgVisibility;
|
|
39717
|
+
parser;
|
|
39718
|
+
quirks;
|
|
39719
|
+
readonly = false;
|
|
39720
|
+
removed = false;
|
|
39721
|
+
schema;
|
|
39722
|
+
selection;
|
|
39723
|
+
serializer;
|
|
39724
|
+
startContent = '';
|
|
39725
|
+
targetElm;
|
|
39726
|
+
theme;
|
|
39727
|
+
model;
|
|
39728
|
+
undoManager;
|
|
39729
|
+
windowManager;
|
|
39730
|
+
licenseKeyManager;
|
|
39731
|
+
_beforeUnload;
|
|
39732
|
+
_eventDispatcher;
|
|
39733
|
+
_nodeChangeDispatcher;
|
|
39734
|
+
_pendingNativeEvents = [];
|
|
39735
|
+
_selectionOverrides;
|
|
39736
|
+
_skinLoaded = false;
|
|
39737
|
+
_editableRoot = true;
|
|
39738
|
+
// EditorObservable patches
|
|
39739
|
+
bindPendingEventDelegates;
|
|
39740
|
+
toggleNativeEvent;
|
|
39741
|
+
unbindAllNativeEvents;
|
|
39742
|
+
fire;
|
|
39743
|
+
dispatch;
|
|
39744
|
+
on;
|
|
39745
|
+
off;
|
|
39746
|
+
once;
|
|
39747
|
+
hasEventListeners;
|
|
39487
39748
|
/**
|
|
39488
39749
|
* Constructs a editor instance by id.
|
|
39489
39750
|
*
|
|
@@ -39494,43 +39755,6 @@
|
|
|
39494
39755
|
* @param {tinymce.EditorManager} editorManager EditorManager instance.
|
|
39495
39756
|
*/
|
|
39496
39757
|
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
39758
|
this.editorManager = editorManager;
|
|
39535
39759
|
// Patch in the EditorObservable functions
|
|
39536
39760
|
extend(this, EditorObservable);
|
|
@@ -40113,9 +40337,8 @@
|
|
|
40113
40337
|
* @return {Element} The root element of the editable area.
|
|
40114
40338
|
*/
|
|
40115
40339
|
getBody() {
|
|
40116
|
-
var _a, _b;
|
|
40117
40340
|
const doc = this.getDoc();
|
|
40118
|
-
return
|
|
40341
|
+
return this.bodyElement ?? doc?.body ?? null;
|
|
40119
40342
|
}
|
|
40120
40343
|
/**
|
|
40121
40344
|
* URL converter function this gets executed each time a user adds an img, a or
|
|
@@ -40306,14 +40529,14 @@
|
|
|
40306
40529
|
* @property minorVersion
|
|
40307
40530
|
* @type String
|
|
40308
40531
|
*/
|
|
40309
|
-
minorVersion: '
|
|
40532
|
+
minorVersion: '2.0',
|
|
40310
40533
|
/**
|
|
40311
40534
|
* Release date of TinyMCE build.
|
|
40312
40535
|
*
|
|
40313
40536
|
* @property releaseDate
|
|
40314
40537
|
* @type String
|
|
40315
40538
|
*/
|
|
40316
|
-
releaseDate: '
|
|
40539
|
+
releaseDate: '2025-10-23',
|
|
40317
40540
|
/**
|
|
40318
40541
|
* Collection of language pack data.
|
|
40319
40542
|
*
|
|
@@ -40723,9 +40946,8 @@
|
|
|
40723
40946
|
* @return {Boolean} true/false if the command was executed or not.
|
|
40724
40947
|
*/
|
|
40725
40948
|
execCommand(cmd, ui, value) {
|
|
40726
|
-
var _a;
|
|
40727
40949
|
const self = this;
|
|
40728
|
-
const editorId = isObject(value) ?
|
|
40950
|
+
const editorId = isObject(value) ? value.id ?? value.index : value;
|
|
40729
40951
|
// Manager commands
|
|
40730
40952
|
switch (cmd) {
|
|
40731
40953
|
case 'mceAddEditor': {
|
|
@@ -41131,7 +41353,7 @@
|
|
|
41131
41353
|
localStorage.setItem(test, test);
|
|
41132
41354
|
localStorage.removeItem(test);
|
|
41133
41355
|
}
|
|
41134
|
-
catch
|
|
41356
|
+
catch {
|
|
41135
41357
|
localStorage = create();
|
|
41136
41358
|
}
|
|
41137
41359
|
var LocalStorage = localStorage;
|
|
@@ -41228,7 +41450,7 @@
|
|
|
41228
41450
|
try {
|
|
41229
41451
|
module.exports = tinymce;
|
|
41230
41452
|
}
|
|
41231
|
-
catch
|
|
41453
|
+
catch {
|
|
41232
41454
|
// It will thrown an error when running this module
|
|
41233
41455
|
// within webpack where the module.exports object is sealed
|
|
41234
41456
|
}
|