From ab4c953d8258e9f857cc945d7b0a59082051b623 Mon Sep 17 00:00:00 2001 From: Vinoth Kannan Date: Mon, 4 Dec 2017 20:53:42 +0530 Subject: [PATCH] FEATURE: Paste plain text table as Markdown table --- .../components/composer-editor.js.es6 | 4 +- .../discourse/components/d-editor.js.es6 | 39 +++++++++++++++++-- .../discourse/lib/utilities.js.es6 | 10 ++--- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/discourse/components/composer-editor.js.es6 b/app/assets/javascripts/discourse/components/composer-editor.js.es6 index 39835269769..065a92db77e 100644 --- a/app/assets/javascripts/discourse/components/composer-editor.js.es6 +++ b/app/assets/javascripts/discourse/components/composer-editor.js.es6 @@ -396,10 +396,10 @@ export default Ember.Component.extend({ }); $element.on('fileuploadpaste', (e) => { - let {types} = clipboardData(e); + const clipboard = clipboardData(e); this._pasted = true; - if (types.some(t => t === "text/plain")) { + if (clipboard.types.some(t => t === "text/plain")) { e.preventDefault(); } }); diff --git a/app/assets/javascripts/discourse/components/d-editor.js.es6 b/app/assets/javascripts/discourse/components/d-editor.js.es6 index b46c934568d..1d29e8b3c91 100644 --- a/app/assets/javascripts/discourse/components/d-editor.js.es6 +++ b/app/assets/javascripts/discourse/components/d-editor.js.es6 @@ -616,10 +616,43 @@ export default Ember.Component.extend({ Ember.run.scheduleOnce("afterRender", () => $textarea.focus()); }, - paste(e) { - let {types} = clipboardData(e); + _detectTable(text) { + if (text.endsWith("\n")) { + text = text.substring(0, text.length - 1); + let rows = text.split("\r").join("").split("\n"); - if (types.some(t => t === "Files") && !types.some(t => t === "text/plain")) { + if (rows.length > 1) { + const columns = rows.map(r => r.split("\t").length); + const isTable = columns.reduce((a, b) => a && columns[0] === b && b > 1); + + if (isTable) { + const splitterRow = [...Array(columns[0])].map(c => "---").join("\t"); + rows.splice(1, 0, splitterRow); + + return "|" + rows.map(r => r.split("\t").join("|")).join("|\n|") + "|\n"; + } + } + } + return null; + }, + + paste(e) { + const clipboard = clipboardData(e); + const types = clipboard.types; + let preventDefault = false; + + if (types.some(t => t === "text/plain")) { + const text = clipboard.getData("text/plain"); + const table = this._detectTable(text); + if (table) { + this._addText(this._getSelected(), table); + preventDefault = true; + } + } else if (types.some(t => t === "Files")) { + preventDefault = true; + } + + if (preventDefault) { e.preventDefault(); } }, diff --git a/app/assets/javascripts/discourse/lib/utilities.js.es6 b/app/assets/javascripts/discourse/lib/utilities.js.es6 index 625b68c68e7..7a460cd0ae3 100644 --- a/app/assets/javascripts/discourse/lib/utilities.js.es6 +++ b/app/assets/javascripts/discourse/lib/utilities.js.es6 @@ -422,12 +422,10 @@ export function isAppleDevice() { } export function clipboardData(e) { - let data = e.clipboardData || - e.originalEvent.clipboardData || - e.delegatedEvent.originalEvent.clipboardData || - event.clipboardData; - - return { items: data.items, types: data.types }; + return e.clipboardData || + e.originalEvent.clipboardData || + e.delegatedEvent.originalEvent.clipboardData || + event.clipboardData; } // This prevents a mini racer crash