tinymce-rails 8.9.3 → 8.10.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 +110 -68
- data/lib/tinymce/rails/version.rb +2 -2
- data/vendor/assets/javascripts/tinymce/icons/default/icons.js +1 -1
- data/vendor/assets/javascripts/tinymce/models/dom/model.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/advlist/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 +2 -1
- data/vendor/assets/javascripts/tinymce/tinymce.js +3 -3
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4a61952e308104873ef07b099e38b1695ee58eef14f81cf862ad3afeadd07d80
|
|
4
|
+
data.tar.gz: 368d783df479b393e05443329c53a047cd565f23f5e137a3b812192f2ab18fdb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 63d959b67aff1a65e5279f146e65c331b0221746acad246fd2a186aad2985455137c17e7a487d332c314c1b41aab14aab167bf5650eecbe706b1dd36e4f0d8a2
|
|
7
|
+
data.tar.gz: a4691ff86f4ba66f24cbf4cb7371a77c435ce51e38f92be0285e6691d7303b44af9f7a6d6c9e555edf04c2bb1b4de42f656ce94bfb5595f9945b9d2f26d2e618
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* TinyMCE version 8.
|
|
2
|
+
* TinyMCE version 8.10.0 (2026-10-14)
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
(function () {
|
|
@@ -1155,6 +1155,35 @@
|
|
|
1155
1155
|
return isNaN(num) ? Optional.none() : Optional.some(num);
|
|
1156
1156
|
};
|
|
1157
1157
|
|
|
1158
|
+
// Run a function fn after rate ms. If another invocation occurs
|
|
1159
|
+
// during the time it is waiting, update the arguments f will run
|
|
1160
|
+
// with (but keep the current schedule)
|
|
1161
|
+
const adaptable = (fn, rate) => {
|
|
1162
|
+
let timer = null;
|
|
1163
|
+
let args = null;
|
|
1164
|
+
const cancel = () => {
|
|
1165
|
+
if (!isNull(timer)) {
|
|
1166
|
+
clearTimeout(timer);
|
|
1167
|
+
timer = null;
|
|
1168
|
+
args = null;
|
|
1169
|
+
}
|
|
1170
|
+
};
|
|
1171
|
+
const throttle = (...newArgs) => {
|
|
1172
|
+
args = newArgs;
|
|
1173
|
+
if (isNull(timer)) {
|
|
1174
|
+
timer = setTimeout(() => {
|
|
1175
|
+
const tempArgs = args;
|
|
1176
|
+
timer = null;
|
|
1177
|
+
args = null;
|
|
1178
|
+
fn.apply(null, tempArgs);
|
|
1179
|
+
}, rate);
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
return {
|
|
1183
|
+
cancel,
|
|
1184
|
+
throttle
|
|
1185
|
+
};
|
|
1186
|
+
};
|
|
1158
1187
|
// Run a function fn after rate ms. If another invocation occurs
|
|
1159
1188
|
// during the time it is waiting, ignore it completely.
|
|
1160
1189
|
const first$1 = (fn, rate) => {
|
|
@@ -3374,47 +3403,6 @@
|
|
|
3374
3403
|
}
|
|
3375
3404
|
}
|
|
3376
3405
|
|
|
3377
|
-
const whiteSpaceRegExp = /^[ \t\r\n]*$/;
|
|
3378
|
-
const isWhitespaceText = (text) => whiteSpaceRegExp.test(text);
|
|
3379
|
-
const isZwsp$1 = (text) => {
|
|
3380
|
-
for (const c of text) {
|
|
3381
|
-
if (!isZwsp$2(c)) {
|
|
3382
|
-
return false;
|
|
3383
|
-
}
|
|
3384
|
-
}
|
|
3385
|
-
return true;
|
|
3386
|
-
};
|
|
3387
|
-
// Don't compare other unicode spaces here, as we're only concerned about whitespace the browser would collapse
|
|
3388
|
-
const isCollapsibleWhitespace$1 = (c) => ' \f\t\v'.indexOf(c) !== -1;
|
|
3389
|
-
const isNewLineChar = (c) => c === '\n' || c === '\r';
|
|
3390
|
-
const isNewline = (text, idx) => (idx < text.length && idx >= 0) ? isNewLineChar(text[idx]) : false;
|
|
3391
|
-
// Converts duplicate whitespace to alternating space/nbsps and tabs to spaces
|
|
3392
|
-
const normalize$4 = (text, tabSpaces = 4, isStartOfContent = true, isEndOfContent = true) => {
|
|
3393
|
-
// Replace tabs with a variable amount of spaces
|
|
3394
|
-
// Note: We don't use an actual tab character here, as it only works when in a "whitespace: pre" element,
|
|
3395
|
-
// which will cause other issues, such as trying to type the content will also be treated as being in a pre.
|
|
3396
|
-
const tabSpace = repeat(' ', tabSpaces);
|
|
3397
|
-
const normalizedText = text.replace(/\t/g, tabSpace);
|
|
3398
|
-
const result = foldl(normalizedText, (acc, c) => {
|
|
3399
|
-
// Are we dealing with a char other than some collapsible whitespace or nbsp? if so then just use it as is
|
|
3400
|
-
if (isCollapsibleWhitespace$1(c) || c === nbsp) {
|
|
3401
|
-
// If the previous char is a space, we are at the start or end, or if the next char is a new line char, then we need
|
|
3402
|
-
// to convert the space to a nbsp
|
|
3403
|
-
if (acc.pcIsSpace || (acc.str === '' && isStartOfContent) || (acc.str.length === normalizedText.length - 1 && isEndOfContent) || isNewline(normalizedText, acc.str.length + 1)) {
|
|
3404
|
-
return { pcIsSpace: false, str: acc.str + nbsp };
|
|
3405
|
-
}
|
|
3406
|
-
else {
|
|
3407
|
-
return { pcIsSpace: true, str: acc.str + ' ' };
|
|
3408
|
-
}
|
|
3409
|
-
}
|
|
3410
|
-
else {
|
|
3411
|
-
// Treat newlines as being a space, since we'll need to convert any leading spaces to nsbps
|
|
3412
|
-
return { pcIsSpace: isNewLineChar(c), str: acc.str + c };
|
|
3413
|
-
}
|
|
3414
|
-
}, { pcIsSpace: false, str: '' });
|
|
3415
|
-
return result.str;
|
|
3416
|
-
};
|
|
3417
|
-
|
|
3418
3406
|
const isNodeType = (type) => {
|
|
3419
3407
|
return (node) => {
|
|
3420
3408
|
return !!node && node.nodeType === type;
|
|
@@ -3502,6 +3490,47 @@
|
|
|
3502
3490
|
const ucVideoNodeName = 'uc-video';
|
|
3503
3491
|
const isUcVideo = matchNodeName$1(ucVideoNodeName);
|
|
3504
3492
|
|
|
3493
|
+
const whiteSpaceRegExp = /^[ \t\r\n]*$/;
|
|
3494
|
+
const isWhitespaceText = (text) => whiteSpaceRegExp.test(text);
|
|
3495
|
+
const isZwsp$1 = (text) => {
|
|
3496
|
+
for (const c of text) {
|
|
3497
|
+
if (!isZwsp$2(c)) {
|
|
3498
|
+
return false;
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3501
|
+
return true;
|
|
3502
|
+
};
|
|
3503
|
+
// Don't compare other unicode spaces here, as we're only concerned about whitespace the browser would collapse
|
|
3504
|
+
const isCollapsibleWhitespace$1 = (c) => ' \f\t\v'.indexOf(c) !== -1;
|
|
3505
|
+
const isNewLineChar = (c) => c === '\n' || c === '\r';
|
|
3506
|
+
const isNewline = (text, idx) => (idx < text.length && idx >= 0) ? isNewLineChar(text[idx]) : false;
|
|
3507
|
+
// Converts duplicate whitespace to alternating space/nbsps and tabs to spaces
|
|
3508
|
+
const normalize$4 = (text, tabSpaces = 4, isStartOfContent = true, isEndOfContent = true) => {
|
|
3509
|
+
// Replace tabs with a variable amount of spaces
|
|
3510
|
+
// Note: We don't use an actual tab character here, as it only works when in a "whitespace: pre" element,
|
|
3511
|
+
// which will cause other issues, such as trying to type the content will also be treated as being in a pre.
|
|
3512
|
+
const tabSpace = repeat(' ', tabSpaces);
|
|
3513
|
+
const normalizedText = text.replace(/\t/g, tabSpace);
|
|
3514
|
+
const result = foldl(normalizedText, (acc, c) => {
|
|
3515
|
+
// Are we dealing with a char other than some collapsible whitespace or nbsp? if so then just use it as is
|
|
3516
|
+
if (isCollapsibleWhitespace$1(c) || c === nbsp) {
|
|
3517
|
+
// If the previous char is a space, we are at the start or end, or if the next char is a new line char, then we need
|
|
3518
|
+
// to convert the space to a nbsp
|
|
3519
|
+
if (acc.pcIsSpace || (acc.str === '' && isStartOfContent) || (acc.str.length === normalizedText.length - 1 && isEndOfContent) || isNewline(normalizedText, acc.str.length + 1)) {
|
|
3520
|
+
return { pcIsSpace: false, str: acc.str + nbsp };
|
|
3521
|
+
}
|
|
3522
|
+
else {
|
|
3523
|
+
return { pcIsSpace: true, str: acc.str + ' ' };
|
|
3524
|
+
}
|
|
3525
|
+
}
|
|
3526
|
+
else {
|
|
3527
|
+
// Treat newlines as being a space, since we'll need to convert any leading spaces to nsbps
|
|
3528
|
+
return { pcIsSpace: isNewLineChar(c), str: acc.str + c };
|
|
3529
|
+
}
|
|
3530
|
+
}, { pcIsSpace: false, str: '' });
|
|
3531
|
+
return result.str;
|
|
3532
|
+
};
|
|
3533
|
+
|
|
3505
3534
|
const defaultOptionValues = {
|
|
3506
3535
|
skipBogus: true,
|
|
3507
3536
|
includeZwsp: false,
|
|
@@ -13765,6 +13794,12 @@
|
|
|
13765
13794
|
editor.nodeChanged();
|
|
13766
13795
|
};
|
|
13767
13796
|
const showResizeRect = (targetElm) => {
|
|
13797
|
+
// The throttled call can fire after setContent has replaced the target, leaving
|
|
13798
|
+
// handles bound to the zero-sized geometry of a detached element
|
|
13799
|
+
if (!targetElm.isConnected) {
|
|
13800
|
+
hideResizeRect();
|
|
13801
|
+
return;
|
|
13802
|
+
}
|
|
13768
13803
|
unbindResizeHandleEvents();
|
|
13769
13804
|
// Get position and size of target
|
|
13770
13805
|
const position = dom.getPos(targetElm, rootElement);
|
|
@@ -13863,7 +13898,9 @@
|
|
|
13863
13898
|
hideResizeRect(false);
|
|
13864
13899
|
}
|
|
13865
13900
|
};
|
|
13866
|
-
|
|
13901
|
+
// Adaptable so a burst of update requests shows the rect for the most recently
|
|
13902
|
+
// requested element rather than the first, which may since have been detached
|
|
13903
|
+
const throttledShowResizeRect = adaptable(showResizeRect, 0);
|
|
13867
13904
|
const hideResizeRect = (removeSelected = true) => {
|
|
13868
13905
|
throttledShowResizeRect.cancel();
|
|
13869
13906
|
unbindResizeHandleEvents();
|
|
@@ -16935,14 +16972,18 @@
|
|
|
16935
16972
|
selection.setRng(rng);
|
|
16936
16973
|
}
|
|
16937
16974
|
};
|
|
16975
|
+
const isAdjacent = (node, sibling) => node.nextSibling === sibling || node.previousSibling === sibling;
|
|
16976
|
+
const isCaretContainerNodeAdjacentToSelection = (node, startContainer, endContainer) => node === startContainer || node === endContainer || isAdjacent(node, startContainer) || isAdjacent(node, endContainer);
|
|
16938
16977
|
// Removes the caret container for the specified node or all on the current document
|
|
16939
16978
|
const removeCaretContainer = (editor, node, moveCaret) => {
|
|
16940
16979
|
const dom = editor.dom, selection = editor.selection;
|
|
16941
16980
|
if (!node) {
|
|
16942
16981
|
node = getParentCaretContainer(editor.getBody(), selection.getStart());
|
|
16943
16982
|
if (!node) {
|
|
16983
|
+
const startContainer = editor.selection.getRng().startContainer;
|
|
16984
|
+
const endContainer = editor.selection.getRng().endContainer;
|
|
16944
16985
|
while ((node = dom.get(CARET_ID))) {
|
|
16945
|
-
removeCaretContainerNode(editor, node,
|
|
16986
|
+
removeCaretContainerNode(editor, node, isCaretContainerNodeAdjacentToSelection(node, startContainer, endContainer));
|
|
16946
16987
|
}
|
|
16947
16988
|
}
|
|
16948
16989
|
}
|
|
@@ -17145,9 +17186,9 @@
|
|
|
17145
17186
|
}
|
|
17146
17187
|
}
|
|
17147
17188
|
};
|
|
17148
|
-
const disableCaretContainer = (editor, keyCode
|
|
17189
|
+
const disableCaretContainer = (editor, keyCode) => {
|
|
17149
17190
|
const selection = editor.selection, body = editor.getBody();
|
|
17150
|
-
removeCaretContainer(editor, null,
|
|
17191
|
+
removeCaretContainer(editor, null, false);
|
|
17151
17192
|
// Remove caret container if it's empty
|
|
17152
17193
|
if ((keyCode === 8 || keyCode === 46) && selection.isCollapsed() && selection.getStart().innerHTML === ZWSP) {
|
|
17153
17194
|
removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()), true);
|
|
@@ -17157,10 +17198,9 @@
|
|
|
17157
17198
|
removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()), true);
|
|
17158
17199
|
}
|
|
17159
17200
|
};
|
|
17160
|
-
const endsWithNbsp = (element) => isText$b(element) && endsWith(element.data, nbsp);
|
|
17161
17201
|
const setup$B = (editor) => {
|
|
17162
17202
|
editor.on('mouseup keydown', (e) => {
|
|
17163
|
-
disableCaretContainer(editor, e.keyCode
|
|
17203
|
+
disableCaretContainer(editor, e.keyCode);
|
|
17164
17204
|
});
|
|
17165
17205
|
};
|
|
17166
17206
|
const createCaretFormat = (formatNodes) => {
|
|
@@ -28952,6 +28992,16 @@
|
|
|
28952
28992
|
}
|
|
28953
28993
|
};
|
|
28954
28994
|
|
|
28995
|
+
const clearShadowingItemStyles = (editor) => {
|
|
28996
|
+
each$e(getSelectedListItems(editor), (item) => {
|
|
28997
|
+
const styleType = editor.dom.getStyle(item, 'list-style-type');
|
|
28998
|
+
// Keep none intact as TinyMCE uses it for nested lists
|
|
28999
|
+
if (isNonNullable(styleType) && styleType !== 'none') {
|
|
29000
|
+
editor.dom.setStyle(item, 'list-style-type', '');
|
|
29001
|
+
}
|
|
29002
|
+
});
|
|
29003
|
+
};
|
|
29004
|
+
|
|
28955
29005
|
const updateListStyle = (dom, el, detail) => {
|
|
28956
29006
|
const type = detail['list-style-type'] ? detail['list-style-type'] : null;
|
|
28957
29007
|
dom.setStyle(el, 'list-style-type', type);
|
|
@@ -29286,6 +29336,7 @@
|
|
|
29286
29336
|
else {
|
|
29287
29337
|
toggleSingleList(editor, parentList, listName, detail);
|
|
29288
29338
|
}
|
|
29339
|
+
clearShadowingItemStyles(editor);
|
|
29289
29340
|
};
|
|
29290
29341
|
|
|
29291
29342
|
const findNextCaretContainer = (editor, rng, isForward, root) => {
|
|
@@ -37597,16 +37648,6 @@
|
|
|
37597
37648
|
}
|
|
37598
37649
|
}, true);
|
|
37599
37650
|
};
|
|
37600
|
-
/**
|
|
37601
|
-
* Forces Gecko to render a broken image icon if it fails to load an image.
|
|
37602
|
-
*/
|
|
37603
|
-
const showBrokenImageIcon = () => {
|
|
37604
|
-
editor.contentStyles.push('img:-moz-broken {' +
|
|
37605
|
-
'-moz-force-broken-image-icon:1;' +
|
|
37606
|
-
'min-width:24px;' +
|
|
37607
|
-
'min-height:24px' +
|
|
37608
|
-
'}');
|
|
37609
|
-
};
|
|
37610
37651
|
/**
|
|
37611
37652
|
* iOS has a bug where it's impossible to type if the document has a touchstart event
|
|
37612
37653
|
* bound and the user touches the document while having the on screen keyboard visible.
|
|
@@ -37783,8 +37824,8 @@
|
|
|
37783
37824
|
const clickAfterEl = (clientX, clientY, el) => get$c(getClientRects([el.dom]), 0).exists((rect) => clientX >= rect.right && clientY >= rect.top && clientY <= rect.bottom);
|
|
37784
37825
|
const selectPos = (editor, e, pos) => {
|
|
37785
37826
|
e.preventDefault();
|
|
37786
|
-
editor.focus();
|
|
37787
37827
|
editor.selection.setRng(pos.toRange());
|
|
37828
|
+
editor.focus();
|
|
37788
37829
|
};
|
|
37789
37830
|
/**
|
|
37790
37831
|
* In Chrome in a `LI` that contains a block element and where the first child is an inline element
|
|
@@ -37792,7 +37833,7 @@
|
|
|
37792
37833
|
* issue: https://issues.chromium.org/issues/40767343
|
|
37793
37834
|
**/
|
|
37794
37835
|
const fixInLISelection = () => {
|
|
37795
|
-
editor.on('
|
|
37836
|
+
editor.on('click', (e) => {
|
|
37796
37837
|
const target = SugarElement.fromDom(e.target);
|
|
37797
37838
|
if (isListItem$2(target)) {
|
|
37798
37839
|
firstBlockChildOrNewLine(target).fold(() => {
|
|
@@ -37836,7 +37877,6 @@
|
|
|
37836
37877
|
if (isGecko) {
|
|
37837
37878
|
focusBody();
|
|
37838
37879
|
setGeckoEditingOptions();
|
|
37839
|
-
showBrokenImageIcon();
|
|
37840
37880
|
blockCmdArrowNavigation();
|
|
37841
37881
|
}
|
|
37842
37882
|
};
|
|
@@ -37880,7 +37920,6 @@
|
|
|
37880
37920
|
removeStylesWhenDeletingAcrossBlockElements();
|
|
37881
37921
|
setGeckoEditingOptions();
|
|
37882
37922
|
addBrAfterLastLinks();
|
|
37883
|
-
showBrokenImageIcon();
|
|
37884
37923
|
blockCmdArrowNavigation();
|
|
37885
37924
|
disableBackspaceIntoATable();
|
|
37886
37925
|
}
|
|
@@ -38399,7 +38438,7 @@
|
|
|
38399
38438
|
id: id + '_ifr',
|
|
38400
38439
|
frameBorder: '0',
|
|
38401
38440
|
allowTransparency: 'true',
|
|
38402
|
-
|
|
38441
|
+
title
|
|
38403
38442
|
});
|
|
38404
38443
|
add$2(iframe, 'tox-edit-area__iframe');
|
|
38405
38444
|
return iframe;
|
|
@@ -38415,12 +38454,15 @@
|
|
|
38415
38454
|
const bodyId = getBodyId(editor);
|
|
38416
38455
|
const bodyClass = getBodyClass(editor);
|
|
38417
38456
|
const translatedAriaText = editor.translate(getIframeAriaText(editor));
|
|
38418
|
-
|
|
38457
|
+
// TINYMCE-13100: VoiceOver does not read the iframe title, so the body is labelled
|
|
38458
|
+
// for it. VoiceOver only runs on macOS, and elsewhere the title is announced.
|
|
38459
|
+
// The role goes with it, since aria-label on a generic role is a violation.
|
|
38460
|
+
const iframeBodyAriaAttrs = Env.os.isMacOS() || Env.os.isiOS() ? `role="textbox" aria-multiline="true" aria-label="${translatedAriaText}"` : '';
|
|
38419
38461
|
if (getContentSecurityPolicy(editor)) {
|
|
38420
38462
|
iframeHTML += '<meta http-equiv="Content-Security-Policy" content="' + getContentSecurityPolicy(editor) + '" />';
|
|
38421
38463
|
}
|
|
38422
38464
|
iframeHTML += '</head>' +
|
|
38423
|
-
`<body id="${bodyId}" class="mce-content-body ${bodyClass}" data-id="${editor.id}" ${
|
|
38465
|
+
`<body id="${bodyId}" class="mce-content-body ${bodyClass}" data-id="${editor.id}" ${iframeBodyAriaAttrs}>` +
|
|
38424
38466
|
'<br>' +
|
|
38425
38467
|
'</body></html>';
|
|
38426
38468
|
return iframeHTML;
|
|
@@ -39725,7 +39767,7 @@
|
|
|
39725
39767
|
return false;
|
|
39726
39768
|
}
|
|
39727
39769
|
if (lowerCaseCommand !== 'mcefocus') {
|
|
39728
|
-
if (!/^(mceAddUndoLevel|mceEndUndoLevel)$/i.test(lowerCaseCommand) && !skipFocus) {
|
|
39770
|
+
if (!/^(mceAddUndoLevel|mceEndUndoLevel|toggleview)$/i.test(lowerCaseCommand) && !skipFocus) {
|
|
39729
39771
|
editor.focus();
|
|
39730
39772
|
}
|
|
39731
39773
|
else {
|
|
@@ -42102,14 +42144,14 @@
|
|
|
42102
42144
|
* @property minorVersion
|
|
42103
42145
|
* @type String
|
|
42104
42146
|
*/
|
|
42105
|
-
minorVersion: '
|
|
42147
|
+
minorVersion: '10.0',
|
|
42106
42148
|
/**
|
|
42107
42149
|
* Release date of TinyMCE build.
|
|
42108
42150
|
*
|
|
42109
42151
|
* @property releaseDate
|
|
42110
42152
|
* @type String
|
|
42111
42153
|
*/
|
|
42112
|
-
releaseDate: '2026-10-
|
|
42154
|
+
releaseDate: '2026-10-14',
|
|
42113
42155
|
/**
|
|
42114
42156
|
* Collection of language pack data.
|
|
42115
42157
|
*
|