From 427fa36edd509cf9b410f5f0dff3d01e44944b5a Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Wed, 26 Apr 2023 10:05:48 +0200 Subject: [PATCH] FIX: generates markdown from pasting link (#21241) After removing `TextareaTextManipulation` from `ChatComposer` and using `TextareaInteractor` as a proxy, one function has been forgotten: `paste(event)` which is not available in glimmer components anymore, and even less avaiable now that the mixin is not tied to a component anymore but a real DOM node. As a solution we now add a manual paste event listener which will call `paste(event)`. --- .../app/mixins/textarea-text-manipulation.js | 20 +++++++----- .../discourse/lib/textarea-interactor.js | 14 +++++++++ .../chat/spec/system/chat_composer_spec.rb | 31 +++++++++++++++++++ 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/discourse/app/mixins/textarea-text-manipulation.js b/app/assets/javascripts/discourse/app/mixins/textarea-text-manipulation.js index 46e4b7cc729..73bde2f7cbc 100644 --- a/app/assets/javascripts/discourse/app/mixins/textarea-text-manipulation.js +++ b/app/assets/javascripts/discourse/app/mixins/textarea-text-manipulation.js @@ -402,10 +402,12 @@ export default Mixin.create({ plainText = plainText.replace(/\r/g, ""); const table = this.extractTable(plainText); if (table) { - this.appEvents.trigger( - `${this.composerEventPrefix}:insert-text`, - table - ); + this.composerEventPrefix + ? this.appEvents.trigger( + `${this.composerEventPrefix}:insert-text`, + table + ) + : this.insertText(table); handled = true; } } @@ -457,10 +459,12 @@ export default Mixin.create({ } if (isComposer) { - this.appEvents.trigger( - `${this.composerEventPrefix}:insert-text`, - markdown - ); + this.composerEventPrefix + ? this.appEvents.trigger( + `${this.composerEventPrefix}:insert-text`, + markdown + ) + : this.insertText(markdown); handled = true; } } diff --git a/plugins/chat/assets/javascripts/discourse/lib/textarea-interactor.js b/plugins/chat/assets/javascripts/discourse/lib/textarea-interactor.js index 025f9c316d8..d10eb0c5504 100644 --- a/plugins/chat/assets/javascripts/discourse/lib/textarea-interactor.js +++ b/plugins/chat/assets/javascripts/discourse/lib/textarea-interactor.js @@ -3,6 +3,7 @@ import TextareaTextManipulation from "discourse/mixins/textarea-text-manipulatio import { next, schedule } from "@ember/runloop"; import { setOwner } from "@ember/application"; import { inject as service } from "@ember/service"; +import { registerDestructor } from "@ember/destroyable"; // This class sole purpose is to provide a way to interact with the textarea // using the existing TextareaTextManipulation mixin without using it directly @@ -12,6 +13,7 @@ export default class TextareaInteractor extends EmberObject.extend( ) { @service capabilities; @service site; + @service siteSettings; constructor(owner, textarea) { super(...arguments); @@ -20,6 +22,18 @@ export default class TextareaInteractor extends EmberObject.extend( this._textarea = textarea; this.element = this._textarea; this.ready = true; + this.composerFocusSelector = ".chat-composer__input"; + + this.init(); // mixin init wouldn't be called otherwise + this.composerEventPrefix = null; // we don't need app events + + // paste is using old native ember events defined on composer + this.textarea.addEventListener("paste", this.paste); + registerDestructor(this, (instance) => instance.teardown()); + } + + teardown() { + this.textarea.removeEventListener("paste", this.paste); } set value(value) { diff --git a/plugins/chat/spec/system/chat_composer_spec.rb b/plugins/chat/spec/system/chat_composer_spec.rb index 22d59dd6e55..0e94ec482e4 100644 --- a/plugins/chat/spec/system/chat_composer_spec.rb +++ b/plugins/chat/spec/system/chat_composer_spec.rb @@ -262,4 +262,35 @@ RSpec.describe "Chat composer", type: :system, js: true do expect(find(".chat-composer__input").value).to eq("bb") end end + + context "when pasting link over selected text" do + before do + channel_1.add(current_user) + sign_in(current_user) + end + + it "outputs a markdown link" do + modifier = /darwin/i =~ RbConfig::CONFIG["host_os"] ? :command : :control + select_text = <<-JS + const element = document.querySelector(arguments[0]); + element.focus(); + element.setSelectionRange(0, element.value.length) + JS + + chat.visit_channel(channel_1) + + find("body").send_keys("https://www.discourse.org") + page.execute_script(select_text, ".chat-composer__input") + + page.send_keys [modifier, "c"] + page.send_keys [:backspace] + + find("body").send_keys("discourse") + page.execute_script(select_text, ".chat-composer__input") + + page.send_keys [modifier, "v"] + + expect(find(".chat-composer__input").value).to eq("[discourse](https://www.discourse.org)") + end + end end