From 791947ff748bf819636bf58cc43ca0e2051ebc64 Mon Sep 17 00:00:00 2001 From: Justin D'Arcangelo Date: Thu, 23 Jun 2011 20:50:01 -0400 Subject: [PATCH 1/6] Refactored the multi-page viewer to adhere to the coding style guidelines. --- multi-page-viewer.css | 197 ----------------- multi-page-viewer.html | 51 ----- multi-page-viewer.js | 466 ----------------------------------------- multi_page_viewer.css | 197 +++++++++++++++++ multi_page_viewer.html | 51 +++++ multi_page_viewer.js | 458 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 706 insertions(+), 714 deletions(-) delete mode 100644 multi-page-viewer.css delete mode 100644 multi-page-viewer.html delete mode 100644 multi-page-viewer.js create mode 100644 multi_page_viewer.css create mode 100644 multi_page_viewer.html create mode 100644 multi_page_viewer.js diff --git a/multi-page-viewer.css b/multi-page-viewer.css deleted file mode 100644 index 7f4701022..000000000 --- a/multi-page-viewer.css +++ /dev/null @@ -1,197 +0,0 @@ -/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / -/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ - -body { - background-color: #929292; - font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, Verdana, sans-serif; - margin: 0px; - padding: 0px; -} - -canvas { - box-shadow: 0px 4px 10px #000; - -moz-box-shadow: 0px 4px 10px #000; - -webkit-box-shadow: 0px 4px 10px #000; -} - -span { - font-size: 0.8em; -} - -.control { - display: inline-block; - float: left; - margin: 0px 20px 0px 0px; - padding: 0px 4px 0px 0px; -} - -.control > input { - float: left; - border: 1px solid #4d4d4d; - height: 20px; - padding: 0px; - margin: 0px 2px 0px 0px; - border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); -} - -.control > select { - float: left; - border: 1px solid #4d4d4d; - height: 22px; - padding: 2px 0px 0px; - margin: 0px 0px 1px; - border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); -} - -.control > span { - cursor: default; - float: left; - height: 18px; - margin: 5px 2px 0px; - padding: 0px; - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; -} - -.control .label { - clear: both; - float: left; - font-size: 0.65em; - margin: 2px 0px 0px; - position: relative; - text-align: center; - width: 100%; -} - -.page { - width: 816px; - height: 1056px; - margin: 10px auto; -} - -#controls { - background-color: #eee; - border-bottom: 1px solid #666; - padding: 4px 0px 0px 8px; - position: fixed; - left: 0px; - top: 0px; - height: 40px; - width: 100%; - box-shadow: 0px 2px 8px #000; - -moz-box-shadow: 0px 2px 8px #000; - -webkit-box-shadow: 0px 2px 8px #000; -} - -#controls input { - user-select: text; - -moz-user-select: text; - -webkit-user-select: text; -} - -#previousPageButton { - background: url('images/buttons.png') no-repeat 0px -23px; - cursor: default; - display: inline-block; - float: left; - margin: 0px; - width: 28px; - height: 23px; -} - -#previousPageButton.down { - background: url('images/buttons.png') no-repeat 0px -46px; -} - -#previousPageButton.disabled { - background: url('images/buttons.png') no-repeat 0px 0px; -} - -#nextPageButton { - background: url('images/buttons.png') no-repeat -28px -23px; - cursor: default; - display: inline-block; - float: left; - margin: 0px; - width: 28px; - height: 23px; -} - -#nextPageButton.down { - background: url('images/buttons.png') no-repeat -28px -46px; -} - -#nextPageButton.disabled { - background: url('images/buttons.png') no-repeat -28px 0px; -} - -#openFileButton { - background: url('images/buttons.png') no-repeat -56px -23px; - cursor: default; - display: inline-block; - float: left; - margin: 0px 0px 0px 3px; - width: 29px; - height: 23px; -} - -#openFileButton.down { - background: url('images/buttons.png') no-repeat -56px -46px; -} - -#openFileButton.disabled { - background: url('images/buttons.png') no-repeat -56px 0px; -} - -#fileInput { - display: none; -} - -#pageNumber { - text-align: right; -} - -#sidebar { - background-color: rgba(0, 0, 0, 0.8); - position: fixed; - width: 150px; - top: 62px; - bottom: 18px; - border-top-right-radius: 8px; - border-bottom-right-radius: 8px; - -moz-border-radius-topright: 8px; - -moz-border-radius-bottomright: 8px; - -webkit-border-top-right-radius: 8px; - -webkit-border-bottom-right-radius: 8px; -} - -#sidebarScrollView { - position: absolute; - overflow: hidden; - overflow-y: auto; - top: 40px; - right: 10px; - bottom: 10px; - left: 10px; -} - -#sidebarContentView { - height: auto; - width: 100px; -} - -#viewer { - margin: 44px 0px 0px; - padding: 8px 0px; -} diff --git a/multi-page-viewer.html b/multi-page-viewer.html deleted file mode 100644 index ffbdfe707..000000000 --- a/multi-page-viewer.html +++ /dev/null @@ -1,51 +0,0 @@ - - - -pdf.js Multi-Page Viewer - - - - - - - - -
- - - - Previous/Next - - - - / - -- - Page Number - - - - Zoom - - - - - Open File - -
- -
- - diff --git a/multi-page-viewer.js b/multi-page-viewer.js deleted file mode 100644 index baad7809e..000000000 --- a/multi-page-viewer.js +++ /dev/null @@ -1,466 +0,0 @@ -/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / -/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ - -"use strict"; - -var PDFViewer = { - queryParams: {}, - - element: null, - - previousPageButton: null, - nextPageButton: null, - pageNumberInput: null, - scaleSelect: null, - fileInput: null, - - willJumpToPage: false, - - pdf: null, - - url: 'compressed.tracemonkey-pldi-09.pdf', - pageNumber: 1, - numberOfPages: 1, - - scale: 1.0, - - pageWidth: function() { - return 816 * PDFViewer.scale; - }, - - pageHeight: function() { - return 1056 * PDFViewer.scale; - }, - - lastPagesDrawn: [], - - visiblePages: function() { - var pageHeight = PDFViewer.pageHeight() + 20; // Add 20 for the margins. - var windowTop = window.pageYOffset; - var windowBottom = window.pageYOffset + window.innerHeight; - var pageStartIndex = Math.floor(windowTop / pageHeight); - var pageStopIndex = Math.ceil(windowBottom / pageHeight); - - var pages = []; - - for (var i = pageStartIndex; i <= pageStopIndex; i++) { - pages.push(i + 1); - } - - return pages; - }, - - createPage: function(num) { - var anchor = document.createElement('a'); - anchor.name = '' + num; - - var div = document.createElement('div'); - div.id = 'pageContainer' + num; - div.className = 'page'; - div.style.width = PDFViewer.pageWidth() + 'px'; - div.style.height = PDFViewer.pageHeight() + 'px'; - - PDFViewer.element.appendChild(anchor); - PDFViewer.element.appendChild(div); - }, - - removePage: function(num) { - var div = document.getElementById('pageContainer' + num); - - if (div) { - while (div.hasChildNodes()) { - div.removeChild(div.firstChild); - } - } - }, - - drawPage: function(num) { - if (!PDFViewer.pdf) { - return; - } - - var div = document.getElementById('pageContainer' + num); - var canvas = document.createElement('canvas'); - - if (div && !div.hasChildNodes()) { - div.appendChild(canvas); - - var page = PDFViewer.pdf.getPage(num); - - canvas.id = 'page' + num; - canvas.mozOpaque = true; - - // Canvas dimensions must be specified in CSS pixels. CSS pixels - // are always 96 dpi. These dimensions are 8.5in x 11in at 96dpi. - canvas.width = PDFViewer.pageWidth(); - canvas.height = PDFViewer.pageHeight(); - - var ctx = canvas.getContext('2d'); - ctx.save(); - ctx.fillStyle = 'rgb(255, 255, 255)'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.restore(); - - var gfx = new CanvasGraphics(ctx); - var fonts = []; - - // page.compile will collect all fonts for us, once we have loaded them - // we can trigger the actual page rendering with page.display - page.compile(gfx, fonts); - - var areFontsReady = true; - - // Inspect fonts and translate the missing one - var fontCount = fonts.length; - - for (var i = 0; i < fontCount; i++) { - var font = fonts[i]; - - if (Fonts[font.name]) { - areFontsReady = areFontsReady && !Fonts[font.name].loading; - continue; - } - - new Font(font.name, font.file, font.properties); - - areFontsReady = false; - } - - var pageInterval; - - var delayLoadFont = function() { - for (var i = 0; i < fontCount; i++) { - if (Fonts[font.name].loading) { - return; - } - } - - clearInterval(pageInterval); - - while (div.hasChildNodes()) { - div.removeChild(div.firstChild); - } - - PDFViewer.drawPage(num); - } - - if (!areFontsReady) { - pageInterval = setInterval(delayLoadFont, 10); - return; - } - - page.display(gfx); - } - }, - - changeScale: function(num) { - while (PDFViewer.element.hasChildNodes()) { - PDFViewer.element.removeChild(PDFViewer.element.firstChild); - } - - PDFViewer.scale = num / 100; - - var i; - - if (PDFViewer.pdf) { - for (i = 1; i <= PDFViewer.numberOfPages; i++) { - PDFViewer.createPage(i); - } - - if (PDFViewer.numberOfPages > 0) { - PDFViewer.drawPage(1); - } - } - - for (i = 0; i < PDFViewer.scaleSelect.childNodes; i++) { - var option = PDFViewer.scaleSelect.childNodes[i]; - - if (option.value == num) { - if (!option.selected) { - option.selected = 'selected'; - } - } else { - if (option.selected) { - option.removeAttribute('selected'); - } - } - } - - PDFViewer.scaleSelect.value = Math.floor(PDFViewer.scale * 100) + '%'; - }, - - goToPage: function(num) { - if (1 <= num && num <= PDFViewer.numberOfPages) { - PDFViewer.pageNumber = num; - PDFViewer.pageNumberInput.value = PDFViewer.pageNumber; - PDFViewer.willJumpToPage = true; - - document.location.hash = PDFViewer.pageNumber; - - PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? - 'disabled' : ''; - PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? - 'disabled' : ''; - } - }, - - goToPreviousPage: function() { - if (PDFViewer.pageNumber > 1) { - PDFViewer.goToPage(--PDFViewer.pageNumber); - } - }, - - goToNextPage: function() { - if (PDFViewer.pageNumber < PDFViewer.numberOfPages) { - PDFViewer.goToPage(++PDFViewer.pageNumber); - } - }, - - openURL: function(url) { - PDFViewer.url = url; - document.title = url; - - var req = new XMLHttpRequest(); - req.open('GET', url); - req.mozResponseType = req.responseType = 'arraybuffer'; - req.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; - - req.onreadystatechange = function() { - if (req.readyState === 4 && req.status === req.expected) { - var data = req.mozResponseArrayBuffer || - req.mozResponse || - req.responseArrayBuffer || - req.response; - - PDFViewer.readPDF(data); - } - }; - - req.send(null); - }, - - readPDF: function(data) { - while (PDFViewer.element.hasChildNodes()) { - PDFViewer.element.removeChild(PDFViewer.element.firstChild); - } - - PDFViewer.pdf = new PDFDoc(new Stream(data)); - PDFViewer.numberOfPages = PDFViewer.pdf.numPages; - document.getElementById('numPages').innerHTML = PDFViewer.numberOfPages.toString(); - - for (var i = 1; i <= PDFViewer.numberOfPages; i++) { - PDFViewer.createPage(i); - } - - if (PDFViewer.numberOfPages > 0) { - PDFViewer.drawPage(1); - document.location.hash = 1; - } - - PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? - 'disabled' : ''; - PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? - 'disabled' : ''; - } -}; - -window.onload = function() { - - // Parse the URL query parameters into a cached object. - PDFViewer.queryParams = function() { - var qs = window.location.search.substring(1); - var kvs = qs.split('&'); - var params = {}; - for (var i = 0; i < kvs.length; ++i) { - var kv = kvs[i].split('='); - params[unescape(kv[0])] = unescape(kv[1]); - } - - return params; - }(); - - PDFViewer.element = document.getElementById('viewer'); - - PDFViewer.pageNumberInput = document.getElementById('pageNumber'); - PDFViewer.pageNumberInput.onkeydown = function(evt) { - var charCode = evt.charCode || evt.keyCode; - - // Up arrow key. - if (charCode === 38) { - PDFViewer.goToNextPage(); - this.select(); - } - - // Down arrow key. - else if (charCode === 40) { - PDFViewer.goToPreviousPage(); - this.select(); - } - - // All other non-numeric keys (excluding Left arrow, Right arrow, - // Backspace, and Delete keys). - else if ((charCode < 48 || charCode > 57) && - charCode !== 8 && // Backspace - charCode !== 46 && // Delete - charCode !== 37 && // Left arrow - charCode !== 39 // Right arrow - ) { - return false; - } - - return true; - }; - PDFViewer.pageNumberInput.onkeyup = function(evt) { - var charCode = evt.charCode || evt.keyCode; - - // All numeric keys, Backspace, and Delete. - if ((charCode >= 48 && charCode <= 57) || - charCode === 8 || // Backspace - charCode === 46 // Delete - ) { - PDFViewer.goToPage(this.value); - } - - this.focus(); - }; - - PDFViewer.previousPageButton = document.getElementById('previousPageButton'); - PDFViewer.previousPageButton.onclick = function(evt) { - if (this.className.indexOf('disabled') === -1) { - PDFViewer.goToPreviousPage(); - } - }; - PDFViewer.previousPageButton.onmousedown = function(evt) { - if (this.className.indexOf('disabled') === -1) { - this.className = 'down'; - } - }; - PDFViewer.previousPageButton.onmouseup = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - PDFViewer.previousPageButton.onmouseout = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - - PDFViewer.nextPageButton = document.getElementById('nextPageButton'); - PDFViewer.nextPageButton.onclick = function(evt) { - if (this.className.indexOf('disabled') === -1) { - PDFViewer.goToNextPage(); - } - }; - PDFViewer.nextPageButton.onmousedown = function(evt) { - if (this.className.indexOf('disabled') === -1) { - this.className = 'down'; - } - }; - PDFViewer.nextPageButton.onmouseup = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - PDFViewer.nextPageButton.onmouseout = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - - PDFViewer.scaleSelect = document.getElementById('scaleSelect'); - PDFViewer.scaleSelect.onchange = function(evt) { - PDFViewer.changeScale(parseInt(this.value)); - }; - - if (window.File && window.FileReader && window.FileList && window.Blob) { - var openFileButton = document.getElementById('openFileButton'); - openFileButton.onclick = function(evt) { - if (this.className.indexOf('disabled') === -1) { - PDFViewer.fileInput.click(); - } - }; - openFileButton.onmousedown = function(evt) { - if (this.className.indexOf('disabled') === -1) { - this.className = 'down'; - } - }; - openFileButton.onmouseup = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - openFileButton.onmouseout = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - - PDFViewer.fileInput = document.getElementById('fileInput'); - PDFViewer.fileInput.onchange = function(evt) { - var files = evt.target.files; - - if (files.length > 0) { - var file = files[0]; - var fileReader = new FileReader(); - - document.title = file.name; - - // Read the local file into a Uint8Array. - fileReader.onload = function(evt) { - var data = evt.target.result; - var buffer = new ArrayBuffer(data.length); - var uint8Array = new Uint8Array(buffer); - - for (var i = 0; i < data.length; i++) { - uint8Array[i] = data.charCodeAt(i); - } - - PDFViewer.readPDF(uint8Array); - }; - - // Read as a binary string since "readAsArrayBuffer" is not yet - // implemented in Firefox. - fileReader.readAsBinaryString(file); - } - }; - PDFViewer.fileInput.value = null; - } else { - document.getElementById('fileWrapper').style.display = 'none'; - } - - PDFViewer.pageNumber = parseInt(PDFViewer.queryParams.page) || PDFViewer.pageNumber; - PDFViewer.scale = parseInt(PDFViewer.scaleSelect.value) / 100 || 1.0; - - PDFViewer.openURL(PDFViewer.queryParams.file || PDFViewer.url); - - window.onscroll = function(evt) { - var lastPagesDrawn = PDFViewer.lastPagesDrawn; - var visiblePages = PDFViewer.visiblePages(); - - var pagesToDraw = []; - var pagesToKeep = []; - var pagesToRemove = []; - - var i; - - // Determine which visible pages were not previously drawn. - for (i = 0; i < visiblePages.length; i++) { - if (lastPagesDrawn.indexOf(visiblePages[i]) === -1) { - pagesToDraw.push(visiblePages[i]); - PDFViewer.drawPage(visiblePages[i]); - } else { - pagesToKeep.push(visiblePages[i]); - } - } - - // Determine which previously drawn pages are no longer visible. - for (i = 0; i < lastPagesDrawn.length; i++) { - if (visiblePages.indexOf(lastPagesDrawn[i]) === -1) { - pagesToRemove.push(lastPagesDrawn[i]); - PDFViewer.removePage(lastPagesDrawn[i]); - } - } - - PDFViewer.lastPagesDrawn = pagesToDraw.concat(pagesToKeep); - - // Update the page number input with the current page number. - if (!PDFViewer.willJumpToPage && visiblePages.length > 0) { - PDFViewer.pageNumber = PDFViewer.pageNumberInput.value = visiblePages[0]; - PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? - 'disabled' : ''; - PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? - 'disabled' : ''; - } else { - PDFViewer.willJumpToPage = false; - } - }; -}; diff --git a/multi_page_viewer.css b/multi_page_viewer.css new file mode 100644 index 000000000..fce7d7b32 --- /dev/null +++ b/multi_page_viewer.css @@ -0,0 +1,197 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / +/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ + +body { + background-color: #929292; + font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, Verdana, sans-serif; + margin: 0px; + padding: 0px; +} + +canvas { + box-shadow: 0px 4px 10px #000; + -moz-box-shadow: 0px 4px 10px #000; + -webkit-box-shadow: 0px 4px 10px #000; +} + +span { + font-size: 0.8em; +} + +.control { + display: inline-block; + float: left; + margin: 0px 20px 0px 0px; + padding: 0px 4px 0px 0px; +} + +.control > input { + float: left; + border: 1px solid #4d4d4d; + height: 20px; + padding: 0px; + margin: 0px 2px 0px 0px; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); +} + +.control > select { + float: left; + border: 1px solid #4d4d4d; + height: 22px; + padding: 2px 0px 0px; + margin: 0px 0px 1px; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); +} + +.control > span { + cursor: default; + float: left; + height: 18px; + margin: 5px 2px 0px; + padding: 0px; + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; +} + +.control .label { + clear: both; + float: left; + font-size: 0.65em; + margin: 2px 0px 0px; + position: relative; + text-align: center; + width: 100%; +} + +.page { + width: 816px; + height: 1056px; + margin: 10px auto; +} + +#controls { + background-color: #eee; + border-bottom: 1px solid #666; + padding: 4px 0px 0px 8px; + position: fixed; + left: 0px; + top: 0px; + height: 40px; + width: 100%; + box-shadow: 0px 2px 8px #000; + -moz-box-shadow: 0px 2px 8px #000; + -webkit-box-shadow: 0px 2px 8px #000; +} + +#controls input { + user-select: text; + -moz-user-select: text; + -webkit-user-select: text; +} + +#previousPageButton { + background: url('images/buttons.png') no-repeat 0px -23px; + cursor: default; + display: inline-block; + float: left; + margin: 0px; + width: 28px; + height: 23px; +} + +#previousPageButton.down { + background: url('images/buttons.png') no-repeat 0px -46px; +} + +#previousPageButton.disabled { + background: url('images/buttons.png') no-repeat 0px 0px; +} + +#nextPageButton { + background: url('images/buttons.png') no-repeat -28px -23px; + cursor: default; + display: inline-block; + float: left; + margin: 0px; + width: 28px; + height: 23px; +} + +#nextPageButton.down { + background: url('images/buttons.png') no-repeat -28px -46px; +} + +#nextPageButton.disabled { + background: url('images/buttons.png') no-repeat -28px 0px; +} + +#openFileButton { + background: url('images/buttons.png') no-repeat -56px -23px; + cursor: default; + display: inline-block; + float: left; + margin: 0px 0px 0px 3px; + width: 29px; + height: 23px; +} + +#openFileButton.down { + background: url('images/buttons.png') no-repeat -56px -46px; +} + +#openFileButton.disabled { + background: url('images/buttons.png') no-repeat -56px 0px; +} + +#fileInput { + display: none; +} + +#pageNumber { + text-align: right; +} + +#sidebar { + background-color: rgba(0, 0, 0, 0.8); + position: fixed; + width: 150px; + top: 62px; + bottom: 18px; + border-top-right-radius: 8px; + border-bottom-right-radius: 8px; + -moz-border-radius-topright: 8px; + -moz-border-radius-bottomright: 8px; + -webkit-border-top-right-radius: 8px; + -webkit-border-bottom-right-radius: 8px; +} + +#sidebarScrollView { + position: absolute; + overflow: hidden; + overflow-y: auto; + top: 40px; + right: 10px; + bottom: 10px; + left: 10px; +} + +#sidebarContentView { + height: auto; + width: 100px; +} + +#viewer { + margin: 44px 0px 0px; + padding: 8px 0px; +} diff --git a/multi_page_viewer.html b/multi_page_viewer.html new file mode 100644 index 000000000..47234686d --- /dev/null +++ b/multi_page_viewer.html @@ -0,0 +1,51 @@ + + + +pdf.js Multi-Page Viewer + + + + + + + + +
+ + + + Previous/Next + + + + / + -- + Page Number + + + + Zoom + + + + + Open File + +
+ +
+ + diff --git a/multi_page_viewer.js b/multi_page_viewer.js new file mode 100644 index 000000000..ddb541175 --- /dev/null +++ b/multi_page_viewer.js @@ -0,0 +1,458 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / +/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ + +"use strict"; + +var PDFViewer = { + queryParams: {}, + + element: null, + + previousPageButton: null, + nextPageButton: null, + pageNumberInput: null, + scaleSelect: null, + fileInput: null, + + willJumpToPage: false, + + pdf: null, + + url: 'compressed.tracemonkey-pldi-09.pdf', + pageNumber: 1, + numberOfPages: 1, + + scale: 1.0, + + pageWidth: function() { + return 816 * PDFViewer.scale; + }, + + pageHeight: function() { + return 1056 * PDFViewer.scale; + }, + + lastPagesDrawn: [], + + visiblePages: function() { + var pageHeight = PDFViewer.pageHeight() + 20; // Add 20 for the margins. + var windowTop = window.pageYOffset; + var windowBottom = window.pageYOffset + window.innerHeight; + var pageStartIndex = Math.floor(windowTop / pageHeight); + var pageStopIndex = Math.ceil(windowBottom / pageHeight); + + var pages = []; + + for (var i = pageStartIndex; i <= pageStopIndex; i++) { + pages.push(i + 1); + } + + return pages; + }, + + createPage: function(num) { + var anchor = document.createElement('a'); + anchor.name = '' + num; + + var div = document.createElement('div'); + div.id = 'pageContainer' + num; + div.className = 'page'; + div.style.width = PDFViewer.pageWidth() + 'px'; + div.style.height = PDFViewer.pageHeight() + 'px'; + + PDFViewer.element.appendChild(anchor); + PDFViewer.element.appendChild(div); + }, + + removePage: function(num) { + var div = document.getElementById('pageContainer' + num); + + if (div) { + while (div.hasChildNodes()) { + div.removeChild(div.firstChild); + } + } + }, + + drawPage: function(num) { + if (!PDFViewer.pdf) { + return; + } + + var div = document.getElementById('pageContainer' + num); + var canvas = document.createElement('canvas'); + + if (div && !div.hasChildNodes()) { + div.appendChild(canvas); + + var page = PDFViewer.pdf.getPage(num); + + canvas.id = 'page' + num; + canvas.mozOpaque = true; + + // Canvas dimensions must be specified in CSS pixels. CSS pixels + // are always 96 dpi. These dimensions are 8.5in x 11in at 96dpi. + canvas.width = PDFViewer.pageWidth(); + canvas.height = PDFViewer.pageHeight(); + + var ctx = canvas.getContext('2d'); + ctx.save(); + ctx.fillStyle = 'rgb(255, 255, 255)'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.restore(); + + var gfx = new CanvasGraphics(ctx); + var fonts = []; + + // page.compile will collect all fonts for us, once we have loaded them + // we can trigger the actual page rendering with page.display + page.compile(gfx, fonts); + + var areFontsReady = true; + + // Inspect fonts and translate the missing one + var fontCount = fonts.length; + + for (var i = 0; i < fontCount; i++) { + var font = fonts[i]; + + if (Fonts[font.name]) { + areFontsReady = areFontsReady && !Fonts[font.name].loading; + continue; + } + + new Font(font.name, font.file, font.properties); + + areFontsReady = false; + } + + var pageInterval; + + var delayLoadFont = function() { + for (var i = 0; i < fontCount; i++) { + if (Fonts[font.name].loading) { + return; + } + } + + clearInterval(pageInterval); + + while (div.hasChildNodes()) { + div.removeChild(div.firstChild); + } + + PDFViewer.drawPage(num); + } + + if (!areFontsReady) { + pageInterval = setInterval(delayLoadFont, 10); + return; + } + + page.display(gfx); + } + }, + + changeScale: function(num) { + while (PDFViewer.element.hasChildNodes()) { + PDFViewer.element.removeChild(PDFViewer.element.firstChild); + } + + PDFViewer.scale = num / 100; + + var i; + + if (PDFViewer.pdf) { + for (i = 1; i <= PDFViewer.numberOfPages; i++) { + PDFViewer.createPage(i); + } + + if (PDFViewer.numberOfPages > 0) { + PDFViewer.drawPage(1); + } + } + + for (i = 0; i < PDFViewer.scaleSelect.childNodes; i++) { + var option = PDFViewer.scaleSelect.childNodes[i]; + + if (option.value == num) { + if (!option.selected) { + option.selected = 'selected'; + } + } else { + if (option.selected) { + option.removeAttribute('selected'); + } + } + } + + PDFViewer.scaleSelect.value = Math.floor(PDFViewer.scale * 100) + '%'; + }, + + goToPage: function(num) { + if (1 <= num && num <= PDFViewer.numberOfPages) { + PDFViewer.pageNumber = num; + PDFViewer.pageNumberInput.value = PDFViewer.pageNumber; + PDFViewer.willJumpToPage = true; + + document.location.hash = PDFViewer.pageNumber; + + PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? 'disabled' : ''; + PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? 'disabled' : ''; + } + }, + + goToPreviousPage: function() { + if (PDFViewer.pageNumber > 1) { + PDFViewer.goToPage(--PDFViewer.pageNumber); + } + }, + + goToNextPage: function() { + if (PDFViewer.pageNumber < PDFViewer.numberOfPages) { + PDFViewer.goToPage(++PDFViewer.pageNumber); + } + }, + + openURL: function(url) { + PDFViewer.url = url; + document.title = url; + + var req = new XMLHttpRequest(); + req.open('GET', url); + req.mozResponseType = req.responseType = 'arraybuffer'; + req.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; + + req.onreadystatechange = function() { + if (req.readyState === 4 && req.status === req.expected) { + var data = req.mozResponseArrayBuffer || req.mozResponse || req.responseArrayBuffer || req.response; + + PDFViewer.readPDF(data); + } + }; + + req.send(null); + }, + + readPDF: function(data) { + while (PDFViewer.element.hasChildNodes()) { + PDFViewer.element.removeChild(PDFViewer.element.firstChild); + } + + PDFViewer.pdf = new PDFDoc(new Stream(data)); + PDFViewer.numberOfPages = PDFViewer.pdf.numPages; + document.getElementById('numPages').innerHTML = PDFViewer.numberOfPages.toString(); + + for (var i = 1; i <= PDFViewer.numberOfPages; i++) { + PDFViewer.createPage(i); + } + + if (PDFViewer.numberOfPages > 0) { + PDFViewer.drawPage(1); + document.location.hash = 1; + } + + PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? 'disabled' : ''; + PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? 'disabled' : ''; + } +}; + +window.onload = function() { + + // Parse the URL query parameters into a cached object. + PDFViewer.queryParams = function() { + var qs = window.location.search.substring(1); + var kvs = qs.split('&'); + var params = {}; + + for (var i = 0; i < kvs.length; ++i) { + var kv = kvs[i].split('='); + params[unescape(kv[0])] = unescape(kv[1]); + } + + return params; + }(); + + PDFViewer.element = document.getElementById('viewer'); + + PDFViewer.pageNumberInput = document.getElementById('pageNumber'); + PDFViewer.pageNumberInput.onkeydown = function(evt) { + var charCode = evt.charCode || evt.keyCode; + + // Up arrow key. + if (charCode === 38) { + PDFViewer.goToNextPage(); + this.select(); + } + + // Down arrow key. + else if (charCode === 40) { + PDFViewer.goToPreviousPage(); + this.select(); + } + + // All other non-numeric keys (excluding Left arrow, Right arrow, + // Backspace, and Delete keys). + else if ((charCode < 48 || charCode > 57) && + charCode !== 8 && // Backspace + charCode !== 46 && // Delete + charCode !== 37 && // Left arrow + charCode !== 39 // Right arrow + ) { + return false; + } + + return true; + }; + PDFViewer.pageNumberInput.onkeyup = function(evt) { + var charCode = evt.charCode || evt.keyCode; + + // All numeric keys, Backspace, and Delete. + if ((charCode >= 48 && charCode <= 57) || + charCode === 8 || // Backspace + charCode === 46 // Delete + ) { + PDFViewer.goToPage(this.value); + } + + this.focus(); + }; + + PDFViewer.previousPageButton = document.getElementById('previousPageButton'); + PDFViewer.previousPageButton.onclick = function(evt) { + if (this.className.indexOf('disabled') === -1) { + PDFViewer.goToPreviousPage(); + } + }; + PDFViewer.previousPageButton.onmousedown = function(evt) { + if (this.className.indexOf('disabled') === -1) { + this.className = 'down'; + } + }; + PDFViewer.previousPageButton.onmouseup = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + PDFViewer.previousPageButton.onmouseout = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + + PDFViewer.nextPageButton = document.getElementById('nextPageButton'); + PDFViewer.nextPageButton.onclick = function(evt) { + if (this.className.indexOf('disabled') === -1) { + PDFViewer.goToNextPage(); + } + }; + PDFViewer.nextPageButton.onmousedown = function(evt) { + if (this.className.indexOf('disabled') === -1) { + this.className = 'down'; + } + }; + PDFViewer.nextPageButton.onmouseup = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + PDFViewer.nextPageButton.onmouseout = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + + PDFViewer.scaleSelect = document.getElementById('scaleSelect'); + PDFViewer.scaleSelect.onchange = function(evt) { + PDFViewer.changeScale(parseInt(this.value)); + }; + + if (window.File && window.FileReader && window.FileList && window.Blob) { + var openFileButton = document.getElementById('openFileButton'); + openFileButton.onclick = function(evt) { + if (this.className.indexOf('disabled') === -1) { + PDFViewer.fileInput.click(); + } + }; + openFileButton.onmousedown = function(evt) { + if (this.className.indexOf('disabled') === -1) { + this.className = 'down'; + } + }; + openFileButton.onmouseup = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + openFileButton.onmouseout = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + + PDFViewer.fileInput = document.getElementById('fileInput'); + PDFViewer.fileInput.onchange = function(evt) { + var files = evt.target.files; + + if (files.length > 0) { + var file = files[0]; + var fileReader = new FileReader(); + + document.title = file.name; + + // Read the local file into a Uint8Array. + fileReader.onload = function(evt) { + var data = evt.target.result; + var buffer = new ArrayBuffer(data.length); + var uint8Array = new Uint8Array(buffer); + + for (var i = 0; i < data.length; i++) { + uint8Array[i] = data.charCodeAt(i); + } + + PDFViewer.readPDF(uint8Array); + }; + + // Read as a binary string since "readAsArrayBuffer" is not yet + // implemented in Firefox. + fileReader.readAsBinaryString(file); + } + }; + PDFViewer.fileInput.value = null; + } else { + document.getElementById('fileWrapper').style.display = 'none'; + } + + PDFViewer.pageNumber = parseInt(PDFViewer.queryParams.page) || PDFViewer.pageNumber; + PDFViewer.scale = parseInt(PDFViewer.scaleSelect.value) / 100 || 1.0; + + PDFViewer.openURL(PDFViewer.queryParams.file || PDFViewer.url); + + window.onscroll = function(evt) { + var lastPagesDrawn = PDFViewer.lastPagesDrawn; + var visiblePages = PDFViewer.visiblePages(); + + var pagesToDraw = []; + var pagesToKeep = []; + var pagesToRemove = []; + + var i; + + // Determine which visible pages were not previously drawn. + for (i = 0; i < visiblePages.length; i++) { + if (lastPagesDrawn.indexOf(visiblePages[i]) === -1) { + pagesToDraw.push(visiblePages[i]); + PDFViewer.drawPage(visiblePages[i]); + } else { + pagesToKeep.push(visiblePages[i]); + } + } + + // Determine which previously drawn pages are no longer visible. + for (i = 0; i < lastPagesDrawn.length; i++) { + if (visiblePages.indexOf(lastPagesDrawn[i]) === -1) { + pagesToRemove.push(lastPagesDrawn[i]); + PDFViewer.removePage(lastPagesDrawn[i]); + } + } + + PDFViewer.lastPagesDrawn = pagesToDraw.concat(pagesToKeep); + + // Update the page number input with the current page number. + if (!PDFViewer.willJumpToPage && visiblePages.length > 0) { + PDFViewer.pageNumber = PDFViewer.pageNumberInput.value = visiblePages[0]; + PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? 'disabled' : ''; + PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? 'disabled' : ''; + } else { + PDFViewer.willJumpToPage = false; + } + }; +}; From 8584daf7380bc9ef6f885a1de81dbcabd261bb5b Mon Sep 17 00:00:00 2001 From: Justin D'Arcangelo Date: Thu, 23 Jun 2011 21:11:50 -0400 Subject: [PATCH 2/6] Revert ae2e637044e5abe5d4c119de133e65e0aef4a9b5^..HEAD --- multi-page-viewer.css | 197 ++++++++++ multi-page-viewer.html | 51 +++ multi-page-viewer.js | 466 ++++++++++++++++++++++ multi_page_viewer.css | 234 ++++++------ multi_page_viewer.html | 76 ++-- multi_page_viewer.js | 850 +++++++++++++++++++++-------------------- pdf.js | 7 +- 7 files changed, 1300 insertions(+), 581 deletions(-) create mode 100644 multi-page-viewer.css create mode 100644 multi-page-viewer.html create mode 100644 multi-page-viewer.js diff --git a/multi-page-viewer.css b/multi-page-viewer.css new file mode 100644 index 000000000..7f4701022 --- /dev/null +++ b/multi-page-viewer.css @@ -0,0 +1,197 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / +/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ + +body { + background-color: #929292; + font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, Verdana, sans-serif; + margin: 0px; + padding: 0px; +} + +canvas { + box-shadow: 0px 4px 10px #000; + -moz-box-shadow: 0px 4px 10px #000; + -webkit-box-shadow: 0px 4px 10px #000; +} + +span { + font-size: 0.8em; +} + +.control { + display: inline-block; + float: left; + margin: 0px 20px 0px 0px; + padding: 0px 4px 0px 0px; +} + +.control > input { + float: left; + border: 1px solid #4d4d4d; + height: 20px; + padding: 0px; + margin: 0px 2px 0px 0px; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); +} + +.control > select { + float: left; + border: 1px solid #4d4d4d; + height: 22px; + padding: 2px 0px 0px; + margin: 0px 0px 1px; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); +} + +.control > span { + cursor: default; + float: left; + height: 18px; + margin: 5px 2px 0px; + padding: 0px; + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; +} + +.control .label { + clear: both; + float: left; + font-size: 0.65em; + margin: 2px 0px 0px; + position: relative; + text-align: center; + width: 100%; +} + +.page { + width: 816px; + height: 1056px; + margin: 10px auto; +} + +#controls { + background-color: #eee; + border-bottom: 1px solid #666; + padding: 4px 0px 0px 8px; + position: fixed; + left: 0px; + top: 0px; + height: 40px; + width: 100%; + box-shadow: 0px 2px 8px #000; + -moz-box-shadow: 0px 2px 8px #000; + -webkit-box-shadow: 0px 2px 8px #000; +} + +#controls input { + user-select: text; + -moz-user-select: text; + -webkit-user-select: text; +} + +#previousPageButton { + background: url('images/buttons.png') no-repeat 0px -23px; + cursor: default; + display: inline-block; + float: left; + margin: 0px; + width: 28px; + height: 23px; +} + +#previousPageButton.down { + background: url('images/buttons.png') no-repeat 0px -46px; +} + +#previousPageButton.disabled { + background: url('images/buttons.png') no-repeat 0px 0px; +} + +#nextPageButton { + background: url('images/buttons.png') no-repeat -28px -23px; + cursor: default; + display: inline-block; + float: left; + margin: 0px; + width: 28px; + height: 23px; +} + +#nextPageButton.down { + background: url('images/buttons.png') no-repeat -28px -46px; +} + +#nextPageButton.disabled { + background: url('images/buttons.png') no-repeat -28px 0px; +} + +#openFileButton { + background: url('images/buttons.png') no-repeat -56px -23px; + cursor: default; + display: inline-block; + float: left; + margin: 0px 0px 0px 3px; + width: 29px; + height: 23px; +} + +#openFileButton.down { + background: url('images/buttons.png') no-repeat -56px -46px; +} + +#openFileButton.disabled { + background: url('images/buttons.png') no-repeat -56px 0px; +} + +#fileInput { + display: none; +} + +#pageNumber { + text-align: right; +} + +#sidebar { + background-color: rgba(0, 0, 0, 0.8); + position: fixed; + width: 150px; + top: 62px; + bottom: 18px; + border-top-right-radius: 8px; + border-bottom-right-radius: 8px; + -moz-border-radius-topright: 8px; + -moz-border-radius-bottomright: 8px; + -webkit-border-top-right-radius: 8px; + -webkit-border-bottom-right-radius: 8px; +} + +#sidebarScrollView { + position: absolute; + overflow: hidden; + overflow-y: auto; + top: 40px; + right: 10px; + bottom: 10px; + left: 10px; +} + +#sidebarContentView { + height: auto; + width: 100px; +} + +#viewer { + margin: 44px 0px 0px; + padding: 8px 0px; +} diff --git a/multi-page-viewer.html b/multi-page-viewer.html new file mode 100644 index 000000000..ffbdfe707 --- /dev/null +++ b/multi-page-viewer.html @@ -0,0 +1,51 @@ + + + +pdf.js Multi-Page Viewer + + + + + + + + +
+ + + + Previous/Next + + + + / + -- + Page Number + + + + Zoom + + + + + Open File + +
+ +
+ + diff --git a/multi-page-viewer.js b/multi-page-viewer.js new file mode 100644 index 000000000..baad7809e --- /dev/null +++ b/multi-page-viewer.js @@ -0,0 +1,466 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / +/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ + +"use strict"; + +var PDFViewer = { + queryParams: {}, + + element: null, + + previousPageButton: null, + nextPageButton: null, + pageNumberInput: null, + scaleSelect: null, + fileInput: null, + + willJumpToPage: false, + + pdf: null, + + url: 'compressed.tracemonkey-pldi-09.pdf', + pageNumber: 1, + numberOfPages: 1, + + scale: 1.0, + + pageWidth: function() { + return 816 * PDFViewer.scale; + }, + + pageHeight: function() { + return 1056 * PDFViewer.scale; + }, + + lastPagesDrawn: [], + + visiblePages: function() { + var pageHeight = PDFViewer.pageHeight() + 20; // Add 20 for the margins. + var windowTop = window.pageYOffset; + var windowBottom = window.pageYOffset + window.innerHeight; + var pageStartIndex = Math.floor(windowTop / pageHeight); + var pageStopIndex = Math.ceil(windowBottom / pageHeight); + + var pages = []; + + for (var i = pageStartIndex; i <= pageStopIndex; i++) { + pages.push(i + 1); + } + + return pages; + }, + + createPage: function(num) { + var anchor = document.createElement('a'); + anchor.name = '' + num; + + var div = document.createElement('div'); + div.id = 'pageContainer' + num; + div.className = 'page'; + div.style.width = PDFViewer.pageWidth() + 'px'; + div.style.height = PDFViewer.pageHeight() + 'px'; + + PDFViewer.element.appendChild(anchor); + PDFViewer.element.appendChild(div); + }, + + removePage: function(num) { + var div = document.getElementById('pageContainer' + num); + + if (div) { + while (div.hasChildNodes()) { + div.removeChild(div.firstChild); + } + } + }, + + drawPage: function(num) { + if (!PDFViewer.pdf) { + return; + } + + var div = document.getElementById('pageContainer' + num); + var canvas = document.createElement('canvas'); + + if (div && !div.hasChildNodes()) { + div.appendChild(canvas); + + var page = PDFViewer.pdf.getPage(num); + + canvas.id = 'page' + num; + canvas.mozOpaque = true; + + // Canvas dimensions must be specified in CSS pixels. CSS pixels + // are always 96 dpi. These dimensions are 8.5in x 11in at 96dpi. + canvas.width = PDFViewer.pageWidth(); + canvas.height = PDFViewer.pageHeight(); + + var ctx = canvas.getContext('2d'); + ctx.save(); + ctx.fillStyle = 'rgb(255, 255, 255)'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.restore(); + + var gfx = new CanvasGraphics(ctx); + var fonts = []; + + // page.compile will collect all fonts for us, once we have loaded them + // we can trigger the actual page rendering with page.display + page.compile(gfx, fonts); + + var areFontsReady = true; + + // Inspect fonts and translate the missing one + var fontCount = fonts.length; + + for (var i = 0; i < fontCount; i++) { + var font = fonts[i]; + + if (Fonts[font.name]) { + areFontsReady = areFontsReady && !Fonts[font.name].loading; + continue; + } + + new Font(font.name, font.file, font.properties); + + areFontsReady = false; + } + + var pageInterval; + + var delayLoadFont = function() { + for (var i = 0; i < fontCount; i++) { + if (Fonts[font.name].loading) { + return; + } + } + + clearInterval(pageInterval); + + while (div.hasChildNodes()) { + div.removeChild(div.firstChild); + } + + PDFViewer.drawPage(num); + } + + if (!areFontsReady) { + pageInterval = setInterval(delayLoadFont, 10); + return; + } + + page.display(gfx); + } + }, + + changeScale: function(num) { + while (PDFViewer.element.hasChildNodes()) { + PDFViewer.element.removeChild(PDFViewer.element.firstChild); + } + + PDFViewer.scale = num / 100; + + var i; + + if (PDFViewer.pdf) { + for (i = 1; i <= PDFViewer.numberOfPages; i++) { + PDFViewer.createPage(i); + } + + if (PDFViewer.numberOfPages > 0) { + PDFViewer.drawPage(1); + } + } + + for (i = 0; i < PDFViewer.scaleSelect.childNodes; i++) { + var option = PDFViewer.scaleSelect.childNodes[i]; + + if (option.value == num) { + if (!option.selected) { + option.selected = 'selected'; + } + } else { + if (option.selected) { + option.removeAttribute('selected'); + } + } + } + + PDFViewer.scaleSelect.value = Math.floor(PDFViewer.scale * 100) + '%'; + }, + + goToPage: function(num) { + if (1 <= num && num <= PDFViewer.numberOfPages) { + PDFViewer.pageNumber = num; + PDFViewer.pageNumberInput.value = PDFViewer.pageNumber; + PDFViewer.willJumpToPage = true; + + document.location.hash = PDFViewer.pageNumber; + + PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? + 'disabled' : ''; + PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? + 'disabled' : ''; + } + }, + + goToPreviousPage: function() { + if (PDFViewer.pageNumber > 1) { + PDFViewer.goToPage(--PDFViewer.pageNumber); + } + }, + + goToNextPage: function() { + if (PDFViewer.pageNumber < PDFViewer.numberOfPages) { + PDFViewer.goToPage(++PDFViewer.pageNumber); + } + }, + + openURL: function(url) { + PDFViewer.url = url; + document.title = url; + + var req = new XMLHttpRequest(); + req.open('GET', url); + req.mozResponseType = req.responseType = 'arraybuffer'; + req.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; + + req.onreadystatechange = function() { + if (req.readyState === 4 && req.status === req.expected) { + var data = req.mozResponseArrayBuffer || + req.mozResponse || + req.responseArrayBuffer || + req.response; + + PDFViewer.readPDF(data); + } + }; + + req.send(null); + }, + + readPDF: function(data) { + while (PDFViewer.element.hasChildNodes()) { + PDFViewer.element.removeChild(PDFViewer.element.firstChild); + } + + PDFViewer.pdf = new PDFDoc(new Stream(data)); + PDFViewer.numberOfPages = PDFViewer.pdf.numPages; + document.getElementById('numPages').innerHTML = PDFViewer.numberOfPages.toString(); + + for (var i = 1; i <= PDFViewer.numberOfPages; i++) { + PDFViewer.createPage(i); + } + + if (PDFViewer.numberOfPages > 0) { + PDFViewer.drawPage(1); + document.location.hash = 1; + } + + PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? + 'disabled' : ''; + PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? + 'disabled' : ''; + } +}; + +window.onload = function() { + + // Parse the URL query parameters into a cached object. + PDFViewer.queryParams = function() { + var qs = window.location.search.substring(1); + var kvs = qs.split('&'); + var params = {}; + for (var i = 0; i < kvs.length; ++i) { + var kv = kvs[i].split('='); + params[unescape(kv[0])] = unescape(kv[1]); + } + + return params; + }(); + + PDFViewer.element = document.getElementById('viewer'); + + PDFViewer.pageNumberInput = document.getElementById('pageNumber'); + PDFViewer.pageNumberInput.onkeydown = function(evt) { + var charCode = evt.charCode || evt.keyCode; + + // Up arrow key. + if (charCode === 38) { + PDFViewer.goToNextPage(); + this.select(); + } + + // Down arrow key. + else if (charCode === 40) { + PDFViewer.goToPreviousPage(); + this.select(); + } + + // All other non-numeric keys (excluding Left arrow, Right arrow, + // Backspace, and Delete keys). + else if ((charCode < 48 || charCode > 57) && + charCode !== 8 && // Backspace + charCode !== 46 && // Delete + charCode !== 37 && // Left arrow + charCode !== 39 // Right arrow + ) { + return false; + } + + return true; + }; + PDFViewer.pageNumberInput.onkeyup = function(evt) { + var charCode = evt.charCode || evt.keyCode; + + // All numeric keys, Backspace, and Delete. + if ((charCode >= 48 && charCode <= 57) || + charCode === 8 || // Backspace + charCode === 46 // Delete + ) { + PDFViewer.goToPage(this.value); + } + + this.focus(); + }; + + PDFViewer.previousPageButton = document.getElementById('previousPageButton'); + PDFViewer.previousPageButton.onclick = function(evt) { + if (this.className.indexOf('disabled') === -1) { + PDFViewer.goToPreviousPage(); + } + }; + PDFViewer.previousPageButton.onmousedown = function(evt) { + if (this.className.indexOf('disabled') === -1) { + this.className = 'down'; + } + }; + PDFViewer.previousPageButton.onmouseup = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + PDFViewer.previousPageButton.onmouseout = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + + PDFViewer.nextPageButton = document.getElementById('nextPageButton'); + PDFViewer.nextPageButton.onclick = function(evt) { + if (this.className.indexOf('disabled') === -1) { + PDFViewer.goToNextPage(); + } + }; + PDFViewer.nextPageButton.onmousedown = function(evt) { + if (this.className.indexOf('disabled') === -1) { + this.className = 'down'; + } + }; + PDFViewer.nextPageButton.onmouseup = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + PDFViewer.nextPageButton.onmouseout = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + + PDFViewer.scaleSelect = document.getElementById('scaleSelect'); + PDFViewer.scaleSelect.onchange = function(evt) { + PDFViewer.changeScale(parseInt(this.value)); + }; + + if (window.File && window.FileReader && window.FileList && window.Blob) { + var openFileButton = document.getElementById('openFileButton'); + openFileButton.onclick = function(evt) { + if (this.className.indexOf('disabled') === -1) { + PDFViewer.fileInput.click(); + } + }; + openFileButton.onmousedown = function(evt) { + if (this.className.indexOf('disabled') === -1) { + this.className = 'down'; + } + }; + openFileButton.onmouseup = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + openFileButton.onmouseout = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + + PDFViewer.fileInput = document.getElementById('fileInput'); + PDFViewer.fileInput.onchange = function(evt) { + var files = evt.target.files; + + if (files.length > 0) { + var file = files[0]; + var fileReader = new FileReader(); + + document.title = file.name; + + // Read the local file into a Uint8Array. + fileReader.onload = function(evt) { + var data = evt.target.result; + var buffer = new ArrayBuffer(data.length); + var uint8Array = new Uint8Array(buffer); + + for (var i = 0; i < data.length; i++) { + uint8Array[i] = data.charCodeAt(i); + } + + PDFViewer.readPDF(uint8Array); + }; + + // Read as a binary string since "readAsArrayBuffer" is not yet + // implemented in Firefox. + fileReader.readAsBinaryString(file); + } + }; + PDFViewer.fileInput.value = null; + } else { + document.getElementById('fileWrapper').style.display = 'none'; + } + + PDFViewer.pageNumber = parseInt(PDFViewer.queryParams.page) || PDFViewer.pageNumber; + PDFViewer.scale = parseInt(PDFViewer.scaleSelect.value) / 100 || 1.0; + + PDFViewer.openURL(PDFViewer.queryParams.file || PDFViewer.url); + + window.onscroll = function(evt) { + var lastPagesDrawn = PDFViewer.lastPagesDrawn; + var visiblePages = PDFViewer.visiblePages(); + + var pagesToDraw = []; + var pagesToKeep = []; + var pagesToRemove = []; + + var i; + + // Determine which visible pages were not previously drawn. + for (i = 0; i < visiblePages.length; i++) { + if (lastPagesDrawn.indexOf(visiblePages[i]) === -1) { + pagesToDraw.push(visiblePages[i]); + PDFViewer.drawPage(visiblePages[i]); + } else { + pagesToKeep.push(visiblePages[i]); + } + } + + // Determine which previously drawn pages are no longer visible. + for (i = 0; i < lastPagesDrawn.length; i++) { + if (visiblePages.indexOf(lastPagesDrawn[i]) === -1) { + pagesToRemove.push(lastPagesDrawn[i]); + PDFViewer.removePage(lastPagesDrawn[i]); + } + } + + PDFViewer.lastPagesDrawn = pagesToDraw.concat(pagesToKeep); + + // Update the page number input with the current page number. + if (!PDFViewer.willJumpToPage && visiblePages.length > 0) { + PDFViewer.pageNumber = PDFViewer.pageNumberInput.value = visiblePages[0]; + PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? + 'disabled' : ''; + PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? + 'disabled' : ''; + } else { + PDFViewer.willJumpToPage = false; + } + }; +}; diff --git a/multi_page_viewer.css b/multi_page_viewer.css index fce7d7b32..7f4701022 100644 --- a/multi_page_viewer.css +++ b/multi_page_viewer.css @@ -2,196 +2,196 @@ /* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ body { - background-color: #929292; - font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, Verdana, sans-serif; - margin: 0px; - padding: 0px; + background-color: #929292; + font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, Verdana, sans-serif; + margin: 0px; + padding: 0px; } canvas { - box-shadow: 0px 4px 10px #000; - -moz-box-shadow: 0px 4px 10px #000; - -webkit-box-shadow: 0px 4px 10px #000; + box-shadow: 0px 4px 10px #000; + -moz-box-shadow: 0px 4px 10px #000; + -webkit-box-shadow: 0px 4px 10px #000; } span { - font-size: 0.8em; + font-size: 0.8em; } .control { - display: inline-block; - float: left; - margin: 0px 20px 0px 0px; - padding: 0px 4px 0px 0px; + display: inline-block; + float: left; + margin: 0px 20px 0px 0px; + padding: 0px 4px 0px 0px; } .control > input { - float: left; - border: 1px solid #4d4d4d; - height: 20px; - padding: 0px; - margin: 0px 2px 0px 0px; - border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + float: left; + border: 1px solid #4d4d4d; + height: 20px; + padding: 0px; + margin: 0px 2px 0px 0px; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); } .control > select { - float: left; - border: 1px solid #4d4d4d; - height: 22px; - padding: 2px 0px 0px; - margin: 0px 0px 1px; - border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + float: left; + border: 1px solid #4d4d4d; + height: 22px; + padding: 2px 0px 0px; + margin: 0px 0px 1px; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); } .control > span { - cursor: default; - float: left; - height: 18px; - margin: 5px 2px 0px; - padding: 0px; - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; + cursor: default; + float: left; + height: 18px; + margin: 5px 2px 0px; + padding: 0px; + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; } .control .label { - clear: both; - float: left; - font-size: 0.65em; - margin: 2px 0px 0px; - position: relative; - text-align: center; - width: 100%; + clear: both; + float: left; + font-size: 0.65em; + margin: 2px 0px 0px; + position: relative; + text-align: center; + width: 100%; } .page { - width: 816px; - height: 1056px; - margin: 10px auto; + width: 816px; + height: 1056px; + margin: 10px auto; } #controls { - background-color: #eee; - border-bottom: 1px solid #666; - padding: 4px 0px 0px 8px; - position: fixed; - left: 0px; - top: 0px; - height: 40px; - width: 100%; - box-shadow: 0px 2px 8px #000; - -moz-box-shadow: 0px 2px 8px #000; - -webkit-box-shadow: 0px 2px 8px #000; + background-color: #eee; + border-bottom: 1px solid #666; + padding: 4px 0px 0px 8px; + position: fixed; + left: 0px; + top: 0px; + height: 40px; + width: 100%; + box-shadow: 0px 2px 8px #000; + -moz-box-shadow: 0px 2px 8px #000; + -webkit-box-shadow: 0px 2px 8px #000; } #controls input { - user-select: text; - -moz-user-select: text; - -webkit-user-select: text; + user-select: text; + -moz-user-select: text; + -webkit-user-select: text; } #previousPageButton { - background: url('images/buttons.png') no-repeat 0px -23px; - cursor: default; - display: inline-block; - float: left; - margin: 0px; - width: 28px; - height: 23px; + background: url('images/buttons.png') no-repeat 0px -23px; + cursor: default; + display: inline-block; + float: left; + margin: 0px; + width: 28px; + height: 23px; } #previousPageButton.down { - background: url('images/buttons.png') no-repeat 0px -46px; + background: url('images/buttons.png') no-repeat 0px -46px; } #previousPageButton.disabled { - background: url('images/buttons.png') no-repeat 0px 0px; + background: url('images/buttons.png') no-repeat 0px 0px; } #nextPageButton { - background: url('images/buttons.png') no-repeat -28px -23px; - cursor: default; - display: inline-block; - float: left; - margin: 0px; - width: 28px; - height: 23px; + background: url('images/buttons.png') no-repeat -28px -23px; + cursor: default; + display: inline-block; + float: left; + margin: 0px; + width: 28px; + height: 23px; } #nextPageButton.down { - background: url('images/buttons.png') no-repeat -28px -46px; + background: url('images/buttons.png') no-repeat -28px -46px; } #nextPageButton.disabled { - background: url('images/buttons.png') no-repeat -28px 0px; + background: url('images/buttons.png') no-repeat -28px 0px; } #openFileButton { - background: url('images/buttons.png') no-repeat -56px -23px; - cursor: default; - display: inline-block; - float: left; - margin: 0px 0px 0px 3px; - width: 29px; - height: 23px; + background: url('images/buttons.png') no-repeat -56px -23px; + cursor: default; + display: inline-block; + float: left; + margin: 0px 0px 0px 3px; + width: 29px; + height: 23px; } #openFileButton.down { - background: url('images/buttons.png') no-repeat -56px -46px; + background: url('images/buttons.png') no-repeat -56px -46px; } #openFileButton.disabled { - background: url('images/buttons.png') no-repeat -56px 0px; + background: url('images/buttons.png') no-repeat -56px 0px; } #fileInput { - display: none; + display: none; } #pageNumber { - text-align: right; + text-align: right; } #sidebar { - background-color: rgba(0, 0, 0, 0.8); - position: fixed; - width: 150px; - top: 62px; - bottom: 18px; - border-top-right-radius: 8px; - border-bottom-right-radius: 8px; - -moz-border-radius-topright: 8px; - -moz-border-radius-bottomright: 8px; - -webkit-border-top-right-radius: 8px; - -webkit-border-bottom-right-radius: 8px; + background-color: rgba(0, 0, 0, 0.8); + position: fixed; + width: 150px; + top: 62px; + bottom: 18px; + border-top-right-radius: 8px; + border-bottom-right-radius: 8px; + -moz-border-radius-topright: 8px; + -moz-border-radius-bottomright: 8px; + -webkit-border-top-right-radius: 8px; + -webkit-border-bottom-right-radius: 8px; } #sidebarScrollView { - position: absolute; - overflow: hidden; - overflow-y: auto; - top: 40px; - right: 10px; - bottom: 10px; - left: 10px; + position: absolute; + overflow: hidden; + overflow-y: auto; + top: 40px; + right: 10px; + bottom: 10px; + left: 10px; } #sidebarContentView { - height: auto; - width: 100px; + height: auto; + width: 100px; } #viewer { - margin: 44px 0px 0px; - padding: 8px 0px; + margin: 44px 0px 0px; + padding: 8px 0px; } diff --git a/multi_page_viewer.html b/multi_page_viewer.html index 47234686d..ffbdfe707 100644 --- a/multi_page_viewer.html +++ b/multi_page_viewer.html @@ -3,49 +3,49 @@ pdf.js Multi-Page Viewer - + - + -
- - - - Previous/Next - - - - / - -- - Page Number - - - - Zoom - - - - - Open File - -
- -
+ +
diff --git a/multi_page_viewer.js b/multi_page_viewer.js index ddb541175..baad7809e 100644 --- a/multi_page_viewer.js +++ b/multi_page_viewer.js @@ -4,455 +4,463 @@ "use strict"; var PDFViewer = { - queryParams: {}, - - element: null, - - previousPageButton: null, - nextPageButton: null, - pageNumberInput: null, - scaleSelect: null, - fileInput: null, - - willJumpToPage: false, - - pdf: null, - - url: 'compressed.tracemonkey-pldi-09.pdf', - pageNumber: 1, - numberOfPages: 1, - - scale: 1.0, - - pageWidth: function() { - return 816 * PDFViewer.scale; - }, - - pageHeight: function() { - return 1056 * PDFViewer.scale; - }, - - lastPagesDrawn: [], - - visiblePages: function() { - var pageHeight = PDFViewer.pageHeight() + 20; // Add 20 for the margins. - var windowTop = window.pageYOffset; - var windowBottom = window.pageYOffset + window.innerHeight; - var pageStartIndex = Math.floor(windowTop / pageHeight); - var pageStopIndex = Math.ceil(windowBottom / pageHeight); + queryParams: {}, + + element: null, + + previousPageButton: null, + nextPageButton: null, + pageNumberInput: null, + scaleSelect: null, + fileInput: null, - var pages = []; + willJumpToPage: false, + + pdf: null, + + url: 'compressed.tracemonkey-pldi-09.pdf', + pageNumber: 1, + numberOfPages: 1, + + scale: 1.0, + + pageWidth: function() { + return 816 * PDFViewer.scale; + }, + + pageHeight: function() { + return 1056 * PDFViewer.scale; + }, - for (var i = pageStartIndex; i <= pageStopIndex; i++) { - pages.push(i + 1); - } + lastPagesDrawn: [], - return pages; - }, - - createPage: function(num) { - var anchor = document.createElement('a'); - anchor.name = '' + num; - - var div = document.createElement('div'); - div.id = 'pageContainer' + num; - div.className = 'page'; - div.style.width = PDFViewer.pageWidth() + 'px'; - div.style.height = PDFViewer.pageHeight() + 'px'; - - PDFViewer.element.appendChild(anchor); - PDFViewer.element.appendChild(div); - }, - - removePage: function(num) { - var div = document.getElementById('pageContainer' + num); - - if (div) { - while (div.hasChildNodes()) { - div.removeChild(div.firstChild); - } - } - }, - - drawPage: function(num) { - if (!PDFViewer.pdf) { - return; - } - - var div = document.getElementById('pageContainer' + num); - var canvas = document.createElement('canvas'); - - if (div && !div.hasChildNodes()) { - div.appendChild(canvas); - - var page = PDFViewer.pdf.getPage(num); - - canvas.id = 'page' + num; - canvas.mozOpaque = true; - - // Canvas dimensions must be specified in CSS pixels. CSS pixels - // are always 96 dpi. These dimensions are 8.5in x 11in at 96dpi. - canvas.width = PDFViewer.pageWidth(); - canvas.height = PDFViewer.pageHeight(); - - var ctx = canvas.getContext('2d'); - ctx.save(); - ctx.fillStyle = 'rgb(255, 255, 255)'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.restore(); - - var gfx = new CanvasGraphics(ctx); - var fonts = []; - - // page.compile will collect all fonts for us, once we have loaded them - // we can trigger the actual page rendering with page.display - page.compile(gfx, fonts); - - var areFontsReady = true; - - // Inspect fonts and translate the missing one - var fontCount = fonts.length; - - for (var i = 0; i < fontCount; i++) { - var font = fonts[i]; - - if (Fonts[font.name]) { - areFontsReady = areFontsReady && !Fonts[font.name].loading; - continue; + visiblePages: function() { + var pageHeight = PDFViewer.pageHeight() + 20; // Add 20 for the margins. + var windowTop = window.pageYOffset; + var windowBottom = window.pageYOffset + window.innerHeight; + var pageStartIndex = Math.floor(windowTop / pageHeight); + var pageStopIndex = Math.ceil(windowBottom / pageHeight); + + var pages = []; + + for (var i = pageStartIndex; i <= pageStopIndex; i++) { + pages.push(i + 1); } + + return pages; + }, + + createPage: function(num) { + var anchor = document.createElement('a'); + anchor.name = '' + num; + + var div = document.createElement('div'); + div.id = 'pageContainer' + num; + div.className = 'page'; + div.style.width = PDFViewer.pageWidth() + 'px'; + div.style.height = PDFViewer.pageHeight() + 'px'; - new Font(font.name, font.file, font.properties); + PDFViewer.element.appendChild(anchor); + PDFViewer.element.appendChild(div); + }, + + removePage: function(num) { + var div = document.getElementById('pageContainer' + num); - areFontsReady = false; - } - - var pageInterval; - - var delayLoadFont = function() { - for (var i = 0; i < fontCount; i++) { - if (Fonts[font.name].loading) { + if (div) { + while (div.hasChildNodes()) { + div.removeChild(div.firstChild); + } + } + }, + + drawPage: function(num) { + if (!PDFViewer.pdf) { return; - } } - clearInterval(pageInterval); + var div = document.getElementById('pageContainer' + num); + var canvas = document.createElement('canvas'); - while (div.hasChildNodes()) { - div.removeChild(div.firstChild); + if (div && !div.hasChildNodes()) { + div.appendChild(canvas); + + var page = PDFViewer.pdf.getPage(num); + + canvas.id = 'page' + num; + canvas.mozOpaque = true; + + // Canvas dimensions must be specified in CSS pixels. CSS pixels + // are always 96 dpi. These dimensions are 8.5in x 11in at 96dpi. + canvas.width = PDFViewer.pageWidth(); + canvas.height = PDFViewer.pageHeight(); + + var ctx = canvas.getContext('2d'); + ctx.save(); + ctx.fillStyle = 'rgb(255, 255, 255)'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.restore(); + + var gfx = new CanvasGraphics(ctx); + var fonts = []; + + // page.compile will collect all fonts for us, once we have loaded them + // we can trigger the actual page rendering with page.display + page.compile(gfx, fonts); + + var areFontsReady = true; + + // Inspect fonts and translate the missing one + var fontCount = fonts.length; + + for (var i = 0; i < fontCount; i++) { + var font = fonts[i]; + + if (Fonts[font.name]) { + areFontsReady = areFontsReady && !Fonts[font.name].loading; + continue; + } + + new Font(font.name, font.file, font.properties); + + areFontsReady = false; + } + + var pageInterval; + + var delayLoadFont = function() { + for (var i = 0; i < fontCount; i++) { + if (Fonts[font.name].loading) { + return; + } + } + + clearInterval(pageInterval); + + while (div.hasChildNodes()) { + div.removeChild(div.firstChild); + } + + PDFViewer.drawPage(num); + } + + if (!areFontsReady) { + pageInterval = setInterval(delayLoadFont, 10); + return; + } + + page.display(gfx); + } + }, + + changeScale: function(num) { + while (PDFViewer.element.hasChildNodes()) { + PDFViewer.element.removeChild(PDFViewer.element.firstChild); + } + + PDFViewer.scale = num / 100; + + var i; + + if (PDFViewer.pdf) { + for (i = 1; i <= PDFViewer.numberOfPages; i++) { + PDFViewer.createPage(i); + } + + if (PDFViewer.numberOfPages > 0) { + PDFViewer.drawPage(1); + } + } + + for (i = 0; i < PDFViewer.scaleSelect.childNodes; i++) { + var option = PDFViewer.scaleSelect.childNodes[i]; + + if (option.value == num) { + if (!option.selected) { + option.selected = 'selected'; + } + } else { + if (option.selected) { + option.removeAttribute('selected'); + } + } } - PDFViewer.drawPage(num); - } - - if (!areFontsReady) { - pageInterval = setInterval(delayLoadFont, 10); - return; - } - - page.display(gfx); - } - }, - - changeScale: function(num) { - while (PDFViewer.element.hasChildNodes()) { - PDFViewer.element.removeChild(PDFViewer.element.firstChild); - } - - PDFViewer.scale = num / 100; - - var i; - - if (PDFViewer.pdf) { - for (i = 1; i <= PDFViewer.numberOfPages; i++) { - PDFViewer.createPage(i); - } - - if (PDFViewer.numberOfPages > 0) { - PDFViewer.drawPage(1); - } - } - - for (i = 0; i < PDFViewer.scaleSelect.childNodes; i++) { - var option = PDFViewer.scaleSelect.childNodes[i]; - - if (option.value == num) { - if (!option.selected) { - option.selected = 'selected'; + PDFViewer.scaleSelect.value = Math.floor(PDFViewer.scale * 100) + '%'; + }, + + goToPage: function(num) { + if (1 <= num && num <= PDFViewer.numberOfPages) { + PDFViewer.pageNumber = num; + PDFViewer.pageNumberInput.value = PDFViewer.pageNumber; + PDFViewer.willJumpToPage = true; + + document.location.hash = PDFViewer.pageNumber; + + PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? + 'disabled' : ''; + PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? + 'disabled' : ''; } - } else { - if (option.selected) { - option.removeAttribute('selected'); + }, + + goToPreviousPage: function() { + if (PDFViewer.pageNumber > 1) { + PDFViewer.goToPage(--PDFViewer.pageNumber); } - } - } + }, + + goToNextPage: function() { + if (PDFViewer.pageNumber < PDFViewer.numberOfPages) { + PDFViewer.goToPage(++PDFViewer.pageNumber); + } + }, + + openURL: function(url) { + PDFViewer.url = url; + document.title = url; - PDFViewer.scaleSelect.value = Math.floor(PDFViewer.scale * 100) + '%'; - }, - - goToPage: function(num) { - if (1 <= num && num <= PDFViewer.numberOfPages) { - PDFViewer.pageNumber = num; - PDFViewer.pageNumberInput.value = PDFViewer.pageNumber; - PDFViewer.willJumpToPage = true; - - document.location.hash = PDFViewer.pageNumber; - - PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? 'disabled' : ''; - PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? 'disabled' : ''; - } - }, - - goToPreviousPage: function() { - if (PDFViewer.pageNumber > 1) { - PDFViewer.goToPage(--PDFViewer.pageNumber); - } - }, - - goToNextPage: function() { - if (PDFViewer.pageNumber < PDFViewer.numberOfPages) { - PDFViewer.goToPage(++PDFViewer.pageNumber); - } - }, - - openURL: function(url) { - PDFViewer.url = url; - document.title = url; + var req = new XMLHttpRequest(); + req.open('GET', url); + req.mozResponseType = req.responseType = 'arraybuffer'; + req.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; - var req = new XMLHttpRequest(); - req.open('GET', url); - req.mozResponseType = req.responseType = 'arraybuffer'; - req.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; + req.onreadystatechange = function() { + if (req.readyState === 4 && req.status === req.expected) { + var data = req.mozResponseArrayBuffer || + req.mozResponse || + req.responseArrayBuffer || + req.response; + + PDFViewer.readPDF(data); + } + }; - req.onreadystatechange = function() { - if (req.readyState === 4 && req.status === req.expected) { - var data = req.mozResponseArrayBuffer || req.mozResponse || req.responseArrayBuffer || req.response; + req.send(null); + }, + + readPDF: function(data) { + while (PDFViewer.element.hasChildNodes()) { + PDFViewer.element.removeChild(PDFViewer.element.firstChild); + } - PDFViewer.readPDF(data); - } - }; - - req.send(null); - }, + PDFViewer.pdf = new PDFDoc(new Stream(data)); + PDFViewer.numberOfPages = PDFViewer.pdf.numPages; + document.getElementById('numPages').innerHTML = PDFViewer.numberOfPages.toString(); - readPDF: function(data) { - while (PDFViewer.element.hasChildNodes()) { - PDFViewer.element.removeChild(PDFViewer.element.firstChild); + for (var i = 1; i <= PDFViewer.numberOfPages; i++) { + PDFViewer.createPage(i); + } + + if (PDFViewer.numberOfPages > 0) { + PDFViewer.drawPage(1); + document.location.hash = 1; + } + + PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? + 'disabled' : ''; + PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? + 'disabled' : ''; } - - PDFViewer.pdf = new PDFDoc(new Stream(data)); - PDFViewer.numberOfPages = PDFViewer.pdf.numPages; - document.getElementById('numPages').innerHTML = PDFViewer.numberOfPages.toString(); - - for (var i = 1; i <= PDFViewer.numberOfPages; i++) { - PDFViewer.createPage(i); - } - - if (PDFViewer.numberOfPages > 0) { - PDFViewer.drawPage(1); - document.location.hash = 1; - } - - PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? 'disabled' : ''; - PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? 'disabled' : ''; - } }; window.onload = function() { - - // Parse the URL query parameters into a cached object. - PDFViewer.queryParams = function() { - var qs = window.location.search.substring(1); - var kvs = qs.split('&'); - var params = {}; - - for (var i = 0; i < kvs.length; ++i) { - var kv = kvs[i].split('='); - params[unescape(kv[0])] = unescape(kv[1]); - } - - return params; - }(); - PDFViewer.element = document.getElementById('viewer'); - - PDFViewer.pageNumberInput = document.getElementById('pageNumber'); - PDFViewer.pageNumberInput.onkeydown = function(evt) { - var charCode = evt.charCode || evt.keyCode; - - // Up arrow key. - if (charCode === 38) { - PDFViewer.goToNextPage(); - this.select(); - } - - // Down arrow key. - else if (charCode === 40) { - PDFViewer.goToPreviousPage(); - this.select(); - } - - // All other non-numeric keys (excluding Left arrow, Right arrow, - // Backspace, and Delete keys). - else if ((charCode < 48 || charCode > 57) && - charCode !== 8 && // Backspace - charCode !== 46 && // Delete - charCode !== 37 && // Left arrow - charCode !== 39 // Right arrow - ) { - return false; - } - - return true; - }; - PDFViewer.pageNumberInput.onkeyup = function(evt) { - var charCode = evt.charCode || evt.keyCode; - - // All numeric keys, Backspace, and Delete. - if ((charCode >= 48 && charCode <= 57) || - charCode === 8 || // Backspace - charCode === 46 // Delete - ) { - PDFViewer.goToPage(this.value); - } - - this.focus(); - }; - - PDFViewer.previousPageButton = document.getElementById('previousPageButton'); - PDFViewer.previousPageButton.onclick = function(evt) { - if (this.className.indexOf('disabled') === -1) { - PDFViewer.goToPreviousPage(); - } - }; - PDFViewer.previousPageButton.onmousedown = function(evt) { - if (this.className.indexOf('disabled') === -1) { - this.className = 'down'; - } - }; - PDFViewer.previousPageButton.onmouseup = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - PDFViewer.previousPageButton.onmouseout = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - - PDFViewer.nextPageButton = document.getElementById('nextPageButton'); - PDFViewer.nextPageButton.onclick = function(evt) { - if (this.className.indexOf('disabled') === -1) { - PDFViewer.goToNextPage(); - } - }; - PDFViewer.nextPageButton.onmousedown = function(evt) { - if (this.className.indexOf('disabled') === -1) { - this.className = 'down'; - } - }; - PDFViewer.nextPageButton.onmouseup = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - PDFViewer.nextPageButton.onmouseout = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - - PDFViewer.scaleSelect = document.getElementById('scaleSelect'); - PDFViewer.scaleSelect.onchange = function(evt) { - PDFViewer.changeScale(parseInt(this.value)); - }; - - if (window.File && window.FileReader && window.FileList && window.Blob) { - var openFileButton = document.getElementById('openFileButton'); - openFileButton.onclick = function(evt) { - if (this.className.indexOf('disabled') === -1) { - PDFViewer.fileInput.click(); - } - }; - openFileButton.onmousedown = function(evt) { - if (this.className.indexOf('disabled') === -1) { - this.className = 'down'; - } - }; - openFileButton.onmouseup = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - openFileButton.onmouseout = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - - PDFViewer.fileInput = document.getElementById('fileInput'); - PDFViewer.fileInput.onchange = function(evt) { - var files = evt.target.files; - - if (files.length > 0) { - var file = files[0]; - var fileReader = new FileReader(); + // Parse the URL query parameters into a cached object. + PDFViewer.queryParams = function() { + var qs = window.location.search.substring(1); + var kvs = qs.split('&'); + var params = {}; + for (var i = 0; i < kvs.length; ++i) { + var kv = kvs[i].split('='); + params[unescape(kv[0])] = unescape(kv[1]); + } - document.title = file.name; + return params; + }(); + + PDFViewer.element = document.getElementById('viewer'); + + PDFViewer.pageNumberInput = document.getElementById('pageNumber'); + PDFViewer.pageNumberInput.onkeydown = function(evt) { + var charCode = evt.charCode || evt.keyCode; + + // Up arrow key. + if (charCode === 38) { + PDFViewer.goToNextPage(); + this.select(); + } - // Read the local file into a Uint8Array. - fileReader.onload = function(evt) { - var data = evt.target.result; - var buffer = new ArrayBuffer(data.length); - var uint8Array = new Uint8Array(buffer); - - for (var i = 0; i < data.length; i++) { - uint8Array[i] = data.charCodeAt(i); - } - - PDFViewer.readPDF(uint8Array); + // Down arrow key. + else if (charCode === 40) { + PDFViewer.goToPreviousPage(); + this.select(); + } + + // All other non-numeric keys (excluding Left arrow, Right arrow, + // Backspace, and Delete keys). + else if ((charCode < 48 || charCode > 57) && + charCode !== 8 && // Backspace + charCode !== 46 && // Delete + charCode !== 37 && // Left arrow + charCode !== 39 // Right arrow + ) { + return false; + } + + return true; + }; + PDFViewer.pageNumberInput.onkeyup = function(evt) { + var charCode = evt.charCode || evt.keyCode; + + // All numeric keys, Backspace, and Delete. + if ((charCode >= 48 && charCode <= 57) || + charCode === 8 || // Backspace + charCode === 46 // Delete + ) { + PDFViewer.goToPage(this.value); + } + + this.focus(); + }; + + PDFViewer.previousPageButton = document.getElementById('previousPageButton'); + PDFViewer.previousPageButton.onclick = function(evt) { + if (this.className.indexOf('disabled') === -1) { + PDFViewer.goToPreviousPage(); + } + }; + PDFViewer.previousPageButton.onmousedown = function(evt) { + if (this.className.indexOf('disabled') === -1) { + this.className = 'down'; + } + }; + PDFViewer.previousPageButton.onmouseup = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + PDFViewer.previousPageButton.onmouseout = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + + PDFViewer.nextPageButton = document.getElementById('nextPageButton'); + PDFViewer.nextPageButton.onclick = function(evt) { + if (this.className.indexOf('disabled') === -1) { + PDFViewer.goToNextPage(); + } + }; + PDFViewer.nextPageButton.onmousedown = function(evt) { + if (this.className.indexOf('disabled') === -1) { + this.className = 'down'; + } + }; + PDFViewer.nextPageButton.onmouseup = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + PDFViewer.nextPageButton.onmouseout = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + + PDFViewer.scaleSelect = document.getElementById('scaleSelect'); + PDFViewer.scaleSelect.onchange = function(evt) { + PDFViewer.changeScale(parseInt(this.value)); + }; + + if (window.File && window.FileReader && window.FileList && window.Blob) { + var openFileButton = document.getElementById('openFileButton'); + openFileButton.onclick = function(evt) { + if (this.className.indexOf('disabled') === -1) { + PDFViewer.fileInput.click(); + } + }; + openFileButton.onmousedown = function(evt) { + if (this.className.indexOf('disabled') === -1) { + this.className = 'down'; + } + }; + openFileButton.onmouseup = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + openFileButton.onmouseout = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; }; - // Read as a binary string since "readAsArrayBuffer" is not yet - // implemented in Firefox. - fileReader.readAsBinaryString(file); - } - }; - PDFViewer.fileInput.value = null; - } else { - document.getElementById('fileWrapper').style.display = 'none'; - } - - PDFViewer.pageNumber = parseInt(PDFViewer.queryParams.page) || PDFViewer.pageNumber; - PDFViewer.scale = parseInt(PDFViewer.scaleSelect.value) / 100 || 1.0; - - PDFViewer.openURL(PDFViewer.queryParams.file || PDFViewer.url); - - window.onscroll = function(evt) { - var lastPagesDrawn = PDFViewer.lastPagesDrawn; - var visiblePages = PDFViewer.visiblePages(); - - var pagesToDraw = []; - var pagesToKeep = []; - var pagesToRemove = []; - - var i; - - // Determine which visible pages were not previously drawn. - for (i = 0; i < visiblePages.length; i++) { - if (lastPagesDrawn.indexOf(visiblePages[i]) === -1) { - pagesToDraw.push(visiblePages[i]); - PDFViewer.drawPage(visiblePages[i]); - } else { - pagesToKeep.push(visiblePages[i]); - } - } - - // Determine which previously drawn pages are no longer visible. - for (i = 0; i < lastPagesDrawn.length; i++) { - if (visiblePages.indexOf(lastPagesDrawn[i]) === -1) { - pagesToRemove.push(lastPagesDrawn[i]); - PDFViewer.removePage(lastPagesDrawn[i]); - } - } - - PDFViewer.lastPagesDrawn = pagesToDraw.concat(pagesToKeep); - - // Update the page number input with the current page number. - if (!PDFViewer.willJumpToPage && visiblePages.length > 0) { - PDFViewer.pageNumber = PDFViewer.pageNumberInput.value = visiblePages[0]; - PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? 'disabled' : ''; - PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? 'disabled' : ''; + PDFViewer.fileInput = document.getElementById('fileInput'); + PDFViewer.fileInput.onchange = function(evt) { + var files = evt.target.files; + + if (files.length > 0) { + var file = files[0]; + var fileReader = new FileReader(); + + document.title = file.name; + + // Read the local file into a Uint8Array. + fileReader.onload = function(evt) { + var data = evt.target.result; + var buffer = new ArrayBuffer(data.length); + var uint8Array = new Uint8Array(buffer); + + for (var i = 0; i < data.length; i++) { + uint8Array[i] = data.charCodeAt(i); + } + + PDFViewer.readPDF(uint8Array); + }; + + // Read as a binary string since "readAsArrayBuffer" is not yet + // implemented in Firefox. + fileReader.readAsBinaryString(file); + } + }; + PDFViewer.fileInput.value = null; } else { - PDFViewer.willJumpToPage = false; + document.getElementById('fileWrapper').style.display = 'none'; } - }; + + PDFViewer.pageNumber = parseInt(PDFViewer.queryParams.page) || PDFViewer.pageNumber; + PDFViewer.scale = parseInt(PDFViewer.scaleSelect.value) / 100 || 1.0; + + PDFViewer.openURL(PDFViewer.queryParams.file || PDFViewer.url); + + window.onscroll = function(evt) { + var lastPagesDrawn = PDFViewer.lastPagesDrawn; + var visiblePages = PDFViewer.visiblePages(); + + var pagesToDraw = []; + var pagesToKeep = []; + var pagesToRemove = []; + + var i; + + // Determine which visible pages were not previously drawn. + for (i = 0; i < visiblePages.length; i++) { + if (lastPagesDrawn.indexOf(visiblePages[i]) === -1) { + pagesToDraw.push(visiblePages[i]); + PDFViewer.drawPage(visiblePages[i]); + } else { + pagesToKeep.push(visiblePages[i]); + } + } + + // Determine which previously drawn pages are no longer visible. + for (i = 0; i < lastPagesDrawn.length; i++) { + if (visiblePages.indexOf(lastPagesDrawn[i]) === -1) { + pagesToRemove.push(lastPagesDrawn[i]); + PDFViewer.removePage(lastPagesDrawn[i]); + } + } + + PDFViewer.lastPagesDrawn = pagesToDraw.concat(pagesToKeep); + + // Update the page number input with the current page number. + if (!PDFViewer.willJumpToPage && visiblePages.length > 0) { + PDFViewer.pageNumber = PDFViewer.pageNumberInput.value = visiblePages[0]; + PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? + 'disabled' : ''; + PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? + 'disabled' : ''; + } else { + PDFViewer.willJumpToPage = false; + } + }; }; diff --git a/pdf.js b/pdf.js index b2b6401fd..ffefc61a1 100644 --- a/pdf.js +++ b/pdf.js @@ -3275,11 +3275,8 @@ var CanvasGraphics = (function() { } } - if (bitsPerComponent !== 8) { - TODO("Support bpc="+ bitsPerComponent); - this.restore(); - return; - } + if (bitsPerComponent !== 8) + error("Unsupported bpc"); var xref = this.xref; var colorSpaces = this.colorSpaces; From f9687a1707adc61d17aff2533b8498bfbfedff82 Mon Sep 17 00:00:00 2001 From: Justin D'Arcangelo Date: Thu, 23 Jun 2011 21:12:39 -0400 Subject: [PATCH 3/6] Fixed file renaming issues. --- multi_page_viewer.css | 197 ----------------- multi_page_viewer.html | 51 ----- multi_page_viewer.js | 466 ----------------------------------------- 3 files changed, 714 deletions(-) delete mode 100644 multi_page_viewer.css delete mode 100644 multi_page_viewer.html delete mode 100644 multi_page_viewer.js diff --git a/multi_page_viewer.css b/multi_page_viewer.css deleted file mode 100644 index 7f4701022..000000000 --- a/multi_page_viewer.css +++ /dev/null @@ -1,197 +0,0 @@ -/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / -/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ - -body { - background-color: #929292; - font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, Verdana, sans-serif; - margin: 0px; - padding: 0px; -} - -canvas { - box-shadow: 0px 4px 10px #000; - -moz-box-shadow: 0px 4px 10px #000; - -webkit-box-shadow: 0px 4px 10px #000; -} - -span { - font-size: 0.8em; -} - -.control { - display: inline-block; - float: left; - margin: 0px 20px 0px 0px; - padding: 0px 4px 0px 0px; -} - -.control > input { - float: left; - border: 1px solid #4d4d4d; - height: 20px; - padding: 0px; - margin: 0px 2px 0px 0px; - border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); -} - -.control > select { - float: left; - border: 1px solid #4d4d4d; - height: 22px; - padding: 2px 0px 0px; - margin: 0px 0px 1px; - border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); -} - -.control > span { - cursor: default; - float: left; - height: 18px; - margin: 5px 2px 0px; - padding: 0px; - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; -} - -.control .label { - clear: both; - float: left; - font-size: 0.65em; - margin: 2px 0px 0px; - position: relative; - text-align: center; - width: 100%; -} - -.page { - width: 816px; - height: 1056px; - margin: 10px auto; -} - -#controls { - background-color: #eee; - border-bottom: 1px solid #666; - padding: 4px 0px 0px 8px; - position: fixed; - left: 0px; - top: 0px; - height: 40px; - width: 100%; - box-shadow: 0px 2px 8px #000; - -moz-box-shadow: 0px 2px 8px #000; - -webkit-box-shadow: 0px 2px 8px #000; -} - -#controls input { - user-select: text; - -moz-user-select: text; - -webkit-user-select: text; -} - -#previousPageButton { - background: url('images/buttons.png') no-repeat 0px -23px; - cursor: default; - display: inline-block; - float: left; - margin: 0px; - width: 28px; - height: 23px; -} - -#previousPageButton.down { - background: url('images/buttons.png') no-repeat 0px -46px; -} - -#previousPageButton.disabled { - background: url('images/buttons.png') no-repeat 0px 0px; -} - -#nextPageButton { - background: url('images/buttons.png') no-repeat -28px -23px; - cursor: default; - display: inline-block; - float: left; - margin: 0px; - width: 28px; - height: 23px; -} - -#nextPageButton.down { - background: url('images/buttons.png') no-repeat -28px -46px; -} - -#nextPageButton.disabled { - background: url('images/buttons.png') no-repeat -28px 0px; -} - -#openFileButton { - background: url('images/buttons.png') no-repeat -56px -23px; - cursor: default; - display: inline-block; - float: left; - margin: 0px 0px 0px 3px; - width: 29px; - height: 23px; -} - -#openFileButton.down { - background: url('images/buttons.png') no-repeat -56px -46px; -} - -#openFileButton.disabled { - background: url('images/buttons.png') no-repeat -56px 0px; -} - -#fileInput { - display: none; -} - -#pageNumber { - text-align: right; -} - -#sidebar { - background-color: rgba(0, 0, 0, 0.8); - position: fixed; - width: 150px; - top: 62px; - bottom: 18px; - border-top-right-radius: 8px; - border-bottom-right-radius: 8px; - -moz-border-radius-topright: 8px; - -moz-border-radius-bottomright: 8px; - -webkit-border-top-right-radius: 8px; - -webkit-border-bottom-right-radius: 8px; -} - -#sidebarScrollView { - position: absolute; - overflow: hidden; - overflow-y: auto; - top: 40px; - right: 10px; - bottom: 10px; - left: 10px; -} - -#sidebarContentView { - height: auto; - width: 100px; -} - -#viewer { - margin: 44px 0px 0px; - padding: 8px 0px; -} diff --git a/multi_page_viewer.html b/multi_page_viewer.html deleted file mode 100644 index ffbdfe707..000000000 --- a/multi_page_viewer.html +++ /dev/null @@ -1,51 +0,0 @@ - - - -pdf.js Multi-Page Viewer - - - - - - - - -
- - - - Previous/Next - - - - / - -- - Page Number - - - - Zoom - - - - - Open File - -
- -
- - diff --git a/multi_page_viewer.js b/multi_page_viewer.js deleted file mode 100644 index baad7809e..000000000 --- a/multi_page_viewer.js +++ /dev/null @@ -1,466 +0,0 @@ -/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / -/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ - -"use strict"; - -var PDFViewer = { - queryParams: {}, - - element: null, - - previousPageButton: null, - nextPageButton: null, - pageNumberInput: null, - scaleSelect: null, - fileInput: null, - - willJumpToPage: false, - - pdf: null, - - url: 'compressed.tracemonkey-pldi-09.pdf', - pageNumber: 1, - numberOfPages: 1, - - scale: 1.0, - - pageWidth: function() { - return 816 * PDFViewer.scale; - }, - - pageHeight: function() { - return 1056 * PDFViewer.scale; - }, - - lastPagesDrawn: [], - - visiblePages: function() { - var pageHeight = PDFViewer.pageHeight() + 20; // Add 20 for the margins. - var windowTop = window.pageYOffset; - var windowBottom = window.pageYOffset + window.innerHeight; - var pageStartIndex = Math.floor(windowTop / pageHeight); - var pageStopIndex = Math.ceil(windowBottom / pageHeight); - - var pages = []; - - for (var i = pageStartIndex; i <= pageStopIndex; i++) { - pages.push(i + 1); - } - - return pages; - }, - - createPage: function(num) { - var anchor = document.createElement('a'); - anchor.name = '' + num; - - var div = document.createElement('div'); - div.id = 'pageContainer' + num; - div.className = 'page'; - div.style.width = PDFViewer.pageWidth() + 'px'; - div.style.height = PDFViewer.pageHeight() + 'px'; - - PDFViewer.element.appendChild(anchor); - PDFViewer.element.appendChild(div); - }, - - removePage: function(num) { - var div = document.getElementById('pageContainer' + num); - - if (div) { - while (div.hasChildNodes()) { - div.removeChild(div.firstChild); - } - } - }, - - drawPage: function(num) { - if (!PDFViewer.pdf) { - return; - } - - var div = document.getElementById('pageContainer' + num); - var canvas = document.createElement('canvas'); - - if (div && !div.hasChildNodes()) { - div.appendChild(canvas); - - var page = PDFViewer.pdf.getPage(num); - - canvas.id = 'page' + num; - canvas.mozOpaque = true; - - // Canvas dimensions must be specified in CSS pixels. CSS pixels - // are always 96 dpi. These dimensions are 8.5in x 11in at 96dpi. - canvas.width = PDFViewer.pageWidth(); - canvas.height = PDFViewer.pageHeight(); - - var ctx = canvas.getContext('2d'); - ctx.save(); - ctx.fillStyle = 'rgb(255, 255, 255)'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.restore(); - - var gfx = new CanvasGraphics(ctx); - var fonts = []; - - // page.compile will collect all fonts for us, once we have loaded them - // we can trigger the actual page rendering with page.display - page.compile(gfx, fonts); - - var areFontsReady = true; - - // Inspect fonts and translate the missing one - var fontCount = fonts.length; - - for (var i = 0; i < fontCount; i++) { - var font = fonts[i]; - - if (Fonts[font.name]) { - areFontsReady = areFontsReady && !Fonts[font.name].loading; - continue; - } - - new Font(font.name, font.file, font.properties); - - areFontsReady = false; - } - - var pageInterval; - - var delayLoadFont = function() { - for (var i = 0; i < fontCount; i++) { - if (Fonts[font.name].loading) { - return; - } - } - - clearInterval(pageInterval); - - while (div.hasChildNodes()) { - div.removeChild(div.firstChild); - } - - PDFViewer.drawPage(num); - } - - if (!areFontsReady) { - pageInterval = setInterval(delayLoadFont, 10); - return; - } - - page.display(gfx); - } - }, - - changeScale: function(num) { - while (PDFViewer.element.hasChildNodes()) { - PDFViewer.element.removeChild(PDFViewer.element.firstChild); - } - - PDFViewer.scale = num / 100; - - var i; - - if (PDFViewer.pdf) { - for (i = 1; i <= PDFViewer.numberOfPages; i++) { - PDFViewer.createPage(i); - } - - if (PDFViewer.numberOfPages > 0) { - PDFViewer.drawPage(1); - } - } - - for (i = 0; i < PDFViewer.scaleSelect.childNodes; i++) { - var option = PDFViewer.scaleSelect.childNodes[i]; - - if (option.value == num) { - if (!option.selected) { - option.selected = 'selected'; - } - } else { - if (option.selected) { - option.removeAttribute('selected'); - } - } - } - - PDFViewer.scaleSelect.value = Math.floor(PDFViewer.scale * 100) + '%'; - }, - - goToPage: function(num) { - if (1 <= num && num <= PDFViewer.numberOfPages) { - PDFViewer.pageNumber = num; - PDFViewer.pageNumberInput.value = PDFViewer.pageNumber; - PDFViewer.willJumpToPage = true; - - document.location.hash = PDFViewer.pageNumber; - - PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? - 'disabled' : ''; - PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? - 'disabled' : ''; - } - }, - - goToPreviousPage: function() { - if (PDFViewer.pageNumber > 1) { - PDFViewer.goToPage(--PDFViewer.pageNumber); - } - }, - - goToNextPage: function() { - if (PDFViewer.pageNumber < PDFViewer.numberOfPages) { - PDFViewer.goToPage(++PDFViewer.pageNumber); - } - }, - - openURL: function(url) { - PDFViewer.url = url; - document.title = url; - - var req = new XMLHttpRequest(); - req.open('GET', url); - req.mozResponseType = req.responseType = 'arraybuffer'; - req.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; - - req.onreadystatechange = function() { - if (req.readyState === 4 && req.status === req.expected) { - var data = req.mozResponseArrayBuffer || - req.mozResponse || - req.responseArrayBuffer || - req.response; - - PDFViewer.readPDF(data); - } - }; - - req.send(null); - }, - - readPDF: function(data) { - while (PDFViewer.element.hasChildNodes()) { - PDFViewer.element.removeChild(PDFViewer.element.firstChild); - } - - PDFViewer.pdf = new PDFDoc(new Stream(data)); - PDFViewer.numberOfPages = PDFViewer.pdf.numPages; - document.getElementById('numPages').innerHTML = PDFViewer.numberOfPages.toString(); - - for (var i = 1; i <= PDFViewer.numberOfPages; i++) { - PDFViewer.createPage(i); - } - - if (PDFViewer.numberOfPages > 0) { - PDFViewer.drawPage(1); - document.location.hash = 1; - } - - PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? - 'disabled' : ''; - PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? - 'disabled' : ''; - } -}; - -window.onload = function() { - - // Parse the URL query parameters into a cached object. - PDFViewer.queryParams = function() { - var qs = window.location.search.substring(1); - var kvs = qs.split('&'); - var params = {}; - for (var i = 0; i < kvs.length; ++i) { - var kv = kvs[i].split('='); - params[unescape(kv[0])] = unescape(kv[1]); - } - - return params; - }(); - - PDFViewer.element = document.getElementById('viewer'); - - PDFViewer.pageNumberInput = document.getElementById('pageNumber'); - PDFViewer.pageNumberInput.onkeydown = function(evt) { - var charCode = evt.charCode || evt.keyCode; - - // Up arrow key. - if (charCode === 38) { - PDFViewer.goToNextPage(); - this.select(); - } - - // Down arrow key. - else if (charCode === 40) { - PDFViewer.goToPreviousPage(); - this.select(); - } - - // All other non-numeric keys (excluding Left arrow, Right arrow, - // Backspace, and Delete keys). - else if ((charCode < 48 || charCode > 57) && - charCode !== 8 && // Backspace - charCode !== 46 && // Delete - charCode !== 37 && // Left arrow - charCode !== 39 // Right arrow - ) { - return false; - } - - return true; - }; - PDFViewer.pageNumberInput.onkeyup = function(evt) { - var charCode = evt.charCode || evt.keyCode; - - // All numeric keys, Backspace, and Delete. - if ((charCode >= 48 && charCode <= 57) || - charCode === 8 || // Backspace - charCode === 46 // Delete - ) { - PDFViewer.goToPage(this.value); - } - - this.focus(); - }; - - PDFViewer.previousPageButton = document.getElementById('previousPageButton'); - PDFViewer.previousPageButton.onclick = function(evt) { - if (this.className.indexOf('disabled') === -1) { - PDFViewer.goToPreviousPage(); - } - }; - PDFViewer.previousPageButton.onmousedown = function(evt) { - if (this.className.indexOf('disabled') === -1) { - this.className = 'down'; - } - }; - PDFViewer.previousPageButton.onmouseup = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - PDFViewer.previousPageButton.onmouseout = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - - PDFViewer.nextPageButton = document.getElementById('nextPageButton'); - PDFViewer.nextPageButton.onclick = function(evt) { - if (this.className.indexOf('disabled') === -1) { - PDFViewer.goToNextPage(); - } - }; - PDFViewer.nextPageButton.onmousedown = function(evt) { - if (this.className.indexOf('disabled') === -1) { - this.className = 'down'; - } - }; - PDFViewer.nextPageButton.onmouseup = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - PDFViewer.nextPageButton.onmouseout = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - - PDFViewer.scaleSelect = document.getElementById('scaleSelect'); - PDFViewer.scaleSelect.onchange = function(evt) { - PDFViewer.changeScale(parseInt(this.value)); - }; - - if (window.File && window.FileReader && window.FileList && window.Blob) { - var openFileButton = document.getElementById('openFileButton'); - openFileButton.onclick = function(evt) { - if (this.className.indexOf('disabled') === -1) { - PDFViewer.fileInput.click(); - } - }; - openFileButton.onmousedown = function(evt) { - if (this.className.indexOf('disabled') === -1) { - this.className = 'down'; - } - }; - openFileButton.onmouseup = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - openFileButton.onmouseout = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - - PDFViewer.fileInput = document.getElementById('fileInput'); - PDFViewer.fileInput.onchange = function(evt) { - var files = evt.target.files; - - if (files.length > 0) { - var file = files[0]; - var fileReader = new FileReader(); - - document.title = file.name; - - // Read the local file into a Uint8Array. - fileReader.onload = function(evt) { - var data = evt.target.result; - var buffer = new ArrayBuffer(data.length); - var uint8Array = new Uint8Array(buffer); - - for (var i = 0; i < data.length; i++) { - uint8Array[i] = data.charCodeAt(i); - } - - PDFViewer.readPDF(uint8Array); - }; - - // Read as a binary string since "readAsArrayBuffer" is not yet - // implemented in Firefox. - fileReader.readAsBinaryString(file); - } - }; - PDFViewer.fileInput.value = null; - } else { - document.getElementById('fileWrapper').style.display = 'none'; - } - - PDFViewer.pageNumber = parseInt(PDFViewer.queryParams.page) || PDFViewer.pageNumber; - PDFViewer.scale = parseInt(PDFViewer.scaleSelect.value) / 100 || 1.0; - - PDFViewer.openURL(PDFViewer.queryParams.file || PDFViewer.url); - - window.onscroll = function(evt) { - var lastPagesDrawn = PDFViewer.lastPagesDrawn; - var visiblePages = PDFViewer.visiblePages(); - - var pagesToDraw = []; - var pagesToKeep = []; - var pagesToRemove = []; - - var i; - - // Determine which visible pages were not previously drawn. - for (i = 0; i < visiblePages.length; i++) { - if (lastPagesDrawn.indexOf(visiblePages[i]) === -1) { - pagesToDraw.push(visiblePages[i]); - PDFViewer.drawPage(visiblePages[i]); - } else { - pagesToKeep.push(visiblePages[i]); - } - } - - // Determine which previously drawn pages are no longer visible. - for (i = 0; i < lastPagesDrawn.length; i++) { - if (visiblePages.indexOf(lastPagesDrawn[i]) === -1) { - pagesToRemove.push(lastPagesDrawn[i]); - PDFViewer.removePage(lastPagesDrawn[i]); - } - } - - PDFViewer.lastPagesDrawn = pagesToDraw.concat(pagesToKeep); - - // Update the page number input with the current page number. - if (!PDFViewer.willJumpToPage && visiblePages.length > 0) { - PDFViewer.pageNumber = PDFViewer.pageNumberInput.value = visiblePages[0]; - PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? - 'disabled' : ''; - PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? - 'disabled' : ''; - } else { - PDFViewer.willJumpToPage = false; - } - }; -}; From b18006a055b07eefc6b1495c7a581c1fa55681b5 Mon Sep 17 00:00:00 2001 From: Justin D'Arcangelo Date: Thu, 23 Jun 2011 21:17:31 -0400 Subject: [PATCH 4/6] Fixed file renaming issues. --- multi-page-viewer.css => multi_page_viewer.css | 0 multi-page-viewer.html => multi_page_viewer.html | 0 multi-page-viewer.js => multi_page_viewer.js | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename multi-page-viewer.css => multi_page_viewer.css (100%) rename multi-page-viewer.html => multi_page_viewer.html (100%) rename multi-page-viewer.js => multi_page_viewer.js (100%) diff --git a/multi-page-viewer.css b/multi_page_viewer.css similarity index 100% rename from multi-page-viewer.css rename to multi_page_viewer.css diff --git a/multi-page-viewer.html b/multi_page_viewer.html similarity index 100% rename from multi-page-viewer.html rename to multi_page_viewer.html diff --git a/multi-page-viewer.js b/multi_page_viewer.js similarity index 100% rename from multi-page-viewer.js rename to multi_page_viewer.js From b9af0da8f8bd59874b1141649b5b84dc30b7ca71 Mon Sep 17 00:00:00 2001 From: Justin D'Arcangelo Date: Thu, 23 Jun 2011 21:18:07 -0400 Subject: [PATCH 5/6] Fixed vim indentation rules. --- multi_page_viewer.css | 238 +++++------ multi_page_viewer.html | 76 ++-- multi_page_viewer.js | 886 ++++++++++++++++++++--------------------- 3 files changed, 596 insertions(+), 604 deletions(-) diff --git a/multi_page_viewer.css b/multi_page_viewer.css index 7f4701022..b3eaab792 100644 --- a/multi_page_viewer.css +++ b/multi_page_viewer.css @@ -1,197 +1,197 @@ -/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / -/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ body { - background-color: #929292; - font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, Verdana, sans-serif; - margin: 0px; - padding: 0px; + background-color: #929292; + font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, Verdana, sans-serif; + margin: 0px; + padding: 0px; } canvas { - box-shadow: 0px 4px 10px #000; - -moz-box-shadow: 0px 4px 10px #000; - -webkit-box-shadow: 0px 4px 10px #000; + box-shadow: 0px 4px 10px #000; + -moz-box-shadow: 0px 4px 10px #000; + -webkit-box-shadow: 0px 4px 10px #000; } span { - font-size: 0.8em; + font-size: 0.8em; } .control { - display: inline-block; - float: left; - margin: 0px 20px 0px 0px; - padding: 0px 4px 0px 0px; + display: inline-block; + float: left; + margin: 0px 20px 0px 0px; + padding: 0px 4px 0px 0px; } .control > input { - float: left; - border: 1px solid #4d4d4d; - height: 20px; - padding: 0px; - margin: 0px 2px 0px 0px; - border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + float: left; + border: 1px solid #4d4d4d; + height: 20px; + padding: 0px; + margin: 0px 2px 0px 0px; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); } .control > select { - float: left; - border: 1px solid #4d4d4d; - height: 22px; - padding: 2px 0px 0px; - margin: 0px 0px 1px; - border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); - -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + float: left; + border: 1px solid #4d4d4d; + height: 22px; + padding: 2px 0px 0px; + margin: 0px 0px 1px; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); + -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25); } .control > span { - cursor: default; - float: left; - height: 18px; - margin: 5px 2px 0px; - padding: 0px; - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; + cursor: default; + float: left; + height: 18px; + margin: 5px 2px 0px; + padding: 0px; + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; } .control .label { - clear: both; - float: left; - font-size: 0.65em; - margin: 2px 0px 0px; - position: relative; - text-align: center; - width: 100%; + clear: both; + float: left; + font-size: 0.65em; + margin: 2px 0px 0px; + position: relative; + text-align: center; + width: 100%; } .page { - width: 816px; - height: 1056px; - margin: 10px auto; + width: 816px; + height: 1056px; + margin: 10px auto; } #controls { - background-color: #eee; - border-bottom: 1px solid #666; - padding: 4px 0px 0px 8px; - position: fixed; - left: 0px; - top: 0px; - height: 40px; - width: 100%; - box-shadow: 0px 2px 8px #000; - -moz-box-shadow: 0px 2px 8px #000; - -webkit-box-shadow: 0px 2px 8px #000; + background-color: #eee; + border-bottom: 1px solid #666; + padding: 4px 0px 0px 8px; + position: fixed; + left: 0px; + top: 0px; + height: 40px; + width: 100%; + box-shadow: 0px 2px 8px #000; + -moz-box-shadow: 0px 2px 8px #000; + -webkit-box-shadow: 0px 2px 8px #000; } #controls input { - user-select: text; - -moz-user-select: text; - -webkit-user-select: text; + user-select: text; + -moz-user-select: text; + -webkit-user-select: text; } #previousPageButton { - background: url('images/buttons.png') no-repeat 0px -23px; - cursor: default; - display: inline-block; - float: left; - margin: 0px; - width: 28px; - height: 23px; + background: url('images/buttons.png') no-repeat 0px -23px; + cursor: default; + display: inline-block; + float: left; + margin: 0px; + width: 28px; + height: 23px; } #previousPageButton.down { - background: url('images/buttons.png') no-repeat 0px -46px; + background: url('images/buttons.png') no-repeat 0px -46px; } #previousPageButton.disabled { - background: url('images/buttons.png') no-repeat 0px 0px; + background: url('images/buttons.png') no-repeat 0px 0px; } #nextPageButton { - background: url('images/buttons.png') no-repeat -28px -23px; - cursor: default; - display: inline-block; - float: left; - margin: 0px; - width: 28px; - height: 23px; + background: url('images/buttons.png') no-repeat -28px -23px; + cursor: default; + display: inline-block; + float: left; + margin: 0px; + width: 28px; + height: 23px; } #nextPageButton.down { - background: url('images/buttons.png') no-repeat -28px -46px; + background: url('images/buttons.png') no-repeat -28px -46px; } #nextPageButton.disabled { - background: url('images/buttons.png') no-repeat -28px 0px; + background: url('images/buttons.png') no-repeat -28px 0px; } #openFileButton { - background: url('images/buttons.png') no-repeat -56px -23px; - cursor: default; - display: inline-block; - float: left; - margin: 0px 0px 0px 3px; - width: 29px; - height: 23px; + background: url('images/buttons.png') no-repeat -56px -23px; + cursor: default; + display: inline-block; + float: left; + margin: 0px 0px 0px 3px; + width: 29px; + height: 23px; } #openFileButton.down { - background: url('images/buttons.png') no-repeat -56px -46px; + background: url('images/buttons.png') no-repeat -56px -46px; } #openFileButton.disabled { - background: url('images/buttons.png') no-repeat -56px 0px; + background: url('images/buttons.png') no-repeat -56px 0px; } #fileInput { - display: none; + display: none; } #pageNumber { - text-align: right; + text-align: right; } #sidebar { - background-color: rgba(0, 0, 0, 0.8); - position: fixed; - width: 150px; - top: 62px; - bottom: 18px; - border-top-right-radius: 8px; - border-bottom-right-radius: 8px; - -moz-border-radius-topright: 8px; - -moz-border-radius-bottomright: 8px; - -webkit-border-top-right-radius: 8px; - -webkit-border-bottom-right-radius: 8px; + background-color: rgba(0, 0, 0, 0.8); + position: fixed; + width: 150px; + top: 62px; + bottom: 18px; + border-top-right-radius: 8px; + border-bottom-right-radius: 8px; + -moz-border-radius-topright: 8px; + -moz-border-radius-bottomright: 8px; + -webkit-border-top-right-radius: 8px; + -webkit-border-bottom-right-radius: 8px; } #sidebarScrollView { - position: absolute; - overflow: hidden; - overflow-y: auto; - top: 40px; - right: 10px; - bottom: 10px; - left: 10px; + position: absolute; + overflow: hidden; + overflow-y: auto; + top: 40px; + right: 10px; + bottom: 10px; + left: 10px; } #sidebarContentView { - height: auto; - width: 100px; + height: auto; + width: 100px; } #viewer { - margin: 44px 0px 0px; - padding: 8px 0px; + margin: 44px 0px 0px; + padding: 8px 0px; } diff --git a/multi_page_viewer.html b/multi_page_viewer.html index ffbdfe707..47234686d 100644 --- a/multi_page_viewer.html +++ b/multi_page_viewer.html @@ -3,49 +3,49 @@ pdf.js Multi-Page Viewer - + - + -
- - - - Previous/Next - - - - / - -- - Page Number - - - - Zoom - - - - - Open File - +
+ + + + Previous/Next + + + + / + -- + Page Number + + + + Zoom + + + + + Open File + +
+ -
+
--> +
diff --git a/multi_page_viewer.js b/multi_page_viewer.js index baad7809e..3a02ea332 100644 --- a/multi_page_viewer.js +++ b/multi_page_viewer.js @@ -1,466 +1,458 @@ -/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / -/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ "use strict"; var PDFViewer = { - queryParams: {}, - - element: null, - - previousPageButton: null, - nextPageButton: null, - pageNumberInput: null, - scaleSelect: null, - fileInput: null, - - willJumpToPage: false, - - pdf: null, - - url: 'compressed.tracemonkey-pldi-09.pdf', - pageNumber: 1, - numberOfPages: 1, - - scale: 1.0, - - pageWidth: function() { - return 816 * PDFViewer.scale; - }, - - pageHeight: function() { - return 1056 * PDFViewer.scale; - }, - - lastPagesDrawn: [], - - visiblePages: function() { - var pageHeight = PDFViewer.pageHeight() + 20; // Add 20 for the margins. - var windowTop = window.pageYOffset; - var windowBottom = window.pageYOffset + window.innerHeight; - var pageStartIndex = Math.floor(windowTop / pageHeight); - var pageStopIndex = Math.ceil(windowBottom / pageHeight); - - var pages = []; - - for (var i = pageStartIndex; i <= pageStopIndex; i++) { - pages.push(i + 1); - } - - return pages; - }, + queryParams: {}, - createPage: function(num) { - var anchor = document.createElement('a'); - anchor.name = '' + num; - - var div = document.createElement('div'); - div.id = 'pageContainer' + num; - div.className = 'page'; - div.style.width = PDFViewer.pageWidth() + 'px'; - div.style.height = PDFViewer.pageHeight() + 'px'; - - PDFViewer.element.appendChild(anchor); - PDFViewer.element.appendChild(div); - }, - - removePage: function(num) { - var div = document.getElementById('pageContainer' + num); - - if (div) { - while (div.hasChildNodes()) { - div.removeChild(div.firstChild); - } - } - }, - - drawPage: function(num) { - if (!PDFViewer.pdf) { - return; - } - - var div = document.getElementById('pageContainer' + num); - var canvas = document.createElement('canvas'); - - if (div && !div.hasChildNodes()) { - div.appendChild(canvas); - - var page = PDFViewer.pdf.getPage(num); - - canvas.id = 'page' + num; - canvas.mozOpaque = true; - - // Canvas dimensions must be specified in CSS pixels. CSS pixels - // are always 96 dpi. These dimensions are 8.5in x 11in at 96dpi. - canvas.width = PDFViewer.pageWidth(); - canvas.height = PDFViewer.pageHeight(); - - var ctx = canvas.getContext('2d'); - ctx.save(); - ctx.fillStyle = 'rgb(255, 255, 255)'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.restore(); - - var gfx = new CanvasGraphics(ctx); - var fonts = []; - - // page.compile will collect all fonts for us, once we have loaded them - // we can trigger the actual page rendering with page.display - page.compile(gfx, fonts); - - var areFontsReady = true; - - // Inspect fonts and translate the missing one - var fontCount = fonts.length; - - for (var i = 0; i < fontCount; i++) { - var font = fonts[i]; - - if (Fonts[font.name]) { - areFontsReady = areFontsReady && !Fonts[font.name].loading; - continue; - } - - new Font(font.name, font.file, font.properties); - - areFontsReady = false; - } - - var pageInterval; - - var delayLoadFont = function() { - for (var i = 0; i < fontCount; i++) { - if (Fonts[font.name].loading) { - return; - } - } - - clearInterval(pageInterval); - - while (div.hasChildNodes()) { - div.removeChild(div.firstChild); - } - - PDFViewer.drawPage(num); - } - - if (!areFontsReady) { - pageInterval = setInterval(delayLoadFont, 10); - return; - } - - page.display(gfx); - } - }, - - changeScale: function(num) { - while (PDFViewer.element.hasChildNodes()) { - PDFViewer.element.removeChild(PDFViewer.element.firstChild); - } - - PDFViewer.scale = num / 100; - - var i; - - if (PDFViewer.pdf) { - for (i = 1; i <= PDFViewer.numberOfPages; i++) { - PDFViewer.createPage(i); - } - - if (PDFViewer.numberOfPages > 0) { - PDFViewer.drawPage(1); - } - } - - for (i = 0; i < PDFViewer.scaleSelect.childNodes; i++) { - var option = PDFViewer.scaleSelect.childNodes[i]; - - if (option.value == num) { - if (!option.selected) { - option.selected = 'selected'; - } - } else { - if (option.selected) { - option.removeAttribute('selected'); - } - } - } - - PDFViewer.scaleSelect.value = Math.floor(PDFViewer.scale * 100) + '%'; - }, - - goToPage: function(num) { - if (1 <= num && num <= PDFViewer.numberOfPages) { - PDFViewer.pageNumber = num; - PDFViewer.pageNumberInput.value = PDFViewer.pageNumber; - PDFViewer.willJumpToPage = true; - - document.location.hash = PDFViewer.pageNumber; - - PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? - 'disabled' : ''; - PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? - 'disabled' : ''; - } - }, + element: null, - goToPreviousPage: function() { - if (PDFViewer.pageNumber > 1) { - PDFViewer.goToPage(--PDFViewer.pageNumber); - } - }, + previousPageButton: null, + nextPageButton: null, + pageNumberInput: null, + scaleSelect: null, + fileInput: null, - goToNextPage: function() { - if (PDFViewer.pageNumber < PDFViewer.numberOfPages) { - PDFViewer.goToPage(++PDFViewer.pageNumber); - } - }, + willJumpToPage: false, - openURL: function(url) { - PDFViewer.url = url; - document.title = url; - - var req = new XMLHttpRequest(); - req.open('GET', url); - req.mozResponseType = req.responseType = 'arraybuffer'; - req.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; - - req.onreadystatechange = function() { - if (req.readyState === 4 && req.status === req.expected) { - var data = req.mozResponseArrayBuffer || - req.mozResponse || - req.responseArrayBuffer || - req.response; - - PDFViewer.readPDF(data); - } - }; - - req.send(null); - }, - - readPDF: function(data) { - while (PDFViewer.element.hasChildNodes()) { - PDFViewer.element.removeChild(PDFViewer.element.firstChild); - } - - PDFViewer.pdf = new PDFDoc(new Stream(data)); - PDFViewer.numberOfPages = PDFViewer.pdf.numPages; - document.getElementById('numPages').innerHTML = PDFViewer.numberOfPages.toString(); + pdf: null, - for (var i = 1; i <= PDFViewer.numberOfPages; i++) { - PDFViewer.createPage(i); - } - - if (PDFViewer.numberOfPages > 0) { - PDFViewer.drawPage(1); - document.location.hash = 1; - } - - PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? - 'disabled' : ''; - PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? - 'disabled' : ''; + url: 'compressed.tracemonkey-pldi-09.pdf', + pageNumber: 1, + numberOfPages: 1, + + scale: 1.0, + + pageWidth: function() { + return 816 * PDFViewer.scale; + }, + + pageHeight: function() { + return 1056 * PDFViewer.scale; + }, + + lastPagesDrawn: [], + + visiblePages: function() { + var pageHeight = PDFViewer.pageHeight() + 20; // Add 20 for the margins. + var windowTop = window.pageYOffset; + var windowBottom = window.pageYOffset + window.innerHeight; + var pageStartIndex = Math.floor(windowTop / pageHeight); + var pageStopIndex = Math.ceil(windowBottom / pageHeight); + + var pages = []; + + for (var i = pageStartIndex; i <= pageStopIndex; i++) { + pages.push(i + 1); } + + return pages; + }, + + createPage: function(num) { + var anchor = document.createElement('a'); + anchor.name = '' + num; + + var div = document.createElement('div'); + div.id = 'pageContainer' + num; + div.className = 'page'; + div.style.width = PDFViewer.pageWidth() + 'px'; + div.style.height = PDFViewer.pageHeight() + 'px'; + + PDFViewer.element.appendChild(anchor); + PDFViewer.element.appendChild(div); + }, + + removePage: function(num) { + var div = document.getElementById('pageContainer' + num); + + if (div) { + while (div.hasChildNodes()) { + div.removeChild(div.firstChild); + } + } + }, + + drawPage: function(num) { + if (!PDFViewer.pdf) { + return; + } + + var div = document.getElementById('pageContainer' + num); + var canvas = document.createElement('canvas'); + + if (div && !div.hasChildNodes()) { + div.appendChild(canvas); + + var page = PDFViewer.pdf.getPage(num); + + canvas.id = 'page' + num; + canvas.mozOpaque = true; + + // Canvas dimensions must be specified in CSS pixels. CSS pixels + // are always 96 dpi. These dimensions are 8.5in x 11in at 96dpi. + canvas.width = PDFViewer.pageWidth(); + canvas.height = PDFViewer.pageHeight(); + + var ctx = canvas.getContext('2d'); + ctx.save(); + ctx.fillStyle = 'rgb(255, 255, 255)'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.restore(); + + var gfx = new CanvasGraphics(ctx); + var fonts = []; + + // page.compile will collect all fonts for us, once we have loaded them + // we can trigger the actual page rendering with page.display + page.compile(gfx, fonts); + + var areFontsReady = true; + + // Inspect fonts and translate the missing one + var fontCount = fonts.length; + + for (var i = 0; i < fontCount; i++) { + var font = fonts[i]; + + if (Fonts[font.name]) { + areFontsReady = areFontsReady && !Fonts[font.name].loading; + continue; + } + + new Font(font.name, font.file, font.properties); + + areFontsReady = false; + } + + var pageInterval; + + var delayLoadFont = function() { + for (var i = 0; i < fontCount; i++) { + if (Fonts[font.name].loading) { + return; + } + } + + clearInterval(pageInterval); + + while (div.hasChildNodes()) { + div.removeChild(div.firstChild); + } + + PDFViewer.drawPage(num); + } + + if (!areFontsReady) { + pageInterval = setInterval(delayLoadFont, 10); + return; + } + + page.display(gfx); + } + }, + + changeScale: function(num) { + while (PDFViewer.element.hasChildNodes()) { + PDFViewer.element.removeChild(PDFViewer.element.firstChild); + } + + PDFViewer.scale = num / 100; + + var i; + + if (PDFViewer.pdf) { + for (i = 1; i <= PDFViewer.numberOfPages; i++) { + PDFViewer.createPage(i); + } + + if (PDFViewer.numberOfPages > 0) { + PDFViewer.drawPage(1); + } + } + + for (i = 0; i < PDFViewer.scaleSelect.childNodes; i++) { + var option = PDFViewer.scaleSelect.childNodes[i]; + + if (option.value == num) { + if (!option.selected) { + option.selected = 'selected'; + } + } else { + if (option.selected) { + option.removeAttribute('selected'); + } + } + } + + PDFViewer.scaleSelect.value = Math.floor(PDFViewer.scale * 100) + '%'; + }, + + goToPage: function(num) { + if (1 <= num && num <= PDFViewer.numberOfPages) { + PDFViewer.pageNumber = num; + PDFViewer.pageNumberInput.value = PDFViewer.pageNumber; + PDFViewer.willJumpToPage = true; + + document.location.hash = PDFViewer.pageNumber; + + PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? 'disabled' : ''; + PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? 'disabled' : ''; + } + }, + + goToPreviousPage: function() { + if (PDFViewer.pageNumber > 1) { + PDFViewer.goToPage(--PDFViewer.pageNumber); + } + }, + + goToNextPage: function() { + if (PDFViewer.pageNumber < PDFViewer.numberOfPages) { + PDFViewer.goToPage(++PDFViewer.pageNumber); + } + }, + + openURL: function(url) { + PDFViewer.url = url; + document.title = url; + + var req = new XMLHttpRequest(); + req.open('GET', url); + req.mozResponseType = req.responseType = 'arraybuffer'; + req.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; + + req.onreadystatechange = function() { + if (req.readyState === 4 && req.status === req.expected) { + var data = req.mozResponseArrayBuffer || req.mozResponse || req.responseArrayBuffer || req.response; + + PDFViewer.readPDF(data); + } + }; + + req.send(null); + }, + + readPDF: function(data) { + while (PDFViewer.element.hasChildNodes()) { + PDFViewer.element.removeChild(PDFViewer.element.firstChild); + } + + PDFViewer.pdf = new PDFDoc(new Stream(data)); + PDFViewer.numberOfPages = PDFViewer.pdf.numPages; + document.getElementById('numPages').innerHTML = PDFViewer.numberOfPages.toString(); + + for (var i = 1; i <= PDFViewer.numberOfPages; i++) { + PDFViewer.createPage(i); + } + + if (PDFViewer.numberOfPages > 0) { + PDFViewer.drawPage(1); + document.location.hash = 1; + } + + PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? 'disabled' : ''; + PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? 'disabled' : ''; + } }; window.onload = function() { - - // Parse the URL query parameters into a cached object. - PDFViewer.queryParams = function() { - var qs = window.location.search.substring(1); - var kvs = qs.split('&'); - var params = {}; - for (var i = 0; i < kvs.length; ++i) { - var kv = kvs[i].split('='); - params[unescape(kv[0])] = unescape(kv[1]); - } - - return params; - }(); - - PDFViewer.element = document.getElementById('viewer'); - - PDFViewer.pageNumberInput = document.getElementById('pageNumber'); - PDFViewer.pageNumberInput.onkeydown = function(evt) { - var charCode = evt.charCode || evt.keyCode; - - // Up arrow key. - if (charCode === 38) { - PDFViewer.goToNextPage(); - this.select(); - } - - // Down arrow key. - else if (charCode === 40) { - PDFViewer.goToPreviousPage(); - this.select(); - } - - // All other non-numeric keys (excluding Left arrow, Right arrow, - // Backspace, and Delete keys). - else if ((charCode < 48 || charCode > 57) && - charCode !== 8 && // Backspace - charCode !== 46 && // Delete - charCode !== 37 && // Left arrow - charCode !== 39 // Right arrow - ) { - return false; - } - - return true; - }; - PDFViewer.pageNumberInput.onkeyup = function(evt) { - var charCode = evt.charCode || evt.keyCode; - - // All numeric keys, Backspace, and Delete. - if ((charCode >= 48 && charCode <= 57) || - charCode === 8 || // Backspace - charCode === 46 // Delete - ) { - PDFViewer.goToPage(this.value); - } - - this.focus(); - }; - - PDFViewer.previousPageButton = document.getElementById('previousPageButton'); - PDFViewer.previousPageButton.onclick = function(evt) { - if (this.className.indexOf('disabled') === -1) { - PDFViewer.goToPreviousPage(); - } - }; - PDFViewer.previousPageButton.onmousedown = function(evt) { - if (this.className.indexOf('disabled') === -1) { - this.className = 'down'; - } - }; - PDFViewer.previousPageButton.onmouseup = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - PDFViewer.previousPageButton.onmouseout = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; + + // Parse the URL query parameters into a cached object. + PDFViewer.queryParams = function() { + var qs = window.location.search.substring(1); + var kvs = qs.split('&'); + var params = {}; - PDFViewer.nextPageButton = document.getElementById('nextPageButton'); - PDFViewer.nextPageButton.onclick = function(evt) { - if (this.className.indexOf('disabled') === -1) { - PDFViewer.goToNextPage(); - } - }; - PDFViewer.nextPageButton.onmousedown = function(evt) { - if (this.className.indexOf('disabled') === -1) { - this.className = 'down'; - } - }; - PDFViewer.nextPageButton.onmouseup = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - PDFViewer.nextPageButton.onmouseout = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - - PDFViewer.scaleSelect = document.getElementById('scaleSelect'); - PDFViewer.scaleSelect.onchange = function(evt) { - PDFViewer.changeScale(parseInt(this.value)); - }; - - if (window.File && window.FileReader && window.FileList && window.Blob) { - var openFileButton = document.getElementById('openFileButton'); - openFileButton.onclick = function(evt) { - if (this.className.indexOf('disabled') === -1) { - PDFViewer.fileInput.click(); - } - }; - openFileButton.onmousedown = function(evt) { - if (this.className.indexOf('disabled') === -1) { - this.className = 'down'; - } - }; - openFileButton.onmouseup = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - openFileButton.onmouseout = function(evt) { - this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; - }; - - PDFViewer.fileInput = document.getElementById('fileInput'); - PDFViewer.fileInput.onchange = function(evt) { - var files = evt.target.files; - - if (files.length > 0) { - var file = files[0]; - var fileReader = new FileReader(); - - document.title = file.name; - - // Read the local file into a Uint8Array. - fileReader.onload = function(evt) { - var data = evt.target.result; - var buffer = new ArrayBuffer(data.length); - var uint8Array = new Uint8Array(buffer); - - for (var i = 0; i < data.length; i++) { - uint8Array[i] = data.charCodeAt(i); - } - - PDFViewer.readPDF(uint8Array); - }; - - // Read as a binary string since "readAsArrayBuffer" is not yet - // implemented in Firefox. - fileReader.readAsBinaryString(file); - } - }; - PDFViewer.fileInput.value = null; - } else { - document.getElementById('fileWrapper').style.display = 'none'; + for (var i = 0; i < kvs.length; ++i) { + var kv = kvs[i].split('='); + params[unescape(kv[0])] = unescape(kv[1]); } - - PDFViewer.pageNumber = parseInt(PDFViewer.queryParams.page) || PDFViewer.pageNumber; - PDFViewer.scale = parseInt(PDFViewer.scaleSelect.value) / 100 || 1.0; - PDFViewer.openURL(PDFViewer.queryParams.file || PDFViewer.url); + return params; + }(); - window.onscroll = function(evt) { - var lastPagesDrawn = PDFViewer.lastPagesDrawn; - var visiblePages = PDFViewer.visiblePages(); - - var pagesToDraw = []; - var pagesToKeep = []; - var pagesToRemove = []; - - var i; - - // Determine which visible pages were not previously drawn. - for (i = 0; i < visiblePages.length; i++) { - if (lastPagesDrawn.indexOf(visiblePages[i]) === -1) { - pagesToDraw.push(visiblePages[i]); - PDFViewer.drawPage(visiblePages[i]); - } else { - pagesToKeep.push(visiblePages[i]); - } - } - - // Determine which previously drawn pages are no longer visible. - for (i = 0; i < lastPagesDrawn.length; i++) { - if (visiblePages.indexOf(lastPagesDrawn[i]) === -1) { - pagesToRemove.push(lastPagesDrawn[i]); - PDFViewer.removePage(lastPagesDrawn[i]); - } - } - - PDFViewer.lastPagesDrawn = pagesToDraw.concat(pagesToKeep); - - // Update the page number input with the current page number. - if (!PDFViewer.willJumpToPage && visiblePages.length > 0) { - PDFViewer.pageNumber = PDFViewer.pageNumberInput.value = visiblePages[0]; - PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? - 'disabled' : ''; - PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? - 'disabled' : ''; - } else { - PDFViewer.willJumpToPage = false; - } + PDFViewer.element = document.getElementById('viewer'); + + PDFViewer.pageNumberInput = document.getElementById('pageNumber'); + PDFViewer.pageNumberInput.onkeydown = function(evt) { + var charCode = evt.charCode || evt.keyCode; + + // Up arrow key. + if (charCode === 38) { + PDFViewer.goToNextPage(); + this.select(); + } + + // Down arrow key. + else if (charCode === 40) { + PDFViewer.goToPreviousPage(); + this.select(); + } + + // All other non-numeric keys (excluding Left arrow, Right arrow, + // Backspace, and Delete keys). + else if ((charCode < 48 || charCode > 57) && + charCode !== 8 && // Backspace + charCode !== 46 && // Delete + charCode !== 37 && // Left arrow + charCode !== 39 // Right arrow + ) { + return false; + } + + return true; + }; + PDFViewer.pageNumberInput.onkeyup = function(evt) { + var charCode = evt.charCode || evt.keyCode; + + // All numeric keys, Backspace, and Delete. + if ((charCode >= 48 && charCode <= 57) || + charCode === 8 || // Backspace + charCode === 46 // Delete + ) { + PDFViewer.goToPage(this.value); + } + + this.focus(); + }; + + PDFViewer.previousPageButton = document.getElementById('previousPageButton'); + PDFViewer.previousPageButton.onclick = function(evt) { + if (this.className.indexOf('disabled') === -1) { + PDFViewer.goToPreviousPage(); + } + }; + PDFViewer.previousPageButton.onmousedown = function(evt) { + if (this.className.indexOf('disabled') === -1) { + this.className = 'down'; + } + }; + PDFViewer.previousPageButton.onmouseup = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + PDFViewer.previousPageButton.onmouseout = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + + PDFViewer.nextPageButton = document.getElementById('nextPageButton'); + PDFViewer.nextPageButton.onclick = function(evt) { + if (this.className.indexOf('disabled') === -1) { + PDFViewer.goToNextPage(); + } + }; + PDFViewer.nextPageButton.onmousedown = function(evt) { + if (this.className.indexOf('disabled') === -1) { + this.className = 'down'; + } + }; + PDFViewer.nextPageButton.onmouseup = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + PDFViewer.nextPageButton.onmouseout = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + + PDFViewer.scaleSelect = document.getElementById('scaleSelect'); + PDFViewer.scaleSelect.onchange = function(evt) { + PDFViewer.changeScale(parseInt(this.value)); + }; + + if (window.File && window.FileReader && window.FileList && window.Blob) { + var openFileButton = document.getElementById('openFileButton'); + openFileButton.onclick = function(evt) { + if (this.className.indexOf('disabled') === -1) { + PDFViewer.fileInput.click(); + } }; + openFileButton.onmousedown = function(evt) { + if (this.className.indexOf('disabled') === -1) { + this.className = 'down'; + } + }; + openFileButton.onmouseup = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + openFileButton.onmouseout = function(evt) { + this.className = (this.className.indexOf('disabled') !== -1) ? 'disabled' : ''; + }; + + PDFViewer.fileInput = document.getElementById('fileInput'); + PDFViewer.fileInput.onchange = function(evt) { + var files = evt.target.files; + + if (files.length > 0) { + var file = files[0]; + var fileReader = new FileReader(); + + document.title = file.name; + + // Read the local file into a Uint8Array. + fileReader.onload = function(evt) { + var data = evt.target.result; + var buffer = new ArrayBuffer(data.length); + var uint8Array = new Uint8Array(buffer); + + for (var i = 0; i < data.length; i++) { + uint8Array[i] = data.charCodeAt(i); + } + + PDFViewer.readPDF(uint8Array); + }; + + // Read as a binary string since "readAsArrayBuffer" is not yet + // implemented in Firefox. + fileReader.readAsBinaryString(file); + } + }; + PDFViewer.fileInput.value = null; + } else { + document.getElementById('fileWrapper').style.display = 'none'; + } + + PDFViewer.pageNumber = parseInt(PDFViewer.queryParams.page) || PDFViewer.pageNumber; + PDFViewer.scale = parseInt(PDFViewer.scaleSelect.value) / 100 || 1.0; + + PDFViewer.openURL(PDFViewer.queryParams.file || PDFViewer.url); + + window.onscroll = function(evt) { + var lastPagesDrawn = PDFViewer.lastPagesDrawn; + var visiblePages = PDFViewer.visiblePages(); + + var pagesToDraw = []; + var pagesToKeep = []; + var pagesToRemove = []; + + var i; + + // Determine which visible pages were not previously drawn. + for (i = 0; i < visiblePages.length; i++) { + if (lastPagesDrawn.indexOf(visiblePages[i]) === -1) { + pagesToDraw.push(visiblePages[i]); + PDFViewer.drawPage(visiblePages[i]); + } else { + pagesToKeep.push(visiblePages[i]); + } + } + + // Determine which previously drawn pages are no longer visible. + for (i = 0; i < lastPagesDrawn.length; i++) { + if (visiblePages.indexOf(lastPagesDrawn[i]) === -1) { + pagesToRemove.push(lastPagesDrawn[i]); + PDFViewer.removePage(lastPagesDrawn[i]); + } + } + + PDFViewer.lastPagesDrawn = pagesToDraw.concat(pagesToKeep); + + // Update the page number input with the current page number. + if (!PDFViewer.willJumpToPage && visiblePages.length > 0) { + PDFViewer.pageNumber = PDFViewer.pageNumberInput.value = visiblePages[0]; + PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? 'disabled' : ''; + PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? 'disabled' : ''; + } else { + PDFViewer.willJumpToPage = false; + } + }; }; From c5b889a47baad3a581cda3861c4137a1f63f8943 Mon Sep 17 00:00:00 2001 From: Justin D'Arcangelo Date: Thu, 23 Jun 2011 21:37:40 -0400 Subject: [PATCH 6/6] Brought pdf.js back up to the latest revision. --- pdf.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pdf.js b/pdf.js index ffefc61a1..b2b6401fd 100644 --- a/pdf.js +++ b/pdf.js @@ -3275,8 +3275,11 @@ var CanvasGraphics = (function() { } } - if (bitsPerComponent !== 8) - error("Unsupported bpc"); + if (bitsPerComponent !== 8) { + TODO("Support bpc="+ bitsPerComponent); + this.restore(); + return; + } var xref = this.xref; var colorSpaces = this.colorSpaces;