Bug 995431 - Update pdf.js to version 1.0.2. r=yury

This commit is contained in:
Brendan Dahl 2014-04-11 14:26:11 -07:00
parent 3776ff61fb
commit e9aae6856c
8 changed files with 3517 additions and 2368 deletions

View File

@ -1,4 +1,4 @@
This is the pdf.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 0.8.1334
Current extension version is: 1.0.2

View File

@ -64,7 +64,9 @@ function initializeDefaultPreferences() {
var DEFAULT_PREFERENCES = {
showPreviousViewOnLoad: true,
defaultZoomValue: '',
ifAvailableShowOutlineOnLoad: false
ifAvailableShowOutlineOnLoad: false,
enableHandToolOnLoad: false,
enableWebGL: false
};
@ -134,15 +136,19 @@ let PdfJs = {
},
_migrate: function migrate() {
const VERSION = 1;
const VERSION = 2;
var currentVersion = getIntPref(PREF_MIGRATION_VERSION, 0);
if (currentVersion >= VERSION) {
return;
}
// Make pdf.js the default pdf viewer on the first migration.
if (currentVersion < 2) {
if (currentVersion < 1) {
this._becomeHandler();
}
if (currentVersion < 2) {
// cleaning up of unused database preference (see #3994)
Services.prefs.clearUserPref(PREF_PREFIX + '.database');
}
Services.prefs.setIntPref(PREF_MIGRATION_VERSION, VERSION);
},

View File

@ -32,7 +32,6 @@ const PDFJS_EVENT_ID = 'pdf.js.message';
const PDF_CONTENT_TYPE = 'application/pdf';
const PREF_PREFIX = 'pdfjs';
const PDF_VIEWER_WEB_PAGE = 'resource://pdf.js/web/viewer.html';
const MAX_DATABASE_LENGTH = 4096;
const MAX_NUMBER_OF_PREFS = 50;
const MAX_STRING_PREF_LENGTH = 128;
@ -295,19 +294,6 @@ ChromeActions.prototype = {
channel.asyncOpen(listener, null);
});
},
setDatabase: function(data) {
if (this.isInPrivateBrowsing())
return;
// Protect against something sending tons of data to setDatabase.
if (data.length > MAX_DATABASE_LENGTH)
return;
setStringPref(PREF_PREFIX + '.database', data);
},
getDatabase: function() {
if (this.isInPrivateBrowsing())
return '{}';
return getStringPref(PREF_PREFIX + '.database', '{}');
},
getLocale: function() {
return getStringPref('general.useragent.locale', 'en-US');
},
@ -452,7 +438,7 @@ ChromeActions.prototype = {
getChromeWindow(this.domWindow).gFindBar
.updateControlState(result, findPrevious);
},
setPreferences: function(prefs) {
setPreferences: function(prefs, sendResponse) {
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
var numberOfPrefs = 0;
var prefValue, prefName;
@ -483,8 +469,11 @@ ChromeActions.prototype = {
break;
}
}
if (sendResponse) {
sendResponse(true);
}
},
getPreferences: function(prefs) {
getPreferences: function(prefs, sendResponse) {
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
var currentPrefs = {}, numberOfPrefs = 0;
var prefValue, prefName;
@ -510,7 +499,11 @@ ChromeActions.prototype = {
break;
}
}
return JSON.stringify(currentPrefs);
if (sendResponse) {
sendResponse(JSON.stringify(currentPrefs));
} else {
return JSON.stringify(currentPrefs);
}
}
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -211,10 +211,11 @@ var StepperManager = (function StepperManagerClosure() {
return stepper;
},
selectStepper: function selectStepper(pageIndex, selectPanel) {
var i;
if (selectPanel) {
this.manager.selectPanel(this);
}
for (var i = 0; i < steppers.length; ++i) {
for (i = 0; i < steppers.length; ++i) {
var stepper = steppers[i];
if (stepper.pageIndex == pageIndex) {
stepper.panel.removeAttribute('hidden');
@ -223,7 +224,7 @@ var StepperManager = (function StepperManagerClosure() {
}
}
var options = stepperChooser.options;
for (var i = 0; i < options.length; ++i) {
for (i = 0; i < options.length; ++i) {
var option = options[i];
option.selected = option.value == pageIndex;
}
@ -344,7 +345,7 @@ var Stepper = (function StepperClosure() {
var self = this;
var chunk = document.createDocumentFragment();
var operatorsToDisplay = Math.min(MAX_OPERATORS_COUNT,
operatorList.fnArray.length);
operatorList.fnArray.length);
for (var i = this.operatorListIdx; i < operatorsToDisplay; i++) {
var line = c('tr');
line.className = 'line';
@ -369,7 +370,7 @@ var Stepper = (function StepperClosure() {
if (fn in glyphCommands) {
var glyphIndex = glyphCommands[fn];
var glyphs = args[glyphIndex];
var decArgs = args.slice();
decArgs = args.slice();
var newArg;
if (fn === 'showSpacedText') {
newArg = [];

View File

@ -67,10 +67,12 @@ select {
:-moz-full-screen .page {
margin-bottom: 100%;
border: 0;
}
:fullscreen .page {
margin-bottom: 100%;
border: 0;
}
:-moz-full-screen a:not(.internalLink) {
@ -1187,7 +1189,6 @@ canvas {
.textLayer > div {
color: transparent;
position: absolute;
line-height: 1;
white-space: pre;
cursor: text;
}
@ -1305,6 +1306,9 @@ canvas {
background-color: hsla(0,0%,0%,.2);
z-index: 10000;
}
#overlayContainer > * {
overflow: auto;
}
#promptContainer {
display: table-cell;

View File

@ -309,49 +309,99 @@ var Cache = function cacheCache(size) {
var DEFAULT_PREFERENCES = {
showPreviousViewOnLoad: true,
defaultZoomValue: '',
ifAvailableShowOutlineOnLoad: false
ifAvailableShowOutlineOnLoad: false,
enableHandToolOnLoad: false,
enableWebGL: false
};
var Preferences = (function PreferencesClosure() {
function Preferences() {
this.prefs = {};
this.isInitializedPromiseResolved = false;
this.initializedPromise = this.readFromStorage(DEFAULT_PREFERENCES).then(
function(prefObj) {
this.isInitializedPromiseResolved = true;
/**
* Preferences - Utility for storing persistent settings.
* Used for settings that should be applied to all opened documents,
* or every time the viewer is loaded.
*/
var Preferences = {
prefs: Object.create(DEFAULT_PREFERENCES),
isInitializedPromiseResolved: false,
initializedPromise: null,
/**
* Initialize and fetch the current preference values from storage.
* @return {Promise} A promise that is resolved when the preferences
* have been initialized.
*/
initialize: function preferencesInitialize() {
return this.initializedPromise =
this._readFromStorage(DEFAULT_PREFERENCES).then(function(prefObj) {
this.isInitializedPromiseResolved = true;
if (prefObj) {
this.prefs = prefObj;
}
}.bind(this));
},
/**
* Stub function for writing preferences to storage.
* NOTE: This should be overridden by a build-specific function defined below.
* @param {Object} prefObj The preferences that should be written to storage.
* @return {Promise} A promise that is resolved when the preference values
* have been written.
*/
_writeToStorage: function preferences_writeToStorage(prefObj) {
return Promise.resolve();
},
/**
* Stub function for reading preferences from storage.
* NOTE: This should be overridden by a build-specific function defined below.
* @param {Object} prefObj The preferences that should be read from storage.
* @return {Promise} A promise that is resolved with an {Object} containing
* the preferences that have been read.
*/
_readFromStorage: function preferences_readFromStorage(prefObj) {
return Promise.resolve();
},
/**
* Reset the preferences to their default values and update storage.
* @return {Promise} A promise that is resolved when the preference values
* have been reset.
*/
reset: function preferencesReset() {
return this.initializedPromise.then(function() {
this.prefs = Object.create(DEFAULT_PREFERENCES);
return this._writeToStorage(DEFAULT_PREFERENCES);
}.bind(this));
},
/**
* Replace the current preference values with the ones from storage.
* @return {Promise} A promise that is resolved when the preference values
* have been updated.
*/
reload: function preferencesReload() {
return this.initializedPromise.then(function () {
this._readFromStorage(DEFAULT_PREFERENCES).then(function(prefObj) {
if (prefObj) {
this.prefs = prefObj;
}
}.bind(this));
}
}.bind(this));
},
Preferences.prototype = {
writeToStorage: function Preferences_writeToStorage(prefObj) {
return;
},
readFromStorage: function Preferences_readFromStorage(prefObj) {
var readFromStoragePromise = Promise.resolve();
return readFromStoragePromise;
},
reset: function Preferences_reset() {
if (this.isInitializedPromiseResolved) {
this.prefs = {};
this.writeToStorage(DEFAULT_PREFERENCES);
}
},
set: function Preferences_set(name, value) {
if (!this.isInitializedPromiseResolved) {
return;
} else if (DEFAULT_PREFERENCES[name] === undefined) {
console.error('Preferences_set: \'' + name + '\' is undefined.');
return;
/**
* Set the value of a preference.
* @param {string} name The name of the preference that should be changed.
* @param {boolean|number|string} value The new value of the preference.
* @return {Promise} A promise that is resolved when the value has been set,
* provided that the preference exists and the types match.
*/
set: function preferencesSet(name, value) {
return this.initializedPromise.then(function () {
if (DEFAULT_PREFERENCES[name] === undefined) {
throw new Error('preferencesSet: \'' + name + '\' is undefined.');
} else if (value === undefined) {
console.error('Preferences_set: no value is specified.');
return;
throw new Error('preferencesSet: no value is specified.');
}
var valueType = typeof value;
var defaultType = typeof DEFAULT_PREFERENCES[name];
@ -360,40 +410,43 @@ var Preferences = (function PreferencesClosure() {
if (valueType === 'number' && defaultType === 'string') {
value = value.toString();
} else {
console.error('Preferences_set: \'' + value + '\' is a \"' +
valueType + '\", expected a \"' + defaultType + '\".');
return;
throw new Error('Preferences_set: \'' + value + '\' is a \"' +
valueType + '\", expected \"' + defaultType + '\".');
}
} else {
if (valueType === 'number' && (value | 0) !== value) {
console.error('Preferences_set: \'' + value +
'\' must be an \"integer\".');
return;
throw new Error('Preferences_set: \'' + value +
'\' must be an \"integer\".');
}
}
this.prefs[name] = value;
this.writeToStorage(this.prefs);
},
return this._writeToStorage(this.prefs);
}.bind(this));
},
get: function Preferences_get(name) {
var defaultPref = DEFAULT_PREFERENCES[name];
/**
* Get the value of a preference.
* @param {string} name The name of the preference whose value is requested.
* @return {Promise} A promise that is resolved with a {boolean|number|string}
* containing the value of the preference.
*/
get: function preferencesGet(name) {
return this.initializedPromise.then(function () {
var defaultValue = DEFAULT_PREFERENCES[name];
if (defaultPref === undefined) {
console.error('Preferences_get: \'' + name + '\' is undefined.');
return;
} else if (this.isInitializedPromiseResolved) {
var pref = this.prefs[name];
if (defaultValue === undefined) {
throw new Error('preferencesGet: \'' + name + '\' is undefined.');
} else {
var prefValue = this.prefs[name];
if (pref !== undefined) {
return pref;
if (prefValue !== undefined) {
return prefValue;
}
}
return defaultPref;
}
};
return Preferences;
})();
return defaultValue;
}.bind(this));
}
};
@ -488,17 +541,19 @@ var DownloadManager = (function DownloadManagerClosure() {
return DownloadManager;
})();
Preferences.prototype.writeToStorage = function(prefObj) {
FirefoxCom.requestSync('setPreferences', prefObj);
Preferences._writeToStorage = function (prefObj) {
return new Promise(function (resolve) {
FirefoxCom.request('setPreferences', prefObj, resolve);
});
};
Preferences.prototype.readFromStorage = function(prefObj) {
var readFromStoragePromise = new Promise(function (resolve) {
var readPrefs = JSON.parse(FirefoxCom.requestSync('getPreferences',
prefObj));
resolve(readPrefs);
Preferences._readFromStorage = function (prefObj) {
return new Promise(function (resolve) {
FirefoxCom.request('getPreferences', prefObj, function (prefStr) {
var readPrefs = JSON.parse(prefStr);
resolve(readPrefs);
});
});
return readFromStoragePromise;
};
@ -513,7 +568,7 @@ var currentPageNumber = 1;
*
* The way that the view parameters are stored depends on how PDF.js is built,
* for 'node make <flag>' the following cases exist:
* - FIREFOX or MOZCENTRAL - uses about:config.
* - FIREFOX or MOZCENTRAL - uses sessionStorage.
* - B2G - uses asyncStorage.
* - GENERIC or CHROME - uses localStorage, if it is available.
*/
@ -533,7 +588,7 @@ var ViewHistory = (function ViewHistoryClosure() {
}).bind(this);
resolvePromise(FirefoxCom.requestSync('getDatabase', null));
resolvePromise(sessionStorage.getItem('pdfjsHistory'));
}
@ -570,7 +625,7 @@ var ViewHistory = (function ViewHistoryClosure() {
var database = JSON.stringify(this.database);
FirefoxCom.requestSync('setDatabase', database);
sessionStorage.setItem('pdfjsHistory',database);
},
@ -871,11 +926,12 @@ var PDFFindController = {
var self = this;
function extractPageText(pageIndex) {
self.pdfPageSource.pages[pageIndex].getTextContent().then(
function textContentResolved(bidiTexts) {
function textContentResolved(textContent) {
var textItems = textContent.items;
var str = '';
for (var i = 0; i < bidiTexts.length; i++) {
str += bidiTexts[i].str;
for (var i = 0; i < textItems.length; i++) {
str += textItems[i].str;
}
// Store the pageContent as a string.
@ -1778,11 +1834,9 @@ var PresentationMode = {
// Presentation Mode, by waiting until fullscreen mode is disabled.
// Note: This is only necessary in non-Mozilla browsers.
setTimeout(function exitPresentationModeTimeout() {
this.active = false;
PDFView.setScale(this.args.previousScale);
PDFView.page = page;
// Keep Presentation Mode active until the page is scrolled into view,
// to prevent issues in non-Mozilla browsers.
this.active = false;
this.args = null;
}.bind(this), 0);
@ -2110,8 +2164,15 @@ var HandTool = {
});
if (toggleHandTool) {
toggleHandTool.addEventListener('click', this.toggle.bind(this), false);
window.addEventListener('localized', function (evt) {
Preferences.get('enableHandToolOnLoad').then(function (prefValue) {
if (prefValue) {
this.handTool.activate();
}
}.bind(this));
}.bind(this));
}
// TODO: Read global prefs and call this.handTool.activate() if needed.
},
toggle: function handToolToggle() {
@ -2177,6 +2238,10 @@ var DocumentProperties = {
options.closeButton.addEventListener('click', this.hide.bind(this));
}
this.dataAvailablePromise = new Promise(function (resolve) {
this.resolveDataAvailable = resolve;
}.bind(this));
// Bind the event listener for the Esc key (to close the dialog).
window.addEventListener('keydown',
function (e) {
@ -2187,44 +2252,51 @@ var DocumentProperties = {
},
getProperties: function documentPropertiesGetProperties() {
var self = this;
if (!this.visible) {
// If the dialog was closed before dataAvailablePromise was resolved,
// don't bother updating the properties.
return;
}
// Get the file name.
this.fileName = getPDFFileNameFromURL(PDFView.url);
// Get the file size.
PDFView.pdfDocument.getDownloadInfo().then(function(data) {
self.setFileSize(data.length);
});
this.setFileSize(data.length);
this.updateUI(this.fileSizeField, this.fileSize);
}.bind(this));
// Get the other document properties.
PDFView.pdfDocument.getMetadata().then(function(data) {
var fields = [
{ field: self.fileNameField, content: self.fileName },
{ field: self.fileSizeField, content: self.fileSize },
{ field: self.titleField, content: data.info.Title },
{ field: self.authorField, content: data.info.Author },
{ field: self.subjectField, content: data.info.Subject },
{ field: self.keywordsField, content: data.info.Keywords },
{ field: self.creationDateField,
content: self.parseDate(data.info.CreationDate) },
{ field: self.modificationDateField,
content: self.parseDate(data.info.ModDate) },
{ field: self.creatorField, content: data.info.Creator },
{ field: self.producerField, content: data.info.Producer },
{ field: self.versionField, content: data.info.PDFFormatVersion },
{ field: self.pageCountField, content: PDFView.pdfDocument.numPages }
{ field: this.fileNameField, content: this.fileName },
// The fileSize field is updated once getDownloadInfo is resolved.
{ field: this.titleField, content: data.info.Title },
{ field: this.authorField, content: data.info.Author },
{ field: this.subjectField, content: data.info.Subject },
{ field: this.keywordsField, content: data.info.Keywords },
{ field: this.creationDateField,
content: this.parseDate(data.info.CreationDate) },
{ field: this.modificationDateField,
content: this.parseDate(data.info.ModDate) },
{ field: this.creatorField, content: data.info.Creator },
{ field: this.producerField, content: data.info.Producer },
{ field: this.versionField, content: data.info.PDFFormatVersion },
{ field: this.pageCountField, content: PDFView.pdfDocument.numPages }
];
// Show the properties in the dialog.
for (var item in fields) {
var element = fields[item];
if (element.field && element.content !== undefined &&
element.content !== '') {
element.field.textContent = element.content;
}
this.updateUI(element.field, element.content);
}
});
}.bind(this));
},
updateUI: function documentPropertiesUpdateUI(field, content) {
if (field && content !== undefined && content !== '') {
field.textContent = content;
}
},
setFileSize: function documentPropertiesSetFileSize(fileSize) {
@ -2249,7 +2321,10 @@ var DocumentProperties = {
this.visible = true;
this.overlayContainer.classList.remove('hidden');
this.overlayContainer.lastElementChild.classList.remove('hidden');
this.getProperties();
this.dataAvailablePromise.then(function () {
this.getProperties();
}.bind(this));
},
hide: function documentPropertiesClose() {
@ -2347,6 +2422,8 @@ var PDFView = {
this.watchScroll(thumbnailContainer, this.thumbnailViewScroll,
this.renderHighestPriority.bind(this));
Preferences.initialize();
PDFFindBar.initialize({
bar: document.getElementById('findbar'),
toggleButton: document.getElementById('viewFind'),
@ -2421,10 +2498,20 @@ var PDFView = {
pageCountField: document.getElementById('pageCountField')
});
this.initialized = true;
container.addEventListener('scroll', function() {
self.lastScroll = Date.now();
}, false);
var initializedPromise = Promise.all([
Preferences.get('enableWebGL').then(function (value) {
PDFJS.disableWebGL = !value;
})
// TODO move more preferences and other async stuff here
]);
return initializedPromise.then(function () {
PDFView.initialized = true;
});
},
getPage: function pdfViewGetPage(n) {
@ -2490,9 +2577,11 @@ var PDFView = {
if (!currentPage) {
return;
}
var pageWidthScale = (this.container.clientWidth - SCROLLBAR_PADDING) /
var hPadding = PresentationMode.active ? 0 : SCROLLBAR_PADDING;
var vPadding = PresentationMode.active ? 0 : VERTICAL_PADDING;
var pageWidthScale = (this.container.clientWidth - hPadding) /
currentPage.width * currentPage.scale;
var pageHeightScale = (this.container.clientHeight - VERTICAL_PADDING) /
var pageHeightScale = (this.container.clientHeight - vPadding) /
currentPage.height * currentPage.scale;
switch (value) {
case 'page-actual':
@ -2774,6 +2863,9 @@ var PDFView = {
pdfDataRangeTransport, args) {
if (this.pdfDocument) {
this.close();
// Reload the preferences if a document was previously opened.
Preferences.reload();
}
var parameters = {password: password};
@ -2791,6 +2883,8 @@ var PDFView = {
var self = this;
self.loading = true;
self.downloadComplete = false;
var passwordNeeded = function passwordNeeded(updatePassword, reason) {
PasswordPrompt.updatePassword = updatePassword;
PasswordPrompt.reason = reason;
@ -2813,13 +2907,13 @@ var PDFView = {
if (exception && exception.name === 'InvalidPDFException') {
// change error message also for other builds
var loadingErrorMessage = mozL10n.get('invalid_file_error', null,
loadingErrorMessage = mozL10n.get('invalid_file_error', null,
'Invalid or corrupted PDF file.');
}
if (exception && exception.name === 'MissingPDFException') {
// special message for missing PDF's
var loadingErrorMessage = mozL10n.get('missing_file_error', null,
loadingErrorMessage = mozL10n.get('missing_file_error', null,
'Missing PDF file.');
}
@ -2834,7 +2928,7 @@ var PDFView = {
},
download: function pdfViewDownload() {
function noData() {
function downloadByUrl() {
downloadManager.downloadUrl(url, filename);
}
@ -2848,7 +2942,12 @@ var PDFView = {
};
if (!this.pdfDocument) { // the PDF is not ready yet
noData();
downloadByUrl();
return;
}
if (!this.downloadComplete) { // the PDF is still downloading
downloadByUrl();
return;
}
@ -2857,8 +2956,8 @@ var PDFView = {
var blob = PDFJS.createBlob(data, 'application/pdf');
downloadManager.download(blob, url, filename);
},
noData // Error occurred try downloading with just the url.
).then(null, noData);
downloadByUrl // Error occurred try downloading with just the url.
).then(null, downloadByUrl);
},
fallback: function pdfViewFallback(featureId) {
@ -3026,7 +3125,10 @@ var PDFView = {
this.pdfDocument = pdfDocument;
DocumentProperties.resolveDataAvailable();
pdfDocument.getDownloadInfo().then(function() {
self.downloadComplete = true;
PDFView.loadingBar.hide();
var outerContainer = document.getElementById('outerContainer');
outerContainer.classList.remove('loadingInProgress');
@ -3039,7 +3141,6 @@ var PDFView = {
mozL10n.get('page_of', {pageCount: pagesCount}, 'of {{pageCount}}');
document.getElementById('pageNumber').max = pagesCount;
var prefs = PDFView.prefs = new Preferences();
PDFView.documentFingerprint = id;
var store = PDFView.store = new ViewHistory(id);
@ -3108,15 +3209,26 @@ var PDFView = {
PDFView.loadingBar.setWidth(container);
PDFFindController.resolveFirstPage();
// Initialize the browsing history.
PDFHistory.initialize(self.documentFingerprint);
});
var prefsPromise = prefs.initializedPromise;
var storePromise = store.initializedPromise;
Promise.all([firstPagePromise, prefsPromise, storePromise]).
then(function() {
var showPreviousViewOnLoad = prefs.get('showPreviousViewOnLoad');
var defaultZoomValue = prefs.get('defaultZoomValue');
// Fetch the necessary preference values.
var showPreviousViewOnLoad;
var showPreviousViewOnLoadPromise =
Preferences.get('showPreviousViewOnLoad').then(function (prefValue) {
showPreviousViewOnLoad = prefValue;
});
var defaultZoomValue;
var defaultZoomValuePromise =
Preferences.get('defaultZoomValue').then(function (prefValue) {
defaultZoomValue = prefValue;
});
var storePromise = store.initializedPromise;
Promise.all([firstPagePromise, storePromise, showPreviousViewOnLoadPromise,
defaultZoomValuePromise]).then(function resolved() {
var storedHash = null;
if (showPreviousViewOnLoad && store.get('exists', false)) {
var pageNum = store.get('page', '1');
@ -3129,9 +3241,6 @@ var PDFView = {
} else if (defaultZoomValue) {
storedHash = 'page=1&zoom=' + defaultZoomValue;
}
// Initialize the browsing history.
PDFHistory.initialize(self.documentFingerprint);
self.setInitialView(storedHash, scale);
// Make all navigation keys work on document load,
@ -3140,6 +3249,12 @@ var PDFView = {
self.container.focus();
self.container.blur();
}
}, function rejected(errorMsg) {
console.error(errorMsg);
firstPagePromise.then(function () {
self.setInitialView(null, scale);
});
});
pagesPromise.then(function() {
@ -3178,11 +3293,16 @@ var PDFView = {
self.outline = new DocumentOutlineView(outline);
document.getElementById('viewOutline').disabled = !outline;
if (outline && prefs.get('ifAvailableShowOutlineOnLoad')) {
if (!self.sidebarOpen) {
document.getElementById('sidebarToggle').click();
}
self.switchSidebarView('outline');
if (outline) {
Preferences.get('ifAvailableShowOutlineOnLoad').then(
function (prefValue) {
if (prefValue) {
if (!self.sidebarOpen) {
document.getElementById('sidebarToggle').click();
}
self.switchSidebarView('outline');
}
});
}
});
});
@ -3194,9 +3314,10 @@ var PDFView = {
// Provides some basic debug information
console.log('PDF ' + pdfDocument.fingerprint + ' [' +
info.PDFFormatVersion + ' ' + (info.Producer || '-') +
' / ' + (info.Creator || '-') + ']' +
(PDFJS.version ? ' (PDF.js: ' + PDFJS.version + ')' : ''));
info.PDFFormatVersion + ' ' + (info.Producer || '-').trim() +
' / ' + (info.Creator || '-').trim() + ']' +
' (PDF.js: ' + (PDFJS.version || '-') +
(!PDFJS.disableWebGL ? ' [WebGL]' : '') + ')');
var pdfTitle;
if (metadata && metadata.has('dc:title')) {
@ -3568,10 +3689,11 @@ var PDFView = {
}
var alertNotReady = false;
var i, ii;
if (!this.pages.length) {
alertNotReady = true;
} else {
for (var i = 0, ii = this.pages.length; i < ii; ++i) {
for (i = 0, ii = this.pages.length; i < ii; ++i) {
if (!this.pages[i].pdfPage) {
alertNotReady = true;
break;
@ -3587,7 +3709,7 @@ var PDFView = {
var body = document.querySelector('body');
body.setAttribute('data-mozPrintCallback', true);
for (var i = 0, ii = this.pages.length; i < ii; ++i) {
for (i = 0, ii = this.pages.length; i < ii; ++i) {
this.pages[i].beforePrint();
}
},
@ -3601,14 +3723,15 @@ var PDFView = {
rotatePages: function pdfViewRotatePages(delta) {
var currentPage = this.pages[this.page - 1];
var i, l;
this.pageRotation = (this.pageRotation + 360 + delta) % 360;
for (var i = 0, l = this.pages.length; i < l; i++) {
for (i = 0, l = this.pages.length; i < l; i++) {
var page = this.pages[i];
page.update(page.scale, this.pageRotation);
}
for (var i = 0, l = this.thumbnails.length; i < l; i++) {
for (i = 0, l = this.thumbnails.length; i < l; i++) {
var thumb = this.thumbnails[i];
thumb.update(this.pageRotation);
}
@ -4019,7 +4142,7 @@ var PageView = function pageView(container, id, scale,
var x = 0, y = 0;
var width = 0, height = 0, widthScale, heightScale;
var changeOrientation = !!(this.rotation % 180);
var changeOrientation = (this.rotation % 180 === 0 ? false : true);
var pageWidth = (changeOrientation ? this.height : this.width) /
this.scale / CSS_UNITS;
var pageHeight = (changeOrientation ? this.width : this.height) /
@ -4156,8 +4279,8 @@ var PageView = function pageView(container, id, scale,
if (!PDFJS.disableTextLayer) {
textLayerDiv = document.createElement('div');
textLayerDiv.className = 'textLayer';
textLayerDiv.style.width = canvas.width + 'px';
textLayerDiv.style.height = canvas.height + 'px';
textLayerDiv.style.width = canvas.style.width;
textLayerDiv.style.height = canvas.style.height;
div.appendChild(textLayerDiv);
}
var textLayer = this.textLayer =
@ -4174,14 +4297,6 @@ var PageView = function pageView(container, id, scale,
if (outputScale.scaled) {
ctx.scale(outputScale.sx, outputScale.sy);
}
if (outputScale.scaled && textLayerDiv) {
var cssScale = 'scale(' + (1 / outputScale.sx) + ', ' +
(1 / outputScale.sy) + ')';
CustomStyle.setProp('transform' , textLayerDiv, cssScale);
CustomStyle.setProp('transformOrigin' , textLayerDiv, '0% 0%');
textLayerDiv.dataset._scaleX = outputScale.sx;
textLayerDiv.dataset._scaleY = outputScale.sy;
}
// Rendering area
@ -4267,20 +4382,19 @@ var PageView = function pageView(container, id, scale,
this.renderTask.promise.then(
function pdfPageRenderCallback() {
pageViewDrawCallback(null);
if (textLayer) {
self.getTextContent().then(
function textContentResolved(textContent) {
textLayer.setTextContent(textContent);
}
);
}
},
function pdfPageRenderError(error) {
pageViewDrawCallback(error);
}
);
if (textLayer) {
this.getTextContent().then(
function textContentResolved(textContent) {
textLayer.setTextContent(textContent);
}
);
}
setupAnnotations(div, pdfPage, this.viewport);
div.setAttribute('data-loaded', true);
};
@ -4555,6 +4669,7 @@ var TextLayerBuilder = function textLayerBuilder(options) {
this.lastScrollSource = options.lastScrollSource;
this.viewport = options.viewport;
this.isViewerInPresentationMode = options.isViewerInPresentationMode;
this.textDivs = [];
if (typeof PDFFindController === 'undefined') {
window.PDFFindController = null;
@ -4564,16 +4679,6 @@ var TextLayerBuilder = function textLayerBuilder(options) {
this.lastScrollSource = null;
}
this.beginLayout = function textLayerBuilderBeginLayout() {
this.textDivs = [];
this.renderingDone = false;
};
this.endLayout = function textLayerBuilderEndLayout() {
this.layoutDone = true;
this.insertDivContent();
};
this.renderLayer = function textLayerBuilderRenderLayer() {
var textDivs = this.textDivs;
var canvas = document.createElement('canvas');
@ -4633,70 +4738,56 @@ var TextLayerBuilder = function textLayerBuilder(options) {
}
};
this.appendText = function textLayerBuilderAppendText(geom) {
this.appendText = function textLayerBuilderAppendText(geom, styles) {
var style = styles[geom.fontName];
var textDiv = document.createElement('div');
// vScale and hScale already contain the scaling to pixel units
var fontHeight = geom.fontSize * Math.abs(geom.vScale);
textDiv.dataset.canvasWidth = geom.canvasWidth * Math.abs(geom.hScale);
textDiv.dataset.fontName = geom.fontName;
textDiv.dataset.angle = geom.angle * (180 / Math.PI);
textDiv.style.fontSize = fontHeight + 'px';
textDiv.style.fontFamily = geom.fontFamily;
var fontAscent = (geom.ascent ? geom.ascent * fontHeight :
(geom.descent ? (1 + geom.descent) * fontHeight : fontHeight));
textDiv.style.left = (geom.x + (fontAscent * Math.sin(geom.angle))) + 'px';
textDiv.style.top = (geom.y - (fontAscent * Math.cos(geom.angle))) + 'px';
// The content of the div is set in the `setTextContent` function.
this.textDivs.push(textDiv);
};
this.insertDivContent = function textLayerUpdateTextContent() {
// Only set the content of the divs once layout has finished, the content
// for the divs is available and content is not yet set on the divs.
if (!this.layoutDone || this.divContentDone || !this.textContent) {
if (!/\S/.test(geom.str)) {
textDiv.dataset.isWhitespace = true;
return;
}
var tx = PDFJS.Util.transform(this.viewport.transform, geom.transform);
var angle = Math.atan2(tx[1], tx[0]);
if (style.vertical) {
angle += Math.PI / 2;
}
var fontHeight = Math.sqrt((tx[2] * tx[2]) + (tx[3] * tx[3]));
var fontAscent = (style.ascent ? style.ascent * fontHeight :
(style.descent ? (1 + style.descent) * fontHeight : fontHeight));
this.divContentDone = true;
textDiv.style.position = 'absolute';
textDiv.style.left = (tx[4] + (fontAscent * Math.sin(angle))) + 'px';
textDiv.style.top = (tx[5] - (fontAscent * Math.cos(angle))) + 'px';
textDiv.style.fontSize = fontHeight + 'px';
textDiv.style.fontFamily = style.fontFamily;
var textDivs = this.textDivs;
var bidiTexts = this.textContent;
for (var i = 0; i < bidiTexts.length; i++) {
var bidiText = bidiTexts[i];
var textDiv = textDivs[i];
if (!/\S/.test(bidiText.str)) {
textDiv.dataset.isWhitespace = true;
continue;
}
textDiv.textContent = bidiText.str;
// TODO refactor text layer to use text content position
/**
* var arr = this.viewport.convertToViewportPoint(bidiText.x, bidiText.y);
* textDiv.style.left = arr[0] + 'px';
* textDiv.style.top = arr[1] + 'px';
*/
// bidiText.dir may be 'ttb' for vertical texts.
textDiv.dir = bidiText.dir;
textDiv.textContent = geom.str;
textDiv.dataset.fontName = geom.fontName;
textDiv.dataset.angle = angle * (180 / Math.PI);
if (style.vertical) {
textDiv.dataset.canvasWidth = geom.height * this.viewport.scale;
} else {
textDiv.dataset.canvasWidth = geom.width * this.viewport.scale;
}
this.setupRenderLayoutTimer();
};
this.setTextContent = function textLayerBuilderSetTextContent(textContent) {
this.textContent = textContent;
this.insertDivContent();
var textItems = textContent.items;
for (var i = 0; i < textItems.length; i++) {
this.appendText(textItems[i], textContent.styles);
}
this.divContentDone = true;
this.setupRenderLayoutTimer();
};
this.convertMatches = function textLayerBuilderConvertMatches(matches) {
var i = 0;
var iIndex = 0;
var bidiTexts = this.textContent;
var bidiTexts = this.textContent.items;
var end = bidiTexts.length - 1;
var queryLen = (PDFFindController === null ?
0 : PDFFindController.state.query.length);
@ -4755,7 +4846,7 @@ var TextLayerBuilder = function textLayerBuilder(options) {
return;
}
var bidiTexts = this.textContent;
var bidiTexts = this.textContent.items;
var textDivs = this.textDivs;
var prevEnd = null;
var isSelectedPage = (PDFFindController === null ?
@ -4871,7 +4962,7 @@ var TextLayerBuilder = function textLayerBuilder(options) {
// Clear out all matches.
var matches = this.matches;
var textDivs = this.textDivs;
var bidiTexts = this.textContent;
var bidiTexts = this.textContent.items;
var clearedUntilDivIdx = -1;
// Clear out all current matches.
@ -4951,8 +5042,10 @@ var DocumentOutlineView = function documentOutlineView(outline) {
function webViewerLoad(evt) {
PDFView.initialize();
PDFView.initialize().then(webViewerInitialized);
}
function webViewerInitialized() {
var file = window.location.href.split('#')[0];
document.getElementById('openFile').setAttribute('hidden', 'true');
@ -4982,6 +5075,10 @@ function webViewerLoad(evt) {
PDFJS.disableHistory = (hashParams['disableHistory'] === 'true');
}
if ('webgl' in hashParams) {
PDFJS.disableWebGL = (hashParams['webgl'] !== 'true');
}
if ('useOnlyCssZoom' in hashParams) {
USE_ONLY_CSS_ZOOM = (hashParams['useOnlyCssZoom'] === 'true');
}
@ -5135,7 +5232,6 @@ function webViewerLoad(evt) {
if (file) {
PDFView.open(file, 0);
}
}
document.addEventListener('DOMContentLoaded', webViewerLoad, true);