Use PDFLab to render PDFs in GitLab
This commit is contained in:
parent
97667b8342
commit
dad30d6bbf
|
@ -0,0 +1,62 @@
|
|||
/* eslint-disable no-new */
|
||||
import Vue from 'vue';
|
||||
import PDFLab from 'vendor/pdflab';
|
||||
import workerSrc from 'vendor/pdf.worker';
|
||||
|
||||
Vue.use(PDFLab, {
|
||||
workerSrc,
|
||||
});
|
||||
|
||||
export default () => {
|
||||
const el = document.getElementById('js-pdf-viewer');
|
||||
|
||||
new Vue({
|
||||
el,
|
||||
data() {
|
||||
return {
|
||||
error: false,
|
||||
loadError: false,
|
||||
loading: true,
|
||||
pdf: el.dataset.endpoint,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onLoad() {
|
||||
this.loading = false;
|
||||
},
|
||||
onError(error) {
|
||||
this.loading = false;
|
||||
this.loadError = true;
|
||||
this.error = error;
|
||||
},
|
||||
},
|
||||
template: `
|
||||
<div class="container-fluid md prepend-top-default append-bottom-default">
|
||||
<div
|
||||
class="text-center loading"
|
||||
v-if="loading && !error">
|
||||
<i
|
||||
class="fa fa-spinner fa-spin"
|
||||
aria-hidden="true"
|
||||
aria-label="PDF loading">
|
||||
</i>
|
||||
</div>
|
||||
<pdf-lab
|
||||
v-if="!loadError"
|
||||
:pdf="pdf"
|
||||
@pdflabload="onLoad"
|
||||
@pdflaberror="onError" />
|
||||
<p
|
||||
class="text-center"
|
||||
v-if="error">
|
||||
<span v-if="loadError">
|
||||
An error occured whilst loading the file. Please try again later.
|
||||
</span>
|
||||
<span v-else>
|
||||
An error occured whilst decoding the file.
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
};
|
|
@ -0,0 +1,3 @@
|
|||
import renderPDF from './pdf';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', renderPDF);
|
|
@ -46,6 +46,10 @@ class Blob < SimpleDelegator
|
|||
text? && language && language.name == 'SVG'
|
||||
end
|
||||
|
||||
def pdf?
|
||||
name && File.extname(name) == '.pdf'
|
||||
end
|
||||
|
||||
def ipython_notebook?
|
||||
text? && language&.name == 'Jupyter Notebook'
|
||||
end
|
||||
|
@ -71,6 +75,8 @@ class Blob < SimpleDelegator
|
|||
end
|
||||
elsif image? || svg?
|
||||
'image'
|
||||
elsif pdf?
|
||||
'pdf'
|
||||
elsif ipython_notebook?
|
||||
'notebook'
|
||||
elsif sketch?
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
- content_for :page_specific_javascripts do
|
||||
= page_specific_javascript_bundle_tag('common_vue')
|
||||
= page_specific_javascript_bundle_tag('pdf_viewer')
|
||||
|
||||
.file-content#js-pdf-viewer{ data: { endpoint: namespace_project_raw_path(@project.namespace, @project, @id) } }
|
|
@ -38,6 +38,7 @@ var config = {
|
|||
network: './network/network_bundle.js',
|
||||
notebook_viewer: './blob/notebook_viewer.js',
|
||||
sketch_viewer: './blob/sketch_viewer.js',
|
||||
pdf_viewer: './blob/pdf_viewer.js',
|
||||
profile: './profile/profile_bundle.js',
|
||||
protected_branches: './protected_branches/protected_branches_bundle.js',
|
||||
snippet: './snippet/snippet_bundle.js',
|
||||
|
@ -65,7 +66,11 @@ var config = {
|
|||
{
|
||||
test: /\.svg$/,
|
||||
use: 'raw-loader'
|
||||
}
|
||||
}, {
|
||||
test: /\.(worker.js|pdf)$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'file-loader',
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
|
@ -107,6 +112,7 @@ var config = {
|
|||
'issuable',
|
||||
'merge_conflicts',
|
||||
'notebook_viewer',
|
||||
'pdf_viewer',
|
||||
'vue_pipelines',
|
||||
],
|
||||
minChunks: function(module, count) {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
"document-register-element": "^1.3.0",
|
||||
"dropzone": "^4.2.0",
|
||||
"emoji-unicode-version": "^0.2.1",
|
||||
"file-loader": "^0.11.1",
|
||||
"jquery": "^2.2.1",
|
||||
"jquery-ujs": "^1.2.1",
|
||||
"js-cookie": "^2.1.3",
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
import renderPDF from '~/blob/pdf';
|
||||
import testPDF from './test.pdf';
|
||||
|
||||
describe('PDF renderer', () => {
|
||||
let viewer;
|
||||
preloadFixtures('static/pdf_viewer.html.raw');
|
||||
|
||||
beforeEach(() => {
|
||||
loadFixtures('static/pdf_viewer.html.raw');
|
||||
viewer = document.getElementById('js-pdf-viewer');
|
||||
viewer.dataset.endpoint = testPDF;
|
||||
});
|
||||
|
||||
it('shows loading icon', () => {
|
||||
renderPDF();
|
||||
|
||||
expect(
|
||||
document.querySelector('.loading'),
|
||||
).not.toBeNull();
|
||||
});
|
||||
|
||||
describe('successful response', () => {
|
||||
beforeEach((done) => {
|
||||
renderPDF();
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it('does not show loading icon', () => {
|
||||
expect(
|
||||
document.querySelector('.loading'),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it('renders the PDF', () => {
|
||||
expect(
|
||||
document.querySelector('.pdf-viewer'),
|
||||
).not.toBeNull();
|
||||
});
|
||||
|
||||
it('renders the PDF page', () => {
|
||||
expect(
|
||||
document.querySelector('.pdf-page'),
|
||||
).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('error getting file', () => {
|
||||
beforeEach((done) => {
|
||||
viewer.dataset.endpoint = 'invalid/endpoint';
|
||||
renderPDF();
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it('does not show loading icon', () => {
|
||||
expect(
|
||||
document.querySelector('.loading'),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it('shows error message', () => {
|
||||
expect(
|
||||
document.querySelector('.md').textContent.trim(),
|
||||
).toBe('An error occured whilst loading the file. Please try again later.');
|
||||
});
|
||||
});
|
||||
});
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
.file-content#js-pdf-viewer{ data: { endpoint: '/test' } }
|
|
@ -53,6 +53,20 @@ describe Blob do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#pdf?' do
|
||||
it 'is falsey when file extension is not .pdf' do
|
||||
git_blob = double(name: 'git_blob.txt')
|
||||
|
||||
expect(described_class.decorate(git_blob)).not_to be_pdf
|
||||
end
|
||||
|
||||
it 'is truthy when file extension is .pdf' do
|
||||
git_blob = double(name: 'git_blob.pdf')
|
||||
|
||||
expect(described_class.decorate(git_blob)).to be_pdf
|
||||
end
|
||||
end
|
||||
|
||||
describe '#ipython_notebook?' do
|
||||
it 'is falsey when language is not Jupyter Notebook' do
|
||||
git_blob = double(text?: true, language: double(name: 'JSON'))
|
||||
|
@ -102,6 +116,7 @@ describe Blob do
|
|||
|
||||
def stubbed_blob(overrides = {})
|
||||
overrides.reverse_merge!(
|
||||
name: nil,
|
||||
image?: false,
|
||||
language: nil,
|
||||
lfs_pointer?: false,
|
||||
|
@ -146,6 +161,11 @@ describe Blob do
|
|||
expect(blob.to_partial_path(project)).to eq 'download'
|
||||
end
|
||||
|
||||
it 'handles PDFs' do
|
||||
blob = stubbed_blob(name: 'blob.pdf', pdf?: true)
|
||||
expect(blob.to_partial_path(project)).to eq 'pdf'
|
||||
end
|
||||
|
||||
it 'handles iPython notebooks' do
|
||||
blob = stubbed_blob(text?: true, ipython_notebook?: true)
|
||||
expect(blob.to_partial_path(project)).to eq 'notebook'
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
14
yarn.lock
14
yarn.lock
|
@ -1942,6 +1942,12 @@ file-entry-cache@^2.0.0:
|
|||
flat-cache "^1.2.1"
|
||||
object-assign "^4.0.1"
|
||||
|
||||
file-loader@^0.11.1:
|
||||
version "0.11.1"
|
||||
resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.11.1.tgz#6b328ee1234a729e4e47d36375dd6d35c0e1db84"
|
||||
dependencies:
|
||||
loader-utils "^1.0.2"
|
||||
|
||||
filename-regex@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775"
|
||||
|
@ -2923,6 +2929,14 @@ loader-utils@^0.2.11, loader-utils@^0.2.16, loader-utils@^0.2.5:
|
|||
json5 "^0.5.0"
|
||||
object-assign "^4.0.1"
|
||||
|
||||
loader-utils@^1.0.2:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd"
|
||||
dependencies:
|
||||
big.js "^3.1.3"
|
||||
emojis-list "^2.0.0"
|
||||
json5 "^0.5.0"
|
||||
|
||||
locate-path@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
|
||||
|
|
Loading…
Reference in New Issue