diff --git a/extensions/chromium/extension-router.js b/extensions/chromium/extension-router.js index d3c7d52b1..e56c45fa0 100644 --- a/extensions/chromium/extension-router.js +++ b/extensions/chromium/extension-router.js @@ -22,16 +22,33 @@ limitations under the License. var VIEWER_URL = chrome.extension.getURL('content/web/viewer.html'); var CRX_BASE_URL = chrome.extension.getURL('/'); + var schemes = [ + 'http', + 'https', + 'ftp', + 'file', + 'chrome-extension', + // Chromium OS + 'filesystem', + // Chromium OS, shorthand for filesystem:/external/ + 'drive' + ]; + /** * @param {string} url The URL prefixed with chrome-extension://.../ * @return {string|undefined} The percent-encoded URL of the (PDF) file. */ function parseExtensionURL(url) { url = url.substring(CRX_BASE_URL.length); - var matchingUrl = /^(?:https?|file|ftp|chrome-extension)(:|%3A)/i.exec(url); - if (matchingUrl) { + // Find the (url-encoded) colon and verify that the scheme is whitelisted. + var schemeIndex = url.search(/:|%3A/i); + if (schemeIndex === -1) { + return; + } + var scheme = url.slice(0, schemeIndex).toLowerCase(); + if (schemes.indexOf(scheme) >= 0) { url = url.split('#')[0]; - if (matchingUrl[1] === ':') { + if (url.charAt(schemeIndex) === ':') { url = encodeURIComponent(url); } return url; @@ -86,12 +103,10 @@ limitations under the License. } }, { types: ['main_frame', 'sub_frame'], - urls: [ - CRX_BASE_URL + 'http*', // and https - CRX_BASE_URL + 'file*', - CRX_BASE_URL + 'ftp*', - CRX_BASE_URL + 'chrome-extension*' - ] + urls: schemes.map(function(scheme) { + // Format: "chrome-extension://[EXTENSIONID]/*" + return CRX_BASE_URL + scheme + '*'; + }) }, ['blocking']); chrome.runtime.onMessage.addListener(function(message, sender) { @@ -104,7 +119,7 @@ limitations under the License. // webRequest event listener is attached (= page not found). // Reload these tabs. chrome.tabs.query({ - url: CRX_BASE_URL + '*://*' + url: CRX_BASE_URL + '*:*' }, function(tabsFromLastSession) { for (var i = 0; i < tabsFromLastSession.length; ++i) { chrome.tabs.reload(tabsFromLastSession[i].id); diff --git a/extensions/chromium/manifest.json b/extensions/chromium/manifest.json index cd760480b..a70994830 100644 --- a/extensions/chromium/manifest.json +++ b/extensions/chromium/manifest.json @@ -9,6 +9,7 @@ "16": "icon16.png" }, "permissions": [ + "fileBrowserHandler", "webRequest", "webRequestBlocking", "", "tabs", @@ -25,6 +26,13 @@ ], "js": ["nothing.js"] }], + "file_browser_handlers": [{ + "id": "open-as-pdf", + "default_title": "Open with PDF Viewer", + "file_filters": [ + "filesystem:*.pdf" + ] + }], "mime_types": [ "application/pdf" ], @@ -47,6 +55,8 @@ "https:/*", "ftp:/*", "file:/*", - "chrome-extension:/*" + "chrome-extension:/*", + "filesystem:/*", + "drive:*" ] } diff --git a/extensions/chromium/pdfHandler-vcros.js b/extensions/chromium/pdfHandler-vcros.js new file mode 100644 index 000000000..4fb7b3614 --- /dev/null +++ b/extensions/chromium/pdfHandler-vcros.js @@ -0,0 +1,95 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ +/* +Copyright 2014 Mozilla Foundation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +/* globals chrome, getViewerURL */ + +(function() { +'use strict'; + +if (!chrome.fileBrowserHandler) { + // Not on Chromium OS, bail out + return; +} +chrome.fileBrowserHandler.onExecute.addListener(onExecuteFileBrowserHandler); + +/** + * Invoked when "Open with PDF Viewer" is chosen in the File browser. + * + * @param {String} id File browser action ID as specified in manifest.json + * @param {Object} details Object of type FileHandlerExecuteEventDetails + */ +function onExecuteFileBrowserHandler(id, details) { + if (id !== 'open-as-pdf') { + return; + } + var fileEntries = details.entries; + // "tab_id" is the currently documented format, but it is inconsistent with + // the other Chrome APIs that use "tabId" (http://crbug.com/179767) + var tabId = details.tab_id || details.tabId; + if (tabId > 0) { + chrome.tabs.get(tabId, function(tab) { + openViewer(tab && tab.windowId, fileEntries); + }); + } else { + // Re-use existing window, if available. + chrome.windows.getLastFocused(function(chromeWindow) { + var windowId = chromeWindow && chromeWindow.id; + if (windowId) { + chrome.windows.update(windowId, { focused: true }); + } + openViewer(windowId, fileEntries); + }); + } +} + +/** + * Open the PDF Viewer for the given list of PDF files. + * + * @param {number} windowId + * @param {Array} fileEntries List of Entry objects (HTML5 FileSystem API) + */ +function openViewer(windowId, fileEntries) { + if (!fileEntries.length) { + return; + } + var fileEntry = fileEntries.shift(); + var url = fileEntry.toURL(); + // Use drive: alias to get shorter (more human-readable) URLs. + url = url.replace(/^filesystem:chrome-extension:\/\/[a-p]{32}\/external\//, + 'drive:'); + url = getViewerURL(url); + + if (windowId) { + chrome.tabs.create({ + windowId: windowId, + active: true, + url: url + }, function() { + openViewer(windowId, fileEntries); + }); + } else { + chrome.windows.create({ + type: 'normal', + focused: true, + url: url + }, function(chromeWindow) { + openViewer(chromeWindow.id, fileEntries); + }); + } +} + +})(); diff --git a/extensions/chromium/pdfHandler.html b/extensions/chromium/pdfHandler.html index df35754e0..ffb6c1ae6 100644 --- a/extensions/chromium/pdfHandler.html +++ b/extensions/chromium/pdfHandler.html @@ -18,3 +18,4 @@ limitations under the License. + diff --git a/web/viewer.js b/web/viewer.js index 4cd233be5..f85f3c5a0 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -1588,6 +1588,9 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) { //#endif //#if CHROME //var file = DEFAULT_URL; +//// XHR cannot get data from drive:-URLs, so expand to filesystem: (Chrome OS) +//file = file.replace(/^drive:/i, +// 'filesystem:' + location.origin + '/external/'); //#endif //#if !(FIREFOX || MOZCENTRAL || CHROME || B2G)