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:
Jacob Overgaard
2024-01-08 08:58:57 +01:00
committed by GitHub
parent a36c7beabf
commit 77861ae55b
7 changed files with 41 additions and 14 deletions

View File

@@ -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]

View File

@@ -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; }
}

View File

@@ -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;

View File

@@ -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",

View File

@@ -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"

View File

@@ -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,

View File

@@ -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);