[CRX] Add a pageAction to omnibox showing PDF URL
In Chromium extensions, the viewer's URL looks like this: chrome-extension://oemmndcbldboiebfnladdacbdfmadadm/http://example.com/file.pdf Furthermore, the PDF Viewer itself can also add something to the reference fragment: chrome-extension://oemmndcbldboiebfnladdacbdfmadadm/http://example.com/file.pdf#page=2 Consequently, it is difficult to copy a clean URL (e.g. for sharing over mail) without having to tidy-up the URL manually. This commit solves this issue by adding a button to the omnibox, which shows the clean PDF URL on click.
This commit is contained in:
parent
58807ec860
commit
8526d3c600
@ -22,6 +22,55 @@ limitations under the License.
|
|||||||
var VIEWER_URL = chrome.extension.getURL('content/web/viewer.html');
|
var VIEWER_URL = chrome.extension.getURL('content/web/viewer.html');
|
||||||
var CRX_BASE_URL = chrome.extension.getURL('/');
|
var CRX_BASE_URL = chrome.extension.getURL('/');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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) {
|
||||||
|
url = url.split('#')[0];
|
||||||
|
if (matchingUrl[1] === ':') {
|
||||||
|
url = encodeURIComponent(url);
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} url URL of PDF Viewer.
|
||||||
|
* @return {string|undefined} The percent-encoded URL of the (PDF) file.
|
||||||
|
*/
|
||||||
|
function parseViewerURL(url) {
|
||||||
|
if (url.lastIndexOf(VIEWER_URL, 0) !== 0) {
|
||||||
|
// Does not even start with the correct URL. Bye!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
url = url.match(/[&?]file=([^&#]+)/);
|
||||||
|
if (url) {
|
||||||
|
url = url[1];
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} tabId ID of tab where the page action will be shown
|
||||||
|
* @param {string} url URL to be displayed in page action
|
||||||
|
*/
|
||||||
|
function showPageAction(tabId, displayUrl) {
|
||||||
|
var url = parseExtensionURL(displayUrl) || parseViewerURL(displayUrl);
|
||||||
|
if (url) {
|
||||||
|
chrome.pageAction.setPopup({
|
||||||
|
tabId: tabId,
|
||||||
|
popup: 'pageActionPopup.html?file=' + url
|
||||||
|
});
|
||||||
|
chrome.pageAction.show(tabId);
|
||||||
|
} else {
|
||||||
|
console.log('Unable to get PDF url from ' + displayUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(rob): Use declarativeWebRequest once declared URL-encoding is
|
// TODO(rob): Use declarativeWebRequest once declared URL-encoding is
|
||||||
// supported, see http://crbug.com/273589
|
// supported, see http://crbug.com/273589
|
||||||
// (or rewrite the query string parser in viewer.js to get it to
|
// (or rewrite the query string parser in viewer.js to get it to
|
||||||
@ -29,14 +78,8 @@ limitations under the License.
|
|||||||
chrome.webRequest.onBeforeRequest.addListener(function(details) {
|
chrome.webRequest.onBeforeRequest.addListener(function(details) {
|
||||||
// This listener converts chrome-extension://.../http://...pdf to
|
// This listener converts chrome-extension://.../http://...pdf to
|
||||||
// chrome-extension://.../content/web/viewer.html?file=http%3A%2F%2F...pdf
|
// chrome-extension://.../content/web/viewer.html?file=http%3A%2F%2F...pdf
|
||||||
var url = details.url.substring(CRX_BASE_URL.length);
|
var url = parseExtensionURL(details.url);
|
||||||
var matchingUrl = /^(?:https?|file|ftp|chrome-extension)(:|%3A)/.exec(url);
|
if (url) {
|
||||||
if (matchingUrl) {
|
|
||||||
// location.hash is restored when "#" is missing from URL.
|
|
||||||
url = url.split('#')[0];
|
|
||||||
if (matchingUrl[1] === ':') {
|
|
||||||
url = encodeURIComponent(url);
|
|
||||||
}
|
|
||||||
url = VIEWER_URL + '?file=' + url;
|
url = VIEWER_URL + '?file=' + url;
|
||||||
console.log('Redirecting ' + details.url + ' to ' + url);
|
console.log('Redirecting ' + details.url + ' to ' + url);
|
||||||
return { redirectUrl: url };
|
return { redirectUrl: url };
|
||||||
@ -51,6 +94,15 @@ limitations under the License.
|
|||||||
]
|
]
|
||||||
}, ['blocking']);
|
}, ['blocking']);
|
||||||
|
|
||||||
|
chrome.runtime.onMessage.addListener(function(message, sender) {
|
||||||
|
if (message === 'showPageAction' && sender.tab) {
|
||||||
|
if (sender.tab.url === sender.url) {
|
||||||
|
// Only respond to messages from the top-level frame
|
||||||
|
showPageAction(sender.tab.id, sender.url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// When session restore is used, viewer pages may be loaded before the
|
// When session restore is used, viewer pages may be loaded before the
|
||||||
// webRequest event listener is attached (= page not found).
|
// webRequest event listener is attached (= page not found).
|
||||||
// Reload these tabs.
|
// Reload these tabs.
|
||||||
|
BIN
extensions/chromium/icon19.png
Normal file
BIN
extensions/chromium/icon19.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 787 B |
BIN
extensions/chromium/icon38.png
Normal file
BIN
extensions/chromium/icon38.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
@ -21,6 +21,14 @@
|
|||||||
"background": {
|
"background": {
|
||||||
"page": "pdfHandler.html"
|
"page": "pdfHandler.html"
|
||||||
},
|
},
|
||||||
|
"page_action": {
|
||||||
|
"default_icon": {
|
||||||
|
"19": "icon19.png",
|
||||||
|
"38": "icon38.png"
|
||||||
|
},
|
||||||
|
"default_title": "Show PDF URL",
|
||||||
|
"default_popup": "pageActionPopup.html"
|
||||||
|
},
|
||||||
"incognito": "split",
|
"incognito": "split",
|
||||||
"web_accessible_resources": [
|
"web_accessible_resources": [
|
||||||
"getFrameId",
|
"getFrameId",
|
||||||
|
43
extensions/chromium/pageActionPopup.html
Normal file
43
extensions/chromium/pageActionPopup.html
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<!--
|
||||||
|
Copyright 2012 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.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
/* maximum width of popup as defined in Chromium's source code as kMaxWidth
|
||||||
|
//src/chrome/browser/ui/views/extensions/extension_popup.cc
|
||||||
|
//src/chrome/browser/ui/gtk/extensions/extension_popup_gtk.cc
|
||||||
|
*/
|
||||||
|
width: 800px;
|
||||||
|
/* in case Chromium decides to lower the value of kMaxWidth */
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding: 5px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body contentEditable="plaintext-only">
|
||||||
|
<script src="pageActionPopup.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
22
extensions/chromium/pageActionPopup.js
Normal file
22
extensions/chromium/pageActionPopup.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/* Copyright 2012 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.
|
||||||
|
*/
|
||||||
|
var url = location.search.match(/[&?]file=([^&]+)/i);
|
||||||
|
if (url) {
|
||||||
|
url = decodeURIComponent(url[1]);
|
||||||
|
document.body.textContent = url;
|
||||||
|
// Set cursor to end of the content-editable section.
|
||||||
|
getSelection().selectAllChildren(document.body);
|
||||||
|
getSelection().collapseToEnd();
|
||||||
|
}
|
@ -143,6 +143,9 @@ var PDFHistory = {
|
|||||||
window.history.pushState(stateObj, '', document.URL);
|
window.history.pushState(stateObj, '', document.URL);
|
||||||
//#else
|
//#else
|
||||||
// window.history.pushState(stateObj, '');
|
// window.history.pushState(stateObj, '');
|
||||||
|
//#endif
|
||||||
|
//#if CHROME
|
||||||
|
// chrome.runtime.sendMessage('showPageAction');
|
||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1530,6 +1530,7 @@ var DocumentOutlineView = function documentOutlineView(outline) {
|
|||||||
// // Example: chrome-extension://.../http://example.com/file.pdf
|
// // Example: chrome-extension://.../http://example.com/file.pdf
|
||||||
// var humanReadableUrl = '/' + DEFAULT_URL + location.hash;
|
// var humanReadableUrl = '/' + DEFAULT_URL + location.hash;
|
||||||
// history.replaceState(history.state, '', humanReadableUrl);
|
// history.replaceState(history.state, '', humanReadableUrl);
|
||||||
|
// chrome.runtime.sendMessage('showPageAction');
|
||||||
// }
|
// }
|
||||||
//})();
|
//})();
|
||||||
//#endif
|
//#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user