Added base RTL support

For #939

- Adds way to check if current language is RTL via config system.
- Made TinyMCE default direction be based on current language text
direction.
- Fixed bullet points to be RTL compatible.
- Set page content body to have direction based on content.
This commit is contained in:
Dan Brown 2018-09-22 13:18:26 +01:00
parent c667c6e235
commit 1cb6ae39c8
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
9 changed files with 50 additions and 2 deletions

View File

@ -6,6 +6,9 @@ use Illuminate\Http\Request;
class Localization class Localization
{ {
protected $rtlLocales = ['ar'];
/** /**
* Handle an incoming request. * Handle an incoming request.
* *
@ -23,6 +26,11 @@ class Localization
$locale = setting()->getUser(user(), 'language', $defaultLang); $locale = setting()->getUser(user(), 'language', $defaultLang);
} }
// Set text direction
if (in_array($locale, $this->rtlLocales)) {
config()->set('app.rtl', true);
}
app()->setLocale($locale); app()->setLocale($locale);
Carbon::setLocale($locale); Carbon::setLocale($locale);
return $next($request); return $next($request);

View File

@ -79,6 +79,19 @@ return [
'locale' => env('APP_LANG', 'en'), 'locale' => env('APP_LANG', 'en'),
'locales' => ['en', 'ar', 'de', 'es', 'es_AR', 'fr', 'nl', 'pt_BR', 'sk', 'sv', 'ja', 'pl', 'it', 'ru', 'zh_CN', 'zh_TW'], 'locales' => ['en', 'ar', 'de', 'es', 'es_AR', 'fr', 'nl', 'pt_BR', 'sk', 'sv', 'ja', 'pl', 'it', 'ru', 'zh_CN', 'zh_TW'],
/*
|--------------------------------------------------------------------------
| Right-to-left text control
|--------------------------------------------------------------------------
|
| Right-to-left text control is set to false by default since English
| is the primary supported application but this may be dynamically
| altered by the applications localization system.
|
*/
'rtl' => false,
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Auto-detect the locale for public users | Auto-detect the locale for public users

View File

@ -8,6 +8,7 @@ class MarkdownEditor {
constructor(elem) { constructor(elem) {
this.elem = elem; this.elem = elem;
this.textDirection = document.getElementById('page-editor').getAttribute('text-direction');
this.markdown = new MarkdownIt({html: true}); this.markdown = new MarkdownIt({html: true});
this.markdown.use(mdTasksLists, {label: true}); this.markdown.use(mdTasksLists, {label: true});
@ -98,6 +99,9 @@ class MarkdownEditor {
codeMirrorSetup() { codeMirrorSetup() {
let cm = this.cm; let cm = this.cm;
// Text direction
// cm.setOption('direction', this.textDirection);
cm.setOption('direction', 'ltr'); // Will force to remain as ltr for now due to issues when HTML is in editor.
// Custom key commands // Custom key commands
let metaKey = code.getMetaKey(); let metaKey = code.getMetaKey();
const extraKeys = {}; const extraKeys = {};

View File

@ -370,6 +370,7 @@ class WysiwygEditor {
constructor(elem) { constructor(elem) {
this.elem = elem; this.elem = elem;
this.textDirection = document.getElementById('page-editor').getAttribute('text-direction');
this.plugins = "image table textcolor paste link autolink fullscreen imagetools code customhr autosave lists codeeditor media"; this.plugins = "image table textcolor paste link autolink fullscreen imagetools code customhr autosave lists codeeditor media";
this.loadPlugins(); this.loadPlugins();
@ -385,6 +386,14 @@ class WysiwygEditor {
drawIoPlugin(); drawIoPlugin();
this.plugins += ' drawio'; this.plugins += ' drawio';
} }
if (this.textDirection === 'rtl') {
this.plugins += ' directionality'
}
}
getToolBar() {
const textDirPlugins = this.textDirection === 'rtl' ? 'ltr rtl' : '';
return `undo redo | styleselect | bold italic underline strikethrough superscript subscript | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image-insert link hr drawio media | removeformat code ${textDirPlugins} fullscreen`
} }
getTinyMceConfig() { getTinyMceConfig() {
@ -397,6 +406,7 @@ class WysiwygEditor {
body_class: 'page-content', body_class: 'page-content',
browser_spellcheck: true, browser_spellcheck: true,
relative_urls: false, relative_urls: false,
directionality : this.textDirection,
remove_script_host: false, remove_script_host: false,
document_base_url: window.baseUrl('/'), document_base_url: window.baseUrl('/'),
statusbar: false, statusbar: false,
@ -407,7 +417,7 @@ class WysiwygEditor {
valid_children: "-div[p|h1|h2|h3|h4|h5|h6|blockquote],+div[pre],+div[img]", valid_children: "-div[p|h1|h2|h3|h4|h5|h6|blockquote],+div[pre],+div[img]",
plugins: this.plugins, plugins: this.plugins,
imagetools_toolbar: 'imageoptions', imagetools_toolbar: 'imageoptions',
toolbar: "undo redo | styleselect | bold italic underline strikethrough superscript subscript | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image-insert link hr drawio media | removeformat code fullscreen", toolbar: this.getToolBar(),
content_style: "body {padding-left: 15px !important; padding-right: 15px !important; margin:0!important; margin-left:auto!important;margin-right:auto!important;}", content_style: "body {padding-left: 15px !important; padding-right: 15px !important; margin:0!important; margin-left:auto!important;margin-right:auto!important;}",
style_formats: [ style_formats: [
{title: "Header Large", format: "h2"}, {title: "Header Large", format: "h2"},

View File

@ -157,6 +157,7 @@ function wysiwygView(elem) {
newWrap.className = 'CodeMirrorContainer'; newWrap.className = 'CodeMirrorContainer';
newWrap.setAttribute('data-lang', lang); newWrap.setAttribute('data-lang', lang);
newWrap.setAttribute('dir', 'ltr');
newTextArea.style.display = 'none'; newTextArea.style.display = 'none';
elem.parentNode.replaceChild(newWrap, elem); elem.parentNode.replaceChild(newWrap, elem);

View File

@ -351,6 +351,7 @@ ul, ol {
} }
ul { ul {
padding-left: $-m * 1.3; padding-left: $-m * 1.3;
padding-right: $-m * 1.3;
list-style: disc; list-style: disc;
ul { ul {
list-style: circle; list-style: circle;
@ -365,6 +366,7 @@ ul {
ol { ol {
list-style: decimal; list-style: decimal;
padding-left: $-m * 2; padding-left: $-m * 2;
padding-right: $-m * 2;
} }
li.checkbox-item, li.task-list-item { li.checkbox-item, li.task-list-item {

View File

@ -4,6 +4,7 @@
drawio-enabled="{{ config('services.drawio') ? 'true' : 'false' }}" drawio-enabled="{{ config('services.drawio') ? 'true' : 'false' }}"
editor-type="{{ setting('app-editor') }}" editor-type="{{ setting('app-editor') }}"
page-id="{{ $model->id or 0 }}" page-id="{{ $model->id or 0 }}"
text-direction="{{ config('app.rtl') ? 'rtl' : 'ltr' }}"
page-new-draft="{{ $model->draft or 0 }}" page-new-draft="{{ $model->draft or 0 }}"
page-update-draft="{{ $model->isDraft or 0 }}"> page-update-draft="{{ $model->isDraft or 0 }}">

View File

@ -1,4 +1,4 @@
<div> <div dir="auto">
<h1 class="break-text" v-pre id="bkmrk-page-title">{{$page->name}}</h1> <h1 class="break-text" v-pre id="bkmrk-page-title">{{$page->name}}</h1>

View File

@ -72,4 +72,13 @@ class LanguageTest extends TestCase
} }
} }
public function test_rtl_config_set_if_lang_is_rtl()
{
$this->asEditor();
$this->assertFalse(config('app.rtl'), "App RTL config should be false by default");
setting()->putUser($this->getEditor(), 'language', 'ar');
$this->get('/');
$this->assertTrue(config('app.rtl'), "App RTL config should have been set to true by middleware");
}
} }