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:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-04-09 09:09:30 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-04-09 09:09:30 +0300
commit4dfc8711171fe0c04bc6b8b224687603026dea46 (patch)
treee1b4640f8e56bb09f412a3dca1510983245491c2 /app/assets/javascripts/code_navigation
parentcfd62c3a3ebbc85f5787c103bfa6de1997ab8e11 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/code_navigation')
-rw-r--r--app/assets/javascripts/code_navigation/components/app.vue16
-rw-r--r--app/assets/javascripts/code_navigation/index.js4
-rw-r--r--app/assets/javascripts/code_navigation/store/actions.js54
-rw-r--r--app/assets/javascripts/code_navigation/store/mutations.js8
-rw-r--r--app/assets/javascripts/code_navigation/store/state.js4
-rw-r--r--app/assets/javascripts/code_navigation/utils/index.js33
6 files changed, 73 insertions, 46 deletions
diff --git a/app/assets/javascripts/code_navigation/components/app.vue b/app/assets/javascripts/code_navigation/components/app.vue
index 0e0160b9832..d738c914125 100644
--- a/app/assets/javascripts/code_navigation/components/app.vue
+++ b/app/assets/javascripts/code_navigation/components/app.vue
@@ -1,6 +1,7 @@
<script>
import { mapActions, mapState } from 'vuex';
import Popover from './popover.vue';
+import eventHub from '../../notes/event_hub';
export default {
components: {
@@ -10,24 +11,27 @@ export default {
...mapState(['currentDefinition', 'currentDefinitionPosition', 'definitionPathPrefix']),
},
mounted() {
- this.blobViewer = document.querySelector('.blob-viewer');
+ this.body = document.body;
+
+ eventHub.$on('showBlobInteractionZones', this.showBlobInteractionZones);
this.addGlobalEventListeners();
this.fetchData();
},
beforeDestroy() {
+ eventHub.$off('showBlobInteractionZones', this.showBlobInteractionZones);
this.removeGlobalEventListeners();
},
methods: {
- ...mapActions(['fetchData', 'showDefinition']),
+ ...mapActions(['fetchData', 'showDefinition', 'showBlobInteractionZones']),
addGlobalEventListeners() {
- if (this.blobViewer) {
- this.blobViewer.addEventListener('click', this.showDefinition);
+ if (this.body) {
+ this.body.addEventListener('click', this.showDefinition);
}
},
removeGlobalEventListeners() {
- if (this.blobViewer) {
- this.blobViewer.removeEventListener('click', this.showDefinition);
+ if (this.body) {
+ this.body.removeEventListener('click', this.showDefinition);
}
},
},
diff --git a/app/assets/javascripts/code_navigation/index.js b/app/assets/javascripts/code_navigation/index.js
index 2222c986dfe..362c26ae065 100644
--- a/app/assets/javascripts/code_navigation/index.js
+++ b/app/assets/javascripts/code_navigation/index.js
@@ -5,10 +5,10 @@ import App from './components/app.vue';
Vue.use(Vuex);
-export default () => {
+export default initialData => {
const el = document.getElementById('js-code-navigation');
- store.dispatch('setInitialData', el.dataset);
+ store.dispatch('setInitialData', initialData);
return new Vue({
el,
diff --git a/app/assets/javascripts/code_navigation/store/actions.js b/app/assets/javascripts/code_navigation/store/actions.js
index 9b607023f39..6ecede32944 100644
--- a/app/assets/javascripts/code_navigation/store/actions.js
+++ b/app/assets/javascripts/code_navigation/store/actions.js
@@ -12,20 +12,25 @@ export default {
fetchData({ commit, dispatch, state }) {
commit(types.REQUEST_DATA);
- axios
- .get(state.codeNavUrl)
- .then(({ data }) => {
- const normalizedData = data.reduce((acc, d) => {
- if (d.hover) {
- acc[`${d.start_line}:${d.start_char}`] = d;
- addInteractionClass(d);
- }
- return acc;
- }, {});
-
- commit(types.REQUEST_DATA_SUCCESS, normalizedData);
- })
- .catch(() => dispatch('requestDataError'));
+ state.blobs.forEach(({ path, codeNavigationPath }) => {
+ axios
+ .get(codeNavigationPath)
+ .then(({ data }) => {
+ const normalizedData = data.reduce((acc, d) => {
+ if (d.hover) {
+ acc[`${d.start_line}:${d.start_char}`] = d;
+ addInteractionClass(path, d);
+ }
+ return acc;
+ }, {});
+
+ commit(types.REQUEST_DATA_SUCCESS, { path, normalizedData });
+ })
+ .catch(() => dispatch('requestDataError'));
+ });
+ },
+ showBlobInteractionZones({ state }, path) {
+ Object.values(state.data[path]).forEach(d => addInteractionClass(path, d));
},
showDefinition({ commit, state }, { target: el }) {
let definition;
@@ -39,15 +44,28 @@ export default {
getCurrentHoverElement().classList.remove('hll');
}
- if (el.classList.contains('js-code-navigation') && !isCurrentElementPopoverOpen) {
+ const blobEl = el.closest('[data-path]');
+
+ if (!blobEl) {
+ commit(types.SET_CURRENT_DEFINITION, { definition, position });
+
+ return;
+ }
+
+ const data = state.data[blobEl.dataset.path];
+
+ if (!data) return;
+
+ if (el.closest('.js-code-navigation') && !isCurrentElementPopoverOpen) {
const { lineIndex, charIndex } = el.dataset;
+ const { x, y } = el.getBoundingClientRect();
position = {
- x: el.offsetLeft,
- y: el.offsetTop,
+ x: x || 0,
+ y: y + window.scrollY || 0,
height: el.offsetHeight,
};
- definition = state.data[`${lineIndex}:${charIndex}`];
+ definition = data[`${lineIndex}:${charIndex}`];
el.classList.add('hll');
diff --git a/app/assets/javascripts/code_navigation/store/mutations.js b/app/assets/javascripts/code_navigation/store/mutations.js
index febb7afe2f8..84b1c264418 100644
--- a/app/assets/javascripts/code_navigation/store/mutations.js
+++ b/app/assets/javascripts/code_navigation/store/mutations.js
@@ -1,16 +1,16 @@
import * as types from './mutation_types';
export default {
- [types.SET_INITIAL_DATA](state, { codeNavUrl, definitionPathPrefix }) {
- state.codeNavUrl = codeNavUrl;
+ [types.SET_INITIAL_DATA](state, { blobs, definitionPathPrefix }) {
+ state.blobs = blobs;
state.definitionPathPrefix = definitionPathPrefix;
},
[types.REQUEST_DATA](state) {
state.loading = true;
},
- [types.REQUEST_DATA_SUCCESS](state, data) {
+ [types.REQUEST_DATA_SUCCESS](state, { path, normalizedData }) {
state.loading = false;
- state.data = data;
+ state.data = { ...state.data, [path]: normalizedData };
},
[types.REQUEST_DATA_ERROR](state) {
state.loading = false;
diff --git a/app/assets/javascripts/code_navigation/store/state.js b/app/assets/javascripts/code_navigation/store/state.js
index a7b3b289db4..ffe44ec5381 100644
--- a/app/assets/javascripts/code_navigation/store/state.js
+++ b/app/assets/javascripts/code_navigation/store/state.js
@@ -1,7 +1,5 @@
export default () => ({
- projectPath: null,
- commitId: null,
- blobPath: null,
+ blobs: [],
loading: false,
data: null,
currentDefinition: null,
diff --git a/app/assets/javascripts/code_navigation/utils/index.js b/app/assets/javascripts/code_navigation/utils/index.js
index 2dee0de6501..4d118852a94 100644
--- a/app/assets/javascripts/code_navigation/utils/index.js
+++ b/app/assets/javascripts/code_navigation/utils/index.js
@@ -3,18 +3,25 @@ export const cachedData = new Map();
export const getCurrentHoverElement = () => cachedData.get('current');
export const setCurrentHoverElement = el => cachedData.set('current', el);
-export const addInteractionClass = d => {
- let charCount = 0;
- const line = document.getElementById(`LC${d.start_line + 1}`);
- const el = [...line.childNodes].find(({ textContent }) => {
- if (charCount === d.start_char) return true;
- charCount += textContent.length;
- return false;
- });
+export const addInteractionClass = (path, d) => {
+ const lineNumber = d.start_line + 1;
+ const lines = document
+ .querySelector(`[data-path="${path}"]`)
+ .querySelectorAll(`.blob-content #LC${lineNumber}, .line_content:not(.old) #LC${lineNumber}`);
+ if (!lines?.length) return;
+
+ lines.forEach(line => {
+ let charCount = 0;
+ const el = [...line.childNodes].find(({ textContent }) => {
+ if (charCount === d.start_char) return true;
+ charCount += textContent.length;
+ return false;
+ });
- if (el) {
- el.setAttribute('data-char-index', d.start_char);
- el.setAttribute('data-line-index', d.start_line);
- el.classList.add('cursor-pointer', 'code-navigation', 'js-code-navigation');
- }
+ if (el) {
+ el.setAttribute('data-char-index', d.start_char);
+ el.setAttribute('data-line-index', d.start_line);
+ el.classList.add('cursor-pointer', 'code-navigation', 'js-code-navigation');
+ }
+ });
};