diff --git a/app/assets/javascripts/discourse/components/d-editor.js.es6 b/app/assets/javascripts/discourse/components/d-editor.js.es6 index 10d1a4fa534..010f11bd2ba 100644 --- a/app/assets/javascripts/discourse/components/d-editor.js.es6 +++ b/app/assets/javascripts/discourse/components/d-editor.js.es6 @@ -112,7 +112,7 @@ class Toolbar { this.addButton({ id: 'toggle-direction', group: 'extras', - icon: 'arrows-h', + icon: 'exchange', shortcut: 'Shift+6', title: 'composer.toggle_direction', perform: e => e.toggleDirection(), diff --git a/app/assets/javascripts/discourse/components/text-field.js.es6 b/app/assets/javascripts/discourse/components/text-field.js.es6 index c2bb0eaf51c..ae26f6e99f0 100644 --- a/app/assets/javascripts/discourse/components/text-field.js.es6 +++ b/app/assets/javascripts/discourse/components/text-field.js.es6 @@ -1,14 +1,12 @@ import computed from "ember-addons/ember-computed-decorators"; -import { siteDir } from "discourse/lib/text-direction"; -import { isRTL } from "discourse/lib/text-direction"; -import { isLTR } from "discourse/lib/text-direction"; +import { siteDir, isRTL, isLTR } from "discourse/lib/text-direction"; export default Ember.TextField.extend({ attributeBindings: ['autocorrect', 'autocapitalize', 'autofocus', 'maxLength', 'dir'], @computed dir() { - if (Discourse.SiteSettings.support_mixed_text_direction) { + if (this.siteSettings.support_mixed_text_direction) { let val = this.value; if (val) { return isRTL(val) ? 'rtl' : 'ltr'; @@ -19,7 +17,7 @@ export default Ember.TextField.extend({ }, keyUp() { - if (Discourse.SiteSettings.support_mixed_text_direction) { + if (this.siteSettings.support_mixed_text_direction) { let val = this.value; if (isRTL(val)) { this.set('dir', 'rtl'); diff --git a/app/assets/javascripts/discourse/lib/text-direction.js.es6 b/app/assets/javascripts/discourse/lib/text-direction.js.es6 index 2a4b9da2c36..928b147ed79 100644 --- a/app/assets/javascripts/discourse/lib/text-direction.js.es6 +++ b/app/assets/javascripts/discourse/lib/text-direction.js.es6 @@ -1,15 +1,14 @@ const ltrChars = 'A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF\u2C00-\uFB1C\uFDFE-\uFE6F\uFEFD-\uFFFF'; const rtlChars = '\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC'; +const rtlDirCheck = new RegExp('^[^'+ltrChars+']*['+rtlChars+']'); +const ltrDirCheck = new RegExp('^[^'+rtlChars+']*['+ltrChars+']'); +let _siteDir; export function isRTL(text) { - const rtlDirCheck = new RegExp('^[^'+ltrChars+']*['+rtlChars+']'); - return rtlDirCheck.test(text); } export function isLTR(text) { - const ltrDirCheck = new RegExp('^[^'+rtlChars+']*['+ltrChars+']'); - return ltrDirCheck.test(text); } @@ -24,5 +23,8 @@ export function setTextDirections($elem) { } export function siteDir() { - return $('html').hasClass('rtl') ? 'rtl' : 'ltr'; + if (!_siteDir) { + _siteDir = $('html').hasClass('rtl') ? 'rtl' : 'ltr'; + } + return _siteDir; } diff --git a/test/javascripts/components/d-editor-test.js.es6 b/test/javascripts/components/d-editor-test.js.es6 index faf4f30b3b8..e0409e4957d 100644 --- a/test/javascripts/components/d-editor-test.js.es6 +++ b/test/javascripts/components/d-editor-test.js.es6 @@ -715,6 +715,26 @@ testCase(`list button with line sequence`, function(assert, textarea) { }); }); +componentTest('clicking the toggle-direction button toggles the direction', { + template: '{{d-editor value=value}}', + beforeEach() { + this.siteSettings.support_mixed_text_direction = true; + this.siteSettings.default_locale = "en"; + }, + + test(assert) { + const textarea = this.$('textarea.d-editor-input'); + click('button.toggle-direction'); + andThen(() => { + assert.equal(textarea.attr('dir'), 'rtl'); + }); + click('button.toggle-direction'); + andThen(() => { + assert.equal(textarea.attr('dir'), 'ltr'); + }); + } +}); + testCase(`doesn't jump to bottom with long text`, function(assert, textarea) { let longText = 'hello world.'; diff --git a/test/javascripts/components/text-field-test.js.es6 b/test/javascripts/components/text-field-test.js.es6 index e18662c2ab9..7a2de69a5a2 100644 --- a/test/javascripts/components/text-field-test.js.es6 +++ b/test/javascripts/components/text-field-test.js.es6 @@ -22,3 +22,27 @@ componentTest("support a placeholder", { assert.equal(this.$('input').prop('placeholder'), 'placeholder.i18n.key'); } }); + +componentTest("sets the dir attribute to ltr for Hebrew text", { + template: `{{text-field value='זהו שם עברי עם מקום עברי'}}`, + beforeEach() { + this.siteSettings.support_mixed_text_direction = true; + }, + + test(assert) { + assert.equal(this.$('input').attr('dir'), 'rtl'); + } +}); + +componentTest("sets the dir attribute to ltr for English text", { + template: `{{text-field value='This is a ltr title'}}`, + beforeEach() { + this.siteSettings.support_mixed_text_direction = true; + }, + + test(assert) { + assert.equal(this.$('input').attr('dir'), 'ltr'); + } +}); + + diff --git a/test/javascripts/lib/category-badge-test.js.es6 b/test/javascripts/lib/category-badge-test.js.es6 index 17322d46191..5fdc807dec4 100644 --- a/test/javascripts/lib/category-badge-test.js.es6 +++ b/test/javascripts/lib/category-badge-test.js.es6 @@ -45,3 +45,28 @@ QUnit.test("allowUncategorized", assert => { assert.blank(categoryBadgeHTML(uncategorized), "it doesn't return HTML for uncategorized by default"); assert.present(categoryBadgeHTML(uncategorized, {allowUncategorized: true}), "it returns HTML"); }); + +QUnit.test("category names are wrapped in dir-spans", assert => { + Discourse.SiteSettings.support_mixed_text_direction = true; + const store = createStore(); + const rtlCategory = store.createRecord('category', { + name: 'תכנות עם Ruby', + id: 123, + description_text: 'cool description', + color: 'ff0', + text_color: 'f00' + }); + + const ltrCategory = store.createRecord('category', { + name: 'Programming in Ruby', + id: 234 + }); + + let tag = parseHTML(categoryBadgeHTML(rtlCategory))[0]; + let dirSpan = tag.children[1].children[0]; + assert.equal(dirSpan.attributes.dir, 'rtl'); + + tag = parseHTML(categoryBadgeHTML(ltrCategory))[0]; + dirSpan = tag.children[1].children[0]; + assert.equal(dirSpan.attributes.dir, 'ltr'); +}); diff --git a/test/javascripts/models/topic-test.js.es6 b/test/javascripts/models/topic-test.js.es6 index 2e9ce444365..7c33bceff03 100644 --- a/test/javascripts/models/topic-test.js.es6 +++ b/test/javascripts/models/topic-test.js.es6 @@ -98,6 +98,15 @@ QUnit.test('fancyTitle', assert => { "supports emojis"); }); +QUnit.test('fancyTitle direction', assert => { + const rtlTopic = Topic.create({ fancy_title: "هذا اختبار" }); + const ltrTopic = Topic.create({ fancy_title: "This is a test"}); + + Discourse.SiteSettings.support_mixed_text_direction = true; + assert.equal(rtlTopic.get('fancyTitle'), `هذا اختبار`, "sets the dir-span to rtl"); + assert.equal(ltrTopic.get('fancyTitle'), `This is a test`, "sets the dir-span to ltr"); +}); + QUnit.test('excerpt', assert => { const topic = Topic.create({ excerpt: "This is a test topic :smile:", pinned: true });