summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/resources/pdf
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-10-13 13:24:50 +0200
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-10-14 10:57:25 +0000
commitaf3d4809763ef308f08ced947a73b624729ac7ea (patch)
tree4402b911e30383f6c6dace1e8cf3b8e85355db3a /chromium/chrome/browser/resources/pdf
parent0e8ff63a407fe323e215bb1a2c423c09a4747c8a (diff)
BASELINE: Update Chromium to 47.0.2526.14
Also adding in sources needed for spellchecking. Change-Id: Idd44170fa1616f26315188970a8d5ba7d472b18a Reviewed-by: Michael BrĂ¼ning <michael.bruning@theqtcompany.com>
Diffstat (limited to 'chromium/chrome/browser/resources/pdf')
-rw-r--r--chromium/chrome/browser/resources/pdf/browser_api.js41
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/shared-icon-style.css15
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css34
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html13
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.js61
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.html2
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.js4
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.css19
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.html14
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.js27
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.css45
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.html10
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.js35
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.css39
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.html31
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.js29
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.css58
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html50
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js18
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.css13
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html5
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js15
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css21
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html9
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js118
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css16
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html16
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js125
-rw-r--r--chromium/chrome/browser/resources/pdf/index-material.css42
-rw-r--r--chromium/chrome/browser/resources/pdf/index-material.html13
-rw-r--r--chromium/chrome/browser/resources/pdf/index.html2
-rw-r--r--chromium/chrome/browser/resources/pdf/manifest.json6
-rw-r--r--chromium/chrome/browser/resources/pdf/navigator.js110
-rw-r--r--chromium/chrome/browser/resources/pdf/pdf.js282
-rw-r--r--chromium/chrome/browser/resources/pdf/pdf_scripting_api.js27
-rw-r--r--chromium/chrome/browser/resources/pdf/settings.js5
-rw-r--r--chromium/chrome/browser/resources/pdf/toolbar_manager.js221
-rw-r--r--chromium/chrome/browser/resources/pdf/ui_manager.js106
-rw-r--r--chromium/chrome/browser/resources/pdf/viewport.js100
-rw-r--r--chromium/chrome/browser/resources/pdf/zoom_manager.js6
40 files changed, 1218 insertions, 585 deletions
diff --git a/chromium/chrome/browser/resources/pdf/browser_api.js b/chromium/chrome/browser/resources/pdf/browser_api.js
index 5ba5c49d491..53f14b5460e 100644
--- a/chromium/chrome/browser/resources/pdf/browser_api.js
+++ b/chromium/chrome/browser/resources/pdf/browser_api.js
@@ -25,6 +25,26 @@ function lookupDefaultZoom(streamInfo) {
}
/**
+ * Returns a promise that will resolve to the initial zoom factor
+ * upon starting the plugin. This may differ from the default zoom
+ * if, for example, the page is zoomed before the plugin is run.
+ * @param {!Object} streamInfo The stream object pointing to the data contained
+ * in the PDF.
+ * @return {Promise<number>} A promise that will resolve to the initial zoom
+ * factor.
+ */
+function lookupInitialZoom(streamInfo) {
+ // Webviews don't run in tabs so |streamInfo.tabId| is -1 when running within
+ // a webview.
+ if (!chrome.tabs || streamInfo.tabId < 0)
+ return Promise.resolve(1);
+
+ return new Promise(function(resolve, reject) {
+ chrome.tabs.getZoom(streamInfo.tabId, resolve);
+ });
+}
+
+/**
* A class providing an interface to the browser.
*/
class BrowserApi {
@@ -33,11 +53,14 @@ class BrowserApi {
* @param {!Object} streamInfo The stream object which points to the data
* contained in the PDF.
* @param {number} defaultZoom The default browser zoom.
+ * @param {number} initialZoom The initial browser zoom
+ * upon starting the plugin.
* @param {boolean} manageZoom Whether to manage zoom.
*/
- constructor(streamInfo, defaultZoom, manageZoom) {
+ constructor(streamInfo, defaultZoom, initialZoom, manageZoom) {
this.streamInfo_ = streamInfo;
this.defaultZoom_ = defaultZoom;
+ this.initialZoom_ = initialZoom;
this.manageZoom_ = manageZoom;
}
@@ -48,8 +71,12 @@ class BrowserApi {
* @param {boolean} manageZoom Whether to manage zoom.
*/
static create(streamInfo, manageZoom) {
- return lookupDefaultZoom(streamInfo).then(function(defaultZoom) {
- return new BrowserApi(streamInfo, defaultZoom, manageZoom);
+ return Promise.all([
+ lookupDefaultZoom(streamInfo),
+ lookupInitialZoom(streamInfo)
+ ]).then(function(zoomFactors) {
+ return new BrowserApi(
+ streamInfo, zoomFactors[0], zoomFactors[1], manageZoom);
});
}
@@ -92,6 +119,14 @@ class BrowserApi {
}
/**
+ * Returns the initial browser zoom factor.
+ * @return {number} The initial browser zoom factor.
+ */
+ getInitialZoom() {
+ return this.initialZoom_;
+ }
+
+ /**
* Adds an event listener to be notified when the browser zoom changes.
* @param {function} listener The listener to be called with the new zoom
* factor.
diff --git a/chromium/chrome/browser/resources/pdf/elements/shared-icon-style.css b/chromium/chrome/browser/resources/pdf/elements/shared-icon-style.css
new file mode 100644
index 00000000000..6611e9e09c7
--- /dev/null
+++ b/chromium/chrome/browser/resources/pdf/elements/shared-icon-style.css
@@ -0,0 +1,15 @@
+/* Copyright 2015 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. */
+
+:root {
+ --iron-icon-height: 20px;
+ --iron-icon-width: 20px;
+ --paper-icon-button: {
+ height: 20px;
+ padding: 6px;
+ width: 20px;
+ };
+ --paper-icon-button-ink-color: rgb(189, 189, 189);
+ --viewer-icon-ink-color: rgb(189, 189, 189);
+}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css
index ed9c5746609..58b4cde1726 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css
@@ -3,17 +3,41 @@
* found in the LICENSE file. */
#item {
- -webkit-user-select: none;
+ @apply(--layout-center);
+ @apply(--layout-horizontal);
color: rgb(80, 80, 80);
cursor: pointer;
- min-height: 40px;
+ font-size: 77.8%;
+ height: 30px;
position: relative;
- @apply(--paper-font-subhead);
- @apply(--layout-horizontal);
- @apply(--layout-center);
}
#item:hover {
background-color: rgb(237, 237, 237);
color: rgb(20, 20, 20);
}
+
+#title {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+#expand {
+ --iron-icon-height: 16px;
+ --iron-icon-width: 16px;
+ --paper-icon-button-ink-color: var(--paper-grey-900);
+ height: 16px;
+ min-width: 16px;
+ padding: 6px;
+ transition: transform 150ms;
+ width: 16px;
+}
+
+:host-context([dir=rtl]) #expand {
+ transform: rotate(180deg);
+}
+
+:host([children-shown]) #expand {
+ transform: rotate(90deg);
+}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html
index 9328289811e..008eef63037 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html
@@ -6,17 +6,20 @@
<link rel="import" type="css" href="viewer-bookmark.css">
<template>
<div id="item" on-click="onClick">
- <span>{{bookmark.title}}</span>
<paper-ripple></paper-ripple>
+ <paper-icon-button id="expand" icon="chevron-right"
+ on-click="toggleChildren">
+ </paper-icon-button>
+ <span id="title" tabindex="0">{{bookmark.title}}</span>
</div>
- <div class="sub-bookmark">
- <!-- The sub-bookmarks will only be created after the parent bookmark has
- finished initializing and childDepth is available. -->
+ <!-- dom-if will stamp the complex bookmark tree lazily as individual nodes
+ are opened. -->
+ <template is="dom-if" if="{{childrenShown}}" id="sub-bookmarks">
<template is="dom-repeat" items="{{bookmark.children}}">
<viewer-bookmark bookmark="{{item}}" depth="{{childDepth}}">
</viewer-bookmark>
</template>
- </div>
+ </template>
</template>
</dom-module>
<script src="viewer-bookmark.js"></script>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.js b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.js
index 4f555296490..7905ea4ec34 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.js
@@ -3,8 +3,8 @@
// found in the LICENSE file.
(function() {
- // Amount that each level of bookmarks is indented by (px).
- var BOOKMARK_INDENT = 16;
+ /** Amount that each level of bookmarks is indented by (px). */
+ var BOOKMARK_INDENT = 20;
Polymer({
is: 'viewer-bookmark',
@@ -16,24 +16,75 @@
* - page (optional)
* - children (an array of bookmarks)
*/
- bookmark: Object,
+ bookmark: {
+ type: Object,
+ observer: 'bookmarkChanged_'
+ },
depth: {
type: Number,
observer: 'depthChanged'
},
- childDepth: Number
+ childDepth: Number,
+
+ childrenShown: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false
+ },
+
+ keyEventTarget: {
+ type: Object,
+ value: function() {
+ return this.$.item;
+ }
+ }
+ },
+
+ behaviors: [
+ Polymer.IronA11yKeysBehavior
+ ],
+
+ keyBindings: {
+ 'enter': 'onEnter_',
+ 'space': 'onSpace_'
+ },
+
+ bookmarkChanged_: function() {
+ this.$.expand.style.visibility =
+ this.bookmark.children.length > 0 ? 'visible' : 'hidden';
},
depthChanged: function() {
this.childDepth = this.depth + 1;
- this.$.item.style.paddingLeft = (this.depth * BOOKMARK_INDENT) + 'px';
+ this.$.item.style.webkitPaddingStart =
+ (this.depth * BOOKMARK_INDENT) + 'px';
},
onClick: function() {
if (this.bookmark.hasOwnProperty('page'))
this.fire('change-page', {page: this.bookmark.page});
},
+
+ onEnter_: function(e) {
+ // Don't allow events which have propagated up from the expand button to
+ // trigger a click.
+ if (e.detail.keyboardEvent.target != this.$.expand)
+ this.onClick();
+ },
+
+ onSpace_: function(e) {
+ // paper-icon-button stops propagation of space events, so there's no need
+ // to check the event source here.
+ this.onClick();
+ // Prevent default space scroll behavior.
+ e.detail.keyboardEvent.preventDefault();
+ },
+
+ toggleChildren: function(e) {
+ this.childrenShown = !this.childrenShown;
+ e.stopPropagation(); // Prevent the above onClick handler from firing.
+ }
});
})();
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.html b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.html
index 336ca3a1e32..3f9b6847984 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.html
@@ -4,7 +4,7 @@
<dom-module id="viewer-bookmarks-content">
<template>
<template is="dom-repeat" items="{{bookmarks}}">
- <viewer-bookmark bookmark="{{item}}" depth="1"></viewer-bookmark>
+ <viewer-bookmark bookmark="{{item}}" depth="0"></viewer-bookmark>
</template>
</template>
</dom-module>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.js b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.js
index abd56be2b3a..cd09aed83be 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.js
@@ -6,5 +6,9 @@ Polymer({
is: 'viewer-error-screen-legacy',
properties: {
text: String
+ },
+
+ show: function() {
+ this.style.visibility = 'visible';
}
});
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.css b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.css
index 07ee91dd908..e1e91bd9b39 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.css
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.css
@@ -2,21 +2,6 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-:host {
- background-color: #ccc;
- color: #555;
- font-family: sans-serif;
- font-size: 20px;
- height: 100%;
- pointer-events: none;
- position: fixed;
- text-align: center;
- width: 100%;
+.last-item {
+ margin-bottom: 24px;
}
-
-#load-failed-message {
- line-height: 0;
- position: absolute;
- top: 50%;
- width: 100%;
-} \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.html b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.html
index 24344a23b5c..2795dfbdccd 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.html
@@ -1,9 +1,21 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/fade-in-animation.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html">
<dom-module id="viewer-error-screen">
<link rel="import" type="css" href="viewer-error-screen.css">
<template>
- <div id="load-failed-message">{{text}}</div>
+ <paper-dialog id="dialog" modal no-cancel-on-esc-key
+ entry-animation="fade-in-animation">
+ <div id="load-failed-message"
+ class="last-item">{{strings.pageLoadFailed}}</div>
+ <div class="buttons" hidden$="{{!reloadFn}}">
+ <paper-button on-click="reload" autofocus>
+ <span>{{strings.pageReload}}</span>
+ </paper-button>
+ </div>
+ </paper-dialog>
</template>
</dom-module>
<script src="viewer-error-screen.js"></script>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.js b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.js
index 905c8a0d7a4..88d24a6c459 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.js
@@ -5,6 +5,31 @@
Polymer({
is: 'viewer-error-screen',
properties: {
- text: String
+ strings: Object,
+
+ reloadFn: {
+ type: Object,
+ value: null,
+ observer: 'reloadFnChanged_'
+ }
+ },
+
+ reloadFnChanged_: function() {
+ // The default margins in paper-dialog don't work well with hiding/showing
+ // the .buttons div. We need to manually manage the bottom margin to get
+ // around this.
+ if (this.reloadFn)
+ this.$['load-failed-message'].classList.remove('last-item');
+ else
+ this.$['load-failed-message'].classList.add('last-item');
+ },
+
+ show: function() {
+ this.$.dialog.open();
+ },
+
+ reload: function() {
+ if (this.reloadFn)
+ this.reloadFn();
}
});
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.css b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.css
index 1f858bc2b64..ab14b2587dc 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.css
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.css
@@ -2,29 +2,29 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-#pageselector {
- display: inline-block;
- width: 0.6em;
-}
-
-paper-input-container /deep/ .focused-line {
- visibility: hidden;
-}
-
-paper-input-container /deep/ .unfocused-line {
- visibility: hidden;
+:host {
+ color: #fff;
+ font-size: 88.8%;
}
-paper-input-container {
+#pageselector {
+ --paper-input-container-underline: {
+ visibility: hidden;
+ };
+ --paper-input-container-underline-focus: {
+ visibility: hidden;
+ };
+ display: inline-block;
padding: 0;
+ width: 1ch;
}
input#input {
+ -webkit-margin-start: -3px;
color: #fff;
- font-size: 1em;
- line-height: 20px;
+ line-height: 18px;
padding: 3px;
- text-align: right;
+ text-align: end;
}
input#input:focus,
@@ -33,9 +33,16 @@ input#input:hover {
border-radius: 2px;
}
+#slash {
+ padding: 0 3px;
+}
+
+#pagelength-spacer {
+ display: inline-block;
+ text-align: start;
+}
+
+#slash,
#pagelength {
- color: #fff;
- font-size: 0.7em;
- font-weight: 400;
- padding-left: 3px;
+ font-size: 81.25%;
}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.html b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.html
index 82fc8975526..c686c3ef63b 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.html
@@ -6,10 +6,14 @@
<link rel="import" type="css" href="viewer-page-selector.css">
<template>
<paper-input-container id="pageselector" no-label-float>
- <input id="input" is="iron-input" bind-value="{{pageNo}}" on-mouseup="select"
- on-change="pageNoCommitted">
+ <input id="input" is="iron-input" value="{{pageNo}}"
+ prevent-invalid-input allowed-pattern="\d" on-mouseup="select"
+ on-change="pageNoCommitted" aria-label$="{{strings.labelPageNumber}}">
</paper-input-container>
- <span id="pagelength">/ <span>{{docLength}}</span></span>
+ <span id="slash"> / </span>
+ <span id="pagelength-spacer">
+ <span id="pagelength">{{docLength}}</span>
+ </span>
</template>
</dom-module>
<script src="viewer-page-selector.js"></script>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.js b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.js
index 5086219364e..014362ab962 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.js
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-var DIGIT_LENGTH = 0.6;
-
Polymer({
is: 'viewer-page-selector',
@@ -18,27 +16,44 @@ Polymer({
},
/**
- * The current page being viewed (1-based).
+ * The current page being viewed (1-based). A change to pageNo is mirrored
+ * immediately to the input field. A change to the input field is not
+ * mirrored back until pageNoCommitted() is called and change-page is fired.
*/
pageNo: {
- type: String,
- value: '1'
- }
+ type: Number,
+ value: 1
+ },
+
+ strings: Object
},
pageNoCommitted: function() {
- var page = parseInt(this.pageNo);
- if (!isNaN(page)) {
+ var page = parseInt(this.$.input.value);
+
+ if (!isNaN(page) && page <= this.docLength && page > 0)
this.fire('change-page', {page: page - 1});
- }
+ else
+ this.$.input.value = this.pageNo;
+ this.$.input.blur();
},
docLengthChanged: function() {
var numDigits = this.docLength.toString().length;
- this.$.pageselector.style.width = (numDigits * DIGIT_LENGTH) + 'em';
+ this.$.pageselector.style.width = numDigits + 'ch';
+ // Set both sides of the slash to the same width, so that the layout is
+ // exactly centered.
+ this.$['pagelength-spacer'].style.width = numDigits + 'ch';
},
select: function() {
this.$.input.select();
+ },
+
+ /**
+ * @return {boolean} True if the selector input field is currently focused.
+ */
+ isActive: function() {
+ return this.shadowRoot.activeElement == this.$.input;
}
});
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.css b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.css
deleted file mode 100644
index 83c3fc47961..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.css
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright 2015 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. */
-
-:host {
- -webkit-transition: opacity 400ms ease-in-out;
- background-color: #ccc;
- color: #555;
- display: table;
- font-family: sans-serif;
- font-size: 15px;
- height: 100%;
- pointer-events: none;
- position: fixed;
- text-align: center;
- width: 100%;
-}
-
-#message {
- padding-bottom: 10px;
-}
-
-.center {
- display: table-cell;
- vertical-align: middle;
-}
-
-.form {
- border: 1px solid #777;
- box-shadow: 1px 1px 1px;
- display: inline-block;
- padding: 10px;
- width: 300px;
-}
-
-input {
- color: #333;
- pointer-events: all;
-} \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.html b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.html
index 3506405441e..18065022df7 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.html
@@ -1,15 +1,30 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/fade-in-animation.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/fade-out-animation.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
<dom-module id="viewer-password-screen">
- <link rel="import" type="css" href="viewer-password-screen.css">
<template>
- <div class="center">
- <form class="form">
- <div id="message">{{text}}</div>
- <input id="password" type="password" size="20"></input>
- <input id="submit" type="submit" on-click="submit"></input>
- </form>
- </div>
+ <paper-dialog id="dialog" modal no-cancel-on-esc-key
+ entry-animation="fade-in-animation" exit-animation="fade-out-animation">
+ <div id="message">[[strings.passwordPrompt]]</div>
+ <div class="horizontal layout start">
+ <paper-input-container id="password-container" class="flex"
+ no-label-float invalid="[[invalid]]">
+ <input is="iron-input" id="password" type="password" size="20"
+ on-keypress="handleKey" autofocus>
+ </input>
+ <template is="dom-if" if="[[invalid]]">
+ <paper-input-error>[[strings.passwordInvalid]]</paper-input-error>
+ </template>
+ </paper-input-container>
+ <paper-button id="submit"
+ on-click="submit">{{strings.passwordSubmit}}</paper-button>
+ </div>
+ </paper-dialog>
</template>
</dom-module>
<script src="viewer-password-screen.js"></script>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.js b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.js
index 491c0a8e4c6..6f5cd6ebfa6 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.js
@@ -6,10 +6,9 @@ Polymer({
is: 'viewer-password-screen',
properties: {
- text: {
- type: String,
- value: 'This document is password protected. Please enter a password.',
- },
+ strings: Object,
+
+ invalid: Boolean,
active: {
type: Boolean,
@@ -18,8 +17,6 @@ Polymer({
}
},
- timerId: undefined,
-
ready: function() {
this.activeChanged();
},
@@ -31,13 +28,17 @@ Polymer({
deny: function() {
this.$.password.disabled = false;
this.$.submit.disabled = false;
+ this.invalid = true;
this.$.password.focus();
this.$.password.select();
},
- submit: function(e) {
- // Prevent the default form submission behavior.
- e.preventDefault();
+ handleKey: function(e) {
+ if (e.keyCode == 13)
+ this.submit();
+ },
+
+ submit: function() {
if (this.$.password.value.length == 0)
return;
this.$.password.disabled = true;
@@ -46,17 +47,11 @@ Polymer({
},
activeChanged: function() {
- clearTimeout(this.timerId);
- this.timerId = undefined;
if (this.active) {
- this.style.visibility = 'visible';
- this.style.opacity = 1;
+ this.$.dialog.open();
this.$.password.focus();
} else {
- this.style.opacity = 0;
- this.timerId = setTimeout(function() {
- this.style.visibility = 'hidden';
- }.bind(this), 400);
+ this.$.dialog.close();
}
}
});
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.css b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.css
index 436090c063a..b96c7b278a8 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.css
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.css
@@ -5,10 +5,13 @@
/* We introduce a wrapper aligner element as setting the relevant attributes
* (horizontal justified layout center) have no effect on the core-toolbar. */
#aligner {
+ padding: 0 16px;
width: 100%;
}
#title {
+ font-size: 77.8%;
+ font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -23,37 +26,32 @@
}
#buttons {
- text-align: right;
+ -webkit-user-select: none;
+ text-align: end;
}
-#buttons > paper-icon-button {
- margin-right: 8px;
+paper-icon-button {
+ -webkit-margin-end: 12px;
}
viewer-toolbar-dropdown {
- margin-right: 4px;
+ -webkit-margin-end: 4px;
}
paper-progress {
- height: 56px;
- position: absolute;
+ --paper-progress-active-color: var(--google-blue-300);
+ --paper-progress-container-color: transparent;
+ --paper-progress-height: 3px;
+ transition: opacity 150ms;
width: 100%;
- z-index: 3;
-}
-
-paper-progress {
- --paper-progress-active-color: rgb(50, 54, 57);
- --paper-progress-container-color: rgb(34, 36, 38);
}
paper-toolbar {
- background-color: transparent;
+ --paper-toolbar-background: rgb(50, 54, 57);
+ @apply(--shadow-elevation-2dp);
color: rgb(241, 241, 241);
font-size: 1.5em;
- height: 56px;
- padding-left: 1em;
- padding-right: 1em;
- z-index: 3;
+ height: 48px;
}
paper-toolbar /deep/ ::selection {
@@ -61,9 +59,33 @@ paper-toolbar /deep/ ::selection {
}
paper-toolbar /deep/ .toolbar-tools {
- height: 56px;
+ height: 48px;
}
.invisible {
visibility: hidden;
}
+
+@media(max-width: 675px) {
+ #bookmarks,
+ #rotate-left {
+ display: none;
+ }
+
+ #pageselector-container {
+ flex: 2;
+ }
+}
+
+@media(max-width: 450px) {
+ #rotate-right {
+ display: none;
+ }
+}
+
+@media(max-width: 400px) {
+ #buttons,
+ #pageselector-container {
+ display: none;
+ }
+}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html
index 8cba44f130e..feec286f274 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html
@@ -6,7 +6,6 @@
<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/slide-up-animation.html">
<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animation-runner-behavior.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-material/paper-material.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-progress/paper-progress.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-toolbar/paper-toolbar.html">
<link rel="import" href="../viewer-bookmarks-content/viewer-bookmarks-content.html">
@@ -14,46 +13,57 @@
<link rel="import" href="../viewer-toolbar-dropdown/viewer-toolbar-dropdown.html">
<dom-module id="viewer-pdf-toolbar">
+ <link rel="import" type="css" href="../shared-icon-style.css">
<link rel="import" type="css" href="viewer-pdf-toolbar.css">
<template>
- <paper-material class="fit"></paper-material>
-
- <paper-progress value="{{loadProgress}}"></paper-progress>
<paper-toolbar>
- <div id="aligner" class="horizontal layout center">
- <span id="title" class="invisible flex-5" title="{{docTitle}}">
+ <div id="aligner" class="middle horizontal layout center">
+ <span id="title" class="flex-5" title="{{docTitle}}">
<span>{{docTitle}}</span>
</span>
<div class="flex-1" id="pageselector-container">
<viewer-page-selector id="pageselector" class="invisible"
- doc-length="{{docLength}}" page-no="{{pageNo}}">
+ doc-length="{{docLength}}" page-no="{{pageNo}}"
+ strings="{{strings}}">
</viewer-page-selector>
</div>
<div id="buttons" class="invisible flex-5">
- <!-- TODO(tsergeant): "Bookmarks" should be localized. -->
<viewer-toolbar-dropdown id="bookmarks"
- hidden$="[[!bookmarks]]"
- header="Bookmarks"
+ hidden$="[[!bookmarks.length]]"
+ header="{{strings.bookmarks}}"
open-icon="bookmark"
closed-icon="bookmark-border">
<viewer-bookmarks-content bookmarks="{{bookmarks}}">
</viewer-bookmarks-content>
</viewer-toolbar-dropdown>
- <paper-icon-button icon="image:rotate-right"
- on-click="rotateRight"></paper-icon-button>
- <!-- TODO(tsergeant): Replace this placeholder with a more useful
- button. -->
- <paper-icon-button icon="image:rotate-left"
- on-click="rotateLeft"></paper-icon-button>
- <paper-icon-button icon="save"
- on-click="save"></paper-icon-button>
- <paper-icon-button icon="print"
- on-click="print"></paper-icon-button>
+
+ <paper-icon-button id="rotate-right" icon="image:rotate-right"
+ on-click="rotateRight" alt="{{strings.tooltipRotateCW}}"
+ title="{{strings.tooltipRotateCW}}">
+ </paper-icon-button>
+
+ <paper-icon-button id="rotate-left" icon="image:rotate-left"
+ on-click="rotateLeft" alt="{{strings.tooltipRotateCCW}}"
+ title="{{strings.tooltipRotateCCW}}">
+ </paper-icon-button>
+
+ <paper-icon-button id="save" icon="save"
+ on-click="save" alt="{{strings.tooltipSave}}"
+ title="{{strings.tooltipSave}}">
+ </paper-icon-button>
+
+ <paper-icon-button id="print" icon="print"
+ on-click="print" alt="{{strings.tooltipPrint}}"
+ title="{{strings.tooltipPrint}}">
+ </paper-icon-button>
</div>
</div>
+ <div class="bottom fit">
+ <paper-progress id="progress" value="{{loadProgress}}"></paper-progress>
+ </div>
</paper-toolbar>
</template>
</dom-module>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js
index 62e5cf9a5ec..338d9eaaeb0 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js
@@ -10,6 +10,7 @@
],
properties: {
+ strings: Object,
/**
* The current loading progress of the PDF document (0 - 100).
*/
@@ -78,15 +79,14 @@
},
_onAnimationFinished: function() {
- if (!this.opened)
- this.style.visibility = 'hidden';
+ this.style.transform = this.opened ? 'none' : 'translateY(-100%)';
},
loadProgressChanged: function() {
if (this.loadProgress >= 100) {
- this.$.title.classList.toggle('invisible', false);
this.$.pageselector.classList.toggle('invisible', false);
this.$.buttons.classList.toggle('invisible', false);
+ this.$.progress.style.opacity = 0;
}
},
@@ -98,7 +98,6 @@
show: function() {
if (!this.opened) {
this.toggleVisibility();
- this.style.visibility = 'initial';
}
},
@@ -113,7 +112,16 @@
},
shouldKeepOpen: function() {
- return this.$.bookmarks.dropdownOpen || this.loadProgress < 100;
+ return this.$.bookmarks.dropdownOpen || this.loadProgress < 100 ||
+ this.$.pageselector.isActive();
+ },
+
+ hideDropdowns: function() {
+ if (this.$.bookmarks.dropdownOpen) {
+ this.$.bookmarks.toggleDropdown();
+ return true;
+ }
+ return false;
},
setDropdownLowerBound: function(lowerBound) {
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.css b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.css
index 066c4a52de2..30b9f42abdf 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.css
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.css
@@ -4,7 +4,7 @@
:host {
display: inline-block;
- text-align: left;
+ text-align: start;
}
#container {
@@ -30,20 +30,21 @@ paper-material {
display: inline-block;
}
-#icon.open {
+:host([dropdown-open]) #icon {
background-color: rgb(25, 27, 29);
border-radius: 4px;
}
#arrow {
- margin-left: -18px;
- padding-right: 4px;
+ -webkit-margin-start: -12px;
+ -webkit-padding-end: 4px;
}
h1 {
border-bottom: 1px solid rgb(219, 219, 219);
color: rgb(33, 33, 33);
+ font-size: 77.8%;
+ font-weight: 500;
margin: 0;
- padding: 16px;
- @apply(--paper-font-title);
+ padding: 14px 28px;
}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html
index 9b6ec5ec41e..25b44c296e1 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html
@@ -4,10 +4,13 @@
<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
<dom-module id="viewer-toolbar-dropdown">
+ <link rel="import" type="css" href="../shared-icon-style.css">
<link rel="import" type="css" href="viewer-toolbar-dropdown.css">
<template>
<div on-click="toggleDropdown" id="icon">
- <paper-icon-button icon="[[dropdownIcon]]"></paper-icon-button>
+ <paper-icon-button id="main-icon" icon="[[dropdownIcon]]"
+ alt="{{header}}" title="{{header}}">
+ </paper-icon-button>
<iron-icon icon="arrow-drop-down" id="arrow"></iron-icon>
</div>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js
index 8586d829457..17a04c04d7b 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js
@@ -12,7 +12,7 @@
var DROPDOWN_OUTER_PADDING = 2;
/** Minimum height of toolbar dropdowns (px). */
- var MIN_DROPDOWN_HEIGHT = 300;
+ var MIN_DROPDOWN_HEIGHT = 200;
Polymer({
is: 'viewer-toolbar-dropdown',
@@ -30,6 +30,7 @@
/** True if the dropdown is currently open. */
dropdownOpen: {
type: Boolean,
+ reflectToAttribute: true,
value: false
},
@@ -69,12 +70,9 @@
toggleDropdown: function() {
this.dropdownOpen = !this.dropdownOpen;
if (this.dropdownOpen) {
- this.$.icon.classList.add('open');
this.$.dropdown.style.display = 'block';
if (!this.maxHeightValid_)
this.updateMaxHeight();
- } else {
- this.$.icon.classList.remove('open');
}
this.cancelAnimation_();
this.playAnimation_(this.dropdownOpen);
@@ -102,9 +100,9 @@
* @private
*/
playAnimation_: function(isEntry) {
- this._animation = isEntry ? this.animateEntry_() : this.animateExit_();
- this._animation.onfinish = function() {
- this._animation = null;
+ this.animation_ = isEntry ? this.animateEntry_() : this.animateExit_();
+ this.animation_.onfinish = function() {
+ this.animation_ = null;
if (!this.dropdownOpen)
this.$.dropdown.style.display = 'none';
}.bind(this);
@@ -114,6 +112,9 @@
var maxHeight = this.$.dropdown.getBoundingClientRect().height -
DROPDOWN_OUTER_PADDING;
+ if (maxHeight < 0)
+ maxHeight = 0;
+
var fade = new KeyframeEffect(this.$.dropdown, [
{opacity: 0},
{opacity: 1}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css
index 6c77cbe13dc..c9bb1896f96 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css
@@ -2,7 +2,28 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
+#wrapper {
+ transition: transform 250ms;
+ transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
+}
+
+:host([closed]) #wrapper {
+ transform: translateX(100%);
+ transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
+}
+
+:host-context([dir=rtl]):host([closed]) #wrapper {
+ transform: translateX(-100%);
+}
+
paper-fab {
+ --paper-fab-keyboard-focus-background: var(--viewer-icon-ink-color);
+ --paper-fab-mini: {
+ height: 36px;
+ padding: 8px;
+ width: 36px;
+ };
+ @apply(--shadow-elevation-4dp);
background-color: rgb(242, 242, 242);
color: rgb(96, 96, 96);
margin: 0 48px;
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html
index 84e5da1bf99..fbc51b550d6 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html
@@ -1,13 +1,16 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/transform-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animation-runner-behavior.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-fab/paper-fab.html">
<dom-module id="viewer-zoom-button">
+ <link rel="import" type="css" href="../shared-icon-style.css">
<link rel="import" type="css" href="viewer-zoom-button.css">
<template>
- <paper-fab id="button" mini icon="[[icon]]"></paper-fab>
+ <div id="wrapper">
+ <paper-fab id="button" mini icon="[[visibleIcon_]]" on-click="fireClick"
+ aria-label$="[[visibleTooltip_]]" title="[[visibleTooltip_]]">
+ </paper-fab>
+ </div>
</template>
</dom-module>
<script src="viewer-zoom-button.js"></script>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js
index 754badb3fcb..df556aced28 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js
@@ -5,77 +5,91 @@
Polymer({
is: 'viewer-zoom-button',
- behaviors: [
- Polymer.NeonAnimationRunnerBehavior
- ],
-
properties: {
- icon: String,
+ /**
+ * Icons to be displayed on the FAB. Multiple icons should be separated with
+ * spaces, and will be cycled through every time the FAB is clicked.
+ */
+ icons: String,
+
+ /**
+ * Array version of the list of icons. Polymer does not allow array
+ * properties to be set from HTML, so we must use a string property and
+ * perform the conversion manually.
+ * @private
+ */
+ icons_: {
+ type: Array,
+ value: [''],
+ computed: 'computeIconsArray_(icons)'
+ },
+
+ tooltips: Array,
- opened: {
+ closed: {
type: Boolean,
- value: true
+ reflectToAttribute: true,
+ value: false
+ },
+
+ delay: {
+ type: Number,
+ observer: 'delayChanged_'
+ },
+
+ /**
+ * Index of the icon currently being displayed.
+ */
+ activeIndex: {
+ type: Number,
+ value: 0
},
- delay: Number,
+ /**
+ * Icon currently being displayed on the FAB.
+ * @private
+ */
+ visibleIcon_: {
+ type: String,
+ computed: 'computeVisibleIcon_(icons_, activeIndex)'
+ },
- animationConfig: {
- type: Object,
- computed: 'computeAnimationConfig(delay)'
+ visibleTooltip_: {
+ type: String,
+ computed: 'computeVisibleTooltip_(tooltips, activeIndex)'
}
},
- computeAnimationConfig: function(delay) {
- return {
- 'entry': {
- name: 'transform-animation',
- node: this,
- timing: {
- easing: 'cubic-bezier(0, 0, 0.2, 1)',
- duration: 250,
- delay: delay
- },
- transformFrom: 'translateX(100%)'
- },
- 'exit': {
- name: 'transform-animation',
- node: this,
- timing: {
- easing: 'cubic-bezier(0.4, 0, 1, 1)',
- duration: 250,
- delay: delay
- },
- transformTo: 'translateX(100%)'
- }
- };
+ computeIconsArray_: function(icons) {
+ return icons.split(' ');
+ },
+
+ computeVisibleIcon_: function(icons, activeIndex) {
+ return icons[activeIndex];
},
- listeners: {
- 'neon-animation-finish': '_onAnimationFinished'
+ computeVisibleTooltip_: function(tooltips, activeIndex) {
+ return tooltips[activeIndex];
},
- _onAnimationFinished: function() {
- // Must use visibility: hidden so that the buttons do not change layout as
- // they are hidden.
- if (!this.opened)
- this.style.visibility = 'hidden';
+ delayChanged_: function() {
+ this.$.wrapper.style.transitionDelay = this.delay + 'ms';
},
show: function() {
- if (!this.opened) {
- this.toggle_();
- this.style.visibility = 'initial';
- }
+ this.closed = false;
},
hide: function() {
- if (this.opened)
- this.toggle_();
+ this.closed = true;
},
- toggle_: function() {
- this.opened = !this.opened;
- this.cancelAnimation();
- this.playAnimation(this.opened ? 'entry' : 'exit');
- },
+ fireClick: function() {
+ // We cannot attach an on-click to the entire viewer-zoom-button, as this
+ // will include clicks on the margins. Instead, proxy clicks on the FAB
+ // through.
+ this.fire('fabclick');
+
+ this.activeIndex = (this.activeIndex + 1) % this.icons_.length;
+ }
});
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css
index 808cd91f8fd..4756c8b3ebe 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css
@@ -3,6 +3,7 @@
* found in the LICENSE file. */
:host {
+ -webkit-user-select: none;
bottom: 0;
padding: 48px 0;
position: fixed;
@@ -10,18 +11,21 @@
z-index: 3;
}
+:host-context([dir=rtl]) {
+ left: 0;
+ right: auto;
+}
+
viewer-zoom-button {
display: block;
}
-/* A small gap between the fit to page/fit to width buttons and the zoom in/zoom
- * out buttons. */
-#fit-to-page-button,
+/* A small gap between the zoom in/zoom out buttons. */
#zoom-out-button {
- margin-top: 1em;
+ margin-top: 10px;
}
-/* A larger gap between the top two and bottom two buttons. */
+/* A larger gap between the fit button and bottom two buttons. */
#zoom-in-button {
- margin-top: 2em;
+ margin-top: 24px;
}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html
index 88649f4c52e..a2e3b372014 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html
@@ -8,15 +8,13 @@
<div id="zoom-buttons">
<div id="buttons">
- <!-- TODO(alexandrec): Replace with custom icons. -->
- <viewer-zoom-button id="fit-to-width-button" icon="fullscreen"
- on-click="fitToWidth" delay="0"></viewer-zoom-button>
- <viewer-zoom-button id="fit-to-page-button" icon="fullscreen-exit"
- on-click="fitToPage" delay="50"></viewer-zoom-button>
- <viewer-zoom-button id="zoom-in-button" icon="add"
- on-click="zoomIn" delay="100"></viewer-zoom-button>
- <viewer-zoom-button id="zoom-out-button" icon="remove"
- on-click="zoomOut" delay="150"></viewer-zoom-button>
+ <viewer-zoom-button id="fit-button" icons="fullscreen-exit fullscreen"
+ on-fabclick="fitToggle" delay="100">
+ </viewer-zoom-button>
+ <viewer-zoom-button id="zoom-in-button" icons="add"
+ on-fabclick="zoomIn" delay="50"></viewer-zoom-button>
+ <viewer-zoom-button id="zoom-out-button" icons="remove"
+ on-fabclick="zoomOut" delay="0"></viewer-zoom-button>
</div>
</div>
</template>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js
index 515b49df1cc..c65365c93bb 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js
@@ -2,62 +2,69 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-ANIMATION_INTERVAL = 50;
-
-Polymer({
- is: 'viewer-zoom-toolbar',
-
- properties: {
- /**
- * The default zoom percentage.
- */
- zoomValue: {
- type: Number,
- value: 100
- }
- },
-
- get visible() {
- return this.visible_;
- },
-
- ready: function() {
- this.visible_ = true;
- },
-
- fitToPage: function() {
- this.fire('fit-to-page');
- },
-
- fitToWidth: function() {
- this.fire('fit-to-width');
- },
-
- zoomIn: function() {
- this.fire('zoom-in');
- },
-
- zoomOut: function() {
- this.fire('zoom-out');
- },
-
- show: function() {
- if (!this.visible) {
- this.visible_ = true;
- this.$['fit-to-width-button'].show();
- this.$['fit-to-page-button'].show();
- this.$['zoom-in-button'].show();
- this.$['zoom-out-button'].show();
- }
- },
-
- hide: function() {
- if (this.visible) {
- this.visible_ = false;
- this.$['fit-to-page-button'].hide();
- this.$['fit-to-width-button'].hide();
- this.$['zoom-in-button'].hide();
- this.$['zoom-out-button'].hide();
- }
- },
-});
+(function() {
+
+ var FIT_TO_PAGE = 0;
+ var FIT_TO_WIDTH = 1;
+
+ Polymer({
+ is: 'viewer-zoom-toolbar',
+
+ properties: {
+ strings: {
+ type: Object,
+ observer: 'setTooltips_'
+ },
+
+ visible_: {
+ type: Boolean,
+ value: true
+ }
+ },
+
+ isVisible: function() {
+ return this.visible_;
+ },
+
+ setTooltips_: function() {
+ this.$['fit-button'].tooltips =
+ [this.strings.tooltipFitToPage, this.strings.tooltipFitToWidth];
+ this.$['zoom-in-button'].tooltips = [this.strings.tooltipZoomIn];
+ this.$['zoom-out-button'].tooltips = [this.strings.tooltipZoomOut];
+ },
+
+ fitToggle: function() {
+ if (this.$['fit-button'].activeIndex == FIT_TO_WIDTH)
+ this.fire('fit-to-width');
+ else
+ this.fire('fit-to-page');
+ },
+
+ zoomIn: function() {
+ this.fire('zoom-in');
+ },
+
+ zoomOut: function() {
+ this.fire('zoom-out');
+ },
+
+ show: function() {
+ if (!this.visible_) {
+ this.visible_ = true;
+ this.$['fit-button'].show();
+ this.$['zoom-in-button'].show();
+ this.$['zoom-out-button'].show();
+ }
+ },
+
+ hide: function() {
+ if (this.visible_) {
+ this.visible_ = false;
+ this.$['fit-button'].hide();
+ this.$['zoom-in-button'].hide();
+ this.$['zoom-out-button'].hide();
+ }
+ },
+ });
+
+})();
diff --git a/chromium/chrome/browser/resources/pdf/index-material.css b/chromium/chrome/browser/resources/pdf/index-material.css
index ff62d3f99ec..a443bac50ec 100644
--- a/chromium/chrome/browser/resources/pdf/index-material.css
+++ b/chromium/chrome/browser/resources/pdf/index-material.css
@@ -4,16 +4,19 @@
body {
background-color: rgb(82, 86, 89);
- font-family: Roboto, 'Helvetica Neue', Helvetica, Arial;
+ font-family: 'Roboto', 'Noto', sans-serif;
margin: 0;
}
+viewer-page-indicator {
+ visibility: hidden;
+ z-index: 2;
+}
+
viewer-pdf-toolbar {
position: fixed;
width: 100%;
- /* TODO(alexandrec): the viewer-pane's paper-dialog is set to z-index: 12
- * internally by the polymer element. Figure out why that is happening. */
- z-index: 1000;
+ z-index: 4;
}
#plugin {
@@ -28,27 +31,20 @@ viewer-pdf-toolbar {
z-index: 0;
}
-bookmarks-pane {
- z-index: 2;
+@media(max-height: 250px) {
+ viewer-pdf-toolbar {
+ display: none;
+ }
}
-viewer-toolbar {
- visibility: hidden;
- white-space: nowrap;
- z-index: 3;
+@media(max-height: 200px) {
+ viewer-zoom-toolbar {
+ display: none;
+ }
}
-viewer-page-indicator {
- visibility: hidden;
- z-index: 3;
-}
-
-viewer-error-screen {
- visibility: hidden;
- z-index: 2;
-}
-
-viewer-password-screen {
- visibility: hidden;
- z-index: 2;
+@media(max-width: 300px) {
+ viewer-zoom-toolbar {
+ display: none;
+ }
}
diff --git a/chromium/chrome/browser/resources/pdf/index-material.html b/chromium/chrome/browser/resources/pdf/index-material.html
index 984d7bcb2c7..5c2c1c4e069 100644
--- a/chromium/chrome/browser/resources/pdf/index-material.html
+++ b/chromium/chrome/browser/resources/pdf/index-material.html
@@ -1,10 +1,11 @@
<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
+<html>
<head>
<meta charset="utf-8">
<!-- Must be before any other scripts or Polymer imports. -->
- <script src="settings.js"></script>
+ <script src="chrome://resources/js/polymer_config.js"></script>
<link rel="import" href="elements/viewer-error-screen/viewer-error-screen.html">
+ <link rel="import" href="elements/viewer-page-indicator/viewer-page-indicator.html">
<link rel="import" href="elements/viewer-page-selector/viewer-page-selector.html">
<link rel="import" href="elements/viewer-password-screen/viewer-password-screen.html">
<link rel="import" href="elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html">
@@ -12,21 +13,23 @@
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
<link rel="stylesheet" href="chrome://resources/css/roboto.css">
- <link rel="stylesheet" type="text/css" href="index-material.css">
+ <link rel="stylesheet" href="index-material.css">
</head>
<body>
-<viewer-pdf-toolbar id="material-toolbar"></viewer-pdf-toolbar>
+<viewer-pdf-toolbar id="material-toolbar" hidden></viewer-pdf-toolbar>
<div id="sizer"></div>
<viewer-password-screen id="password-screen"></viewer-password-screen>
<viewer-zoom-toolbar id="zoom-toolbar"></viewer-zoom-toolbar>
+<viewer-page-indicator id="page-indicator"></viewer-page-indicator>
+
<viewer-error-screen id="error-screen"></viewer-error-screen>
</body>
-<script src="ui_manager.js"></script>
+<script src="toolbar_manager.js"></script>
<script src="viewport.js"></script>
<script src="open_pdf_params_parser.js"></script>
<script src="navigator.js"></script>
diff --git a/chromium/chrome/browser/resources/pdf/index.html b/chromium/chrome/browser/resources/pdf/index.html
index d35a6538f21..cfb3551660b 100644
--- a/chromium/chrome/browser/resources/pdf/index.html
+++ b/chromium/chrome/browser/resources/pdf/index.html
@@ -2,7 +2,7 @@
<html i18n-values="dir:textdirection;lang:language">
<head>
<meta charset="utf-8">
- <script src="settings.js"></script>
+ <script src="chrome://resources/js/polymer_config.js"></script>
<link rel="import" href="elements/viewer-button/viewer-button.html">
<link rel="import" href="elements/viewer-error-screen-legacy/viewer-error-screen-legacy.html">
<link rel="import" href="elements/viewer-page-indicator/viewer-page-indicator.html">
diff --git a/chromium/chrome/browser/resources/pdf/manifest.json b/chromium/chrome/browser/resources/pdf/manifest.json
index 8c44ec21b43..b3c4e943521 100644
--- a/chromium/chrome/browser/resources/pdf/manifest.json
+++ b/chromium/chrome/browser/resources/pdf/manifest.json
@@ -8,12 +8,13 @@
"offline_enabled": true,
"incognito": "split",
"permissions": [
- "<all_urls>"
+ "<all_urls>",
+ "resourcesPrivate"
],
"mime_types": [
"application/pdf"
],
- "content_security_policy": "script-src 'self' blob: filesystem: chrome://resources; object-src *; plugin-types application/x-google-chrome-pdf",
+ "content_security_policy": "script-src 'self' blob: filesystem: chrome://resources; object-src * blob: filesystem: data:; plugin-types application/x-google-chrome-pdf",
// This is to work-around an issue where this extension is not granted
// permission to access chrome://resources when iframed for print preview.
// See https://crbug.com/444752.
@@ -25,7 +26,6 @@
],
"mime_types_handler": "<INDEX>",
"web_accessible_resources": [
- "index.html",
"<INDEX>"
]
}
diff --git a/chromium/chrome/browser/resources/pdf/navigator.js b/chromium/chrome/browser/resources/pdf/navigator.js
index bf86d5d371f..e6bd7ad28c4 100644
--- a/chromium/chrome/browser/resources/pdf/navigator.js
+++ b/chromium/chrome/browser/resources/pdf/navigator.js
@@ -27,7 +27,7 @@ function Navigator(originalUrl,
}
Navigator.prototype = {
- /**
+ /**
* @private
* 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).
@@ -38,6 +38,7 @@ Navigator.prototype = {
navigate: function(url, newTab) {
if (url.length == 0)
return;
+
// If |urlFragment| starts with '#', then it's for the same URL with a
// different URL fragment.
if (url.charAt(0) == '#') {
@@ -50,26 +51,12 @@ Navigator.prototype = {
url = this.originalUrl_ + url;
}
- // If there's no scheme, add http.
+ // If there's no scheme, then take a guess at the scheme.
if (url.indexOf('://') == -1 && url.indexOf('mailto:') == -1)
- url = 'http://' + url;
+ url = this.guessUrlWithoutScheme_(url);
- // Make sure inputURL starts with a valid scheme.
- if (url.indexOf('http://') != 0 &&
- url.indexOf('https://') != 0 &&
- url.indexOf('ftp://') != 0 &&
- url.indexOf('file://') != 0 &&
- url.indexOf('mailto:') != 0) {
+ if (!this.isValidUrl_(url))
return;
- }
- // Make sure inputURL is not only a scheme.
- if (url == 'http://' ||
- url == 'https://' ||
- url == 'ftp://' ||
- url == 'file://' ||
- url == 'mailto:') {
- return;
- }
if (newTab) {
this.navigateInNewTabCallback_(url);
@@ -79,7 +66,7 @@ Navigator.prototype = {
}
},
- /**
+ /**
* @private
* Called when the viewport position is received.
* @param {Object} viewportPosition Dictionary containing the viewport
@@ -91,5 +78,90 @@ Navigator.prototype = {
this.viewport_.goToPage(pageNumber);
else
this.navigateInCurrentTabCallback_(viewportPosition['url']);
+ },
+
+ /**
+ * @private
+ * Checks if the URL starts with a scheme and s not just a scheme.
+ * @param {string} The input URL
+ * @return {boolean} Whether the url is valid.
+ */
+ isValidUrl_: function(url) {
+ // Make sure |url| starts with a valid scheme.
+ if (url.indexOf('http://') != 0 &&
+ url.indexOf('https://') != 0 &&
+ url.indexOf('ftp://') != 0 &&
+ url.indexOf('file://') != 0 &&
+ url.indexOf('mailto:') != 0) {
+ return false;
+ }
+
+ // Make sure |url| is not only a scheme.
+ if (url == 'http://' ||
+ url == 'https://' ||
+ url == 'ftp://' ||
+ url == 'file://' ||
+ url == 'mailto:') {
+ return false;
+ }
+
+ return true;
+ },
+
+ /**
+ * @private
+ * Attempt to figure out what a URL is when there is no scheme.
+ * @param {string} The input URL
+ * @return {string} The URL with a scheme or the original URL if it is not
+ * possible to determine the scheme.
+ */
+ guessUrlWithoutScheme_: function(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.
+ // In both cases, just bail out.
+ if (this.originalUrl_.startsWith('mailto:') ||
+ !this.isValidUrl_(this.originalUrl_)) {
+ return url;
+ }
+
+ // Check for absolute paths.
+ if (url.startsWith('/')) {
+ var schemeEndIndex = this.originalUrl_.indexOf('://');
+ var firstSlash = this.originalUrl_.indexOf('/', schemeEndIndex + 3);
+ // e.g. http://www.foo.com/bar -> http://www.foo.com
+ var domain = firstSlash != -1 ?
+ this.originalUrl_.substr(0, firstSlash) : this.originalUrl_;
+ return domain + url;
+ }
+
+ // Check for obvious relative paths.
+ var isRelative = false;
+ if (url.startsWith('.') || url.startsWith('\\'))
+ isRelative = true;
+
+ // In Adobe Acrobat Reader XI, it looks as though links with less than
+ // 2 dot separators in the domain are considered relative links, and
+ // those with 2 of more are considered http URLs. e.g.
+ //
+ // www.foo.com/bar -> http
+ // foo.com/bar -> relative link
+ if (!isRelative) {
+ var domainSeparatorIndex = url.indexOf('/');
+ var domainName = domainSeparatorIndex == -1 ?
+ url : url.substr(0, domainSeparatorIndex);
+ var domainDotCount = (domainName.match(/\./g) || []).length;
+ if (domainDotCount < 2)
+ isRelative = true;
+ }
+
+ if (isRelative) {
+ var slashIndex = this.originalUrl_.lastIndexOf('/');
+ var path = slashIndex != -1 ?
+ this.originalUrl_.substr(0, slashIndex) : this.originalUrl_;
+ return path + '/' + url;
+ }
+
+ return 'http://' + url;
}
};
diff --git a/chromium/chrome/browser/resources/pdf/pdf.js b/chromium/chrome/browser/resources/pdf/pdf.js
index c4975746d57..d667247abda 100644
--- a/chromium/chrome/browser/resources/pdf/pdf.js
+++ b/chromium/chrome/browser/resources/pdf/pdf.js
@@ -21,21 +21,38 @@ function getScrollbarWidth() {
}
/**
- * Return the filename component of a URL.
+ * Return the filename component of a URL, percent decoded if possible.
* @param {string} url The URL to get the filename from.
* @return {string} The filename component.
*/
function getFilenameFromURL(url) {
- var components = url.split(/\/|\\/);
- return components[components.length - 1];
+ // Ignore the query and fragment.
+ var mainUrl = url.split(/#|\?/)[0];
+ var components = mainUrl.split(/\/|\\/);
+ var filename = components[components.length - 1];
+ try {
+ return decodeURIComponent(filename);
+ } catch (e) {
+ if (e instanceof URIError)
+ return filename;
+ throw e;
+ }
}
/**
* Called when navigation happens in the current tab.
+ * @param {boolean} isInTab Indicates if the PDF viewer is displayed in a tab.
+ * @param {boolean} isSourceFileUrl Indicates if the navigation source is a
+ * file:// URL.
* @param {string} url The url to be opened in the current tab.
*/
-function onNavigateInCurrentTab(url) {
- window.location.href = url;
+function onNavigateInCurrentTab(isInTab, isSourceFileUrl, 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 && isInTab && isSourceFileUrl)
+ chrome.tabs.update({url: url});
+ else
+ window.location.href = url;
}
/**
@@ -46,7 +63,7 @@ function onNavigateInNewTab(url) {
// Prefer the tabs API because it guarantees we can just open a new tab.
// window.open doesn't have this guarantee.
if (chrome.tabs)
- chrome.tabs.create({ url: url});
+ chrome.tabs.create({url: url});
else
window.open(url);
}
@@ -75,6 +92,29 @@ function shouldIgnoreKeyEvents(activeElement) {
PDFViewer.MIN_TOOLBAR_OFFSET = 15;
/**
+ * The height of the toolbar along the top of the page. The document will be
+ * shifted down by this much in the viewport.
+ */
+PDFViewer.MATERIAL_TOOLBAR_HEIGHT = 56;
+
+/**
+ * Minimum height for the material toolbar to show (px). Should match the media
+ * query in index-material.css. If the window is smaller than this at load,
+ * leave no space for the toolbar.
+ */
+PDFViewer.TOOLBAR_WINDOW_MIN_HEIGHT = 250;
+
+/**
+ * The light-gray background color used for print preview.
+ */
+PDFViewer.LIGHT_BACKGROUND_COLOR = '0xFFCCCCCC';
+
+/**
+ * The dark-gray background color used for the regular viewer.
+ */
+PDFViewer.DARK_BACKGROUND_COLOR = '0xFF525659';
+
+/**
* Creates a new PDFViewer. There should only be one of these objects per
* document.
* @constructor
@@ -85,6 +125,7 @@ function PDFViewer(browserApi) {
this.loadState_ = LoadState.LOADING;
this.parentWindow_ = null;
this.parentOrigin_ = null;
+ this.isFormFieldFocused_ = false;
this.delayedScriptingMessages_ = [];
@@ -97,21 +138,33 @@ function PDFViewer(browserApi) {
// of the pdf and zoom level.
this.sizer_ = $('sizer');
this.toolbar_ = $('toolbar');
- this.pageIndicator_ = $('page-indicator');
+ if (!this.isMaterial_ || this.isPrintPreview_)
+ this.pageIndicator_ = $('page-indicator');
this.progressBar_ = $('progress-bar');
this.passwordScreen_ = $('password-screen');
this.passwordScreen_.addEventListener('password-submitted',
this.onPasswordSubmitted_.bind(this));
this.errorScreen_ = $('error-screen');
+ // Can only reload if we are in a normal tab.
+ if (chrome.tabs && this.browserApi_.getStreamInfo().tabId != -1) {
+ this.errorScreen_.reloadFn = function() {
+ chrome.tabs.reload(this.browserApi_.getStreamInfo().tabId);
+ }.bind(this);
+ }
// Create the viewport.
+ var shortWindow = window.innerHeight < PDFViewer.TOOLBAR_WINDOW_MIN_HEIGHT;
+ var topToolbarHeight =
+ (this.isMaterial_ && !this.isPrintPreview_ && !shortWindow) ?
+ PDFViewer.MATERIAL_TOOLBAR_HEIGHT : 0;
this.viewport_ = new Viewport(window,
this.sizer_,
this.viewportChanged_.bind(this),
this.beforeZoom_.bind(this),
this.afterZoom_.bind(this),
getScrollbarWidth(),
- this.browserApi_.getDefaultZoom());
+ this.browserApi_.getDefaultZoom(),
+ topToolbarHeight);
// Create the plugin object dynamically so we can set its src. The plugin
// element is sized to fill the entire window and is set to be fixed
@@ -131,8 +184,6 @@ function PDFViewer(browserApi) {
window.addEventListener('message', this.handleScriptingMessage.bind(this),
false);
- document.title = decodeURIComponent(
- getFilenameFromURL(this.browserApi_.getStreamInfo().originalUrl));
this.plugin_.setAttribute('src',
this.browserApi_.getStreamInfo().originalUrl);
this.plugin_.setAttribute('stream-url',
@@ -144,8 +195,11 @@ function PDFViewer(browserApi) {
}
this.plugin_.setAttribute('headers', headers);
- if (this.isMaterial_)
- this.plugin_.setAttribute('is-material', '');
+ var backgroundColor = PDFViewer.DARK_BACKGROUND_COLOR;
+ if (!this.isMaterial_)
+ backgroundColor = PDFViewer.LIGHT_BACKGROUND_COLOR;
+ this.plugin_.setAttribute('background-color', backgroundColor);
+ this.plugin_.setAttribute('top-toolbar-height', topToolbarHeight);
if (!this.browserApi_.getStreamInfo().embedded)
this.plugin_.setAttribute('full-frame', '');
@@ -170,47 +224,68 @@ function PDFViewer(browserApi) {
this.zoomToolbar_.addEventListener('fit-to-width',
this.viewport_.fitToWidth.bind(this.viewport_));
this.zoomToolbar_.addEventListener('fit-to-page',
- this.viewport_.fitToPage.bind(this.viewport_));
+ this.fitToPage_.bind(this));
this.zoomToolbar_.addEventListener('zoom-in',
this.viewport_.zoomIn.bind(this.viewport_));
this.zoomToolbar_.addEventListener('zoom-out',
this.viewport_.zoomOut.bind(this.viewport_));
- this.materialToolbar_ = $('material-toolbar');
- this.materialToolbar_.docTitle = document.title;
- this.materialToolbar_.addEventListener('save', this.save_.bind(this));
- this.materialToolbar_.addEventListener('print', this.print_.bind(this));
- this.materialToolbar_.addEventListener('rotate-right',
- this.rotateClockwise_.bind(this));
- this.materialToolbar_.addEventListener('rotate-left',
- this.rotateCounterClockwise_.bind(this));
+ if (!this.isPrintPreview_) {
+ this.materialToolbar_ = $('material-toolbar');
+ this.materialToolbar_.hidden = false;
+ this.materialToolbar_.addEventListener('save', this.save_.bind(this));
+ this.materialToolbar_.addEventListener('print', this.print_.bind(this));
+ this.materialToolbar_.addEventListener('rotate-right',
+ this.rotateClockwise_.bind(this));
+ this.materialToolbar_.addEventListener('rotate-left',
+ this.rotateCounterClockwise_.bind(this));
+ // Must attach to mouseup on the plugin element, since it eats mousedown
+ // and click events.
+ this.plugin_.addEventListener('mouseup',
+ this.materialToolbar_.hideDropdowns.bind(this.materialToolbar_));
+
+ this.materialToolbar_.docTitle =
+ getFilenameFromURL(this.browserApi_.getStreamInfo().originalUrl);
+ }
document.body.addEventListener('change-page', function(e) {
this.viewport_.goToPage(e.detail.page);
}.bind(this));
- this.uiManager_ =
- new UiManager(window, this.materialToolbar_, this.zoomToolbar_);
+ this.toolbarManager_ =
+ new ToolbarManager(window, this.materialToolbar_, this.zoomToolbar_);
}
// Set up the ZoomManager.
this.zoomManager_ = new ZoomManager(
this.viewport_, this.browserApi_.setZoom.bind(this.browserApi_),
- this.browserApi_.getDefaultZoom());
+ this.browserApi_.getInitialZoom());
this.browserApi_.addZoomEventListener(
this.zoomManager_.onBrowserZoomChange.bind(this.zoomManager_));
// Setup the keyboard event listener.
- document.onkeydown = this.handleKeyEvent_.bind(this);
+ document.addEventListener('keydown', this.handleKeyEvent_.bind(this));
+ document.addEventListener('mousemove', this.handleMouseEvent_.bind(this));
+ document.addEventListener('mouseout', this.handleMouseEvent_.bind(this));
// Parse open pdf parameters.
this.paramsParser_ =
new OpenPDFParamsParser(this.getNamedDestination_.bind(this));
+ var isInTab = this.browserApi_.getStreamInfo().tabId != -1;
+ var isSourceFileUrl =
+ this.browserApi_.getStreamInfo().originalUrl.indexOf('file://') == 0;
this.navigator_ = new Navigator(this.browserApi_.getStreamInfo().originalUrl,
this.viewport_, this.paramsParser_,
- onNavigateInCurrentTab, onNavigateInNewTab);
+ onNavigateInCurrentTab.bind(undefined,
+ isInTab,
+ isSourceFileUrl),
+ onNavigateInNewTab);
this.viewportScroller_ =
new ViewportScroller(this.viewport_, this.plugin_, window);
+
+ // Request translated strings.
+ if (!this.isPrintPreview_)
+ chrome.resourcesPrivate.getStrings('pdf', this.handleStrings_.bind(this));
}
PDFViewer.prototype = {
@@ -228,6 +303,9 @@ PDFViewer.prototype = {
if (shouldIgnoreKeyEvents(document.activeElement) || e.defaultPrevented)
return;
+ if (this.isMaterial_)
+ this.toolbarManager_.hideToolbarsAfterTimeout(e);
+
var pageUpHandler = function() {
// Go to the previous page if we are fit-to-page.
if (this.viewport_.fittingType == Viewport.FittingType.FIT_TO_PAGE) {
@@ -252,6 +330,15 @@ PDFViewer.prototype = {
}.bind(this);
switch (e.keyCode) {
+ case 9: // Tab key.
+ this.toolbarManager_.showToolbarsForKeyboardNavigation();
+ return;
+ case 27: // Escape key.
+ if (this.isMaterial_ && !this.isPrintPreview_) {
+ this.toolbarManager_.hideSingleToolbarLayer();
+ return;
+ }
+ break; // Ensure escape falls through to the print-preview handler.
case 32: // Space key.
if (e.shiftKey)
pageUpHandler();
@@ -266,8 +353,10 @@ PDFViewer.prototype = {
return;
case 37: // Left arrow key.
if (!(e.altKey || e.ctrlKey || e.metaKey || e.shiftKey)) {
- // Go to the previous page if there are no horizontal scrollbars.
- if (!this.viewport_.documentHasScrollbars().horizontal) {
+ // Go to the previous page if there are no horizontal scrollbars and
+ // no form field is focused.
+ if (!(this.viewport_.documentHasScrollbars().horizontal ||
+ this.isFormFieldFocused_)) {
this.viewport_.goToPage(this.viewport_.getMostVisiblePage() - 1);
// Since we do the movement of the page.
e.preventDefault();
@@ -285,8 +374,10 @@ PDFViewer.prototype = {
return;
case 39: // Right arrow key.
if (!(e.altKey || e.ctrlKey || e.metaKey || e.shiftKey)) {
- // Go to the next page if there are no horizontal scrollbars.
- if (!this.viewport_.documentHasScrollbars().horizontal) {
+ // Go to the next page if there are no horizontal scrollbars and no
+ // form field is focused.
+ if (!(this.viewport_.documentHasScrollbars().horizontal ||
+ this.isFormFieldFocused_)) {
this.viewport_.goToPage(this.viewport_.getMostVisiblePage() + 1);
// Since we do the movement of the page.
e.preventDefault();
@@ -312,7 +403,9 @@ PDFViewer.prototype = {
}
return;
case 71: // g key.
- if (this.isMaterial_ && (e.ctrlKey || e.metaKey)) {
+ if (this.isMaterial_ && this.materialToolbar_ &&
+ (e.ctrlKey || e.metaKey)) {
+ this.toolbarManager_.showToolbars();
this.materialToolbar_.selectPageNumber();
// To prevent the default "find text" behaviour in Chrome.
e.preventDefault();
@@ -334,6 +427,19 @@ PDFViewer.prototype = {
type: 'sendKeyEvent',
keyEvent: SerializeKeyEvent(e)
});
+ } else if (this.isMaterial_) {
+ // Show toolbars as a fallback.
+ if (!(e.shiftKey || e.ctrlKey || e.altKey))
+ this.toolbarManager_.showToolbars();
+ }
+ },
+
+ handleMouseEvent_: function(e) {
+ if (this.isMaterial_) {
+ if (e.type == 'mousemove')
+ this.toolbarManager_.handleMouseMove(e);
+ else if (e.type == 'mouseout')
+ this.toolbarManager_.hideToolbarsForMouseOut();
}
},
@@ -357,6 +463,11 @@ PDFViewer.prototype = {
});
},
+ fitToPage_: function() {
+ this.viewport_.fitToPage();
+ this.toolbarManager_.forceHideTopToolbar();
+ },
+
/**
* @private
* Notify the plugin to print.
@@ -432,14 +543,16 @@ PDFViewer.prototype = {
* @param {number} progress the progress as a percentage.
*/
updateProgress_: function(progress) {
- if (this.isMaterial_)
- this.materialToolbar_.loadProgress = progress;
- else
+ if (this.isMaterial_) {
+ if (this.materialToolbar_)
+ this.materialToolbar_.loadProgress = progress;
+ } else {
this.progressBar_.progress = progress;
+ }
if (progress == -1) {
// Document load failed.
- this.errorScreen_.style.visibility = 'visible';
+ this.errorScreen_.show();
this.sizer_.style.display = 'none';
if (!this.isMaterial_)
this.toolbar_.style.visibility = 'hidden';
@@ -462,7 +575,31 @@ PDFViewer.prototype = {
this.handleScriptingMessage(this.delayedScriptingMessages_.shift());
if (this.isMaterial_)
- this.uiManager_.hideUiAfterTimeout();
+ this.toolbarManager_.hideToolbarsAfterTimeout();
+ }
+ },
+
+ /**
+ * @private
+ * Load a dictionary of translated strings into the UI. Used as a callback for
+ * chrome.resourcesPrivate.
+ * @param {Object} strings Dictionary of translated strings
+ */
+ handleStrings_: function(strings) {
+ if (this.isMaterial_) {
+ this.errorScreen_.strings = strings;
+ this.passwordScreen_.strings = strings;
+ if (this.materialToolbar_)
+ this.materialToolbar_.strings = strings;
+ this.zoomToolbar_.strings = strings;
+ document.documentElement.lang = strings['language'];
+ document.dir = strings['textdirection'];
+ } else {
+ this.passwordScreen_.text = strings.passwordPrompt;
+ this.progressBar_.text = strings.pageLoading;
+ if (!this.isPrintPreview_)
+ this.progressBar_.style.visibility = 'visible';
+ this.errorScreen_.text = strings.pageLoadFailed;
}
},
@@ -494,11 +631,15 @@ PDFViewer.prototype = {
if (this.passwordScreen_.active)
this.passwordScreen_.accept();
+ if (this.pageIndicator_)
+ this.pageIndicator_.initialFadeIn();
+
if (this.isMaterial_) {
- this.materialToolbar_.docLength =
- this.documentDimensions_.pageDimensions.length;
+ if (this.materialToolbar_) {
+ this.materialToolbar_.docLength =
+ this.documentDimensions_.pageDimensions.length;
+ }
} else {
- this.pageIndicator_.initialFadeIn();
this.toolbar_.initialFadeIn();
}
break;
@@ -543,22 +684,21 @@ PDFViewer.prototype = {
position.y = message.data.y;
this.viewport_.position = position;
break;
- case 'setTranslatedStrings':
- this.passwordScreen_.text = message.data.getPasswordString;
- if (!this.isMaterial_) {
- this.progressBar_.text = message.data.loadingString;
- if (!this.isPrintPreview_)
- this.progressBar_.style.visibility = 'visible';
- }
- this.errorScreen_.text = message.data.loadFailedString;
- break;
case 'cancelStreamUrl':
chrome.mimeHandlerPrivate.abortStream();
break;
- case 'bookmarks':
+ case 'metadata':
+ if (message.data.title) {
+ document.title = message.data.title;
+ } else {
+ document.title =
+ getFilenameFromURL(this.browserApi_.getStreamInfo().originalUrl);
+ }
this.bookmarks_ = message.data.bookmarks;
- if (this.isMaterial_ && this.bookmarks_.length !== 0)
+ if (this.isMaterial_ && this.materialToolbar_) {
+ this.materialToolbar_.docTitle = document.title;
this.materialToolbar_.bookmarks = this.bookmarks;
+ }
break;
case 'setIsSelecting':
this.viewportScroller_.setEnableScrolling(message.data.isSelecting);
@@ -567,6 +707,9 @@ PDFViewer.prototype = {
this.paramsParser_.onNamedDestinationReceived(
message.data.pageNumber);
break;
+ case 'formFocusChange':
+ this.isFormFieldFocused_ = message.data.focused;
+ break;
}
},
@@ -589,8 +732,6 @@ PDFViewer.prototype = {
afterZoom_: function() {
var position = this.viewport_.position;
var zoom = this.viewport_.zoom;
- if (this.isMaterial_)
- this.zoomToolbar_.zoomValue = 100 * zoom;
this.plugin_.postMessage({
type: 'viewport',
zoom: zoom,
@@ -626,11 +767,28 @@ PDFViewer.prototype = {
var verticalScrollbarWidth = hasScrollbars.vertical ? scrollbarWidth : 0;
var horizontalScrollbarWidth =
hasScrollbars.horizontal ? scrollbarWidth : 0;
- var toolbarRight = Math.max(PDFViewer.MIN_TOOLBAR_OFFSET, scrollbarWidth);
- var toolbarBottom = Math.max(PDFViewer.MIN_TOOLBAR_OFFSET, scrollbarWidth);
- toolbarRight -= verticalScrollbarWidth;
- toolbarBottom -= horizontalScrollbarWidth;
- if (!this.isMaterial_) {
+ if (this.isMaterial_) {
+ // Shift the zoom toolbar to the left by half a scrollbar width. This
+ // gives a compromise: if there is no scrollbar visible then the toolbar
+ // will be half a scrollbar width further left than the spec but if there
+ // is a scrollbar visible it will be half a scrollbar width further right
+ // than the spec. In RTL layout, the zoom toolbar is on the left side, but
+ // the scrollbar is still on the left, so this is not necessary.
+ if (document.dir == 'ltr') {
+ this.zoomToolbar_.style.right = -verticalScrollbarWidth +
+ (scrollbarWidth / 2) + 'px';
+ }
+ // Having a horizontal scrollbar is much rarer so we don't offset the
+ // toolbar from the bottom any more than what the spec says. This means
+ // that when there is a scrollbar visible, it will be a full scrollbar
+ // width closer to the bottom of the screen than usual, but this is ok.
+ this.zoomToolbar_.style.bottom = -horizontalScrollbarWidth + 'px';
+ } else {
+ var toolbarRight = Math.max(PDFViewer.MIN_TOOLBAR_OFFSET, scrollbarWidth);
+ var toolbarBottom =
+ Math.max(PDFViewer.MIN_TOOLBAR_OFFSET, scrollbarWidth);
+ toolbarRight -= verticalScrollbarWidth;
+ toolbarBottom -= horizontalScrollbarWidth;
this.toolbar_.style.right = toolbarRight + 'px';
this.toolbar_.style.bottom = toolbarBottom + 'px';
// Hide the toolbar if it doesn't fit in the viewport.
@@ -642,9 +800,12 @@ PDFViewer.prototype = {
// Update the page indicator.
var visiblePage = this.viewport_.getMostVisiblePage();
- if (this.isMaterial_) {
+
+ if (this.materialToolbar_)
this.materialToolbar_.pageNo = visiblePage + 1;
- } else {
+
+ // TODO(raymes): Give pageIndicator_ the same API as materialToolbar_.
+ if (this.pageIndicator_) {
this.pageIndicator_.index = visiblePage;
if (this.documentDimensions_.pageDimensions.length > 1 &&
hasScrollbars.vertical) {
@@ -734,8 +895,7 @@ PDFViewer.prototype = {
if (saveButton)
saveButton.parentNode.removeChild(saveButton);
- if (!this.isMaterial_)
- this.pageIndicator_.pageLabels = message.data.pageNumbers;
+ this.pageIndicator_.pageLabels = message.data.pageNumbers;
this.plugin_.postMessage({
type: 'resetPrintPreviewMode',
diff --git a/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js b/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js
index 4a08195c83c..06fc8b546c4 100644
--- a/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js
+++ b/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js
@@ -269,16 +269,29 @@ PDFScriptingAPI.prototype = {
* @return {HTMLIFrameElement} the iframe element containing the PDF viewer.
*/
function PDFCreateOutOfProcessPlugin(src) {
+ var client = new PDFScriptingAPI(window);
var iframe = window.document.createElement('iframe');
- iframe.setAttribute(
- 'src',
- 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html?' + src);
// Prevent the frame from being tab-focusable.
iframe.setAttribute('tabindex', '-1');
- var client = new PDFScriptingAPI(window);
- iframe.onload = function() {
- client.setPlugin(iframe.contentWindow);
- };
+
+ // TODO(raymes): This below is a hack to tell if the material design PDF UI
+ // has been enabled. Remove this as soon as we remove the material design PDF
+ // flag.
+ var EXTENSION_URL = 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/';
+ var PAGE_NAME = 'index.html';
+ var MATERIAL_PAGE_NAME = 'index-material.html';
+ fetch(EXTENSION_URL + PAGE_NAME, {
+ method: 'get'
+ }).then(function() {
+ iframe.setAttribute('src', EXTENSION_URL + PAGE_NAME + '?' + src);
+ }, function() {
+ iframe.setAttribute('src', EXTENSION_URL + MATERIAL_PAGE_NAME + '?' + src);
+ }).then(function() {
+ 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);
diff --git a/chromium/chrome/browser/resources/pdf/settings.js b/chromium/chrome/browser/resources/pdf/settings.js
deleted file mode 100644
index 3b20eae9d9f..00000000000
--- a/chromium/chrome/browser/resources/pdf/settings.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2015 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.
-
-Polymer = {dom: 'shadow'};
diff --git a/chromium/chrome/browser/resources/pdf/toolbar_manager.js b/chromium/chrome/browser/resources/pdf/toolbar_manager.js
new file mode 100644
index 00000000000..bef7cf8a41c
--- /dev/null
+++ b/chromium/chrome/browser/resources/pdf/toolbar_manager.js
@@ -0,0 +1,221 @@
+// Copyright 2015 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.
+
+'use strict';
+
+/** Idle time in ms before the UI is hidden. */
+var HIDE_TIMEOUT = 2000;
+/** Time in ms after force hide before toolbar is shown again. */
+var FORCE_HIDE_TIMEOUT = 1000;
+/** Velocity required in a mousemove to reveal the UI (pixels/sample). */
+var SHOW_VELOCITY = 25;
+/** Distance from the top of the screen required to reveal the toolbars. */
+var TOP_TOOLBAR_REVEAL_DISTANCE = 100;
+/** Distance from the bottom-right of the screen required to reveal toolbars. */
+var SIDE_TOOLBAR_REVEAL_DISTANCE_RIGHT = 150;
+var SIDE_TOOLBAR_REVEAL_DISTANCE_BOTTOM = 250;
+
+/**
+ * Whether a mousemove event is high enough velocity to reveal the toolbars.
+ * @param {MouseEvent} e Event to test.
+ * @return {boolean} true if the event is a high velocity mousemove, false
+ * otherwise.
+ */
+function isHighVelocityMouseMove(e) {
+ return e.type == 'mousemove' &&
+ e.movementX * e.movementX + e.movementY * e.movementY >
+ SHOW_VELOCITY * SHOW_VELOCITY;
+}
+
+/**
+ * @param {MouseEvent} e Event to test.
+ * @return {boolean} True if the mouse is close to the top of the screen.
+ */
+function isMouseNearTopToolbar(e) {
+ return e.y < TOP_TOOLBAR_REVEAL_DISTANCE;
+}
+
+/**
+ * @param {MouseEvent} e Event to test.
+ * @return {boolean} True if the mouse is close to the bottom-right of the
+ * screen.
+ */
+function isMouseNearSideToolbar(e) {
+ var atSide = e.x > window.innerWidth - SIDE_TOOLBAR_REVEAL_DISTANCE_RIGHT;
+ if (document.dir == 'rtl')
+ atSide = e.x < SIDE_TOOLBAR_REVEAL_DISTANCE_RIGHT;
+ var atBottom = e.y > window.innerHeight - SIDE_TOOLBAR_REVEAL_DISTANCE_BOTTOM;
+ return atSide && atBottom;
+}
+
+/**
+ * Constructs a Toolbar Manager, responsible for co-ordinating between multiple
+ * toolbar elements.
+ * @constructor
+ * @param {Object} window The window containing the UI.
+ * @param {Object} toolbar The top toolbar element.
+ * @param {Object} zoomToolbar The zoom toolbar element.
+ */
+function ToolbarManager(window, toolbar, zoomToolbar) {
+ this.window_ = window;
+ this.toolbar_ = toolbar;
+ this.zoomToolbar_ = zoomToolbar;
+
+ this.toolbarTimeout_ = null;
+ this.isMouseNearTopToolbar_ = false;
+ this.isMouseNearSideToolbar_ = false;
+
+ this.sideToolbarAllowedOnly_ = false;
+ this.sideToolbarAllowedOnlyTimer_ = null;
+
+ this.keyboardNavigationActive = false;
+
+ this.window_.addEventListener('resize', this.resizeDropdowns_.bind(this));
+ this.resizeDropdowns_();
+}
+
+ToolbarManager.prototype = {
+
+ handleMouseMove: function(e) {
+ this.isMouseNearTopToolbar_ = this.toolbar_ && isMouseNearTopToolbar(e);
+ this.isMouseNearSideToolbar_ = isMouseNearSideToolbar(e);
+
+ this.keyboardNavigationActive = false;
+ var touchInteractionActive =
+ (e.sourceCapabilities && e.sourceCapabilities.firesTouchEvents);
+
+ // Allow the top toolbar to be shown if the mouse moves away from the side
+ // toolbar (as long as the timeout has elapsed).
+ if (!this.isMouseNearSideToolbar_ && !this.sideToolbarAllowedOnlyTimer_)
+ this.sideToolbarAllowedOnly_ = false;
+
+ // Allow the top toolbar to be shown if the mouse moves to the top edge.
+ if (this.isMouseNearTopToolbar_)
+ this.sideToolbarAllowedOnly_ = false;
+
+ // Tapping the screen with toolbars open tries to close them.
+ if (touchInteractionActive && this.zoomToolbar_.isVisible()) {
+ this.hideToolbarsIfAllowed();
+ return;
+ }
+
+ // Show the toolbars if the mouse is near the top or bottom-right of the
+ // screen, if the mouse moved fast, or if the touchscreen was tapped.
+ if (this.isMouseNearTopToolbar_ || this.isMouseNearSideToolbar_ ||
+ isHighVelocityMouseMove(e) || touchInteractionActive) {
+ if (this.sideToolbarAllowedOnly_)
+ this.zoomToolbar_.show();
+ else
+ this.showToolbars();
+ }
+ this.hideToolbarsAfterTimeout();
+ },
+
+ /**
+ * Display both UI toolbars.
+ */
+ showToolbars: function() {
+ if (this.toolbar_)
+ this.toolbar_.show();
+ this.zoomToolbar_.show();
+ },
+
+ /**
+ * Show toolbars and mark that navigation is being performed with
+ * tab/shift-tab. This disables toolbar hiding until the mouse is moved or
+ * escape is pressed.
+ */
+ showToolbarsForKeyboardNavigation: function() {
+ this.keyboardNavigationActive = true;
+ this.showToolbars();
+ },
+
+ /**
+ * Hide toolbars after a delay, regardless of the position of the mouse.
+ * Intended to be called when the mouse has moved out of the parent window.
+ */
+ hideToolbarsForMouseOut: function() {
+ this.isMouseNearTopToolbar_ = false;
+ this.isMouseNearSideToolbar_ = false;
+ this.hideToolbarsAfterTimeout();
+ },
+
+ /**
+ * Check if the toolbars are able to be closed, and close them if they are.
+ * Toolbars may be kept open based on mouse/keyboard activity and active
+ * elements.
+ */
+ hideToolbarsIfAllowed: function() {
+ if (this.isMouseNearSideToolbar_ || this.isMouseNearTopToolbar_)
+ return;
+
+ if (this.toolbar_ && this.toolbar_.shouldKeepOpen())
+ return;
+
+ if (this.keyboardNavigationActive)
+ return;
+
+ // Remove focus to make any visible tooltips disappear -- otherwise they'll
+ // still be visible on screen when the toolbar is off screen.
+ if ((this.toolbar_ && document.activeElement == this.toolbar_) ||
+ document.activeElement == this.zoomToolbar_) {
+ document.activeElement.blur();
+ }
+
+ if (this.toolbar_)
+ this.toolbar_.hide();
+ this.zoomToolbar_.hide();
+ },
+
+ /**
+ * Hide the toolbar after the HIDE_TIMEOUT has elapsed.
+ */
+ hideToolbarsAfterTimeout: function() {
+ if (this.toolbarTimeout_)
+ this.window_.clearTimeout(this.toolbarTimeout_);
+ this.toolbarTimeout_ = this.window_.setTimeout(
+ this.hideToolbarsIfAllowed.bind(this), HIDE_TIMEOUT);
+ },
+
+ /**
+ * Hide the 'topmost' layer of toolbars. Hides any dropdowns that are open, or
+ * hides the basic toolbars otherwise.
+ */
+ hideSingleToolbarLayer: function() {
+ if (!this.toolbar_ || !this.toolbar_.hideDropdowns()) {
+ this.keyboardNavigationActive = false;
+ this.hideToolbarsIfAllowed();
+ }
+ },
+
+ /**
+ * Hide the top toolbar and keep it hidden until both:
+ * - The mouse is moved away from the right side of the screen
+ * - 1 second has passed.
+ *
+ * The top toolbar can be immediately re-opened by moving the mouse to the top
+ * of the screen.
+ */
+ forceHideTopToolbar: function() {
+ if (!this.toolbar_)
+ return;
+ this.toolbar_.hide();
+ this.sideToolbarAllowedOnly_ = true;
+ this.sideToolbarAllowedOnlyTimer_ = this.window_.setTimeout(function() {
+ this.sideToolbarAllowedOnlyTimer_ = null;
+ }.bind(this), FORCE_HIDE_TIMEOUT);
+ },
+
+ /**
+ * Updates the size of toolbar dropdowns based on the positions of the rest of
+ * the UI.
+ * @private
+ */
+ resizeDropdowns_: function() {
+ if (!this.toolbar_)
+ return;
+ var lowerBound = this.window_.innerHeight - this.zoomToolbar_.clientHeight;
+ this.toolbar_.setDropdownLowerBound(lowerBound);
+ }
+};
diff --git a/chromium/chrome/browser/resources/pdf/ui_manager.js b/chromium/chrome/browser/resources/pdf/ui_manager.js
deleted file mode 100644
index baee7bc0d43..00000000000
--- a/chromium/chrome/browser/resources/pdf/ui_manager.js
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2015 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.
-
-'use strict';
-
-/** Idle time in ms before the UI is hidden. */
-var HIDE_TIMEOUT = 2000;
-/** Velocity required in a mousemove to reveal the UI (pixels/sample). */
-var SHOW_VELOCITY = 20;
-/** Distance from the top or right of the screen required to reveal the UI. */
-var EDGE_REVEAL = 100;
-
-/**
- * Whether a mousemove event is high enough velocity to reveal the toolbars.
- * @param {MouseEvent} e Event to test.
- * @return {boolean} true if the event is a high velocity mousemove, false
- * otherwise.
- */
-function isHighVelocityMouseMove(e) {
- return e.type == 'mousemove' &&
- e.movementX * e.movementX + e.movementY * e.movementY >
- SHOW_VELOCITY * SHOW_VELOCITY;
-}
-
-/**
- * Whether the mouse is close enough to the edge of the screen to keep the
- * toolbars open.
- * @param {Event} e Event to test.
- * @return {boolean} true if the mouse is close to the top or right of the
- * screen.
- */
-function shouldKeepUiOpen(e) {
- return (e.y < EDGE_REVEAL || e.x > window.innerWidth - EDGE_REVEAL);
-}
-
-/**
- * Creates a UI Manager to handle transitioning of toolbars.
- * @constructor
- * @param {Object} window The window containing the UI.
- * @param {Object} toolbar The top toolbar element.
- * @param {Object} zoomToolbar The zoom toolbar element.
- */
-function UiManager(window, toolbar, zoomToolbar) {
- this.window_ = window;
- this.toolbar_ = toolbar;
- this.zoomToolbar_ = zoomToolbar;
-
- this.uiTimeout_ = null;
- this.keepOpen_ = false;
-
- var userInputs = ['keydown', 'mousemove'];
- for (var i = 0; i < userInputs.length; i++)
- this.window_.addEventListener(userInputs[i], this.handleEvent.bind(this));
-
- this.window_.addEventListener('resize', this.resizeDropdowns_.bind(this));
- this.resizeDropdowns_();
-}
-
-UiManager.prototype = {
- handleEvent: function(e) {
- this.keepOpen_ = shouldKeepUiOpen(e);
- if (e.type != 'mousemove' || this.keepOpen_ || isHighVelocityMouseMove(e))
- this.showUi_();
- },
-
- /**
- * @private
- * Display the toolbar and any pane that was previously opened.
- */
- showUi_: function() {
- this.toolbar_.show();
- this.zoomToolbar_.show();
- this.hideUiAfterTimeout();
- },
-
- /**
- * @private
- * Hide the toolbar and any pane that was previously opened.
- */
- hideUi_: function() {
- if (!(this.keepOpen_ || this.toolbar_.shouldKeepOpen())) {
- this.toolbar_.hide();
- this.zoomToolbar_.hide();
- }
- },
-
- /**
- * Hide the toolbar after the HIDE_TIMEOUT has elapsed.
- */
- hideUiAfterTimeout: function() {
- if (this.uiTimeout_)
- clearTimeout(this.uiTimeout_);
- this.uiTimeout_ = setTimeout(this.hideUi_.bind(this), HIDE_TIMEOUT);
- },
-
- /**
- * Updates the size of toolbar dropdowns based on the positions of the rest of
- * the UI.
- * @private
- */
- resizeDropdowns_: function() {
- var lowerBound = this.window_.innerHeight - this.zoomToolbar_.clientHeight;
- this.toolbar_.setDropdownLowerBound(lowerBound);
- }
-};
diff --git a/chromium/chrome/browser/resources/pdf/viewport.js b/chromium/chrome/browser/resources/pdf/viewport.js
index 47c25079faa..4cb8fee0f66 100644
--- a/chromium/chrome/browser/resources/pdf/viewport.js
+++ b/chromium/chrome/browser/resources/pdf/viewport.js
@@ -25,6 +25,8 @@ function getIntersectionHeight(rect1, rect2) {
* @param {Function} afterZoomCallback is run after a change in zoom
* @param {number} scrollbarWidth the width of scrollbars on the page
* @param {number} defaultZoom The default zoom level.
+ * @param {number} topToolbarHeight The number of pixels that should initially
+ * be left blank above the document for the toolbar.
*/
function Viewport(window,
sizer,
@@ -32,7 +34,8 @@ function Viewport(window,
beforeZoomCallback,
afterZoomCallback,
scrollbarWidth,
- defaultZoom) {
+ defaultZoom,
+ topToolbarHeight) {
this.window_ = window;
this.sizer_ = sizer;
this.viewportChangedCallback_ = viewportChangedCallback;
@@ -45,6 +48,7 @@ function Viewport(window,
this.scrollbarWidth_ = scrollbarWidth;
this.fittingType_ = Viewport.FittingType.NONE;
this.defaultZoom_ = defaultZoom;
+ this.topToolbarHeight_ = topToolbarHeight;
window.addEventListener('scroll', this.updateViewport_.bind(this));
window.addEventListener('resize', this.resize_.bind(this));
@@ -91,6 +95,24 @@ Viewport.PAGE_SHADOW = {top: 3, bottom: 7, left: 5, right: 5};
Viewport.prototype = {
/**
+ * Returns the zoomed and rounded document dimensions for the given zoom.
+ * Rounding is necessary when interacting with the renderer which tends to
+ * operate in integral values (for example for determining if scrollbars
+ * should be shown).
+ * @param {number} zoom The zoom to use to compute the scaled dimensions.
+ * @return {Object} A dictionary with scaled 'width'/'height' of the document.
+ * @private
+ */
+ getZoomedDocumentDimensions_: function(zoom) {
+ if (!this.documentDimensions_)
+ return null;
+ return {
+ width: Math.round(this.documentDimensions_.width * zoom),
+ height: Math.round(this.documentDimensions_.height * zoom)
+ };
+ },
+
+ /**
* @private
* Returns true if the document needs scrollbars at the given zoom level.
* @param {number} zoom compute whether scrollbars are needed at this zoom
@@ -99,25 +121,25 @@ Viewport.prototype = {
* respectively.
*/
documentNeedsScrollbars_: function(zoom) {
- if (!this.documentDimensions_) {
+ var zoomedDimensions = this.getZoomedDocumentDimensions_(zoom);
+ if (!zoomedDimensions) {
return {
horizontal: false,
vertical: false
};
}
- var documentWidth = this.documentDimensions_.width * zoom;
- var documentHeight = this.documentDimensions_.height * zoom;
// If scrollbars are required for one direction, expand the document in the
// other direction to take the width of the scrollbars into account when
// deciding whether the other direction needs scrollbars.
- if (documentWidth > this.window_.innerWidth)
- documentHeight += this.scrollbarWidth_;
- else if (documentHeight > this.window_.innerHeight)
- documentWidth += this.scrollbarWidth_;
+ if (zoomedDimensions.width > this.window_.innerWidth)
+ zoomedDimensions.height += this.scrollbarWidth_;
+ else if (zoomedDimensions.height > this.window_.innerHeight)
+ zoomedDimensions.width += this.scrollbarWidth_;
return {
- horizontal: documentWidth > this.window_.innerWidth,
- vertical: documentHeight > this.window_.innerHeight
+ horizontal: zoomedDimensions.width > this.window_.innerWidth,
+ vertical: zoomedDimensions.height + this.topToolbarHeight_ >
+ this.window_.innerHeight
};
},
@@ -136,11 +158,11 @@ Viewport.prototype = {
* Helper function called when the zoomed document size changes.
*/
contentSizeChanged_: function() {
- if (this.documentDimensions_) {
- this.sizer_.style.width =
- this.documentDimensions_.width * this.zoom_ + 'px';
- this.sizer_.style.height =
- this.documentDimensions_.height * this.zoom_ + 'px';
+ var zoomedDimensions = this.getZoomedDocumentDimensions_(this.zoom_);
+ if (zoomedDimensions) {
+ this.sizer_.style.width = zoomedDimensions.width + 'px';
+ this.sizer_.style.height = zoomedDimensions.height +
+ this.topToolbarHeight_ + 'px';
}
},
@@ -171,7 +193,7 @@ Viewport.prototype = {
get position() {
return {
x: this.window_.pageXOffset,
- y: this.window_.pageYOffset
+ y: this.window_.pageYOffset - this.topToolbarHeight_
};
},
@@ -180,7 +202,7 @@ Viewport.prototype = {
* @type {Object} position the position to scroll to.
*/
set position(position) {
- this.window_.scrollTo(position.x, position.y);
+ this.window_.scrollTo(position.x, position.y + this.topToolbarHeight_);
},
/**
@@ -229,15 +251,17 @@ Viewport.prototype = {
'Viewport.mightZoom_.';
}
// Record the scroll position (relative to the top-left of the window).
- var currentScrollPos = [
- this.window_.pageXOffset / this.zoom_,
- this.window_.pageYOffset / this.zoom_
- ];
+ var currentScrollPos = {
+ x: this.position.x / this.zoom_,
+ y: this.position.y / this.zoom_
+ };
this.zoom_ = newZoom;
this.contentSizeChanged_();
// Scroll to the scaled scroll position.
- this.window_.scrollTo(currentScrollPos[0] * newZoom,
- currentScrollPos[1] * newZoom);
+ this.position = {
+ x: currentScrollPos.x * newZoom,
+ y: currentScrollPos.y * newZoom
+ };
},
/**
@@ -353,10 +377,7 @@ Viewport.prototype = {
if (!needsScrollbars.horizontal && !needsScrollbars.vertical)
return zoom;
- var zoomedDimensions = {
- width: this.documentDimensions_.width * zoom,
- height: this.documentDimensions_.height * zoom
- };
+ var zoomedDimensions = this.getZoomedDocumentDimensions_(zoom);
// Check if adding a scrollbar will result in needing the other scrollbar.
var scrollbarWidth = this.scrollbarWidth_;
@@ -426,8 +447,12 @@ Viewport.prototype = {
height: this.pageDimensions_[page].height,
};
this.setZoomInternal_(this.computeFittingZoom_(dimensions, false));
- if (scrollToTopOfPage)
- this.window_.scrollTo(0, this.pageDimensions_[page].y * this.zoom_);
+ if (scrollToTopOfPage) {
+ this.position = {
+ x: 0,
+ y: this.pageDimensions_[page].y * this.zoom_
+ };
+ }
this.updateViewport_();
}.bind(this));
},
@@ -485,8 +510,16 @@ Viewport.prototype = {
if (page >= this.pageDimensions_.length)
page = this.pageDimensions_.length - 1;
var dimensions = this.pageDimensions_[page];
- this.window_.scrollTo(dimensions.x * this.zoom_,
- dimensions.y * this.zoom_);
+ var toolbarOffset = 0;
+ // Unless we're in fit to page mode, scroll above the page by
+ // |this.topToolbarHeight_| so that the toolbar isn't covering it
+ // initially.
+ if (this.fittingType_ != Viewport.FittingType.FIT_TO_PAGE)
+ toolbarOffset = this.topToolbarHeight_;
+ this.position = {
+ x: dimensions.x * this.zoom_,
+ y: dimensions.y * this.zoom_ - toolbarOffset
+ };
this.updateViewport_();
}.bind(this));
},
@@ -504,7 +537,10 @@ Viewport.prototype = {
this.setZoomInternal_(
Math.min(this.defaultZoom_,
this.computeFittingZoom_(this.documentDimensions_, true)));
- this.window_.scrollTo(0, 0);
+ this.position = {
+ x: 0,
+ y: -this.topToolbarHeight_
+ };
}
this.contentSizeChanged_();
this.resize_();
diff --git a/chromium/chrome/browser/resources/pdf/zoom_manager.js b/chromium/chrome/browser/resources/pdf/zoom_manager.js
index 14c57a061d8..2b52c54aba3 100644
--- a/chromium/chrome/browser/resources/pdf/zoom_manager.js
+++ b/chromium/chrome/browser/resources/pdf/zoom_manager.js
@@ -13,12 +13,12 @@ class ZoomManager {
* @param {!Viewport} viewport A Viewport for which to manage zoom.
* @param {Function} setBrowserZoomFunction A function that sets the browser
* zoom to the provided value.
- * @param {number} defaultZoom The default browser zoom level.
+ * @param {number} initialZoom The initial browser zoom level.
*/
- constructor(viewport, setBrowserZoomFunction, defaultZoom) {
+ constructor(viewport, setBrowserZoomFunction, initialZoom) {
this.viewport_ = viewport;
this.setBrowserZoomFunction_ = setBrowserZoomFunction;
- this.browserZoom_ = defaultZoom;
+ this.browserZoom_ = initialZoom;
this.changingBrowserZoom_ = null;
}