diff options
Diffstat (limited to 'apps/files_pdfviewer/js/pdfjs/viewer.js')
-rw-r--r-- | apps/files_pdfviewer/js/pdfjs/viewer.js | 1873 |
1 files changed, 0 insertions, 1873 deletions
diff --git a/apps/files_pdfviewer/js/pdfjs/viewer.js b/apps/files_pdfviewer/js/pdfjs/viewer.js deleted file mode 100644 index 90dd1eef020..00000000000 --- a/apps/files_pdfviewer/js/pdfjs/viewer.js +++ /dev/null @@ -1,1873 +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 kDefaultURL = 'compressed.tracemonkey-pldi-09.pdf'; -var kDefaultScale = 'auto'; -var kDefaultScaleDelta = 1.1; -var kUnknownScale = 0; -var kCacheSize = 20; -var kCssUnits = 96.0 / 72.0; -var kScrollbarPadding = 40; -var kMinScale = 0.25; -var kMaxScale = 4.0; -var kImageDirectory = './images/'; -var kSettingsMemory = 20; - -var mozL10n = document.mozL10n || document.webL10n; - -function getFileName(url) { - var anchor = url.indexOf('#'); - var query = url.indexOf('?'); - var end = Math.min( - anchor > 0 ? anchor : url.length, - query > 0 ? query : url.length); - return url.substring(url.lastIndexOf('/', end) + 1, end); -} - -var Cache = function cacheCache(size) { - var data = []; - this.push = function cachePush(view) { - var i = data.indexOf(view); - if (i >= 0) - data.splice(i); - data.push(view); - if (data.length > size) - data.shift().destroy(); - }; -}; - -var ProgressBar = (function ProgressBarClosure() { - - function clamp(v, min, max) { - return Math.min(Math.max(v, min), max); - } - - function ProgressBar(id, opts) { - - // Fetch the sub-elements for later - this.div = document.querySelector(id + ' .progress'); - - // Get options, with sensible defaults - this.height = opts.height || 100; - this.width = opts.width || 100; - this.units = opts.units || '%'; - this.percent = opts.percent || 0; - - // Initialize heights - this.div.style.height = this.height + this.units; - } - - ProgressBar.prototype = { - - updateBar: function ProgressBar_updateBar() { - var progressSize = this.width * this._percent / 100; - - if (this._percent > 95) - this.div.classList.add('full'); - - this.div.style.width = progressSize + this.units; - }, - - get percent() { - return this._percent; - }, - - set percent(val) { - this._percent = clamp(val, 0, 100); - this.updateBar(); - } - }; - - return ProgressBar; -})(); - -var RenderingQueue = (function RenderingQueueClosure() { - function RenderingQueue() { - this.items = []; - } - - RenderingQueue.prototype = { - enqueueDraw: function RenderingQueueEnqueueDraw(item) { - if (!item.drawingRequired()) - return; // as no redraw required, no need for queueing. - - this.items.push(item); - if (this.items.length > 1) - return; // not first item - - item.draw(this.continueExecution.bind(this)); - }, - continueExecution: function RenderingQueueContinueExecution() { - var item = this.items.shift(); - - if (this.items.length == 0) - return; // queue is empty - - item = this.items[0]; - item.draw(this.continueExecution.bind(this)); - } - }; - - return RenderingQueue; -})(); - -var FirefoxCom = (function FirefoxComClosure() { - return { - /** - * Creates an event that the extension is listening for and will - * synchronously respond to. - * NOTE: It is reccomended to use request() instead since one day we may not - * be able to synchronously reply. - * @param {String} action The action to trigger. - * @param {String} data Optional data to send. - * @return {*} The response. - */ - requestSync: function(action, data) { - var request = document.createTextNode(''); - request.setUserData('action', action, null); - request.setUserData('data', data, null); - request.setUserData('sync', true, null); - document.documentElement.appendChild(request); - - var sender = document.createEvent('Events'); - sender.initEvent('pdf.js.message', true, false); - request.dispatchEvent(sender); - var response = request.getUserData('response'); - document.documentElement.removeChild(request); - return response; - }, - /** - * Creates an event that the extension is listening for and will - * asynchronously respond by calling the callback. - * @param {String} action The action to trigger. - * @param {String} data Optional data to send. - * @param {Function} callback Optional response callback that will be called - * with one data argument. - */ - request: function(action, data, callback) { - var request = document.createTextNode(''); - request.setUserData('action', action, null); - request.setUserData('data', data, null); - request.setUserData('sync', false, null); - if (callback) { - request.setUserData('callback', callback, null); - - document.addEventListener('pdf.js.response', function listener(event) { - var node = event.target, - callback = node.getUserData('callback'), - response = node.getUserData('response'); - - document.documentElement.removeChild(node); - - document.removeEventListener('pdf.js.response', listener, false); - return callback(response); - }, false); - } - document.documentElement.appendChild(request); - - var sender = document.createEvent('HTMLEvents'); - sender.initEvent('pdf.js.message', true, false); - return request.dispatchEvent(sender); - } - }; -})(); - -// Settings Manager - This is a utility for saving settings -// First we see if localStorage is available -// If not, we use FUEL in FF -var Settings = (function SettingsClosure() { - var isLocalStorageEnabled = (function localStorageEnabledTest() { - // Feature test as per http://diveintohtml5.info/storage.html - // The additional localStorage call is to get around a FF quirk, see - // bug #495747 in bugzilla - try { - return 'localStorage' in window && window['localStorage'] !== null && - localStorage; - } catch (e) { - return false; - } - })(); - - var isFirefoxExtension = PDFJS.isFirefoxExtension; - - function Settings(fingerprint) { - var database = null; - var index; - if (isFirefoxExtension) - database = FirefoxCom.requestSync('getDatabase', null) || '{}'; - else if (isLocalStorageEnabled) - database = localStorage.getItem('database') || '{}'; - else - return false; - - database = JSON.parse(database); - if (!('files' in database)) - database.files = []; - if (database.files.length >= kSettingsMemory) - database.files.shift(); - for (var i = 0, length = database.files.length; i < length; i++) { - var branch = database.files[i]; - if (branch.fingerprint == fingerprint) { - index = i; - break; - } - } - if (typeof index != 'number') - index = database.files.push({fingerprint: fingerprint}) - 1; - this.file = database.files[index]; - this.database = database; - } - - Settings.prototype = { - set: function settingsSet(name, val) { - if (!('file' in this)) - return false; - - var file = this.file; - file[name] = val; - var database = JSON.stringify(this.database); - if (isFirefoxExtension) - FirefoxCom.requestSync('setDatabase', database); - else if (isLocalStorageEnabled) - localStorage.setItem('database', database); - }, - - get: function settingsGet(name, defaultValue) { - if (!('file' in this)) - return defaultValue; - - return this.file[name] || defaultValue; - } - }; - - return Settings; -})(); - -var cache = new Cache(kCacheSize); -var renderingQueue = new RenderingQueue(); -var currentPageNumber = 1; - -var PDFView = { - pages: [], - thumbnails: [], - currentScale: kUnknownScale, - currentScaleValue: null, - initialBookmark: document.location.hash.substring(1), - startedTextExtraction: false, - pageText: [], - container: null, - initialized: false, - fellback: false, - pdfDocument: null, - // called once when the document is loaded - initialize: function pdfViewInitialize() { - this.container = document.getElementById('viewer'); - this.initialized = true; - }, - - setScale: function pdfViewSetScale(val, resetAutoSettings) { - if (val == this.currentScale) - return; - - var pages = this.pages; - for (var i = 0; i < pages.length; i++) - pages[i].update(val * kCssUnits); - - if (this.currentScale != val) - this.pages[this.page - 1].scrollIntoView(); - this.currentScale = val; - - var event = document.createEvent('UIEvents'); - event.initUIEvent('scalechange', false, false, window, 0); - event.scale = val; - event.resetAutoSettings = resetAutoSettings; - window.dispatchEvent(event); - }, - - parseScale: function pdfViewParseScale(value, resetAutoSettings) { - if ('custom' == value) - return; - - var scale = parseFloat(value); - this.currentScaleValue = value; - if (scale) { - this.setScale(scale, true); - return; - } - - var container = this.container; - var currentPage = this.pages[this.page - 1]; - var pageWidthScale = (container.clientWidth - kScrollbarPadding) / - currentPage.width * currentPage.scale / kCssUnits; - var pageHeightScale = (container.clientHeight - kScrollbarPadding) / - currentPage.height * currentPage.scale / kCssUnits; - switch (value) { - case 'page-actual': - this.setScale(1, resetAutoSettings); - break; - case 'page-width': - this.setScale(pageWidthScale, resetAutoSettings); - break; - case 'page-height': - this.setScale(pageHeightScale, resetAutoSettings); - break; - case 'page-fit': - this.setScale( - Math.min(pageWidthScale, pageHeightScale), resetAutoSettings); - break; - case 'auto': - this.setScale(Math.min(1.0, pageWidthScale), resetAutoSettings); - break; - } - - selectScaleOption(value); - }, - - zoomIn: function pdfViewZoomIn() { - var newScale = (this.currentScale * kDefaultScaleDelta).toFixed(2); - newScale = Math.min(kMaxScale, newScale); - this.parseScale(newScale, true); - }, - - zoomOut: function pdfViewZoomOut() { - var newScale = (this.currentScale / kDefaultScaleDelta).toFixed(2); - newScale = Math.max(kMinScale, newScale); - this.parseScale(newScale, true); - }, - - set page(val) { - var pages = this.pages; - var input = document.getElementById('pageNumber'); - if (!(0 < val && val <= pages.length)) { - var event = document.createEvent('UIEvents'); - event.initUIEvent('pagechange', false, false, window, 0); - event.pageNumber = this.page; - window.dispatchEvent(event); - return; - } - - pages[val - 1].updateStats(); - currentPageNumber = val; - var event = document.createEvent('UIEvents'); - event.initUIEvent('pagechange', false, false, window, 0); - event.pageNumber = val; - window.dispatchEvent(event); - - // checking if the this.page was called from the updateViewarea function: - // avoiding the creation of two "set page" method (internal and public) - if (updateViewarea.inProgress) - return; - - // Avoid scrolling the first page during loading - if (this.loading && val == 1) - return; - - pages[val - 1].scrollIntoView(); - }, - - get page() { - return currentPageNumber; - }, - - open: function pdfViewOpen(url, scale, password) { - var parameters = {password: password}; - if (typeof url === 'string') { // URL - this.url = url; - document.title = decodeURIComponent(getFileName(url)) || url; - parameters.url = url; - } else if (url && 'byteLength' in url) { // ArrayBuffer - parameters.data = url; - } - -// if (!PDFView.loadingBar) { -// PDFView.loadingBar = new ProgressBar('#loadingBar', {}); -// } - - this.container = document.getElementById('viewer'); - - this.pdfDocument = null; - var self = this; - self.loading = true; - PDFJS.getDocument(parameters).then( - function getDocumentCallback(pdfDocument) { - self.load(pdfDocument, scale); - self.loading = false; - }, - function getDocumentError(message, exception) { - if (exception.name === 'PasswordException') { - if (exception.code === 'needpassword') { - var promptString = mozL10n.get('request_password', null, - 'PDF is protected by a password:'); - password = prompt(promptString); - if (password && password.length > 0) { - return PDFView.open(url, scale, password); - } - } - } - - var loadingIndicator = document.getElementById('loading'); - loadingIndicator.textContent = mozL10n.get('loading_error_indicator', - null, 'Error'); - var moreInfo = { - message: message - }; - self.error(mozL10n.get('loading_error', null, - 'An error occurred while loading the PDF.'), moreInfo); - self.loading = false; - }, - function getDocumentProgress(progressData) { - self.progress(progressData.loaded / progressData.total); - } - ); - }, - - download: function pdfViewDownload() { - function noData() { - FirefoxCom.request('download', { originalUrl: url }); - } - - var url = this.url.split('#')[0]; - if (PDFJS.isFirefoxExtension) { - // Document isn't ready just try to download with the url. - if (!this.pdfDocument) { - noData(); - return; - } - this.pdfDocument.getData().then( - function getDataSuccess(data) { - var bb = new MozBlobBuilder(); - bb.append(data.buffer); - var blobUrl = window.URL.createObjectURL( - bb.getBlob('application/pdf')); - - FirefoxCom.request('download', { blobUrl: blobUrl, originalUrl: url }, - function response(err) { - if (err) { - // This error won't really be helpful because it's likely the - // fallback won't work either (or is already open). - PDFView.error('PDF failed to download.'); - } - window.URL.revokeObjectURL(blobUrl); - } - ); - }, - noData // Error ocurred try downloading with just the url. - ); - } else { - url += '#pdfjs.action=download', '_parent'; - window.open(url, '_parent'); - } - }, - - fallback: function pdfViewFallback() { - if (!PDFJS.isFirefoxExtension) - return; - // Only trigger the fallback once so we don't spam the user with messages - // for one PDF. - if (this.fellback) - return; - this.fellback = true; - var url = this.url.split('#')[0]; - FirefoxCom.request('fallback', url, function response(download) { - if (!download) - return; - PDFView.download(); - }); - }, - - navigateTo: function pdfViewNavigateTo(dest) { - if (typeof dest === 'string') - dest = this.destinations[dest]; - if (!(dest instanceof Array)) - return; // invalid destination - // dest array looks like that: <page-ref> </XYZ|FitXXX> <args..> - var destRef = dest[0]; - var pageNumber = destRef instanceof Object ? - this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] : (destRef + 1); - if (pageNumber > this.pages.length) - pageNumber = this.pages.length; - if (pageNumber) { - this.page = pageNumber; - var currentPage = this.pages[pageNumber - 1]; - currentPage.scrollIntoView(dest); - } - }, - - getDestinationHash: function pdfViewGetDestinationHash(dest) { - if (typeof dest === 'string') - return PDFView.getAnchorUrl('#' + escape(dest)); - if (dest instanceof Array) { - var destRef = dest[0]; // see navigateTo method for dest format - var pageNumber = destRef instanceof Object ? - this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] : - (destRef + 1); - if (pageNumber) { - var pdfOpenParams = PDFView.getAnchorUrl('#page=' + pageNumber); - var destKind = dest[1]; - if (typeof destKind === 'object' && 'name' in destKind && - destKind.name == 'XYZ') { - var scale = (dest[4] || this.currentScale); - pdfOpenParams += '&zoom=' + (scale * 100); - if (dest[2] || dest[3]) { - pdfOpenParams += ',' + (dest[2] || 0) + ',' + (dest[3] || 0); - } - } - return pdfOpenParams; - } - } - return ''; - }, - - /** - * For the firefox extension we prefix the full url on anchor links so they - * don't come up as resource:// urls and so open in new tab/window works. - * @param {String} anchor The anchor hash include the #. - */ - getAnchorUrl: function getAnchorUrl(anchor) { - if (PDFJS.isFirefoxExtension) - return this.url.split('#')[0] + anchor; - return anchor; - }, - - /** - * Show the error box. - * @param {String} message A message that is human readable. - * @param {Object} moreInfo (optional) Further information about the error - * that is more technical. Should have a 'message' - * and optionally a 'stack' property. - */ - error: function pdfViewError(message, moreInfo) { - var moreInfoText = mozL10n.get('error_build', {build: PDFJS.build}, - 'PDF.JS Build: {{build}}') + '\n'; - if (moreInfo) { - moreInfoText += - mozL10n.get('error_message', {message: moreInfo.message}, - 'Message: {{message}}'); - if (moreInfo.stack) { - moreInfoText += '\n' + - mozL10n.get('error_stack', {stack: moreInfo.stack}, - 'Stack: {{stack}}'); - } else { - if (moreInfo.filename) { - moreInfoText += '\n' + - mozL10n.get('error_file', {file: moreInfo.filename}, - 'File: {{file}}'); - } - if (moreInfo.lineNumber) { - moreInfoText += '\n' + - mozL10n.get('error_line', {line: moreInfo.lineNumber}, - 'Line: {{line}}'); - } - } - } - if (PDFJS.isFirefoxExtension) { - console.error(message + '\n' + moreInfoText); - this.fallback(); - return; - } - var errorWrapper = document.getElementById('errorWrapper'); - errorWrapper.removeAttribute('hidden'); - - var errorMessage = document.getElementById('errorMessage'); - errorMessage.textContent = message; - - var closeButton = document.getElementById('errorClose'); - closeButton.onclick = function() { - errorWrapper.setAttribute('hidden', 'true'); - }; - - var errorMoreInfo = document.getElementById('errorMoreInfo'); - var moreInfoButton = document.getElementById('errorShowMore'); - var lessInfoButton = document.getElementById('errorShowLess'); - moreInfoButton.onclick = function() { - errorMoreInfo.removeAttribute('hidden'); - moreInfoButton.setAttribute('hidden', 'true'); - lessInfoButton.removeAttribute('hidden'); - }; - lessInfoButton.onclick = function() { - errorMoreInfo.setAttribute('hidden', 'true'); - moreInfoButton.removeAttribute('hidden'); - lessInfoButton.setAttribute('hidden', 'true'); - }; - moreInfoButton.removeAttribute('hidden'); - lessInfoButton.setAttribute('hidden', 'true'); - errorMoreInfo.value = moreInfoText; - - errorMoreInfo.rows = moreInfoText.split('\n').length - 1; - }, - - progress: function pdfViewProgress(level) { - var percent = Math.round(level * 100); - var loadingIndicator = document.getElementById('loading'); - loadingIndicator.textContent = mozL10n.get('loading', {percent: percent}, - 'Loading... {{percent}}%'); - -// PDFView.loadingBar.percent = percent; - }, - - load: function pdfViewLoad(pdfDocument, scale) { - function bindOnAfterDraw(pageView, thumbnailView) { - // when page is painted, using the image as thumbnail base - pageView.onAfterDraw = function pdfViewLoadOnAfterDraw() { - thumbnailView.setImage(pageView.canvas); - preDraw(); - }; - } - - this.pdfDocument = pdfDocument; - -// var errorWrapper = document.getElementById('errorWrapper'); -// errorWrapper.setAttribute('hidden', 'true'); - - var loadingBox = document.getElementById('loading'); - loadingBox.setAttribute('hidden', 'true'); - -// var loadingBox = document.getElementById('loadingBox'); -// loadingBox.setAttribute('hidden', 'true'); - -// var thumbsView = document.getElementById('thumbnailView'); -// thumbsView.parentNode.scrollTop = 0; - -// while (thumbsView.hasChildNodes()) -// thumbsView.removeChild(thumbsView.lastChild); - -// if ('_loadingInterval' in thumbsView) -// clearInterval(thumbsView._loadingInterval); - - var container = document.getElementById('viewer'); - while (container.hasChildNodes()) - container.removeChild(container.lastChild); - - var pagesCount = pdfDocument.numPages; - var id = pdfDocument.fingerprint; - var storedHash = null; -// document.getElementById('numPages').textContent = -// mozL10n.get('page_of', {pageCount: pagesCount}, 'of {{pageCount}}'); - document.getElementById('numPages').innerHTML = pagesCount; - document.getElementById('pageNumber').max = pagesCount; - PDFView.documentFingerprint = id; - var store = PDFView.store = new Settings(id); - if (store.get('exists', false)) { - var page = store.get('page', '1'); - var zoom = store.get('zoom', PDFView.currentScale); - var left = store.get('scrollLeft', '0'); - var top = store.get('scrollTop', '0'); - - storedHash = 'page=' + page + '&zoom=' + zoom + ',' + left + ',' + top; - } - - var pages = this.pages = []; - this.pageText = []; - this.startedTextExtraction = false; - var pagesRefMap = {}; - var thumbnails = this.thumbnails = []; - var pagePromises = []; - for (var i = 1; i <= pagesCount; i++) - pagePromises.push(pdfDocument.getPage(i)); - var self = this; - var pagesPromise = PDFJS.Promise.all(pagePromises); - pagesPromise.then(function(promisedPages) { - for (var i = 1; i <= pagesCount; i++) { - var page = promisedPages[i - 1]; - var pageView = new PageView(container, page, i, scale, - page.stats, self.navigateTo.bind(self)); -// var thumbnailView = new ThumbnailView(thumbsView, page, i); -// bindOnAfterDraw(pageView, thumbnailView); - - pages.push(pageView); -// thumbnails.push(thumbnailView); - var pageRef = page.ref; - pagesRefMap[pageRef.num + ' ' + pageRef.gen + ' R'] = i; - } - - self.pagesRefMap = pagesRefMap; - }); - - var destinationsPromise = pdfDocument.getDestinations(); - destinationsPromise.then(function(destinations) { - self.destinations = destinations; - }); - - // outline and initial view depends on destinations and pagesRefMap - PDFJS.Promise.all([pagesPromise, destinationsPromise]).then(function() { - pdfDocument.getOutline().then(function(outline) { - self.outline = new DocumentOutlineView(outline); - }); - - self.setInitialView(storedHash, scale); - }); - - pdfDocument.getMetadata().then(function(data) { - var info = data.info, metadata = data.metadata; - self.documentInfo = info; - self.metadata = metadata; - - var pdfTitle; - if (metadata) { - if (metadata.has('dc:title')) - pdfTitle = metadata.get('dc:title'); - } - - if (!pdfTitle && info && info['Title']) - pdfTitle = info['Title']; - - if (pdfTitle) - document.title = pdfTitle + ' - ' + document.title; - }); - }, - - setInitialView: function pdfViewSetInitialView(storedHash, scale) { - // Reset the current scale, as otherwise the page's scale might not get - // updated if the zoom level stayed the same. - this.currentScale = 0; - this.currentScaleValue = null; - if (this.initialBookmark) { - this.setHash(this.initialBookmark); - this.initialBookmark = null; - } - else if (storedHash) - this.setHash(storedHash); - else if (scale) { - this.parseScale(scale, true); - this.page = 1; - } - - if (PDFView.currentScale === kUnknownScale) { - // Scale was not initialized: invalid bookmark or scale was not specified. - // Setting the default one. - this.parseScale(kDefaultScale, true); - } - }, - - search: function pdfViewStartSearch() { - // Limit this function to run every <SEARCH_TIMEOUT>ms. - var SEARCH_TIMEOUT = 250; - var lastSeach = this.lastSearch; - var now = Date.now(); - if (lastSeach && (now - lastSeach) < SEARCH_TIMEOUT) { - if (!this.searchTimer) { - this.searchTimer = setTimeout(function resumeSearch() { - PDFView.search(); - }, - SEARCH_TIMEOUT - (now - lastSeach) - ); - } - return; - } - this.searchTimer = null; - this.lastSearch = now; - - function bindLink(link, pageNumber) { - link.href = '#' + pageNumber; - link.onclick = function searchBindLink() { - PDFView.page = pageNumber; - return false; - }; - } - - var searchResults = document.getElementById('searchResults'); - - var searchTermsInput = document.getElementById('searchTermsInput'); - searchResults.removeAttribute('hidden'); - searchResults.textContent = ''; - - var terms = searchTermsInput.value; - - if (!terms) - return; - - // simple search: removing spaces and hyphens, then scanning every - terms = terms.replace(/\s-/g, '').toLowerCase(); - var index = PDFView.pageText; - var pageFound = false; - for (var i = 0, ii = index.length; i < ii; i++) { - var pageText = index[i].replace(/\s-/g, '').toLowerCase(); - var j = pageText.indexOf(terms); - if (j < 0) - continue; - - var pageNumber = i + 1; - var textSample = index[i].substr(j, 50); - var link = document.createElement('a'); - bindLink(link, pageNumber); - link.textContent = 'Page ' + pageNumber + ': ' + textSample; - searchResults.appendChild(link); - - pageFound = true; - } - if (!pageFound) { - searchResults.textContent = mozL10n.get('search_terms_not_found', null, - '(Not found)'); - } - }, - - setHash: function pdfViewSetHash(hash) { - if (!hash) - return; - - if (hash.indexOf('=') >= 0) { - var params = PDFView.parseQueryString(hash); - // borrowing syntax from "Parameters for Opening PDF Files" - if ('nameddest' in params) { - PDFView.navigateTo(params.nameddest); - return; - } - if ('page' in params) { - var pageNumber = (params.page | 0) || 1; - this.page = pageNumber; - if ('zoom' in params) { - var zoomArgs = params.zoom.split(','); // scale,left,top - // building destination array - - // If the zoom value, it has to get divided by 100. If it is a string, - // it should stay as it is. - var zoomArg = zoomArgs[0]; - var zoomArgNumber = parseFloat(zoomArg); - if (zoomArgNumber) - zoomArg = zoomArgNumber / 100; - - var dest = [null, {name: 'XYZ'}, (zoomArgs[1] | 0), - (zoomArgs[2] | 0), zoomArg]; - var currentPage = this.pages[pageNumber - 1]; - currentPage.scrollIntoView(dest); - } else - this.page = params.page; // simple page - return; - } - } else if (/^\d+$/.test(hash)) // page number - this.page = hash; - else // named destination - PDFView.navigateTo(unescape(hash)); - }, - - switchSidebarView: function pdfViewSwitchSidebarView(view) { - var thumbsView = document.getElementById('thumbnailView'); - var outlineView = document.getElementById('outlineView'); - var searchView = document.getElementById('searchView'); - - var thumbsButton = document.getElementById('viewThumbnail'); - var outlineButton = document.getElementById('viewOutline'); - var searchButton = document.getElementById('viewSearch'); - - switch (view) { - case 'thumbs': - thumbsButton.classList.add('toggled'); - outlineButton.classList.remove('toggled'); - searchButton.classList.remove('toggled'); - thumbsView.classList.remove('hidden'); - outlineView.classList.add('hidden'); - searchView.classList.add('hidden'); - - updateThumbViewArea(); - break; - - case 'outline': - thumbsButton.classList.remove('toggled'); - outlineButton.classList.add('toggled'); - searchButton.classList.remove('toggled'); - thumbsView.classList.add('hidden'); - outlineView.classList.remove('hidden'); - searchView.classList.add('hidden'); - - if (outlineButton.getAttribute('disabled')) - return; - break; - - case 'search': - thumbsButton.classList.remove('toggled'); - outlineButton.classList.remove('toggled'); - searchButton.classList.add('toggled'); - thumbsView.classList.add('hidden'); - outlineView.classList.add('hidden'); - searchView.classList.remove('hidden'); - - var searchTermsInput = document.getElementById('searchTermsInput'); - searchTermsInput.focus(); - // Start text extraction as soon as the search gets displayed. - this.extractText(); - break; - } - }, - - extractText: function() { - if (this.startedTextExtraction) - return; - this.startedTextExtraction = true; - var self = this; - function extractPageText(pageIndex) { - self.pages[pageIndex].pdfPage.getTextContent().then( - function textContentResolved(textContent) { - self.pageText[pageIndex] = textContent; - self.search(); - if ((pageIndex + 1) < self.pages.length) - extractPageText(pageIndex + 1); - } - ); - }; - extractPageText(0); - }, - - getVisiblePages: function pdfViewGetVisiblePages() { - var pages = this.pages; - var kBottomMargin = 10; - var kTopPadding = 30; - var visiblePages = []; - - var currentHeight = kTopPadding + kBottomMargin; - //var container = this.container; - var container = document.getElementById('viewer'); - - // Add 1px to the scrolltop to give a little wiggle room if the math is off, - // this won't be needed if we calc current page number based off the middle - // of the screen instead of the top. - var containerTop = container.scrollTop + 1; - for (var i = 1; i <= pages.length; ++i) { - var page = pages[i - 1]; - var pageHeight = page.height + kBottomMargin; - if (currentHeight + pageHeight > containerTop) - break; - - currentHeight += pageHeight; - } - - var containerBottom = containerTop + container.clientHeight; - for (; i <= pages.length && currentHeight < containerBottom; ++i) { - var singlePage = pages[i - 1]; - visiblePages.push({ id: singlePage.id, y: currentHeight, - view: singlePage }); - currentHeight += page.height + kBottomMargin; - } - return visiblePages; - }, - - getVisibleThumbs: function pdfViewGetVisibleThumbs() { - var thumbs = this.thumbnails; - var kBottomMargin = 15; - var visibleThumbs = []; - - var view = document.getElementById('thumbnailView'); - var currentHeight = kBottomMargin; - - var top = view.scrollTop; - for (var i = 1; i <= thumbs.length; ++i) { - var thumb = thumbs[i - 1]; - var thumbHeight = thumb.height * thumb.scaleY + kBottomMargin; - if (currentHeight + thumbHeight > top) - break; - - currentHeight += thumbHeight; - } - - var bottom = top + view.clientHeight; - for (; i <= thumbs.length && currentHeight < bottom; ++i) { - var singleThumb = thumbs[i - 1]; - visibleThumbs.push({ id: singleThumb.id, y: currentHeight, - view: singleThumb }); - currentHeight += singleThumb.height * singleThumb.scaleY + kBottomMargin; - } - - return visibleThumbs; - }, - - // Helper function to parse query string (e.g. ?param1=value&parm2=...). - parseQueryString: function pdfViewParseQueryString(query) { - var parts = query.split('&'); - var params = {}; - for (var i = 0, ii = parts.length; i < parts.length; ++i) { - var param = parts[i].split('='); - var key = param[0]; - var value = param.length > 1 ? param[1] : null; - params[unescape(key)] = unescape(value); - } - return params; - } -}; - -var PageView = function pageView(container, pdfPage, id, scale, - stats, navigateTo) { - this.id = id; - this.pdfPage = pdfPage; - - this.scale = scale || 1.0; - this.viewport = this.pdfPage.getViewport(this.scale); - - 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.destroy = function pageViewDestroy() { - this.update(); - this.pdfPage.destroy(); - }; - - this.update = function pageViewUpdate(scale) { - this.scale = scale || this.scale; - var viewport = this.pdfPage.getViewport(this.scale); - - this.viewport = viewport; - div.style.width = viewport.width + 'px'; - div.style.height = viewport.height + 'px'; - - while (div.hasChildNodes()) - div.removeChild(div.lastChild); - div.removeAttribute('data-loaded'); - - delete this.canvas; - - this.loadingIconDiv = document.createElement('div'); - this.loadingIconDiv.className = 'loadingIcon'; - div.appendChild(this.loadingIconDiv); - }; - - Object.defineProperty(this, 'width', { - get: function PageView_getWidth() { - return this.viewport.width; - }, - enumerable: true - }); - - Object.defineProperty(this, 'height', { - get: function PageView_getHeight() { - return this.viewport.height; - }, - enumerable: true - }); - - function setupAnnotations(pdfPage, viewport) { - function bindLink(link, dest) { - link.href = PDFView.getDestinationHash(dest); - link.onclick = function pageViewSetupLinksOnclick() { - if (dest) - PDFView.navigateTo(dest); - return false; - }; - } - function createElementWithStyle(tagName, item) { - var rect = viewport.convertToViewportRectangle(item.rect); - rect = PDFJS.Util.normalizeRect(rect); - var element = document.createElement(tagName); - element.style.left = Math.floor(rect[0]) + 'px'; - element.style.top = Math.floor(rect[1]) + 'px'; - element.style.width = Math.ceil(rect[2] - rect[0]) + 'px'; - element.style.height = Math.ceil(rect[3] - rect[1]) + 'px'; - return element; - } - function createCommentAnnotation(type, item) { - var container = document.createElement('section'); - container.className = 'annotComment'; - - var image = createElementWithStyle('img', item); - var type = item.type; - var rect = viewport.convertToViewportRectangle(item.rect); - rect = PDFJS.Util.normalizeRect(rect); - image.src = kImageDirectory + 'annotation-' + type.toLowerCase() + '.svg'; - image.alt = mozL10n.get('text_annotation_type', {type: type}, - '[{{type}} Annotation]'); - var content = document.createElement('div'); - content.setAttribute('hidden', true); - var title = document.createElement('h1'); - var text = document.createElement('p'); - content.style.left = Math.floor(rect[2]) + 'px'; - content.style.top = Math.floor(rect[1]) + 'px'; - title.textContent = item.title; - - if (!item.content && !item.title) { - content.setAttribute('hidden', true); - } else { - var e = document.createElement('span'); - var lines = item.content.split('\n'); - for (var i = 0, ii = lines.length; i < ii; ++i) { - var line = lines[i]; - e.appendChild(document.createTextNode(line)); - if (i < (ii - 1)) - e.appendChild(document.createElement('br')); - } - text.appendChild(e); - image.addEventListener('mouseover', function annotationImageOver() { - content.removeAttribute('hidden'); - }, false); - - image.addEventListener('mouseout', function annotationImageOut() { - content.setAttribute('hidden', true); - }, false); - } - - content.appendChild(title); - content.appendChild(text); - container.appendChild(image); - container.appendChild(content); - - return container; - } - - pdfPage.getAnnotations().then(function(items) { - for (var i = 0; i < items.length; i++) { - var item = items[i]; - switch (item.type) { - case 'Link': - var link = createElementWithStyle('a', item); - link.href = item.url || ''; - if (!item.url) - bindLink(link, ('dest' in item) ? item.dest : null); - div.appendChild(link); - break; - case 'Text': - var comment = createCommentAnnotation(item.name, item); - if (comment) - div.appendChild(comment); - break; - case 'Widget': - // TODO: support forms - PDFView.fallback(); - break; - } - } - }); - } - - this.getPagePoint = function pageViewGetPagePoint(x, y) { - return this.viewport.convertToPdfPoint(x, y); - }; - - this.scrollIntoView = function pageViewScrollIntoView(dest) { - if (!dest) { - div.scrollIntoView(true); - return; - } - - var x = 0, y = 0; - var width = 0, height = 0, widthScale, heightScale; - var scale = 0; - switch (dest[1].name) { - case 'XYZ': - x = dest[2]; - y = dest[3]; - scale = dest[4]; - break; - case 'Fit': - case 'FitB': - scale = 'page-fit'; - break; - case 'FitH': - case 'FitBH': - y = dest[2]; - scale = 'page-width'; - break; - case 'FitV': - case 'FitBV': - x = dest[2]; - scale = 'page-height'; - break; - case 'FitR': - x = dest[2]; - y = dest[3]; - width = dest[4] - x; - height = dest[5] - y; - widthScale = (this.container.clientWidth - kScrollbarPadding) / - width / kCssUnits; - heightScale = (this.container.clientHeight - kScrollbarPadding) / - height / kCssUnits; - scale = Math.min(widthScale, heightScale); - break; - default: - return; - } - - if (scale && scale !== PDFView.currentScale) - PDFView.parseScale(scale, true); - else if (PDFView.currentScale === kUnknownScale) - PDFView.parseScale(kDefaultScale, true); - - var boundingRect = [ - this.viewport.convertToViewportPoint(x, y), - this.viewport.convertToViewportPoint(x + width, y + height) - ]; - setTimeout(function pageViewScrollIntoViewRelayout() { - // letting page to re-layout before scrolling - var scale = PDFView.currentScale; - var x = Math.min(boundingRect[0][0], boundingRect[1][0]); - var y = Math.min(boundingRect[0][1], boundingRect[1][1]); - var width = Math.abs(boundingRect[0][0] - boundingRect[1][0]); - var height = Math.abs(boundingRect[0][1] - boundingRect[1][1]); - - // using temporary div to scroll it into view - var tempDiv = document.createElement('div'); - tempDiv.style.position = 'absolute'; - tempDiv.style.left = Math.floor(x) + 'px'; - tempDiv.style.top = Math.floor(y) + 'px'; - tempDiv.style.width = Math.ceil(width) + 'px'; - tempDiv.style.height = Math.ceil(height) + 'px'; - div.appendChild(tempDiv); - tempDiv.scrollIntoView(true); - div.removeChild(tempDiv); - }, 0); - }; - - this.drawingRequired = function() { - return !div.querySelector('canvas'); - }; - - this.draw = function pageviewDraw(callback) { - if (!this.drawingRequired()) { - this.updateStats(); - callback(); - return; - } - - var canvas = document.createElement('canvas'); - canvas.id = 'page' + this.id; - canvas.mozOpaque = true; - div.appendChild(canvas); - this.canvas = canvas; - - var textLayerDiv = null; - if (!PDFJS.disableTextLayer) { - textLayerDiv = document.createElement('div'); - textLayerDiv.className = 'textLayer'; - div.appendChild(textLayerDiv); - } - var textLayer = textLayerDiv ? new TextLayerBuilder(textLayerDiv) : null; - - var scale = this.scale, viewport = this.viewport; - canvas.width = viewport.width; - canvas.height = viewport.height; - - var ctx = canvas.getContext('2d'); - ctx.save(); - ctx.fillStyle = 'rgb(255, 255, 255)'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.restore(); - - // Rendering area - - var self = this; - function pageViewDrawCallback(error) { - if (self.loadingIconDiv) { - div.removeChild(self.loadingIconDiv); - delete self.loadingIconDiv; - } - - if (error) { - PDFView.error(mozL10n.get('rendering_error', null, - 'An error occurred while rendering the page.'), error); - } - - self.stats = pdfPage.stats; - self.updateStats(); - if (self.onAfterDraw) - self.onAfterDraw(); - - cache.push(self); - callback(); - } - - var renderContext = { - canvasContext: ctx, - viewport: this.viewport, - textLayer: textLayer - }; - this.pdfPage.render(renderContext).then( - function pdfPageRenderCallback() { - pageViewDrawCallback(null); - }, - function pdfPageRenderError(error) { - pageViewDrawCallback(error); - } - ); - - setupAnnotations(this.pdfPage, this.viewport); - div.setAttribute('data-loaded', true); - }; - - this.updateStats = function pageViewUpdateStats() { - if (PDFJS.pdfBug && Stats.enabled) { - var stats = this.stats; - Stats.add(this.id, stats); - } - }; -}; - -var ThumbnailView = function thumbnailView(container, pdfPage, id) { - var anchor = document.createElement('a'); - anchor.href = PDFView.getAnchorUrl('#page=' + id); - anchor.title = mozL10n.get('thumb_page_title', {page: id}, 'Page {{page}}'); - anchor.onclick = function stopNavigation() { - PDFView.page = id; - return false; - }; - - var viewport = pdfPage.getViewport(1); - var pageWidth = this.width = viewport.width; - var pageHeight = this.height = viewport.height; - var pageRatio = pageWidth / pageHeight; - this.id = id; - - var canvasWidth = 98; - var canvasHeight = canvasWidth / this.width * this.height; - var scaleX = this.scaleX = (canvasWidth / pageWidth); - var scaleY = this.scaleY = (canvasHeight / pageHeight); - - var div = document.createElement('div'); - div.id = 'thumbnailContainer' + id; - div.className = 'thumbnail'; - - anchor.appendChild(div); - container.appendChild(anchor); - - this.hasImage = false; - - function getPageDrawContext() { - var canvas = document.createElement('canvas'); - canvas.id = 'thumbnail' + id; - canvas.mozOpaque = true; - - canvas.width = canvasWidth; - canvas.height = canvasHeight; - canvas.className = 'thumbnailImage'; - canvas.setAttribute('aria-label', mozL10n.get('thumb_page_canvas', - {page: id}, 'Thumbnail of Page {{page}}')); - - div.setAttribute('data-loaded', true); - - var ring = document.createElement('div'); - ring.className = 'thumbnailSelectionRing'; - ring.appendChild(canvas); - div.appendChild(ring); - - var ctx = canvas.getContext('2d'); - ctx.save(); - ctx.fillStyle = 'rgb(255, 255, 255)'; - ctx.fillRect(0, 0, canvasWidth, canvasHeight); - ctx.restore(); - return ctx; - } - - this.drawingRequired = function thumbnailViewDrawingRequired() { - return !this.hasImage; - }; - - this.draw = function thumbnailViewDraw(callback) { - if (this.hasImage) { - callback(); - return; - } - - var ctx = getPageDrawContext(); - var drawViewport = pdfPage.getViewport(scaleX); - var renderContext = { - canvasContext: ctx, - viewport: drawViewport - }; - pdfPage.render(renderContext).then( - function pdfPageRenderCallback() { - callback(); - }, - function pdfPageRenderError(error) { - callback(); - } - ); - this.hasImage = true; - }; - - this.setImage = function thumbnailViewSetImage(img) { - if (this.hasImage || !img) - return; - - var ctx = getPageDrawContext(); - ctx.drawImage(img, 0, 0, img.width, img.height, - 0, 0, ctx.canvas.width, ctx.canvas.height); - - this.hasImage = true; - }; -}; - -var DocumentOutlineView = function documentOutlineView(outline) { - var outlineView = document.getElementById('outlineView'); -// while (outlineView.firstChild) -// outlineView.removeChild(outlineView.firstChild); - - function bindItemLink(domObj, item) { - domObj.href = PDFView.getDestinationHash(item.dest); - domObj.onclick = function documentOutlineViewOnclick(e) { - PDFView.navigateTo(item.dest); - return false; - }; - } - - if (!outline) { - var noOutline = document.createElement('div'); - noOutline.classList.add('noOutline'); - //noOutline.textContent = mozL10n.get('no_outline', null, - // 'No Outline Available'); - noOutline.textContent = 'No Outline Available'; - //outlineView.appendChild(noOutline); - return; - } - - var queue = [{parent: outlineView, items: outline}]; - while (queue.length > 0) { - var levelData = queue.shift(); - var i, n = levelData.items.length; - for (i = 0; i < n; i++) { - var item = levelData.items[i]; - var div = document.createElement('div'); - div.className = 'outlineItem'; - var a = document.createElement('a'); - bindItemLink(a, item); - a.textContent = item.title; - div.appendChild(a); - - if (item.items.length > 0) { - var itemsDiv = document.createElement('div'); - itemsDiv.className = 'outlineItems'; - div.appendChild(itemsDiv); - queue.push({parent: itemsDiv, items: item.items}); - } - -// levelData.parent.appendChild(div); - } - } -}; - -// optimised CSS custom property getter/setter -var CustomStyle = (function CustomStyleClosure() { - - // As noted on: http://www.zachstronaut.com/posts/2009/02/17/ - // animate-css-transforms-firefox-webkit.html - // in some versions of IE9 it is critical that ms appear in this list - // before Moz - var prefixes = ['ms', 'Moz', 'Webkit', 'O']; - var _cache = { }; - - function CustomStyle() { - } - - CustomStyle.getProp = function get(propName, element) { - // check cache only when no element is given - if (arguments.length == 1 && typeof _cache[propName] == 'string') { - return _cache[propName]; - } - - element = element || document.documentElement; - var style = element.style, prefixed, uPropName; - - // test standard property first - if (typeof style[propName] == 'string') { - return (_cache[propName] = propName); - } - - // capitalize - uPropName = propName.charAt(0).toUpperCase() + propName.slice(1); - - // test vendor specific properties - for (var i = 0, l = prefixes.length; i < l; i++) { - prefixed = prefixes[i] + uPropName; - if (typeof style[prefixed] == 'string') { - return (_cache[propName] = prefixed); - } - } - - //if all fails then set to undefined - return (_cache[propName] = 'undefined'); - } - - CustomStyle.setProp = function set(propName, element, str) { - var prop = this.getProp(propName); - if (prop != 'undefined') - element.style[prop] = str; - } - - return CustomStyle; -})(); - -var TextLayerBuilder = function textLayerBuilder(textLayerDiv) { - this.textLayerDiv = textLayerDiv; - - this.beginLayout = function textLayerBuilderBeginLayout() { - this.textDivs = []; - this.textLayerQueue = []; - }; - - this.endLayout = function textLayerBuilderEndLayout() { - var self = this; - var textDivs = this.textDivs; - var textLayerDiv = this.textLayerDiv; - var renderTimer = null; - var renderingDone = false; - var renderInterval = 0; - var resumeInterval = 500; // in ms - - // Render the text layer, one div at a time - function renderTextLayer() { - if (textDivs.length === 0) { - clearInterval(renderTimer); - renderingDone = true; - return; - } - var textDiv = textDivs.shift(); - if (textDiv.dataset.textLength > 0) { - textLayerDiv.appendChild(textDiv); - - if (textDiv.dataset.textLength > 1) { // avoid div by zero - // Adjust div width to match canvas text - // Due to the .offsetWidth calls, this is slow - // This needs to come after appending to the DOM - var textScale = textDiv.dataset.canvasWidth / textDiv.offsetWidth; - CustomStyle.setProp('transform' , textDiv, - 'scale(' + textScale + ', 1)'); - CustomStyle.setProp('transformOrigin' , textDiv, '0% 0%'); - } - } // textLength > 0 - } - renderTimer = setInterval(renderTextLayer, renderInterval); - - // Stop rendering when user scrolls. Resume after XXX milliseconds - // of no scroll events - var scrollTimer = null; - function textLayerOnScroll() { - if (renderingDone) { - window.removeEventListener('scroll', textLayerOnScroll, false); - return; - } - - // Immediately pause rendering - clearInterval(renderTimer); - - clearTimeout(scrollTimer); - scrollTimer = setTimeout(function textLayerScrollTimer() { - // Resume rendering - renderTimer = setInterval(renderTextLayer, renderInterval); - }, resumeInterval); - }; // textLayerOnScroll - - window.addEventListener('scroll', textLayerOnScroll, false); - }; // endLayout - - this.appendText = function textLayerBuilderAppendText(text, - fontName, fontSize) { - var textDiv = document.createElement('div'); - - // vScale and hScale already contain the scaling to pixel units - var fontHeight = fontSize * text.geom.vScale; - textDiv.dataset.canvasWidth = text.canvasWidth * text.geom.hScale; - textDiv.dataset.fontName = fontName; - - textDiv.style.fontSize = fontHeight + 'px'; - textDiv.style.left = text.geom.x + 'px'; - textDiv.style.top = (text.geom.y - fontHeight) + 'px'; - textDiv.textContent = PDFJS.bidi(text, -1); - textDiv.dir = text.direction; - textDiv.dataset.textLength = text.length; - this.textDivs.push(textDiv); - }; -}; - -window.addEventListener('load', function webViewerLoad(evt) { - PDFView.initialize(); - var params = PDFView.parseQueryString(document.location.search.substring(1)); - - var file = PDFJS.isFirefoxExtension ? - window.location.toString() : params.file || kDefaultURL; - -/* if (PDFJS.isFirefoxExtension || !window.File || !window.FileReader || - !window.FileList || !window.Blob) { - document.getElementById('openFile').setAttribute('hidden', 'true'); - } else { - document.getElementById('fileInput').value = null; - } -*/ - // Special debugging flags in the hash section of the URL. - var hash = document.location.hash.substring(1); - var hashParams = PDFView.parseQueryString(hash); - - if ('disableWorker' in hashParams) - PDFJS.disableWorker = (hashParams['disableWorker'] === 'true'); - -/* if (!PDFJS.isFirefoxExtension) { - var locale = navigator.language; - if ('locale' in hashParams) - locale = hashParams['locale']; - mozL10n.language.code = locale; - } -*/ - if ('disableTextLayer' in hashParams) - PDFJS.disableTextLayer = (hashParams['disableTextLayer'] === 'true'); - - if ('pdfBug' in hashParams && - (!PDFJS.isFirefoxExtension || FirefoxCom.requestSync('pdfBugEnabled'))) { - PDFJS.pdfBug = true; - var pdfBug = hashParams['pdfBug']; - var enabled = pdfBug.split(','); - PDFBug.enable(enabled); - PDFBug.init(); - } - -/* if (!PDFJS.isFirefoxExtension || - (PDFJS.isFirefoxExtension && FirefoxCom.requestSync('searchEnabled'))) { - document.querySelector('#viewSearch').classList.remove('hidden'); - } -*/ - // Listen for warnings to trigger the fallback UI. Errors should be caught - // and call PDFView.error() so we don't need to listen for those. - PDFJS.LogManager.addLogger({ - warn: function() { - PDFView.fallback(); - } - }); - -// var thumbsView = document.getElementById('thumbnailView'); -// thumbsView.addEventListener('scroll', updateThumbViewArea, true); -/* - var mainContainer = document.getElementById('mainContainer'); - var outerContainer = document.getElementById('outerContainer'); - mainContainer.addEventListener('transitionend', function(e) { - if (e.target == mainContainer) { - var event = document.createEvent('UIEvents'); - event.initUIEvent('resize', false, false, window, 0); - window.dispatchEvent(event); - outerContainer.classList.remove('sidebarMoving'); - } - }, true); - - document.getElementById('sidebarToggle').addEventListener('click', - function() { - this.classList.toggle('toggled'); - outerContainer.classList.add('sidebarMoving'); - outerContainer.classList.toggle('sidebarOpen'); - updateThumbViewArea(); - }); - - PDFView.open(file, 0); -*/ -}, true); - -/** - * Render the next not yet visible page already such that it is - * hopefully ready once the user scrolls to it. - */ -function preDraw() { - var pages = PDFView.pages; - var visible = PDFView.getVisiblePages(); - var last = visible[visible.length - 1]; - // PageView.id is the actual page number, which is + 1 compared - // to the index in `pages`. That means, pages[last.id] is the next - // PageView instance. - if (pages[last.id] && pages[last.id].drawingRequired()) { - renderingQueue.enqueueDraw(pages[last.id]); - return; - } - // If there is nothing to draw on the next page, maybe the user - // is scrolling up, so, let's try to render the next page *before* - // the first visible page - if (pages[visible[0].id - 2]) { - renderingQueue.enqueueDraw(pages[visible[0].id - 2]); - } -} - -function updateViewarea() { - if (!PDFView.initialized) - return; - var container = document.getElementById('viewer'); - if (!container) - return; - - var visiblePages = PDFView.getVisiblePages(); - var pageToDraw; - for (var i = 0; i < visiblePages.length; i++) { - var page = visiblePages[i]; - var pageObj = PDFView.pages[page.id - 1]; - - pageToDraw |= pageObj.drawingRequired(); - renderingQueue.enqueueDraw(pageObj); - } - - if (!visiblePages.length) - return; - - // If there is no need to draw a page that is currenlty visible, preDraw the - // next page the user might scroll to. - if (!pageToDraw) { - preDraw(); - } - - updateViewarea.inProgress = true; // used in "set page" - var currentId = PDFView.page; - var firstPage = visiblePages[0]; - PDFView.page = firstPage.id; - updateViewarea.inProgress = false; - - var currentScale = PDFView.currentScale; - var currentScaleValue = PDFView.currentScaleValue; - var normalizedScaleValue = currentScaleValue == currentScale ? - currentScale * 100 : currentScaleValue; - - var pageNumber = firstPage.id; - var pdfOpenParams = '#page=' + pageNumber; - pdfOpenParams += '&zoom=' + normalizedScaleValue; - var currentPage = PDFView.pages[pageNumber - 1]; - var topLeft = currentPage.getPagePoint(PDFView.container.scrollLeft, - (PDFView.container.scrollTop - firstPage.y)); - pdfOpenParams += ',' + Math.round(topLeft[0]) + ',' + Math.round(topLeft[1]); - - var store = PDFView.store; - store.set('exists', true); - store.set('page', pageNumber); - store.set('zoom', normalizedScaleValue); - store.set('scrollLeft', Math.round(topLeft[0])); - store.set('scrollTop', Math.round(topLeft[1])); -// var href = PDFView.getAnchorUrl(pdfOpenParams); -// document.getElementById('viewBookmark').href = href; -} - -window.addEventListener('scroll', function webViewerScroll(evt) { - updateViewarea(); -}, true); - -var thumbnailTimer; - -function updateThumbViewArea() { - // Only render thumbs after pausing scrolling for this amount of time - // (makes UI more responsive) - var delay = 50; // in ms - - if (thumbnailTimer) - clearTimeout(thumbnailTimer); - - thumbnailTimer = setTimeout(function() { - var visibleThumbs = PDFView.getVisibleThumbs(); - for (var i = 0; i < visibleThumbs.length; i++) { - var thumb = visibleThumbs[i]; - renderingQueue.enqueueDraw(PDFView.thumbnails[thumb.id - 1]); - } - }, delay); -} - -window.addEventListener('resize', function webViewerResize(evt) { - if (PDFView.initialized && PDFView.active && - (document.getElementById('pageWidthOption').selected || - document.getElementById('pageFitOption').selected )) - PDFView.parseScale(document.getElementById('scaleSelect').value); - updateViewarea(); -}); - -window.addEventListener('hashchange', function webViewerHashchange(evt) { - PDFView.setHash(document.location.hash.substring(1)); -}); - -window.addEventListener('change', function webViewerChange(evt) { - var files = evt.target.files; - if (!files || files.length == 0) - return; - - // Read the local file into a Uint8Array. - var fileReader = new FileReader(); - fileReader.onload = function webViewerChangeFileReaderOnload(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); - - PDFView.open(uint8Array, 0); - }; - - // Read as a binary string since "readAsArrayBuffer" is not yet - // implemented in Firefox. - var file = files[0]; - fileReader.readAsBinaryString(file); - document.title = file.name; - - // URL does not reflect proper document location - hiding some icons. -// document.getElementById('viewBookmark').setAttribute('hidden', 'true'); -// document.getElementById('download').setAttribute('hidden', 'true'); -}, true); - -function selectScaleOption(value) { - var options = document.getElementById('scaleSelect').options; - var predefinedValueFound = false; - for (var i = 0; i < options.length; i++) { - var option = options[i]; - if (option.value != value) { - option.selected = false; - continue; - } - option.selected = true; - predefinedValueFound = true; - } - return predefinedValueFound; -} - -window.addEventListener('localized', function localized(evt) { - document.getElementsByTagName('html')[0].dir = mozL10n.language.direction; -}, true); - -window.addEventListener('scalechange', function scalechange(evt) { - var customScaleOption = document.getElementById('customScaleOption'); - customScaleOption.selected = false; - - if (!evt.resetAutoSettings && - (document.getElementById('pageWidthOption').selected || - document.getElementById('pageFitOption').selected || - document.getElementById('pageAutoOption').selected)) { - updateViewarea(); - return; - } - - var predefinedValueFound = selectScaleOption('' + evt.scale); - if (!predefinedValueFound) { - customScaleOption.textContent = Math.round(evt.scale * 10000) / 100 + '%'; - customScaleOption.selected = true; - } - - updateViewarea(); -}, true); - -window.addEventListener('pagechange', function pagechange(evt) { - var page = evt.pageNumber; - if (document.getElementById('pageNumber').value != page) { - document.getElementById('pageNumber').value = page; - var selected = document.querySelector('.thumbnail.selected'); - if (selected) - selected.classList.remove('selected'); -/* - var thumbnail = document.getElementById('thumbnailContainer' + page); - thumbnail.classList.add('selected'); - var visibleThumbs = PDFView.getVisibleThumbs(); - var numVisibleThumbs = visibleThumbs.length; - // If the thumbnail isn't currently visible scroll it into view. - if (numVisibleThumbs > 0) { - var first = visibleThumbs[0].id; - // Account for only one thumbnail being visible. - var last = numVisibleThumbs > 1 ? - visibleThumbs[numVisibleThumbs - 1].id : first; - if (page <= first || page >= last) - thumbnail.scrollIntoView(); - } -*/ - } - document.getElementById('previous').disabled = (page <= 1); - document.getElementById('next').disabled = (page >= PDFView.pages.length); -}, true); - -// Firefox specific event, so that we can prevent browser from zooming -window.addEventListener('DOMMouseScroll', function(evt) { - if (evt.ctrlKey) { - evt.preventDefault(); - - var ticks = evt.detail; - var direction = (ticks > 0) ? 'zoomOut' : 'zoomIn'; - for (var i = 0, length = Math.abs(ticks); i < length; i++) - PDFView[direction](); - } -}, false); - - |