From 35a7213a6756ada832944ac577fc8bb79365ba85 Mon Sep 17 00:00:00 2001 From: Thomas Marstrander Date: Tue, 5 Apr 2016 18:35:02 +0200 Subject: [PATCH 1/2] Added confirmation dialog. HFJ-1572 --- h5p.classes.php | 3 + js/h5p-confirmation-dialog.js | 162 +++++++++++++++++++++++++++++ js/h5p-event-dispatcher.js | 2 +- styles/h5p-confirmation-dialog.css | 103 ++++++++++++++++++ styles/h5p-core-button.css | 59 +++++++++++ 5 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 js/h5p-confirmation-dialog.js create mode 100644 styles/h5p-confirmation-dialog.css create mode 100644 styles/h5p-core-button.css diff --git a/h5p.classes.php b/h5p.classes.php index 5ede697..395e7a4 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -1664,6 +1664,8 @@ class H5PCore { ); public static $styles = array( 'styles/h5p.css', + 'styles/h5p-confirmation-dialog.css', + 'styles/h5p-core-button.css' ); public static $scripts = array( 'js/jquery.js', @@ -1672,6 +1674,7 @@ class H5PCore { 'js/h5p-x-api-event.js', 'js/h5p-x-api.js', 'js/h5p-content-type.js', + 'js/h5p-confirmation-dialog.js' ); public static $adminScripts = array( 'js/jquery.js', diff --git a/js/h5p-confirmation-dialog.js b/js/h5p-confirmation-dialog.js new file mode 100644 index 0000000..7675d06 --- /dev/null +++ b/js/h5p-confirmation-dialog.js @@ -0,0 +1,162 @@ +/*global H5P*/ +H5P.ConfirmationDialog = (function (EventDispatcher) { + "use strict"; + + /** + * Create a confirmation dialog + * + * @param [options] Options for confirmation dialog + * @param [options.headerText] Header text + * @param [options.dialogText] Dialog text + * @param [options.cancelText] Cancel dialog button text + * @param [options.confirmText] Confirm dialog button text + * @constructor + */ + function ConfirmationDialog(options) { + EventDispatcher.call(this); + var self = this; + + // 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'; + + // Create background + var popupBackground = document.createElement('div'); + popupBackground.classList + .add('h5p-confirmation-dialog-background', 'hidden', 'hiding'); + + // Create outer popup + var popup = document.createElement('div'); + popup.classList.add('h5p-confirmation-dialog-popup', 'hidden'); + popupBackground.appendChild(popup); + + // Popup header + var header = document.createElement('div'); + header.classList.add('h5p-confirmation-dialog-header'); + popup.appendChild(header); + + // Header text + var headerText = document.createElement('div'); + headerText.classList.add('h5p-confirmation-dialog-header-text'); + headerText.innerHTML = options.headerText; + header.appendChild(headerText); + + // Popup body + var body = document.createElement('div'); + body.classList.add('h5p-confirmation-dialog-body'); + popup.appendChild(body); + + // Popup text + var text = document.createElement('div'); + text.classList.add('h5p-confirmation-dialog-text'); + text.innerHTML = options.dialogText; + body.appendChild(text); + + // Popup buttons + var buttons = document.createElement('div'); + buttons.classList.add('h5p-confirmation-dialog-buttons'); + body.appendChild(buttons); + + // Cancel button + var cancelButton = document.createElement('button'); + cancelButton.classList.add('h5p-core-cancel-button'); + cancelButton.tabindex = 0; + cancelButton.textContent = options.cancelText; + cancelButton.onclick = function () { + self.hide(); + self.trigger('canceled'); + }; + buttons.appendChild(cancelButton); + + // Confirm button + var confirmButton = document.createElement('button'); + confirmButton.classList.add('h5p-core-button', + 'h5p-confirmation-dialog-confirm-button'); + confirmButton.tabindex = 0; + confirmButton.textContent = options.confirmText; + confirmButton.onclick = function () { + self.hide(); + self.trigger('confirmed'); + }; + buttons.appendChild(confirmButton); + + // Exit button + var exitButton = document.createElement('button'); + exitButton.classList.add('h5p-confirmation-dialog-exit'); + exitButton.tabindex = 0; + exitButton.onclick = function () { + self.hide(); + self.trigger('canceled'); + }; + popup.appendChild(exitButton); + + // Wrapper element + var wrapperElement; + + /** + * Append confirmation dialog + * @param {HTMLElement} wrapper + * @returns {H5P.ConfirmationDialog} + */ + this.appendTo = function (wrapper) { + wrapper.appendChild(popupBackground); + wrapperElement = wrapper; + + return this; + }; + + /** + * Fit popup to container. Makes sure it doesn't overflow. + */ + var fitToContainer = function () { + var popupOffset = parseInt(popup.style.top, 10) + popup.offsetHeight; + + // Overflows wrapper + if (popupOffset > wrapperElement.offsetHeight) { + var overflowedContainerOffset = wrapperElement.offsetHeight - popup.offsetHeight; + popup.style.top = overflowedContainerOffset + 'px'; + } + }; + + /** + * Show confirmation dialog + * @params {number} offsetTop Offset top + * @returns {H5P.ConfirmationDialog} + */ + this.show = function (offsetTop) { + popup.style.top = offsetTop + 'px'; + popupBackground.classList.remove('hidden'); + fitToContainer(); + popupBackground.classList.remove('hiding'); + popup.classList.remove('hidden'); + cancelButton.focus(); + + return this; + }; + + /** + * Hide confirmation dialog + * @returns {H5P.ConfirmationDialog} + */ + this.hide = function () { + popupBackground.classList.add('hiding'); + popup.classList.add('hidden'); + setTimeout(function () { + popupBackground.classList.add('hidden'); + }, 100); + + return this; + }; + } + + ConfirmationDialog.prototype = Object.create(EventDispatcher.prototype); + ConfirmationDialog.prototype.constructor = ConfirmationDialog; + + return ConfirmationDialog; + +}(H5P.EventDispatcher)); diff --git a/js/h5p-event-dispatcher.js b/js/h5p-event-dispatcher.js index fb8dd66..592e8cf 100644 --- a/js/h5p-event-dispatcher.js +++ b/js/h5p-event-dispatcher.js @@ -99,7 +99,7 @@ H5P.EventDispatcher = (function () { * Event type * @param {H5P.EventCallback} listener * Event listener - * @param {Object} thisArg + * @param {Object} [thisArg] * Optionally specify the this value when calling listener. */ this.on = function (type, listener, thisArg) { diff --git a/styles/h5p-confirmation-dialog.css b/styles/h5p-confirmation-dialog.css new file mode 100644 index 0000000..b7b4475 --- /dev/null +++ b/styles/h5p-confirmation-dialog.css @@ -0,0 +1,103 @@ +.h5p-confirmation-dialog-background { + position: absolute; + height: 100%; + width: 100%; + left: 0; + top: 0; + + background: rgba(255, 255, 255, 0.85); + opacity: 1; + visibility: visible; + -webkit-transition: opacity 0.1s, linear 0s, visibility 0s linear 0s; + transition: opacity 0.1s linear 0s, visibility 0s linear 0s; + + z-index: 11; +} + +.h5p-confirmation-dialog-background.hidden { + display: none; +} + +.h5p-confirmation-dialog-background.hiding { + opacity: 0; + visibility: hidden; + -webkit-transition: opacity 0.1s, linear 0s, visibility 0s linear 0.1s; + transition: opacity 0.1s linear 0s, visibility 0s linear 0.1s; +} + +.h5p-confirmation-dialog-popup { + position: absolute; + display: flex; + flex-direction: column; + justify-content: center; + + box-sizing: border-box; + max-width: calc(100% - 2em); + min-width: 25em; + + top: 2em; + left: 50%; + -webkit-transform: translate(-50%, 0%); + -ms-transform: translate(-50%, 0%); + transform: translate(-50%, 0%); + + color: #555; + box-shadow: 0 0 6px 1px #ddd; + + -webkit-transition: transform 0.1s ease-in; + transition: transform 0.1s ease-in; +} + +.h5p-confirmation-dialog-popup.hidden { + -webkit-transform: translate(-50%, 50%); + -ms-transform: translate(-50%, 50%); + transform: translate(-50%, 50%); +} + +.h5p-confirmation-dialog-header { + padding: 1.5em; + background: #fff; + color: #1a73d9; +} + +.h5p-confirmation-dialog-header-text { + font-size: 1.25em; +} + +.h5p-confirmation-dialog-body { + padding: 1.25em 1.5em; + background: #fafafa; +} + +.h5p-confirmation-dialog-text { + margin-bottom: 1.5em; +} + +.h5p-confirmation-dialog-buttons { + float: right; +} + +.h5p-confirmation-dialog-exit { + position: absolute; + background: none; + border: none; + font-size: 2.5em; + top: -0.9em; + right: -1.15em; + color: #777; + cursor: pointer; +} + +.h5p-confirmation-dialog-exit:before { + font-family: "H5P"; + content: "\e890"; +} + +.h5p-core-button.h5p-confirmation-dialog-confirm-button { + padding-left: 0.75em; + margin-bottom: 0; +} + +.h5p-core-button.h5p-confirmation-dialog-confirm-button:before { + content: "\e601"; +} diff --git a/styles/h5p-core-button.css b/styles/h5p-core-button.css new file mode 100644 index 0000000..e073e74 --- /dev/null +++ b/styles/h5p-core-button.css @@ -0,0 +1,59 @@ +.h5p-core-button { + font-size: 1em; + line-height: 1.2; + padding: 0.5em 1.25em; + border-radius: 2em; + + background: #1a73d9; + color: #ffffff; + + cursor: pointer; + border: none; + box-shadow: none; + outline: none; + + display: inline-block; + text-align: center; + text-shadow: none; + vertical-align: baseline; +} +.h5p-core-button:hover, +.h5p-core-button:focus { + background: #1356a3; + color: #fff; + text-decoration: none; + -webkit-transition: initial; + transition: initial; +} +.h5p-core-button:active { + position: relative; + background: #104888; + + -webkit-box-shadow: inset 0 4px 0 #0e407a; + -moz-box-shadow: inset 0 4px 0 #0e407a; + box-shadow: inset 0 4px 0 #0e407a; +} + +.h5p-core-button:before { + font-family: 'H5P'; + padding-right: 0.15em; + font-size: 1.5em; + vertical-align: middle; + line-height: 0.7; +} + +.h5p-core-cancel-button { + cursor: pointer; + background: none; + border: none; + color: #a00; + margin-right: 1em; + font-size: 1em; +} + +.h5p-core-cancel-button:hover, +.h5p-core-cancel-button:focus { + background: none; + border: none; + color: #e40000; +} From 02e5f2045e8fc2824d14c1e9c78b02e16a5ceb71 Mon Sep 17 00:00:00 2001 From: Marc Laporte Date: Tue, 5 Apr 2016 12:40:06 -0400 Subject: [PATCH 2/2] Fix some typos --- doc/spec_en.html | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/spec_en.html b/doc/spec_en.html index b13a744..b671f86 100644 --- a/doc/spec_en.html +++ b/doc/spec_en.html @@ -1,5 +1,5 @@ 

Overview

-

H5P is a file format for content/applications made using modern, open web technlogies (HTML5). The format enables easy installation and transfer of applications/content on different CMSes, LMSes and other platforms. An H5P canbe uploaded and published on a platform in mostly the same way one would publish a Flash file today. H5P files may also be updated by simply uploading a new version of the file, the same way as one would using Flash.

+

H5P is a file format for content/applications made using modern, open web technlogies (HTML5). The format enables easy installation and transfer of applications/content on different CMSes, LMSes and other platforms. An H5P can be uploaded and published on a platform in mostly the same way one would publish a Flash file today. H5P files may also be updated by simply uploading a new version of the file, the same way as one would using Flash.

H5P opens for extensive reuse of code and wide flexibility regarding what may be developed as an H5P.

The system uses package files containing all necessary files and libraries for the application to function. These files are based on open formats.

Overview of package files

@@ -12,7 +12,7 @@
  • A mandatory file in the root folder named h5p.json
  • An optional image file named h5p.jpg. This is an icon or an image of the application, 512 × 512 pixels. This image may be used by the platform as a preview of the application, and could be included in OG meta tags for use with social media.
  • One content folder, named content. This will contain the preset configuration for the application, as well as any required media files.
  • -
  • One or more library diractories named the same as the library's internal name.
  • +
  • One or more library directories named the same as the library's internal name.
  • h5p.json

    The h5p.json file is a normal JSON text file containing a JSON object with the following predefined properties.

    @@ -27,7 +27,7 @@