diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 9e0a72f81..6b97da279 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -10,8 +10,13 @@ module ApplicationHelper tag.span class: class_names("icon icon--#{name}", options.delete(:class)), "aria-hidden": true, **options end - def back_link_to(label, url, action, **options) - link_to url, class: "btn btn--back btn--circle-mobile", data: { controller: "hotkey", action: action }, **options do + def back_link_to(label, url, action, prefer_referrer: [], **options) + data = { controller: "hotkey", action: action } + if prefer_referrer.any? + data[:turbo_navigation_target] = "referrerBackLink" + data[:turbo_navigation_allowed_referrer_paths] = prefer_referrer.join(",") + end + link_to url, class: "btn btn--back btn--circle-mobile", data: data, **options do icon_tag("arrow-left") + tag.strong("Back to #{label}", class: "overflow-ellipsis") + tag.kbd("ESC", class: "txt-x-small hide-on-touch").html_safe end end diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb index 5f12b9259..814b0b0e2 100644 --- a/app/helpers/boards_helper.rb +++ b/app/helpers/boards_helper.rb @@ -1,6 +1,6 @@ module BoardsHelper - def link_back_to_board(board) - back_link_to board.name, board, "keydown.left@document->hotkey#click keydown.esc@document->hotkey#click click->turbo-navigation#backIfSamePath" + def link_back_to_board(board, prefer_referrer: []) + back_link_to board.name, board, "keydown.left@document->hotkey#click keydown.esc@document->hotkey#click click->turbo-navigation#backIfSamePath", prefer_referrer: end def link_to_edit_board(board) diff --git a/app/javascript/controllers/turbo_navigation_controller.js b/app/javascript/controllers/turbo_navigation_controller.js index d755342e9..8f47dac9b 100644 --- a/app/javascript/controllers/turbo_navigation_controller.js +++ b/app/javascript/controllers/turbo_navigation_controller.js @@ -1,8 +1,12 @@ import { Controller } from "@hotwired/stimulus" export default class extends Controller { + static values = { label: String } + static targets = [ "referrerBackLink" ] + rememberLocation() { sessionStorage.setItem("referrerUrl", window.location.href) + sessionStorage.setItem("referrerLabel", this.labelValue) } backIfSamePath(event) { @@ -16,6 +20,19 @@ export default class extends Controller { Turbo.visit(this.#referrerUrl) } } + + referrerBackLinkTargetConnected(link) { + if (!this.#referrerUrl || !this.#referrerLabel) { return } + + const allowedPaths = (link.dataset.turboNavigationAllowedReferrerPaths || "").split(",") + const referrerPath = new URL(this.#referrerUrl).pathname + if (!allowedPaths.includes(referrerPath)) { return } + + link.href = this.#referrerUrl + const strong = link.querySelector("strong") + if (strong) { strong.textContent = `Back to ${this.#referrerLabel}` } + } + get #referrerPath() { if (!this.#referrerUrl) return null return new URL(this.#referrerUrl).pathname @@ -24,4 +41,8 @@ export default class extends Controller { get #referrerUrl() { return sessionStorage.getItem("referrerUrl") } + + get #referrerLabel() { + return sessionStorage.getItem("referrerLabel") + } } diff --git a/app/views/cards/show.html.erb b/app/views/cards/show.html.erb index fabd2ad02..fd9101d58 100644 --- a/app/views/cards/show.html.erb +++ b/app/views/cards/show.html.erb @@ -7,7 +7,7 @@ <% content_for :header do %>
- <%= link_back_to_board(@card.board) %> + <%= link_back_to_board @card.board, prefer_referrer: [ cards_path, board_path(@card.board) ] %>
<% end %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index b83d199d2..2e54a82df 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -5,6 +5,7 @@ [ + { name: "span", inner_html: "Hello" }, + { name: "br" }, + { name: "span", inner_html: "World" } + ] + end + end + + private + def paste_markdown(markdown) + page.execute_script(<<~JS, markdown) + const dt = new DataTransfer(); + dt.setData("text/plain", arguments[0]); + document.activeElement.dispatchEvent(new ClipboardEvent("paste", { clipboardData: dt, bubbles: true })); + JS + end +end diff --git a/test/system/smoke_test.rb b/test/system/smoke_test.rb index 5af13f890..467483fc1 100644 --- a/test/system/smoke_test.rb +++ b/test/system/smoke_test.rb @@ -76,38 +76,6 @@ class SmokeTest < ApplicationSystemTestCase assert_no_selector "div##{dom_id(notification)}" end - test "markdown paste adds block spacing" do - sign_in_as(users(:david)) - - visit card_url(cards(:layout)) - find("lexxy-editor").click - paste_markdown("Hello\n\nWorld") - - within("lexxy-editor") do - assert_selector "p", text: "Hello" - assert_selector "p br", visible: :all - assert_selector "p", text: "World" - end - end - - test "markdown paste preserves line breaks" do - sign_in_as(users(:david)) - - visit card_url(cards(:layout)) - find("lexxy-editor").click - paste_markdown("Hello\nWorld") - - inner_html = find("lexxy-editor p", text: "Hello").native.property("innerHTML") - children = Nokogiri::HTML5.fragment(inner_html).children - assert_pattern do - children => [ - { name: "span", inner_html: "Hello" }, - { name: "br" }, - { name: "span", inner_html: "World" } - ] - end - end - test "dragging card to a new column" do sign_in_as(users(:david)) @@ -127,22 +95,9 @@ class SmokeTest < ApplicationSystemTestCase end private - def sign_in_as(user) - visit session_transfer_url(user.identity.transfer_id, script_name: nil) - assert_selector "h1", text: "Latest Activity" - end - def fill_in_lexxy(selector = "lexxy-editor", with:) editor_element = find(selector) editor_element.set with page.execute_script("arguments[0].value = '#{with}'", editor_element) end - - def paste_markdown(markdown) - page.execute_script(<<~JS, markdown) - const dt = new DataTransfer(); - dt.setData("text/plain", arguments[0]); - document.activeElement.dispatchEvent(new ClipboardEvent("paste", { clipboardData: dt, bubbles: true })); - JS - end end