Show SVG icons for toolbar in configuration of richtext editor (#14404)

* Load default icons to show them next to checkboxes in configuration of richtext editor

* More mapping of icons

* Fix vertical align items centered not reflected

* Wrap mapping in function

* Map a few more icons

* Cleanup and formatting

* Cleanup

* Cleanup

* Add period in description
This commit is contained in:
Bjarne Fyrstenborg
2023-06-19 13:48:03 +02:00
committed by GitHub
parent 0a4a938b88
commit 583965cf9d
4 changed files with 120 additions and 30 deletions

View File

@@ -115,18 +115,18 @@ public class RichTextEditorSettings
new Dictionary<string, string> { ["entity_encoding"] = "raw" };
/// <summary>
/// HTML RichText Editor TinyMCE Commands
/// HTML RichText Editor TinyMCE Commands.
/// </summary>
/// WB-TODO Custom Array of objects
public RichTextEditorCommand[] Commands { get; set; } = Default_commands;
/// <summary>
/// HTML RichText Editor TinyMCE Plugins
/// HTML RichText Editor TinyMCE Plugins.
/// </summary>
public string[] Plugins { get; set; } = Default_plugins;
/// <summary>
/// HTML RichText Editor TinyMCE Custom Config
/// HTML RichText Editor TinyMCE Custom Config.
/// </summary>
/// WB-TODO Custom Dictionary
public IDictionary<string, string> CustomConfig { get; set; } = Default_custom_config;
@@ -137,7 +137,7 @@ public class RichTextEditorSettings
public string ValidElements { get; set; } = StaticValidElements;
/// <summary>
/// Invalid HTML elements for RichText Editor
/// Invalid HTML elements for RichText Editor.
/// </summary>
[DefaultValue(StaticInvalidElements)]
public string InvalidElements { get; set; } = StaticInvalidElements;

View File

@@ -354,20 +354,25 @@ label:not([for]) {
margin: 0 !important;
}
.controls > .vertical-align-items,
.controls-row > .vertical-align-items {
display: flex;
align-items: center;
}
.controls > .vertical-align-items > input.umb-property-editor-tiny,
.controls > .vertical-align-items > input.umb-property-editor-small,
.controls-row > .vertical-align-items > input.umb-property-editor-tiny,
.controls-row > .vertical-align-items > input.umb-property-editor-small {
margin-left: 5px;
margin-right: 5px;
margin-left: 5px;
margin-right: 5px;
}
.controls > .vertical-align-items > input.umb-property-editor-tiny:first-child
.controls > .vertical-align-items > input.umb-property-editor-small:first-child,
.controls-row > .vertical-align-items > input.umb-property-editor-tiny:first-child
.controls-row > .vertical-align-items > input.umb-property-editor-small:first-child {
margin-left: 0;
margin-left: 0;
}
.thumbnails .selected {

View File

@@ -1,12 +1,12 @@
angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController",
function ($scope, $timeout, $log, tinyMceService, stylesheetResource, assetsService) {
function ($scope, $sce, tinyMceService, stylesheetResource, assetsService) {
var cfg = tinyMceService.defaultPrevalues();
if($scope.model.value){
if(Utilities.isString($scope.model.value)){
if($scope.model.value) {
if (Utilities.isString($scope.model.value)){
$scope.model.value = cfg;
}
}else{
}else {
$scope.model.value = cfg;
}
@@ -27,14 +27,14 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController",
$scope.model.value.mode = 'inline';
}
tinyMceService.configuration().then(function(config){
$scope.tinyMceConfig = config;
tinyMceService.configuration().then(config => {
$scope.tinyMceConfig = config;
// extend commands with properties for font-icon and if it is a custom command
$scope.tinyMceConfig.commands = _.map($scope.tinyMceConfig.commands, function (obj) {
var icon = getFontIcon(obj.alias);
var objCmd = Utilities.extend(obj, {
$scope.tinyMceConfig.commands = _.map($scope.tinyMceConfig.commands, obj => {
const icon = getIcon(obj.alias);
const objCmd = Utilities.extend(obj, {
fontIcon: icon.name,
isCustom: icon.isCustom,
selected: $scope.model.value.toolbar.indexOf(obj.alias) >= 0,
@@ -43,9 +43,30 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController",
return objCmd;
});
assetsService.loadJs("lib/tinymce/icons/default/icons.js", $scope).then(() => {
const icons = tinymce.IconManager.get('default').icons;
const parser = new DOMParser();
Utilities.forEach($scope.tinyMceConfig.commands, cmd => {
let icon = getTinyIcon(cmd.alias);
if (!cmd.isCustom && icons.hasOwnProperty(icon)) {
const svg = icons[icon];
const frag = parser.parseFromString(svg, 'text/html').body.childNodes[0];
const width = frag.getAttribute("width");
const height = frag.getAttribute("height");
frag.setAttribute("viewBox", `0 0 ${width} ${height}`);
cmd.svgIcon = $sce.trustAsHtml(frag.outerHTML);
cmd.icon = null;
}
});
});
});
stylesheetResource.getAll().then(function(stylesheets){
stylesheetResource.getAll().then(stylesheets => {
$scope.stylesheets = stylesheets;
// if the CSS directory changes, previously assigned stylesheets are retained, but will not be visible
@@ -63,14 +84,14 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController",
$scope.selectCommand = function(command){
var index = $scope.model.value.toolbar.indexOf(command.alias);
if(command.selected && index === -1){
if (command.selected && index === -1){
$scope.model.value.toolbar.push(command.alias);
}else if(index >= 0){
}else if (index >= 0){
$scope.model.value.toolbar.splice(index, 1);
}
};
$scope.selectStylesheet = function (css) {
$scope.selectStylesheet = css => {
// find out if the stylesheet is already selected; first look for the full stylesheet path (current format)
var index = $scope.model.value.stylesheets.indexOf(css.path);
@@ -79,15 +100,80 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController",
index = $scope.model.value.stylesheets.indexOf(css.name);
}
if(index === -1){
if (index === -1){
$scope.model.value.stylesheets.push(css.path);
}else{
} else {
$scope.model.value.stylesheets.splice(index, 1);
}
};
// map properties for specific commands
function getFontIcon(alias) {
// Map command alias to icon name.
function getTinyIcon(alias) {
let icon = alias;
switch (alias) {
case "ace":
case "code":
icon = "sourcecode";
break;
case "anchor":
icon = "bookmark";
break;
case "alignleft":
icon = "align-left";
break;
case "aligncenter":
icon = "align-center";
break;
case "alignright":
icon = "align-right";
break;
case "alignjustify":
icon = "align-justify";
break;
case "charmap":
icon = "insert-character";
break;
case "hr":
icon = "horizontal-rule";
break;
case "bullist":
icon = "unordered-list";
break;
case "numlist":
icon = "ordered-list";
break;
case "strikethrough":
icon = "strike-through";
break;
case "removeformat":
icon = "remove-formatting";
break;
case "blockquote":
icon = "quote";
break;
case "forecolor":
icon = "text-color";
break;
case "hilitecolor":
icon = "highlight-bg-color";
break;
case "wordcount":
icon = "character-count";
break;
case "emoticons":
icon = "emoji";
break;
case "codesample":
icon = "code-sample";
break;
}
return icon;
}
// Map properties for specific commands
function getIcon(alias) {
var icon = { name: alias, isCustom: false };
switch (alias) {

View File

@@ -5,22 +5,21 @@
<umb-checkbox
model="cmd.selected"
on-change="selectCommand(cmd)"
icon="{{cmd.icon}}"
text="{{cmd.name}}"
class="mce-cmd">
<umb-icon ng-if="cmd.icon" icon="{{cmd.icon}}"></umb-icon>
<span ng-if="!cmd.icon && cmd.svgIcon" ng-bind-html="cmd.svgIcon" class="umb-icon"></span>
<span ng-if="cmd.name" class="umb-form-check__text">{{cmd.name}}</span>
</umb-checkbox>
</div>
</umb-control-group>
<umb-control-group label="Stylesheets" description="Pick the stylesheets whose editor styles should be available when editing">
<div ng-repeat="css in stylesheets">
<umb-checkbox
model="css.selected"
on-change="selectStylesheet(css)"
text="{{css.name}}">
</umb-checkbox>
</div>
</umb-control-group>