Bug 1148192 - Update pdf.js to version 1.1.24. r=bdahl, r=Mossop

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2015-03-27 17:02:06 -04:00
Родитель 499b1fa2b9
Коммит 89f1889368
13 изменённых файлов: 444 добавлений и 315 удалений

Просмотреть файл

@ -175,4 +175,3 @@
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

Просмотреть файл

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

Просмотреть файл

@ -266,9 +266,9 @@ let PdfJs = {
PdfjsChromeUtils.notifyChildOfSettingsChange();
}
},
/**
* pdf.js is only enabled if it is both selected as the pdf viewer and if the
* pdf.js is only enabled if it is both selected as the pdf viewer and if the
* global switch enabling it is true.
* @return {boolean} Wether or not it's enabled.
*/

Просмотреть файл

@ -63,16 +63,9 @@ function getContainingBrowser(domWindow) {
.chromeEventHandler;
}
function getChromeWindow(domWindow) {
if (PdfjsContentUtils.isRemote) {
return PdfjsContentUtils.getChromeWindow(domWindow);
}
return getContainingBrowser(domWindow).ownerDocument.defaultView;
}
function getFindBar(domWindow) {
if (PdfjsContentUtils.isRemote) {
return PdfjsContentUtils.getFindBar(domWindow);
throw new Error('FindBar is not accessible from the content process.');
}
var browser = getContainingBrowser(domWindow);
try {
@ -163,6 +156,21 @@ function makeContentReadable(obj, window) {
return Cu.cloneInto(obj, window);
}
function createNewChannel(uri, node, principal) {
return NetUtil.newChannel2(uri,
null,
null,
node, // aLoadingNode
principal, // aLoadingPrincipal
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
}
function asyncFetchChannel(channel, callback) {
return NetUtil.asyncFetch2(channel, callback);
}
// PDF data storage
function PdfDataListener(length) {
this.length = length; // less than 0, if length is unknown
@ -241,15 +249,16 @@ ChromeActions.prototype = {
download: function(data, sendResponse) {
var self = this;
var originalUrl = data.originalUrl;
var blobUrl = data.blobUrl || originalUrl;
// The data may not be downloaded so we need just retry getting the pdf with
// the original url.
var originalUri = NetUtil.newURI(data.originalUrl);
var originalUri = NetUtil.newURI(originalUrl);
var filename = data.filename;
if (typeof filename !== 'string' ||
(!/\.pdf$/i.test(filename) && !data.isAttachment)) {
filename = 'document.pdf';
}
var blobUri = data.blobUrl ? NetUtil.newURI(data.blobUrl) : originalUri;
var blobUri = NetUtil.newURI(blobUrl);
var extHelperAppSvc =
Cc['@mozilla.org/uriloader/external-helper-app-service;1'].
getService(Ci.nsIExternalHelperAppService);
@ -257,12 +266,12 @@ ChromeActions.prototype = {
getService(Ci.nsIWindowWatcher).activeWindow;
var docIsPrivate = this.isInPrivateBrowsing();
var netChannel = NetUtil.newChannel(blobUri);
var netChannel = createNewChannel(blobUri, frontWindow.document, null);
if ('nsIPrivateBrowsingChannel' in Ci &&
netChannel instanceof Ci.nsIPrivateBrowsingChannel) {
netChannel.setPrivate(docIsPrivate);
}
NetUtil.asyncFetch(netChannel, function(aInputStream, aResult) {
asyncFetchChannel(netChannel, function(aInputStream, aResult) {
if (!Components.isSuccessCode(aResult)) {
if (sendResponse) {
sendResponse(true);
@ -339,7 +348,13 @@ ChromeActions.prototype = {
if (this.domWindow.frameElement !== null) {
return false;
}
// ... and when the new find events code exists.
// ... and we are in a child process
if (PdfjsContentUtils.isRemote) {
return true;
}
// ... or when the new find events code exists.
var findBar = getFindBar(this.domWindow);
return findBar && ('updateControlState' in findBar);
},
@ -441,7 +456,15 @@ ChromeActions.prototype = {
(findPreviousType !== 'undefined' && findPreviousType !== 'boolean')) {
return;
}
getFindBar(this.domWindow).updateControlState(result, findPrevious);
var winmm = this.domWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.sameTypeRootTreeItem
.QueryInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
winmm.sendAsyncMessage('PDFJS:Parent:updateControlState', data);
},
setPreferences: function(prefs, sendResponse) {
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
@ -746,14 +769,14 @@ RequestListener.prototype.receive = function(event) {
// Forwards events from the eventElement to the contentWindow only if the
// content window matches the currently selected browser window.
function FindEventManager(eventElement, contentWindow, chromeWindow) {
this.types = ['find',
'findagain',
'findhighlightallchange',
'findcasesensitivitychange'];
this.chromeWindow = chromeWindow;
function FindEventManager(contentWindow) {
this.contentWindow = contentWindow;
this.eventElement = eventElement;
this.winmm = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.sameTypeRootTreeItem
.QueryInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
}
FindEventManager.prototype.bind = function() {
@ -763,41 +786,27 @@ FindEventManager.prototype.bind = function() {
}.bind(this);
this.contentWindow.addEventListener('unload', unload);
for (var i = 0; i < this.types.length; i++) {
var type = this.types[i];
this.eventElement.addEventListener(type, this, true);
}
// We cannot directly attach listeners to for the find events
// since the FindBar is in the parent process. Instead we're
// asking the PdfjsChromeUtils to do it for us and forward
// all the find events to us.
this.winmm.sendAsyncMessage('PDFJS:Parent:addEventListener');
this.winmm.addMessageListener('PDFJS:Child:handleEvent', this);
};
FindEventManager.prototype.handleEvent = function(e) {
var chromeWindow = this.chromeWindow;
FindEventManager.prototype.receiveMessage = function(msg) {
var detail = msg.data.detail;
var type = msg.data.type;
var contentWindow = this.contentWindow;
// Only forward the events if they are for our dom window.
if (chromeWindow.gBrowser.selectedBrowser.contentWindow === contentWindow) {
var detail = {
query: e.detail.query,
caseSensitive: e.detail.caseSensitive,
highlightAll: e.detail.highlightAll,
findPrevious: e.detail.findPrevious
};
detail = makeContentReadable(detail, contentWindow);
var forward = contentWindow.document.createEvent('CustomEvent');
forward.initCustomEvent(e.type, true, true, detail);
// Due to restrictions with cpow use, we can't dispatch
// dom events with an urgent message on the stack. So bounce
// this off the main thread to make it async.
Services.tm.mainThread.dispatch(function () {
contentWindow.dispatchEvent(forward);
}, Ci.nsIThread.DISPATCH_NORMAL);
e.preventDefault();
}
detail = makeContentReadable(detail, contentWindow);
var forward = contentWindow.document.createEvent('CustomEvent');
forward.initCustomEvent(type, true, true, detail);
contentWindow.dispatchEvent(forward);
};
FindEventManager.prototype.unbind = function() {
for (var i = 0; i < this.types.length; i++) {
var type = this.types[i];
this.eventElement.removeEventListener(type, this, true);
}
this.winmm.sendAsyncMessage('PDFJS:Parent:removeEventListener');
};
function PdfStreamConverter() {
@ -922,9 +931,8 @@ PdfStreamConverter.prototype = {
.createInstance(Ci.nsIBinaryInputStream);
// Create a new channel that is viewer loaded as a resource.
var ioService = Services.io;
var channel = ioService.newChannel(
PDF_VIEWER_WEB_PAGE, null, null);
var systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
var channel = createNewChannel(PDF_VIEWER_WEB_PAGE, null, systemPrincipal);
var listener = this.listener;
var dataListener = this.dataListener;
@ -957,11 +965,7 @@ PdfStreamConverter.prototype = {
requestListener.receive(event);
}, false, true);
if (actions.supportsIntegratedFind()) {
var chromeWindow = getChromeWindow(domWindow);
var findBar = getFindBar(domWindow);
var findEventManager = new FindEventManager(findBar,
domWindow,
chromeWindow);
var findEventManager = new FindEventManager(domWindow);
findEventManager.bind();
}
listener.onStopRequest(aRequest, context, statusCode);
@ -982,7 +986,7 @@ PdfStreamConverter.prototype = {
// e.g. useful for NoScript
var securityManager = Cc['@mozilla.org/scriptsecuritymanager;1']
.getService(Ci.nsIScriptSecurityManager);
var uri = ioService.newURI(PDF_VIEWER_WEB_PAGE, null, null);
var uri = NetUtil.newURI(PDF_VIEWER_WEB_PAGE, null, null);
// FF16 and below had getCodebasePrincipal, it was replaced by
// getNoAppCodebasePrincipal (bug 758258).
var resourcePrincipal = 'getNoAppCodebasePrincipal' in securityManager ?

Просмотреть файл

@ -66,6 +66,7 @@ let PdfjsChromeUtils = {
*/
init: function () {
this._browsers = new Set();
if (!this._ppmm) {
// global parent process message manager (PPMM)
this._ppmm = Cc['@mozilla.org/parentprocessmessagemanager;1'].
@ -80,10 +81,12 @@ let PdfjsChromeUtils = {
// global dom message manager (MMg)
this._mmg = Cc['@mozilla.org/globalmessagemanager;1'].
getService(Ci.nsIMessageListenerManager);
this._mmg.addMessageListener('PDFJS:Parent:getChromeWindow', this);
this._mmg.addMessageListener('PDFJS:Parent:getFindBar', this);
this._mmg.addMessageListener('PDFJS:Parent:displayWarning', this);
this._mmg.addMessageListener('PDFJS:Parent:addEventListener', this);
this._mmg.addMessageListener('PDFJS:Parent:removeEventListener', this);
this._mmg.addMessageListener('PDFJS:Parent:updateControlState', this);
// observer to handle shutdown
Services.obs.addObserver(this, 'quit-application', false);
}
@ -99,10 +102,12 @@ let PdfjsChromeUtils = {
this._ppmm.removeMessageListener('PDFJS:Parent:isDefaultHandlerApp',
this);
this._mmg.removeMessageListener('PDFJS:Parent:getChromeWindow', this);
this._mmg.removeMessageListener('PDFJS:Parent:getFindBar', this);
this._mmg.removeMessageListener('PDFJS:Parent:displayWarning', this);
this._mmg.removeMessageListener('PDFJS:Parent:addEventListener', this);
this._mmg.removeMessageListener('PDFJS:Parent:removeEventListener', this);
this._mmg.removeMessageListener('PDFJS:Parent:updateControlState', this);
Services.obs.removeObserver(this, 'quit-application', false);
this._mmg = null;
@ -161,11 +166,13 @@ let PdfjsChromeUtils = {
this._displayWarning(aMsg);
break;
// CPOW getters
case 'PDFJS:Parent:getChromeWindow':
return this._getChromeWindow(aMsg);
case 'PDFJS:Parent:getFindBar':
return this._getFindBar(aMsg);
case 'PDFJS:Parent:updateControlState':
return this._updateControlState(aMsg);
case 'PDFJS:Parent:addEventListener':
return this._addEventListener(aMsg);
case 'PDFJS:Parent:removeEventListener':
return this._removeEventListener(aMsg);
}
},
@ -173,24 +180,81 @@ let PdfjsChromeUtils = {
* Internal
*/
_getChromeWindow: function (aMsg) {
// See the child module, our return result here can't be the element
// since return results don't get auto CPOW'd.
_findbarFromMessage: function(aMsg) {
let browser = aMsg.target;
let wrapper = new PdfjsWindowWrapper(browser);
let suitcase = aMsg.objects.suitcase;
suitcase.setChromeWindow(wrapper);
return true;
let tabbrowser = browser.getTabBrowser();
let tab = tabbrowser.getTabForBrowser(browser);
return tabbrowser.getFindBar(tab);
},
_getFindBar: function (aMsg) {
// We send this over via the window's message manager, so target should
// be the dom window.
_updateControlState: function (aMsg) {
let data = aMsg.data;
this._findbarFromMessage(aMsg)
.updateControlState(data.result, data.findPrevious);
},
handleEvent: function(aEvent) {
// We cannot just forward the message as a CPOW without setting up
// __exposedProps__ on it. Instead, let's just create a structured
// cloneable version of the event for performance and for the ease of usage.
let type = aEvent.type;
let detail = {
query: aEvent.detail.query,
caseSensitive: aEvent.detail.caseSensitive,
highlightAll: aEvent.detail.highlightAll,
findPrevious: aEvent.detail.findPrevious
};
let chromeWindow = aEvent.target.ownerDocument.defaultView;
let browser = chromeWindow.gBrowser.selectedBrowser;
if (this._browsers.has(browser)) {
// Only forward the events if the selected browser is a registered
// browser.
let mm = browser.messageManager;
mm.sendAsyncMessage('PDFJS:Child:handleEvent',
{ type: type, detail: detail });
aEvent.preventDefault();
}
},
_types: ['find',
'findagain',
'findhighlightallchange',
'findcasesensitivitychange'],
_addEventListener: function (aMsg) {
let browser = aMsg.target;
let wrapper = new PdfjsFindbarWrapper(browser);
let suitcase = aMsg.objects.suitcase;
suitcase.setFindBar(wrapper);
return true;
if (this._browsers.has(browser)) {
throw new Error('FindEventManager was bound 2nd time ' +
'without unbinding it first.');
}
// Since this jsm is global, we need to store all the browsers
// we have to forward the messages for.
this._browsers.add(browser);
// And we need to start listening to find events.
for (var i = 0; i < this._types.length; i++) {
var type = this._types[i];
this._findbarFromMessage(aMsg)
.addEventListener(type, this, true);
}
},
_removeEventListener: function (aMsg) {
let browser = aMsg.target;
if (!this._browsers.has(browser)) {
throw new Error('FindEventManager was unbound without binding it first.');
}
this._browsers.delete(browser);
// No reason to listen to find events any longer.
for (var i = 0; i < this._types.length; i++) {
var type = this._types[i];
this._findbarFromMessage(aMsg)
.removeEventListener(type, this, true);
}
},
_ensurePreferenceAllowed: function (aPrefName) {
@ -283,53 +347,4 @@ let PdfjsChromeUtils = {
}
};
/*
* CPOW security features require chrome objects declare exposed
* properties via __exposedProps__. We don't want to expose things
* directly on the findbar, so we wrap the findbar in a smaller
* object here that supports the features pdf.js needs.
*/
function PdfjsFindbarWrapper(aBrowser) {
let tabbrowser = aBrowser.getTabBrowser();
let tab;
tab = tabbrowser.getTabForBrowser(aBrowser);
this._findbar = tabbrowser.getFindBar(tab);
}
PdfjsFindbarWrapper.prototype = {
__exposedProps__: {
addEventListener: 'r',
removeEventListener: 'r',
updateControlState: 'r',
},
_findbar: null,
updateControlState: function (aResult, aFindPrevious) {
this._findbar.updateControlState(aResult, aFindPrevious);
},
addEventListener: function (aType, aListener, aUseCapture, aWantsUntrusted) {
this._findbar.addEventListener(aType, aListener, aUseCapture,
aWantsUntrusted);
},
removeEventListener: function (aType, aListener, aUseCapture) {
this._findbar.removeEventListener(aType, aListener, aUseCapture);
}
};
function PdfjsWindowWrapper(aBrowser) {
this._window = aBrowser.ownerDocument.defaultView;
}
PdfjsWindowWrapper.prototype = {
__exposedProps__: {
valueOf: 'r',
},
_window: null,
valueOf: function () {
return this._window.valueOf();
}
};

Просмотреть файл

@ -149,56 +149,6 @@ let PdfjsContentUtils = {
}
break;
}
},
/*
* CPOWs
*/
getChromeWindow: function (aWindow) {
let winmm = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.sameTypeRootTreeItem
.QueryInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
// Sync calls don't support cpow wrapping of returned results, so we
// send over a small container for the object we want.
let suitcase = {
_window: null,
setChromeWindow: function (aObj) {
this._window = aObj;
}
};
if (!winmm.sendSyncMessage('PDFJS:Parent:getChromeWindow', {},
{ suitcase: suitcase })[0]) {
Cu.reportError('A request for a CPOW wrapped chrome window ' +
'failed for unknown reasons.');
return null;
}
return suitcase._window;
},
getFindBar: function (aWindow) {
let winmm = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.sameTypeRootTreeItem
.QueryInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
let suitcase = {
_findbar: null,
setFindBar: function (aObj) {
this._findbar = aObj;
}
};
if (!winmm.sendSyncMessage('PDFJS:Parent:getFindBar', {},
{ suitcase: suitcase })[0]) {
Cu.reportError('A request for a CPOW wrapped findbar ' +
'failed for unknown reasons.');
return null;
}
return suitcase._findbar;
}
};

Просмотреть файл

@ -22,8 +22,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
PDFJS.version = '1.0.1149';
PDFJS.build = 'bc7a110';
PDFJS.version = '1.1.24';
PDFJS.build = 'f6a8110';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
@ -949,10 +949,6 @@ function isString(v) {
return typeof v === 'string';
}
function isNull(v) {
return v === null;
}
function isName(v) {
return v instanceof Name;
}
@ -1324,7 +1320,7 @@ PDFJS.cMapUrl = (PDFJS.cMapUrl === undefined ? null : PDFJS.cMapUrl);
*/
PDFJS.cMapPacked = PDFJS.cMapPacked === undefined ? false : PDFJS.cMapPacked;
/*
/**
* By default fonts are converted to OpenType fonts and loaded via font face
* rules. If disabled, the font will be rendered using a built in font renderer
* that constructs the glyphs with primitive path commands.
@ -1414,6 +1410,14 @@ PDFJS.disableCreateObjectURL = (PDFJS.disableCreateObjectURL === undefined ?
PDFJS.disableWebGL = (PDFJS.disableWebGL === undefined ?
true : PDFJS.disableWebGL);
/**
* Disables fullscreen support, and by extension Presentation Mode,
* in browsers which support the fullscreen API.
* @var {boolean}
*/
PDFJS.disableFullscreen = (PDFJS.disableFullscreen === undefined ?
false : PDFJS.disableFullscreen);
/**
* Enables CSS only zooming.
* @var {boolean}
@ -1433,13 +1437,22 @@ PDFJS.verbosity = (PDFJS.verbosity === undefined ?
PDFJS.VERBOSITY_LEVELS.warnings : PDFJS.verbosity);
/**
* The maximum supported canvas size in total pixels e.g. width * height.
* The maximum supported canvas size in total pixels e.g. width * height.
* The default value is 4096 * 4096. Use -1 for no limit.
* @var {number}
*/
PDFJS.maxCanvasPixels = (PDFJS.maxCanvasPixels === undefined ?
16777216 : PDFJS.maxCanvasPixels);
/**
* Opens external links in a new window if enabled. The default behavior opens
* external links in the PDF.js window.
* @var {boolean}
*/
PDFJS.openExternalLinksInNewWindow = (
PDFJS.openExternalLinksInNewWindow === undefined ?
false : PDFJS.openExternalLinksInNewWindow);
/**
* Document initialization / loading parameters object.
*
@ -1879,7 +1892,7 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
* rendering call the function that is the first argument
* to the callback.
*/
/**
* PDF page operator list.
*
@ -5118,7 +5131,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
})();
var WebGLUtils = (function WebGLUtilsClosure() {
function loadShader(gl, code, shaderType) {
var shader = gl.createShader(shaderType);
@ -6235,6 +6247,9 @@ var AnnotationUtils = (function AnnotationUtilsClosure() {
var link = document.createElement('a');
link.href = link.title = item.url || '';
if (item.url && PDFJS.openExternalLinksInNewWindow) {
link.target = '_blank';
}
container.appendChild(link);

Просмотреть файл

@ -22,8 +22,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
PDFJS.version = '1.0.1149';
PDFJS.build = 'bc7a110';
PDFJS.version = '1.1.24';
PDFJS.build = 'f6a8110';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
@ -949,10 +949,6 @@ function isString(v) {
return typeof v === 'string';
}
function isNull(v) {
return v === null;
}
function isName(v) {
return v instanceof Name;
}
@ -1842,7 +1838,6 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() {
})();
// The maximum number of bytes fetched per range request
var RANGE_CHUNK_SIZE = 65536;
@ -2048,7 +2043,6 @@ var NetworkPdfManager = (function NetworkPdfManagerClosure() {
})();
var Page = (function PageClosure() {
var LETTER_SIZE_MEDIABOX = [0, 0, 612, 792];
@ -2558,7 +2552,6 @@ var PDFDocument = (function PDFDocumentClosure() {
})();
var Name = (function NameClosure() {
function Name(name) {
this.name = name;
@ -3091,7 +3084,7 @@ var Catalog = (function CatalogClosure() {
var isPrintAction = (isName(objType) && objType.name === 'Action' &&
isName(actionType) && actionType.name === 'Named' &&
isName(action) && action.name === 'Print');
if (isPrintAction) {
javaScript.push('print(true);');
}
@ -3947,7 +3940,7 @@ var NameTree = (function NameTreeClosure() {
warn('Search depth limit for named destionations has been reached.');
return null;
}
var kids = kidsOrNames.get('Kids');
if (!isArray(kids)) {
return null;
@ -4002,10 +3995,10 @@ var NameTree = (function NameTreeClosure() {
})();
/**
* "A PDF file can refer to the contents of another file by using a File
* "A PDF file can refer to the contents of another file by using a File
* Specification (PDF 1.1)", see the spec (7.11) for more details.
* NOTE: Only embedded files are supported (as part of the attachments support)
* TODO: support the 'URL' file system (with caching if !/V), portable
* TODO: support the 'URL' file system (with caching if !/V), portable
* collections attributes and related files (/RF)
*/
var FileSpec = (function FileSpecClosure() {
@ -4335,7 +4328,6 @@ var ExpertSubsetCharset = [
];
var DEFAULT_ICON_SIZE = 22; // px
var SUPPORTED_TYPES = ['Link', 'Text', 'Widget'];
@ -6229,10 +6221,10 @@ var ColorSpace = (function ColorSpaceClosure() {
case 'CMYK':
return 'DeviceCmykCS';
case 'CalGray':
params = cs[1].getAll();
params = xref.fetchIfRef(cs[1]).getAll();
return ['CalGrayCS', params];
case 'CalRGB':
params = cs[1].getAll();
params = xref.fetchIfRef(cs[1]).getAll();
return ['CalRGBCS', params];
case 'ICCBased':
var stream = xref.fetchIfRef(cs[1]);
@ -10873,7 +10865,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
styles: Object.create(null)
};
var bidiTexts = textContent.items;
var SPACE_FACTOR = 0.35;
var SPACE_FACTOR = 0.3;
var MULTI_SPACE_FACTOR = 1.5;
var self = this;
@ -11312,8 +11304,11 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
var cmap, cmapObj = toUnicode;
if (isName(cmapObj)) {
cmap = CMapFactory.create(cmapObj,
{ url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null).getMap();
return new ToUnicodeMap(cmap);
{ url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null);
if (cmap instanceof IdentityCMap) {
return new IdentityToUnicodeMap(0, 0xFFFF);
}
return new ToUnicodeMap(cmap.getMap());
} else if (isStream(cmapObj)) {
cmap = CMapFactory.create(cmapObj,
{ url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null).getMap();
@ -15768,7 +15763,7 @@ var IdentityToUnicodeMap = (function IdentityToUnicodeMapClosure() {
IdentityToUnicodeMap.prototype = {
get length() {
error('should not access .length');
return (this.lastChar + 1) - this.firstChar;
},
forEach: function (callback) {
@ -16113,8 +16108,6 @@ var Font = (function FontClosure() {
if (subtype === 'CIDFontType0C' && type !== 'CIDFontType0') {
type = 'CIDFontType0';
}
// XXX: Temporarily change the type for open type so we trigger a warning.
// This should be removed when we add support for open type.
if (subtype === 'OpenType') {
type = 'OpenType';
}
@ -16241,6 +16234,8 @@ var Font = (function FontClosure() {
fontCharCode === 0x7F || // Control char
fontCharCode === 0xAD || // Soft hyphen
fontCharCode === 0xA0 || // Non breaking space
fontCharCode === 0x0E33 || // Thai character SARA AM
fontCharCode === 0x25CC || // Dotted circle (combining mark)
(fontCharCode >= 0x80 && fontCharCode <= 0x9F) || // Control chars
// Prevent drawing characters in the specials unicode block.
(fontCharCode >= 0xFFF0 && fontCharCode <= 0xFFFF) ||
@ -17521,7 +17516,8 @@ var Font = (function FontClosure() {
var isTrueType = !tables['CFF '];
if (!isTrueType) {
// OpenType font
if (!tables.head || !tables.hhea || !tables.maxp || !tables.post) {
if (header.version === 'OTTO' ||
!tables.head || !tables.hhea || !tables.maxp || !tables.post) {
// no major tables: throwing everything at CFFFont
cffFile = new Stream(tables['CFF '].data);
cff = new CFFFont(cffFile, properties);
@ -21490,7 +21486,6 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
})();
var GlyphsUnicode = {
A: 0x0041,
AE: 0x00C6,
@ -29497,7 +29492,6 @@ var Metrics = {
};
var EOF = {};
function isEOF(v) {
@ -33655,9 +33649,9 @@ if (typeof window === 'undefined') {
/* This class implements the QM Coder decoding as defined in
* JPEG 2000 Part I Final Committee Draft Version 1.0
* Annex C.3 Arithmetic decoding procedure
* Annex C.3 Arithmetic decoding procedure
* available at http://www.jpeg.org/public/fcd15444-1.pdf
*
*
* The arithmetic decoder is used in conjunction with context models to decode
* JPEG2000 and JBIG2 streams.
*/
@ -34459,9 +34453,9 @@ var JpegImage = (function jpegImage() {
if (fileMarker === 0xFFEE) {
if (appData[0] === 0x41 && appData[1] === 0x64 &&
appData[2] === 0x6F && appData[3] === 0x62 &&
appData[4] === 0x65 && appData[5] === 0) { // 'Adobe\x00'
appData[4] === 0x65) { // 'Adobe'
adobe = {
version: appData[6],
version: (appData[5] << 8) | appData[6],
flags0: (appData[7] << 8) | appData[8],
flags1: (appData[9] << 8) | appData[10],
transformCode: appData[11]
@ -34582,6 +34576,13 @@ var JpegImage = (function jpegImage() {
successiveApproximation >> 4, successiveApproximation & 15);
offset += processed;
break;
case 0xFFFF: // Fill bytes
if (data[offset] !== 0xFF) { // Avoid skipping a valid marker.
offset--;
}
break;
default:
if (data[offset - 3] === 0xFF &&
data[offset - 2] >= 0xC0 && data[offset - 2] <= 0xFE) {
@ -37016,7 +37017,6 @@ var JpxImage = (function JpxImageClosure() {
})();
var Jbig2Image = (function Jbig2ImageClosure() {
// Utility data structures
function ContextCache() {}
@ -38493,7 +38493,6 @@ var bidi = PDFJS.bidi = (function bidiClosure() {
return bidi;
})();
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

Просмотреть файл

@ -269,4 +269,3 @@ var NetworkManager = (function NetworkManagerClosure() {
return NetworkManager;
})();

Просмотреть файл

@ -124,7 +124,7 @@
// Arabic, Hebrew, Farsi, Pashto, Urdu
var rtlList = ['ar', 'he', 'fa', 'ps', 'ur'];
// use the short language code for "full" codes like 'ar-sa' (issue 5440)
// use the short language code for "full" codes like 'ar-sa' (issue 5440)
var shortCode = gLanguage.split('-')[0];
return (rtlList.indexOf(shortCode) >= 0) ? 'rtl' : 'ltr';
@ -134,4 +134,3 @@
translate: translateFragment
};
})(this);

Просмотреть файл

@ -76,6 +76,11 @@
background-color: white;
}
.pdfViewer.removePageBorders .page {
margin: 0px auto 10px auto;
border: none;
}
.pdfViewer .page canvas {
margin: 0;
display: block;
@ -1751,10 +1756,6 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * {
left: 0;
display: block;
}
#printContainer div {
page-break-after: always;
page-break-inside: avoid;
}
}
.visibleLargeView,

Просмотреть файл

@ -133,7 +133,7 @@ http://sourceforge.net/adobe/cmap/wiki/License/
<button id="toggleHandTool" class="secondaryToolbarButton handTool" title="Enable hand tool" tabindex="60" data-l10n-id="hand_tool_enable">
<span data-l10n-id="hand_tool_enable_label">Enable hand tool</span>
</button>
<div class="horizontalToolbarSeparator"></div>
<button id="documentProperties" class="secondaryToolbarButton documentProperties" title="Document Properties…" tabindex="61" data-l10n-id="document_properties">
@ -188,10 +188,10 @@ http://sourceforge.net/adobe/cmap/wiki/License/
</a>
<div class="verticalToolbarSeparator hiddenSmallView"></div>
<button id="secondaryToolbarToggle" class="toolbarButton" title="Tools" tabindex="36" data-l10n-id="tools">
<span data-l10n-id="tools_label">Tools</span>
</button>
</button>
</div>
<div class="outerCenter">
<div class="innerCenter" id="toolbarViewerMiddle">

Просмотреть файл

@ -189,13 +189,10 @@ function watchScroll(viewAreaElement, callback) {
var currentY = viewAreaElement.scrollTop;
var lastY = state.lastY;
if (currentY > lastY) {
state.down = true;
} else if (currentY < lastY) {
state.down = false;
if (currentY !== lastY) {
state.down = currentY > lastY;
}
state.lastY = currentY;
// else do nothing and use previous value
callback(state);
});
};
@ -211,6 +208,38 @@ function watchScroll(viewAreaElement, callback) {
return state;
}
/**
* Use binary search to find the index of the first item in a given array which
* passes a given condition. The items are expected to be sorted in the sense
* that if the condition is true for one item in the array, then it is also true
* for all following items.
*
* @returns {Number} Index of the first array element to pass the test,
* or |items.length| if no such element exists.
*/
function binarySearchFirstItem(items, condition) {
var minIndex = 0;
var maxIndex = items.length - 1;
if (items.length === 0 || !condition(items[maxIndex])) {
return items.length;
}
if (condition(items[minIndex])) {
return minIndex;
}
while (minIndex < maxIndex) {
var currentIndex = (minIndex + maxIndex) >> 1;
var currentItem = items[currentIndex];
if (condition(currentItem)) {
maxIndex = currentIndex;
} else {
minIndex = currentIndex + 1;
}
}
return minIndex; /* === maxIndex */
}
/**
* Generic helper to find out what elements are visible within a scroll pane.
*/
@ -218,30 +247,45 @@ function getVisibleElements(scrollEl, views, sortByVisibility) {
var top = scrollEl.scrollTop, bottom = top + scrollEl.clientHeight;
var left = scrollEl.scrollLeft, right = left + scrollEl.clientWidth;
var visible = [], view;
function isElementBottomBelowViewTop(view) {
var element = view.div;
var elementBottom =
element.offsetTop + element.clientTop + element.clientHeight;
return elementBottom > top;
}
var visible = [], view, element;
var currentHeight, viewHeight, hiddenHeight, percentHeight;
var currentWidth, viewWidth;
for (var i = 0, ii = views.length; i < ii; ++i) {
var firstVisibleElementInd = (views.length === 0) ? 0 :
binarySearchFirstItem(views, isElementBottomBelowViewTop);
for (var i = firstVisibleElementInd, ii = views.length; i < ii; i++) {
view = views[i];
currentHeight = view.el.offsetTop + view.el.clientTop;
viewHeight = view.el.clientHeight;
if ((currentHeight + viewHeight) < top) {
continue;
}
element = view.div;
currentHeight = element.offsetTop + element.clientTop;
viewHeight = element.clientHeight;
if (currentHeight > bottom) {
break;
}
currentWidth = view.el.offsetLeft + view.el.clientLeft;
viewWidth = view.el.clientWidth;
if ((currentWidth + viewWidth) < left || currentWidth > right) {
currentWidth = element.offsetLeft + element.clientLeft;
viewWidth = element.clientWidth;
if (currentWidth + viewWidth < left || currentWidth > right) {
continue;
}
hiddenHeight = Math.max(0, top - currentHeight) +
Math.max(0, currentHeight + viewHeight - bottom);
percentHeight = ((viewHeight - hiddenHeight) * 100 / viewHeight) | 0;
visible.push({ id: view.id, x: currentWidth, y: currentHeight,
view: view, percent: percentHeight });
visible.push({
id: view.id,
x: currentWidth,
y: currentHeight,
view: view,
percent: percentHeight
});
}
var first = visible[0];
@ -615,7 +659,7 @@ var DownloadManager = (function DownloadManagerClosure() {
downloadData: function DownloadManager_downloadData(data, filename,
contentType) {
var blobUrl = PDFJS.createObjectURL(data, contentType);
FirefoxCom.request('download', {
blobUrl: blobUrl,
originalUrl: blobUrl,
@ -902,7 +946,6 @@ var PDFFindBar = (function PDFFindBarClosure() {
})();
var FindStates = {
FIND_FOUND: 0,
FIND_NOTFOUND: 1,
@ -951,7 +994,8 @@ var PDFFindController = (function PDFFindControllerClosure() {
'\u201F': '"', // Double high-reversed-9 quotation mark
'\u00BC': '1/4', // Vulgar fraction one quarter
'\u00BD': '1/2', // Vulgar fraction one half
'\u00BE': '3/4' // Vulgar fraction three quarters
'\u00BE': '3/4', // Vulgar fraction three quarters
'\u00A0': ' ' // No-break space
};
this.findBar = options.findBar || null;
@ -1187,7 +1231,7 @@ var PDFFindController = (function PDFFindControllerClosure() {
if (this.pagesToSearch < 0) {
// No point in wrapping again, there were no matches.
this.updateMatch(false);
// while matches were not found, searching for a page
// while matches were not found, searching for a page
// with matches should nevertheless halt.
return true;
}
@ -1240,7 +1284,7 @@ var PDFFindController = (function PDFFindControllerClosure() {
offset.matchIdx = null;
this.pagesToSearch--;
if (offset.pageIdx >= numPages || offset.pageIdx < 0) {
offset.pageIdx = (previous ? numPages - 1 : 0);
offset.wrapped = true;
@ -1251,7 +1295,7 @@ var PDFFindController = (function PDFFindControllerClosure() {
var state = FindStates.FIND_NOTFOUND;
var wrapped = this.offset.wrapped;
this.offset.wrapped = false;
if (found) {
var previousPage = this.selected.pageIdx;
this.selected.pageIdx = this.offset.pageIdx;
@ -1262,7 +1306,7 @@ var PDFFindController = (function PDFFindControllerClosure() {
this.updatePage(previousPage);
}
}
this.updateUIState(state, this.state.findPrevious);
if (this.selected.pageIdx !== -1) {
this.updatePage(this.selected.pageIdx);
@ -1286,7 +1330,6 @@ var PDFFindController = (function PDFFindControllerClosure() {
})();
var PDFHistory = {
initialized: false,
initialDestination: null,
@ -1863,8 +1906,8 @@ var PresentationMode = {
this.container.requestFullscreen();
} else if (this.container.mozRequestFullScreen) {
this.container.mozRequestFullScreen();
} else if (this.container.webkitRequestFullScreen) {
this.container.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
} else if (this.container.webkitRequestFullscreen) {
this.container.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
} else if (this.container.msRequestFullscreen) {
this.container.msRequestFullscreen();
} else {
@ -2617,7 +2660,7 @@ var DocumentProperties = {
parseDate: function documentPropertiesParseDate(inputDate) {
// This is implemented according to the PDF specification (see
// http://www.gnupdf.org/Date for an overview), but note that
// http://www.gnupdf.org/Date for an overview), but note that
// Adobe Reader doesn't handle changing the date to universal time
// and doesn't use the user's time zone (they're effectively ignoring
// the HH' and mm' parts of the date string).
@ -2899,7 +2942,6 @@ var PDFPageView = (function PDFPageViewClosure() {
div.className = 'page';
div.style.width = Math.floor(this.viewport.width) + 'px';
div.style.height = Math.floor(this.viewport.height) + 'px';
this.el = div; // TODO replace 'el' property usage
this.div = div;
container.appendChild(div);
@ -3924,6 +3966,8 @@ DefaultAnnotationsLayerFactory.prototype = {
* @property {IPDFLinkService} linkService - The navigation/linking service.
* @property {PDFRenderingQueue} renderingQueue - (optional) The rendering
* queue object.
* @property {boolean} removePageBorders - (optional) Removes the border shadow
* around the pages. The default is false.
*/
/**
@ -3960,6 +4004,7 @@ var PDFViewer = (function pdfViewer() {
this.container = options.container;
this.viewer = options.viewer || options.container.firstElementChild;
this.linkService = options.linkService || new SimpleLinkService(this);
this.removePageBorders = options.removePageBorders || false;
this.defaultRenderingQueue = !options.renderingQueue;
if (this.defaultRenderingQueue) {
@ -3974,6 +4019,10 @@ var PDFViewer = (function pdfViewer() {
this.updateInProgress = false;
this.presentationModeState = PresentationModeState.UNKNOWN;
this._resetView();
if (this.removePageBorders) {
this.viewer.classList.add('removePageBorders');
}
}
PDFViewer.prototype = /** @lends PDFViewer.prototype */{
@ -4186,6 +4235,10 @@ var PDFViewer = (function pdfViewer() {
if (this.defaultRenderingQueue) {
this.update();
}
if (this.findController) {
this.findController.resolveFirstPage();
}
}.bind(this));
},
@ -4215,12 +4268,27 @@ var PDFViewer = (function pdfViewer() {
}
},
_setScaleDispatchEvent: function pdfViewer_setScaleDispatchEvent(
newScale, newValue, preset) {
var event = document.createEvent('UIEvents');
event.initUIEvent('scalechange', true, true, window, 0);
event.scale = newScale;
if (preset) {
event.presetValue = newValue;
}
this.container.dispatchEvent(event);
},
_setScaleUpdatePages: function pdfViewer_setScaleUpdatePages(
newScale, newValue, noScroll, preset) {
this._currentScaleValue = newValue;
if (newScale === this._currentScale) {
if (preset) {
this._setScaleDispatchEvent(newScale, newValue, true);
}
return;
}
for (var i = 0, ii = this.pages.length; i < ii; i++) {
this.pages[i].update(newScale);
}
@ -4240,13 +4308,7 @@ var PDFViewer = (function pdfViewer() {
this.scrollPageIntoView(page, dest);
}
var event = document.createEvent('UIEvents');
event.initUIEvent('scalechange', true, true, window, 0);
event.scale = newScale;
if (preset) {
event.presetValue = newValue;
}
this.container.dispatchEvent(event);
this._setScaleDispatchEvent(newScale, newValue, preset);
},
_setScale: function pdfViewer_setScale(value, noScroll) {
@ -4264,8 +4326,10 @@ var PDFViewer = (function pdfViewer() {
}
var inPresentationMode =
this.presentationModeState === PresentationModeState.FULLSCREEN;
var hPadding = inPresentationMode ? 0 : SCROLLBAR_PADDING;
var vPadding = inPresentationMode ? 0 : VERTICAL_PADDING;
var hPadding = (inPresentationMode || this.removePageBorders) ?
0 : SCROLLBAR_PADDING;
var vPadding = (inPresentationMode || this.removePageBorders) ?
0 : VERTICAL_PADDING;
var pageWidthScale = (this.container.clientWidth - hPadding) /
currentPage.width * currentPage.scale;
var pageHeightScale = (this.container.clientHeight - vPadding) /
@ -4368,9 +4432,12 @@ var PDFViewer = (function pdfViewer() {
width = dest[4] - x;
height = dest[5] - y;
var viewerContainer = this.container;
widthScale = (viewerContainer.clientWidth - SCROLLBAR_PADDING) /
var hPadding = this.removePageBorders ? 0 : SCROLLBAR_PADDING;
var vPadding = this.removePageBorders ? 0 : VERTICAL_PADDING;
widthScale = (viewerContainer.clientWidth - hPadding) /
width / CSS_UNITS;
heightScale = (viewerContainer.clientHeight - SCROLLBAR_PADDING) /
heightScale = (viewerContainer.clientHeight - vPadding) /
height / CSS_UNITS;
scale = Math.min(Math.abs(widthScale), Math.abs(heightScale));
break;
@ -4727,7 +4794,6 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
var div = document.createElement('div');
div.id = 'thumbnailContainer' + id;
div.className = 'thumbnail';
this.el = div; // TODO: replace 'el' property usage.
this.div = div;
if (id === 1) {
@ -4995,7 +5061,9 @@ var PDFThumbnailViewer = (function PDFThumbnailViewerClosure() {
selected.classList.remove('selected');
}
var thumbnail = document.getElementById('thumbnailContainer' + page);
thumbnail.classList.add('selected');
if (thumbnail) {
thumbnail.classList.add('selected');
}
var visibleThumbs = this._getVisibleThumbs();
var numVisibleThumbs = visibleThumbs.views.length;
@ -5152,6 +5220,17 @@ var PDFOutlineView = (function PDFOutlineViewClosure() {
}
},
/**
* @private
*/
_dispatchEvent: function PDFOutlineView_dispatchEvent(outlineCount) {
var event = document.createEvent('CustomEvent');
event.initCustomEvent('outlineloaded', true, true, {
outlineCount: outlineCount
});
this.container.dispatchEvent(event);
},
/**
* @private
*/
@ -5166,10 +5245,12 @@ var PDFOutlineView = (function PDFOutlineViewClosure() {
render: function PDFOutlineView_render() {
var outline = this.outline;
var outlineCount = 0;
this.reset();
if (!outline) {
this._dispatchEvent(outlineCount);
return;
}
@ -5193,8 +5274,11 @@ var PDFOutlineView = (function PDFOutlineViewClosure() {
}
levelData.parent.appendChild(div);
outlineCount++;
}
}
this._dispatchEvent(outlineCount);
}
};
@ -5231,6 +5315,17 @@ var PDFAttachmentView = (function PDFAttachmentViewClosure() {
}
},
/**
* @private
*/
_dispatchEvent: function PDFAttachmentView_dispatchEvent(attachmentsCount) {
var event = document.createEvent('CustomEvent');
event.initCustomEvent('attachmentsloaded', true, true, {
attachmentsCount: attachmentsCount
});
this.container.dispatchEvent(event);
},
/**
* @private
*/
@ -5243,17 +5338,21 @@ var PDFAttachmentView = (function PDFAttachmentViewClosure() {
render: function PDFAttachmentView_render() {
var attachments = this.attachments;
var attachmentsCount = 0;
this.reset();
if (!attachments) {
this._dispatchEvent(attachmentsCount);
return;
}
var names = Object.keys(attachments).sort(function(a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
for (var i = 0, len = names.length; i < len; i++) {
attachmentsCount = names.length;
for (var i = 0; i < attachmentsCount; i++) {
var item = attachments[names[i]];
var filename = getFileName(item.filename);
var div = document.createElement('div');
@ -5264,6 +5363,8 @@ var PDFAttachmentView = (function PDFAttachmentViewClosure() {
div.appendChild(button);
this.container.appendChild(div);
}
this._dispatchEvent(attachmentsCount);
}
};
@ -5292,6 +5393,7 @@ var PDFViewerApplication = {
mouseScrollDelta: 0,
preferenceSidebarViewOnLoad: SidebarView.NONE,
preferencePdfBugEnabled: false,
preferenceShowPreviousViewOnLoad: true,
isViewerEmbedded: (window.parent !== window),
url: '',
@ -5410,6 +5512,12 @@ var PDFViewerApplication = {
Preferences.get('pdfBugEnabled').then(function resolved(value) {
self.preferencePdfBugEnabled = value;
}),
Preferences.get('showPreviousViewOnLoad').then(function resolved(value) {
self.preferenceShowPreviousViewOnLoad = value;
if (!value && window.history.state) {
window.history.replaceState(null, '');
}
}),
Preferences.get('disableTextLayer').then(function resolved(value) {
if (PDFJS.disableTextLayer === true) {
return;
@ -5434,6 +5542,7 @@ var PDFViewerApplication = {
Preferences.get('useOnlyCssZoom').then(function resolved(value) {
PDFJS.useOnlyCssZoom = value;
})
// TODO move more preferences and other async stuff here
]).catch(function (reason) { });
@ -5496,6 +5605,9 @@ var PDFViewerApplication = {
document.msFullscreenEnabled === false) {
support = false;
}
if (support && PDFJS.disableFullscreen === true) {
support = false;
}
return PDFJS.shadow(this, 'supportsFullscreen', support);
},
@ -5600,6 +5712,10 @@ var PDFViewerApplication = {
},
setTitle: function pdfViewSetTitle(title) {
if (this.isViewerEmbedded) {
// Embedded PDF viewers should not be changing their parent page's title.
return;
}
document.title = title;
},
@ -5984,8 +6100,6 @@ var PDFViewerApplication = {
self.loadingBar.setWidth(document.getElementById('viewer'));
self.findController.resolveFirstPage();
if (!PDFJS.disableHistory && !self.isViewerEmbedded) {
// The browsing history is only enabled when the viewer is standalone,
// i.e. not when it is embedded in a web page.
@ -5994,11 +6108,6 @@ var PDFViewerApplication = {
});
// 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) {
@ -6006,10 +6115,11 @@ var PDFViewerApplication = {
});
var storePromise = store.initializedPromise;
Promise.all([firstPagePromise, storePromise, showPreviousViewOnLoadPromise,
defaultZoomValuePromise]).then(function resolved() {
Promise.all([firstPagePromise, storePromise, defaultZoomValuePromise]).then(
function resolved() {
var storedHash = null;
if (showPreviousViewOnLoad && store.get('exists', false)) {
if (PDFViewerApplication.preferenceShowPreviousViewOnLoad &&
store.get('exists', false)) {
var pageNum = store.get('page', '1');
var zoom = defaultZoomValue ||
store.get('zoom', self.pdfViewer.currentScale);
@ -6215,10 +6325,6 @@ var PDFViewerApplication = {
this.initialBookmark = hash;
return;
}
var validFitZoomValues = ['Fit','FitB','FitH','FitBH',
'FitV','FitBV','FitR'];
if (!hash) {
return;
}
@ -6236,23 +6342,39 @@ var PDFViewerApplication = {
pageNumber = (params.page | 0) || 1;
}
if ('zoom' in params) {
// Build the destination array.
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);
var destName = 'XYZ';
if (zoomArgNumber) {
zoomArg = zoomArgNumber / 100;
} else if (validFitZoomValues.indexOf(zoomArg) >= 0) {
destName = zoomArg;
if (zoomArg.indexOf('Fit') === -1) {
// If the zoomArg is a number, it has to get divided by 100. If it's
// a string, it should stay as it is.
dest = [null, { name: 'XYZ' },
zoomArgs.length > 1 ? (zoomArgs[1] | 0) : null,
zoomArgs.length > 2 ? (zoomArgs[2] | 0) : null,
(zoomArgNumber ? zoomArgNumber / 100 : zoomArg)];
} else {
if (zoomArg === 'Fit' || zoomArg === 'FitB') {
dest = [null, { name: zoomArg }];
} else if ((zoomArg === 'FitH' || zoomArg === 'FitBH') ||
(zoomArg === 'FitV' || zoomArg === 'FitBV')) {
dest = [null, { name: zoomArg },
zoomArgs.length > 1 ? (zoomArgs[1] | 0) : null];
} else if (zoomArg === 'FitR') {
if (zoomArgs.length !== 5) {
console.error('pdfViewSetHash: ' +
'Not enough parameters for \'FitR\'.');
} else {
dest = [null, { name: zoomArg },
(zoomArgs[1] | 0), (zoomArgs[2] | 0),
(zoomArgs[3] | 0), (zoomArgs[4] | 0)];
}
} else {
console.error('pdfViewSetHash: \'' + zoomArg +
'\' is not a valid zoom value.');
}
}
dest = [null, { name: destName },
zoomArgs.length > 1 ? (zoomArgs[1] | 0) : null,
zoomArgs.length > 2 ? (zoomArgs[2] | 0) : null,
zoomArg];
}
if (dest) {
this.pdfViewer.scrollPageIntoView(pageNumber || this.page, dest);
@ -6276,6 +6398,23 @@ var PDFViewerApplication = {
}
},
refreshThumbnailViewer: function pdfViewRefreshThumbnailViewer() {
var pdfViewer = this.pdfViewer;
var thumbnailViewer = this.pdfThumbnailViewer;
// set thumbnail images of rendered pages
var pagesCount = pdfViewer.pagesCount;
for (var pageIndex = 0; pageIndex < pagesCount; pageIndex++) {
var pageView = pdfViewer.getPageView(pageIndex);
if (pageView && pageView.renderingState === RenderingStates.FINISHED) {
var thumbnailView = thumbnailViewer.getThumbnail(pageIndex);
thumbnailView.setImage(pageView);
}
}
thumbnailViewer.scrollThumbnailIntoView(this.page);
},
switchSidebarView: function pdfViewSwitchSidebarView(view, openSidebar) {
if (openSidebar && !this.sidebarOpen) {
document.getElementById('sidebarToggle').click();
@ -6600,6 +6739,9 @@ function webViewerInitialized() {
outerContainer.classList.toggle('sidebarOpen');
PDFViewerApplication.sidebarOpen =
outerContainer.classList.contains('sidebarOpen');
if (PDFViewerApplication.sidebarOpen) {
PDFViewerApplication.refreshThumbnailViewer();
}
PDFViewerApplication.forceRendering();
});
@ -6684,9 +6826,12 @@ document.addEventListener('pagerendered', function (e) {
var pageNumber = e.detail.pageNumber;
var pageIndex = pageNumber - 1;
var pageView = PDFViewerApplication.pdfViewer.getPageView(pageIndex);
var thumbnailView = PDFViewerApplication.pdfThumbnailViewer.
getThumbnail(pageIndex);
thumbnailView.setImage(pageView);
if (PDFViewerApplication.sidebarOpen) {
var thumbnailView = PDFViewerApplication.pdfThumbnailViewer.
getThumbnail(pageIndex);
thumbnailView.setImage(pageView);
}
if (PDFJS.pdfBug && Stats.enabled && pageView.stats) {
Stats.add(pageNumber, pageView.stats);
@ -6785,9 +6930,10 @@ window.addEventListener('updateviewarea', function () {
window.addEventListener('resize', function webViewerResize(evt) {
if (PDFViewerApplication.initialized &&
(document.getElementById('pageWidthOption').selected ||
(document.getElementById('pageAutoOption').selected ||
/* Note: the scale is constant for |pageActualOption|. */
document.getElementById('pageFitOption').selected ||
document.getElementById('pageAutoOption').selected)) {
document.getElementById('pageWidthOption').selected)) {
var selectedScale = document.getElementById('scaleSelect').value;
PDFViewerApplication.setScale(selectedScale, false);
}
@ -6853,9 +6999,10 @@ window.addEventListener('scalechange', function scalechange(evt) {
customScaleOption.selected = false;
if (!PDFViewerApplication.updateScaleControls &&
(document.getElementById('pageWidthOption').selected ||
(document.getElementById('pageAutoOption').selected ||
document.getElementById('pageActualOption').selected ||
document.getElementById('pageFitOption').selected ||
document.getElementById('pageAutoOption').selected)) {
document.getElementById('pageWidthOption').selected)) {
updateViewarea();
return;
}
@ -6880,7 +7027,9 @@ window.addEventListener('pagechange', function pagechange(evt) {
var page = evt.pageNumber;
if (evt.previousPageNumber !== page) {
document.getElementById('pageNumber').value = page;
PDFViewerApplication.pdfThumbnailViewer.scrollThumbnailIntoView(page);
if (PDFViewerApplication.sidebarOpen) {
PDFViewerApplication.pdfThumbnailViewer.scrollThumbnailIntoView(page);
}
}
var numPages = PDFViewerApplication.pagesCount;