2018-05-09 12:01:36 +05:30
|
|
|
import $ from 'jquery';
|
2023-03-17 16:20:25 +05:30
|
|
|
import { renderGFM } from '~/behaviors/markdown/render_gfm';
|
2023-05-27 22:25:52 +05:30
|
|
|
import { createAlert } from '~/alert';
|
2021-03-11 19:13:27 +05:30
|
|
|
import { __ } from '~/locale';
|
2021-06-08 01:23:25 +05:30
|
|
|
import {
|
|
|
|
REPO_BLOB_LOAD_VIEWER_START,
|
|
|
|
REPO_BLOB_LOAD_VIEWER_FINISH,
|
|
|
|
REPO_BLOB_LOAD_VIEWER,
|
2021-09-30 23:02:18 +05:30
|
|
|
REPO_BLOB_SWITCH_TO_VIEWER_START,
|
|
|
|
REPO_BLOB_SWITCH_VIEWER,
|
2021-06-08 01:23:25 +05:30
|
|
|
} from '~/performance/constants';
|
|
|
|
import { performanceMarkAndMeasure } from '~/performance/utils';
|
2021-03-11 19:13:27 +05:30
|
|
|
import { fixTitle } from '~/tooltips';
|
2022-06-21 17:19:12 +05:30
|
|
|
import axios from '~/lib/utils/axios_utils';
|
|
|
|
import { handleLocationHash } from '~/lib/utils/common_utils';
|
|
|
|
import eventHub from '~/notes/event_hub';
|
2018-03-17 18:26:18 +05:30
|
|
|
|
2021-03-08 18:12:59 +05:30
|
|
|
const loadRichBlobViewer = (type) => {
|
2020-04-08 14:13:33 +05:30
|
|
|
switch (type) {
|
|
|
|
case 'notebook':
|
|
|
|
return import(/* webpackChunkName: 'notebook_viewer' */ '../notebook_viewer');
|
|
|
|
case 'openapi':
|
|
|
|
return import(/* webpackChunkName: 'openapi_viewer' */ '../openapi_viewer');
|
2021-09-30 23:02:18 +05:30
|
|
|
case 'csv':
|
|
|
|
return import(/* webpackChunkName: 'csv_viewer' */ '../csv_viewer');
|
2020-04-08 14:13:33 +05:30
|
|
|
case 'pdf':
|
|
|
|
return import(/* webpackChunkName: 'pdf_viewer' */ '../pdf_viewer');
|
|
|
|
case 'sketch':
|
|
|
|
return import(/* webpackChunkName: 'sketch_viewer' */ '../sketch_viewer');
|
|
|
|
case 'stl':
|
|
|
|
return import(/* webpackChunkName: 'stl_viewer' */ '../stl_viewer');
|
|
|
|
default:
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-10-27 15:23:28 +05:30
|
|
|
const loadViewer = (viewerParam) => {
|
|
|
|
const viewer = viewerParam;
|
2022-07-23 23:45:48 +05:30
|
|
|
const { url } = viewer.dataset;
|
2021-10-27 15:23:28 +05:30
|
|
|
|
2022-07-23 23:45:48 +05:30
|
|
|
if (!url || viewer.dataset.loaded || viewer.dataset.loading) {
|
2021-10-27 15:23:28 +05:30
|
|
|
return Promise.resolve(viewer);
|
|
|
|
}
|
|
|
|
|
2022-07-23 23:45:48 +05:30
|
|
|
viewer.dataset.loading = 'true';
|
2021-10-27 15:23:28 +05:30
|
|
|
|
|
|
|
return axios.get(url).then(({ data }) => {
|
2022-10-11 01:57:18 +05:30
|
|
|
// eslint-disable-next-line no-unsanitized/property
|
2021-10-27 15:23:28 +05:30
|
|
|
viewer.innerHTML = data.html;
|
|
|
|
|
|
|
|
window.requestIdleCallback(() => {
|
2022-07-23 23:45:48 +05:30
|
|
|
delete viewer.dataset.loading;
|
2021-10-27 15:23:28 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
return viewer;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
export const initAuxiliaryViewer = () => {
|
|
|
|
const auxiliaryViewer = document.querySelector('.blob-viewer[data-type="auxiliary"]');
|
|
|
|
if (!auxiliaryViewer) return;
|
|
|
|
|
|
|
|
loadViewer(auxiliaryViewer);
|
|
|
|
};
|
|
|
|
|
2020-04-08 14:13:33 +05:30
|
|
|
export const handleBlobRichViewer = (viewer, type) => {
|
|
|
|
if (!viewer || !type) return;
|
|
|
|
|
|
|
|
loadRichBlobViewer(type)
|
2021-03-08 18:12:59 +05:30
|
|
|
.then((module) => module?.default(viewer))
|
|
|
|
.catch((error) => {
|
2022-11-25 23:54:43 +05:30
|
|
|
createAlert({
|
2021-09-30 23:02:18 +05:30
|
|
|
message: __('Error loading file viewer.'),
|
|
|
|
});
|
2020-04-08 14:13:33 +05:30
|
|
|
throw error;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2021-10-27 15:23:28 +05:30
|
|
|
export class BlobViewer {
|
2017-08-17 22:00:37 +05:30
|
|
|
constructor() {
|
2021-09-30 23:02:18 +05:30
|
|
|
performanceMarkAndMeasure({
|
|
|
|
mark: REPO_BLOB_LOAD_VIEWER_START,
|
|
|
|
});
|
2020-04-08 14:13:33 +05:30
|
|
|
const viewer = document.querySelector('.blob-viewer[data-type="rich"]');
|
|
|
|
const type = viewer?.dataset?.richType;
|
2021-10-27 15:23:28 +05:30
|
|
|
initAuxiliaryViewer();
|
2020-04-08 14:13:33 +05:30
|
|
|
|
|
|
|
handleBlobRichViewer(viewer, type);
|
2017-09-10 17:25:29 +05:30
|
|
|
|
|
|
|
this.initMainViewers();
|
|
|
|
}
|
|
|
|
|
|
|
|
initMainViewers() {
|
|
|
|
this.$fileHolder = $('.file-holder');
|
|
|
|
if (!this.$fileHolder.length) return;
|
|
|
|
|
2017-08-17 22:00:37 +05:30
|
|
|
this.switcher = document.querySelector('.js-blob-viewer-switcher');
|
|
|
|
this.switcherBtns = document.querySelectorAll('.js-blob-viewer-switch-btn');
|
|
|
|
this.copySourceBtn = document.querySelector('.js-copy-blob-source-btn');
|
2021-04-17 20:07:23 +05:30
|
|
|
this.copySourceBtnTooltip = document.querySelector('.js-copy-blob-source-btn-tooltip');
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2017-09-10 17:25:29 +05:30
|
|
|
this.simpleViewer = this.$fileHolder[0].querySelector('.blob-viewer[data-type="simple"]');
|
|
|
|
this.richViewer = this.$fileHolder[0].querySelector('.blob-viewer[data-type="rich"]');
|
2017-08-17 22:00:37 +05:30
|
|
|
|
|
|
|
this.initBindings();
|
|
|
|
|
2017-09-10 17:25:29 +05:30
|
|
|
this.switchToInitialViewer();
|
|
|
|
}
|
|
|
|
|
|
|
|
switchToInitialViewer() {
|
|
|
|
const initialViewer = this.$fileHolder[0].querySelector('.blob-viewer:not(.hidden)');
|
2022-07-23 23:45:48 +05:30
|
|
|
let initialViewerName = initialViewer.dataset.type;
|
2017-09-10 17:25:29 +05:30
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
if (this.switcher && window.location.hash.indexOf('#L') === 0) {
|
2017-08-17 22:00:37 +05:30
|
|
|
initialViewerName = 'simple';
|
|
|
|
}
|
|
|
|
|
|
|
|
this.switchToViewer(initialViewerName);
|
|
|
|
}
|
|
|
|
|
|
|
|
initBindings() {
|
|
|
|
if (this.switcherBtns.length) {
|
2021-03-08 18:12:59 +05:30
|
|
|
Array.from(this.switcherBtns).forEach((el) => {
|
2018-12-13 13:39:08 +05:30
|
|
|
el.addEventListener('click', this.switchViewHandler.bind(this));
|
|
|
|
});
|
2017-08-17 22:00:37 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
if (this.copySourceBtn) {
|
|
|
|
this.copySourceBtn.addEventListener('click', () => {
|
|
|
|
if (this.copySourceBtn.classList.contains('disabled')) return this.copySourceBtn.blur();
|
|
|
|
|
|
|
|
return this.switchToViewer('simple');
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switchViewHandler(e) {
|
|
|
|
const target = e.currentTarget;
|
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
2022-07-23 23:45:48 +05:30
|
|
|
this.switchToViewer(target.dataset.viewer);
|
2017-08-17 22:00:37 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
toggleCopyButtonState() {
|
|
|
|
if (!this.copySourceBtn) return;
|
2022-07-23 23:45:48 +05:30
|
|
|
if (this.simpleViewer.dataset.loaded) {
|
2021-04-17 20:07:23 +05:30
|
|
|
this.copySourceBtnTooltip.setAttribute('title', __('Copy file contents'));
|
2017-08-17 22:00:37 +05:30
|
|
|
this.copySourceBtn.classList.remove('disabled');
|
|
|
|
} else if (this.activeViewer === this.simpleViewer) {
|
2021-04-17 20:07:23 +05:30
|
|
|
this.copySourceBtnTooltip.setAttribute(
|
2018-12-13 13:39:08 +05:30
|
|
|
'title',
|
2019-12-21 20:55:43 +05:30
|
|
|
__('Wait for the file to load to copy its contents'),
|
2018-12-13 13:39:08 +05:30
|
|
|
);
|
2017-08-17 22:00:37 +05:30
|
|
|
this.copySourceBtn.classList.add('disabled');
|
|
|
|
} else {
|
2021-04-17 20:07:23 +05:30
|
|
|
this.copySourceBtnTooltip.setAttribute(
|
2019-07-31 22:56:46 +05:30
|
|
|
'title',
|
2019-12-21 20:55:43 +05:30
|
|
|
__('Switch to the source to copy the file contents'),
|
2019-07-31 22:56:46 +05:30
|
|
|
);
|
2017-08-17 22:00:37 +05:30
|
|
|
this.copySourceBtn.classList.add('disabled');
|
|
|
|
}
|
|
|
|
|
2021-04-17 20:07:23 +05:30
|
|
|
fixTitle($(this.copySourceBtnTooltip));
|
2017-08-17 22:00:37 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
switchToViewer(name) {
|
2021-06-08 01:23:25 +05:30
|
|
|
performanceMarkAndMeasure({
|
2021-09-30 23:02:18 +05:30
|
|
|
mark: REPO_BLOB_SWITCH_TO_VIEWER_START,
|
2021-06-08 01:23:25 +05:30
|
|
|
});
|
2017-09-10 17:25:29 +05:30
|
|
|
const newViewer = this.$fileHolder[0].querySelector(`.blob-viewer[data-type='${name}']`);
|
2017-08-17 22:00:37 +05:30
|
|
|
if (this.activeViewer === newViewer) return;
|
|
|
|
|
2021-02-22 17:27:13 +05:30
|
|
|
const oldButton = document.querySelector('.js-blob-viewer-switch-btn.selected');
|
2017-08-17 22:00:37 +05:30
|
|
|
const newButton = document.querySelector(`.js-blob-viewer-switch-btn[data-viewer='${name}']`);
|
2017-09-10 17:25:29 +05:30
|
|
|
const oldViewer = this.$fileHolder[0].querySelector(`.blob-viewer:not([data-type='${name}'])`);
|
2017-08-17 22:00:37 +05:30
|
|
|
|
|
|
|
if (oldButton) {
|
2021-02-22 17:27:13 +05:30
|
|
|
oldButton.classList.remove('selected');
|
2017-08-17 22:00:37 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
if (newButton) {
|
2021-02-22 17:27:13 +05:30
|
|
|
newButton.classList.add('selected');
|
2017-08-17 22:00:37 +05:30
|
|
|
newButton.blur();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (oldViewer) {
|
|
|
|
oldViewer.classList.add('hidden');
|
|
|
|
}
|
|
|
|
|
|
|
|
newViewer.classList.remove('hidden');
|
|
|
|
|
|
|
|
this.activeViewer = newViewer;
|
|
|
|
|
|
|
|
this.toggleCopyButtonState();
|
2021-10-27 15:23:28 +05:30
|
|
|
loadViewer(newViewer)
|
2021-03-08 18:12:59 +05:30
|
|
|
.then((viewer) => {
|
2023-03-17 16:20:25 +05:30
|
|
|
renderGFM(viewer);
|
2021-09-30 23:02:18 +05:30
|
|
|
window.requestIdleCallback(() => {
|
|
|
|
this.$fileHolder.trigger('highlight:line');
|
|
|
|
handleLocationHash();
|
2017-09-10 17:25:29 +05:30
|
|
|
|
2022-07-23 23:45:48 +05:30
|
|
|
// eslint-disable-next-line no-param-reassign
|
|
|
|
viewer.dataset.loaded = 'true';
|
2021-09-30 23:02:18 +05:30
|
|
|
this.toggleCopyButtonState();
|
|
|
|
eventHub.$emit('showBlobInteractionZones', viewer.dataset.path);
|
|
|
|
});
|
2017-09-10 17:25:29 +05:30
|
|
|
|
2021-06-08 01:23:25 +05:30
|
|
|
performanceMarkAndMeasure({
|
|
|
|
mark: REPO_BLOB_LOAD_VIEWER_FINISH,
|
|
|
|
measures: [
|
|
|
|
{
|
|
|
|
name: REPO_BLOB_LOAD_VIEWER,
|
|
|
|
start: REPO_BLOB_LOAD_VIEWER_START,
|
|
|
|
},
|
2021-09-30 23:02:18 +05:30
|
|
|
{
|
|
|
|
name: REPO_BLOB_SWITCH_VIEWER,
|
|
|
|
start: REPO_BLOB_SWITCH_TO_VIEWER_START,
|
|
|
|
},
|
2021-06-08 01:23:25 +05:30
|
|
|
],
|
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
})
|
2021-09-30 23:02:18 +05:30
|
|
|
.catch(() =>
|
2022-11-25 23:54:43 +05:30
|
|
|
createAlert({
|
2021-09-30 23:02:18 +05:30
|
|
|
message: __('Error loading viewer'),
|
|
|
|
}),
|
|
|
|
);
|
2017-09-10 17:25:29 +05:30
|
|
|
}
|
2017-08-17 22:00:37 +05:30
|
|
|
}
|