Skip to content

Commit

Permalink
feat: better support for rtl languages
Browse files Browse the repository at this point in the history
  • Loading branch information
stepan662 committed Jan 31, 2024
1 parent 5afe889 commit 478213a
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
79 changes: 79 additions & 0 deletions src/parser/htmlIsolatesPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {
EditorView,
Direction,
ViewPlugin,
ViewUpdate,
Decoration,
DecorationSet,
} from "@codemirror/view";
import { Prec } from "@codemirror/state";
import { syntaxTree } from "@codemirror/language";
import { Tree } from "@lezer/common";
import { RangeSetBuilder } from "@codemirror/state";

export const htmlIsolatesPlugin = ViewPlugin.fromClass(
class {
isolates: DecorationSet;
tree: Tree;

constructor(view: EditorView) {
this.isolates = computeIsolates(view);
this.tree = syntaxTree(view.state);
}

update(update: ViewUpdate) {
if (
update.docChanged ||
update.viewportChanged ||
syntaxTree(update.state) != this.tree
) {
this.isolates = computeIsolates(update.view);
this.tree = syntaxTree(update.state);
}
}
},
{
provide: (plugin) => {
function access(view: EditorView) {
return view.plugin(plugin)?.isolates ?? Decoration.none;
}
return Prec.lowest([
EditorView.decorations.of(access),
EditorView.bidiIsolatedRanges.of(access),
]);
},
}
);

const isolateLTR = Decoration.mark({
attributes: { style: "direction: ltr; unicode-bidi: isolate" },
bidiIsolate: Direction.LTR,
});

const isolateRTL = Decoration.mark({
attributes: { style: "direction: rtl; unicode-bidi: isolate" },
bidiIsolate: Direction.RTL,
});

function computeIsolates(view: EditorView) {
const set = new RangeSetBuilder<Decoration>();
for (const { from, to } of view.visibleRanges) {
syntaxTree(view.state).iterate({
from,
to,
enter(node) {
if (
node.name === "HtmlTagOpen" ||
node.name === "HtmlTagClose" ||
node.name === "Expression"
) {
set.add(node.from, node.to, isolateLTR);
}
if (node.name === "TextRoot" || node.name === "Text") {
set.add(node.from, node.to, isolateRTL);
}
},
});
}
return set.finish();
}
8 changes: 8 additions & 0 deletions src/parser/tolgeeTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ export const tolgeeThemeBase = EditorView.baseTheme({
borderRadius: "0px 12px 12px 0px",
paddingLeft: "8px",
},

'*[dir="rtl"] .placeholder-widget': {
transform: "scaleX(-1)",
},

'*[dir="rtl"] .placeholder-widget > *': {
transform: "scaleX(-1)",
},
});

export const tolgeeThemeDark = EditorView.theme({
Expand Down
1 change: 1 addition & 0 deletions src/tolgee-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export { tolgeeSyntax } from "./parser/tolgeeSyntax";
export { getTolgeePlurals } from "./parser/getTolgeePlurals";
export { tolgeeThemeDark, tolgeeThemeBase } from "./parser/tolgeeTheme";
export { tolgeeHighlight } from "./parser/tolgeeHighlight";
export { htmlIsolatesPlugin } from "./parser/htmlIsolatesPlugin";
export * from "./parser/types";

0 comments on commit 478213a

Please sign in to comment.