i18n: add RTL support for nav bar and child items #470

This commit is contained in:
Sören Weber 2023-02-09 00:53:11 +01:00
parent ba09924026
commit 381b74f837
No known key found for this signature in database
GPG key ID: BEC6D55545451B6D
5 changed files with 98 additions and 32 deletions

View file

@ -18,6 +18,12 @@ This document shows you what's new in the latest release. For a detailed list of
--- ---
## 5.12.0 (not yet released)
- {{% badge style="info" icon="plus-circle" title=" " %}}New{{% /badge %}} Support for languages that are written right to left (like Arabic) is expanded to the top navigation bar. This feature is not available in Internet Explorer 11.
---
## 5.11.0 (2023-02-07) ## 5.11.0 (2023-02-07)
- {{% badge style="note" title=" " %}}Change{{% /badge %}} The theme removed the popular [jQuery](https://jquery.com) library from its distribution. - {{% badge style="note" title=" " %}}Change{{% /badge %}} The theme removed the popular [jQuery](https://jquery.com) library from its distribution.

View file

@ -56,7 +56,7 @@
<div id="body" class="default-animation"> <div id="body" class="default-animation">
<div id="sidebar-overlay"></div> <div id="sidebar-overlay"></div>
<div id="toc-overlay"></div> <div id="toc-overlay"></div>
<nav id="topbar" class="highlightable" dir="ltr"> <nav id="topbar" class="highlightable">
<div> <div>
{{- $File := .File }} {{- $File := .File }}
{{- $Site := .Site }} {{- $Site := .Site }}
@ -67,12 +67,18 @@
{{- if $parent }} {{- if $parent }}
{{- $ispublished = gt (int (len $parent.Permalink)) 0 }} {{- $ispublished = gt (int (len $parent.Permalink)) 0 }}
{{- end }} {{- end }}
{{- $startarrow := "&#129104;" }}
{{- $endarrow := "&#129106;" }}
{{- if eq (T "Reading-direction" | default "ltr") "rtl" }}
{{- $startarrow = "&#129106;" }}
{{- $endarrow = "&#129104;" }}
{{- end }}
<div class="navigation"> <div class="navigation">
{{- if or (ne $outputFormat "html") (not (and $ispublished ($.Scratch.Get "relearnNextPage"))) }} {{- if or (ne $outputFormat "html") (not (and $ispublished ($.Scratch.Get "relearnNextPage"))) }}
<span class="nav nav-next topbar-link"><i class="fa fa-chevron-right fa-fw"></i></span> <span class="nav nav-next topbar-link"><i class="fa fa-chevron-right fa-fw"></i></span>
{{- else }} {{- else }}
{{- with ($.Scratch.Get "relearnNextPage") }} {{- with ($.Scratch.Get "relearnNextPage") }}
<a class="nav nav-next topbar-link" href="{{ partial "relLangPrettyUglyURL.hugo" (dict "to" .) }}" title="{{.Title}} (&#129106;)"><i class="fas fa-chevron-right fa-fw"></i></a> <a class="nav nav-next topbar-link" href="{{ partial "relLangPrettyUglyURL.hugo" (dict "to" .) }}" title="{{.Title}} ({{ $endarrow | safeHTML }})"><i class="fas fa-chevron-right fa-fw"></i></a>
{{- end }} {{- end }}
{{- end }} {{- end }}
</div> </div>
@ -81,11 +87,11 @@
<span class="nav nav-prev topbar-link"><i class="fa fa-chevron-left fa-fw"></i></span> <span class="nav nav-prev topbar-link"><i class="fa fa-chevron-left fa-fw"></i></span>
{{- else if or (ne $outputFormat "html") (eq .Page.Kind "taxonomy") (eq .Page.Kind "term") (not (and $ispublished ($.Scratch.Get "relearnPrevPage"))) }} {{- else if or (ne $outputFormat "html") (eq .Page.Kind "taxonomy") (eq .Page.Kind "term") (not (and $ispublished ($.Scratch.Get "relearnPrevPage"))) }}
{{- with .Site.Home }} {{- with .Site.Home }}
<a class="nav nav-prev topbar-link" href="{{ partial "relLangPrettyUglyURL.hugo" (dict "to" .) }}" title="{{.Title}} (&#129104;)"><i class="fas fa-chevron-left fa-fw"></i></a> <a class="nav nav-prev topbar-link" href="{{ partial "relLangPrettyUglyURL.hugo" (dict "to" .) }}" title="{{.Title}} ({{ $startarrow | safeHTML }})"><i class="fas fa-chevron-left fa-fw"></i></a>
{{- end }} {{- end }}
{{- else }} {{- else }}
{{- with ($.Scratch.Get "relearnPrevPage") }} {{- with ($.Scratch.Get "relearnPrevPage") }}
<a class="nav nav-prev topbar-link" href="{{ partial "relLangPrettyUglyURL.hugo" (dict "to" .) }}" title="{{.Title}} (&#129104;)"><i class="fas fa-chevron-left fa-fw"></i></a> <a class="nav nav-prev topbar-link" href="{{ partial "relLangPrettyUglyURL.hugo" (dict "to" .) }}" title="{{.Title}} ({{ $startarrow | safeHTML }})"><i class="fas fa-chevron-left fa-fw"></i></a>
{{- end}} {{- end}}
{{- end}} {{- end}}
</div> </div>

View file

@ -1,5 +1,19 @@
@media all and (-ms-high-contrast:none) { @media all and (-ms-high-contrast:none) {
/* turn off LTR support as it is dependend on CSS properties that aren't supported by IE11 */ /* turn off LTR support as it is dependend on CSS properties that aren't supported by IE11 */
html[dir="rtl"] #body #breadcrumbs {
float: left;
}
html[dir="rtl"] .navigation,
html[dir="rtl"] #top-print-link,
html[dir="rtl"] #top-github-link {
float: right;
}
html[dir="rtl"] .nav i{
transform: scaleX(1);
}
html[dir="rtl"] .progress {
left: 4.25rem;
}
article, article,
.toc-wrapper, .toc-wrapper,
.tags { .tags {

View file

@ -843,6 +843,11 @@ td {
display: block; display: block;
float: right; float: right;
} }
html[dir="rtl"] .navigation,
html[dir="rtl"] #top-print-link,
html[dir="rtl"] #top-github-link {
float: left;
}
.nav, .nav,
.print-link, .print-link,
@ -851,6 +856,9 @@ td {
padding-left: 1rem; padding-left: 1rem;
padding-right: 1rem; padding-right: 1rem;
} }
html[dir="rtl"] .nav i{
transform: scaleX(-1);
}
span.nav i{ span.nav i{
color: rgba( 134, 134, 134, .333 ); color: rgba( 134, 134, 134, .333 );
} }
@ -887,6 +895,9 @@ span.nav i{
white-space: nowrap; white-space: nowrap;
width: calc(100% - 5*3.25rem); width: calc(100% - 5*3.25rem);
} }
html[dir="rtl"] #body #breadcrumbs {
float: right;
}
@media screen and (max-width: 47.938em) { @media screen and (max-width: 47.938em) {
#body #breadcrumbs { #body #breadcrumbs {
text-overflow: unset; text-overflow: unset;
@ -897,16 +908,24 @@ span.nav i{
display: none; display: none;
} }
.progress { .progress {
left: 1rem;
top: 1rem; top: 1rem;
} }
html[dir="ltr"] .progress {
left: 1rem;
}
html[dir="rtl"] .progress {
right: 1rem;
}
@media screen and (max-width: 47.938em) { @media screen and (max-width: 47.938em) {
.mobile-support #sidebar-toggle-span { .mobile-support #sidebar-toggle-span {
display: inline; display: inline;
} }
.progress { html[dir="ltr"] .progress {
left: 4.25rem; left: 4.25rem;
} }
html[dir="rtl"] .progress {
right: 4.25rem;
}
} }
#body #breadcrumbs .links { #body #breadcrumbs .links {
@ -1750,3 +1769,7 @@ article ul li input[type="checkbox"]:checked::before {
overflow: auto; overflow: auto;
padding: min(2vh, 2vw); padding: min(2vh, 2vw);
} }
#TableOfContents{
min-width: 1px;
}

View file

@ -11,6 +11,20 @@ else{
} }
var isPrint = document.querySelector( 'body' ).classList.contains( 'print' ); var isPrint = document.querySelector( 'body' ).classList.contains( 'print' );
var isRtl = document.querySelector( 'html' ).getAttribute( 'dir' ) == 'rtl';
var dir_padding_start = 'padding-left';
var dir_padding_end = 'padding-right';
var dir_key_start = 37;
var dir_key_end = 39;
var dir_scroll = 1;
if( isRtl && !isIE ){
dir_padding_start = 'padding-right';
dir_padding_end = 'padding-left';
dir_key_start = 39;
dir_key_end = 37;
dir_scroll = -1;
}
var touchsupport = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0) var touchsupport = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)
var formelements = 'button, datalist, fieldset, input, label, legend, meter, optgroup, option, output, progress, select, textarea'; var formelements = 'button, datalist, fieldset, input, label, legend, meter, optgroup, option, output, progress, select, textarea';
@ -26,7 +40,7 @@ var pst;
var elc = document.querySelector('#body-inner'); var elc = document.querySelector('#body-inner');
function documentFocus(){ function documentFocus(){
document.querySelector( '#body-inner' ).focus(); elc.focus();
psc && psc.scrollbarY.focus(); psc && psc.scrollbarY.focus();
} }
@ -45,13 +59,13 @@ function scrollbarWidth(){
var scrollbarSize = scrollbarWidth(); var scrollbarSize = scrollbarWidth();
function adjustContentWidth(){ function adjustContentWidth(){
var left = parseFloat( getComputedStyle( elc ).getPropertyValue( 'padding-left' ) ); var start = parseFloat( getComputedStyle( elc ).getPropertyValue( dir_padding_start ) );
var right = left; var end = start;
if( elc.scrollHeight > elc.clientHeight ){ if( elc.scrollHeight > elc.clientHeight ){
// if we have a scrollbar reduce the right margin by the scrollbar width // if we have a scrollbar reduce the end margin by the scrollbar width
right = Math.max( 0, left - scrollbarSize ); end = Math.max( 0, start - scrollbarSize );
} }
elc.style[ 'padding-right' ] = '' + right + 'px'; elc.style[ dir_padding_end ] = '' + end + 'px';
} }
function switchTab(tabGroup, tabId) { function switchTab(tabGroup, tabId) {
@ -416,41 +430,41 @@ function initArrowNav(){
// avoid prev/next navigation if we are not at the start/end of the // avoid prev/next navigation if we are not at the start/end of the
// horizontal area // horizontal area
var el = document.querySelector('#body-inner'); var el = document.querySelector('#body-inner');
var scrollLeft = 0; var scrollStart = 0;
var scrollRight = 0; var scrollEnd = 0;
document.addEventListener('keydown', function(event){ document.addEventListener('keydown', function(event){
if( !event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey ){ if( !event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey ){
if( event.which == '37' ){ if( event.which == dir_key_start ){
if( !scrollLeft && +el.scrollLeft.toFixed() <= 0 ){ if( !scrollStart && +el.scrollLeft.toFixed()*dir_scroll <= 0 ){
prev && prev.click(); prev && prev.click();
} }
else if( scrollLeft != -1 ){ else if( scrollStart != -1 ){
clearTimeout( scrollLeft ); clearTimeout( scrollStart );
} }
scrollLeft = -1; scrollStart = -1;
} }
if( event.which == '39' ){ if( event.which == dir_key_end ){
if( !scrollRight && +el.scrollLeft.toFixed() + +el.clientWidth.toFixed() >= +el.scrollWidth.toFixed() ){ if( !scrollEnd && +el.scrollLeft.toFixed()*dir_scroll + +el.clientWidth.toFixed() >= +el.scrollWidth.toFixed() ){
next && next.click(); next && next.click();
} }
else if( scrollRight != -1 ){ else if( scrollEnd != -1 ){
clearTimeout( scrollRight ); clearTimeout( scrollEnd );
} }
scrollRight = -1; scrollEnd = -1;
} }
} }
}); });
document.addEventListener('keyup', function(event){ document.addEventListener('keyup', function(event){
if( !event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey ){ if( !event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey ){
if( event.which == '37' ){ if( event.which == dir_key_start ){
// check for false indication if keyup is delayed after navigation // check for false indication if keyup is delayed after navigation
if( scrollLeft == -1 ){ if( scrollStart == -1 ){
scrollLeft = setTimeout( function(){ scrollLeft = 0; }, 300 ); scrollStart = setTimeout( function(){ scrollStart = 0; }, 300 );
} }
} }
if( event.which == '39' ){ if( event.which == dir_key_end ){
if( scrollRight == -1 ){ if( scrollEnd == -1 ){
scrollRight = setTimeout( function(){ scrollRight = 0; }, 300 ); scrollEnd = setTimeout( function(){ scrollEnd = 0; }, 300 );
} }
} }
} }
@ -459,7 +473,7 @@ function initArrowNav(){
// avoid keyboard navigation for input fields // avoid keyboard navigation for input fields
document.querySelectorAll( formelements ).forEach( function( e ){ document.querySelectorAll( formelements ).forEach( function( e ){
e.addEventListener( 'keydown', function( event ){ e.addEventListener( 'keydown', function( event ){
if( event.which == 37 || event.which == 39 ){ if( event.which == dir_key_start || event.which == dir_key_end ){
event.stopPropagation(); event.stopPropagation();
} }
}); });
@ -545,8 +559,11 @@ function initMenuScrollbar(){
psm && psm.update(); psm && psm.update();
}); });
}); });
// bugfix for PS in RTL mode: the initial scrollbar position is off;
// calling update() once, fixes this
pst && setTimeout( function(){ pst.update(); }, 0 );
// finally, we want to adjust the contents right padding if there is a scrollbar visible // finally, we want to adjust the contents end padding if there is a scrollbar visible
window.addEventListener('resize', adjustContentWidth ); window.addEventListener('resize', adjustContentWidth );
adjustContentWidth(); adjustContentWidth();
} }