]> BookStack Code Mirror - bookstack/commitdiff
Updated styles to use logical properties/values 2003/head
authorDan Brown <redacted>
Sun, 5 Apr 2020 12:07:19 +0000 (13:07 +0100)
committerDan Brown <redacted>
Sun, 5 Apr 2020 12:07:19 +0000 (13:07 +0100)
- Intended to improve RTL support in the interface.
- Also adds hebrew to language dropdown since that was missing.

Related to #1794

21 files changed:
resources/js/components/dropdown.js
resources/lang/en/settings.php
resources/sass/_blocks.scss
resources/sass/_buttons.scss
resources/sass/_components.scss
resources/sass/_forms.scss
resources/sass/_header.scss
resources/sass/_layout.scss
resources/sass/_lists.scss
resources/sass/_mixins.scss
resources/sass/_pages.scss
resources/sass/_spacing.scss
resources/sass/_tables.scss
resources/sass/_text.scss
resources/sass/print-styles.scss
resources/sass/styles.scss
resources/views/auth/forms/login/saml2.blade.php
resources/views/auth/login.blade.php
resources/views/auth/register.blade.php
resources/views/base.blade.php
tests/LanguageTest.php

index 4de1e239b93b3747bd7474ad188d7684b62dfb9e..367c956ce3b7b757c28cefc6140c1ea19c794d35 100644 (file)
@@ -11,6 +11,7 @@ class DropDown {
         this.menu = elem.querySelector('.dropdown-menu, [dropdown-menu]');
         this.moveMenu = elem.hasAttribute('dropdown-move-menu');
         this.toggle = elem.querySelector('[dropdown-toggle]');
+        this.direction = (document.dir === 'rtl') ? 'right' : 'left';
         this.body = document.body;
         this.showing = false;
         this.setupListeners();
@@ -28,7 +29,11 @@ class DropDown {
             this.rect = this.menu.getBoundingClientRect();
             this.body.appendChild(this.menu);
             this.menu.style.position = 'fixed';
-            this.menu.style.left = `${this.rect.left}px`;
+            if (this.direction === 'right') {
+                this.menu.style.right = `${(this.rect.right - this.rect.width)}px`;
+            } else {
+                this.menu.style.left = `${this.rect.left}px`;
+            }
             this.menu.style.top = `${this.rect.top}px`;
             this.menu.style.width = `${this.rect.width}px`;
         }
@@ -67,7 +72,7 @@ class DropDown {
         this.toggle.setAttribute('aria-expanded', 'false');
         if (this.moveMenu) {
             this.menu.style.position = '';
-            this.menu.style.left = '';
+            this.menu.style[this.direction] = '';
             this.menu.style.top = '';
             this.menu.style.width = '';
             this.container.appendChild(this.menu);
index 35bb09cd40c3f87ec7d19372e4f73d6dfd1b3694..f1345c743b6dcc2bdfc7555774627195ebcd4109 100755 (executable)
@@ -192,6 +192,7 @@ return [
         'es' => 'Español',
         'es_AR' => 'Español Argentina',
         'fr' => 'Français',
+        'he' => 'עברית',
         'hu' => 'Magyar',
         'it' => 'Italian',
         'ja' => '日本語',
index ff344158f81c547c027ef55f8d370d529679e923..d02d25db4baa127018365b945ac1febe58381417 100644 (file)
@@ -3,7 +3,7 @@
  * Callouts
  */
 .callout {
-  border-left: 3px solid #BBB;
+  border-inline-start: 3px solid #BBB;
   background-color: #EEE;
   padding: $-s $-s $-s $-xl;
   display: block;
       background-color: #EEE;
     }
     .svg-icon {
-      margin-right: 0px;
+      margin-inline-end: 0px;
     }
   }
   > div .outline input {
 
 .content-wrap.card {
   padding: $-m $-xxl;
-  margin-left: auto;
-  margin-right: auto;
+  margin-inline-start: auto;
+  margin-inline-end: auto;
   margin-bottom: $-xl;
   overflow: initial;
   min-height: 60vh;
 .tag-item {
   display: inline-flex;
   margin-bottom: $-xs;
-  margin-right: $-xs;
+  margin-inline-end: $-xs;
   border-radius: 4px;
   border: 1px solid #CCC;
   overflow: hidden;
     fill: #888;
   }
   .tag-value {
-    border-left: 1px solid #DDD;
+    border-inline-start: 1px solid #DDD;
     background-color: rgba(255, 255, 255, 0.5);
   }
 }
index e3d9e17cad825beec15792dac617ce3914c45d9b..7df1d61a47668c1927f12eea2112f81eb4c015a8 100644 (file)
@@ -66,7 +66,7 @@ button {
 }
 
 .button + .button {
-  margin-left: $-s;
+  margin-inline-start: $-s;
 }
 
 .button.small {
@@ -99,26 +99,28 @@ button {
 
 .button.block {
   width: 100%;
-  text-align: left;
+  text-align: start;
   display: block;
 }
 
 .button.icon {
   .svg-icon {
-    margin-right: 0;
+    margin-inline-end: 0;
   }
 }
 
 .button.svg {
+  display: flex;
+  align-items: center;
+  padding: $-s $-m;
+  padding-bottom: ($-s - 2px);
   svg {
     display: inline-block;
-    position: absolute;
-    left: $-m;
-    top: $-s - 2px;
     width: 24px;
     height: 24px;
+    bottom: auto;
+    margin-inline-end: $-m;
   }
-  padding: $-s $-m ($-s - 2px) ($-m*2 + 24px);
 }
 
 .button[disabled] {
index 6ef53b7193d60825627fc194765d73eabb5e5499..f4ed45c2c9400dc6b6cd879dfc31dbb87f40b900 100644 (file)
@@ -7,7 +7,7 @@
   padding: $-m $-l;
   background-color: #FFF;
   border-radius: 4px;
-  border-left: 6px solid currentColor;
+  border-inline-start: 6px solid currentColor;
   box-shadow: $bs-large;
   z-index: 999999;
   cursor: pointer;
@@ -26,7 +26,7 @@
   svg {
     width: 2.8rem;
     height: 2.8rem;
-    padding-right: $-s;
+    padding-inline-end: $-s;
     fill: currentColor;
   }
   .dismiss {
@@ -63,7 +63,7 @@
   transition: all ease-in-out 180ms;
   user-select: none;
   svg[data-icon="caret-right"] {
-    margin-right: 0;
+    margin-inline-end: 0;
     font-size: 1rem;
     transition: all ease-in-out 180ms;
     transform: rotate(0deg);
@@ -73,7 +73,7 @@
     transform: rotate(90deg);
   }
   svg[data-icon="caret-right"] + * {
-    margin-left: $-xs;
+    margin-inline-start: $-xs;
   }
 }
 
@@ -243,7 +243,7 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
   width: 300px;
   overflow-y: auto;
   overflow-x: hidden;
-  border-left: 1px solid #DDD;
+  border-inline-start: 1px solid #DDD;
   .inner {
     padding: $-m;
   }
@@ -477,7 +477,7 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
   display: block;
   top: 50%;
   left: 50%;
-  margin-left: -27px;
+  margin-inline-start: -27px;
   margin-top: -35px;
 }
 
@@ -511,7 +511,7 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
   top: 50%;
   margin-top: -8px;
   width: 80px;
-  margin-left: -40px;
+  margin-inline-start: -40px;
   background: rgba(255, 255, 255, 0.9);
   transform: scale(1);
   border-radius: 8px;
@@ -568,14 +568,14 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
   left: 44px;
   width: 0;
   height: 0;
-  border-left: 6px solid transparent;
-  border-right: 6px solid transparent;
+  border-inline-start: 6px solid transparent;
+  border-inline-end: 6px solid transparent;
   border-bottom: 6px solid $negative;
 }
 
 
 .tab-container .nav-tabs {
-  text-align: left;
+  text-align: start;
   border-bottom: 1px solid #DDD;
   margin-bottom: $-m;
   .tab-item {
@@ -613,7 +613,7 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
   max-width: 480px;
   margin-bottom: $-s;
   a {
-    margin-right: $-xs;
+    margin-inline-end: $-xs;
     text-decoration: underline;
   }
 }
@@ -659,7 +659,7 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
     }
     a { color: #666; }
     span {
-      padding-left: $-xxs;
+      padding-inline-start: $-xxs;
     }
   }
   .text-muted {
@@ -692,7 +692,7 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
     height: 100%;
     display: flex;
     flex-direction: column;
-    border-left: 1px solid #DDD;
+    border-inline-start: 1px solid #DDD;
   }
   .template-item-actions button {
     cursor: pointer;
index da0f7ef4c191be13f4989186ffe03e208f95ca57..f306a717b3608225ef15daf3f992c4e2c7491054 100644 (file)
 }
 
 .markdown-display {
-  margin-left: -1px;
+  margin-inline-start: -1px;
 }
 
 .markdown-editor-display {
   background-color: #FFFFFF;
   body {
     background-color: #FFFFFF;
-    padding-left: 16px;
-    padding-right: 16px;
+    padding-inline-start: 16px;
+    pmargin-inline-end: 16px;
   }
   [drawio-diagram]:hover {
     outline: 2px solid var(--color-primary);
@@ -155,12 +155,12 @@ label.radio, label.checkbox {
   font-weight: 400;
   user-select: none;
   input[type="radio"], input[type="checkbox"] {
-    margin-right: $-xs;
+    margin-inline-end: $-xs;
   }
 }
 
 label.inline.checkbox {
-  margin-right: $-m;
+  margin-inline-end: $-m;
 }
 
 label + p.small {
@@ -288,12 +288,12 @@ input[type=color] {
   border: 1px solid #DDD;
   border-radius: 4px;
   .collapse-title {
-    margin-left: -$-m;
-    margin-right: -$-m;
+    margin-inline-start: -$-m;
+    margin-inline-end: -$-m;
     padding: $-s $-m;
     display: block;
     width: calc(100% + 32px);
-    text-align: left;
+    text-align: start;
   }
   .collapse-title, .collapse-title label {
     cursor: pointer;
@@ -306,7 +306,7 @@ input[type=color] {
   .collapse-title label:before {
     display: inline-block;
     content: '▸';
-    margin-right: $-m;
+    margin-inline-end: $-m;
     transition: all ease-in-out 400ms;
     transform: rotate(0);
   }
@@ -373,10 +373,14 @@ div[editor-type="markdown"] .title-input.page-title input[type="text"] {
     position: absolute;
     left: 8px;
     top: 9px;
+    @include rtl {
+      right: 8px;
+      left: auto;
+    }
   }
   input {
     display: block;
-    padding-left: $-l + 4px;
+    padding-inline-start: $-l + 4px;
     width: 300px;
     max-width: 100%;
   }
index 687ddd8d2259c83dcf0cb94530e7b34b7d5e9b9d..5503a0895d5c5ca6b83e4a08ca7357dc43589f2d 100644 (file)
@@ -34,8 +34,8 @@ header {
     fill: #FFF;
   }
   .dropdown-container {
-    padding-left: $-m;
-    padding-right: 0;
+    padding-inline-start: $-m;
+    padding-inline-end: 0;
   }
   .avatar, .user-name {
     display: inline-block;
@@ -53,7 +53,7 @@ header {
       vertical-align: top;
     }
     > span {
-      padding-left: $-xs;
+      padding-inline-start: $-xs;
       display: inline-block;
       padding-top: $-xxs;
     }
@@ -62,7 +62,7 @@ header {
       font-size: 18px;
     }
     @include between($l, $xl) {
-      padding-left: $-xs;
+      padding-inline-start: $-xs;
       .name {
         display: none;
       }
@@ -87,7 +87,7 @@ header .search-box {
     border-radius: 40px;
     color: #EEE;
     z-index: 2;
-    padding-left: 40px;
+    padding-inline-start: 40px;
     &:focus {
       outline: none;
       border: 1px solid rgba(255, 255, 255, 0.6);
@@ -97,8 +97,12 @@ header .search-box {
     fill: #EEE;
     z-index: 1;
     left: 16px;
+    @include rtl {
+      left: auto;
+      right: 16px;
+    }
     svg {
-      margin-right: 0;
+      margin-block-end: 0;
     }
   }
   ::-webkit-input-placeholder { /* Chrome/Opera/Safari */
@@ -124,12 +128,12 @@ header .search-box {
   font-size: 1.8em;
   color: #fff;
   font-weight: 400;
-  padding: 14px $-l 14px 0;
+  @include padding(14px, $-l, 14px, 0);
   vertical-align: top;
   line-height: 1;
 }
 .logo-image {
-  margin: $-xs $-s $-xs 0;
+  @include margin($-xs, $-s, $-xs, 0);
   vertical-align: top;
   height: 43px;
 }
@@ -151,8 +155,14 @@ header .search-box {
     margin: 0;
     bottom: -2px;
   }
+  @include rtl() {
+    left: $-m;
+    right: auto;
+  }
 }
 
+
+
 @include smaller-than($l) {
   header .header-links {
     display: none;
@@ -169,13 +179,13 @@ header .search-box {
     }
   }
   header .links a, header .dropdown-container ul li a {
-    text-align: left;
+    text-align: start;
     display: block;
     padding: $-s $-m;
     color: $text-dark;
     fill: $text-dark;
     svg {
-      margin-right: $-s;
+      margin-inline-end: $-s;
     }
     &:hover {
       background-color: #EEE;
@@ -186,7 +196,7 @@ header .search-box {
   }
   header .dropdown-container {
     display: block;
-    padding-left: 0;
+    padding-inline-start: 0;
   }
   header .links {
     display: block;
@@ -215,7 +225,7 @@ header .search-box {
   border-bottom: 3px solid #BBB;
   cursor: pointer;
   &:first-child {
-    border-right: 1px solid #DDD;
+    border-inline-end: 1px solid #DDD;
   }
   &.active {
     border-bottom-color: currentColor;
@@ -253,7 +263,7 @@ header .search-box {
       display: none;
     }
     > span:first-child {
-      margin-right: 0;
+      margin-block-end: 0;
     }
   }
 }
@@ -269,7 +279,7 @@ header .search-box {
     }
   }
   .svg-icon {
-    margin-right: 0;
+    margin-block-end: 0;
   }
 }
 
@@ -282,9 +292,17 @@ header .search-box {
   position: absolute;
   z-index: 80;
   right: -$-m;
+  @include rtl {
+    right: auto;
+    left: -$-m;
+  }
   .breadcrumb-listing-search .svg-icon {
     position: absolute;
     left: $-s;
+    @include rtl {
+      right: $-s;
+      left: auto;
+    }
     top: 11px;
     fill: #888;
     pointer-events: none;
@@ -292,10 +310,10 @@ header .search-box {
   .breadcrumb-listing-entity-list {
     max-height: 400px;
     overflow-y: scroll;
-    text-align: left;
+    text-align: start;
   }
   input {
-    padding-left: $-xl;
+    padding-inline-start: $-xl;
     border-radius: 0;
     border: 0;
     border-bottom: 1px solid #DDD;
@@ -337,25 +355,25 @@ header .search-box {
   display: inline-block;
   padding: $-xs $-s;
   &:last-child {
-    padding-right: 0;
+    padding-inline-end: 0;
   }
   &:first-child {
-    padding-left: 0;
+    padding-inline-start: 0;
   }
 }
 
 
 .action-buttons .dropdown-container:last-child a {
-  padding-right: 0;
-  padding-left: $-s;
+  padding-inline-end: 0;
+  padding-inline-start: $-s;
 }
 .action-buttons {
-  text-align: right;
+  text-align: end;
   &.text-left {
-    text-align: left;
+    text-align: start;
     .text-button {
-      padding-right: $-m;
-      padding-left: 0;
+      padding-inline-end: $-m;
+      padding-inline-start: 0;
     }
   }
   &.text-center {
@@ -368,6 +386,6 @@ header .search-box {
     padding: $-xs $-xs;
   }
   .action-buttons .dropdown-container:last-child a {
-    padding-left: $-xs;
+    padding-inline-start: $-xs;
   }
 }
\ No newline at end of file
index a280e4ed1f25514ad689b590dda7522d3aba2caa..197d5271b7d1017cf8c2293c494a46dbc392ac40 100644 (file)
@@ -4,10 +4,10 @@
  */
 .container {
   max-width: $xxl;
-  margin-left: auto;
-  margin-right: auto;
-  padding-left: $-m;
-  padding-right: $-m;
+  margin-inline-start: auto;
+  margin-inline-end: auto;
+  padding-inline-start: $-m;
+  padding-inline-end: $-m;
   &.small {
     max-width: 840px;
   }
@@ -198,8 +198,8 @@ body.flexbox {
  */
 .tri-layout-container {
   display: grid;
-  margin-left: $-xl;
-  margin-right: $-xl;
+  margin-inline-start: $-xl;
+  margin-inline-end: $-xl;
   grid-template-columns: 1fr 4fr 1fr;
   grid-template-areas: "a b c";
   grid-column-gap: $-xxl;
@@ -223,7 +223,7 @@ body.flexbox {
     ". b b";
     grid-template-columns: 1fr 3fr;
     grid-template-rows: min-content min-content 1fr;
-    padding-right: $-l;
+    padding-inline-end: $-l;
   }
 }
 @include between($l, $xxl) {
@@ -258,11 +258,11 @@ body.flexbox {
     grid-template-areas:  none;
     grid-template-columns: 1fr;
     grid-column-gap: 0;
-    padding-right: $-xs;
-    padding-left: $-xs;
+    padding-inline-end: $-xs;
+    padding-inline-start: $-xs;
     .tri-layout-left-contents, .tri-layout-right-contents {
-      padding-left: $-m;
-      padding-right: $-m;
+      padding-inline-start: $-m;
+      padding-inline-end: $-m;
     }
     .tri-layout-left > *, .tri-layout-right > * {
       display: none;
@@ -316,7 +316,7 @@ body.flexbox {
 
 @include smaller-than($m) {
   .tri-layout-container {
-    margin-left: 0;
-    margin-right: 0;
+    margin-inline-start: 0;
+    margin-inline-end: 0;
   }
 }
\ No newline at end of file
index 2e8fa257aebcf270e87bf438b00659ca85efcebd..7beb63d4e57b01ad1840a8425ba7e365ec4efb93 100644 (file)
@@ -6,7 +6,7 @@
     justify-self: stretch;
     align-self: stretch;
     height: auto;
-    margin-right: $-l;
+    margin-inline-end: $-l;
   }
   .icon:after {
     opacity: 0.5;
@@ -60,7 +60,7 @@
     border-radius: 0 4px 4px 0;
     padding: $-xs $-m;
     width: 100%;
-    text-align: left;
+    text-align: start;
   }
   .chapter-expansion-toggle:hover {
     background-color: rgba(0, 0, 0, 0.06);
 .sidebar-page-nav {
   $nav-indent: $-m;
   list-style: none;
-  margin: $-s 0 $-m $-xs;
+  @include margin($-s, 0, $-m, $-xs);
   position: relative;
   &:after {
     content: '';
     display: block;
     position: absolute;
     left: 0;
+    @include rtl {
+      left: auto;
+      right: 0;
+    }
     background-color: rgba(0, 0, 0, 0.2);
     width: 2px;
     top: 5px;
     position: relative;
   }
   .h1 {
-    padding-left: $nav-indent;
+    padding-inline-start: $nav-indent;
   }
   .h2 {
-    padding-left: $nav-indent * 1.5;
+    padding-inline-start: $nav-indent * 1.5;
   }
   .h3 {
-    padding-left: $nav-indent * 2;
+    padding-inline-start: $nav-indent * 2;
   }
   .h4 {
-    padding-left: $nav-indent * 2.5;
+    padding-inline-start: $nav-indent * 2.5;
   }
   .h5 {
-    padding-left: $nav-indent*3;
+    padding-inline-start: $nav-indent*3;
   }
   .h6 {
-    padding-left: $nav-indent*3.5;
+    padding-inline-start: $nav-indent*3.5;
   }
   .current-heading {
     font-weight: bold;
     border-radius: 50%;
     box-shadow: 0 0 0 6px #F2F2F2;
     z-index: 1;
+    @include rtl {
+      left: auto;
+      right: -2px;
+    }
   }
 }
 
 // Sidebar list
 .book-tree .sidebar-page-list  {
   list-style: none;
-  margin: $-xs -$-s 0 -$-s;
-  padding-left: 0;
-  padding-right: 0;
+  @include margin($-xs, -$-s, 0, -$-s);
+  padding-inline-start: 0;
+  padding-inline-end: 0;
   position: relative;
 
   &:after, .sub-menu:after {
     left: $-m;
     top: 1rem;
     bottom: 1rem;
-    border-left: 4px solid rgba(0, 0, 0, 0.1);
+    border-inline-start: 4px solid rgba(0, 0, 0, 0.1);
     z-index: 0;
+    @include rtl {
+      left: auto;
+      right: $-m;
+    }
   }
 
   ul {
     list-style: none;
-    padding-left: 1rem;
-    padding-right: 0;
+    padding-inline-start: 1rem;
+    padding-inline-end: 0;
   }
 
   .entity-list-item {
   }
   .entity-list-item.no-hover {
     margin-top: -$-xs;
-    padding-right: 0;
+    padding-inline-end: 0;
   }
   .entity-list-item-name {
     font-size: 1em;
   .chapter-child-menu {
     font-size: .8rem;
     margin-top: -.2rem;
-    margin-left: -1rem;
+    margin-inline-start: -1rem;
   }
   [chapter-toggle] {
-    padding-left: .7rem;
+    padding-inline-start: .7rem;
     padding-bottom: .2rem;
   }
   .entity-list-item .icon {
 .chapter-child-menu {
   ul.sub-menu {
     display: none;
-    padding-left: 0;
+    padding-inline-start: 0;
     position: relative;
   }
   [chapter-toggle].open + .sub-menu {
   justify-content: space-between;
 }
 .sort-box-options .button {
-  margin-left: 0;
+  margin-inline-start: 0;
 }
 .sortable-page-list {
-  margin-left: 0;
+  margin-inline-start: 0;
   padding: 0;
   .entity-list-item > span:first-child {
     align-self: flex-start;
     flex: 1;
   }
   > ul {
-    margin-left: 0;
+    margin-inline-start: 0;
   }
   ul {
     margin-bottom: $-m;
     margin-top: 0;
-    padding-left: $-m;
+    padding-inline-start: $-m;
   }
   li {
     border: 1px solid #DDD;
     min-height: 38px;
   }
   li.text-page, li.text-chapter {
-    border-left: 2px solid currentColor;
+    border-inline-start: 2px solid currentColor;
   }
   li:first-child {
     margin-top: $-xs;
@@ -320,7 +332,7 @@ ul.pagination {
   display: inline-block;
   list-style: none;
   margin: $-m 0;
-  padding-left: 1px;
+  padding-inline-start: 1px;
   li {
     float: left;
   }
@@ -338,7 +350,7 @@ ul.pagination {
     display: block;
     padding: $-xxs $-s;
     border: 1px solid #CCC;
-    margin-left: -1px;
+    margin-inline-start: -1px;
     user-select: none;
     &.disabled {
       cursor: not-allowed;
@@ -402,13 +414,13 @@ ul.pagination {
     color: #666;
   }
   > span:first-child {
-    margin-right: $-m;
+    margin-inline-end: $-m;
     flex-basis: 1.88em;
     flex: none;
   }
   > span:last-child {
     flex: 1;
-    text-align: left;
+    text-align: start;
   }
   &:not(.no-hover) {
     cursor: pointer;
@@ -438,7 +450,7 @@ ul.pagination {
   position: relative;
   top: 1px;
   svg {
-    margin-right: 0;
+    margin-inline-end: 0;
   }
 }
 
@@ -460,7 +472,7 @@ ul.pagination {
     text-overflow: ellipsis;
     height: 2.5em;
     overflow: hidden;
-    text-align: left;
+    text-align: start;
     display: block;
     white-space: nowrap;
   }
@@ -474,7 +486,7 @@ ul.pagination {
   background-position: 50% 50%;
   border-radius: 3px;
   position: relative;
-  margin-right: $-l;
+  margin-inline-end: $-l;
 
   &.entity-list-item-image-wide {
     width: 220px;
@@ -484,7 +496,7 @@ ul.pagination {
     color: #FFF;
     fill: #FFF;
     font-size: 1.66rem;
-    margin-right: 0;
+    margin-inline-end: 0;
     position: absolute;
     bottom: $-xs;
     left: $-xs;
@@ -550,7 +562,7 @@ ul.pagination {
   padding: $-xs 0;
   color: #555;
   fill: #555;
-  text-align: left !important;
+  text-align: start !important;
   &.wide {
     min-width: 220px;
   }
@@ -577,14 +589,14 @@ ul.pagination {
       outline-offset: -2px;
     }
     svg {
-      margin-right: $-s;
+      margin-inline-end: $-s;
       display: inline-block;
       width: 16px;
     }
   }
   button {
     width: 100%;
-    text-align: left;
+    text-align: start;
   }
   li.border-bottom {
     border-bottom: 1px solid #DDD;
@@ -615,7 +627,7 @@ ul.pagination {
     color: #FFF;
     fill: #FFF;
     font-size: 2rem;
-    margin-right: 0;
+    margin-inline-end: 0;
     position: absolute;
     bottom: 10px;
     left: 6px;
index 1c45ebd3080b92ff4f14ebce0f181e84dac71100..8a6becf6b70746131a0e54b05545b4bc288721f9 100644 (file)
@@ -8,3 +8,27 @@
 @mixin between($min, $max) {
   @media screen and (min-width: $min) and (max-width: $max) { @content; }
 }
+
+// Padding shorthand using logical operators to better support RTL.
+@mixin padding($t, $r, $b, $l) {
+  padding-block-start: $t;
+  padding-block-end: $b;
+  padding-inline-start: $l;
+  padding-inline-end: $r;
+}
+
+// Margin shorthand using logical operators to better support RTL.
+@mixin margin($t, $r, $b, $l) {
+  margin-block-start: $t;
+  margin-block-end: $b;
+  margin-inline-start: $l;
+  margin-inline-end: $r;
+}
+
+// Create a RTL specific style block.
+// Mostly used as a patch until browser support improves for logical properties.
+@mixin rtl() {
+  html[dir=rtl] & {
+    @content;
+  }
+}
\ No newline at end of file
index 9281a21946db4c75a6211cdf2ee20568640cd6b7..7019051653f8a17e62f400e2079143786797c876 100755 (executable)
@@ -59,7 +59,7 @@ body.mce-fullscreen, body.markdown-fullscreen {
   text-align: center;
   svg {
     fill: #FFF;
-    margin-right: 0;
+    margin-inline-end: 0;
   }
 }
 
@@ -174,14 +174,14 @@ body.mce-fullscreen, body.markdown-fullscreen {
     bottom: -9px;
     width: 16px;
     height: 16px;
-    margin-left: -8px;
+    margin-inline-start: -8px;
     content: '';
     display: block;
     background-color:#FFF;
     transform: rotate(45deg);
     transform-origin: 50% 50%;
-    border-bottom: 1px solid #CCC;
-    border-right: 1px solid #CCC;
+    border-inline-startom: 1px solid #CCC;
+    border-inline-end: 1px solid #CCC;
     z-index: 56;
   }
   input, button, a {
@@ -255,7 +255,7 @@ body.mce-fullscreen, body.markdown-fullscreen {
   }
   .tabs {
     display: block;
-    border-right: 1px solid #DDD;
+    border-inline-end: 1px solid #DDD;
     width: 48px;
     flex: 0 1 auto;
   }
@@ -294,8 +294,8 @@ body.mce-fullscreen, body.markdown-fullscreen {
     width: 100%;
     min-width: 50px;
   }
-  .tags td, .tag-table > div > div > div {
-    padding-right: $-s;
+  .tags td, .inline-start-table > div > div > div {
+    padding-inline-end: $-s;
     padding-top: $-s;
     position: relative;
   }
@@ -319,42 +319,6 @@ body.mce-fullscreen, body.markdown-fullscreen {
   display: none;
 }
 
-.tag-display {
-  position: relative;
-  table {
-    width: 100%;
-    margin: 0;
-    padding: 0;
-  }
-  tr:first-child td {
-    padding-top: 0;
-  }
-  .heading th {
-    padding: $-xs $-s;
-    color: rgba(100, 100, 100, 0.7);
-    border: 0;
-    font-weight: 400;
-  }
-  td {
-    border: 0;
-    border-bottom: 1px solid #EEE;
-    padding: $-xs $-s;
-    color: #444;
-  }
-  tr td:first-child {
-    padding-left:0;
-  }
-  .tag-value {
-    color: #888;
-  }
-  tr:last-child td {
-    border-bottom: none;
-  }
-  .tag {
-    padding: $-s;
-  }
-}
-
 .suggestion-box {
   position: absolute;
   background-color: #FFF;
index 69ed5a2d3c0174517ba02ed44d491ad098782d3d..57b229ab8eb3f50617c26e112f5ab2fb5e16bd4e 100644 (file)
@@ -7,8 +7,8 @@
       #{$prop}: $size !important;
     }
     .#{$propLetter}x-#{$sizeLetter} {
-      #{$prop}-left: $size !important;
-      #{$prop}-right: $size !important;
+      #{$prop}-inline-start: $size !important;
+      #{$prop}-inline-end: $size !important;
     }
     .#{$propLetter}y-#{$sizeLetter} {
       #{$prop}-top: $size !important;
       #{$prop}-top: $size !important;
     }
     .#{$propLetter}r-#{$sizeLetter} {
-      #{$prop}-right: $size !important;
+      #{$prop}-inline-end: $size !important;
     }
     .#{$propLetter}b-#{$sizeLetter} {
       #{$prop}-bottom: $size !important;
     }
     .#{$propLetter}l-#{$sizeLetter} {
-      #{$prop}-left: $size !important;
+      #{$prop}-inline-start: $size !important;
     }
   }
 }
index a1a2fef0a44537057b186fdd1969bf7461edb175..2778736083662ac7901612bc4b590c09547da625 100644 (file)
@@ -23,7 +23,7 @@ table.table {
     border-bottom: 1px solid rgba(0, 0, 0, 0.05);
   }
   th, td {
-    text-align: left;
+    text-align: start;
     border: none;
     padding: $-s $-s;
     vertical-align: middle;
@@ -36,7 +36,7 @@ table.table {
     background-color: #EEE;
   }
   .text-right {
-    text-align: right;
+    text-align: end;
   }
   .text-center {
     text-align: center;
index 8210d6d443fa5c1f368e895a65b6d3369b629a5e..00fc772ccd041f7c3c4bfa07747679a86247db64 100644 (file)
@@ -313,10 +313,10 @@ li > ol, li > ul {
   text-align: center;
 }
 .text-left {
-  text-align: left;
+  text-align: start;
 }
 .text-right {
-  text-align: right;
+  text-align: end;
 }
 
 @each $sizeLetter, $size in $screen-sizes {
@@ -325,10 +325,10 @@ li > ol, li > ul {
       text-align: center;
     }
     .text-#{$sizeLetter}-left {
-      text-align: left;
+      text-align: start;
     }
     .text-#{$sizeLetter}-right {
-      text-align: right;
+      text-align: end;
     }
   }
 }
@@ -384,6 +384,6 @@ span.sep {
   display: inline-block;
   position: relative;
   bottom: -0.105em;
-  margin-right: $-xs;
+  margin-inline-end: $-xs;
   pointer-events: none;
 }
index 296afbe76f0cb11efbb7c0b327885858016c949d..5cbd7f9d5e226b9c4710acaa3b5012862ea77c63 100644 (file)
@@ -20,8 +20,8 @@ html, body {
 .tri-layout-container {
   grid-template-columns: 1fr;
   grid-template-areas: "b";
-  margin-left: 0;
-  margin-right: 0;
+  margin-inline-start: 0;
+  margin-inline-end: 0;
   display: block;
 }
 
@@ -30,6 +30,6 @@ html, body {
 }
 
 .content-wrap.card {
-  padding-left: 0;
-  padding-right: 0;
+  padding-inline-start: 0;
+  padding-inline-end: 0;
 }
\ No newline at end of file
index 1f4d00f6b9606b1ebe15d94b0c5b8788dd747b6e..09d8b41000f199d6599a1fd96a400a7e226a0e0f 100644 (file)
@@ -74,7 +74,7 @@ $loadingSize: 10px;
     animation-duration: 1.4s;
     animation-iteration-count: infinite;
     animation-timing-function: cubic-bezier(.62, .28, .23, .99);
-    margin-right: 4px;
+    margin-inline-end: 4px;
     background-color: var(--color-page);
     animation-delay: 0.3s;
   }
@@ -89,7 +89,7 @@ $loadingSize: 10px;
     animation-delay: 0.6s;
   }
   > span {
-    margin-left: $-s;
+    margin-inline-start: $-s;
     font-style: italic;
     color: #888;
     vertical-align: top;
@@ -110,7 +110,7 @@ $btt-size: 40px;
   svg {
     width: $btt-size / 1.5;
     height: $btt-size / 1.5;
-    margin-right: 4px;
+    margin-inline-end: 4px;
   }
   width: $btt-size;
   height: $btt-size;
@@ -138,7 +138,7 @@ $btt-size: 40px;
   input, button {
     border-radius: 0;
     border: 1px solid #DDD;
-    margin-left: -1px;
+    margin-inline-start: -1px;
   }
   input {
     flex: 5;
@@ -177,8 +177,8 @@ $btt-size: 40px;
     overflow-y: scroll;
     height: 400px;
     background-color: #EEEEEE;
-    margin-right: 0;
-    margin-left: 0;
+    margin-inline-end: 0;
+    margin-inline-start: 0;
   }
   .entity-list-item {
     background-color: #FFF;
@@ -252,7 +252,7 @@ $btt-size: 40px;
   }
   .list-sort {
     display: inline-grid;
-    margin-left: $-s;
+    margin-inline-start: $-s;
     grid-template-columns: minmax(120px, max-content) 40px;
     font-size: 0.9rem;
     border: 2px solid #DDD;
@@ -264,14 +264,14 @@ $btt-size: 40px;
     color: #555;
   }
   .list-sort-type {
-    text-align: left;
+    text-align: start;
   }
   .list-sort-type, .list-sort-dir {
     padding: $-xs $-s;
     cursor: pointer;
   }
   .list-sort-dir {
-    border-left: 2px solid #DDD;
+    border-inline-start: 2px solid #DDD;
     fill: #888;
     .svg-icon {
       transition: transform ease-in-out 120ms;
index aa1913e3179853c203035dcfcbd64c1ae1c9871c..7d6595894fa5222c974e670415bd7dceddc04b3f 100644 (file)
@@ -4,7 +4,7 @@
     <div>
         <button id="saml-login" class="button outline block svg">
             @icon('saml2')
-            {{ trans('auth.log_in_with', ['socialDriver' => config('saml2.name')]) }}
+            <span>{{ trans('auth.log_in_with', ['socialDriver' => config('saml2.name')]) }}</span>
         </button>
     </div>
 
index 0a21a0f62d421238e97130de5be402505958b946..868e0555fd5fe7a13f6cad9f0ce5142892223492 100644 (file)
@@ -17,7 +17,7 @@
                     <div>
                         <a id="social-login-{{$driver}}" class="button outline block svg" href="{{ url("/login/service/" . $driver) }}">
                             @icon('auth/' . $driver)
-                            {{ trans('auth.log_in_with', ['socialDriver' => $name]) }}
+                            <span>{{ trans('auth.log_in_with', ['socialDriver' => $name]) }}</span>
                         </a>
                     </div>
                 @endforeach
index 1625ebc4c588afbcf77d18475a6336a4c61439a1..34aa81d7bf991f078104f8cff5dbecca69773737 100644 (file)
@@ -44,7 +44,7 @@
                     <div>
                         <a id="social-register-{{$driver}}" class="button block outline svg" href="{{ url("/register/service/" . $driver) }}">
                             @icon('auth/' . $driver)
-                            {{ trans('auth.sign_up_with', ['socialDriver' => $name]) }}
+                            <span>{{ trans('auth.sign_up_with', ['socialDriver' => $name]) }}</span>
                         </a>
                     </div>
                 @endforeach
index 07548162067404fa82061695c6753fe5bd15e27c..d362ef37360dcafe48a5157865ba85dd11529a5a 100644 (file)
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html lang="{{ config('app.lang') }}" class="@yield('body-class')">
+<html lang="{{ config('app.lang') }}" dir="{{ config('app.rtl') ? 'rtl' : 'ltr' }}" class="@yield('body-class')">
 <head>
     <title>{{ isset($pageTitle) ? $pageTitle . ' | ' : '' }}{{ setting('app-name') }}</title>
 
index d7654b8671892ed32ced98a2b85470a479bddc7e..d5c6e453238ead0b3d82f0d805d23f7983fdf676 100644 (file)
@@ -11,7 +11,7 @@ class LanguageTest extends TestCase
     public function setUp(): void
     {
         parent::setUp();
-        $this->langs = array_diff(scandir(resource_path('lang')), ['..', '.', 'check.php', 'format.php']);
+        $this->langs = array_diff(scandir(resource_path('lang')), ['..', '.']);
     }
 
     public function test_locales_config_key_set_properly()
@@ -22,6 +22,20 @@ class LanguageTest extends TestCase
         $this->assertEquals(implode(':', $configLocales), implode(':', $this->langs), 'app.locales configuration variable does not match those found in lang files');
     }
 
+    // Not part of standard phpunit test runs since we sometimes expect non-added langs.
+    public function do_test_locales_all_have_language_dropdown_entry()
+    {
+        $dropdownLocales = array_keys(trans('settings.language_select', [], 'en'));
+        sort($dropdownLocales);
+        sort($this->langs);
+        $diffs = array_diff($this->langs, $dropdownLocales);
+        if (count($diffs) > 0) {
+            $diffText = implode(',', $diffs);
+            $this->addWarning("Languages: {$diffText} found in files but not in language select dropdown.");
+        }
+        $this->assertTrue(true);
+    }
+
     public function test_correct_language_if_not_logged_in()
     {
         $loginReq = $this->get('/login');