Skip to content
Snippets Groups Projects
Commit dad30d6b authored by Sam Rose's avatar Sam Rose Committed by Jacob Schatz
Browse files

Use PDFLab to render PDFs in GitLab

parent 97667b83
No related branches found
No related tags found
No related merge requests found
/* 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>
`,
});
};
import renderPDF from './pdf';
document.addEventListener('DOMContentLoaded', renderPDF);
Loading
Loading
@@ -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
Loading
Loading
@@ -71,6 +75,8 @@ class Blob < SimpleDelegator
end
elsif image? || svg?
'image'
elsif pdf?
'pdf'
elsif ipython_notebook?
'notebook'
elsif sketch?
Loading
Loading
- 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) } }
Loading
Loading
@@ -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',
Loading
Loading
@@ -65,7 +66,11 @@ var config = {
{
test: /\.svg$/,
use: 'raw-loader'
}
}, {
test: /\.(worker.js|pdf)$/,
exclude: /node_modules/,
loader: 'file-loader',
},
]
},
 
Loading
Loading
@@ -107,6 +112,7 @@ var config = {
'issuable',
'merge_conflicts',
'notebook_viewer',
'pdf_viewer',
'vue_pipelines',
],
minChunks: function(module, count) {
Loading
Loading
Loading
Loading
@@ -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",
Loading
Loading
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.');
});
});
});
File added
.file-content#js-pdf-viewer{ data: { endpoint: '/test' } }
Loading
Loading
@@ -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'))
Loading
Loading
@@ -102,6 +116,7 @@ describe Blob do
 
def stubbed_blob(overrides = {})
overrides.reverse_merge!(
name: nil,
image?: false,
language: nil,
lfs_pointer?: false,
Loading
Loading
@@ -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'
Loading
Loading
This diff is collapsed.
This diff is collapsed.
Loading
Loading
@@ -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"
Loading
Loading
@@ -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
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment