From 796acbe1e05f934c02bc0ca9fca1747aab49267c Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 13 Apr 2017 12:05:09 -0500 Subject: Add BlobViewer JS --- app/assets/javascripts/blob/viewer/index.js | 130 ++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 app/assets/javascripts/blob/viewer/index.js (limited to 'app/assets/javascripts/blob/viewer/index.js') diff --git a/app/assets/javascripts/blob/viewer/index.js b/app/assets/javascripts/blob/viewer/index.js new file mode 100644 index 00000000000..47c20d60446 --- /dev/null +++ b/app/assets/javascripts/blob/viewer/index.js @@ -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'); + }); + } +} -- cgit v1.2.1