From ad41523895974bc954b423342768c8bd41f5b751 Mon Sep 17 00:00:00 2001 From: Vinoth Kannan Date: Mon, 18 Dec 2017 22:12:05 +0530 Subject: [PATCH] FEATURE: Converting code tags to Markdown while pasting --- .../discourse/components/d-editor.js.es6 | 38 ++++++++----- .../discourse/lib/to-markdown.js.es6 | 56 +++++++++++++++++-- .../discourse/lib/utilities.js.es6 | 2 +- test/javascripts/lib/to-markdown-test.js.es6 | 24 +++++++- 4 files changed, 100 insertions(+), 20 deletions(-) diff --git a/app/assets/javascripts/discourse/components/d-editor.js.es6 b/app/assets/javascripts/discourse/components/d-editor.js.es6 index 3c8970fb22b..f7ff2e51c14 100644 --- a/app/assets/javascripts/discourse/components/d-editor.js.es6 +++ b/app/assets/javascripts/discourse/components/d-editor.js.es6 @@ -37,6 +37,11 @@ const FOUR_SPACES_INDENT = '4-spaces-indent'; const _createCallbacks = []; +const isInside = (text, regex) => { + const matches = text.match(regex); + return matches && (matches.length % 2); +}; + class Toolbar { constructor(site) { @@ -639,24 +644,13 @@ export default Ember.Component.extend({ return null; }, - _pasteMarkdown(text) { - const { pre, lineVal } = this._getSelected(null, {lineVal: true}); - - if(lineVal && pre.match(/[^\n]$/)) { // inline pasting - text = text.replace(/^#+/, "").trim(); - text = pre.match(/\S$/) ? ` ${text}` : text; - } - - this.appEvents.trigger('composer:insert-text', text); - }, - paste(e) { if (!$(".d-editor-input").is(":focus")) { return; } const isComposer = $("#reply-control .d-editor-input").is(":focus"); - const { clipboard, canPasteHtml } = clipboardData(e, isComposer); + let { clipboard, canPasteHtml } = clipboardData(e, isComposer); let plainText = clipboard.getData("text/plain"); let html = clipboard.getData("text/html"); @@ -673,11 +667,27 @@ export default Ember.Component.extend({ } } + const { pre, lineVal } = this._getSelected(null, {lineVal: true}); + const isInlinePasting = pre.match(/[^\n]$/); + + if (canPasteHtml && plainText) { + if (isInlinePasting) { + canPasteHtml = !(lineVal.match(/^```/) || isInside(pre, /`/g) || lineVal.match(/^ /)); + } else { + canPasteHtml = !isInside(pre, /(^|\n)```/g); + } + } + if (canPasteHtml && !handled) { - const markdown = toMarkdown(html); + let markdown = toMarkdown(html); if (!plainText || plainText.length < markdown.length) { - this._pasteMarkdown(markdown); + if(isInlinePasting) { + markdown = markdown.replace(/^#+/, "").trim(); + markdown = pre.match(/\S$/) ? ` ${markdown}` : markdown; + } + + this.appEvents.trigger('composer:insert-text', markdown); handled = true; } } diff --git a/app/assets/javascripts/discourse/lib/to-markdown.js.es6 b/app/assets/javascripts/discourse/lib/to-markdown.js.es6 index 6a5d000c58a..1d5e771f1b6 100644 --- a/app/assets/javascripts/discourse/lib/to-markdown.js.es6 +++ b/app/assets/javascripts/discourse/lib/to-markdown.js.es6 @@ -183,6 +183,24 @@ class Tag { }; } + static code() { + return class extends Tag { + constructor() { + super("code", "`", "`"); + } + + decorate(text) { + if (this.element.parentNames.includes("pre")) { + this.prefix = '\n\n```\n'; + this.suffix = '\n```\n\n'; + } + + text = $('