summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/behaviors
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-17 09:08:52 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-17 09:08:52 +0000
commit53ae6b7e3f83591ad251a3f771f5bf3b8cf087ba (patch)
tree5180b96d6a84f36a515cedfa8e81d72de5ccf4fb /app/assets/javascripts/behaviors
parentcfe63cce6a90a1c70397c1b9f6d90480f25cae0a (diff)
downloadgitlab-ce-53ae6b7e3f83591ad251a3f771f5bf3b8cf087ba.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/behaviors')
-rw-r--r--app/assets/javascripts/behaviors/markdown/render_mermaid.js19
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts.js23
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js22
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue60
4 files changed, 122 insertions, 2 deletions
diff --git a/app/assets/javascripts/behaviors/markdown/render_mermaid.js b/app/assets/javascripts/behaviors/markdown/render_mermaid.js
index c86a4c9f178..3856832de90 100644
--- a/app/assets/javascripts/behaviors/markdown/render_mermaid.js
+++ b/app/assets/javascripts/behaviors/markdown/render_mermaid.js
@@ -1,4 +1,5 @@
import flash from '~/flash';
+import $ from 'jquery';
import { sprintf, __ } from '../../locale';
// Renders diagrams and flowcharts from text using Mermaid in any element with the
@@ -18,7 +19,7 @@ import { sprintf, __ } from '../../locale';
// This is an arbitrary number; Can be iterated upon when suitable.
const MAX_CHAR_LIMIT = 5000;
-export default function renderMermaid($els) {
+function renderMermaids($els) {
if (!$els.length) return;
// A diagram may have been truncated in search results which will cause errors, so abort the render.
@@ -95,3 +96,19 @@ export default function renderMermaid($els) {
flash(`Can't load mermaid module: ${err}`);
});
}
+
+export default function renderMermaid($els) {
+ if (!$els.length) return;
+
+ const visibleMermaids = $els.filter(function filter() {
+ return $(this).closest('details').length === 0;
+ });
+
+ renderMermaids(visibleMermaids);
+
+ $els.closest('details').one('toggle', function toggle() {
+ if (this.open) {
+ renderMermaids($(this).find('.js-render-mermaid'));
+ }
+ });
+}
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
index 66cb9fd7672..85636f3e5d2 100644
--- a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
@@ -1,6 +1,9 @@
import $ from 'jquery';
import Cookies from 'js-cookie';
import Mousetrap from 'mousetrap';
+import Vue from 'vue';
+import { disableShortcuts, shouldDisableShortcuts } from './shortcuts_toggle';
+import ShortcutsToggle from './shortcuts_toggle.vue';
import axios from '../../lib/utils/axios_utils';
import { refreshCurrentPage, visitUrl } from '../../lib/utils/url_utility';
import findAndFollowLink from '../../lib/utils/navigation_utility';
@@ -15,6 +18,15 @@ Mousetrap.stopCallback = (e, element, combo) => {
return defaultStopCallback(e, element, combo);
};
+function initToggleButton() {
+ return new Vue({
+ el: document.querySelector('.js-toggle-shortcuts'),
+ render(createElement) {
+ return createElement(ShortcutsToggle);
+ },
+ });
+}
+
export default class Shortcuts {
constructor() {
this.onToggleHelp = this.onToggleHelp.bind(this);
@@ -48,6 +60,14 @@ export default class Shortcuts {
$(this).remove();
e.preventDefault();
});
+
+ $('.js-shortcuts-modal-trigger')
+ .off('click')
+ .on('click', this.onToggleHelp);
+
+ if (shouldDisableShortcuts()) {
+ disableShortcuts();
+ }
}
onToggleHelp(e) {
@@ -104,7 +124,8 @@ export default class Shortcuts {
}
return $('.js-more-help-button').remove();
- });
+ })
+ .then(initToggleButton);
}
focusFilter(e) {
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js
new file mode 100644
index 00000000000..66aa1b752ae
--- /dev/null
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js
@@ -0,0 +1,22 @@
+import Mousetrap from 'mousetrap';
+import 'mousetrap/plugins/pause/mousetrap-pause';
+
+const shorcutsDisabledKey = 'shortcutsDisabled';
+
+export const shouldDisableShortcuts = () => {
+ try {
+ return localStorage.getItem(shorcutsDisabledKey) === 'true';
+ } catch (e) {
+ return false;
+ }
+};
+
+export function enableShortcuts() {
+ localStorage.setItem(shorcutsDisabledKey, false);
+ Mousetrap.unpause();
+}
+
+export function disableShortcuts() {
+ localStorage.setItem(shorcutsDisabledKey, true);
+ Mousetrap.pause();
+}
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue
new file mode 100644
index 00000000000..a53b1b06be9
--- /dev/null
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue
@@ -0,0 +1,60 @@
+<script>
+import { GlToggle, GlSprintf } from '@gitlab/ui';
+import AccessorUtilities from '~/lib/utils/accessor';
+import { disableShortcuts, enableShortcuts, shouldDisableShortcuts } from './shortcuts_toggle';
+
+export default {
+ components: {
+ GlSprintf,
+ GlToggle,
+ },
+ data() {
+ return {
+ localStorageUsable: AccessorUtilities.isLocalStorageAccessSafe(),
+ shortcutsEnabled: !shouldDisableShortcuts(),
+ };
+ },
+ methods: {
+ onChange(value) {
+ this.shortcutsEnabled = value;
+ if (value) {
+ enableShortcuts();
+ } else {
+ disableShortcuts();
+ }
+ },
+ },
+};
+</script>
+
+<template>
+ <div v-if="localStorageUsable" class="d-inline-flex align-items-center js-toggle-shortcuts">
+ <gl-toggle
+ v-model="shortcutsEnabled"
+ aria-describedby="shortcutsToggle"
+ class="prepend-left-10 mb-0"
+ label-position="right"
+ @change="onChange"
+ >
+ <template #labelOn>
+ <gl-sprintf
+ :message="__('%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Enabled')"
+ >
+ <template #screenreaderOnly="{ content }">
+ <span class="sr-only">{{ content }}</span>
+ </template>
+ </gl-sprintf>
+ </template>
+ <template #labelOff>
+ <gl-sprintf
+ :message="__('%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled')"
+ >
+ <template #screenreaderOnly="{ content }">
+ <span class="sr-only">{{ content }}</span>
+ </template>
+ </gl-sprintf>
+ </template>
+ </gl-toggle>
+ <div id="shortcutsToggle" class="sr-only">{{ __('Enable or disable keyboard shortcuts') }}</div>
+ </div>
+</template>