@sapui5/sap.ui.richtexteditor 1.139.0 → 1.141.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.
- package/package.json +1 -1
- package/src/sap/ui/richtexteditor/.library +1 -1
- package/src/sap/ui/richtexteditor/RTESplitButton.js +1 -1
- package/src/sap/ui/richtexteditor/RichTextEditor.js +49 -5
- package/src/sap/ui/richtexteditor/RichTextEditorFontFamily.js +78 -0
- package/src/sap/ui/richtexteditor/ToolbarWrapper.js +123 -60
- package/src/sap/ui/richtexteditor/js/styles/RichTextEditor.css +0 -3
- package/src/sap/ui/richtexteditor/library.js +56 -38
- package/src/sap/ui/richtexteditor/messagebundle.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_ar.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_bg.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_ca.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_cnr.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_cs.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_cy.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_da.properties +4 -1
- package/src/sap/ui/richtexteditor/messagebundle_de.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_el.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_en.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_en_GB.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_en_US_saprigi.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_es.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_es_MX.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_et.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_fi.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_fr.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_fr_CA.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_hi.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_hr.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_hu.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_id.properties +4 -1
- package/src/sap/ui/richtexteditor/messagebundle_it.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_iw.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_ja.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_kk.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_ko.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_lt.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_lv.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_mk.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_ms.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_nl.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_no.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_pl.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_pt.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_pt_PT.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_ro.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_ru.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_sh.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_sk.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_sl.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_sr.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_sv.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_th.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_tr.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_uk.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_vi.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_zh_CN.properties +3 -0
- package/src/sap/ui/richtexteditor/messagebundle_zh_TW.properties +3 -0
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<vendor>SAP SE</vendor>
|
|
6
6
|
<copyright>SAPUI5
|
|
7
7
|
* (c) Copyright 2025 SAP SE. All rights reserved.</copyright>
|
|
8
|
-
<version>1.
|
|
8
|
+
<version>1.141.0</version>
|
|
9
9
|
|
|
10
10
|
<documentation>A rich text editor (RTE) control. Requires installation of an additional rich text editor library.</documentation>
|
|
11
11
|
|
|
@@ -372,11 +372,18 @@ sap.ui.define([
|
|
|
372
372
|
/**
|
|
373
373
|
* Custom buttons are meant to extend the <code>RichTextEditor</code>'s custom toolbar.
|
|
374
374
|
* Though type is set to sap.ui.Control, only sap.m.Button is allowed.
|
|
375
|
-
* <b>Note:</b> customButtons are available only when the customToolbar is enabled and all the requirements are fulfilled.
|
|
375
|
+
* <b>Note:</b> customButtons are available only when the <code>customToolbar</code> is enabled and all the requirements are fulfilled.
|
|
376
376
|
*
|
|
377
377
|
* @since 1.48
|
|
378
378
|
*/
|
|
379
|
-
customButtons: {type: "sap.ui.core.Control", multiple: true, singularName: "customButton", defaultValue: null}
|
|
379
|
+
customButtons: {type: "sap.ui.core.Control", multiple: true, singularName: "customButton", defaultValue: null},
|
|
380
|
+
/**
|
|
381
|
+
* Custom font families that can be used in the <code>RichTextEditor</code>.
|
|
382
|
+
* <b>Note:</b> Custom fonts are available only when the <code>customToolbar</code> is enabled.
|
|
383
|
+
*
|
|
384
|
+
* @since 1.141
|
|
385
|
+
*/
|
|
386
|
+
customFonts: {type: "sap.ui.richtexteditor.RichTextEditorFontFamily", multiple: true, singularName: "customFont", defaultValue: null}
|
|
380
387
|
},
|
|
381
388
|
associations: {
|
|
382
389
|
/**
|
|
@@ -412,6 +419,9 @@ sap.ui.define([
|
|
|
412
419
|
*/
|
|
413
420
|
RichTextEditor.EDITORTYPE_TINYMCE5 = library.EditorType.TinyMCE5;
|
|
414
421
|
|
|
422
|
+
/**
|
|
423
|
+
* @deprecated As of version 1.141.0
|
|
424
|
+
*/
|
|
415
425
|
RichTextEditor.EDITORTYPE_TINYMCE6 = library.EditorType.TinyMCE6;
|
|
416
426
|
|
|
417
427
|
RichTextEditor.EDITORTYPE_TINYMCE7 = library.EditorType.TinyMCE7;
|
|
@@ -448,6 +458,9 @@ sap.ui.define([
|
|
|
448
458
|
"powerpaste"
|
|
449
459
|
];
|
|
450
460
|
|
|
461
|
+
/**
|
|
462
|
+
* @deprecated As of version 1.141.0
|
|
463
|
+
*/
|
|
451
464
|
RichTextEditor.DEFAULT_PLUGINS_TINYMCE6 = [
|
|
452
465
|
"emoticons",
|
|
453
466
|
"directionality",
|
|
@@ -1305,11 +1318,14 @@ sap.ui.define([
|
|
|
1305
1318
|
* @deprecated As of version 1.120
|
|
1306
1319
|
*/
|
|
1307
1320
|
if (oEditorMapping[sEditorType] === "TinyMCE5") {
|
|
1308
|
-
Log.error("TinyMCE version 5 is used as editor type. TinyMCE 5 is deprecated and will be removed from the code entirely
|
|
1321
|
+
Log.error("TinyMCE version 5 is used as editor type. TinyMCE 5 is deprecated and will be removed from the code entirely at the beginning of 2026. The latest version will be automatically loaded instead.");
|
|
1309
1322
|
}
|
|
1310
1323
|
|
|
1324
|
+
/**
|
|
1325
|
+
* @deprecated As of version 1.141.0
|
|
1326
|
+
*/
|
|
1311
1327
|
if (oEditorMapping[sEditorType] === "TinyMCE6") {
|
|
1312
|
-
Log.
|
|
1328
|
+
Log.error("TinyMCE version 6 is used as editor type. TinyMCE 6 is deprecated as of version 1.141.0 and will be removed from the code entirely in near future.");
|
|
1313
1329
|
}
|
|
1314
1330
|
|
|
1315
1331
|
this.initTinyMCE();
|
|
@@ -1932,7 +1948,6 @@ sap.ui.define([
|
|
|
1932
1948
|
toolbar_items_size: 'small',
|
|
1933
1949
|
toolbar: aButtonRows,
|
|
1934
1950
|
toolbar_mode: "sliding",
|
|
1935
|
-
content_css: [sap.ui.require.toUrl("sap/ui/richtexteditor/js/styles/RichTextEditor.css")],
|
|
1936
1951
|
statusbar: false, // disables display of the status bar at the bottom of the editor
|
|
1937
1952
|
image_advtab: true, // Adds an "Advanced" tab to the image dialog allowing you to add custom styles, spacing and borders to images
|
|
1938
1953
|
readonly: !this.getEditable(),
|
|
@@ -1943,6 +1958,7 @@ sap.ui.define([
|
|
|
1943
1958
|
sandbox_iframes: true, // default for v.7, remove after upgrade
|
|
1944
1959
|
init_instance_callback: function(oEditor) {
|
|
1945
1960
|
this._oEditor = oEditor;
|
|
1961
|
+
this._insertCustomFonts();
|
|
1946
1962
|
fnOnInit();
|
|
1947
1963
|
}.bind(this)
|
|
1948
1964
|
};
|
|
@@ -1961,6 +1977,34 @@ sap.ui.define([
|
|
|
1961
1977
|
return oConfig;
|
|
1962
1978
|
};
|
|
1963
1979
|
|
|
1980
|
+
RichTextEditor.prototype._insertCustomFonts = function() {
|
|
1981
|
+
const doc = this._oEditor?.getDoc();
|
|
1982
|
+
|
|
1983
|
+
if (!doc) {
|
|
1984
|
+
return;
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1987
|
+
const head = doc.getElementsByTagName("head")[0];
|
|
1988
|
+
const style = doc.getElementById("custom-fonts") || doc.createElement("style");
|
|
1989
|
+
style?.setAttribute("id", "custom-fonts");
|
|
1990
|
+
|
|
1991
|
+
const fontImports = this.getCustomFonts().map((oFont) => {
|
|
1992
|
+
return `@import url('${oFont.getUrl()}');`;
|
|
1993
|
+
}).join("\n");
|
|
1994
|
+
|
|
1995
|
+
const currentFonts = style?.textContent || "";
|
|
1996
|
+
|
|
1997
|
+
if (currentFonts === fontImports) {
|
|
1998
|
+
return;
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
style.textContent = fontImports;
|
|
2002
|
+
|
|
2003
|
+
if (head && style) {
|
|
2004
|
+
head.appendChild(style);
|
|
2005
|
+
}
|
|
2006
|
+
};
|
|
2007
|
+
|
|
1964
2008
|
|
|
1965
2009
|
/**
|
|
1966
2010
|
* Map languages that are incorrectly assigned or fallback if languages do not work
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* SAPUI5
|
|
3
|
+
* (c) Copyright 2025 SAP SE. All rights reserved.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Provides control sap.ui.richtexteditor.RichTextEditorFontFamily.
|
|
7
|
+
sap.ui.define([
|
|
8
|
+
"sap/ui/core/Element",
|
|
9
|
+
"sap/base/Log",
|
|
10
|
+
"./library"
|
|
11
|
+
], function(Element, Log, library) {
|
|
12
|
+
"use strict";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Constructor for a new <code>RichTextEditorFontFamily</code>.
|
|
16
|
+
*
|
|
17
|
+
* @param {string} [sId] id for the new control, generated automatically if no id is given
|
|
18
|
+
* @param {object} [mSettings] initial settings for the new control
|
|
19
|
+
*
|
|
20
|
+
* @class
|
|
21
|
+
* Represents a font family option for <code>RichTextEditor</code>.
|
|
22
|
+
* @extends sap.ui.core.Element
|
|
23
|
+
*
|
|
24
|
+
* @author SAP SE
|
|
25
|
+
* @version 1.141.0
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
* @alias sap.ui.richtexteditor.RichTextEditorFontFamily
|
|
29
|
+
*/
|
|
30
|
+
var RichTextEditorFontFamily = Element.extend("sap.ui.richtexteditor.RichTextEditorFontFamily", /** @lends sap.ui.richtexteditor.RichTextEditorFontFamily.prototype */ {
|
|
31
|
+
metadata : {
|
|
32
|
+
library : "sap.ui.richtexteditor",
|
|
33
|
+
properties : {
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Used to identify the font in the editor.
|
|
37
|
+
* Names should be unique and descriptive.
|
|
38
|
+
*/
|
|
39
|
+
name : {type : "string", group : "Misc", defaultValue : null},
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The text displayed in the font family dropdown.
|
|
43
|
+
*/
|
|
44
|
+
text : {type : "string", group : "Misc", defaultValue : null},
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The value of the font family.
|
|
48
|
+
* CSS font-family value that will be applied to the text.
|
|
49
|
+
*/
|
|
50
|
+
value : {type : "string", group : "Misc", defaultValue : null},
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Used to load the font.
|
|
54
|
+
* The URL should point to a CSS file that defines the font-face.
|
|
55
|
+
*/
|
|
56
|
+
url : {type: "sap.ui.core.URI", group : "Data", defaultValue : null}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
RichTextEditorFontFamily.prototype.validateProperty = function(sPropertyName, oValue) {
|
|
62
|
+
if (sPropertyName === "url") {
|
|
63
|
+
var sUrl = Element.prototype.validateProperty.call(this, sPropertyName, oValue);
|
|
64
|
+
|
|
65
|
+
// Stronger validation to prevent CSS injection
|
|
66
|
+
if (sUrl && /[<>()'"\\]|\/\*|\*\/|javascript:|data:/i.test(sUrl)) {
|
|
67
|
+
Log.Error("RichTextEditorFontFamily: URL contains potentially dangerous characters: " + sUrl, this);
|
|
68
|
+
return "";
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return sUrl;
|
|
72
|
+
}
|
|
73
|
+
return Element.prototype.validateProperty.call(this, sPropertyName, oValue);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
return RichTextEditorFontFamily;
|
|
77
|
+
|
|
78
|
+
});
|
|
@@ -39,6 +39,11 @@ sap.ui.define([
|
|
|
39
39
|
ButtonsToCommandsMap = library.ButtonsToCommandsMap,
|
|
40
40
|
ButtonType = mLibrary.ButtonType;
|
|
41
41
|
|
|
42
|
+
const SYSTEM_FONT_CHROME = "-apple-system,system-ui,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif";
|
|
43
|
+
// Safari and FF return BlinkMacSystemFont, Chrome returns system-ui
|
|
44
|
+
const SYSTEM_FONT_LEGACY = "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif";
|
|
45
|
+
const SYSTEM_FONT_KEY = "custom-font-family";
|
|
46
|
+
|
|
42
47
|
/**
|
|
43
48
|
* Constructor for a new RichTextEditor's Custom Toolbar.
|
|
44
49
|
*
|
|
@@ -105,6 +110,7 @@ sap.ui.define([
|
|
|
105
110
|
this._oAccessibilityTexts = {};
|
|
106
111
|
this._sTextColor = EditorCommands.TextColor.defaultValue;
|
|
107
112
|
this._sBackgroundColor = EditorCommands.BackgroundColor.defaultValue;
|
|
113
|
+
this._oPreservedMergetagSelection = null;
|
|
108
114
|
};
|
|
109
115
|
|
|
110
116
|
ToolbarWrapper.prototype.onBeforeRendering = function () {
|
|
@@ -157,6 +163,7 @@ sap.ui.define([
|
|
|
157
163
|
this._sTextColor = null;
|
|
158
164
|
this._sBackgroundColor = null;
|
|
159
165
|
this._bLinkPrefixChecked = null;
|
|
166
|
+
this._oPreservedMergetagSelection = null;
|
|
160
167
|
};
|
|
161
168
|
|
|
162
169
|
/**
|
|
@@ -291,6 +298,17 @@ sap.ui.define([
|
|
|
291
298
|
editor.on('NodeChange', function () {
|
|
292
299
|
that._syncToolbarStates(this);
|
|
293
300
|
});
|
|
301
|
+
|
|
302
|
+
// When using mergetags plugin, the selection is lost when the user clicks on a toolbar action.
|
|
303
|
+
// This is a workaround to restore the last selection made by the user.
|
|
304
|
+
editor.on('SelectionChange', function() {
|
|
305
|
+
var oSelectionNode = this.selection.getNode();
|
|
306
|
+
if (oSelectionNode && oSelectionNode.classList && oSelectionNode.classList.contains('mce-mergetag')) {
|
|
307
|
+
that._oPreservedMergetagSelection = oSelectionNode;
|
|
308
|
+
} else {
|
|
309
|
+
that._oPreservedMergetagSelection = null;
|
|
310
|
+
}
|
|
311
|
+
});
|
|
294
312
|
};
|
|
295
313
|
|
|
296
314
|
return oConfig;
|
|
@@ -309,6 +327,7 @@ sap.ui.define([
|
|
|
309
327
|
// Prevent losing the focus to the overflow toolbar button after the menu popover is closed
|
|
310
328
|
setTimeout(function(){
|
|
311
329
|
if (bDefaultColor || this._getColor(sCommand).replace(/,\s/g, ',') !== sColor) {
|
|
330
|
+
this._restoreMergetagSelection();
|
|
312
331
|
this.getEditor().getNativeApi().execCommand(sCommandName, false, sColor);
|
|
313
332
|
}
|
|
314
333
|
}.bind(this), 0);
|
|
@@ -347,6 +366,7 @@ sap.ui.define([
|
|
|
347
366
|
var oEditorCommand, oControl, sEditorCommand,
|
|
348
367
|
oFormatter = oNativeEditor.formatter,
|
|
349
368
|
oResourceBundle = this._oResourceBundle,
|
|
369
|
+
that = this,
|
|
350
370
|
_syncTextAlign = function (oTextAlignCommand, oEditorFormatter, oControl) {
|
|
351
371
|
var sAlignCommand, sIconUri, oCommand;
|
|
352
372
|
|
|
@@ -386,29 +406,6 @@ sap.ui.define([
|
|
|
386
406
|
}
|
|
387
407
|
}
|
|
388
408
|
},
|
|
389
|
-
_syncTextFontFamily = function (oEditor, oFontFamilyCommand, oControl) {
|
|
390
|
-
var sFontName, sCommandValue, sText, sItemId,
|
|
391
|
-
sFontNameCommandValue = oEditor.getDoc().queryCommandValue("FontName");
|
|
392
|
-
|
|
393
|
-
// Synchronize the selected item of the Font Family Select with the applied font family style
|
|
394
|
-
for (sFontName in oFontFamilyCommand) {
|
|
395
|
-
if (!oFontFamilyCommand.hasOwnProperty(sFontName)) {
|
|
396
|
-
continue;
|
|
397
|
-
}
|
|
398
|
-
sItemId = oControl.getId() + sFontName;
|
|
399
|
-
|
|
400
|
-
sCommandValue = oFontFamilyCommand[sFontName].commandValue.match(/\w+/g).join("").toLowerCase();
|
|
401
|
-
sFontNameCommandValue = sFontNameCommandValue && sFontNameCommandValue.match(/\w+/g)?.join("").toLowerCase();
|
|
402
|
-
sText = oFontFamilyCommand[sFontName].text.match(/\w+/g).join("").toLowerCase();
|
|
403
|
-
|
|
404
|
-
// the selected item should be changed, only when the new one is different
|
|
405
|
-
if ((oControl.getSelectedItemId() !== sItemId) &&
|
|
406
|
-
(sCommandValue === sFontNameCommandValue || sFontNameCommandValue === sText)) {
|
|
407
|
-
oControl.setSelectedItemId(sItemId);
|
|
408
|
-
break;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
},
|
|
412
409
|
_syncImage = function (oEditor, oControl) {
|
|
413
410
|
var oSelection = oEditor.selection.getNode(),
|
|
414
411
|
bImage = oSelection && oSelection.tagName.toLowerCase() === "img" ||
|
|
@@ -445,9 +442,32 @@ sap.ui.define([
|
|
|
445
442
|
case "TextAlign":
|
|
446
443
|
_syncTextAlign(oEditorCommand, oFormatter, oControl);
|
|
447
444
|
break;
|
|
448
|
-
case "FontFamily":
|
|
449
|
-
|
|
445
|
+
case "FontFamily": {
|
|
446
|
+
let sFontName = oNativeEditor.queryCommandValue("FontName");
|
|
447
|
+
const bSystemFont = sFontName.includes(SYSTEM_FONT_CHROME) || sFontName.includes(SYSTEM_FONT_LEGACY);
|
|
448
|
+
|
|
449
|
+
// Enhanced mergetag font family detection
|
|
450
|
+
if (that._oPreservedMergetagSelection) {
|
|
451
|
+
var oPreservedComputedStyle = oNativeEditor.getDoc().defaultView.getComputedStyle(that._oPreservedMergetagSelection);
|
|
452
|
+
sFontName = oPreservedComputedStyle.fontFamily || sFontName;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (bSystemFont) {
|
|
456
|
+
oControl.setSelectedKey(SYSTEM_FONT_KEY);
|
|
457
|
+
oControl.getSelectedItem()?.setText(oResourceBundle.getText("FONT_FAMILY_DEFAULT_TEXT"));
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const bExistingFont = oControl.getItems().find((oItem) => oItem.getKey() === sFontName);
|
|
462
|
+
|
|
463
|
+
if (bExistingFont) {
|
|
464
|
+
oControl.setSelectedKey(sFontName);
|
|
465
|
+
} else {
|
|
466
|
+
oControl.setSelectedKey(SYSTEM_FONT_KEY);
|
|
467
|
+
oControl.getSelectedItem()?.setText(sFontName);
|
|
468
|
+
}
|
|
450
469
|
break;
|
|
470
|
+
}
|
|
451
471
|
case "FormatBlock":
|
|
452
472
|
_syncTextFormatBlock(oNativeEditor, oEditorCommand, oControl);
|
|
453
473
|
break;
|
|
@@ -502,7 +522,8 @@ sap.ui.define([
|
|
|
502
522
|
*/
|
|
503
523
|
ToolbarWrapper.prototype._createButtonConfig = function (sCommand) {
|
|
504
524
|
var oCommand = EditorCommands[sCommand],
|
|
505
|
-
oRTE = this.getEditor()
|
|
525
|
+
oRTE = this.getEditor(),
|
|
526
|
+
that = this;
|
|
506
527
|
|
|
507
528
|
return {
|
|
508
529
|
id: this._getId(sCommand),
|
|
@@ -511,6 +532,7 @@ sap.ui.define([
|
|
|
511
532
|
text: this._oResourceBundle.getText(oCommand.bundleKey),
|
|
512
533
|
press: function () {
|
|
513
534
|
if (oRTE) {
|
|
535
|
+
that._restoreMergetagSelection();
|
|
514
536
|
oRTE.getNativeApi().execCommand(oCommand.command);
|
|
515
537
|
} else {
|
|
516
538
|
Log.warning("Cannot execute native command: " + oCommand.command);
|
|
@@ -575,37 +597,25 @@ sap.ui.define([
|
|
|
575
597
|
* @private
|
|
576
598
|
*/
|
|
577
599
|
ToolbarWrapper.prototype._createFontStyleSelectItems = function () {
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
text: oFontFamilies[sFontStyle].text
|
|
586
|
-
};
|
|
587
|
-
|
|
588
|
-
aItems.push(new Item(oItem));
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
return aItems;
|
|
592
|
-
};
|
|
593
|
-
|
|
594
|
-
/**
|
|
595
|
-
* Helper function for finding the command value of a given font style command
|
|
596
|
-
*
|
|
597
|
-
* @param {string} [sItemText] Font Family
|
|
598
|
-
* @returns {string} The command value of the given font style
|
|
599
|
-
* @private
|
|
600
|
-
*/
|
|
601
|
-
ToolbarWrapper.prototype._getFontStyleCommand = function (sItemText) {
|
|
602
|
-
var oFontFamilies = EditorCommands["FontFamily"];
|
|
600
|
+
const aFontFamilies = EditorCommands["FontFamily"];
|
|
601
|
+
const aCustomFonts = this.getEditor().getCustomFonts();
|
|
602
|
+
const cleanFontString = (fontKey) => {
|
|
603
|
+
return fontKey
|
|
604
|
+
.replace(/['"]/g, "")
|
|
605
|
+
.replace(/,\s+/g, ",");
|
|
606
|
+
};
|
|
603
607
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
608
|
+
return [...aFontFamilies.map((oFontFamily) => {
|
|
609
|
+
return new Item({
|
|
610
|
+
text: oFontFamily.text,
|
|
611
|
+
key: oFontFamily.value
|
|
612
|
+
});
|
|
613
|
+
}), ...aCustomFonts.map((oFont) => {
|
|
614
|
+
return new Item({
|
|
615
|
+
text: oFont.getText(),
|
|
616
|
+
key: cleanFontString(oFont.getValue())
|
|
617
|
+
});
|
|
618
|
+
})];
|
|
609
619
|
};
|
|
610
620
|
|
|
611
621
|
/**
|
|
@@ -727,6 +737,9 @@ sap.ui.define([
|
|
|
727
737
|
}
|
|
728
738
|
},
|
|
729
739
|
arrowPress: function () {
|
|
740
|
+
// Preserve mergetag selection before opening popover
|
|
741
|
+
that._preserveMergetagSelection();
|
|
742
|
+
|
|
730
743
|
oDialog = that.getAggregation("_custom" + sCommand + "Dialog");
|
|
731
744
|
|
|
732
745
|
this._getArrowButton()._activeButton();
|
|
@@ -1593,14 +1606,21 @@ sap.ui.define([
|
|
|
1593
1606
|
this._helper.createSelect({
|
|
1594
1607
|
id: this._getId("FontFamily"),
|
|
1595
1608
|
ariaLabelledBy: oInvisibleTextFontFamily,
|
|
1596
|
-
|
|
1597
|
-
|
|
1609
|
+
items: [
|
|
1610
|
+
...this._createFontStyleSelectItems(),
|
|
1611
|
+
new Item({
|
|
1612
|
+
key: "custom-font-family",
|
|
1613
|
+
enabled: false
|
|
1614
|
+
})
|
|
1615
|
+
],
|
|
1598
1616
|
change: function (oEvent) {
|
|
1617
|
+
that._preserveMergetagSelection();
|
|
1599
1618
|
var oItem;
|
|
1600
1619
|
|
|
1601
1620
|
if (oRTE) {
|
|
1602
1621
|
oItem = oEvent.getSource().getSelectedItem();
|
|
1603
|
-
|
|
1622
|
+
that._restoreMergetagSelection();
|
|
1623
|
+
oRTE.getNativeApi().execCommand('FontName', false, oItem.getKey());
|
|
1604
1624
|
} else {
|
|
1605
1625
|
Log.warning("Cannot execute native command: " + 'FontName');
|
|
1606
1626
|
}
|
|
@@ -1629,10 +1649,12 @@ sap.ui.define([
|
|
|
1629
1649
|
})
|
|
1630
1650
|
],
|
|
1631
1651
|
change: function (oEvent) {
|
|
1652
|
+
that._preserveMergetagSelection();
|
|
1632
1653
|
var oItem;
|
|
1633
1654
|
|
|
1634
1655
|
if (oRTE) {
|
|
1635
1656
|
oItem = oEvent.getSource().getSelectedItem();
|
|
1657
|
+
that._restoreMergetagSelection();
|
|
1636
1658
|
oRTE.getNativeApi().execCommand('FontSize', false, oItem.getText().replace(/\s/g, ""));
|
|
1637
1659
|
} else {
|
|
1638
1660
|
Log.warning("Cannot execute native command: " + 'FontSize');
|
|
@@ -1671,22 +1693,26 @@ sap.ui.define([
|
|
|
1671
1693
|
ToolbarWrapper.prototype._createTextAlignToolbarContent = function (bVisible) {
|
|
1672
1694
|
var oRTE = this.getEditor();
|
|
1673
1695
|
var bGroupVisible = oRTE ? oRTE.getShowGroupFontStyle() || bVisible : false;
|
|
1674
|
-
var that = this;
|
|
1675
1696
|
var bTextAlignLRight = oRTE._getTextDirection() === "rtl";
|
|
1676
1697
|
var iDefaultItemIndex = bTextAlignLRight ? 2 : 0;
|
|
1677
1698
|
var aMenuItems = this._createMenuButtonItems("TextAlign");
|
|
1699
|
+
var that = this;
|
|
1678
1700
|
|
|
1679
1701
|
return [
|
|
1680
1702
|
this._helper.createMenuButton(
|
|
1681
1703
|
this._getId("TextAlign"),
|
|
1682
1704
|
aMenuItems,
|
|
1683
1705
|
function (oEvent) {
|
|
1706
|
+
that._preserveMergetagSelection();
|
|
1684
1707
|
var oSelectedItem, oEditor, oSelectedItemIcon;
|
|
1708
|
+
var oPreservedNode = that._oPreservedMergetagSelection;
|
|
1685
1709
|
|
|
1686
1710
|
if (oRTE) {
|
|
1687
1711
|
oSelectedItem = oEvent.getParameter("item");
|
|
1688
1712
|
oEditor = oRTE.getNativeApi();
|
|
1689
1713
|
oSelectedItemIcon = oSelectedItem.getIcon();
|
|
1714
|
+
|
|
1715
|
+
that._restoreMergetagSelection();
|
|
1690
1716
|
if (oSelectedItemIcon === this.getParent().getIcon()) {
|
|
1691
1717
|
var sTextAlign = bTextAlignLRight ? "JustifyRight" : "JustifyLeft";
|
|
1692
1718
|
// Text Align commands in TinyMCE have a toggle behavior when you set a
|
|
@@ -1695,6 +1721,14 @@ sap.ui.define([
|
|
|
1695
1721
|
} else {
|
|
1696
1722
|
oEditor.execCommand('Justify' + that._findTextAlignCommandByIcon(oSelectedItemIcon));
|
|
1697
1723
|
}
|
|
1724
|
+
|
|
1725
|
+
// Restore mergetag selection after TinyMCE moves focus
|
|
1726
|
+
if (oPreservedNode && oPreservedNode.classList && oPreservedNode.classList.contains('mce-mergetag')) {
|
|
1727
|
+
// Prevent losing the focus to the overflow toolbar button after the menu popover is closed
|
|
1728
|
+
requestAnimationFrame(function() {
|
|
1729
|
+
oEditor.selection.select(oPreservedNode);
|
|
1730
|
+
});
|
|
1731
|
+
}
|
|
1698
1732
|
} else {
|
|
1699
1733
|
Log.warning("Cannot execute native command: " + 'Justify');
|
|
1700
1734
|
}
|
|
@@ -1706,6 +1740,7 @@ sap.ui.define([
|
|
|
1706
1740
|
};
|
|
1707
1741
|
|
|
1708
1742
|
ToolbarWrapper.prototype._createFormatSelectToolbarContent = function (bVisible) {
|
|
1743
|
+
var that = this;
|
|
1709
1744
|
var oRTE = this.getEditor();
|
|
1710
1745
|
var oAccessibilityKeys = library.Accessibility;
|
|
1711
1746
|
var oInvisibleTextFormatBlock = this._helper.createInvisibleText({
|
|
@@ -1720,10 +1755,12 @@ sap.ui.define([
|
|
|
1720
1755
|
ariaLabelledBy: oInvisibleTextFormatBlock,
|
|
1721
1756
|
items: this._createFormatBlockItems(),
|
|
1722
1757
|
change: function (oEvent) {
|
|
1758
|
+
that._preserveMergetagSelection();
|
|
1723
1759
|
var oSelectedItem;
|
|
1724
1760
|
if (oRTE) {
|
|
1725
1761
|
oSelectedItem = oEvent.getSource().getSelectedItem();
|
|
1726
1762
|
if (oSelectedItem) {
|
|
1763
|
+
that._restoreMergetagSelection();
|
|
1727
1764
|
var currentFormatterCommand = oRTE.getAggregation("_toolbarWrapper")._getFormatBlockCommand(oSelectedItem.getText());
|
|
1728
1765
|
oRTE.getNativeApi().execCommand('FormatBlock', false, currentFormatterCommand);
|
|
1729
1766
|
}
|
|
@@ -2352,5 +2389,31 @@ sap.ui.define([
|
|
|
2352
2389
|
return Element.getElementById(oRTE.getId() + this.getId() + "-" + sButtonName);
|
|
2353
2390
|
};
|
|
2354
2391
|
|
|
2392
|
+
// When using mergetags plugin, the selection is lost when the user clicks on a toolbar action.
|
|
2393
|
+
// This is a workaround to restore the last selection made by the user.
|
|
2394
|
+
ToolbarWrapper.prototype._preserveMergetagSelection = function () {
|
|
2395
|
+
var oEditor = this.getEditor();
|
|
2396
|
+
if (!oEditor) {
|
|
2397
|
+
return;
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
var oSelectionNode = oEditor.getNativeApi().selection.getNode();
|
|
2401
|
+
|
|
2402
|
+
if (oSelectionNode && oSelectionNode.classList && oSelectionNode.classList.contains('mce-mergetag')) {
|
|
2403
|
+
this._oPreservedMergetagSelection = oSelectionNode;
|
|
2404
|
+
}
|
|
2405
|
+
};
|
|
2406
|
+
|
|
2407
|
+
ToolbarWrapper.prototype._restoreMergetagSelection = function () {
|
|
2408
|
+
if (this._oPreservedMergetagSelection) {
|
|
2409
|
+
var oEditor = this.getEditor();
|
|
2410
|
+
if (oEditor) {
|
|
2411
|
+
var oNativeEditor = oEditor.getNativeApi();
|
|
2412
|
+
oNativeEditor.selection.select(this._oPreservedMergetagSelection);
|
|
2413
|
+
}
|
|
2414
|
+
this._oPreservedMergetagSelection = null;
|
|
2415
|
+
}
|
|
2416
|
+
};
|
|
2417
|
+
|
|
2355
2418
|
return ToolbarWrapper;
|
|
2356
2419
|
});
|