Merge pull request #3527 from timvandermeij/better-password-prompt

Improved password prompt
This commit is contained in:
Brendan Dahl 2013-09-24 09:36:02 -07:00
commit 2a2150380a
6 changed files with 203 additions and 17 deletions

View File

@ -125,8 +125,10 @@ missing_file_error=Missing PDF file.
# the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
text_annotation_type.alt=[{{type}} Annotation]
request_password=PDF is protected by a password:
invalid_password=Invalid Password.
password_label=Enter the password to open this PDF file.
password_invalid=Invalid password. Please try again.
password_ok=OK
password_cancel=Cancel
printing_not_supported=Warning: Printing is not fully supported by this browser.
printing_not_ready=Warning: The PDF is not fully loaded for printing.

View File

@ -125,8 +125,10 @@ missing_file_error=Ontbrekend PDF-bestand.
# the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
text_annotation_type.alt=[{{type}}-aantekening]
request_password=Dit PDF-bestand is beveiligd met een wachtwoord:
invalid_password=Onjuist wachtwoord.
password_label=Voer het wachtwoord in om dit PDF-bestand te openen.
password_invalid=Onjuist wachtwoord. Probeer het opnieuw.
password_ok=OK
password_cancel=Annuleren
printing_not_supported=Waarschuwing: afdrukken wordt niet volledig ondersteund door deze browser.
printing_not_ready=Waarschuwing: het PDF-bestand is niet volledig geladen en kan daarom nog niet afgedrukt worden.

94
web/password_prompt.js Normal file
View File

@ -0,0 +1,94 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2012 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* globals PDFJS, mozL10n */
'use strict';
var PasswordPrompt = {
visible: false,
updatePassword: null,
reason: null,
overlayContainer: null,
passwordField: null,
passwordText: null,
passwordSubmit: null,
passwordCancel: null,
initialize: function secondaryToolbarInitialize(options) {
this.overlayContainer = options.overlayContainer;
this.passwordField = options.passwordField;
this.passwordText = options.passwordText;
this.passwordSubmit = options.passwordSubmit;
this.passwordCancel = options.passwordCancel;
// Attach the event listeners.
this.passwordSubmit.addEventListener('click',
this.verifyPassword.bind(this));
this.passwordCancel.addEventListener('click', this.hide.bind(this));
this.passwordField.addEventListener('keydown',
function (e) {
if (e.keyCode === 13) { // Enter key
this.verifyPassword();
}
}.bind(this));
this.overlayContainer.addEventListener('keydown',
function (e) {
if (e.keyCode === 27) { // Esc key
this.hide();
}
}.bind(this));
},
show: function passwordPromptShow() {
if (this.visible) {
return;
}
this.visible = true;
this.overlayContainer.classList.remove('hidden');
this.passwordField.focus();
var promptString = mozL10n.get('password_label', null,
'Enter the password to open this PDF file.');
if (this.reason === PDFJS.PasswordResponses.INCORRECT_PASSWORD) {
promptString = mozL10n.get('password_invalid', null,
'Invalid password. Please try again.');
}
this.passwordText.textContent = promptString;
},
hide: function passwordPromptClose() {
if (!this.visible) {
return;
}
this.visible = false;
this.passwordField.value = '';
this.overlayContainer.classList.add('hidden');
},
verifyPassword: function passwordPromptVerifyPassword() {
var password = this.passwordField.value;
if (password && password.length > 0) {
this.hide();
return this.updatePassword(password);
}
}
};

View File

@ -547,6 +547,7 @@ html[dir='rtl'] .splitToolbarButton > .toolbarButton {
.splitToolbarButton > .toolbarButton:hover,
.splitToolbarButton > .toolbarButton:focus,
.dropdownToolbarButton:hover,
.promptButton:hover,
.toolbarButton.textButton:hover,
.toolbarButton.textButton:focus {
background-color: hsla(0,0%,0%,.2);
@ -603,6 +604,7 @@ html[dir='rtl'] .splitToolbarButtonSeparator {
.toolbarButton,
.dropdownToolbarButton,
.promptButton,
.secondaryToolbarButton {
min-width: 16px;
padding: 2px 6px 0;
@ -625,10 +627,12 @@ html[dir='rtl'] .splitToolbarButtonSeparator {
}
html[dir='ltr'] .toolbarButton,
html[dir='ltr'] .promptButton,
html[dir='ltr'] .dropdownToolbarButton {
margin: 3px 2px 4px 0;
}
html[dir='rtl'] .toolbarButton,
html[dir='rtl'] .promptButton,
html[dir='rtl'] .dropdownToolbarButton {
margin: 3px 0 4px 2px;
}
@ -636,6 +640,7 @@ html[dir='rtl'] .dropdownToolbarButton {
.toolbarButton:hover,
.toolbarButton:focus,
.dropdownToolbarButton,
.promptButton,
.secondaryToolbarButton:hover,
.secondaryToolbarButton:focus {
background-color: hsla(0,0%,0%,.12);
@ -649,6 +654,7 @@ html[dir='rtl'] .dropdownToolbarButton {
}
.toolbarButton:hover:active,
.promptButton:hover:active,
.dropdownToolbarButton:hover:active,
.secondaryToolbarButton:hover:active {
background-color: hsla(0,0%,0%,.2);
@ -722,6 +728,12 @@ html[dir='rtl'] .dropdownToolbarButton {
background: hsl(0,0%,24%);
}
.promptButton {
margin: 3px 2px 4px 5px !important;
line-height: 16px;
padding: 2px 6px 3px 6px;
}
#customScaleOption {
display: none;
}
@ -1326,6 +1338,60 @@ canvas {
width: 98%;
}
#overlayContainer {
display: table;
position: absolute;
width: 100%;
height: 100%;
background-color: hsla(0,0%,0%,.2);
z-index: 10000;
}
#promptContainer {
display: table-cell;
vertical-align: middle;
text-align: center;
}
#promptContainer > * {
display: inline-block;
}
.prompt {
display: table;
padding: 15px;
border-spacing: 4px;
color: hsl(0,0%,85%);
line-height: 14px;
text-align: center;
background-color: #474747; /* fallback */
background-image: url(images/texture.png),
linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95));
box-shadow: inset 1px 0 0 hsla(0,0%,100%,.08),
inset 0 1px 1px hsla(0,0%,0%,.15),
inset 0 -1px 0 hsla(0,0%,100%,.05),
0 1px 0 hsla(0,0%,0%,.15),
0 1px 1px hsla(0,0%,0%,.1);
}
.prompt > .row {
display: table-row;
}
.prompt > .row > * {
display: table-cell;
}
.prompt .toolbarField {
margin: 5px 0;
width: 200px;
}
.prompt .toolbarField:hover,
.prompt .toolbarField:focus {
border-color: hsla(0,0%,0%,.32) hsla(0,0%,0%,.38) hsla(0,0%,0%,.42);
}
.clearBoth {
clear: both;
}

View File

@ -67,6 +67,7 @@ limitations under the License.
<script type="text/javascript" src="pdf_find_controller.js"></script>
<script type="text/javascript" src="pdf_history.js"></script>
<script type="text/javascript" src="secondary_toolbar.js"></script>
<script type="text/javascript" src="password_prompt.js"></script>
<!--#endif-->
<script type="text/javascript" src="debugger.js"></script>
@ -281,6 +282,23 @@ limitations under the License.
</div>
</div> <!-- mainContainer -->
<div id="overlayContainer" class="hidden">
<div id="promptContainer">
<div id="passwordContainer" class="prompt doorHanger">
<div class="row">
<p id="passwordText" data-l10n-id="password_label">Enter the password to open this PDF file:</p>
</div>
<div class="row">
<input type="password" id="password" class="toolbarField" />
</div>
<div class="row">
<button id="passwordCancel" class="promptButton"><span data-l10n-id="password_cancel">Cancel</span></button>
<button id="passwordSubmit" class="promptButton"><span data-l10n-id="password_ok">OK</span></button>
</div>
</div>
</div>
</div>
</div> <!-- outerContainer -->
<div id="printContainer"></div>
</body>

View File

@ -18,7 +18,7 @@
PDFFindController, ProgressBar, TextLayerBuilder, DownloadManager,
getFileName, getOutputScale, scrollIntoView, getPDFFileNameFromURL,
PDFHistory, PageView, ThumbnailView, noContextMenuHandler,
SecondaryToolbar */
SecondaryToolbar, PasswordPrompt */
'use strict';
@ -167,6 +167,7 @@ var currentPageNumber = 1;
//#include pdf_find_controller.js
//#include pdf_history.js
//#include secondary_toolbar.js
//#include password_prompt.js
var PDFView = {
pages: [],
@ -217,6 +218,14 @@ var PDFView = {
pageRotateCcw: document.getElementById('pageRotateCcw')
});
PasswordPrompt.initialize({
overlayContainer: document.getElementById('overlayContainer'),
passwordField: document.getElementById('password'),
passwordText: document.getElementById('passwordText'),
passwordSubmit: document.getElementById('passwordSubmit'),
passwordCancel: document.getElementById('passwordCancel')
});
PDFFindBar.initialize({
bar: document.getElementById('findbar'),
toggleButton: document.getElementById('viewFind'),
@ -572,18 +581,9 @@ var PDFView = {
var self = this;
self.loading = true;
var passwordNeeded = function passwordNeeded(updatePassword, reason) {
var promptString = mozL10n.get('request_password', null,
'PDF is protected by a password:');
if (reason === PDFJS.PasswordResponses.INCORRECT_PASSWORD) {
promptString += '\n' + mozL10n.get('invalid_password', null,
'Invalid Password.');
}
password = prompt(promptString);
if (password && password.length > 0) {
return updatePassword(password);
}
PasswordPrompt.updatePassword = updatePassword;
PasswordPrompt.reason = reason;
PasswordPrompt.show();
};
function getDocumentProgress(progressData) {
@ -2092,6 +2092,10 @@ window.addEventListener('click', function click(evt) {
}, false);
window.addEventListener('keydown', function keydown(evt) {
if (PasswordPrompt.visible) {
return;
}
var handled = false;
var cmd = (evt.ctrlKey ? 1 : 0) |
(evt.altKey ? 2 : 0) |