Skip to content

Commit 6404107

Browse files
authored
fix: Fix display of multiline RTL strings in bubbles on Webkit. (#8733)
* fix: Fix display of multiline RTL strings in bubbles on Webkit. * chore: Remove references to spans.
1 parent f9ef785 commit 6404107

1 file changed

Lines changed: 28 additions & 19 deletions

File tree

core/bubbles/text_bubble.ts

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {Bubble} from './bubble.js';
1616
* A bubble that displays non-editable text. Used by the warning icon.
1717
*/
1818
export class TextBubble extends Bubble {
19-
private paragraph: SVGTextElement;
19+
private paragraph: SVGGElement;
2020

2121
constructor(
2222
private text: string,
@@ -48,43 +48,52 @@ export class TextBubble extends Bubble {
4848
*/
4949
private stringToSvg(text: string, container: SVGGElement) {
5050
const paragraph = this.createParagraph(container);
51-
const spans = this.createSpans(paragraph, text);
51+
const fragments = this.createTextFragments(paragraph, text);
5252
if (this.workspace.RTL)
53-
this.rightAlignSpans(paragraph.getBBox().width, spans);
53+
this.rightAlignTextFragments(paragraph.getBBox().width, fragments);
5454
return paragraph;
5555
}
5656

57-
/** Creates the paragraph container for this bubble's view's spans. */
58-
private createParagraph(container: SVGGElement): SVGTextElement {
57+
/** Creates the paragraph container for this bubble's view's text fragments. */
58+
private createParagraph(container: SVGGElement): SVGGElement {
5959
return dom.createSvgElement(
60-
Svg.TEXT,
60+
Svg.G,
6161
{
6262
'class': 'blocklyText blocklyBubbleText blocklyNoPointerEvents',
63-
'y': Bubble.BORDER_WIDTH,
63+
'transform': `translate(0,${Bubble.BORDER_WIDTH})`,
64+
'style': `direction: ${this.workspace.RTL ? 'rtl' : 'ltr'}`,
6465
},
6566
container,
6667
);
6768
}
6869

69-
/** Creates the spans visualizing the text of this bubble. */
70-
private createSpans(parent: SVGTextElement, text: string): SVGTSpanElement[] {
70+
/** Creates the text fragments visualizing the text of this bubble. */
71+
private createTextFragments(
72+
parent: SVGGElement,
73+
text: string,
74+
): SVGTextElement[] {
75+
let lineNum = 1;
7176
return text.split('\n').map((line) => {
72-
const tspan = dom.createSvgElement(
73-
Svg.TSPAN,
74-
{'dy': '1em', 'x': Bubble.BORDER_WIDTH},
77+
const fragment = dom.createSvgElement(
78+
Svg.TEXT,
79+
{'y': `${lineNum}em`, 'x': Bubble.BORDER_WIDTH},
7580
parent,
7681
);
7782
const textNode = document.createTextNode(line);
78-
tspan.appendChild(textNode);
79-
return tspan;
83+
fragment.appendChild(textNode);
84+
lineNum += 1;
85+
return fragment;
8086
});
8187
}
8288

83-
/** Right aligns the given spans. */
84-
private rightAlignSpans(maxWidth: number, spans: SVGTSpanElement[]) {
85-
for (const span of spans) {
86-
span.setAttribute('text-anchor', 'end');
87-
span.setAttribute('x', `${maxWidth + Bubble.BORDER_WIDTH}`);
89+
/** Right aligns the given text fragments. */
90+
private rightAlignTextFragments(
91+
maxWidth: number,
92+
fragments: SVGTextElement[],
93+
) {
94+
for (const text of fragments) {
95+
text.setAttribute('text-anchor', 'start');
96+
text.setAttribute('x', `${maxWidth + Bubble.BORDER_WIDTH}`);
8897
}
8998
}
9099

0 commit comments

Comments
 (0)