diff --git a/web/images/buttons.png b/web/images/buttons.png
deleted file mode 100644
index b96b9e141..000000000
Binary files a/web/images/buttons.png and /dev/null differ
diff --git a/web/images/source/Buttons.psd.zip b/web/images/source/Buttons.psd.zip
deleted file mode 100644
index 39745f540..000000000
Binary files a/web/images/source/Buttons.psd.zip and /dev/null differ
diff --git a/web/multi_page_viewer.css b/web/multi_page_viewer.css
deleted file mode 100644
index 76bf8cd1e..000000000
--- a/web/multi_page_viewer.css
+++ /dev/null
@@ -1,296 +0,0 @@
-/* -*- 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;
-}
-
-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;
- text-shadow: 0px 1px 0px #fff;
-}
-
-.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: 3px;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.3);
- -moz-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.3);
- -webkit-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.3);
-}
-
-.control > select {
- float: left;
- border: 1px solid #4d4d4d;
- height: 22px;
- padding: 2px 0px 0px;
- margin: 0px 0px 1px;
- border-radius: 3px;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.3);
- -moz-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.3);
- -webkit-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.3);
-}
-
-.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%;
-}
-
-.thumbnailPageNumber {
- color: #fff;
- font-size: 0.55em;
- text-align: right;
- margin: -6px 2px 6px 0px;
- width: 102px;
-}
-
-.thumbnail {
- width: 104px;
- height: 134px;
- margin: 0px auto 10px;
-}
-
-.page {
- width: 816px;
- height: 1056px;
- margin: 10px auto;
-}
-
-#controls {
- background-color: #eee;
- background: -moz-linear-gradient(center bottom, #ddd 0%, #fff 100%);
- background: -webkit-gradient(linear, left bottom, left top, color-stop(0.0, #ddd), color-stop(1.0, #fff));
- 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;
-}
-
-button {
- background-color: #ddd;
- background: -moz-linear-gradient(center bottom, #c3c3c3 0%, #f3f3f3 100%);
- background: -webkit-gradient(linear, left bottom, left top, color-stop(0.0, #c3c3c3), color-stop(1.0, #f3f3f3));
- border: 1px solid #4d4d4d;
- cursor: default;
- float: left;
- margin: 0px 0px 1px;
- width: 29px;
- height: 22px;
- border-radius: 3px;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
-}
-
-button:disabled {
- background-color: #eee;
- background: -moz-linear-gradient(center bottom, #ddd 0%, #fff 100%);
- background: -webkit-gradient(linear, left bottom, left top, color-stop(0.0, #ddd), color-stop(1.0, #fff));
-}
-
-button:disabled > span {
- opacity: 0.3;
- -moz-opacity: 0.3;
- -webkit-opacity: 0.3;
-}
-
-button.down {
- background-color: #777;
- background: -moz-linear-gradient(center bottom, #888 0%, #555 100%);
- background: -webkit-gradient(linear, left bottom, left top, color-stop(0.0, #888), color-stop(1.0, #555));
- box-shadow: inset 0px 0px 2px rgba(0, 0, 0, 0.8);
- -moz-box-shadow: inset 0px 0px 2px rgba(0, 0, 0, 0.8);
- -webkit-box-shadow: inset 0px 0px 2px rgba(0, 0, 0, 0.8);
-}
-
-#previousPageButton {
- width: 28px;
- border-right: 0px;
- border-top-right-radius: 0px;
- border-bottom-right-radius: 0px;
- -moz-border-radius-topright: 0px;
- -moz-border-radius-bottomright: 0px;
- -webkit-border-top-right-radius: 0px;
- -webkit-border-bottom-right-radius: 0px;
-}
-
-#previousPageButton > span {
- background: url('images/buttons.png') no-repeat 0px 0px;
- display: inline-block;
- width: 19px;
- height: 19px;
-}
-
-#nextPageButton {
- width: 28px;
- border-top-left-radius: 0px;
- border-bottom-left-radius: 0px;
- -moz-border-radius-topleft: 0px;
- -moz-border-radius-bottomleft: 0px;
- -webkit-border-top-left-radius: 0px;
- -webkit-border-bottom-left-radius: 0px;
-}
-
-#nextPageButton > span {
- background: url('images/buttons.png') no-repeat -19px 0px;
- display: inline-block;
- width: 19px;
- height: 19px;
-}
-
-#singleLayoutButton {
- width: 28px;
- border-right: 0px;
- border-top-right-radius: 0px;
- border-bottom-right-radius: 0px;
- -moz-border-radius-topright: 0px;
- -moz-border-radius-bottomright: 0px;
- -webkit-border-top-right-radius: 0px;
- -webkit-border-bottom-right-radius: 0px;
-}
-
-#singleLayoutButton > span {
- background: url('images/buttons.png') no-repeat -57px 0px;
- display: inline-block;
- width: 19px;
- height: 19px;
-}
-
-#splitLayoutButton {
- width: 28px;
- border-top-left-radius: 0px;
- border-bottom-left-radius: 0px;
- -moz-border-radius-topleft: 0px;
- -moz-border-radius-bottomleft: 0px;
- -webkit-border-top-left-radius: 0px;
- -webkit-border-bottom-left-radius: 0px;
-}
-
-#splitLayoutButton > span {
- background: url('images/buttons.png') no-repeat -76px 0px;
- display: inline-block;
- width: 19px;
- height: 19px;
-}
-
-#openFileButton {
- margin-left: 3px;
-}
-
-#openFileButton > span {
- background: url('images/buttons.png') no-repeat -38px 0px;
- display: inline-block;
- width: 19px;
- height: 19px;
-}
-
-#fileInput {
- display: none;
-}
-
-#pageNumber {
- text-align: right;
-}
-
-#sidebar {
- position: fixed;
- width: 200px;
- top: 62px;
- bottom: 18px;
- left: -140px;
- transition: left 0.25s ease-in-out 1s;
- -moz-transition: left 0.25s ease-in-out 1s;
- -webkit-transition: left 0.25s ease-in-out 1s;
-}
-
-#sidebar:hover {
- left: 0px;
- transition: left 0.25s ease-in-out 0s;
- -moz-transition: left 0.25s ease-in-out 0s;
- -webkit-transition: left 0.25s ease-in-out 0s;
-}
-
-#sidebarBox {
- background-color: rgba(0, 0, 0, 0.7);
- width: 150px;
- height: 100%;
- 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;
- box-shadow: 0px 2px 8px #000;
- -moz-box-shadow: 0px 2px 8px #000;
- -webkit-box-shadow: 0px 2px 8px #000;
-}
-
-#sidebarScrollView {
- position: absolute;
- overflow: hidden;
- overflow-y: auto;
- top: 10px;
- bottom: 10px;
- left: 10px;
- width: 130px;
-}
-
-#sidebarContentView {
- height: auto;
- width: 100px;
-}
-
-#viewer {
- margin: 44px 0px 0px;
- padding: 8px 0px;
-}
diff --git a/web/multi_page_viewer.html b/web/multi_page_viewer.html
deleted file mode 100644
index 00dac6484..000000000
--- a/web/multi_page_viewer.html
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-pdf.js Multi-Page Viewer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Previous/Next
-
-
-
- /
- --
- Page Number
-
-
-
- Zoom
-
-
-
-
-
-
-
-
- Open File
-
-
-
-
-
-
-
-
-
diff --git a/web/multi_page_viewer.js b/web/multi_page_viewer.js
deleted file mode 100644
index 856b672e1..000000000
--- a/web/multi_page_viewer.js
+++ /dev/null
@@ -1,519 +0,0 @@
-/* -*- 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 pageTimeout;
-
-var PDFViewer = {
- queryParams: {},
-
- element: null,
-
- sidebarContentView: 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(page) {
- var pdfToCssUnitsCoef = 96.0 / 72.0;
- var width = (page.mediaBox[2] - page.mediaBox[0]);
- return width * PDFViewer.scale * pdfToCssUnitsCoef;
- },
-
- pageHeight: function(page) {
- var pdfToCssUnitsCoef = 96.0 / 72.0;
- var height = (page.mediaBox[3] - page.mediaBox[1]);
- return height * PDFViewer.scale * pdfToCssUnitsCoef;
- },
-
- lastPagesDrawn: [],
-
- visiblePages: function() {
- var pageBottomMargin = 10;
- var windowTop = window.pageYOffset;
- var windowBottom = window.pageYOffset + window.innerHeight;
-
- var pageHeight, page;
- var i, n = PDFViewer.numberOfPages, currentHeight = pageBottomMargin;
- for (i = 1; i <= n; i++) {
- var page = PDFViewer.pdf.getPage(i);
- pageHeight = PDFViewer.pageHeight(page) + pageBottomMargin;
- if (currentHeight + pageHeight > windowTop)
- break;
- currentHeight += pageHeight;
- }
-
- var pages = [];
- for (; i <= n && currentHeight < windowBottom; i++) {
- var page = PDFViewer.pdf.getPage(i);
- pageHeight = PDFViewer.pageHeight(page) + pageBottomMargin;
- currentHeight += pageHeight;
- pages.push(i);
- }
-
- return pages;
- },
-
- createThumbnail: function(num) {
- if (PDFViewer.sidebarContentView) {
- var anchor = document.createElement('a');
- anchor.href = '#' + num;
-
- var containerDiv = document.createElement('div');
- containerDiv.id = 'thumbnailContainer' + num;
- containerDiv.className = 'thumbnail';
-
- var pageNumberDiv = document.createElement('div');
- pageNumberDiv.className = 'thumbnailPageNumber';
- pageNumberDiv.innerHTML = '' + num;
-
- anchor.appendChild(containerDiv);
- PDFViewer.sidebarContentView.appendChild(anchor);
- PDFViewer.sidebarContentView.appendChild(pageNumberDiv);
- }
- },
-
- removeThumbnail: function(num) {
- var div = document.getElementById('thumbnailContainer' + num);
-
- if (div) {
- while (div.hasChildNodes()) {
- div.removeChild(div.firstChild);
- }
- }
- },
-
- drawThumbnail: function(num) {
- if (!PDFViewer.pdf)
- return;
-
- var div = document.getElementById('thumbnailContainer' + num);
-
- if (div && !div.hasChildNodes()) {
- var page = PDFViewer.pdf.getPage(num);
- var canvas = document.createElement('canvas');
-
- canvas.id = 'thumbnail' + num;
- canvas.mozOpaque = true;
-
- var pageWidth = PDFViewer.pageWidth(page);
- var pageHeight = PDFViewer.pageHeight(page);
- var thumbScale = Math.min(104 / pageWidth, 134 / pageHeight);
- canvas.width = pageWidth * thumbScale;
- canvas.height = pageHeight * thumbScale;
- div.appendChild(canvas);
-
- var ctx = canvas.getContext('2d');
- ctx.save();
- ctx.fillStyle = 'rgb(255, 255, 255)';
- ctx.fillRect(0, 0, canvas.width, canvas.height);
- ctx.restore();
-
- page.startRendering(ctx, function() { });
- }
- },
-
- createPage: function(num) {
- var page = PDFViewer.pdf.getPage(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(page) + 'px';
- div.style.height = PDFViewer.pageHeight(page) + '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);
-
- if (div && !div.hasChildNodes()) {
- var page = PDFViewer.pdf.getPage(num);
- var canvas = document.createElement('canvas');
-
- canvas.id = 'page' + num;
- canvas.mozOpaque = true;
-
- canvas.width = PDFViewer.pageWidth(page);
- canvas.height = PDFViewer.pageHeight(page);
- div.appendChild(canvas);
-
- var ctx = canvas.getContext('2d');
- ctx.save();
- ctx.fillStyle = 'rgb(255, 255, 255)';
- ctx.fillRect(0, 0, canvas.width, canvas.height);
- ctx.restore();
-
- page.startRendering(ctx, function() { });
- }
- },
-
- 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);
- }
- }
-
- 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) + '%';
-
- // Clear the array of the last pages drawn to force a redraw.
- PDFViewer.lastPagesDrawn = [];
-
- // Jump the scroll position to the correct page.
- PDFViewer.goToPage(PDFViewer.pageNumber);
- },
-
- goToPage: function(num) {
- if (1 <= num && num <= PDFViewer.numberOfPages) {
- PDFViewer.pageNumber = num;
- PDFViewer.pageNumberInput.value = PDFViewer.pageNumber;
- PDFViewer.willJumpToPage = true;
-
- if (document.location.hash.substr(1) == PDFViewer.pageNumber)
- // Force a "scroll event" to redraw
- setTimeout(window.onscroll, 0);
- document.location.hash = PDFViewer.pageNumber;
-
- PDFViewer.previousPageButton.disabled = (PDFViewer.pageNumber === 1);
- PDFViewer.nextPageButton.disabled = (PDFViewer.pageNumber === PDFViewer.numberOfPages);
- }
- },
-
- 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;
- if (url.indexOf("http") == 0)
- return;
-
- if (this.thumbsLoadingInterval) {
- // cancel thumbs loading operations
- clearInterval(this.thumbsLoadingInterval);
- this.thumbsLoadingInterval = null;
- }
-
- 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);
- },
-
- thumbsLoadingInterval: null,
-
- readPDF: function(data) {
- while (PDFViewer.element.hasChildNodes()) {
- PDFViewer.element.removeChild(PDFViewer.element.firstChild);
- }
-
- while (PDFViewer.sidebarContentView.hasChildNodes()) {
- PDFViewer.sidebarContentView.removeChild(
- PDFViewer.sidebarContentView.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;
-
- // slowly loading the thumbs (few per second)
- // first time we are loading more images than subsequent
- var currentPageIndex = 1, imagesToLoad = 15;
- this.thumbsLoadingInterval = setInterval((function() {
- while (imagesToLoad-- > 0) {
- if (currentPageIndex > PDFViewer.numberOfPages) {
- clearInterval(this.thumbsLoadingInterval);
- this.thumbsLoadingInterval = null;
- return;
- }
- PDFViewer.createThumbnail(currentPageIndex);
- PDFViewer.drawThumbnail(currentPageIndex);
- ++currentPageIndex;
- }
- imagesToLoad = 3; // next time loading less images
- }).bind(this), 500);
- }
-
- PDFViewer.previousPageButton.disabled = (PDFViewer.pageNumber === 1);
- PDFViewer.nextPageButton.disabled = (PDFViewer.pageNumber === PDFViewer.numberOfPages);
- }
-};
-
-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.sidebarContentView = document.getElementById('sidebarContentView');
-
- 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) {
- PDFViewer.goToPreviousPage();
- };
- PDFViewer.previousPageButton.onmousedown = function(evt) {
- this.className = 'down';
- };
- PDFViewer.previousPageButton.onmouseup = function(evt) {
- this.className = '';
- };
- PDFViewer.previousPageButton.onmouseout = function(evt) {
- this.className = '';
- };
-
- PDFViewer.nextPageButton = document.getElementById('nextPageButton');
- PDFViewer.nextPageButton.onclick = function(evt) {
- PDFViewer.goToNextPage();
- };
- PDFViewer.nextPageButton.onmousedown = function(evt) {
- this.className = 'down';
- };
- PDFViewer.nextPageButton.onmouseup = function(evt) {
- this.className = '';
- };
- PDFViewer.nextPageButton.onmouseout = function(evt) {
- this.className = '';
- };
-
- 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) {
- PDFViewer.fileInput.click();
- };
- openFileButton.onmousedown = function(evt) {
- this.className = 'down';
- };
- openFileButton.onmouseup = function(evt) {
- this.className = '';
- };
- openFileButton.onmouseout = function(evt) {
- this.className = '';
- };
-
- 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.disabled = (PDFViewer.pageNumber === 1);
- PDFViewer.nextPageButton.disabled = (PDFViewer.pageNumber === PDFViewer.numberOfPages);
- } else {
- PDFViewer.willJumpToPage = false;
- }
- };
-};
-
-window.addEventListener('pdfloaded', function(evt) {
- PDFViewer.readPDF(evt.detail);
-}, true);
diff --git a/web/viewer.css b/web/viewer.css
index 9987492dc..54f648adb 100644
--- a/web/viewer.css
+++ b/web/viewer.css
@@ -2,35 +2,129 @@
/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
body {
- margin: 6px;
- padding: 0px;
- background-color: #c0bdb7;
+ background-color: #929292;
+ font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, Verdana, sans-serif;
+ margin: 0px;
+ padding: 0px;
}
+/* === Toolbar === */
#controls {
- position:fixed;
- left: 0px;
- top: 0px;
- width: 100%;
- padding: 7px;
- border-bottom: 1px solid black;
- background-color: rgb(242, 240, 238);
+ background-color: #eee;
+ background: -moz-linear-gradient(center bottom, #eee 0%, #fff 100%);
+ background: -webkit-gradient(linear, left bottom, left top, color-stop(0.0, #ddd), color-stop(1.0, #fff));
+ border-bottom: 1px solid #666;
+ padding: 4px;
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ height: 40px;
+ width: 100%;
}
-span#info {
- float: right;
- font: 14px sans-serif;
- margin-right: 10px;
+.separator {
+ display: inline;
+ border-left: 1px solid #d3d3d3;
+ border-right: 1px solid #fff;
+ height: 32px;
+ width:0px;
+ margin: 4px;
}
-#viewer {
+#controls > button {
+ line-height: 32px;
}
-#canvas {
- margin: auto;
- display: block;
+#controls > button[disabled] > img {
+ opacity: 0.5;
}
#pageNumber {
- text-align: right;
+ text-align: right;
}
+
+#fileInput {
+ line-height: 32px;
+}
+
+span#info {
+ display: none;
+}
+
+@-moz-document regexp("http:.*debug=1.*") {
+ span#info {
+ display: inline-block;
+ }
+}
+
+/* === Sidebar === */
+#sidebar {
+ position: fixed;
+ width: 200px;
+ top: 62px;
+ bottom: 18px;
+ left: -140px;
+ transition: left 0.25s ease-in-out 1s;
+ -moz-transition: left 0.25s ease-in-out 1s;
+ -webkit-transition: left 0.25s ease-in-out 1s;
+}
+
+#sidebar:hover {
+ left: 0px;
+ transition: left 0.25s ease-in-out 0s;
+ -moz-transition: left 0.25s ease-in-out 0s;
+ -webkit-transition: left 0.25s ease-in-out 0s;
+}
+
+#sidebarBox {
+ background-color: rgba(0, 0, 0, 0.7);
+ width: 150px;
+ height: 100%;
+ 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;
+ box-shadow: 0px 2px 8px #000;
+ -moz-box-shadow: 0px 2px 8px #000;
+ -webkit-box-shadow: 0px 2px 8px #000;
+}
+
+#sidebarScrollView {
+ position: absolute;
+ overflow: hidden;
+ overflow-y: auto;
+ top: 10px;
+ bottom: 10px;
+ left: 10px;
+ width: 130px;
+}
+
+.thumbnail {
+ width: 104px;
+ height: 134px;
+ background-color: white;
+ margin: 5px;
+}
+
+/* === Content view === */
+canvas {
+ margin: auto;
+ display: block;
+ box-shadow: 0px 4px 10px #000;
+ -moz-box-shadow: 0px 4px 10px #000;
+ -webkit-box-shadow: 0px 4px 10px #000;
+}
+
+.page {
+ width: 816px;
+ height: 1056px;
+ margin: 10px auto;
+}
+
+#viewer {
+ margin: 44px 0px 0px;
+ padding: 8px 0px;
+}
+
diff --git a/web/viewer.html b/web/viewer.html
index df9604db4..285dadb01 100644
--- a/web/viewer.html
+++ b/web/viewer.html
@@ -12,22 +12,54 @@
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
/
--
-
+
+
+
+
+
+
+
+
+
+
+
+
--
-
-
+
+
+
diff --git a/web/viewer.js b/web/viewer.js
index 12a42006f..8f245028e 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -3,108 +3,298 @@
'use strict';
-var pdfDocument, canvas, pageScale, pageDisplay, pageNum, numPages;
-function load(userInput) {
- canvas = document.getElementById('canvas');
- canvas.mozOpaque = true;
- pageNum = ('page' in queryParams()) ? parseInt(queryParams().page) : 1;
- pageScale = ('scale' in queryParams()) ? parseInt(queryParams().scale) : 1.5;
- var fileName = userInput;
- if (!userInput) {
- fileName = queryParams().file || 'compressed.tracemonkey-pldi-09.pdf';
- }
- open(fileName);
-}
+var kDefaultURL = 'compressed.tracemonkey-pldi-09.pdf';
+var kDefaultScale = 150;
-function queryParams() {
- 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;
-}
+var PDFView = {
+ pages: [],
+ thumbnails: [],
-function open(url) {
- document.title = url;
- if (url.indexOf("http") == 0)
- return;
-
- 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);
- loadDocument(data);
+ set scale(val) {
+ var options = document.getElementById('scaleSelect').options;
+ for (var i = 0; i < options.length; i++) {
+ var option = options[i];
+ option.selected = (option.value == val);
}
- };
- req.send(null);
-}
-window.addEventListener("pdfloaded", function(aEvent) {
- loadDocument(aEvent.detail);
+ var pages = this.pages;
+ var cssUnits = 96.0 / 72.0;
+ for (var i = 0; i < pages.length; i++)
+ pages[i].update(val / 100 * cssUnits);
+
+ // Jump the scroll position to the correct page.
+ this.page = this.page;
+ },
+
+ set page(val) {
+ var pages = this.pages;
+ var input = document.getElementById("pageNumber");
+ if (val <= 0 || val > pages.length) {
+ input.value = this.page;
+ return;
+ }
+
+ document.location.hash = val;
+ document.getElementById("previous").disabled = (val == 1);
+ document.getElementById("next").disabled = (val == pages.length);
+ if (input.value == val)
+ return;
+
+ input.value = val;
+ pages[val - 1].draw();
+ },
+
+ get page() {
+ return parseInt(document.location.hash.substring(1)) || 1;
+ },
+
+ open: function(url, scale) {
+ if (url.indexOf("http") == 0)
+ return;
+
+ document.title = url;
+
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', url);
+ xhr.mozResponseType = xhr.responseType = 'arraybuffer';
+ xhr.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200;
+
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState === 4 && xhr.status === xhr.expected) {
+ var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse ||
+ xhr.responseArrayBuffer || xhr.response);
+
+ PDFView.load(data, scale);
+ }
+ };
+
+ xhr.send(null);
+ },
+
+ load: function(data, scale) {
+ var sidebar = document.getElementById('sidebarView');
+ sidebar.parentNode.scrollTop = 0;
+
+ while (sidebar.hasChildNodes())
+ sidebar.removeChild(sidebar.lastChild);
+ clearInterval(sidebar._loadingInterval);
+
+ var container = document.getElementById('viewer');
+ while (container.hasChildNodes())
+ container.removeChild(container.lastChild);
+
+ var pdf = new PDFDoc(new Stream(data));
+ var pagesCount = pdf.numPages;
+ document.getElementById('numPages').innerHTML = pagesCount;
+
+ var pages = this.pages = [];
+ var thumbnails = this.thumbnails = [];
+ for (var i = 1; i <= pagesCount; i++) {
+ var page = pdf.getPage(i);
+ var mediaBox = page.mediaBox;
+ var width = (mediaBox[2] - mediaBox[0]);
+ var height = (mediaBox[3] - mediaBox[1]);
+ pages.push(new PageView(container, page, i, width, height, page.stats));
+ thumbnails.push(new ThumbnailView(sidebar, pages[i - 1]));
+ };
+
+ this.scale = (scale || kDefaultScale);
+ this.page = parseInt(document.location.hash.substring(1)) || 1;
+ },
+
+ getVisiblePages: function() {
+ var pages = this.pages;
+ var kBottomMargin = 10;
+ var visiblePages = [];
+
+ var currentHeight = kBottomMargin;
+ var windowTop = window.pageYOffset;
+ for (var i = 1; i <= pages.length; i++) {
+ var page = pages[i - 1];
+ var pageHeight = page.height * page.scale + kBottomMargin;
+ if (currentHeight + pageHeight > windowTop)
+ break;
+
+ currentHeight += pageHeight;
+ }
+
+ var windowBottom = window.pageYOffset + window.innerHeight;
+ for (; i <= pages.length && currentHeight < windowBottom; i++) {
+ var page = pages[i - 1];
+ visiblePages.push({ id: page.id, y: currentHeight });
+ currentHeight += page.height * page.scale + kBottomMargin;
+ }
+
+ return visiblePages;
+ },
+};
+
+var PageView = function(container, content, id, width, height, stats) {
+ this.width = width;
+ this.height = height;
+ this.id = id;
+ this.content = content;
+
+ var anchor = document.createElement('a');
+ anchor.name = '' + this.id;
+
+ var div = document.createElement('div');
+ div.id = 'pageContainer' + this.id;
+ div.className = 'page';
+
+ container.appendChild(anchor);
+ container.appendChild(div);
+
+ this.update = function(scale) {
+ this.scale = scale;
+ div.style.width = (this.width * this.scale)+ 'px';
+ div.style.height = (this.height * this.scale) + 'px';
+
+ while (div.hasChildNodes())
+ div.removeChild(div.lastChild);
+ };
+
+ this.draw = function() {
+ if (div.hasChildNodes()) {
+ this.updateStats();
+ return;
+ }
+
+ var canvas = document.createElement('canvas');
+ canvas.id = 'page' + this.id;
+ canvas.mozOpaque = true;
+
+ canvas.width = this.width * this.scale;
+ canvas.height = this.height * this.scale;
+ div.appendChild(canvas);
+
+ var ctx = canvas.getContext('2d');
+ ctx.save();
+ ctx.fillStyle = 'rgb(255, 255, 255)';
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ ctx.restore();
+
+ stats.begin = Date.now();
+ this.content.startRendering(ctx, this.updateStats);
+ };
+
+ this.updateStats = function() {
+ var t1 = stats.compile, t2 = stats.fonts, t3 = stats.render;
+ var str = 'Time to compile/fonts/render: ' +
+ (t1 - stats.begin) + '/' + (t2 - t1) + '/' + (t3 - t2) + ' ms';
+ document.getElementById('info').innerHTML = str;
+ };
+};
+
+var ThumbnailView = function(container, page) {
+ var anchor = document.createElement('a');
+ anchor.href = '#' + page.id;
+
+ var div = document.createElement('div');
+ div.id = 'thumbnailContainer' + page.id;
+ div.className = 'thumbnail';
+
+ anchor.appendChild(div);
+ container.appendChild(anchor);
+
+ this.draw = function() {
+ if (div.hasChildNodes())
+ return;
+
+ var canvas = document.createElement('canvas');
+ canvas.id = 'thumbnail' + page.id;
+ canvas.mozOpaque = true;
+
+ canvas.width = 104;
+ canvas.height = 134;
+ div.appendChild(canvas);
+
+ var ctx = canvas.getContext('2d');
+ ctx.save();
+ ctx.fillStyle = 'rgb(255, 255, 255)';
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ ctx.restore();
+
+ page.content.startRendering(ctx, function() { });
+ };
+};
+
+window.addEventListener('load', function(evt) {
+ var params = document.location.search.substring(1).split('&');
+ for (var i = 0; i < params.length; i++) {
+ var param = params[i].split('=');
+ params[unescape(param[0])] = unescape(param[1]);
+ }
+
+ PDFView.open(params.file || kDefaultURL, parseInt(params.scale));
+
+ if (!window.File || !window.FileReader || !window.FileList || !window.Blob)
+ document.getElementById('fileInput').style.display = 'none';
+ else
+ document.getElementById('fileInput').value = null;
}, true);
-function loadDocument(data) {
- pdfDocument = new PDFDoc(new Stream(data));
- numPages = pdfDocument.numPages;
- document.getElementById('numPages').innerHTML = numPages.toString();
- goToPage(pageNum);
-}
+window.addEventListener('pdfloaded', function(evt) {
+ PDFView.load(evt.detail);
+}, true);
-function gotoPage(num) {
- if (0 <= num && num <= numPages)
- pageNum = num;
- displayPage(pageNum);
-}
+window.addEventListener('scroll', function(evt) {
+ var visiblePages = PDFView.getVisiblePages();
+ for (var i = 0; i < visiblePages.length; i++)
+ PDFView.pages[visiblePages[i].id - 1].draw();
-function displayPage(num) {
- document.getElementById('pageNumber').value = num;
+ if (!visiblePages.length)
+ return;
- var t0 = Date.now();
+ var currentId = PDFView.page;
+ var firstPage = visiblePages[0];
+ var lastPage = visiblePages[visiblePages.length - 1];
+ if (currentId > lastPage.id && lastPage.y > window.pageYOffset)
+ PDFView.page = lastPage.id;
+ else if (currentId < firstPage.id)
+ PDFView.page = firstPage.id;
+}, true);
- var page = pdfDocument.getPage(pageNum = num);
+window.addEventListener("hashchange", function(evt) {
+ PDFView.page = PDFView.page;
+});
- var pdfToCssUnitsCoef = 96.0 / 72.0;
- var pageWidth = (page.mediaBox[2] - page.mediaBox[0]);
- var pageHeight = (page.mediaBox[3] - page.mediaBox[1]);
- canvas.width = pageScale * pageWidth * pdfToCssUnitsCoef;
- canvas.height = pageScale * pageHeight * pdfToCssUnitsCoef;
+window.addEventListener("change", function(evt) {
+ var files = evt.target.files;
+ if (!files || files.length == 0)
+ return;
- var t1 = Date.now();
- var ctx = canvas.getContext('2d');
- ctx.save();
- ctx.fillStyle = 'rgb(255, 255, 255)';
- ctx.fillRect(0, 0, canvas.width, canvas.height);
- ctx.restore();
+ // Read the local file into a Uint8Array.
+ var fileReader = new FileReader();
+ fileReader.onload = function(evt) {
+ var data = evt.target.result;
+ var buffer = new ArrayBuffer(data.length);
+ var uint8Array = new Uint8Array(buffer);
- page.startRendering(
- ctx,
- function() {
- var infoDisplay = document.getElementById('info');
- var stats = page.stats;
- var t2 = stats.compile, t3 = stats.fonts, t4 = stats.render;
- infoDisplay.innerHTML = 'Time to load/compile/fonts/render: ' +
- (t1 - t0) + '/' + (t2 - t1) + '/' + (t3 - t2) + '/' + (t4 - t3) + ' ms';
- });
-}
+ for (var i = 0; i < data.length; i++)
+ uint8Array[i] = data.charCodeAt(i);
+ PDFView.load(uint8Array);
+ };
-function nextPage() {
- if (pageNum < pdfDocument.numPages)
- displayPage(++pageNum);
-}
+ // Read as a binary string since "readAsArrayBuffer" is not yet
+ // implemented in Firefox.
+ var file = files[0];
+ fileReader.readAsBinaryString(file);
-function prevPage() {
- if (pageNum > 1)
- displayPage(--pageNum);
-}
+ document.title = file.name;
+ document.location.hash = 1;
+}, true);
+
+window.addEventListener("transitionend", function(evt) {
+ var pageIndex = 0;
+ var pagesCount = PDFView.pages.length;
+
+ var container = document.getElementById('sidebarView');
+ container._interval = window.setInterval(function() {
+ if (pageIndex >= pagesCount)
+ return window.clearInterval(container._interval);
+
+ PDFView.thumbnails[pageIndex++].draw();
+ }, 500);
+}, true);
-function goToPage(num) {
- if (0 <= num && num <= numPages)
- displayPage(pageNum = num);
-}