Merge branch 'master' of git://github.com/mozilla/pdf.js.git into loadingbychrome

Conflicts:
	web/viewer.js
This commit is contained in:
Yury Delendik 2012-08-15 10:17:30 -05:00
commit 9cc5fc4e38
30 changed files with 839 additions and 430 deletions

View file

@ -90,66 +90,9 @@ var ProgressBar = (function ProgressBarClosure() {
return ProgressBar;
})();
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);
}
};
})();
//#if FIREFOX || MOZCENTRAL
//#include firefoxcom.js
//#endif
// Settings Manager - This is a utility for saving settings
// First we see if localStorage is available
@ -167,17 +110,17 @@ var Settings = (function SettingsClosure() {
}
})();
var isFirefoxExtension = PDFJS.isFirefoxExtension;
function Settings(fingerprint) {
var database = null;
var index;
if (isFirefoxExtension)
database = FirefoxCom.requestSync('getDatabase', null) || '{}';
else if (isLocalStorageEnabled)
//#if !(FIREFOX || MOZCENTRAL)
if (isLocalStorageEnabled)
database = localStorage.getItem('database') || '{}';
else
return false;
return;
//#else
// database = FirefoxCom.requestSync('getDatabase', null) || '{}';
//#endif
database = JSON.parse(database);
if (!('files' in database))
@ -205,10 +148,12 @@ var Settings = (function SettingsClosure() {
var file = this.file;
file[name] = val;
var database = JSON.stringify(this.database);
if (isFirefoxExtension)
FirefoxCom.requestSync('setDatabase', database);
else if (isLocalStorageEnabled)
//#if !(FIREFOX || MOZCENTRAL)
if (isLocalStorageEnabled)
localStorage.setItem('database', database);
//#else
// FirefoxCom.requestSync('setDatabase', database);
//#endif
},
get: function settingsGet(name, defaultValue) {
@ -351,9 +296,10 @@ var PDFView = {
set page(val) {
var pages = this.pages;
var input = document.getElementById('pageNumber');
var event = document.createEvent('UIEvents');
event.initUIEvent('pagechange', false, false, window, 0);
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;
@ -361,8 +307,6 @@ var PDFView = {
pages[val - 1].updateStats();
currentPageNumber = val;
var event = document.createEvent('UIEvents');
event.initUIEvent('pagechange', false, false, window, 0);
event.pageNumber = val;
window.dispatchEvent(event);
@ -486,52 +430,54 @@ var PDFView = {
}
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');
}
//#if !(FIREFOX || MOZCENTRAL)
url += '#pdfjs.action=download';
window.open(url, '_parent');
//#else
// // 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 occurred try downloading with just the url.
// );
//#endif
},
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();
});
//#if !(FIREFOX || MOZCENTRAL)
// return;
//#else
// // 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();
// });
//#endif
},
navigateTo: function pdfViewNavigateTo(dest) {
@ -583,9 +529,11 @@ var PDFView = {
* @param {String} anchor The anchor hash include the #.
*/
getAnchorUrl: function getAnchorUrl(anchor) {
if (PDFJS.isFirefoxExtension)
return this.url.split('#')[0] + anchor;
//#if !(FIREFOX || MOZCENTRAL)
return anchor;
//#else
// return this.url.split('#')[0] + anchor;
//#endif
},
/**
@ -619,11 +567,7 @@ var PDFView = {
}
}
}
if (PDFJS.isFirefoxExtension) {
console.error(message + '\n' + moreInfoText);
this.fallback();
return;
}
//#if !(FIREFOX || MOZCENTRAL)
var errorWrapper = document.getElementById('errorWrapper');
errorWrapper.removeAttribute('hidden');
@ -653,6 +597,10 @@ var PDFView = {
errorMoreInfo.value = moreInfoText;
errorMoreInfo.rows = moreInfoText.split('\n').length - 1;
//#else
// console.error(message + '\n' + moreInfoText);
// this.fallback();
//#endif
},
progress: function pdfViewProgress(level) {
@ -811,7 +759,7 @@ var PDFView = {
}
},
getHighestPriority: function pdfViewGetHighestPriority(visibleViews, views,
getHighestPriority: function pdfViewGetHighestPriority(visible, views,
scrolledDown) {
// The state has changed figure out which page has the highest priority to
// render next (if any).
@ -819,9 +767,10 @@ var PDFView = {
// 1 visible pages
// 2 if last scrolled down page after the visible pages
// 2 if last scrolled up page before the visible pages
var visibleViews = visible.views;
var numVisible = visibleViews.length;
if (numVisible === 0) {
info('No visible views.');
return false;
}
for (var i = 0; i < numVisible; ++i) {
@ -832,13 +781,12 @@ var PDFView = {
// All the visible views have rendered, try to render next/previous pages.
if (scrolledDown) {
var lastVisible = visibleViews[visibleViews.length - 1];
var nextPageIndex = lastVisible.id;
var nextPageIndex = visible.last.id;
// ID's start at 1 so no need to add 1.
if (views[nextPageIndex] && !this.isViewFinished(views[nextPageIndex]))
return views[nextPageIndex];
} else {
var previousPageIndex = visibleViews[0].id - 2;
var previousPageIndex = visible.first.id - 2;
if (views[previousPageIndex] &&
!this.isViewFinished(views[previousPageIndex]))
return views[previousPageIndex];
@ -876,14 +824,14 @@ var PDFView = {
search: function pdfViewStartSearch() {
// Limit this function to run every <SEARCH_TIMEOUT>ms.
var SEARCH_TIMEOUT = 250;
var lastSeach = this.lastSearch;
var lastSearch = this.lastSearch;
var now = Date.now();
if (lastSeach && (now - lastSeach) < SEARCH_TIMEOUT) {
if (lastSearch && (now - lastSearch) < SEARCH_TIMEOUT) {
if (!this.searchTimer) {
this.searchTimer = setTimeout(function resumeSearch() {
PDFView.search();
},
SEARCH_TIMEOUT - (now - lastSeach)
SEARCH_TIMEOUT - (now - lastSearch)
);
}
return;
@ -952,7 +900,6 @@ var PDFView = {
}
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
@ -968,9 +915,9 @@ var PDFView = {
(zoomArgs[2] | 0), zoomArg];
var currentPage = this.pages[pageNumber - 1];
currentPage.scrollIntoView(dest);
} else
this.page = params.page; // simple page
return;
} else {
this.page = pageNumber; // simple page
}
}
} else if (/^\d+$/.test(hash)) // page number
this.page = hash;
@ -1041,13 +988,13 @@ var PDFView = {
extractPageText(pageIndex + 1);
}
);
};
}
extractPageText(0);
},
getVisiblePages: function pdfViewGetVisiblePages() {
return this.getVisibleElements(this.container,
this.pages);
this.pages, true);
},
getVisibleThumbs: function pdfViewGetVisibleThumbs() {
@ -1056,11 +1003,12 @@ var PDFView = {
},
// Generic helper to find out what elements are visible within a scroll pane.
getVisibleElements: function pdfViewGetVisibleElements(scrollEl, views) {
getVisibleElements: function pdfViewGetVisibleElements(
scrollEl, views, sortByVisibility) {
var currentHeight = 0, view;
var top = scrollEl.scrollTop;
for (var i = 1; i <= views.length; ++i) {
for (var i = 1, ii = views.length; i <= ii; ++i) {
view = views[i - 1];
currentHeight = view.el.offsetTop;
if (currentHeight + view.el.clientHeight > top)
@ -1078,19 +1026,38 @@ var PDFView = {
view: currentPage
});
return visible;
return { first: currentPage, last: currentPage, views: visible};
}
var bottom = top + scrollEl.clientHeight;
for (; i <= views.length && currentHeight < bottom; ++i) {
var nextHeight, hidden, percent, viewHeight;
for (; i <= ii && currentHeight < bottom; ++i) {
view = views[i - 1];
viewHeight = view.el.clientHeight;
currentHeight = view.el.offsetTop;
nextHeight = currentHeight + viewHeight;
hidden = Math.max(0, top - currentHeight) +
Math.max(0, nextHeight - bottom);
percent = Math.floor((viewHeight - hidden) * 100.0 / viewHeight);
visible.push({ id: view.id, y: currentHeight,
view: view });
currentHeight += view.el.clientHeight;
view: view, percent: percent });
currentHeight = nextHeight;
}
return visible;
var first = visible[0];
var last = visible[visible.length - 1];
if (sortByVisibility) {
visible.sort(function(a, b) {
var pc = a.percent - b.percent;
if (Math.abs(pc) > 0.001)
return -pc;
return a.id - b.id; // ensure stability
});
}
return {first: first, last: last, views: visible};
},
// Helper function to parse query string (e.g. ?param1=value&parm2=...).
@ -1727,13 +1694,13 @@ var CustomStyle = (function CustomStyleClosure() {
//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;
})();
@ -1763,6 +1730,7 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
if (textDivs.length === 0) {
clearInterval(renderTimer);
renderingDone = true;
self.textLayerDiv = textLayerDiv = canvas = ctx = null;
return;
}
var textDiv = textDivs.shift();
@ -1802,7 +1770,7 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
// Resume rendering
renderTimer = setInterval(renderTextLayer, renderInterval);
}, resumeInterval);
}; // textLayerOnScroll
} // textLayerOnScroll
window.addEventListener('scroll', textLayerOnScroll, false);
}; // endLayout
@ -1830,15 +1798,21 @@ document.addEventListener('DOMContentLoaded', 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 !(FIREFOX || MOZCENTRAL)
var file = params.file || kDefaultURL;
//#else
//var file = window.location.toString()
//#endif
if (PDFJS.isFirefoxExtension || !window.File || !window.FileReader ||
!window.FileList || !window.Blob) {
//#if !(FIREFOX || MOZCENTRAL)
if (!window.File || !window.FileReader || !window.FileList || !window.Blob) {
document.getElementById('openFile').setAttribute('hidden', 'true');
} else {
document.getElementById('fileInput').value = null;
}
//#else
//document.getElementById('openFile').setAttribute('hidden', 'true');
//#endif
// Special debugging flags in the hash section of the URL.
var hash = document.location.hash.substring(1);
@ -1847,18 +1821,21 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
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 !(FIREFOX || MOZCENTRAL)
var locale = navigator.language;
if ('locale' in hashParams)
locale = hashParams['locale'];
mozL10n.language.code = locale;
//#endif
if ('disableTextLayer' in hashParams)
PDFJS.disableTextLayer = (hashParams['disableTextLayer'] === 'true');
if ('pdfBug' in hashParams &&
(!PDFJS.isFirefoxExtension || FirefoxCom.requestSync('pdfBugEnabled'))) {
//#if !(FIREFOX || MOZCENTRAL)
if ('pdfBug' in hashParams) {
//#else
//if ('pdfBug' in hashParams && FirefoxCom.requestSync('pdfBugEnabled')) {
//#endif
PDFJS.pdfBug = true;
var pdfBug = hashParams['pdfBug'];
var enabled = pdfBug.split(',');
@ -1866,10 +1843,12 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
PDFBug.init();
}
if (!PDFJS.isFirefoxExtension ||
(PDFJS.isFirefoxExtension && FirefoxCom.requestSync('searchEnabled'))) {
document.querySelector('#viewSearch').classList.remove('hidden');
}
//#if !(FIREFOX || MOZCENTRAL)
//#else
//if (FirefoxCom.requestSync('searchEnabled')) {
// document.querySelector('#viewSearch').classList.remove('hidden');
//}
//#endif
if (!PDFView.supportsPrinting) {
document.getElementById('print').classList.add('hidden');
@ -1907,27 +1886,50 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
PDFView.renderHighestPriority();
});
if (PDFJS.isFirefoxExtension &&
FirefoxCom.requestSync('getLoadingType') == 'passive') {
PDFView.setTitleUsingUrl(file);
PDFView.initPassiveLoading();
} else
PDFView.open(file, 0);
//#if (FIREFOX || MOZCENTRAL)
//if (FirefoxCom.requestSync('getLoadingType') == 'passive') {
// PDFView.setTitleUsingUrl(file);
// PDFView.initPassiveLoading();
//}
//#endif
//#if !B2G
PDFView.open(file, 0);
//#endif
}, true);
function updateViewarea() {
if (!PDFView.initialized)
return;
var visiblePages = PDFView.getVisiblePages();
var visible = PDFView.getVisiblePages();
var visiblePages = visible.views;
PDFView.renderHighestPriority();
var currentId = PDFView.page;
var firstPage = visiblePages[0];
var firstPage = visible.first;
for (var i = 0, ii = visiblePages.length, stillFullyVisible = false;
i < ii; ++i) {
var page = visiblePages[i];
if (page.percent < 100)
break;
if (page.id === PDFView.page) {
stillFullyVisible = true;
break;
}
}
if (!stillFullyVisible) {
currentId = visiblePages[0].id;
}
if (!PDFView.isFullscreen) {
updateViewarea.inProgress = true; // used in "set page"
PDFView.page = firstPage.id;
PDFView.page = currentId;
updateViewarea.inProgress = false;
}
@ -1975,20 +1977,13 @@ window.addEventListener('change', function webViewerChange(evt) {
// 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 buffer = evt.target.result;
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);
fileReader.readAsArrayBuffer(file);
PDFView.setTitleUsingUrl(file.name);
// URL does not reflect proper document location - hiding some icons.
@ -2046,13 +2041,13 @@ window.addEventListener('pagechange', function pagechange(evt) {
var thumbnail = document.getElementById('thumbnailContainer' + page);
thumbnail.classList.add('selected');
var visibleThumbs = PDFView.getVisibleThumbs();
var numVisibleThumbs = visibleThumbs.length;
var numVisibleThumbs = visibleThumbs.views.length;
// If the thumbnail isn't currently visible scroll it into view.
if (numVisibleThumbs > 0) {
var first = visibleThumbs[0].id;
var first = visibleThumbs.first.id;
// Account for only one thumbnail being visible.
var last = numVisibleThumbs > 1 ?
visibleThumbs[numVisibleThumbs - 1].id : first;
visibleThumbs.last.id : first;
if (page <= first || page >= last)
thumbnail.scrollIntoView();
}
@ -2171,3 +2166,21 @@ window.addEventListener('afterprint', function afterPrint(evt) {
window.addEventListener('mozfullscreenchange', fullscreenChange, false);
window.addEventListener('webkitfullscreenchange', fullscreenChange, false);
})();
//#if B2G
//window.navigator.mozSetMessageHandler('activity', function(activity) {
// var url = activity.source.data.url;
// // Temporarily get the data here since the cross domain xhr is broken in
// // the worker currently, see bug 761227.
// var params = {
// url: url,
// error: function(e) {
// PDFView.error(mozL10n.get('loading_error', null,
// 'An error occurred while loading the PDF.'), e);
// }
// };
// PDFJS.getPdf(params, function successCallback(data) {
// PDFView.open(data, 0);
// });
//});
//#endif