Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/static/js/ace2_inner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,11 @@ function Ace2Inner(editorInfo, cssManagers) {
rtlistrue: (value) => {
targetBody.classList.toggle('rtl', value);
targetBody.classList.toggle('ltr', !value);
document.documentElement.dir = value ? 'rtl' : 'ltr';
// Apply the base direction to the inner editor document only. Using the
// top-level `document` here would flip the whole page (toolbar, chrome)
// even though this is a per-pad content option — see issue #7900. The
// page direction is governed solely by the UI language (see l10n.ts).
targetDoc.documentElement.dir = value ? 'rtl' : 'ltr';
},
fadeinactiveauthorcolors: (value) => {
fadeInactiveAuthorColors = `${value}` !== 'false';
Expand Down
26 changes: 26 additions & 0 deletions src/tests/frontend-new/specs/rtl_url_param.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,30 @@ test.describe('RTL URL parameter', function () {
await page.waitForSelector('#editorcontainer.initialized');
await expect(page.locator('#options-rtlcheck')).not.toBeChecked();
});

test('rtl content option flips only the pad inner contents, not the whole page', {tag: '@feature:rtl-toggle'}, async function ({page}) {
// The top-level page direction is owned by the UI language, not the pad's
// RTL content option. Capture whatever the language chose so the assertion
// is locale-independent (it could legitimately be rtl on an RTL locale).
const html = page.locator('html');
await expect(html).toHaveAttribute('dir', /^(ltr|rtl)$/);
const initialPageDir = await html.getAttribute('dir');

await appendQueryParams(page, {rtl: 'true'});
await expect(page.locator('#options-rtlcheck')).toBeChecked();

// The inner editor document is flipped to RTL. Use a frameLocator chain so
// Playwright auto-waits for the nested iframes/body to be ready.
const innerBody = page
.frameLocator('iframe[name="ace_outer"]')
.frameLocator('iframe[name="ace_inner"]')
.locator('#innerdocbody');
await expect(innerBody).toHaveClass(/\brtl\b/);
await expect.poll(() => innerBody.evaluate((el) =>
el.ownerDocument.defaultView!.getComputedStyle(el).direction)).toBe('rtl');

// ...but the top-level page (toolbar, chrome) is unaffected: its dir is
// whatever the UI language set and must not change when the pad flips.
await expect(html).toHaveAttribute('dir', initialPageDir!);
});
});
Loading