diff --git a/images/buttons.png b/images/buttons.png index 682212660..3357b47d6 100644 Binary files a/images/buttons.png and b/images/buttons.png differ diff --git a/images/source/FileButton.psd.zip b/images/source/FileButton.psd.zip new file mode 100644 index 000000000..1f2b51cee Binary files /dev/null and b/images/source/FileButton.psd.zip differ diff --git a/multi-page-viewer.css b/multi-page-viewer.css index f9a7837b1..7f4701022 100644 --- a/multi-page-viewer.css +++ b/multi-page-viewer.css @@ -84,7 +84,7 @@ span { background-color: #eee; border-bottom: 1px solid #666; padding: 4px 0px 0px 8px; - position:fixed; + position: fixed; left: 0px; top: 0px; height: 40px; @@ -136,10 +136,61 @@ span { 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 index 4e15cf4f8..ffbdfe707 100644 --- a/multi-page-viewer.html +++ b/multi-page-viewer.html @@ -33,7 +33,19 @@ Zoom + + + + Open File + +
diff --git a/multi-page-viewer.js b/multi-page-viewer.js index 9d9cec702..baad7809e 100644 --- a/multi-page-viewer.js +++ b/multi-page-viewer.js @@ -12,6 +12,7 @@ var PDFViewer = { nextPageButton: null, pageNumberInput: null, scaleSelect: null, + fileInput: null, willJumpToPage: false, @@ -215,7 +216,7 @@ var PDFViewer = { } }, - open: function(url) { + openURL: function(url) { PDFViewer.url = url; document.title = url; @@ -231,26 +232,35 @@ var PDFViewer = { req.responseArrayBuffer || req.response; - 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); - } - - PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? - 'disabled' : ''; - PDFViewer.nextPageButton.className = (PDFViewer.pageNumber === PDFViewer.numberOfPages) ? - 'disabled' : ''; + 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' : ''; } }; @@ -354,11 +364,63 @@ window.onload = function() { 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.open(PDFViewer.queryParams.file || PDFViewer.url); + PDFViewer.openURL(PDFViewer.queryParams.file || PDFViewer.url); window.onscroll = function(evt) { var lastPagesDrawn = PDFViewer.lastPagesDrawn;