Merge pull request #3527 from timvandermeij/better-password-prompt
Improved password prompt
This commit is contained in:
commit
2a2150380a
@ -125,8 +125,10 @@ missing_file_error=Missing PDF file.
|
|||||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||||
text_annotation_type.alt=[{{type}} Annotation]
|
text_annotation_type.alt=[{{type}} Annotation]
|
||||||
request_password=PDF is protected by a password:
|
password_label=Enter the password to open this PDF file.
|
||||||
invalid_password=Invalid Password.
|
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_supported=Warning: Printing is not fully supported by this browser.
|
||||||
printing_not_ready=Warning: The PDF is not fully loaded for printing.
|
printing_not_ready=Warning: The PDF is not fully loaded for printing.
|
||||||
|
@ -125,8 +125,10 @@ missing_file_error=Ontbrekend PDF-bestand.
|
|||||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||||
text_annotation_type.alt=[{{type}}-aantekening]
|
text_annotation_type.alt=[{{type}}-aantekening]
|
||||||
request_password=Dit PDF-bestand is beveiligd met een wachtwoord:
|
password_label=Voer het wachtwoord in om dit PDF-bestand te openen.
|
||||||
invalid_password=Onjuist wachtwoord.
|
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_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.
|
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
94
web/password_prompt.js
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -547,6 +547,7 @@ html[dir='rtl'] .splitToolbarButton > .toolbarButton {
|
|||||||
.splitToolbarButton > .toolbarButton:hover,
|
.splitToolbarButton > .toolbarButton:hover,
|
||||||
.splitToolbarButton > .toolbarButton:focus,
|
.splitToolbarButton > .toolbarButton:focus,
|
||||||
.dropdownToolbarButton:hover,
|
.dropdownToolbarButton:hover,
|
||||||
|
.promptButton:hover,
|
||||||
.toolbarButton.textButton:hover,
|
.toolbarButton.textButton:hover,
|
||||||
.toolbarButton.textButton:focus {
|
.toolbarButton.textButton:focus {
|
||||||
background-color: hsla(0,0%,0%,.2);
|
background-color: hsla(0,0%,0%,.2);
|
||||||
@ -603,6 +604,7 @@ html[dir='rtl'] .splitToolbarButtonSeparator {
|
|||||||
|
|
||||||
.toolbarButton,
|
.toolbarButton,
|
||||||
.dropdownToolbarButton,
|
.dropdownToolbarButton,
|
||||||
|
.promptButton,
|
||||||
.secondaryToolbarButton {
|
.secondaryToolbarButton {
|
||||||
min-width: 16px;
|
min-width: 16px;
|
||||||
padding: 2px 6px 0;
|
padding: 2px 6px 0;
|
||||||
@ -625,10 +627,12 @@ html[dir='rtl'] .splitToolbarButtonSeparator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
html[dir='ltr'] .toolbarButton,
|
html[dir='ltr'] .toolbarButton,
|
||||||
|
html[dir='ltr'] .promptButton,
|
||||||
html[dir='ltr'] .dropdownToolbarButton {
|
html[dir='ltr'] .dropdownToolbarButton {
|
||||||
margin: 3px 2px 4px 0;
|
margin: 3px 2px 4px 0;
|
||||||
}
|
}
|
||||||
html[dir='rtl'] .toolbarButton,
|
html[dir='rtl'] .toolbarButton,
|
||||||
|
html[dir='rtl'] .promptButton,
|
||||||
html[dir='rtl'] .dropdownToolbarButton {
|
html[dir='rtl'] .dropdownToolbarButton {
|
||||||
margin: 3px 0 4px 2px;
|
margin: 3px 0 4px 2px;
|
||||||
}
|
}
|
||||||
@ -636,6 +640,7 @@ html[dir='rtl'] .dropdownToolbarButton {
|
|||||||
.toolbarButton:hover,
|
.toolbarButton:hover,
|
||||||
.toolbarButton:focus,
|
.toolbarButton:focus,
|
||||||
.dropdownToolbarButton,
|
.dropdownToolbarButton,
|
||||||
|
.promptButton,
|
||||||
.secondaryToolbarButton:hover,
|
.secondaryToolbarButton:hover,
|
||||||
.secondaryToolbarButton:focus {
|
.secondaryToolbarButton:focus {
|
||||||
background-color: hsla(0,0%,0%,.12);
|
background-color: hsla(0,0%,0%,.12);
|
||||||
@ -649,6 +654,7 @@ html[dir='rtl'] .dropdownToolbarButton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.toolbarButton:hover:active,
|
.toolbarButton:hover:active,
|
||||||
|
.promptButton:hover:active,
|
||||||
.dropdownToolbarButton:hover:active,
|
.dropdownToolbarButton:hover:active,
|
||||||
.secondaryToolbarButton:hover:active {
|
.secondaryToolbarButton:hover:active {
|
||||||
background-color: hsla(0,0%,0%,.2);
|
background-color: hsla(0,0%,0%,.2);
|
||||||
@ -722,6 +728,12 @@ html[dir='rtl'] .dropdownToolbarButton {
|
|||||||
background: hsl(0,0%,24%);
|
background: hsl(0,0%,24%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.promptButton {
|
||||||
|
margin: 3px 2px 4px 5px !important;
|
||||||
|
line-height: 16px;
|
||||||
|
padding: 2px 6px 3px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
#customScaleOption {
|
#customScaleOption {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -1326,6 +1338,60 @@ canvas {
|
|||||||
width: 98%;
|
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 {
|
.clearBoth {
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,7 @@ limitations under the License.
|
|||||||
<script type="text/javascript" src="pdf_find_controller.js"></script>
|
<script type="text/javascript" src="pdf_find_controller.js"></script>
|
||||||
<script type="text/javascript" src="pdf_history.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="secondary_toolbar.js"></script>
|
||||||
|
<script type="text/javascript" src="password_prompt.js"></script>
|
||||||
<!--#endif-->
|
<!--#endif-->
|
||||||
|
|
||||||
<script type="text/javascript" src="debugger.js"></script>
|
<script type="text/javascript" src="debugger.js"></script>
|
||||||
@ -281,6 +282,23 @@ limitations under the License.
|
|||||||
</div>
|
</div>
|
||||||
</div> <!-- mainContainer -->
|
</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> <!-- outerContainer -->
|
||||||
<div id="printContainer"></div>
|
<div id="printContainer"></div>
|
||||||
</body>
|
</body>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
PDFFindController, ProgressBar, TextLayerBuilder, DownloadManager,
|
PDFFindController, ProgressBar, TextLayerBuilder, DownloadManager,
|
||||||
getFileName, getOutputScale, scrollIntoView, getPDFFileNameFromURL,
|
getFileName, getOutputScale, scrollIntoView, getPDFFileNameFromURL,
|
||||||
PDFHistory, PageView, ThumbnailView, noContextMenuHandler,
|
PDFHistory, PageView, ThumbnailView, noContextMenuHandler,
|
||||||
SecondaryToolbar */
|
SecondaryToolbar, PasswordPrompt */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
@ -167,6 +167,7 @@ var currentPageNumber = 1;
|
|||||||
//#include pdf_find_controller.js
|
//#include pdf_find_controller.js
|
||||||
//#include pdf_history.js
|
//#include pdf_history.js
|
||||||
//#include secondary_toolbar.js
|
//#include secondary_toolbar.js
|
||||||
|
//#include password_prompt.js
|
||||||
|
|
||||||
var PDFView = {
|
var PDFView = {
|
||||||
pages: [],
|
pages: [],
|
||||||
@ -217,6 +218,14 @@ var PDFView = {
|
|||||||
pageRotateCcw: document.getElementById('pageRotateCcw')
|
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({
|
PDFFindBar.initialize({
|
||||||
bar: document.getElementById('findbar'),
|
bar: document.getElementById('findbar'),
|
||||||
toggleButton: document.getElementById('viewFind'),
|
toggleButton: document.getElementById('viewFind'),
|
||||||
@ -572,18 +581,9 @@ var PDFView = {
|
|||||||
var self = this;
|
var self = this;
|
||||||
self.loading = true;
|
self.loading = true;
|
||||||
var passwordNeeded = function passwordNeeded(updatePassword, reason) {
|
var passwordNeeded = function passwordNeeded(updatePassword, reason) {
|
||||||
var promptString = mozL10n.get('request_password', null,
|
PasswordPrompt.updatePassword = updatePassword;
|
||||||
'PDF is protected by a password:');
|
PasswordPrompt.reason = reason;
|
||||||
|
PasswordPrompt.show();
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function getDocumentProgress(progressData) {
|
function getDocumentProgress(progressData) {
|
||||||
@ -2092,6 +2092,10 @@ window.addEventListener('click', function click(evt) {
|
|||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
window.addEventListener('keydown', function keydown(evt) {
|
window.addEventListener('keydown', function keydown(evt) {
|
||||||
|
if (PasswordPrompt.visible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var handled = false;
|
var handled = false;
|
||||||
var cmd = (evt.ctrlKey ? 1 : 0) |
|
var cmd = (evt.ctrlKey ? 1 : 0) |
|
||||||
(evt.altKey ? 2 : 0) |
|
(evt.altKey ? 2 : 0) |
|
||||||
|
Loading…
x
Reference in New Issue
Block a user