@@ -321,7 +351,7 @@
-
+
@@ -344,7 +374,7 @@
@mouseover="state.showTagsEditBtn = true"
@mouseleave="state.showTagsEditBtn = false">
-
+
{{ t('common.page.tags') }}
-
+
{{ t('common.page.ratePage') }}
@@ -432,7 +462,7 @@
-
+
{{ t('common.page.lastEditedBy') }}
@@ -444,7 +474,7 @@
alt="" />
{{ lastEditorInitial }}
- {{ pageStore.authorName }}
+ {{ pageStore.authorName }}
@@ -691,14 +721,34 @@ const tocPanelIsOpen = computed(() => tocIsPanel.value && showSidebar.value && s
const showTocPanelBtn = computed(() => tocIsPanel.value && showSidebar.value && !state.tocPanelOpen)
/*
- Whether the contents rail runs out to meet the article column's right-hand edge (`.page-article-col`),
- which is only beside it while the contents are a column to the RIGHT of the article. On the left the
- edge is on the article's far side, and the panel has a shadow rather than an edge to meet.
+ Whether the contents are a column to the LEFT of the article, which is what moves the article
+ column's edge (`.page-article-col`) over to that side: the edge is drawn against the contents, and
+ with the contents on the left the right-hand side of the article is the actions rail.
+
+ Only while there is such a column. With nothing to show in it, or below 750px where it is a panel
+ over the article instead, what is on the left is the nav sidebar or the window, and the edge stays on
+ the right against the rail.
*/
-const tocJoinsArticleEdge = computed(
- () => !tocIsPanel.value && siteStore.theme.tocPosition !== 'left'
+const tocColumnIsLeft = computed(
+ () => showSidebar.value && !tocIsPanel.value && siteStore.theme.tocPosition === 'left'
)
+/*
+ Whether the contents rail runs out to meet the article column's edge -- which is only beside it while
+ the contents are a column, and the panel has a shadow rather than an edge to meet.
+
+ The rail is on the side the labels start from, so it meets the edge only where that is the side facing
+ the article: a column on the right read left to right, or one on the left read right to left. In the
+ other two the rail is on the column's far side and there is nothing for it to turn out and meet.
+*/
+const tocJoinsArticleEdge = computed(() => {
+ if (tocIsPanel.value) {
+ return false
+ }
+ const isRtl = siteStore.localeDir(pageStore.locale) === 'rtl'
+ return siteStore.theme.tocPosition === 'left' ? isRtl : !isRtl
+})
+
/**
* Whether the page on screen is a blog's front page, which is drawn as its posts rather than as an
* article -- see `PageBlog.vue`. A blog POST is an ordinary page and is not this.
@@ -953,8 +1003,9 @@ const relationsRight = computed(() => {
})
const lastModified = computed(() => {
return pageStore.updatedAt
- ? // -> The fields luxon's DATETIME_MED expanded to, so the bar reads exactly as before
- Temporal.Instant.from(pageStore.updatedAt).toLocaleString(undefined, {
+ ? // -> The fields luxon's DATETIME_MED expanded to, so the bar reads exactly as before -- and in
+ // the interface's language, since it is set inside a sentence written in it
+ Temporal.Instant.from(pageStore.updatedAt).toLocaleString(locale.value, {
year: 'numeric',
month: 'short',
day: 'numeric',
@@ -964,15 +1015,20 @@ const lastModified = computed(() => {
: 'N/A'
})
-/**
- * The trail the breadcrumb bar draws, root first. The Home crumb is prepended here rather than
- * written into the markup, so the bar takes a single flat list.
- */
/** The blog this page is a post of, as a route on this site. Null-safe: the line is `v-if`'d on it. */
const blogHref = computed(
() => `${siteStore.localeUrlPrefix(pageStore.locale)}/${pageStore.blog?.path ?? ''}`
)
+/** The chevron between two crumbs points down the trail, which right to left is to the left. */
+const crumbSeparator = computed(() =>
+ siteStore.localeDir(commonStore.locale) === 'rtl' ? 'la:angle-left' : 'la:angle-right'
+)
+
+/**
+ * The trail the breadcrumb bar draws, root first. The Home crumb is prepended here rather than
+ * written into the markup, so the bar takes a single flat list.
+ */
const breadcrumbs = computed(() => [
{ key: 'home', icon: 'la:home', to: '/', ariaLabel: 'Home', tooltip: 'Home' },
...pageStore.breadcrumbs.map((brd) => ({
diff --git a/frontend/src/pages/PageVersion.vue b/frontend/src/pages/PageVersion.vue
index 7a5ad49c1..f19c8e30d 100644
--- a/frontend/src/pages/PageVersion.vue
+++ b/frontend/src/pages/PageVersion.vue
@@ -88,6 +88,8 @@
diff --git a/frontend/src/stores/site.js b/frontend/src/stores/site.js
index fe4fd2f81..48ac82a2e 100644
--- a/frontend/src/stores/site.js
+++ b/frontend/src/stores/site.js
@@ -208,6 +208,15 @@ export const useSiteStore = defineStore('site', {
/** How a locale is referred to — `fr` for `fr-FR` — falling back to the code until read. */
localeAlias: (state) => (code) =>
state.installedLocales.find((lc) => lc.code === code)?.displayCode ?? code,
+ /**
+ * The `dir` a locale's text is written in, for the elements that hold a page's own content.
+ *
+ * Asked of the PAGE's locale, not of the interface's: an Arabic page on a wiki read in English is
+ * still read right to left, while the chrome around it stays the way the interface language runs.
+ * A locale the wiki does not have installed reads as `ltr`, since nothing says otherwise.
+ */
+ localeDir: (state) => (code) =>
+ state.installedLocales.find((lc) => lc.code === code)?.isRTL ? 'rtl' : 'ltr',
/**
* The segments a locale-prefixed URL may start with, mapped to the locale each names.
*