Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / resources / pdf / pdf_scripting_api.js
blobfa570aeeb989b0d5f62c29660ceaf7cadb3d92a5
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 /**
6 * Turn a dictionary received from postMessage into a key event.
7 * @param {Object} dict A dictionary representing the key event.
8 * @return {Event} A key event.
9 */
10 function DeserializeKeyEvent(dict) {
11 var e = document.createEvent('Event');
12 e.initEvent('keydown');
13 e.keyCode = dict.keyCode;
14 e.shiftKey = dict.shiftKey;
15 e.ctrlKey = dict.ctrlKey;
16 e.altKey = dict.altKey;
17 e.metaKey = dict.metaKey;
18 e.fromScriptingAPI = true;
19 return e;
22 /**
23 * Turn a key event into a dictionary which can be sent over postMessage.
24 * @param {Event} event A key event.
25 * @return {Object} A dictionary representing the key event.
27 function SerializeKeyEvent(event) {
28 return {
29 keyCode: event.keyCode,
30 shiftKey: event.shiftKey,
31 ctrlKey: event.ctrlKey,
32 altKey: event.altKey,
33 metaKey: event.metaKey
37 /**
38 * Create a new PDFScriptingAPI. This provides a scripting interface to
39 * the PDF viewer so that it can be customized by things like print preview.
40 * @param {Window} window the window of the page containing the pdf viewer.
41 * @param {Object} plugin the plugin element containing the pdf viewer.
43 function PDFScriptingAPI(window, plugin) {
44 this.loaded_ = false;
45 this.pendingScriptingMessages_ = [];
46 this.setPlugin(plugin);
48 window.addEventListener('message', function(event) {
49 if (event.origin != 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai') {
50 console.error('Received message that was not from the extension: ' +
51 event);
52 return;
54 switch (event.data.type) {
55 case 'viewport':
56 if (this.viewportChangedCallback_)
57 this.viewportChangedCallback_(event.data.pageX,
58 event.data.pageY,
59 event.data.pageWidth,
60 event.data.viewportWidth,
61 event.data.viewportHeight);
62 break;
63 case 'documentLoaded':
64 this.loaded_ = true;
65 if (this.loadCallback_)
66 this.loadCallback_();
67 break;
68 case 'getAccessibilityJSONReply':
69 if (this.accessibilityCallback_) {
70 this.accessibilityCallback_(event.data.json);
71 this.accessibilityCallback_ = null;
73 break;
74 case 'getSelectedTextReply':
75 if (this.selectedTextCallback_) {
76 this.selectedTextCallback_(event.data.selectedText);
77 this.selectedTextCallback_ = null;
79 break;
80 case 'sendKeyEvent':
81 if (this.keyEventCallback_)
82 this.keyEventCallback_(DeserializeKeyEvent(event.data.keyEvent));
83 break;
85 }.bind(this), false);
88 PDFScriptingAPI.prototype = {
89 /**
90 * @private
91 * Send a message to the extension. If messages try to get sent before there
92 * is a plugin element set, then we queue them up and send them later (this
93 * can happen in print preview).
94 * @param {Object} message The message to send.
96 sendMessage_: function(message) {
97 if (this.plugin_)
98 this.plugin_.postMessage(message, '*');
99 else
100 this.pendingScriptingMessages_.push(message);
104 * Sets the plugin element containing the PDF viewer. The element will usually
105 * be passed into the PDFScriptingAPI constructor but may also be set later.
106 * @param {Object} plugin the plugin element containing the PDF viewer.
108 setPlugin: function(plugin) {
109 this.plugin_ = plugin;
111 if (this.plugin_) {
112 // Send a message to ensure the postMessage channel is initialized which
113 // allows us to receive messages.
114 this.sendMessage_({
115 type: 'initialize'
117 // Flush pending messages.
118 while (this.pendingScriptingMessages_.length > 0)
119 this.sendMessage_(this.pendingScriptingMessages_.shift());
124 * Sets the callback which will be run when the PDF viewport changes.
125 * @param {Function} callback the callback to be called.
127 setViewportChangedCallback: function(callback) {
128 this.viewportChangedCallback_ = callback;
132 * Sets the callback which will be run when the PDF document has finished
133 * loading. If the document is already loaded, it will be run immediately.
134 * @param {Function} callback the callback to be called.
136 setLoadCallback: function(callback) {
137 this.loadCallback_ = callback;
138 if (this.loaded_ && this.loadCallback_)
139 this.loadCallback_();
143 * Sets a callback that gets run when a key event is fired in the PDF viewer.
144 * @param {Function} callback the callback to be called with a key event.
146 setKeyEventCallback: function(callback) {
147 this.keyEventCallback_ = callback;
151 * Resets the PDF viewer into print preview mode.
152 * @param {string} url the url of the PDF to load.
153 * @param {boolean} grayscale whether or not to display the PDF in grayscale.
154 * @param {Array<number>} pageNumbers an array of the page numbers.
155 * @param {boolean} modifiable whether or not the document is modifiable.
157 resetPrintPreviewMode: function(url, grayscale, pageNumbers, modifiable) {
158 this.loaded_ = false;
159 this.sendMessage_({
160 type: 'resetPrintPreviewMode',
161 url: url,
162 grayscale: grayscale,
163 pageNumbers: pageNumbers,
164 modifiable: modifiable
169 * Load a page into the document while in print preview mode.
170 * @param {string} url the url of the pdf page to load.
171 * @param {number} index the index of the page to load.
173 loadPreviewPage: function(url, index) {
174 this.sendMessage_({
175 type: 'loadPreviewPage',
176 url: url,
177 index: index
182 * Get accessibility JSON for the document. May only be called after document
183 * load.
184 * @param {Function} callback a callback to be called with the accessibility
185 * json that has been retrieved.
186 * @param {number} [page] the 0-indexed page number to get accessibility data
187 * for. If this is not provided, data about the entire document is
188 * returned.
189 * @return {boolean} true if the function is successful, false if there is an
190 * outstanding request for accessibility data that has not been answered.
192 getAccessibilityJSON: function(callback, page) {
193 if (this.accessibilityCallback_)
194 return false;
195 this.accessibilityCallback_ = callback;
196 var message = {
197 type: 'getAccessibilityJSON',
199 if (page || page == 0)
200 message.page = page;
201 this.sendMessage_(message);
202 return true;
206 * Select all the text in the document. May only be called after document
207 * load.
209 selectAll: function() {
210 this.sendMessage_({
211 type: 'selectAll'
216 * Get the selected text in the document. The callback will be called with the
217 * text that is selected. May only be called after document load.
218 * @param {Function} callback a callback to be called with the selected text.
219 * @return {boolean} true if the function is successful, false if there is an
220 * outstanding request for selected text that has not been answered.
222 getSelectedText: function(callback) {
223 if (this.selectedTextCallback_)
224 return false;
225 this.selectedTextCallback_ = callback;
226 this.sendMessage_({
227 type: 'getSelectedText'
229 return true;
233 * Print the document. May only be called after document load.
235 print: function() {
236 this.sendMessage_({
237 type: 'print'
242 * Send a key event to the extension.
243 * @param {Event} keyEvent the key event to send to the extension.
245 sendKeyEvent: function(keyEvent) {
246 this.sendMessage_({
247 type: 'sendKeyEvent',
248 keyEvent: SerializeKeyEvent(keyEvent)
253 var IS_MAC_PARAM = 'isMac&';
256 * Creates a PDF viewer with a scripting interface. This is basically 1) an
257 * iframe which is navigated to the PDF viewer extension and 2) a scripting
258 * interface which provides access to various features of the viewer for use
259 * by print preview and accessibility.
260 * @param {string} src the source URL of the PDF to load initially.
261 * @return {HTMLIFrameElement} the iframe element containing the PDF viewer.
263 function PDFCreateOutOfProcessPlugin(src) {
264 var iframe = window.document.createElement('iframe');
265 var isMac = cr.isMac ? IS_MAC_PARAM : '';
266 iframe.setAttribute(
267 'src',
268 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html?' +
269 isMac + src);
270 // Prevent the frame from being tab-focusable.
271 iframe.setAttribute('tabindex', '-1');
272 var client = new PDFScriptingAPI(window);
273 iframe.onload = function() {
274 client.setPlugin(iframe.contentWindow);
276 // Add the functions to the iframe so that they can be called directly.
277 iframe.setViewportChangedCallback =
278 client.setViewportChangedCallback.bind(client);
279 iframe.setLoadCallback = client.setLoadCallback.bind(client);
280 iframe.setKeyEventCallback = client.setKeyEventCallback.bind(client);
281 iframe.resetPrintPreviewMode = client.resetPrintPreviewMode.bind(client);
282 iframe.loadPreviewPage = client.loadPreviewPage.bind(client);
283 iframe.sendKeyEvent = client.sendKeyEvent.bind(client);
284 return iframe;