V13: Load TinyMCE premium plugins through tiny.cloud (#15367)
* add tinymce cloud api key to configuration * forward apikey through proxied config object after retrieving it from the server * load the plugins.min.js file from tiny.cloud if cloud api key is set * bump tinymce from 6.7.3 to 6.8.1 * disable premium promotion and make plugins unique * make sure tinymce local assets are loaded before trying to load the plugins.js from cloud and before configuring tinymce
This commit is contained in:
@@ -146,6 +146,11 @@ public class RichTextEditorSettings
|
||||
[DefaultValue(StaticInvalidElements)]
|
||||
public string InvalidElements { get; set; } = StaticInvalidElements;
|
||||
|
||||
/// <summary>
|
||||
/// Cloud API Key for TinyMCE. This is required to use TinyMCE premium plugins.
|
||||
/// </summary>
|
||||
public string? CloudApiKey { get; set; }
|
||||
|
||||
public class RichTextEditorCommand
|
||||
{
|
||||
[Required]
|
||||
|
||||
@@ -19,4 +19,7 @@ public class RichTextEditorConfiguration
|
||||
|
||||
[DataMember(Name = "customConfig")]
|
||||
public IDictionary<string, string>? CustomConfig { get; set; }
|
||||
|
||||
[DataMember(Name = "cloudApiKey")]
|
||||
public string? CloudApiKey { get; set; }
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ public class RichTextPreValueController : UmbracoAuthorizedJsonController
|
||||
new RichTextEditorCommand { Alias = x.Alias, Mode = x.Mode, Name = x.Name }),
|
||||
ValidElements = settings.ValidElements,
|
||||
InvalidElements = settings.InvalidElements,
|
||||
CustomConfig = settings.CustomConfig
|
||||
CustomConfig = settings.CustomConfig,
|
||||
CloudApiKey = settings.CloudApiKey,
|
||||
};
|
||||
|
||||
return config;
|
||||
|
||||
8
src/Umbraco.Web.UI.Client/package-lock.json
generated
8
src/Umbraco.Web.UI.Client/package-lock.json
generated
@@ -39,7 +39,7 @@
|
||||
"ng-file-upload": "12.2.13",
|
||||
"nouislider": "15.7.1",
|
||||
"spectrum-colorpicker2": "2.0.10",
|
||||
"tinymce": "6.7.3",
|
||||
"tinymce": "6.8.1",
|
||||
"typeahead.js": "0.11.1",
|
||||
"underscore": "1.13.6",
|
||||
"wicg-inert": "3.1.2"
|
||||
@@ -16606,9 +16606,9 @@
|
||||
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
|
||||
},
|
||||
"node_modules/tinymce": {
|
||||
"version": "6.7.3",
|
||||
"resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.7.3.tgz",
|
||||
"integrity": "sha512-J7WmYIi/gt1RvZ6Ap2oQiUjzAoiS9pfV+d4GnKuZuPu8agmlAEAInNmMvMjfCNBzHv4JnZXY7qlHUAI0IuYQVA=="
|
||||
"version": "6.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.8.1.tgz",
|
||||
"integrity": "sha512-WYPvMXIjBrXM/oBiqGCbT2a8ptiO3TWXm/xxPWDCl8SxRKMW7Rfp0Lk190E9fXmX6uh9lJMRCnmKHzvryz0ftA=="
|
||||
},
|
||||
"node_modules/to-absolute-glob": {
|
||||
"version": "2.0.2",
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
"ng-file-upload": "12.2.13",
|
||||
"nouislider": "15.7.1",
|
||||
"spectrum-colorpicker2": "2.0.10",
|
||||
"tinymce": "6.7.3",
|
||||
"tinymce": "6.8.1",
|
||||
"typeahead.js": "0.11.1",
|
||||
"underscore": "1.13.6",
|
||||
"wicg-inert": "3.1.2"
|
||||
|
||||
@@ -387,8 +387,10 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
|
||||
//create a baseline Config to extend upon
|
||||
var config = {
|
||||
cloudApiKey: tinyMceConfig.cloudApiKey,
|
||||
promotion: false,
|
||||
inline: modeInline,
|
||||
plugins: plugins,
|
||||
plugins: [...new Set(plugins)],
|
||||
custom_elements: 'umb-rte-block,~umb-rte-block-inline',
|
||||
valid_elements: tinyMceConfig.validElements,
|
||||
invalid_elements: tinyMceConfig.inValidElements,
|
||||
|
||||
@@ -177,24 +177,40 @@
|
||||
vm.containerHeight = "auto";
|
||||
vm.containerOverflow = "inherit";
|
||||
|
||||
var promises = [blockModelObjectLoading];
|
||||
const assetPromises = [blockModelObjectLoading];
|
||||
|
||||
//queue file loading
|
||||
tinyMceAssets.forEach(function (tinyJsAsset) {
|
||||
promises.push(assetsService.loadJs(tinyJsAsset, $scope));
|
||||
assetPromises.push(assetsService.loadJs(tinyJsAsset, $scope));
|
||||
});
|
||||
|
||||
promises.push(tinyMceService.getTinyMceEditorConfig({
|
||||
const tinyMceConfigDeferred = $q.defer();
|
||||
|
||||
//wait for assets to load before proceeding
|
||||
$q.all(assetPromises).then(function () {
|
||||
|
||||
tinyMceService.getTinyMceEditorConfig({
|
||||
htmlId: vm.textAreaHtmlId,
|
||||
stylesheets: editorConfig.stylesheets,
|
||||
toolbar: editorConfig.toolbar,
|
||||
mode: editorConfig.mode
|
||||
}));
|
||||
})
|
||||
.then(function (tinyMceConfig) {
|
||||
// Load the plugins.min.js file from the TinyMCE Cloud if a Cloud Api Key is specified
|
||||
if (tinyMceConfig.cloudApiKey) {
|
||||
return assetsService.loadJs(`https://cdn.tiny.cloud/1/${tinyMceConfig.cloudApiKey}/tinymce/${tinymce.majorVersion}.${tinymce.minorVersion}/plugins.min.js`)
|
||||
.then(() => tinyMceConfig);
|
||||
}
|
||||
|
||||
//wait for queue to end
|
||||
$q.all(promises).then(function (result) {
|
||||
return tinyMceConfig;
|
||||
})
|
||||
.then(function (tinyMceConfig) {
|
||||
tinyMceConfigDeferred.resolve(tinyMceConfig);
|
||||
});
|
||||
});
|
||||
|
||||
var standardConfig = result[promises.length - 1];
|
||||
//wait for config to be ready after assets have loaded
|
||||
tinyMceConfigDeferred.promise.then(function (standardConfig) {
|
||||
|
||||
if (height !== null) {
|
||||
standardConfig.plugins.splice(standardConfig.plugins.indexOf("autoresize"), 1);
|
||||
|
||||
Reference in New Issue
Block a user