Only a page we own gets its direction set
An RTL locale reflected onto document.documentElement whenever it
resolved — so a reader following a ?lang=ar link to a PARTNER'S page
flipped the partner's whole <html>: their headings, their nav, their
footer. The existing comment already worried about the host owning that
decision, but it only guarded against CLEARING dir, never against
setting it.
A generated leaf is the only thing that knows a document belongs to the
plugin, so it says so: window.MAP_OWNS_PAGE, written into all three leaf
templates. library/i18n reads it before touching the document. Nothing
else sets it, so the DEFAULT IS "not ours" — a partner page that
declares nothing is never touched. Absence has to mean restraint for a
flag like this.
The element's own direction was never this code's business: ProfileLoader
binds dir on .profile-loader from effectiveLocale (0f6d5049), so the
plugin mirrors correctly whether or not it owns the page.
★ THE OLD GATE COULD NOT HAVE SEEN THIS, which is why it needed a new
case rather than a re-run. check-embedded-rtl drove the locale through
profile-config — the channel a HOST uses. This defect fires on the URL
channel, which is what a READER uses, and detectLocale() reads the URL
FIRST. Added a ?lang=ar case on the partner page:
before profile-config cases partner html unset / body ltr pass
?lang=ar partner html RTL / body RTL FAIL
after ?lang=ar partner html unset / body ltr pass
plugin root stays rtl throughout — it still mirrors
Standalone leaves are unchanged and verified: ownsPage true, html
dir="rtl", plugin root rtl. The page we own still mirrors completely.
This commit is contained in:
parent
d2a643d0aa
commit
57bf76422f
2 changed files with 33 additions and 1 deletions
|
|
@ -613,6 +613,12 @@ function forgeHtml(o) {
|
|||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<!-- THIS PAGE IS OURS. The only thing that knows a document belongs to the plugin is the page
|
||||
the generator writes, so it says so here. library/i18n reads it before reflecting an RTL
|
||||
locale on <html dir>; nothing else sets it, so a PARTNER page defaults to "not ours" and
|
||||
is never touched. Absence must mean restraint — an embedded plugin flipping a partner's
|
||||
whole <html> because a reader followed a ?lang=ar link is the bug this prevents. -->
|
||||
<script>window.MAP_OWNS_PAGE = true;</script>
|
||||
<title>${esc(o.title)}</title>
|
||||
<link rel="icon" href="data:,">
|
||||
<style>${FORGE_CSS}</style>
|
||||
|
|
@ -704,6 +710,12 @@ function studioRootHtml(bakedToken, integrity = '') {
|
|||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<!-- THIS PAGE IS OURS. The only thing that knows a document belongs to the plugin is the page
|
||||
the generator writes, so it says so here. library/i18n reads it before reflecting an RTL
|
||||
locale on <html dir>; nothing else sets it, so a PARTNER page defaults to "not ours" and
|
||||
is never touched. Absence must mean restraint — an embedded plugin flipping a partner's
|
||||
whole <html> because a reader followed a ?lang=ar link is the bug this prevents. -->
|
||||
<script>window.MAP_OWNS_PAGE = true;</script>
|
||||
<title>${esc(DISPLAY_TITLE)} plugin studio</title>
|
||||
<link rel="icon" href="data:,">
|
||||
${bakedToken ? ` <script>window.MAP_TOKEN=${JSON.stringify(bakedToken)};</script>\n` : ''}${DEST_CONFIG.apiBaseUrl ? ` <script>window.MAP_APP_API_URL = ${JSON.stringify(DEST_CONFIG.apiBaseUrl)};</script>\n` : ''} <style>
|
||||
|
|
@ -810,6 +822,12 @@ function mapPageHtml(opts) {
|
|||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<!-- THIS PAGE IS OURS. The only thing that knows a document belongs to the plugin is the page
|
||||
the generator writes, so it says so here. library/i18n reads it before reflecting an RTL
|
||||
locale on <html dir>; nothing else sets it, so a PARTNER page defaults to "not ours" and
|
||||
is never touched. Absence must mean restraint — an embedded plugin flipping a partner's
|
||||
whole <html> because a reader followed a ?lang=ar link is the bug this prevents. -->
|
||||
<script>window.MAP_OWNS_PAGE = true;</script>
|
||||
<title>${esc(title)}</title>
|
||||
<link rel="icon" href="data:,">
|
||||
${peerBlock}
|
||||
|
|
|
|||
|
|
@ -135,8 +135,22 @@ export function createAppI18n() {
|
|||
// Only ever SET it, never clear it: a host page that already declares dir (a
|
||||
// WordPress RTL theme) owns that decision, and stomping it to "ltr" for an
|
||||
// English map embedded in an Arabic page would break the page around us.
|
||||
// ★ ONLY WHERE WE OWN THE PAGE. This used to run whenever the locale resolved to an RTL
|
||||
// language, which meant an EMBEDDED plugin on a partner's page flipped the PARTNER'S whole
|
||||
// <html> — their headings, their nav, their footer — because a reader followed a ?lang=ar link.
|
||||
// The comment below already worried about the host owning that decision, but it only guarded
|
||||
// against CLEARING dir, never against setting it.
|
||||
//
|
||||
// A GENERATED LEAF owns its document and says so with window.MAP_OWNS_PAGE. Nothing else sets
|
||||
// it, so the DEFAULT IS "not ours" — a partner page that declares nothing is never touched,
|
||||
// which is the safe direction for a flag whose absence must mean restraint.
|
||||
//
|
||||
// The element's OWN direction is not this code's business and never was: ProfileLoader binds
|
||||
// dir on .profile-loader from effectiveLocale (0f6d5049), so the plugin mirrors correctly
|
||||
// whether or not it owns the document. This is only about the page around it.
|
||||
try {
|
||||
if (RTL_LOCALES.has(locale) && document?.documentElement) {
|
||||
const ownsPage = typeof window !== 'undefined' && window.MAP_OWNS_PAGE === true
|
||||
if (ownsPage && RTL_LOCALES.has(locale) && document?.documentElement) {
|
||||
document.documentElement.dir = 'rtl'
|
||||
}
|
||||
} catch { /* no document (SSR/tests) — nothing to reflect */ }
|
||||
|
|
|
|||
Loading…
Reference in a new issue