Download and embed granularity (HFP-277)

improved-embed-and-download
Paal Joergensen 2016-12-13 10:29:33 +01:00
parent c906cb7084
commit 0a23dc043d
5 changed files with 236 additions and 128 deletions

View File

@ -558,6 +558,8 @@ interface H5PFrameworkInterface {
* Will trigger after the export file is created.
*/
public function afterExportCreated();
public function hasPermission($permission, $content_id = NULL);
}
/**
@ -1669,6 +1671,20 @@ Class H5PExport {
}
}
abstract class H5PPermission {
const DOWNLOAD_H5P = 0;
const EMBED_H5P = 1;
}
abstract class H5PDisplayOptionBehaviour {
const NEVER_SHOW = 0;
const CONTROLLED_BY_AUTHOR_DEFAULT_ON = 1;
const CONTROLLED_BY_AUTHOR_DEFAULT_OFF = 2;
const ALWAYS_SHOW = 3;
const CONTROLLED_BY_PERMISSIONS = 4;
}
/**
* Functions and storage shared by the other H5P classes
*/
@ -1690,7 +1706,8 @@ class H5PCore {
'js/h5p-x-api-event.js',
'js/h5p-x-api.js',
'js/h5p-content-type.js',
'js/h5p-confirmation-dialog.js'
'js/h5p-confirmation-dialog.js',
'js/h5p-action-bar.js'
);
public static $adminScripts = array(
'js/jquery.js',
@ -2439,34 +2456,6 @@ class H5PCore {
}
}
/**
*
*/
public function getGlobalDisable() {
$disable = self::DISABLE_NONE;
// Allow global settings to override and disable options
if (!$this->h5pF->getOption('frame', TRUE)) {
$disable |= self::DISABLE_FRAME;
}
else {
if (!$this->h5pF->getOption('export', TRUE)) {
$disable |= self::DISABLE_DOWNLOAD;
}
if (!$this->h5pF->getOption('embed', TRUE)) {
$disable |= self::DISABLE_EMBED;
}
if (!$this->h5pF->getOption('copyright', TRUE)) {
$disable |= self::DISABLE_COPYRIGHT;
}
if (!$this->h5pF->getOption('icon', TRUE)) {
$disable |= self::DISABLE_ABOUT;
}
}
return $disable;
}
/**
* Determine disable state from sources.
*
@ -2474,7 +2463,7 @@ class H5PCore {
* @param int $current
* @return int
*/
public function getDisable(&$sources, $current) {
public function getDisplayOptionsAsByte(&$sources, $current) {
foreach (H5PCore::$disable as $bit => $option) {
if ($this->h5pF->getOption(($bit & H5PCore::DISABLE_DOWNLOAD ? 'export' : $option), TRUE)) {
if (!isset($sources[$option]) || !$sources[$option]) {
@ -2488,6 +2477,98 @@ class H5PCore {
return $current;
}
/**
* Determine display options visibility and value on edit
*
* @method getDisplayOptionsForEdit
* @param [int] $disable
* @return [Array]
*/
public function getDisplayOptionsForEdit($disable = NULL) {
$display_options = [];
$current_display_options = $disable === NULL ? [] : $this->getDisplayOptionsAsArray($disable);
if ($this->h5pF->getOption('frame', TRUE)) {
$display_options['frame'] = isset($current_display_options['showFrame']) ? $current_display_options['showFrame'] : TRUE;
$export = $this->h5pF->getOption('export', H5PDisplayOptionBehaviour::ALWAYS_SHOW);
if ($export == H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_ON || $export == H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF) {
$display_options['download'] = isset($current_display_options['showDownload']) ? $current_display_options['showDownload'] : ($export == H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_ON);
}
$embed = $this->h5pF->getOption('embed', H5PDisplayOptionBehaviour::ALWAYS_SHOW);
if ($embed == H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_ON || $embed == H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF) {
$display_options['embed'] = isset($current_display_options['showEmbed']) ? $current_display_options['showEmbed'] : ($embed == H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_ON);
}
if ($this->h5pF->getOption('copyright', TRUE)) {
$display_options['copyright'] = isset($current_display_options['showCopyright']) ? $current_display_options['showCopyright'] : TRUE;
}
}
return $display_options;
}
/**
* Determine display option visibility when viewing H5P
*
* @method getDisplayOptionsForView
* @param [int] $display_options
* @param [int] $id Might be content id or user id.
* Depends on what the platform needs to be able to determine permissions.
* @return [Array]
*/
public function getDisplayOptionsForView($disable, $id) {
$display_options = $this->getDisplayOptionsAsArray($disable);
if ($this->h5pF->getOption('frame', TRUE) == FALSE) {
$display_options['showFrame'] = false;
}
else {
$export = $this->h5pF->getOption('export', H5PDisplayOptionBehaviour::ALWAYS_SHOW);
if ($export == H5PDisplayOptionBehaviour::NEVER_SHOW) {
// If never show globally, force hide
$display_options['showDownload'] = false;
}
elseif ($export == H5PDisplayOptionBehaviour::ALWAYS_SHOW || ($export == H5PDisplayOptionBehaviour::CONTROLLED_BY_PERMISSIONS && $this->h5pF->hasPermission(H5PPermission::DOWNLOAD_H5P, $id))) {
// If always show or permissions say so, force show
$display_options['showDownload'] = true;
}
$embed = $this->h5pF->getOption('embed', H5PDisplayOptionBehaviour::ALWAYS_SHOW);
if ($embed == H5PDisplayOptionBehaviour::NEVER_SHOW) {
// If never show globally, force hide
$display_options['showEmbed'] = false;
}
elseif ($embed == H5PDisplayOptionBehaviour::ALWAYS_SHOW || ($embed == H5PDisplayOptionBehaviour::CONTROLLED_BY_PERMISSIONS && $this->h5pF->hasPermission(H5PPermission::EMBED_H5P, $id))) {
// If always show or permissions say so, force show
$display_options['showEmbed'] = true;
}
if ($this->h5pF->getOption('copyright', TRUE) == FALSE) {
$display_options['showCopyright'] = false;
}
}
return $display_options;
}
/**
* Convert display options as single byte to array
*
* @method getDisplayOptionsAsArray
* @param [int] $disable
* @return [Array]
*/
private function getDisplayOptionsAsArray($disable) {
return array(
'showFrame' => !($disable & H5PCore::DISABLE_FRAME),
'showDownload' => !($disable & H5PCore::DISABLE_DOWNLOAD),
'showEmbed' => !($disable & H5PCore::DISABLE_EMBED),
'showCopyright' => !($disable & H5PCore::DISABLE_COPYRIGHT),
'showAbout' => $this->h5pF->getOption('icon', TRUE),
);
}
/**
* Small helper for getting the library's ID.
*
@ -3147,7 +3228,6 @@ class H5PContentValidator {
break;
}
}
// Using a library in content that is not present at all in semantics
if ($message === NULL) {
$message = $this->h5pF->t('The H5P library %library used in the content is not valid', array(

View File

@ -1,19 +0,0 @@
(function ($) {
$(document).ready(function () {
var $inputs = $('.h5p-action-bar-settings input');
var $frame = $inputs.filter('input[name="frame"], input[name="h5p_frame"]');
var $others = $inputs.filter(':not(input[name="frame"], input[name="h5p_frame"])');
var toggle = function () {
if ($frame.is(':checked')) {
$others.attr('disabled', false);
}
else {
$others.attr('disabled', true);
}
};
$frame.change(toggle);
toggle();
});
})(H5P.jQuery);

77
js/h5p-action-bar.js Normal file
View File

@ -0,0 +1,77 @@
H5P.ActionBar = (function ($, EventDispatcher) {
"use strict";
function ActionBar(displayOptions) {
EventDispatcher.call(this);
var self = this;
var hasActions = false;
// Create action bar
var $actions = H5P.jQuery('<ul class="h5p-actions"></ul>');
/**
* Helper for creating action bar buttons.
*
* @private
* @param {string} type
* @param {string} customClass Instead of type class
*/
var addActionButton = function (type, customClass) {
var handler = function () {
self.trigger(type);
};
H5P.jQuery('<li/>', {
'class': 'h5p-button h5p-' + (customClass ? customClass : type),
role: 'button',
tabindex: 0,
title: H5P.t(type + 'Description'),
html: H5P.t(type),
on: {
click: handler,
keypress: function (e) {
if (e.which === 32) {
handler();
e.preventDefault(); // (since return false will block other inputs)
}
}
},
appendTo: $actions
});
hasActions = true;
};
// Register action bar buttons
if (displayOptions.showDownload) {
// Add export button
addActionButton('download', 'export');
}
if (displayOptions.showCopyrights) {
addActionButton('copyrights');
}
if (displayOptions.showEmbed) {
addActionButton('embed');
}
if (displayOptions.showAbout) {
// Add about H5P button icon
H5P.jQuery('<li><a class="h5p-link" href="http://h5p.org" target="_blank" title="' + H5P.t('h5pDescription') + '"></a></li>').appendTo($actions);
hasActions = true;
}
self.getDOMElement = function () {
return $actions;
};
self.hasActions = function () {
return hasActions;
}
};
ActionBar.prototype = Object.create(EventDispatcher.prototype);
ActionBar.prototype.constructor = ActionBar;
return ActionBar;
})(H5P.jQuery, H5P.EventDispatcher);

23
js/h5p-display-options.js Normal file
View File

@ -0,0 +1,23 @@
/**
* Utility that makes it possible to hide fields when a checkbox is unchecked
*/
(function ($) {
function setupHiding () {
var $toggler = $(this);
// Getting the field which should be hidden:
var $subject = $($toggler.data('h5p-visibility-subject-selector'));
var toggle = function () {
$subject.toggle($toggler.is(':checked'));
};
$toggler.change(toggle);
toggle();
}
$(document).ready(function () {
// Get the checkboxes making other fields being hidden:
$('.h5p-visibility-toggler').each(setupHiding);
});
})(H5P.jQuery);

View File

@ -47,24 +47,6 @@ else if (document.documentElement.msRequestFullscreen) {
H5P.fullScreenBrowserPrefix = 'ms';
}
/** @const {number} */
H5P.DISABLE_NONE = 0;
/** @const {number} */
H5P.DISABLE_FRAME = 1;
/** @const {number} */
H5P.DISABLE_DOWNLOAD = 2;
/** @const {number} */
H5P.DISABLE_EMBED = 4;
/** @const {number} */
H5P.DISABLE_COPYRIGHT = 8;
/** @const {number} */
H5P.DISABLE_ABOUT = 16;
/**
* Keep track of when the H5Ps where started.
*
@ -147,76 +129,41 @@ H5P.init = function (target) {
});
}
// Create action bar
var $actions = H5P.jQuery('<ul class="h5p-actions"></ul>');
/**
* Helper for creating action bar buttons.
*
* @private
* @param {string} type
* @param {function} handler
* @param {string} customClass Instead of type class
* Create action bar
*/
var addActionButton = function (type, handler, customClass) {
H5P.jQuery('<li/>', {
'class': 'h5p-button h5p-' + (customClass ? customClass : type),
role: 'button',
tabindex: 0,
title: H5P.t(type + 'Description'),
html: H5P.t(type),
on: {
click: handler,
keypress: function (e) {
if (e.which === 32) {
handler();
e.preventDefault(); // (since return false will block other inputs)
var displayOptions = contentData.displayOptions;
if (displayOptions.showFrame) {
// Special handling of copyrights
if (displayOptions.showCopyrights) {
var copyrights = H5P.getCopyrights(instance, library.params, contentId);
if (!copyrights) {
displayOptions.showCopyrights = false;
}
}
},
appendTo: $actions
});
};
// Register action bar buttons
if (!(contentData.disable & H5P.DISABLE_DOWNLOAD)) {
// Add export button
addActionButton('download', function () {
// Use button for download to avoid people linking directly to the .h5p
// Create action bar
var actionBar = new H5P.ActionBar(displayOptions);
var $actions = actionBar.getDOMElement();
actionBar.on('download', function () {
window.location.href = contentData.exportUrl;
}, 'export');
}
if (!(contentData.disable & H5P.DISABLE_COPYRIGHT)) {
var copyright = H5P.getCopyrights(instance, library.params, contentId);
if (copyright) {
// Add copyright dialog button
addActionButton('copyrights', function () {
// Open dialog with copyright information
var dialog = new H5P.Dialog('copyrights', H5P.t('copyrightInformation'), copyright, $container);
});
actionBar.on('copyrights', function () {
var dialog = new H5P.Dialog('copyrights', H5P.t('copyrightInformation'), copyrights, $container);
dialog.open();
});
}
}
if (!(contentData.disable & H5P.DISABLE_EMBED)) {
// Add embed button
addActionButton('embed', function () {
// Open dialog with embed information
actionBar.on('embed', function () {
H5P.openEmbedDialog($actions, contentData.embedCode, contentData.resizeCode, {
width: $element.width(),
height: $element.height()
});
});
}
if (!(contentData.disable & H5P.DISABLE_ABOUT)) {
// Add about H5P button icon
H5P.jQuery('<li><a class="h5p-link" href="http://h5p.org" target="_blank" title="' + H5P.t('h5pDescription') + '"></a></li>').appendTo($actions);
}
// Insert action bar if it has any content
if (!(contentData.disable & H5P.DISABLE_FRAME) && $actions.children().length) {
$actions.insertAfter($container);
}
if (displayOptions.showFrame && actionBar.hasActions()) {
$element.addClass('h5p-frame');
}
else {