diff --git a/js/h5p-confirmation-dialog.js b/js/h5p-confirmation-dialog.js index 7675d06..3263b76 100644 --- a/js/h5p-confirmation-dialog.js +++ b/js/h5p-confirmation-dialog.js @@ -18,12 +18,14 @@ H5P.ConfirmationDialog = (function (EventDispatcher) { // Default options options = options || {}; - options.headerText = options.headerText || - 'Confirm action'; - options.dialogText = options.dialogText || - 'Please confirm that you wish to proceed. This action will not be reversible.'; - options.cancelText = options.cancelText || 'Cancel'; - options.confirmText = options.confirmText || 'Confirm'; + options.headerText = options.headerText || H5P.t('confirmDialogHeader'); + options.dialogText = options.dialogText || H5P.t('confirmDialogBody'); + options.cancelText = options.cancelText || H5P.t('cancelLabel'); + options.confirmText = options.confirmText || H5P.t('confirmLabel'); + + // Offset of exit button + var exitButtonOffset = 2 * 16; + var shadowOffset = 8; // Create background var popupBackground = document.createElement('div'); @@ -63,35 +65,71 @@ H5P.ConfirmationDialog = (function (EventDispatcher) { body.appendChild(buttons); // Cancel button - var cancelButton = document.createElement('button'); + var cancelButton = document.createElement('a'); cancelButton.classList.add('h5p-core-cancel-button'); - cancelButton.tabindex = 0; + cancelButton.href = '#'; cancelButton.textContent = options.cancelText; - cancelButton.onclick = function () { + cancelButton.onclick = function (e) { self.hide(); self.trigger('canceled'); + e.preventDefault(); + }; + cancelButton.onkeydown = function (e) { + if (e.which === 32) { // Space + // Prevent jumping + e.preventDefault(); + } + else if (e.which === 13) { // Enter + self.hide(); + self.trigger('canceled'); + e.preventDefault(); + } }; buttons.appendChild(cancelButton); // Confirm button - var confirmButton = document.createElement('button'); + var confirmButton = document.createElement('a'); confirmButton.classList.add('h5p-core-button', 'h5p-confirmation-dialog-confirm-button'); - confirmButton.tabindex = 0; + confirmButton.href = '#'; confirmButton.textContent = options.confirmText; - confirmButton.onclick = function () { + confirmButton.onclick = function (e) { self.hide(); self.trigger('confirmed'); + e.preventDefault(); + }; + confirmButton.onkeydown = function (e) { + if (e.which === 32) { // Space + // Prevent jumping + e.preventDefault(); + } + else if (e.which === 13) { // Enter + self.hide(); + self.trigger('confirmed'); + e.preventDefault(); + } }; buttons.appendChild(confirmButton); // Exit button - var exitButton = document.createElement('button'); + var exitButton = document.createElement('a'); + exitButton.href = '#'; exitButton.classList.add('h5p-confirmation-dialog-exit'); - exitButton.tabindex = 0; - exitButton.onclick = function () { + exitButton.onclick = function (e) { self.hide(); self.trigger('canceled'); + e.preventDefault(); + }; + exitButton.onkeydown = function (e) { + if (e.which === 32) { // Space + // Prevent jumping + e.preventDefault(); + } + else if (e.which === 13) { // Enter + self.hide(); + self.trigger('canceled'); + e.preventDefault(); + } }; popup.appendChild(exitButton); @@ -114,13 +152,17 @@ H5P.ConfirmationDialog = (function (EventDispatcher) { * Fit popup to container. Makes sure it doesn't overflow. */ var fitToContainer = function () { - var popupOffset = parseInt(popup.style.top, 10) + popup.offsetHeight; + var popupOffsetTop = parseInt(popup.style.top, 10); - // Overflows wrapper - if (popupOffset > wrapperElement.offsetHeight) { - var overflowedContainerOffset = wrapperElement.offsetHeight - popup.offsetHeight; - popup.style.top = overflowedContainerOffset + 'px'; + // Overflows height + if (popupOffsetTop + popup.offsetHeight > wrapperElement.offsetHeight) { + popupOffsetTop = wrapperElement.offsetHeight - popup.offsetHeight; } + + if (popupOffsetTop - exitButtonOffset <= 0) { + popupOffsetTop = exitButtonOffset; + } + popup.style.top = popupOffsetTop + 'px'; }; /** @@ -134,7 +176,10 @@ H5P.ConfirmationDialog = (function (EventDispatcher) { fitToContainer(); popupBackground.classList.remove('hiding'); popup.classList.remove('hidden'); - cancelButton.focus(); + + // Programmatically focus popup + popup.setAttribute('tabindex', '-1'); + popup.focus(); return this; }; diff --git a/js/h5p.js b/js/h5p.js index dfa6671..003f179 100644 --- a/js/h5p.js +++ b/js/h5p.js @@ -868,9 +868,9 @@ H5P.error = function (err) { * * @param {string} key * Translation identifier, may only contain a-zA-Z0-9. No spaces or special chars. - * @param {Object} vars + * @param {Object} [vars] * Data for placeholders. - * @param {string} ns + * @param {string} [ns] * Translation namespace. Defaults to H5P. * @returns {string} * Translated text diff --git a/styles/h5p-confirmation-dialog.css b/styles/h5p-confirmation-dialog.css index b7b4475..05e3a3f 100644 --- a/styles/h5p-confirmation-dialog.css +++ b/styles/h5p-confirmation-dialog.css @@ -25,6 +25,10 @@ transition: opacity 0.1s linear 0s, visibility 0s linear 0.1s; } +.h5p-confirmation-dialog-popup:focus { + outline: none; +} + .h5p-confirmation-dialog-popup { position: absolute; display: flex; @@ -32,7 +36,7 @@ justify-content: center; box-sizing: border-box; - max-width: calc(100% - 2em); + max-width: 35em; min-width: 25em; top: 2em; @@ -77,6 +81,11 @@ float: right; } +.h5p-confirmation-dialog-exit:focus, +.h5p-confirmation-dialog-exit:hover { + color: #555; +} + .h5p-confirmation-dialog-exit { position: absolute; background: none; @@ -86,6 +95,7 @@ right: -1.15em; color: #777; cursor: pointer; + text-decoration: none; } .h5p-confirmation-dialog-exit:before { diff --git a/styles/h5p-core-button.css b/styles/h5p-core-button.css index e073e74..f7cc3f1 100644 --- a/styles/h5p-core-button.css +++ b/styles/h5p-core-button.css @@ -16,6 +16,7 @@ text-align: center; text-shadow: none; vertical-align: baseline; + text-decoration: none; } .h5p-core-button:hover, .h5p-core-button:focus { @@ -49,6 +50,7 @@ color: #a00; margin-right: 1em; font-size: 1em; + text-decoration: none; } .h5p-core-cancel-button:hover,