# HG changeset patch
# User Samuel Trégouët <samuel.tregouet@logilab.fr>
# Date 1427977554 -7200
# Thu Apr 02 14:25:54 2015 +0200
# Node ID 395e80e02de09391997820cbc9118a843705615d
# Parent 555f771f0d2ab4d52a3bb6fb4485e636bda01215
pdfview: add basic pdfview (closes #289639)
# User Samuel Trégouët <samuel.tregouet@logilab.fr>
# Date 1427977554 -7200
# Thu Apr 02 14:25:54 2015 +0200
# Node ID 395e80e02de09391997820cbc9118a843705615d
# Parent 555f771f0d2ab4d52a3bb6fb4485e636bda01215
pdfview: add basic pdfview (closes #289639)
diff --git a/components/pdfview/pdf-viewer/js/pdf/pdf.js b/components/pdfview/pdf-viewer/js/pdf/pdf.js
@@ -0,0 +1,1 @@
1 +../../../../../node_modules/pdfjs-dist/build/pdf.js 2 \ No newline at end of file
diff --git a/components/pdfview/pdf-viewer/js/pdf/pdf.worker.js b/components/pdfview/pdf-viewer/js/pdf/pdf.worker.js
@@ -0,0 +1,1 @@
3 +../../../../../node_modules/pdfjs-dist/build/pdf.worker.js 4 \ No newline at end of file
diff --git a/components/pdfview/pdf-viewer/pdf-viewer.html b/components/pdfview/pdf-viewer/pdf-viewer.html
@@ -0,0 +1,22 @@
5 +<!-- come from https://github.com/rahmathm1/pdf-viewer 6 + with small changes: 7 + 8 + - remove polymer-component tag since it is not necessary 9 + - do not disable worker with disableWorker flag 10 + - change PDFJS.workerSrc 11 + - move js in its own file 12 + - call renderBook in setPath method 13 + (to have a chance to fill path attribute) 14 + - run jshint on it: 15 + - add missing `;` 16 + - add `use strict` 17 + - add comment to declare global 18 + --> 19 +<template> 20 + <canvas id="pdf-canvas"></canvas> 21 +</template> 22 +<script src="js/pdf/pdf.js"></script> 23 +<script src="js/pdf/pdf.worker.js"></script> 24 +<script src="pdf-viewer.js"></script> 25 + 26 +
diff --git a/components/pdfview/pdf-viewer/pdf-viewer.js b/components/pdfview/pdf-viewer/pdf-viewer.js
@@ -0,0 +1,121 @@
27 +/* global PDFJS */ 28 + 29 +(function(window, document, undefined) { 30 + 'use strict'; 31 + // Refers to the "importer", which is index.html 32 + var thatDoc = document; 33 + 34 + 35 + // Refers to the "importee", which is src/hello-world.html 36 + var thisDoc = (thatDoc._currentScript || thatDoc.currentScript).ownerDocument; 37 + 38 + // Gets content from <template> 39 + var template = thisDoc.querySelector('template').content; 40 + 41 + // Creates an object based in the HTML Element prototype 42 + var pdfProto = Object.create(HTMLElement.prototype); 43 + 44 + // Fires when an instance of the element is created 45 + pdfProto.createdCallback = function() { 46 + 47 + // Creates the shadow root 48 + var shadowRoot = this.createShadowRoot(); 49 + 50 + // Adds a template clone into shadow root 51 + var clone = thatDoc.importNode(template, true); 52 + shadowRoot.appendChild(clone); 53 + 54 + // Caches <canvas> DOM query 55 + pdfProto.canvas = shadowRoot.getElementById('pdf-canvas'); 56 + 57 + if (this.hasAttribute('path')) { 58 + var path = this.getAttribute('path'); 59 + this.setPath(path); 60 + } 61 + }; 62 + 63 + pdfProto.renderBook = function() { 64 + pdfProto.pageNumPending = null; 65 + pdfProto.pageRendering = false; 66 + pdfProto.pageNumPending = null; 67 + pdfProto.ctx = pdfProto.canvas.getContext('2d'); 68 + pdfProto.scale = 2; 69 + pdfProto.pageNum = 1; 70 + pdfProto.isReady = false; 71 + 72 + //PDFJS.disableWorker = true; 73 + PDFJS.workerSrc = '/components/pdfview/pdf-viewer/js/pdf/pdf.worker.js'; 74 + PDFJS.getDocument(this.path).then(function(pdfDoc) { 75 + pdfProto.pdf = pdfDoc; 76 + pdfProto.renderPage(pdfProto.pageNum); 77 + }); 78 + }; 79 + 80 + pdfProto.renderPage = function(num) { 81 + pdfProto.pageRendering = true; 82 + pdfProto.pdf.getPage(num).then(function(page) { 83 + var viewport = page.getViewport(pdfProto.scale); 84 + pdfProto.canvas.height = viewport.height; 85 + pdfProto.canvas.width = viewport.width; 86 + 87 + var renderContext = { 88 + canvasContext: pdfProto.ctx, 89 + viewport: viewport 90 + }; 91 + var renderTask = page.render(renderContext); 92 + pdfProto.isReady = true; 93 + 94 + renderTask.promise.then(function() { 95 + pdfProto.pageRendering = false; 96 + if (pdfProto.pageNumPending !== null) { 97 + pdfProto.renderPage(pdfProto.pageNumPending); 98 + pdfProto.pageNumPending = null; 99 + } 100 + }); 101 + }); 102 + }; 103 + 104 + pdfProto.nextPage = function() { 105 + if (pdfProto.pageNum >= pdfProto.pdf.numPages) { 106 + return false; 107 + } 108 + pdfProto.pageNum++; 109 + pdfProto.queueRenderPage(pdfProto.pageNum); 110 + return true; 111 + }; 112 + 113 + pdfProto.prevPage = function() { 114 + if (pdfProto.pageNum <= 1) { 115 + return false; 116 + } 117 + pdfProto.pageNum--; 118 + pdfProto.queueRenderPage(pdfProto.pageNum); 119 + return true; 120 + }; 121 + 122 + pdfProto.queueRenderPage = function(num) { 123 + if (pdfProto.pageRendering) { 124 + pdfProto.pageNumPending = num; 125 + } else { 126 + pdfProto.renderPage(num); 127 + } 128 + }; 129 + 130 + // Fires when an attribute was added, removed, or updated 131 + pdfProto.attributeChangedCallback = function(attr, oldVal, newVal) { 132 + if (attr === 'path') { 133 + this.setPath(newVal); 134 + } 135 + }; 136 + 137 + // Sets new value to "who" attribute 138 + pdfProto.setPath = function(val) { 139 + this.path = val; 140 + this.renderBook(); 141 + }; 142 + 143 + // Registers <hello-world> in the main document 144 + window.PdfViewer = thatDoc.registerElement('pdf-viewer', { 145 + prototype: pdfProto 146 + }); 147 +})(window, document);
@@ -0,0 +1,22 @@
148 +<link href="pdf-viewer/pdf-viewer.html" rel="import"/> 149 + 150 +<template> 151 + <style> 152 + @import url("/vendor.css"); /* XXX fix need for absolute path */ 153 + </style> 154 + <nav class="navbar navbar-default"> 155 + <button id="prev-page" type="button" class="btn btn-default navbar-btn"> 156 + prev 157 + </button> 158 + <button id="next-page" type="button" class="btn btn-default navbar-btn"> 159 + next 160 + </button> 161 + </nav> 162 + <pdf-viewer></pdf-viewer> 163 + 164 +</template> 165 + 166 + 167 +<script src="pdfview.js"></script> 168 + 169 +
@@ -0,0 +1,60 @@
170 +(function registerView(ownerDocument) { 171 + 'use strict'; 172 + 173 + // register html component 174 + var proto = Object.create(HTMLDivElement.prototype); 175 + 176 + proto.createdCallback = function() { 177 + var template = ownerDocument.querySelector('template'); 178 + var clone = document.importNode(template.content, true); 179 + var root = this.createShadowRoot(); 180 + root.appendChild(clone); 181 + this.viewer = root.querySelector('pdf-viewer'); 182 + root.appendChild(this.viewer); 183 + 184 + root.addEventListener('click', function(ev) { 185 + if (!ev.target) { 186 + return; 187 + } 188 + switch (ev.target.id) { 189 + case 'next-page': 190 + this.viewer.nextPage(); 191 + break; 192 + case 'prev-page': 193 + this.viewer.prevPage(); 194 + break; 195 + default: 196 + break; 197 + } 198 + }.bind(this)); 199 + 200 + }; 201 + proto.setPath = function(newPath) { 202 + this.viewer.setAttribute('path', newPath); 203 + }; 204 + proto.attributeChangedCallback = function(attr, oldVal, newVal) { 205 + if (attr === 'path') { 206 + this.setPath(newVal); 207 + } 208 + }; 209 + document.registerElement('x-mosaic-pdfview', { 210 + prototype: proto 211 + }); 212 + 213 + 214 + // register view 215 + function pdfView(ctx) { 216 + 217 + var contentType = ctx.xhr.getResponseHeader('content-type'); 218 + if (contentType === 'application/pdf') { 219 + var viewer = document.createElement('x-mosaic-pdfview'); 220 + viewer.setAttribute('path', ctx.reqUrl); 221 + return viewer; 222 + } 223 + 224 + } 225 + 226 + var registry = require('registry'); 227 + registry.registerView('http', 'pdf', pdfView); 228 +})(document._currentScript.ownerDocument); 229 +
@@ -1,11 +1,13 @@
230 { 231 "name": "mosaic", 232 "version": "0.1.0", 233 "description": "mosaic knowledge browser", 234 "main": "index.js", 235 - "dependencies": {}, 236 + "dependencies": { 237 + "pdfjs-dist": "^1.1.28" 238 + }, 239 "devDependencies": { 240 "babel": "^4.7.16", 241 "babel-brunch": "^4.0.0", 242 "bootstrap": "^3.3.4", 243 "brunch": "^1.7.20",
@@ -16,10 +16,11 @@
244 <link rel="import" href="/components/neotableview/neotableview.html" /> 245 <link rel="import" href="/components/neolistview/neolistview.html" /> 246 <link rel="import" href="/components/sparqltableview/sparqltableview.html" /> 247 <link rel="import" href="/components/cwtableview/cwtableview.html" /> 248 <link rel="import" href="/components/markdown-editable/markdown-editable.html" /> 249 + <link rel="import" href="/components/pdfview/pdfview.html" /> 250 </head> 251 <body> 252 <div class="container"> 253 <button id="save-portfolio" class="btn">save portfolio</button> 254 <x-markdown-editable>###Edit me</x-markdown-editable>