summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Eastwood <contact@ericeastwood.com>2017-01-25 21:13:01 -0600
committerEric Eastwood <contact@ericeastwood.com>2017-02-06 16:57:52 -0600
commit584b86da3408826f776ee5e179af91ab61459a46 (patch)
tree33059ba30ec961c2b5dde50d80d932b8bd747185
parent572fb0be9b1d45437b7c0ed1000399657f471ec7 (diff)
downloadgitlab-ce-8082-permalink-to-file.tar.gz
Add keyboard shortcut to move to file permalink8082-permalink-to-file
Fix https://gitlab.com/gitlab-org/gitlab-ce/issues/8082
-rw-r--r--app/assets/javascripts/dispatcher.js.es610
-rw-r--r--app/assets/javascripts/shortcuts_blob.js29
-rw-r--r--app/assets/javascripts/shortcuts_blob.js.es629
-rw-r--r--app/views/help/_shortcuts.html.haml8
-rw-r--r--app/views/projects/blob/_actions.html.haml2
-rw-r--r--changelogs/unreleased/8082-permalink-to-file.yml4
-rw-r--r--spec/features/projects/blobs/shortcuts_blob_spec.rb37
7 files changed, 87 insertions, 32 deletions
diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6
index edec21e3b63..90a0d2ba3e6 100644
--- a/app/assets/javascripts/dispatcher.js.es6
+++ b/app/assets/javascripts/dispatcher.js.es6
@@ -19,7 +19,6 @@
/* global UsersSelect */
/* global GroupAvatar */
/* global LineHighlighter */
-/* global ShortcutsBlob */
/* global ProjectFork */
/* global BuildArtifacts */
/* global GroupsSelect */
@@ -36,6 +35,8 @@
/* global Labels */
/* global Shortcuts */
+const ShortcutsBlob = require('./shortcuts_blob');
+
(function() {
var Dispatcher;
@@ -225,7 +226,12 @@
case 'projects:blame:show':
new LineHighlighter();
shortcut_handler = new ShortcutsNavigation();
- new ShortcutsBlob(true);
+ const fileBlobPermalinkUrlElement = document.querySelector('.js-data-file-blob-permalink-url');
+ const fileBlobPermalinkUrl = fileBlobPermalinkUrlElement && fileBlobPermalinkUrlElement.getAttribute('href');
+ new ShortcutsBlob({
+ skipResetBindings: true,
+ fileBlobPermalinkUrl,
+ });
break;
case 'groups:labels:new':
case 'groups:labels:edit':
diff --git a/app/assets/javascripts/shortcuts_blob.js b/app/assets/javascripts/shortcuts_blob.js
deleted file mode 100644
index a3e549a2735..00000000000
--- a/app/assets/javascripts/shortcuts_blob.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* eslint-disable func-names, space-before-function-paren, max-len, one-var, no-var, no-restricted-syntax, vars-on-top, no-use-before-define, no-param-reassign, new-cap, no-underscore-dangle, wrap-iife, consistent-return */
-/* global Shortcuts */
-/* global Mousetrap */
-
-require('./shortcuts');
-
-(function() {
- var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
- hasProp = {}.hasOwnProperty;
-
- this.ShortcutsBlob = (function(superClass) {
- extend(ShortcutsBlob, superClass);
-
- function ShortcutsBlob(skipResetBindings) {
- ShortcutsBlob.__super__.constructor.call(this, skipResetBindings);
- Mousetrap.bind('y', ShortcutsBlob.copyToClipboard);
- }
-
- ShortcutsBlob.copyToClipboard = function() {
- var clipboardButton;
- clipboardButton = $('.btn-clipboard');
- if (clipboardButton) {
- return clipboardButton.click();
- }
- };
-
- return ShortcutsBlob;
- })(Shortcuts);
-}).call(this);
diff --git a/app/assets/javascripts/shortcuts_blob.js.es6 b/app/assets/javascripts/shortcuts_blob.js.es6
new file mode 100644
index 00000000000..bfe90aef71e
--- /dev/null
+++ b/app/assets/javascripts/shortcuts_blob.js.es6
@@ -0,0 +1,29 @@
+/* global Mousetrap */
+/* global Shortcuts */
+
+require('./shortcuts');
+
+const defaults = {
+ skipResetBindings: false,
+ fileBlobPermalinkUrl: null,
+};
+
+class ShortcutsBlob extends Shortcuts {
+ constructor(opts) {
+ const options = Object.assign({}, defaults, opts);
+ super(options.skipResetBindings);
+ this.options = options;
+
+ Mousetrap.bind('y', this.moveToFilePermalink.bind(this));
+ }
+
+ moveToFilePermalink() {
+ if (this.options.fileBlobPermalinkUrl) {
+ const hash = gl.utils.getLocationHash();
+ const hashUrlString = hash ? `#${hash}` : '';
+ gl.utils.visitUrl(`${this.options.fileBlobPermalinkUrl}${hashUrlString}`);
+ }
+ }
+}
+
+module.exports = ShortcutsBlob;
diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml
index da2df0d8080..705e20112fa 100644
--- a/app/views/help/_shortcuts.html.haml
+++ b/app/views/help/_shortcuts.html.haml
@@ -79,6 +79,14 @@
%td.shortcut
.key esc
%td Go back
+ %tbody
+ %tr
+ %th
+ %th Project File
+ %tr
+ %td.shortcut
+ .key y
+ %td Go to file permalink
.col-lg-4
%table.shortcut-mappings
diff --git a/app/views/projects/blob/_actions.html.haml b/app/views/projects/blob/_actions.html.haml
index ff893ea74e1..26531f0b1a6 100644
--- a/app/views/projects/blob/_actions.html.haml
+++ b/app/views/projects/blob/_actions.html.haml
@@ -12,7 +12,7 @@
= link_to 'History', namespace_project_commits_path(@project.namespace, @project, @id),
class: 'btn btn-sm'
= link_to 'Permalink', namespace_project_blob_path(@project.namespace, @project,
- tree_join(@commit.sha, @path)), class: 'btn btn-sm'
+ tree_join(@commit.sha, @path)), class: 'btn btn-sm js-data-file-blob-permalink-url'
- if current_user
.btn-group{ role: "group" }
diff --git a/changelogs/unreleased/8082-permalink-to-file.yml b/changelogs/unreleased/8082-permalink-to-file.yml
new file mode 100644
index 00000000000..136d2108c63
--- /dev/null
+++ b/changelogs/unreleased/8082-permalink-to-file.yml
@@ -0,0 +1,4 @@
+---
+title: Add `y` keyboard shortcut to move to file permalink
+merge_request:
+author:
diff --git a/spec/features/projects/blobs/shortcuts_blob_spec.rb b/spec/features/projects/blobs/shortcuts_blob_spec.rb
new file mode 100644
index 00000000000..30e2d587267
--- /dev/null
+++ b/spec/features/projects/blobs/shortcuts_blob_spec.rb
@@ -0,0 +1,37 @@
+require 'spec_helper'
+
+feature 'Blob shortcuts', feature: true do
+ include TreeHelper
+ let(:project) { create(:project, :public, :repository) }
+ let(:path) { project.repository.ls_files(project.repository.root_ref)[0] }
+ let(:sha) { project.repository.commit.sha }
+
+ describe 'On a file(blob)', js: true do
+ def get_absolute_url(path = "")
+ "http://#{page.server.host}:#{page.server.port}#{path}"
+ end
+
+ def visit_blob(fragment = nil)
+ visit namespace_project_blob_path(project.namespace, project, tree_join('master', path), anchor: fragment)
+ end
+
+ describe 'pressing "y"' do
+ it 'redirects to permalink with commit sha' do
+ visit_blob
+
+ find('body').native.send_key('y')
+
+ expect(page).to have_current_path(get_absolute_url(namespace_project_blob_path(project.namespace, project, tree_join(sha, path))), url: true)
+ end
+
+ it 'maintains fragment hash when redirecting' do
+ fragment = "L1"
+ visit_blob(fragment)
+
+ find('body').native.send_key('y')
+
+ expect(page).to have_current_path(get_absolute_url(namespace_project_blob_path(project.namespace, project, tree_join(sha, path), anchor: fragment)), url: true)
+ end
+ end
+ end
+end