Commit 71aebd5f authored by Benni Mack's avatar Benni Mack Committed by Andreas Fernandez
Browse files

[BUGFIX] Respect icon size defined by tree

The SVG Tree now builds a SVG-in-SVG element around all
icons (icon + overlay) to ensure the sizes are consistent
and can be positioned properly.

This fixes the issue that possible custom icons have
a different size.

Resolves: #86280
Releases: master
Change-Id: Icf39e74c398d149a9216a64551bdeb250ed2bf00
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/69147

Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Tested-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
parent 06d5edd6
......@@ -43,7 +43,7 @@ interface SvgTreeDataLink {
interface SvgTreeDataIcon {
identifier: string;
icon: string;
icon: string|null|SVGElement;
}
export interface SvgTreeSettings {
......@@ -416,12 +416,13 @@ export class SvgTree extends LitElement {
if (!(iconName in this.icons)) {
this.icons[iconName] = {
identifier: iconName,
icon: ''
};
icon: null
} as SvgTreeDataIcon;
Icons.getIcon(iconName, Icons.sizes.small, null, null, MarkupIdentifiers.inline).then((icon: string) => {
let result = icon.match(/<svg[\s\S]*<\/svg>/i);
if (result) {
this.icons[iconName].icon = result[0];
let iconEl = document.createRange().createContextualFragment(result[0]);
this.icons[iconName].icon = iconEl.firstElementChild as SVGElement;
}
if (update) {
this.updateVisibleNodes();
......@@ -973,7 +974,7 @@ export class SvgTree extends LitElement {
protected enterSvgElements(nodes: TreeNodeSelection): TreeNodeSelection {
if (this.settings.showIcons) {
const iconsArray = Object.values(this.icons)
.filter((icon: SvgTreeDataIcon): boolean => icon.icon !== '');
.filter((icon: SvgTreeDataIcon): boolean => icon.icon !== '' && icon.icon !== null);
const icons = this.iconsContainer
.selectAll('.icon-def')
.data(iconsArray, (icon: SvgTreeDataIcon) => icon.identifier);
......@@ -985,10 +986,12 @@ export class SvgTree extends LitElement {
.attr('class', 'icon-def')
.attr('id', (node: TreeNode) => 'icon-' + node.identifier)
.append((node: TreeNode): SVGElement => {
// workaround for IE11 where you can't simply call .html(content) on svg
if (node.icon instanceof SVGElement) {
return node.icon;
}
// Once all icons are real SVG Elements, this part can safely be removed
const markup = '<svg>' + node.icon + '</svg>';
const parser = new DOMParser();
const markupText = node.icon.replace('<svg', '<g').replace('/svg>', '/g>');
const markup = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' + markupText + '</svg>';
const dom = parser.parseFromString(markup, 'image/svg+xml');
return dom.documentElement.firstChild as SVGElement;
});
......@@ -1018,9 +1021,13 @@ export class SvgTree extends LitElement {
// append the icon element
if (this.settings.showIcons) {
const nodeContainer = nodeEnter
.append('g')
.append('svg')
.attr('class', 'node-icon-container')
.attr('title', this.getNodeTitle)
.attr('height', '20')
.attr('width', '20')
.attr('x', '6')
.attr('y', '-10')
.attr('data-bs-toggle', 'tooltip')
.on('click', (evt: MouseEvent, node: TreeNode) => {
evt.preventDefault();
......@@ -1033,24 +1040,43 @@ export class SvgTree extends LitElement {
.style('opacity', 0)
.attr('width', '20')
.attr('height', '20')
.attr('x', '6')
.attr('y', '-10');
nodeContainer
.attr('y', '0')
.attr('x', '0')
.attr('class', 'node-icon-click');
const nodeInner = nodeContainer
.append('svg')
.attr('height', '16')
.attr('width', '16')
.attr('y', '2')
.attr('x', '2')
.attr('class', 'node-icon-inner');
nodeInner
.append('use')
.attr('class', 'node-icon')
.attr('data-uid', this.getNodeIdentifier)
.attr('transform', 'translate(8, -8)');
.attr('data-uid', this.getNodeIdentifier);
nodeContainer
const nodeIconOverlay = nodeInner
.append('svg')
.attr('height', '11')
.attr('width', '11')
.attr('y', '5')
.attr('x', '5');
nodeIconOverlay
.append('use')
.attr('transform', 'translate(8, -3)')
.attr('class', 'node-icon-overlay');
nodeContainer
const nodeIconLocked = nodeInner
.append('svg')
.attr('height', '11')
.attr('width', '11')
.attr('y', '5')
.attr('x', '5');
nodeIconLocked
.append('use')
.attr('x', 27)
.attr('y', -7)
.attr('class', 'node-icon-locked');
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment