diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js index a0bfd337d10a793494108c597222d5cb98578da5..9f8d7272e5c52e9afca92f48934fc8844a9ab850 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js @@ -1,64 +1,8 @@ import { PROJECT_FILES_GO_TO_PERMALINK } from '~/behaviors/shortcuts/keybindings'; -import { - getLocationHash, - updateHistory, - urlIsDifferent, - urlContainsSha, - getShaFromUrl, -} from '~/lib/utils/url_utility'; -import { updateRefPortionOfTitle } from '~/repository/utils/title'; - -const defaults = { - fileBlobPermalinkUrl: null, - fileBlobPermalinkUrlElement: null, -}; - -function eventHasModifierKeys(event) { - // We ignore alt because I don't think alt clicks normally do anything special? - return event.ctrlKey || event.metaKey || event.shiftKey; -} +import { moveToFilePermalink } from '~/blob/utils'; export default class ShortcutsBlob { - constructor(shortcuts, opts) { - const options = { ...defaults, ...opts }; - this.options = options; - - this.shortcircuitPermalinkButton(); - - shortcuts.add(PROJECT_FILES_GO_TO_PERMALINK, this.moveToFilePermalink.bind(this)); - } - - moveToFilePermalink() { - const permalink = this.options.fileBlobPermalinkUrl; - - if (permalink) { - const hash = getLocationHash(); - const hashUrlString = hash ? `#${hash}` : ''; - - if (urlIsDifferent(permalink)) { - updateHistory({ - url: `${permalink}${hashUrlString}`, - title: document.title, - }); - } - - if (urlContainsSha({ url: permalink })) { - updateRefPortionOfTitle(getShaFromUrl({ url: permalink })); - } - } - } - - shortcircuitPermalinkButton() { - const button = this.options.fileBlobPermalinkUrlElement; - const handleButton = (e) => { - if (!eventHasModifierKeys(e)) { - e.preventDefault(); - this.moveToFilePermalink(); - } - }; - - if (button) { - button.addEventListener('click', handleButton); - } + constructor(shortcuts) { + shortcuts.add(PROJECT_FILES_GO_TO_PERMALINK, moveToFilePermalink); } } diff --git a/app/assets/javascripts/blob/utils.js b/app/assets/javascripts/blob/utils.js index b2400a4b22473626d1fb51a0b9d5434f0efb20eb..0ecc8be102721142edc3f45d272e7bfac6dbb5be 100644 --- a/app/assets/javascripts/blob/utils.js +++ b/app/assets/javascripts/blob/utils.js @@ -1,4 +1,11 @@ -import { getBaseURL } from '~/lib/utils/url_utility'; +import { + getBaseURL, + updateHistory, + urlIsDifferent, + urlContainsSha, + getShaFromUrl, +} from '~/lib/utils/url_utility'; +import { updateRefPortionOfTitle } from '~/repository/utils/title'; const blameLinesPerPage = document.querySelector('.js-per-page')?.dataset?.blamePerPage; @@ -15,4 +22,40 @@ export const getPageSearchString = (path, page) => { return url.search; }; +export function moveToFilePermalink() { + const fileBlobPermalinkUrlElement = document.querySelector('.js-data-file-blob-permalink-url'); + const permalink = fileBlobPermalinkUrlElement?.getAttribute('href'); + + if (!permalink) { + return; + } + + if (urlIsDifferent(permalink)) { + updateHistory({ + url: permalink, + title: document.title, + }); + + if (urlContainsSha({ url: permalink })) { + updateRefPortionOfTitle(getShaFromUrl({ url: permalink })); + } + } +} + +function eventHasModifierKeys(event) { + // We ignore alt because I don't think alt clicks normally do anything special? + return event.ctrlKey || event.metaKey || event.shiftKey; +} + +export function shortcircuitPermalinkButton() { + const fileBlobPermalinkUrlElement = document.querySelector('.js-data-file-blob-permalink-url'); + + fileBlobPermalinkUrlElement?.addEventListener('click', (e) => { + if (!eventHasModifierKeys(e)) { + e.preventDefault(); + moveToFilePermalink(); + } + }); +} + export default () => ({}); diff --git a/app/assets/javascripts/pages/projects/init_blob.js b/app/assets/javascripts/pages/projects/init_blob.js index 6e3e1a35bd27d98e9cf0d708b2860a093309dbc3..0cf109c71210683d0d965c262f49c46ba4066dcd 100644 --- a/app/assets/javascripts/pages/projects/init_blob.js +++ b/app/assets/javascripts/pages/projects/init_blob.js @@ -1,5 +1,6 @@ import { addShortcutsExtension } from '~/behaviors/shortcuts'; import ShortcutsBlob from '~/behaviors/shortcuts/shortcuts_blob'; +import { shortcircuitPermalinkButton } from '~/blob/utils'; import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation'; import BlobForkSuggestion from '~/blob/blob_fork_suggestion'; import BlobLinePermalinkUpdater from '~/blob/blob_line_permalink_updater'; @@ -15,15 +16,10 @@ export default () => { document.querySelectorAll('.js-data-file-blob-permalink-url, .js-blob-blame-link'), ); - const fileBlobPermalinkUrlElement = document.querySelector('.js-data-file-blob-permalink-url'); - const fileBlobPermalinkUrl = - fileBlobPermalinkUrlElement && fileBlobPermalinkUrlElement.getAttribute('href'); + shortcircuitPermalinkButton(); addShortcutsExtension(ShortcutsNavigation); - addShortcutsExtension(ShortcutsBlob, { - fileBlobPermalinkUrl, - fileBlobPermalinkUrlElement, - }); + addShortcutsExtension(ShortcutsBlob); new BlobForkSuggestion({ openButtons: document.querySelectorAll('.js-edit-blob-link-fork-toggler'), diff --git a/app/assets/javascripts/repository/components/blob_controls.vue b/app/assets/javascripts/repository/components/blob_controls.vue index af7dc9ecc2af66c253645fa8533f0d5414368b78..5571796cd9227cdde4adb5cca7df91764364d3c7 100644 --- a/app/assets/javascripts/repository/components/blob_controls.vue +++ b/app/assets/javascripts/repository/components/blob_controls.vue @@ -8,6 +8,7 @@ import Shortcuts from '~/behaviors/shortcuts/shortcuts'; import { addShortcutsExtension } from '~/behaviors/shortcuts'; import { shouldDisableShortcuts } from '~/behaviors/shortcuts/shortcuts_toggle'; import ShortcutsBlob from '~/behaviors/shortcuts/shortcuts_blob'; +import { shortcircuitPermalinkButton } from '~/blob/utils'; import BlobLinePermalinkUpdater from '~/blob/blob_line_permalink_updater'; import { keysFor, @@ -133,15 +134,8 @@ export default { }, methods: { initShortcuts() { - const fileBlobPermalinkUrlElement = document.querySelector( - '.js-data-file-blob-permalink-url', - ); - const fileBlobPermalinkUrl = - fileBlobPermalinkUrlElement && fileBlobPermalinkUrlElement.getAttribute('href'); - addShortcutsExtension(ShortcutsBlob, { - fileBlobPermalinkUrl, - fileBlobPermalinkUrlElement, - }); + shortcircuitPermalinkButton(); + addShortcutsExtension(ShortcutsBlob); }, initLinksUpdate() { // eslint-disable-next-line no-new diff --git a/spec/features/projects/blobs/shortcuts_blob_spec.rb b/spec/features/projects/blobs/shortcuts_blob_spec.rb index 162066540d9d4c21434405684e7c4163f54cf93f..0de9137f9ec70b9e606c62d928241955361ebfc8 100644 --- a/spec/features/projects/blobs/shortcuts_blob_spec.rb +++ b/spec/features/projects/blobs/shortcuts_blob_spec.rb @@ -27,6 +27,20 @@ def visit_blob(fragment = nil) expect(page).to have_current_path(get_absolute_url(project_blob_path(project, tree_join(sha, path))), url: true) end + it 'redirects to permalink of a currently viewed file' do + visit project_path(project) + wait_for_requests + click_link 'VERSION' + wait_for_requests + page.driver.go_back + click_link path + wait_for_requests + + find('body').native.send_key('y') + + expect(page).to have_current_path(get_absolute_url(project_blob_path(project, tree_join(sha, path))), url: true) + end + it 'maintains fragment hash when redirecting' do fragment = "L1" visit_blob(fragment)