gitlab-org--gitlab-foss/app/assets/javascripts/blob/viewer/index.js

180 lines
5.3 KiB
JavaScript
Raw Normal View History

import $ from 'jquery';
import Flash from '../../flash';
import { handleLocationHash } from '../../lib/utils/common_utils';
2018-01-26 04:19:03 -05:00
import axios from '../../lib/utils/axios_utils';
2017-04-13 13:05:09 -04:00
export default class BlobViewer {
constructor() {
2017-05-08 19:50:23 -04:00
BlobViewer.initAuxiliaryViewer();
BlobViewer.initRichViewer();
2017-05-08 19:50:23 -04:00
this.initMainViewers();
}
static initAuxiliaryViewer() {
const auxiliaryViewer = document.querySelector('.blob-viewer[data-type="auxiliary"]');
if (!auxiliaryViewer) return;
BlobViewer.loadViewer(auxiliaryViewer);
}
static initRichViewer() {
const viewer = document.querySelector('.blob-viewer[data-type="rich"]');
if (!viewer || !viewer.dataset.richType) return;
const initViewer = promise => promise
.then(module => module.default(viewer))
.catch((error) => {
Flash('Error loading file viewer.');
throw error;
});
switch (viewer.dataset.richType) {
case 'balsamiq':
initViewer(import(/* webpackChunkName: 'balsamiq_viewer' */ '../balsamiq_viewer'));
break;
case 'notebook':
initViewer(import(/* webpackChunkName: 'notebook_viewer' */ '../notebook_viewer'));
break;
2018-03-01 03:02:18 -05:00
case 'pdf':
initViewer(import(/* webpackChunkName: 'pdf_viewer' */ '../pdf_viewer'));
break;
case 'sketch':
initViewer(import(/* webpackChunkName: 'sketch_viewer' */ '../sketch_viewer'));
break;
2018-03-01 03:21:08 -05:00
case 'stl':
initViewer(import(/* webpackChunkName: 'stl_viewer' */ '../stl_viewer'));
break;
default:
break;
}
}
2017-05-08 19:50:23 -04:00
initMainViewers() {
this.$fileHolder = $('.file-holder');
if (!this.$fileHolder.length) return;
this.switcher = document.querySelector('.js-blob-viewer-switcher');
this.switcherBtns = document.querySelectorAll('.js-blob-viewer-switch-btn');
2017-04-13 13:05:09 -04:00
this.copySourceBtn = document.querySelector('.js-copy-blob-source-btn');
2017-05-08 19:50:23 -04:00
this.simpleViewer = this.$fileHolder[0].querySelector('.blob-viewer[data-type="simple"]');
this.richViewer = this.$fileHolder[0].querySelector('.blob-viewer[data-type="rich"]');
2017-04-13 13:05:09 -04:00
this.initBindings();
2017-04-13 13:05:09 -04:00
2017-05-08 19:50:23 -04:00
this.switchToInitialViewer();
}
switchToInitialViewer() {
const initialViewer = this.$fileHolder[0].querySelector('.blob-viewer:not(.hidden)');
let initialViewerName = initialViewer.getAttribute('data-type');
if (this.switcher && location.hash.indexOf('#L') === 0) {
initialViewerName = 'simple';
2017-04-13 13:05:09 -04:00
}
this.switchToViewer(initialViewerName);
}
initBindings() {
if (this.switcherBtns.length) {
Array.from(this.switcherBtns)
.forEach((el) => {
el.addEventListener('click', this.switchViewHandler.bind(this));
});
}
2017-04-13 13:05:09 -04:00
if (this.copySourceBtn) {
this.copySourceBtn.addEventListener('click', () => {
if (this.copySourceBtn.classList.contains('disabled')) return this.copySourceBtn.blur();
2017-04-13 13:05:09 -04:00
return this.switchToViewer('simple');
2017-04-13 13:05:09 -04:00
});
}
}
switchViewHandler(e) {
const target = e.currentTarget;
e.preventDefault();
this.switchToViewer(target.getAttribute('data-viewer'));
}
toggleCopyButtonState() {
if (!this.copySourceBtn) return;
if (this.simpleViewer.getAttribute('data-loaded')) {
this.copySourceBtn.setAttribute('title', 'Copy source to clipboard');
this.copySourceBtn.classList.remove('disabled');
2017-04-20 18:56:24 -04:00
} else if (this.activeViewer === this.simpleViewer) {
2017-04-13 13:05:09 -04:00
this.copySourceBtn.setAttribute('title', 'Wait for the source to load to copy it to the clipboard');
this.copySourceBtn.classList.add('disabled');
} else {
this.copySourceBtn.setAttribute('title', 'Switch to the source to copy it to the clipboard');
this.copySourceBtn.classList.add('disabled');
}
$(this.copySourceBtn).tooltip('_fixTitle');
2017-04-13 13:05:09 -04:00
}
switchToViewer(name) {
2017-05-08 19:50:23 -04:00
const newViewer = this.$fileHolder[0].querySelector(`.blob-viewer[data-type='${name}']`);
2017-04-20 18:56:24 -04:00
if (this.activeViewer === newViewer) return;
2017-04-13 13:05:09 -04:00
const oldButton = document.querySelector('.js-blob-viewer-switch-btn.active');
const newButton = document.querySelector(`.js-blob-viewer-switch-btn[data-viewer='${name}']`);
2017-05-08 19:50:23 -04:00
const oldViewer = this.$fileHolder[0].querySelector(`.blob-viewer:not([data-type='${name}'])`);
2017-04-13 13:05:09 -04:00
if (oldButton) {
oldButton.classList.remove('active');
}
if (newButton) {
newButton.classList.add('active');
newButton.blur();
}
if (oldViewer) {
oldViewer.classList.add('hidden');
}
2017-04-20 18:56:24 -04:00
2017-04-13 13:05:09 -04:00
newViewer.classList.remove('hidden');
this.activeViewer = newViewer;
this.toggleCopyButtonState();
2017-05-08 19:50:23 -04:00
BlobViewer.loadViewer(newViewer)
.then((viewer) => {
$(viewer).renderGFM();
2017-05-08 19:50:23 -04:00
this.$fileHolder.trigger('highlight:line');
handleLocationHash();
2017-05-08 19:50:23 -04:00
this.toggleCopyButtonState();
})
.catch(() => new Flash('Error loading viewer'));
}
static loadViewer(viewerParam) {
const viewer = viewerParam;
const url = viewer.getAttribute('data-url');
2018-01-26 04:19:03 -05:00
if (!url || viewer.getAttribute('data-loaded') || viewer.getAttribute('data-loading')) {
return Promise.resolve(viewer);
}
2017-05-08 19:50:23 -04:00
2018-01-26 04:19:03 -05:00
viewer.setAttribute('data-loading', 'true');
2017-05-08 19:50:23 -04:00
2018-01-26 04:19:03 -05:00
return axios.get(url)
.then(({ data }) => {
2017-05-08 19:50:23 -04:00
viewer.innerHTML = data.html;
viewer.setAttribute('data-loaded', 'true');
2018-01-26 04:19:03 -05:00
return viewer;
2017-05-08 19:50:23 -04:00
});
2017-04-13 13:05:09 -04:00
}
}