From 90571f036465c95591689b45eca34de1b18b4f98 Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Tue, 23 Aug 2016 14:56:08 +0800 Subject: [PATCH] FIX: Format selection as multiline code only when selection spans multiple lines. --- .../discourse/components/d-editor.js.es6 | 47 +++++++----- .../components/d-editor-test.js.es6 | 72 +++++++++++++++---- 2 files changed, 88 insertions(+), 31 deletions(-) diff --git a/app/assets/javascripts/discourse/components/d-editor.js.es6 b/app/assets/javascripts/discourse/components/d-editor.js.es6 index dcb3e9d9a49..0757d60f8d7 100644 --- a/app/assets/javascripts/discourse/components/d-editor.js.es6 +++ b/app/assets/javascripts/discourse/components/d-editor.js.es6 @@ -364,12 +364,12 @@ export default Ember.Component.extend({ }); }, - _getSelected(trimLeading) { + _getSelected(trimLeading, opts) { if (!this.get('ready')) { return; } const textarea = this.$('textarea.d-editor-input')[0]; const value = textarea.value; - var start = textarea.selectionStart; + let start = textarea.selectionStart; let end = textarea.selectionEnd; // trim trailing spaces cause **test ** would be invalid @@ -388,7 +388,12 @@ export default Ember.Component.extend({ const pre = value.slice(0, start); const post = value.slice(end); - return { start, end, value: selVal, pre, post }; + if (opts && opts.lineVal) { + const lineVal = value.split("\n")[value.substr(0, textarea.selectionStart).split("\n").length - 1]; + return { start, end, value: selVal, pre, post, lineVal }; + } else { + return { start, end, value: selVal, pre, post }; + } }, _selectText(from, length) { @@ -535,21 +540,31 @@ export default Ember.Component.extend({ }, formatCode() { - const sel = this._getSelected(); - const hasNewLine = sel.value.indexOf("\n") !== -1; + const sel = this._getSelected('', { lineVal: true }); + const selValue = sel.value; + const hasNewLine = selValue.indexOf("\n") !== -1; + const isBlankLine = sel.lineVal.trim().length === 0; + const isFourSpacesIndent = this.siteSettings.code_formatting_style === FOUR_SPACES_INDENT; - if (this.siteSettings.code_formatting_style === FOUR_SPACES_INDENT) { - return (hasNewLine ? - this._applySurround(sel, ' ', '', 'code_text') : - this._applySurround(sel, '`', '`', 'code_text')); - } else { - const preNewline = (sel.pre[-1] !== "\n" && sel.pre !== "") ? "\n" : ""; - const postNewline = sel.post[0] !== "\n" ? "\n" : ""; - - if (hasNewLine) { - return this._addText(sel, `${preNewline}\`\`\`\n${sel.value}\n\`\`\`${postNewline}`); + if (!hasNewLine) { + if (selValue.length === 0 && isBlankLine) { + if (isFourSpacesIndent) { + const example = I18n.t(`composer.code_text`); + this.set('value', `${sel.pre} ${example}${sel.post}`); + return this._selectText(sel.pre.length + 4, example.length); + } else { + return this._applySurround(sel, "```\n", "\n```", 'paste_code_text'); + } } else { - return this._applySurround(sel, `${preNewline}\`\`\`\n`, `\n\`\`\`${postNewline}`, 'paste_code_text'); + return this._applySurround(sel, '`', '`', 'code_title'); + } + } else { + if (isFourSpacesIndent) { + return this._applySurround(sel, ' ', '', 'code_text'); + } else { + const preNewline = (sel.pre[-1] !== "\n" && sel.pre !== "") ? "\n" : ""; + const postNewline = sel.post[0] !== "\n" ? "\n" : ""; + return this._addText(sel, `${preNewline}\`\`\`\n${sel.value}\n\`\`\`${postNewline}`); } } }, diff --git a/test/javascripts/components/d-editor-test.js.es6 b/test/javascripts/components/d-editor-test.js.es6 index eea8e277c87..4fefd8c819b 100644 --- a/test/javascripts/components/d-editor-test.js.es6 +++ b/test/javascripts/components/d-editor-test.js.es6 @@ -293,7 +293,6 @@ componentTest('code button', { template: '{{d-editor value=value}}', setup() { this.siteSettings.code_formatting_style = '4-spaces-indent'; - this.set('value', "first line\n\nsecond line\n\nthird line"); }, test(assert) { @@ -301,7 +300,56 @@ componentTest('code button', { click('button.code'); andThen(() => { - assert.equal(this.get('value'), "first line\n\nsecond line\n\nthird line`" + I18n.t('composer.code_text') + "`"); + assert.equal(this.get('value'), +` ${I18n.t('composer.code_text')}` + ); + + this.set('value', "first line\n\nsecond line\n\nthird line"); + + textarea.selectionStart = 11; + textarea.selectionEnd = 11; + }); + + click('button.code'); + andThen(() => { + assert.equal(this.get('value'), +`first line + ${I18n.t('composer.code_text')} +second line + +third line` + ); + + this.set('value', "first line\n\nsecond line\n\nthird line"); + }); + + + click('button.code'); + andThen(() => { + assert.equal(this.get('value'), +`first line + +second line + +third line\`${I18n.t('composer.code_title')}\`` + ); + this.set('value', "first line\n\nsecond line\n\nthird line"); + }); + + andThen(() => { + textarea.selectionStart = 5; + textarea.selectionEnd = 5; + }); + + click('button.code'); + andThen(() => { + assert.equal(this.get('value'), +`first\`${I18n.t('composer.code_title')}\` line + +second line + +third line` + ); this.set('value', "first line\n\nsecond line\n\nthird line"); }); @@ -357,8 +405,7 @@ componentTest('code fences', { assert.equal(this.get('value'), `\`\`\` ${I18n.t("composer.paste_code_text")} -\`\`\` -` +\`\`\`` ); assert.equal(textarea.selectionStart, 4); @@ -393,16 +440,13 @@ third line click('button.code'); andThen(() => { assert.equal(this.get('value'), -`\`\`\` -${I18n.t('composer.paste_code_text')} -\`\`\` -first line +`\`${I18n.t('composer.code_title')}\`first line second line third line` ); - assert.equal(textarea.selectionStart, 4); - assert.equal(textarea.selectionEnd, 27); + assert.equal(textarea.selectionStart, 1); + assert.equal(textarea.selectionEnd, I18n.t('composer.code_title').length + 1); this.set('value', 'first line\nsecond line\nthird line'); @@ -413,15 +457,13 @@ third line` click('button.code'); andThen(() => { assert.equal(this.get('value'), -`\`\`\` -first line -\`\`\` +`\`first line\` second line third line` ); - assert.equal(textarea.selectionStart, 4); - assert.equal(textarea.selectionEnd, 14); + assert.equal(textarea.selectionStart, 1); + assert.equal(textarea.selectionEnd, 11); this.set('value', 'first line\nsecond line\nthird line');