1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Create a new PDFScriptingAPI. This provides a scripting interface to
* the PDF viewer so that it can be customized by things like print preview.
* @param {Window} window the window of the page containing the pdf viewer.
* @param {Object} plugin the plugin element containing the pdf viewer.
*/
function PDFScriptingAPI(window, plugin) {
this.loaded_ = false;
this.pendingScriptingMessages_ = [];
this.setPlugin(plugin);
window.addEventListener('message', function(event) {
if (event.origin != 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai') {
console.error('Received message that was not from the extension: ' +
event);
return;
}
switch (event.data.type) {
case 'viewport':
if (this.viewportChangedCallback_)
this.viewportChangedCallback_(event.data.pageX,
event.data.pageY,
event.data.pageWidth,
event.data.viewportWidth,
event.data.viewportHeight);
break;
case 'documentLoaded':
this.loaded_ = true;
if (this.loadCallback_)
this.loadCallback_();
break;
case 'getAccessibilityJSONReply':
if (this.accessibilityCallback_) {
this.accessibilityCallback_(event.data.json);
this.accessibilityCallback_ = null;
}
break;
}
}.bind(this), false);
}
PDFScriptingAPI.prototype = {
/**
* @private
* Send a message to the extension. If messages try to get sent before there
* is a plugin element set, then we queue them up and send them later (this
* can happen in print preview).
* @param {Object} message The message to send.
*/
sendMessage_: function(message) {
if (this.plugin_)
this.plugin_.postMessage(message, '*');
else
this.pendingScriptingMessages_.push(message);
},
/**
* Sets the plugin element containing the PDF viewer. The element will usually
* be passed into the PDFScriptingAPI constructor but may also be set later.
* @param {Object} plugin the plugin element containing the PDF viewer.
*/
setPlugin: function(plugin) {
this.plugin_ = plugin;
// Send an initialization message to the plugin indicating the window to
// respond to.
if (this.plugin_) {
this.sendMessage_({
type: 'setParentWindow'
});
// Now we can flush pending messages
while (this.pendingScriptingMessages_.length > 0)
this.sendMessage_(this.pendingScriptingMessages_.shift());
}
},
/**
* Sets the callback which will be run when the PDF viewport changes.
* @param {Function} callback the callback to be called.
*/
setViewportChangedCallback: function(callback) {
this.viewportChangedCallback_ = callback;
},
/**
* Sets the callback which will be run when the PDF document has finished
* loading. If the document is already loaded, it will be run immediately.
* @param {Function} callback the callback to be called.
*/
setLoadCallback: function(callback) {
this.loadCallback_ = callback;
if (this.loaded_ && callback)
callback();
},
/**
* Resets the PDF viewer into print preview mode.
* @param {string} url the url of the PDF to load.
* @param {boolean} grayscale whether or not to display the PDF in grayscale.
* @param {Array.<number>} pageNumbers an array of the page numbers.
* @param {boolean} modifiable whether or not the document is modifiable.
*/
resetPrintPreviewMode: function(url, grayscale, pageNumbers, modifiable) {
this.sendMessage_({
type: 'resetPrintPreviewMode',
url: url,
grayscale: grayscale,
pageNumbers: pageNumbers,
modifiable: modifiable
});
},
/**
* Load a page into the document while in print preview mode.
* @param {string} url the url of the pdf page to load.
* @param {number} index the index of the page to load.
*/
loadPreviewPage: function(url, index) {
this.sendMessage_({
type: 'loadPreviewPage',
url: url,
index: index
});
},
/**
* Get accessibility JSON for the document.
* @param {Function} callback a callback to be called with the accessibility
* json that has been retrieved.
* @param {number} [page] the 0-indexed page number to get accessibility data
* for. If this is not provided, data about the entire document is
* returned.
* @return {boolean} true if the function is successful, false if there is an
* outstanding request for accessibility data that has not been answered.
*/
getAccessibilityJSON: function(callback, page) {
if (this.accessibilityCallback_)
return false;
this.accessibilityCallback_ = callback;
var message = {
type: 'getAccessibilityJSON',
};
if (page || page == 0)
message.page = page;
this.sendMessage_(message);
return true;
},
/**
* Send a key event to the extension.
* @param {number} keyCode the key code to send to the extension.
*/
sendKeyEvent: function(keyCode) {
this.sendMessage_({
type: 'sendKeyEvent',
keyCode: keyCode
});
},
};
/**
* Creates a PDF viewer with a scripting interface. This is basically 1) an
* iframe which is navigated to the PDF viewer extension and 2) a scripting
* interface which provides access to various features of the viewer for use
* by print preview and accessibility.
* @param {string} src the source URL of the PDF to load initially.
* @return {HTMLIFrameElement} the iframe element containing the PDF viewer.
*/
function PDFCreateOutOfProcessPlugin(src) {
var iframe = window.document.createElement('iframe');
iframe.setAttribute(
'src',
'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html?' + src);
var client = new PDFScriptingAPI(window);
iframe.onload = function() {
client.setPlugin(iframe.contentWindow);
};
// Add the functions to the iframe so that they can be called directly.
iframe.setViewportChangedCallback =
client.setViewportChangedCallback.bind(client);
iframe.setLoadCallback = client.setLoadCallback.bind(client);
iframe.resetPrintPreviewMode = client.resetPrintPreviewMode.bind(client);
iframe.loadPreviewPage = client.loadPreviewPage.bind(client);
iframe.sendKeyEvent = client.sendKeyEvent.bind(client);
return iframe;
}
|