From 63233fa8c2452e60529d74246749c65d41659b87 Mon Sep 17 00:00:00 2001 From: Tim van der Meij Date: Tue, 24 Sep 2013 17:46:54 +0200 Subject: [PATCH] Improved password prompt --- l10n/en-US/viewer.properties | 6 ++- l10n/nl/viewer.properties | 6 ++- web/password_prompt.js | 94 ++++++++++++++++++++++++++++++++++++ web/viewer.css | 66 +++++++++++++++++++++++++ web/viewer.html | 18 +++++++ web/viewer.js | 30 +++++++----- 6 files changed, 203 insertions(+), 17 deletions(-) create mode 100644 web/password_prompt.js diff --git a/l10n/en-US/viewer.properties b/l10n/en-US/viewer.properties index af749a2df..629bfb27c 100644 --- a/l10n/en-US/viewer.properties +++ b/l10n/en-US/viewer.properties @@ -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. diff --git a/l10n/nl/viewer.properties b/l10n/nl/viewer.properties index e3dae8f99..9288af81e 100644 --- a/l10n/nl/viewer.properties +++ b/l10n/nl/viewer.properties @@ -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. diff --git a/web/password_prompt.js b/web/password_prompt.js new file mode 100644 index 000000000..38053fb60 --- /dev/null +++ b/web/password_prompt.js @@ -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); + } + } +}; diff --git a/web/viewer.css b/web/viewer.css index 5669248b6..b44ba7bff 100644 --- a/web/viewer.css +++ b/web/viewer.css @@ -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; } diff --git a/web/viewer.html b/web/viewer.html index 588269424..2b578091a 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -67,6 +67,7 @@ limitations under the License. + @@ -281,6 +282,23 @@ limitations under the License. + +
diff --git a/web/viewer.js b/web/viewer.js index c20b97a34..5d71b069a 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -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) |