diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-10-24 06:07:07 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-10-24 06:07:07 +0000 |
commit | 12287a65b735d784cda3555d1b261e50b461b29e (patch) | |
tree | e7539b1b3672986a4f41b544f913ee120d623d44 /app/assets/javascripts/blob | |
parent | 24ed154fa81265f47bcfbecfcb331f82a5faad0d (diff) | |
download | gitlab-ce-12287a65b735d784cda3555d1b261e50b461b29e.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/blob')
-rw-r--r-- | app/assets/javascripts/blob/blob_utils.js | 5 | ||||
-rw-r--r-- | app/assets/javascripts/blob/viewer/index.js | 58 |
2 files changed, 42 insertions, 21 deletions
diff --git a/app/assets/javascripts/blob/blob_utils.js b/app/assets/javascripts/blob/blob_utils.js new file mode 100644 index 00000000000..27fcc7f7b79 --- /dev/null +++ b/app/assets/javascripts/blob/blob_utils.js @@ -0,0 +1,5 @@ +// capture anything starting with http:// or https:// +// up until a disallowed character or whitespace +export const blobLinkRegex = /https?:\/\/[^"<>\\^`{|}\s]+/g; + +export default { blobLinkRegex }; diff --git a/app/assets/javascripts/blob/viewer/index.js b/app/assets/javascripts/blob/viewer/index.js index 07e4dde41d9..f032c2f216b 100644 --- a/app/assets/javascripts/blob/viewer/index.js +++ b/app/assets/javascripts/blob/viewer/index.js @@ -4,6 +4,10 @@ import Flash from '../../flash'; import { handleLocationHash } from '../../lib/utils/common_utils'; import axios from '../../lib/utils/axios_utils'; import { __ } from '~/locale'; +import { blobLinkRegex } from '~/blob/blob_utils'; + +const SIMPLE_VIEWER_NAME = 'simple'; +const RICH_VIEWER_NAME = 'rich'; export default class BlobViewer { constructor() { @@ -21,7 +25,7 @@ export default class BlobViewer { } static initRichViewer() { - const viewer = document.querySelector('.blob-viewer[data-type="rich"]'); + const viewer = document.querySelector(`.blob-viewer[data-type="${RICH_VIEWER_NAME}"]`); if (!viewer || !viewer.dataset.richType) return; const initViewer = promise => @@ -61,8 +65,12 @@ export default class BlobViewer { this.switcherBtns = document.querySelectorAll('.js-blob-viewer-switch-btn'); this.copySourceBtn = document.querySelector('.js-copy-blob-source-btn'); - this.simpleViewer = this.$fileHolder[0].querySelector('.blob-viewer[data-type="simple"]'); - this.richViewer = this.$fileHolder[0].querySelector('.blob-viewer[data-type="rich"]'); + this.simpleViewer = this.$fileHolder[0].querySelector( + `.blob-viewer[data-type="${SIMPLE_VIEWER_NAME}"]`, + ); + this.richViewer = this.$fileHolder[0].querySelector( + `.blob-viewer[data-type="${RICH_VIEWER_NAME}"]`, + ); this.initBindings(); @@ -71,10 +79,10 @@ export default class BlobViewer { switchToInitialViewer() { const initialViewer = this.$fileHolder[0].querySelector('.blob-viewer:not(.hidden)'); - let initialViewerName = initialViewer.getAttribute('data-type'); + let initialViewerName = initialViewer.dataset.type; if (this.switcher && window.location.hash.indexOf('#L') === 0) { - initialViewerName = 'simple'; + initialViewerName = SIMPLE_VIEWER_NAME; } this.switchToViewer(initialViewerName); @@ -91,35 +99,41 @@ export default class BlobViewer { this.copySourceBtn.addEventListener('click', () => { if (this.copySourceBtn.classList.contains('disabled')) return this.copySourceBtn.blur(); - return this.switchToViewer('simple'); + return this.switchToViewer(SIMPLE_VIEWER_NAME); }); } } + static linkifyURLs(viewer) { + if (viewer.dataset.linkified) return; + + document.querySelectorAll('.js-blob-content .code .line').forEach(line => { + // eslint-disable-next-line no-param-reassign + line.innerHTML = line.innerHTML.replace(blobLinkRegex, '<a href="$&">$&</a>'); + }); + + // eslint-disable-next-line no-param-reassign + viewer.dataset.linkified = true; + } + switchViewHandler(e) { const target = e.currentTarget; e.preventDefault(); - this.switchToViewer(target.getAttribute('data-viewer')); + this.switchToViewer(target.dataset.viewer); } toggleCopyButtonState() { if (!this.copySourceBtn) return; - if (this.simpleViewer.getAttribute('data-loaded')) { - this.copySourceBtn.setAttribute('title', __('Copy file contents')); + if (this.simpleViewer.dataset.loaded) { + this.copySourceBtn.dataset.title = __('Copy file contents'); this.copySourceBtn.classList.remove('disabled'); } else if (this.activeViewer === this.simpleViewer) { - this.copySourceBtn.setAttribute( - 'title', - __('Wait for the file to load to copy its contents'), - ); + this.copySourceBtn.dataset.title = __('Wait for the file to load to copy its contents'); this.copySourceBtn.classList.add('disabled'); } else { - this.copySourceBtn.setAttribute( - 'title', - __('Switch to the source to copy the file contents'), - ); + this.copySourceBtn.dataset.title = __('Switch to the source to copy the file contents'); this.copySourceBtn.classList.add('disabled'); } @@ -159,6 +173,8 @@ export default class BlobViewer { this.$fileHolder.trigger('highlight:line'); handleLocationHash(); + if (name === SIMPLE_VIEWER_NAME) BlobViewer.linkifyURLs(viewer); + this.toggleCopyButtonState(); }) .catch(() => new Flash(__('Error loading viewer'))); @@ -166,17 +182,17 @@ export default class BlobViewer { static loadViewer(viewerParam) { const viewer = viewerParam; - const url = viewer.getAttribute('data-url'); + const { url, loaded, loading } = viewer.dataset; - if (!url || viewer.getAttribute('data-loaded') || viewer.getAttribute('data-loading')) { + if (!url || loaded || loading) { return Promise.resolve(viewer); } - viewer.setAttribute('data-loading', 'true'); + viewer.dataset.loading = true; return axios.get(url).then(({ data }) => { viewer.innerHTML = data.html; - viewer.setAttribute('data-loaded', 'true'); + viewer.dataset.loaded = true; return viewer; }); |