Skip to content

Commit

Permalink
SVG text iterative stripping of embedding marks (and direction/text-a…
Browse files Browse the repository at this point in the history
…nchor added) workaround for Firefox, see #1643
  • Loading branch information
jonathanolson committed Jul 9, 2024
1 parent a38712b commit 359abce
Showing 1 changed file with 41 additions and 1 deletion.
42 changes: 41 additions & 1 deletion js/display/drawables/TextSVGDrawable.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class TextSVGDrawable extends TextStatefulDrawable( SVGSelfDrawable ) {
// @private {boolean}
this.hasLength = false;

// @private {'ltr' | 'rtl'}
this.direction = 'ltr';

if ( !this.svgElement ) {
const text = document.createElementNS( svgns, 'text' );

Expand Down Expand Up @@ -94,7 +97,44 @@ class TextSVGDrawable extends TextStatefulDrawable( SVGSelfDrawable ) {

// update the text-node's value
if ( this.dirtyText ) {
text.lastChild.nodeValue = Utils.safariEmbeddingMarkWorkaround( this.node.renderedText );
let string = Utils.safariEmbeddingMarkWorkaround( this.node.renderedText );

// Workaround for Firefox handling of RTL embedding marks, https://github.com/phetsims/scenery/issues/1643
// We strip off outer containing embedding marks, and adjust the direction and text-anchor accordingly to match
// our normal behavior.
if ( platform.firefox ) {
let direction = 'ltr';

// While our string is long enough AND the last character is a POP embedding mark
while ( string.length > 2 && string[ string.length - 1 ] === '\u202c' ) {
const isLTR = string[ 0 ] === '\u202a';
const isRTL = string[ 0 ] === '\u202b';

if ( isLTR ) {
direction = 'ltr';
}
else if ( isRTL ) {
direction = 'rtl';
}
else {
break;
}

// Strip off the outer embedding marks
string = string.slice( 1, -1 );
}

if ( this.direction !== direction ) {
this.direction = direction;

text.setAttribute( 'direction', direction );

// To maintain the same positioning, we need to adjust the text-anchor
text.setAttribute( 'text-anchor', direction === 'rtl' ? 'end' : 'start' );
}
}

text.lastChild.nodeValue = string;
}

// text length correction, tested with scenery/tests/text-quality-test.html to determine how to match Canvas/SVG rendering (and overall length)
Expand Down

0 comments on commit 359abce

Please sign in to comment.