Add BlobViewer JS
This commit is contained in:
parent
3079a2d63b
commit
796acbe1e0
3 changed files with 135 additions and 0 deletions
130
app/assets/javascripts/blob/viewer/index.js
Normal file
130
app/assets/javascripts/blob/viewer/index.js
Normal file
|
@ -0,0 +1,130 @@
|
|||
``/* eslint-disable no-new */
|
||||
/* global Flash */
|
||||
export default class BlobViewer {
|
||||
constructor() {
|
||||
this.switcherBtns = document.querySelectorAll('.js-blob-viewer-switcher');
|
||||
this.copySourceBtn = document.querySelector('.js-copy-blob-source-btn');
|
||||
this.simpleViewer = document.querySelector('.blob-viewer[data-type="simple"]');
|
||||
this.richViewer = document.querySelector('.blob-viewer[data-type="rich"]');
|
||||
this.$blobContentHolder = $('#blob-content-holder');
|
||||
|
||||
let initialViewerName = document.querySelector('.blob-viewer:not(.hidden)').getAttribute('data-type');
|
||||
|
||||
if (this.switcherBtns.length) {
|
||||
this.initBindings();
|
||||
|
||||
if (location.hash.indexOf('#L') === 0) {
|
||||
initialViewerName = 'simple';
|
||||
}
|
||||
}
|
||||
|
||||
this.switchToViewer(initialViewerName);
|
||||
}
|
||||
|
||||
initBindings() {
|
||||
Array.from(this.switcherBtns)
|
||||
.forEach((el) => {
|
||||
el.addEventListener('click', this.switchViewHandler.bind(this));
|
||||
});
|
||||
|
||||
if (this.copySourceBtn) {
|
||||
this.copySourceBtn.addEventListener('click', () => {
|
||||
if (this.copySourceBtn.classList.contains('disabled')) return;
|
||||
|
||||
this.switchToViewer('simple');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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');
|
||||
} else if (this.activeViewer == this.simpleViewer) {
|
||||
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');
|
||||
}
|
||||
|
||||
loadViewer(viewerParam, resolve, reject) {
|
||||
const viewer = viewerParam;
|
||||
const url = viewer.getAttribute('data-url');
|
||||
|
||||
if (!url || viewer.getAttribute('data-loaded') || viewer.getAttribute('data-loading')) {
|
||||
if (resolve) resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
viewer.setAttribute('data-loading', 'true');
|
||||
|
||||
$.ajax({
|
||||
url,
|
||||
dataType: 'JSON',
|
||||
})
|
||||
.fail(() => {
|
||||
if (reject) reject();
|
||||
})
|
||||
.done((data) => {
|
||||
viewer.innerHTML = data.html;
|
||||
$(viewer).syntaxHighlight();
|
||||
|
||||
viewer.setAttribute('data-loaded', 'true');
|
||||
|
||||
this.$blobContentHolder.trigger('highlight:line');
|
||||
|
||||
this.toggleCopyButtonState();
|
||||
|
||||
if (resolve) resolve();
|
||||
});
|
||||
}
|
||||
|
||||
switchToViewer(name) {
|
||||
const newViewer = document.querySelector(`.blob-viewer[data-type='${name}']`);
|
||||
if (this.activeViewer == newViewer) return;
|
||||
|
||||
const oldButton = document.querySelector('.js-blob-viewer-switcher.active')
|
||||
const newButton = document.querySelector(`.js-blob-viewer-switcher[data-viewer='${name}']`);
|
||||
const oldViewer = document.querySelector(`.blob-viewer:not([data-type='${name}'])`);
|
||||
|
||||
if (oldButton) {
|
||||
oldButton.classList.remove('active');
|
||||
}
|
||||
|
||||
if (newButton) {
|
||||
newButton.classList.add('active');
|
||||
newButton.blur();
|
||||
}
|
||||
|
||||
if (oldViewer) {
|
||||
oldViewer.classList.add('hidden');
|
||||
}
|
||||
|
||||
newViewer.classList.remove('hidden');
|
||||
|
||||
this.activeViewer = newViewer;
|
||||
|
||||
this.toggleCopyButtonState();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.loadViewer(newViewer, resolve, reject);
|
||||
})
|
||||
.catch(() => {
|
||||
new Flash('Error loading file');
|
||||
});
|
||||
}
|
||||
}
|
|
@ -48,6 +48,7 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
|
|||
import UserCallout from './user_callout';
|
||||
import { ProtectedTagCreate, ProtectedTagEditList } from './protected_tags';
|
||||
import ShortcutsWiki from './shortcuts_wiki';
|
||||
import BlobViewer from './blob/viewer/index';
|
||||
|
||||
const ShortcutsBlob = require('./shortcuts_blob');
|
||||
|
||||
|
@ -299,6 +300,7 @@ const ShortcutsBlob = require('./shortcuts_blob');
|
|||
gl.TargetBranchDropDown.bootstrap();
|
||||
break;
|
||||
case 'projects:blob:show':
|
||||
new BlobViewer();
|
||||
gl.TargetBranchDropDown.bootstrap();
|
||||
initBlob();
|
||||
break;
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
- page_title @blob.path, @ref
|
||||
= render "projects/commits/head"
|
||||
|
||||
- content_for :page_specific_javascripts do
|
||||
= page_specific_javascript_bundle_tag('blob')
|
||||
|
||||
%div{ class: container_class }
|
||||
= render 'projects/last_push'
|
||||
|
||||
|
|
Loading…
Reference in a new issue