diff --git a/app/assets/javascripts/discourse/app/components/quote-button.js b/app/assets/javascripts/discourse/app/components/quote-button.js index 3c057ce72f7..c5a7038b4fb 100644 --- a/app/assets/javascripts/discourse/app/components/quote-button.js +++ b/app/assets/javascripts/discourse/app/components/quote-button.js @@ -39,9 +39,9 @@ function getQuoteTitle(element) { } function fixQuotes(str) { - // u+201c “ - // u+201d ” - return str.replace(/[\u201C\u201D]/g, '"'); + // u+201c, u+201d = “ ” + // u+2018, u+2019 = ‘ ’ + return str.replace(/[\u201C\u201D]/g, '"').replace(/[\u2018\u2019]/g, "'"); } export default Component.extend(KeyEnterEscape, { diff --git a/spec/support/system_helpers.rb b/spec/support/system_helpers.rb index 336584a231c..a9d472a729b 100644 --- a/spec/support/system_helpers.rb +++ b/spec/support/system_helpers.rb @@ -80,4 +80,19 @@ module SystemHelpers def using_session(name, &block) Capybara.using_session(name.to_s + self.method_name, &block) end + + def select_text_range(selector, start = 0, offset = 5) + js = <<-JS + const node = document.querySelector(arguments[0]).childNodes[0]; + const selection = window.getSelection(); + const range = document.createRange(); + range.selectNodeContents(node); + range.setStart(node, arguments[1]); + range.setEnd(node, arguments[1] + arguments[2]); + selection.removeAllRanges(); + selection.addRange(range); + JS + + page.execute_script(js, selector, start, offset) + end end diff --git a/spec/system/fast_edit_spec.rb b/spec/system/fast_edit_spec.rb new file mode 100644 index 00000000000..38bcc4f2b72 --- /dev/null +++ b/spec/system/fast_edit_spec.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +describe "Fast edit", type: :system, js: true do + let(:topic_page) { PageObjects::Pages::Topic.new } + let(:fast_editor) { PageObjects::Components::FastEditor.new } + fab!(:topic) { Fabricate(:topic) } + fab!(:post) { Fabricate(:post, topic: topic) } + fab!(:post_2) { Fabricate(:post, topic: topic, raw: "It ‘twas a great’ “time”!") } + fab!(:current_user) { Fabricate(:admin) } + + before { sign_in(current_user) } + + context "when text selected it opens contact menu and fast editor" do + it "opens context menu and fast edit dialog" do + topic_page.visit_topic(topic) + + select_text_range("#{topic_page.post_by_number_selector(1)} .cooked p", 0, 10) + expect(topic_page.fast_edit_button).to be_visible + + topic_page.click_fast_edit_button + expect(topic_page.fast_edit_input).to be_visible + end + + it "edits first paragraph and saves changes" do + topic_page.visit_topic(topic) + + select_text_range("#{topic_page.post_by_number_selector(1)} .cooked p", 0, 5) + topic_page.click_fast_edit_button + + fast_editor.fill_content("Howdy") + fast_editor.save + + within("#post_1 .cooked > p") do |el| + expect(el).not_to eq("Hello world") + expect(el).to have_content("Howdy") + end + end + end + + context "when editing text that has strange characters" do + it "saves when paragraph contains apostrophe" do + topic_page.visit_topic(topic) + + select_text_range("#{topic_page.post_by_number_selector(2)} .cooked p", 19, 4) + topic_page.click_fast_edit_button + + fast_editor.fill_content("day") + fast_editor.save + + expect(find("#{topic_page.post_by_number_selector(2)} .cooked p")).to have_content( + "It ‘twas a great’ “day”!", + ) + end + end +end diff --git a/spec/system/page_objects/components/fast_editor.rb b/spec/system/page_objects/components/fast_editor.rb new file mode 100644 index 00000000000..93ff5135a03 --- /dev/null +++ b/spec/system/page_objects/components/fast_editor.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module PageObjects + module Components + class FastEditor < PageObjects::Components::Base + def fill_content(content) + fast_edit_input.fill_in(with: content) + self + end + + def clear_content + fill_content("") + end + + def has_content?(content) + fast_edit_input.value == content + end + + def save + find(".save-fast-edit").click + end + + def fast_edit_input + find("#fast-edit-input") + end + end + end +end diff --git a/spec/system/page_objects/pages/topic.rb b/spec/system/page_objects/pages/topic.rb index f8633154681..a9a75c8ba67 100644 --- a/spec/system/page_objects/pages/topic.rb +++ b/spec/system/page_objects/pages/topic.rb @@ -5,6 +5,7 @@ module PageObjects class Topic < PageObjects::Pages::Base def initialize @composer_component = PageObjects::Components::Composer.new + @fast_edit_component = PageObjects::Components::FastEditor.new end def visit_topic(topic) @@ -114,6 +115,18 @@ module PageObjects @composer_component.fill_title(title) end + def fast_edit_button + find(".quote-button .quote-edit-label") + end + + def click_fast_edit_button + find(".quote-button .quote-edit-label").click + end + + def fast_edit_input + @fast_edit_component.fast_edit_input + end + private def topic_footer_button_id(button)