Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js47
-rw-r--r--app/assets/javascripts/lib/utils/url_utility.js36
-rw-r--r--app/assets/javascripts/pages/projects/init_blob.js1
-rw-r--r--app/assets/javascripts/repository/utils/title.js14
4 files changed, 94 insertions, 4 deletions
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js
index 052e33b4a2b..d5d8edd5ac0 100644
--- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js
@@ -1,26 +1,67 @@
import Mousetrap from 'mousetrap';
-import { getLocationHash, visitUrl } from '../../lib/utils/url_utility';
+import {
+ getLocationHash,
+ updateHistory,
+ urlIsDifferent,
+ urlContainsSha,
+ getShaFromUrl,
+} from '~/lib/utils/url_utility';
+import { updateRefPortionOfTitle } from '~/repository/utils/title';
import Shortcuts from './shortcuts';
const defaults = {
skipResetBindings: false,
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;
+}
+
export default class ShortcutsBlob extends Shortcuts {
constructor(opts) {
const options = Object.assign({}, defaults, opts);
super(options.skipResetBindings);
this.options = options;
+ this.shortcircuitPermalinkButton();
+
Mousetrap.bind('y', this.moveToFilePermalink.bind(this));
}
moveToFilePermalink() {
- if (this.options.fileBlobPermalinkUrl) {
+ const permalink = this.options.fileBlobPermalinkUrl;
+
+ if (permalink) {
const hash = getLocationHash();
const hashUrlString = hash ? `#${hash}` : '';
- visitUrl(`${this.options.fileBlobPermalinkUrl}${hashUrlString}`);
+
+ 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);
}
}
}
diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js
index d48678c21f6..202363a1dda 100644
--- a/app/assets/javascripts/lib/utils/url_utility.js
+++ b/app/assets/javascripts/lib/utils/url_utility.js
@@ -1,6 +1,14 @@
const PATH_SEPARATOR = '/';
const PATH_SEPARATOR_LEADING_REGEX = new RegExp(`^${PATH_SEPARATOR}+`);
const PATH_SEPARATOR_ENDING_REGEX = new RegExp(`${PATH_SEPARATOR}+$`);
+const SHA_REGEX = /[\da-f]{40}/gi;
+
+// Reset the cursor in a Regex so that multiple uses before a recompile don't fail
+function resetRegExp(regex) {
+ regex.lastIndex = 0; /* eslint-disable-line no-param-reassign */
+
+ return regex;
+}
// Returns a decoded url parameter value
// - Treats '+' as '%20'
@@ -128,6 +136,20 @@ export function doesHashExistInUrl(hashName) {
return hash && hash.includes(hashName);
}
+export function urlContainsSha({ url = String(window.location) } = {}) {
+ return resetRegExp(SHA_REGEX).test(url);
+}
+
+export function getShaFromUrl({ url = String(window.location) } = {}) {
+ let sha = null;
+
+ if (urlContainsSha({ url })) {
+ [sha] = url.match(resetRegExp(SHA_REGEX));
+ }
+
+ return sha;
+}
+
/**
* Apply the fragment to the given url by returning a new url string that includes
* the fragment. If the given url already contains a fragment, the original fragment
@@ -154,6 +176,16 @@ export function visitUrl(url, external = false) {
}
}
+export function updateHistory({ state = {}, title = '', url, replace = false, win = window } = {}) {
+ if (win.history) {
+ if (replace) {
+ win.history.replaceState(state, title, url);
+ } else {
+ win.history.pushState(state, title, url);
+ }
+ }
+}
+
export function refreshCurrentPage() {
visitUrl(window.location.href);
}
@@ -282,3 +314,7 @@ export const setUrlParams = (params, url = window.location.href, clearParams = f
};
export const escapeFileUrl = fileUrl => encodeURIComponent(fileUrl).replace(/%2F/g, '/');
+
+export function urlIsDifferent(url, compare = String(window.location)) {
+ return url !== compare;
+}
diff --git a/app/assets/javascripts/pages/projects/init_blob.js b/app/assets/javascripts/pages/projects/init_blob.js
index bd8afa2d5ba..e862456f429 100644
--- a/app/assets/javascripts/pages/projects/init_blob.js
+++ b/app/assets/javascripts/pages/projects/init_blob.js
@@ -25,6 +25,7 @@ export default () => {
new ShortcutsBlob({
skipResetBindings: true,
fileBlobPermalinkUrl,
+ fileBlobPermalinkUrlElement,
});
new BlobForkSuggestion({
diff --git a/app/assets/javascripts/repository/utils/title.js b/app/assets/javascripts/repository/utils/title.js
index ff16fbdd420..9c4b334a1ce 100644
--- a/app/assets/javascripts/repository/utils/title.js
+++ b/app/assets/javascripts/repository/utils/title.js
@@ -1,5 +1,5 @@
const DEFAULT_TITLE = '· GitLab';
-// eslint-disable-next-line import/prefer-default-export
+
export const setTitle = (pathMatch, ref, project) => {
if (!pathMatch) {
document.title = `${project} ${DEFAULT_TITLE}`;
@@ -12,3 +12,15 @@ export const setTitle = (pathMatch, ref, project) => {
/* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
document.title = `${isEmpty ? 'Files' : path} · ${ref} · ${project} ${DEFAULT_TITLE}`;
};
+
+export function updateRefPortionOfTitle(sha, doc = document) {
+ const { title = '' } = doc;
+ const titleParts = title.split(' · ');
+
+ if (titleParts.length > 1) {
+ titleParts[1] = sha;
+
+ /* eslint-disable-next-line no-param-reassign */
+ doc.title = titleParts.join(' · ');
+ }
+}