How to set directionality on spans of text

We’re starting to use CM6 in Pontoon, Mozilla’s localization system. In this context, we need to deal with some pretty deep bidirectionality, for example localized messages that as a whole are right-to-left, but may include HTML elements using a Latin left-to-right script, which may have attributes with localized right-to-left values, but then include left-to-right placeholders. All of this on a single line, of course.

I’ve been able to make this work for the presentation by using a parser that understands about elements, quoted attribute values and placeholders, and a small stack of decorator plugins so that I can get the right prioritised nesting of marks to result in the desired <span dir=...> wrappers, but this doesn’t seem to work quite right for left/right arrow navigation, which is now appears broken near directionality boundaries where weakly directional characters are often assigned the wrong direction.

From inspecting the code, enabling perLineTextDirection appears to mean that the overall direction is set by the direction of the <div class="cm-line">, and then an inspection of the text characters results in a set of directional spans that determine the current mapping of left/right to forward/backward.

So there’s a mismatch here that I think needs solving, and I’m not sure exactly what would be the best way to do so. There are at least three options that I see as possible:

  1. Somehow allow for the DocView.p.textDirectionAt(pos) to look at the lowest-level <span> for pos and use its directionality rather than rely on the direction of the line + text bidi spans.
  2. Rather than assigning dir="ltr" and similar mark decorators to spans, insert corresponding directional isolate characters in the text that the view is rendering, based on the syntax parse results.
  3. Write a custom left/right arrow key handler that just looks at the DOM to pick which way is forward and back.

Any suggestions on which way we should go?

1 Like

See this thread. I don’t think it’s necessary to insert directionality characters—you can just use CSS unicode-bidi styles. But at the moment the editor’s bidi algorithm won’t know about this (it doesn’t query the dom for the direction at every single span—that’d be really annoying and expensive).

So the proposal in that thread is to add a mechanism to feed information about bidi isolates to the algorithm that computes the text order, somehow. I have taken a stab at it but it requires some serious complication of code that needs to be fast, and I haven’t found the time to finish it yet.

My current pain point is indeed the mismatch in bidi spans, i.e. that the algorithm isn’t taking into account the DOM directionality. Could you clarify which part of querying DOM would make it “annoying and expensive”, given that DocView.textDirectionAt‎() is already calling getComputedStyle() to do so for the line?

Tbh, I am quite tempted to try feeding in LRI/RLI/FSI/PDI isolate characters into the text, as that might solve both our presentation and navigation issues with a single solution.

See the other thread for an update on this.