Commit 537ece9a authored by Jacques's avatar Jacques

Improve blob line selection

Improved the line selection by using Vue router
parent 0742676a
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import VueRouter from 'vue-router';
import TableOfContents from '~/blob/components/table_contents.vue';
import PipelineTourSuccessModal from '~/blob/pipeline_tour_success_modal.vue';
import { BlobViewer, initAuxiliaryViewer } from '~/blob/viewer/index';
......@@ -12,11 +13,14 @@ import BlobContentViewer from '~/repository/components/blob_content_viewer.vue';
import '~/sourcegraph/load';
Vue.use(VueApollo);
Vue.use(VueRouter);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
});
const router = new VueRouter({ mode: 'history' });
const viewBlobEl = document.querySelector('#js-view-blob-app');
if (viewBlobEl) {
......@@ -25,6 +29,7 @@ if (viewBlobEl) {
// eslint-disable-next-line no-new
new Vue({
el: viewBlobEl,
router,
apolloProvider,
provide: {
targetBranch,
......
......@@ -20,10 +20,9 @@ export default {
v-for="line in lines"
:id="`L${line}`"
:key="line"
class="diff-line-num"
:href="`#LC${line}`"
class="diff-line-num gl-shadow-none!"
:to="`#LC${line}`"
:data-line-number="line"
@click="$emit('select-line', `#LC${line}`)"
>
<gl-icon :size="12" name="link" />
{{ line }}
......
......@@ -56,6 +56,9 @@ export default {
highlightedContent() {
this.$nextTick(() => this.selectLine());
},
$route() {
this.selectLine();
},
},
async mounted() {
this.hljs = await this.loadHighlightJS();
......@@ -90,7 +93,8 @@ export default {
.join('\r\n')
);
},
selectLine(hash = sanitize(window.location.hash)) {
selectLine() {
const hash = sanitize(this.$route.hash);
const lineToSelect = hash && this.$el.querySelector(hash);
if (!lineToSelect) {
......@@ -112,7 +116,7 @@ export default {
</script>
<template>
<div class="file-content code js-syntax-highlight" :class="$options.userColorScheme">
<line-numbers :lines="lineNumbers" @select-line="selectLine" />
<line-numbers :lines="lineNumbers" />
<pre class="code"><code v-safe-html="highlightedContent"></code>
</pre>
</div>
......
import Vue from 'vue';
import VueRouter from 'vue-router';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
......@@ -16,6 +17,8 @@ import {
} from 'jest/repository/mock_data';
jest.mock('~/lib/utils/common_utils');
Vue.use(VueRouter);
const router = new VueRouter();
let wrapper;
let mockResolver;
......@@ -53,6 +56,7 @@ const createComponent = async (mockData = {}) => {
const fakeApollo = createMockApollo([[blobInfoQuery, mockResolver]]);
wrapper = mountExtended(BlobContentViewer, {
router,
apolloProvider: fakeApollo,
propsData: {
...propsMock,
......
......@@ -23,7 +23,7 @@ describe('Line Numbers component', () => {
expect(findLineNumbers().length).toBe(lines);
expect(findFirstLineNumber().attributes()).toMatchObject({
id: 'L1',
href: '#LC1',
to: '#LC1',
});
});
......@@ -34,15 +34,4 @@ describe('Line Numbers component', () => {
});
});
});
describe('clicking a line number', () => {
beforeEach(() => {
jest.spyOn(wrapper.vm, '$emit');
findFirstLineNumber().vm.$emit('click');
});
it('emits a select-line event', () => {
expect(wrapper.vm.$emit).toHaveBeenCalledWith('select-line', '#LC1');
});
});
});
import hljs from 'highlight.js/lib/core';
import Vue, { nextTick } from 'vue';
import VueRouter from 'vue-router';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import SourceViewer from '~/vue_shared/components/source_viewer.vue';
import LineNumbers from '~/vue_shared/components/line_numbers.vue';
import waitForPromises from 'helpers/wait_for_promises';
jest.mock('highlight.js/lib/core');
Vue.use(VueRouter);
const router = new VueRouter();
describe('Source Viewer component', () => {
let wrapper;
......@@ -16,7 +20,10 @@ describe('Source Viewer component', () => {
hljs.highlightAuto.mockImplementation(() => ({ value: highlightedContent }));
const createComponent = async (props = {}) => {
wrapper = shallowMountExtended(SourceViewer, { propsData: { content, language, ...props } });
wrapper = shallowMountExtended(SourceViewer, {
router,
propsData: { content, language, ...props },
});
await waitForPromises();
};
......@@ -69,16 +76,18 @@ describe('Source Viewer component', () => {
jest.spyOn(firstLineElement, 'scrollIntoView');
jest.spyOn(firstLineElement.classList, 'add');
jest.spyOn(firstLineElement.classList, 'remove');
findLineNumbers().vm.$emit('select-line', '#LC1');
});
it('adds the highlight (hll) class', () => {
it('adds the highlight (hll) class', async () => {
wrapper.vm.$router.push('#LC1');
await nextTick();
expect(firstLineElement.classList.add).toHaveBeenCalledWith('hll');
});
it('removes the highlight (hll) class from a previously highlighted line', () => {
findLineNumbers().vm.$emit('select-line', '#LC2');
it('removes the highlight (hll) class from a previously highlighted line', async () => {
wrapper.vm.$router.push('#LC2');
await nextTick();
expect(firstLineElement.classList.remove).toHaveBeenCalledWith('hll');
});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment