Commit 859cc934 authored by rbpotter's avatar rbpotter Committed by Commit Bot

PDF viewer: Closure compile navigator

Bug: 721073
Change-Id: Iaef46bc33ba84563942b68d44a8684d8571914b8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1762544
Commit-Queue: Rebekah Potter <rbpotter@chromium.org>
Reviewed-by: default avatarDan Beam <dbeam@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#691896}
parent a9b47c9e
......@@ -1185,7 +1185,8 @@ IN_PROC_BROWSER_TEST_F(PDFExtensionTest, NavigationOnCorrectTab) {
ASSERT_TRUE(content::ExecuteScript(
guest_contents,
"viewer.navigator_.navigate("
" 'www.example.com', Navigator.WindowOpenDisposition.CURRENT_TAB);"));
" 'www.example.com',"
" PdfNavigator.WindowOpenDisposition.CURRENT_TAB);"));
navigation_observer.Wait();
EXPECT_FALSE(navigation_observer.last_navigation_url().is_empty());
......
......@@ -79,11 +79,19 @@ js_library("metrics") {
externs_list = [ "$externs_path/metrics_private.js" ]
}
js_library("navigator") {
deps = [
":open_pdf_params_parser",
":viewport",
]
}
js_type_check("pdf_resources") {
deps = [
":browser_api",
":gesture_detector",
":metrics",
":navigator",
":open_pdf_params_parser",
":pdf_fitting_type",
":pdf_scripting_api",
......
......@@ -5,42 +5,24 @@
'use strict';
/**
* Creates a new NavigatorDelegate for calling browser-specific functions to
* do the actual navigating.
*
* NavigatorDelegate for calling browser-specific functions to do the actual
* navigating.
*/
class NavigatorDelegate {
/**
* @param {number} tabId The tab ID of the PDF viewer or -1 if the viewer is
* not displayed in a tab.
* @constructor
*/
function NavigatorDelegate(tabId) {
constructor(tabId) {
/** @private {number} */
this.tabId_ = tabId;
}
/**
* Creates a new Navigator for navigating to links inside or outside the PDF.
*
* @param {string} originalUrl The original page URL.
* @param {Object} viewport The viewport info of the page.
* @param {Object} paramsParser The object for URL parsing.
* @param {Object} navigatorDelegate The object with callback functions that
* get called when navigation happens in the current tab, a new tab,
* and a new window.
* @constructor
*/
function Navigator(originalUrl, viewport, paramsParser, navigatorDelegate) {
this.originalUrl_ = originalUrl;
this.viewport_ = viewport;
this.paramsParser_ = paramsParser;
this.navigatorDelegate_ = navigatorDelegate;
}
}
NavigatorDelegate.prototype = {
/**
* Called when navigation should happen in the current tab.
*
* @param {string} url The url to be opened in the current tab.
*/
navigateInCurrentTab: function(url) {
navigateInCurrentTab(url) {
// When the PDFviewer is inside a browser tab, prefer the tabs API because
// it can navigate from one file:// URL to another.
if (chrome.tabs && this.tabId_ != -1) {
......@@ -48,15 +30,14 @@ NavigatorDelegate.prototype = {
} else {
window.location.href = url;
}
},
}
/**
* Called when navigation should happen in the new tab.
*
* @param {string} url The url to be opened in the new tab.
* @param {boolean} active Indicates if the new tab should be the active tab.
*/
navigateInNewTab: function(url, active) {
navigateInNewTab(url, active) {
// Prefer the tabs API because it guarantees we can just open a new tab.
// window.open doesn't have this guarantee.
if (chrome.tabs) {
......@@ -64,14 +45,13 @@ NavigatorDelegate.prototype = {
} else {
window.open(url);
}
},
}
/**
* Called when navigation should happen in the new window.
*
* @param {string} url The url to be opened in the new window.
*/
navigateInNewWindow: function(url) {
navigateInNewWindow(url) {
// Prefer the windows API because it guarantees we can just open a new
// window. window.open with '_blank' argument doesn't have this guarantee.
if (chrome.windows) {
......@@ -80,32 +60,33 @@ NavigatorDelegate.prototype = {
window.open(url, '_blank');
}
}
};
}
/**
* Represents options when navigating to a new url. C++ counterpart of
* the enum is in ui/base/window_open_disposition.h. This enum represents
* the only values that are passed from Plugin.
* @enum {number}
/** Navigator for navigating to links inside or outside the PDF. */
class PdfNavigator {
/**
* @param {string} originalUrl The original page URL.
* @param {!Viewport} viewport The viewport info of the page.
* @param {!OpenPdfParamsParser} paramsParser The object for URL parsing.
* @param {!NavigatorDelegate} navigatorDelegate The object with callback
* functions that get called when navigation happens in the current tab,
* a new tab, and a new window.
*/
Navigator.WindowOpenDisposition = {
CURRENT_TAB: 1,
NEW_FOREGROUND_TAB: 3,
NEW_BACKGROUND_TAB: 4,
NEW_WINDOW: 6,
SAVE_TO_DISK: 7
};
constructor(originalUrl, viewport, paramsParser, navigatorDelegate) {
this.originalUrl_ = originalUrl;
this.viewport_ = viewport;
this.paramsParser_ = paramsParser;
this.navigatorDelegate_ = navigatorDelegate;
}
Navigator.prototype = {
/**
* Function to navigate to the given URL. This might involve navigating
* within the PDF page or opening a new url (in the same tab or a new tab).
*
* @param {string} url The URL to navigate to.
* @param {number} disposition The window open disposition when
* navigating to the new URL.
* @param {!PdfNavigator.WindowOpenDisposition} disposition The window open
* disposition when navigating to the new URL.
*/
navigate: function(url, disposition) {
navigate(url, disposition) {
if (url.length == 0) {
return;
}
......@@ -133,20 +114,20 @@ Navigator.prototype = {
}
switch (disposition) {
case Navigator.WindowOpenDisposition.CURRENT_TAB:
case PdfNavigator.WindowOpenDisposition.CURRENT_TAB:
this.paramsParser_.getViewportFromUrlParams(
url, this.onViewportReceived_.bind(this));
break;
case Navigator.WindowOpenDisposition.NEW_BACKGROUND_TAB:
case PdfNavigator.WindowOpenDisposition.NEW_BACKGROUND_TAB:
this.navigatorDelegate_.navigateInNewTab(url, false);
break;
case Navigator.WindowOpenDisposition.NEW_FOREGROUND_TAB:
case PdfNavigator.WindowOpenDisposition.NEW_FOREGROUND_TAB:
this.navigatorDelegate_.navigateInNewTab(url, true);
break;
case Navigator.WindowOpenDisposition.NEW_WINDOW:
case PdfNavigator.WindowOpenDisposition.NEW_WINDOW:
this.navigatorDelegate_.navigateInNewWindow(url);
break;
case Navigator.WindowOpenDisposition.SAVE_TO_DISK:
case PdfNavigator.WindowOpenDisposition.SAVE_TO_DISK:
// TODO(jaepark): Alt + left clicking a link in PDF should
// download the link.
this.paramsParser_.getViewportFromUrlParams(
......@@ -155,16 +136,15 @@ Navigator.prototype = {
default:
break;
}
},
}
/**
* Called when the viewport position is received.
*
* @param {Object} viewportPosition Dictionary containing the viewport
* position.
* @private
*/
onViewportReceived_: function(viewportPosition) {
onViewportReceived_(viewportPosition) {
let originalUrl = this.originalUrl_;
let hashIndex = originalUrl.search('#');
if (hashIndex != -1) {
......@@ -183,16 +163,16 @@ Navigator.prototype = {
} else {
this.navigatorDelegate_.navigateInCurrentTab(viewportPosition.url);
}
},
}
/**
* Checks if the URL starts with a scheme and is not just a scheme.
*
* TODO (rbpotter): Update to use URL (here and elsewhere in this file).
* @param {string} url The input URL
* @return {boolean} Whether the url is valid.
* @private
*/
isValidUrl_: function(url) {
isValidUrl_(url) {
// Make sure |url| starts with a valid scheme.
if (!url.startsWith('http://') && !url.startsWith('https://') &&
!url.startsWith('ftp://') && !url.startsWith('file://') &&
......@@ -213,17 +193,16 @@ Navigator.prototype = {
}
return true;
},
}
/**
* Attempt to figure out what a URL is when there is no scheme.
*
* @param {string} url The input URL
* @return {string} The URL with a scheme or the original URL if it is not
* possible to determine the scheme.
* @private
*/
guessUrlWithoutScheme_: function(url) {
guessUrlWithoutScheme_(url) {
// If the original URL is mailto:, that does not make sense to start with,
// and neither does adding |url| to it.
// If the original URL is not a valid URL, this cannot make a valid URL.
......@@ -276,4 +255,18 @@ Navigator.prototype = {
return 'http://' + url;
}
}
/**
* Represents options when navigating to a new url. C++ counterpart of
* the enum is in ui/base/window_open_disposition.h. This enum represents
* the only values that are passed from Plugin.
* @enum {number}
*/
PdfNavigator.WindowOpenDisposition = {
CURRENT_TAB: 1,
NEW_FOREGROUND_TAB: 3,
NEW_BACKGROUND_TAB: 4,
NEW_WINDOW: 6,
SAVE_TO_DISK: 7
};
......@@ -2,15 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(function() {
'use strict';
/**
* Parses the open pdf parameters passed in the url to set initial viewport
* settings for opening the pdf.
*/
window.OpenPDFParamsParser = class {
class OpenPdfParamsParser {
/**
* @param {function(Object)} postMessageCallback
* Function called to fetch information for a named destination.
......@@ -206,6 +204,4 @@ window.OpenPDFParamsParser = class {
}
outstandingRequest.callback(outstandingRequest.params);
}
};
}());
}
......@@ -151,7 +151,7 @@ function PDFViewer(browserApi) {
PDFMetrics.record(PDFMetrics.UserAction.DOCUMENT_OPENED);
// Parse open pdf parameters.
this.paramsParser_ = new OpenPDFParamsParser(
this.paramsParser_ = new OpenPdfParamsParser(
message => this.pluginController_.postMessage(message));
const toolbarEnabled =
this.paramsParser_.getUiUrlParams(this.originalUrl_).toolbar &&
......@@ -293,8 +293,8 @@ function PDFViewer(browserApi) {
document.body.addEventListener('navigate', e => {
const disposition = e.detail.newtab ?
Navigator.WindowOpenDisposition.NEW_BACKGROUND_TAB :
Navigator.WindowOpenDisposition.CURRENT_TAB;
PdfNavigator.WindowOpenDisposition.NEW_BACKGROUND_TAB :
PdfNavigator.WindowOpenDisposition.CURRENT_TAB;
this.navigator_.navigate(e.detail.uri, disposition);
});
......@@ -324,7 +324,7 @@ function PDFViewer(browserApi) {
'contextmenu', e => this.handleContextMenuEvent_(e));
const tabId = this.browserApi_.getStreamInfo().tabId;
this.navigator_ = new Navigator(
this.navigator_ = new PdfNavigator(
this.originalUrl_, this.viewport_, this.paramsParser_,
new NavigatorDelegate(tabId));
this.viewportScroller_ =
......@@ -1143,7 +1143,8 @@ PDFViewer.prototype = {
handleNavigate: function(url, disposition) {
// If in print preview, always open a new tab.
if (this.isPrintPreview_) {
this.navigator_.navigate(url, Navigator.WindowOpenDisposition.NEW_BACKGROUND_TAB);
this.navigator_.navigate(
url, PdfNavigator.WindowOpenDisposition.NEW_BACKGROUND_TAB);
} else {
this.navigator_.navigate(url, disposition);
}
......
......@@ -2,28 +2,32 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function MockNavigatorDelegate() {
class MockNavigatorDelegate {
constructor() {
this.navigateInCurrentTabCalled = false;
this.navigateInNewTabCalled = false;
this.navigateInNewWindowCalled = false;
this.url = undefined;
}
}
MockNavigatorDelegate.prototype = {
navigateInCurrentTab: function(url) {
/** @param {?string} url */
navigateInCurrentTab(url) {
this.navigateInCurrentTabCalled = true;
this.url = url || '<called, but no url set>';
},
navigateInNewTab: function(url) {
}
/** @param {?string} url */
navigateInNewTab(url) {
this.navigateInNewTabCalled = true;
this.url = url || '<called, but no url set>';
}
},
navigateInNewWindow: function(url) {
navigateInNewWindow(url) {
this.navigateInNewWindowCalled = true;
this.url = url || '<called, but no url set>';
},
reset: function() {
}
reset() {
this.navigateInCurrentTabCalled = false;
this.navigateInNewTabCalled = false;
this.navigateInNewWindowCalled = false;
......@@ -53,13 +57,13 @@ function doNavigationUrlTest(
return;
}
switch (disposition) {
case Navigator.WindowOpenDisposition.CURRENT_TAB:
case PdfNavigator.WindowOpenDisposition.CURRENT_TAB:
chrome.test.assertTrue(navigatorDelegate.navigateInCurrentTabCalled);
break;
case Navigator.WindowOpenDisposition.NEW_BACKGROUND_TAB:
case PdfNavigator.WindowOpenDisposition.NEW_BACKGROUND_TAB:
chrome.test.assertTrue(navigatorDelegate.navigateInNewTabCalled);
break;
case Navigator.WindowOpenDisposition.NEW_WINDOW:
case PdfNavigator.WindowOpenDisposition.NEW_WINDOW:
chrome.test.assertTrue(navigatorDelegate.navigateInNewWindowCalled);
break;
default:
......@@ -78,23 +82,23 @@ function doNavigationUrlTests(originalUrl, url, expectedResultUrl) {
var viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
viewport.setViewportChangedCallback(mockViewportChangedCallback.callback);
var paramsParser = new OpenPDFParamsParser(function(name) {
var paramsParser = new OpenPdfParamsParser(function(name) {
paramsParser.onNamedDestinationReceived(-1);
});
var navigatorDelegate = new MockNavigatorDelegate();
var navigator = new Navigator(originalUrl, viewport, paramsParser,
navigatorDelegate);
doNavigationUrlTest(navigator, url,
Navigator.WindowOpenDisposition.CURRENT_TAB, expectedResultUrl,
mockViewportChangedCallback, navigatorDelegate);
doNavigationUrlTest(navigator, url,
Navigator.WindowOpenDisposition.NEW_BACKGROUND_TAB, expectedResultUrl,
mockViewportChangedCallback, navigatorDelegate);
doNavigationUrlTest(navigator, url,
Navigator.WindowOpenDisposition.NEW_WINDOW, expectedResultUrl,
mockViewportChangedCallback, navigatorDelegate);
var navigator =
new PdfNavigator(originalUrl, viewport, paramsParser, navigatorDelegate);
doNavigationUrlTest(
navigator, url, PdfNavigator.WindowOpenDisposition.CURRENT_TAB,
expectedResultUrl, mockViewportChangedCallback, navigatorDelegate);
doNavigationUrlTest(
navigator, url, PdfNavigator.WindowOpenDisposition.NEW_BACKGROUND_TAB,
expectedResultUrl, mockViewportChangedCallback, navigatorDelegate);
doNavigationUrlTest(
navigator, url, PdfNavigator.WindowOpenDisposition.NEW_WINDOW,
expectedResultUrl, mockViewportChangedCallback, navigatorDelegate);
}
var tests = [
......@@ -109,7 +113,7 @@ var tests = [
var viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
viewport.setViewportChangedCallback(mockCallback.callback);
var paramsParser = new OpenPDFParamsParser(function(message) {
var paramsParser = new OpenPdfParamsParser(function(message) {
if (message.namedDestination == 'US')
paramsParser.onNamedDestinationReceived(0);
else if (message.namedDestination == 'UY')
......@@ -120,8 +124,8 @@ var tests = [
var url = "http://xyz.pdf";
var navigatorDelegate = new MockNavigatorDelegate();
var navigator = new Navigator(url, viewport, paramsParser,
navigatorDelegate);
var navigator =
new PdfNavigator(url, viewport, paramsParser, navigatorDelegate);
var documentDimensions = new MockDocumentDimensions();
documentDimensions.addPage(100, 100);
......@@ -132,8 +136,8 @@ var tests = [
mockCallback.reset();
// This should move viewport to page 0.
navigator.navigate(url + "#US",
Navigator.WindowOpenDisposition.CURRENT_TAB);
navigator.navigate(
url + '#US', PdfNavigator.WindowOpenDisposition.CURRENT_TAB);
chrome.test.assertTrue(mockCallback.wasCalled);
chrome.test.assertEq(0, viewport.position.x);
chrome.test.assertEq(0, viewport.position.y);
......@@ -142,8 +146,8 @@ var tests = [
navigatorDelegate.reset();
// This should open "http://xyz.pdf#US" in a new tab. So current tab
// viewport should not update and viewport position should remain same.
navigator.navigate(url + "#US",
Navigator.WindowOpenDisposition.NEW_BACKGROUND_TAB);
navigator.navigate(
url + '#US', PdfNavigator.WindowOpenDisposition.NEW_BACKGROUND_TAB);
chrome.test.assertFalse(mockCallback.wasCalled);
chrome.test.assertTrue(navigatorDelegate.navigateInNewTabCalled);
chrome.test.assertEq(0, viewport.position.x);
......@@ -151,8 +155,8 @@ var tests = [
mockCallback.reset();
// This should move viewport to page 2.
navigator.navigate(url + "#UY",
Navigator.WindowOpenDisposition.CURRENT_TAB);
navigator.navigate(
url + '#UY', PdfNavigator.WindowOpenDisposition.CURRENT_TAB);
chrome.test.assertTrue(mockCallback.wasCalled);
chrome.test.assertEq(0, viewport.position.x);
chrome.test.assertEq(300, viewport.position.y);
......@@ -162,8 +166,8 @@ var tests = [
// #ABC is not a named destination in the page so viewport should not
// update and viewport position should remain same. As this link will open
// in the same tab.
navigator.navigate(url + "#ABC",
Navigator.WindowOpenDisposition.CURRENT_TAB);
navigator.navigate(
url + '#ABC', PdfNavigator.WindowOpenDisposition.CURRENT_TAB);
chrome.test.assertFalse(mockCallback.wasCalled);
chrome.test.assertTrue(navigatorDelegate.navigateInCurrentTabCalled);
chrome.test.assertEq(0, viewport.position.x);
......
......@@ -7,7 +7,7 @@ var tests = [
* Test named destinations.
*/
function testParamsParser() {
var paramsParser = new OpenPDFParamsParser(function(message) {
var paramsParser = new OpenPdfParamsParser(function(message) {
chrome.test.assertEq('getNamedDestination', message.type);
if (message.namedDestination == 'RU')
paramsParser.onNamedDestinationReceived(26);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment