From c76caca109e1f0a4cc75c32fe3e088f449a38793 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Tue, 24 Nov 2015 13:03:37 -0500 Subject: [PATCH] FIX: Perform the same operation on multilines in d-editor --- .../discourse/components/d-editor.js.es6 | 56 +++++++++++++------ .../components/d-editor-test.js.es6 | 39 +++++++++++-- 2 files changed, 73 insertions(+), 22 deletions(-) diff --git a/app/assets/javascripts/discourse/components/d-editor.js.es6 b/app/assets/javascripts/discourse/components/d-editor.js.es6 index 019a5d8a72a75e..48cd3b22226414 100644 --- a/app/assets/javascripts/discourse/components/d-editor.js.es6 +++ b/app/assets/javascripts/discourse/components/d-editor.js.es6 @@ -13,6 +13,12 @@ function getHead(head, prev) { } } +const OP = { + NONE: 0, + REMOVED: 1, + ADDED: 2 +}; + const _createCallbacks = []; function Toolbar() { @@ -311,6 +317,37 @@ export default Ember.Component.extend({ }); }, + // perform the same operation over many lines of text + _getMultilineContents(lines, head, hval, hlen, tail, tlen) { + let operation = OP.NONE; + + return lines.map(l => { + if (l.length === 0) { return l; } + + if (operation !== OP.ADDED && + (l.slice(0, hlen) === hval && tlen === 0 || l.slice(-tlen) === tail)) { + operation = OP.REMOVED; + if (tlen === 0) { + const result = l.slice(hlen); + [hval, hlen] = getHead(head, hval); + return result; + } else if (l.slice(-tlen) === tail) { + const result = l.slice(hlen, -tlen); + [hval, hlen] = getHead(head, hval); + return result; + } + } else if (operation === OP.NONE) { + operation = OP.ADDED; + } else if (operation === OP.REMOVED) { + return l; + } + + const result = `${hval}${l}${tail}`; + [hval, hlen] = getHead(head, hval); + return result; + }).join("\n"); + }, + _applySurround(sel, head, tail, exampleKey) { const pre = sel.pre; const post = sel.post; @@ -331,24 +368,7 @@ export default Ember.Component.extend({ this.set('value', `${pre.slice(0, -hlen)}${sel.value}${post.slice(tlen)}`); this._selectText(sel.start - hlen, sel.value.length); } else { - const contents = lines.map(l => { - if (l.length === 0) { return l; } - - if (l.slice(0, hlen) === hval && tlen === 0 || l.slice(-tlen) === tail) { - if (tlen === 0) { - const result = l.slice(hlen); - [hval, hlen] = getHead(head, hval); - return result; - } else if (l.slice(-tlen) === tail) { - const result = l.slice(hlen, -tlen); - [hval, hlen] = getHead(head, hval); - return result; - } - } - const result = `${hval}${l}${tail}`; - [hval, hlen] = getHead(head, hval); - return result; - }).join("\n"); + const contents = this._getMultilineContents(lines, head, hval, hlen, tail, tlen); this.set('value', `${pre}${contents}${post}`); if (lines.length === 1 && tlen > 0) { diff --git a/test/javascripts/components/d-editor-test.js.es6 b/test/javascripts/components/d-editor-test.js.es6 index 745d9586bf8db4..a6454da7ef8eef 100644 --- a/test/javascripts/components/d-editor-test.js.es6 +++ b/test/javascripts/components/d-editor-test.js.es6 @@ -218,6 +218,37 @@ testCase('link modal (link with description)', function(assert) { }); }); +componentTest('advanced code', { + template: '{{d-editor value=value}}', + setup() { + this.set('value', +`function xyz(x, y, z) { + if (y === z) { + return true; + } +}`); + }, + + test(assert) { + const textarea = this.$('textarea.d-editor-input')[0]; + andThen(() => { + textarea.selectionStart = 0; + textarea.selectionEnd = textarea.value.length; + }); + + click('button.code'); + andThen(() => { + assert.equal(this.get('value'), +` function xyz(x, y, z) { + if (y === z) { + return true; + } + }`); + }); + } + +}); + componentTest('code button', { template: '{{d-editor value=value}}', setup() { @@ -342,16 +373,16 @@ testCase(`bullet button with a multiple line selection`, function(assert, textar click(`button.bullet`); andThen(() => { - assert.equal(this.get('value'), "Hello\n\n* World\n\n* Evil"); + assert.equal(this.get('value'), "Hello\n\nWorld\n\nEvil"); assert.equal(textarea.selectionStart, 0); - assert.equal(textarea.selectionEnd, 22); + assert.equal(textarea.selectionEnd, 18); }); click(`button.bullet`); andThen(() => { - assert.equal(this.get('value'), "* Hello\n\nWorld\n\nEvil"); + assert.equal(this.get('value'), "* Hello\n\n* World\n\n* Evil"); assert.equal(textarea.selectionStart, 0); - assert.equal(textarea.selectionEnd, 20); + assert.equal(textarea.selectionEnd, 24); }); });