FEATURE: Use browser dir="auto" for support_mixed_text_direction (#26129)

* FEATURE: Use browser `dir="auto"` for support_mixed_text_direction

Previously we were using regex to parse all sorts of user input and guess the direction. All out target browsers now support this behavior out-the-box using `dir=auto`, which should be significantly faster.

https://meta.discourse.org/t/dir-auto-for-composer-and-elsewhere/276330

* test

* Update app/assets/javascripts/discourse/tests/integration/components/text-field-test.js

Co-authored-by: Jarek Radosz <jradosz@gmail.com>

---------

Co-authored-by: Jarek Radosz <jradosz@gmail.com>
This commit is contained in:
David Taylor 2024-03-13 01:47:39 +00:00 committed by GitHub
parent 111042e575
commit e5020617c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 27 additions and 67 deletions

View File

@ -1,6 +1,5 @@
import { TextField } from "@ember/legacy-built-in-components";
import { cancel, next } from "@ember/runloop";
import { isLTR, isRTL, siteDir } from "discourse/lib/text-direction";
import discourseDebounce from "discourse-common/lib/debounce";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
@ -55,14 +54,7 @@ export default TextField.extend({
get dir() {
if (this.siteSettings.support_mixed_text_direction) {
const val = this.get("value");
if (val && isRTL(val)) {
return "rtl";
} else if (val && isLTR(val)) {
return "ltr";
} else {
return siteDir();
}
return "auto";
}
},

View File

@ -1,7 +1,6 @@
import { get } from "@ember/object";
import { htmlSafe } from "@ember/template";
import categoryVariables from "discourse/helpers/category-variables";
import { isRTL } from "discourse/lib/text-direction";
import { escapeExpression } from "discourse/lib/utilities";
import Category from "discourse/models/category";
import getURL from "discourse-common/lib/get-url";
@ -150,7 +149,7 @@ export function defaultCategoryLinkRenderer(category, opts) {
let categoryName = escapeExpression(get(category, "name"));
if (siteSettings.support_mixed_text_direction) {
categoryDir = isRTL(categoryName) ? 'dir="rtl"' : 'dir="ltr"';
categoryDir = 'dir="auto"';
}
if (restricted) {

View File

@ -1,16 +1,12 @@
import { htmlSafe } from "@ember/template";
import { isRTL } from "discourse/lib/text-direction";
import { escapeExpression } from "discourse/lib/utilities";
import { helperContext, registerRawHelper } from "discourse-common/lib/helpers";
function setDir(text) {
let content = text ? text : "";
let siteSettings = helperContext().siteSettings;
if (content && siteSettings.support_mixed_text_direction) {
let textDir = isRTL(content) ? "rtl" : "ltr";
return `<span dir="${textDir}">${content}</span>`;
}
return content;
const mixed = siteSettings.support_mixed_text_direction;
return `<span ${mixed ? 'dir="auto"' : ""}>${content}</span>`;
}
registerRawHelper("dir-span", dirSpan);

View File

@ -19,7 +19,7 @@ export function setTextDirections(elem) {
if (e.tagName === "ASIDE" && e.classList.contains("quote")) {
setTextDirectionsForQuote(e);
} else {
e.setAttribute("dir", isRTL(e.textContent) ? "rtl" : "ltr");
e.setAttribute("dir", "auto");
}
}
}
@ -43,9 +43,6 @@ function setTextDirectionsForQuote(quoteElem) {
titleElem.setAttribute("dir", siteDir());
}
for (let quoteParagraphElem of quoteElem.querySelectorAll("blockquote > p")) {
quoteParagraphElem.setAttribute(
"dir",
isRTL(quoteParagraphElem.textContent) ? "rtl" : "ltr"
);
quoteParagraphElem.setAttribute("dir", "auto");
}
}

View File

@ -1,6 +1,5 @@
import { censor } from "pretty-text/censored-words";
import { emojiUnescape } from "discourse/lib/text";
import { isRTL } from "discourse/lib/text-direction";
import Site from "discourse/models/site";
export function fancyTitle(topicTitle, supportMixedTextDirection) {
@ -10,8 +9,7 @@ export function fancyTitle(topicTitle, supportMixedTextDirection) {
);
if (supportMixedTextDirection) {
const titleDir = isRTL(title) ? "rtl" : "ltr";
return `<span dir="${titleDir}">${title}</span>`;
return `<span dir="auto">${title}</span>`;
}
return title;

View File

@ -24,34 +24,12 @@ module("Integration | Component | text-field", function (hooks) {
assert.strictEqual(query("input").placeholder, "placeholder.i18n.key");
});
test("sets the dir attribute to ltr for Hebrew text", async function (assert) {
test("sets the dir attribute to auto when mixed text direction enabled", async function (assert) {
this.siteSettings.support_mixed_text_direction = true;
await render(hbs`<TextField @value="זהו שם עברי עם מקום עברי" />`);
assert.strictEqual(query("input").getAttribute("dir"), "rtl");
});
test("sets the dir attribute to ltr for English text", async function (assert) {
this.siteSettings.support_mixed_text_direction = true;
await render(hbs`<TextField @value="This is a ltr title" />`);
assert.strictEqual(query("input").getAttribute("dir"), "ltr");
});
test("updates the dir attribute when value changes", async function (assert) {
this.siteSettings.support_mixed_text_direction = true;
await render(
hbs`<TextField id="mytextfield" @value="This is a ltr title" />`
);
assert.strictEqual(query("input").getAttribute("dir"), "ltr");
await fillIn("#mytextfield", "זהו שם עברי עם מקום עברי");
assert.strictEqual(query("input").getAttribute("dir"), "rtl");
assert.dom("input").hasAttribute("dir", "auto");
});
test("supports onChange", async function (assert) {

View File

@ -110,11 +110,11 @@ module("Unit | Utility | category-badge", function (hooks) {
let tag = $.parseHTML(categoryBadgeHTML(rtlCategory))[0];
let dirSpan = tag.children[0].children[0];
assert.strictEqual(dirSpan.dir, "rtl");
assert.strictEqual(dirSpan.dir, "auto");
tag = $.parseHTML(categoryBadgeHTML(ltrCategory))[0];
dirSpan = tag.children[0].children[0];
assert.strictEqual(dirSpan.dir, "ltr");
assert.strictEqual(dirSpan.dir, "auto");
});
test("recursive", function (assert) {

View File

@ -87,38 +87,38 @@ module("Unit | Utility | text-direction", function (hooks) {
assertDirection(
assert,
quotedRtl,
"rtl",
"RTL paragraphs inside quote have rtl dir"
"auto",
"RTL paragraphs inside quote have auto dir"
);
assertDirection(
assert,
quotedLtr,
"ltr",
"LTR paragraphs inside quote have ltr dir"
"auto",
"LTR paragraphs inside quote have auto dir"
);
assertDirection(
assert,
quotedLtrNested,
"ltr",
"LTR paragraphs inside nested quote have ltr dir"
"auto",
"LTR paragraphs inside nested quote have auto dir"
);
assertDirection(
assert,
quotedRtlNested,
"rtl",
"RTL paragraphs inside nested quote have rtl dir"
"auto",
"RTL paragraphs inside nested quote have auto dir"
);
assertDirection(
assert,
notQuotedLtr,
"ltr",
"LTR paragraphs outside quotes have ltr dir"
"auto",
"LTR paragraphs outside quotes have auto dir"
);
assertDirection(
assert,
notQuotedRtl,
"rtl",
"RTL paragraphs outside quotes have rtl dir"
"auto",
"RTL paragraphs outside quotes have auto dir"
);
});
});

View File

@ -209,13 +209,13 @@ module("Unit | Model | topic", function (hooks) {
assert.strictEqual(
rtlTopic.fancyTitle,
`<span dir="rtl">هذا اختبار</span>`,
"sets the dir-span to rtl"
`<span dir="auto">هذا اختبار</span>`,
"sets the dir-span to auto"
);
assert.strictEqual(
ltrTopic.fancyTitle,
`<span dir="ltr">This is a test</span>`,
"sets the dir-span to ltr"
`<span dir="auto">This is a test</span>`,
"sets the dir-span to auto"
);
});