Sindbad~EG File Manager
/*global H5P*/
H5P.DragNBarDialog = (function ($, EventDispatcher) {
/**
* Controls the dialog in the interactive video.
*
* @class
* @param {H5P.jQuery} $container for dialog
* @param {H5P.jQuery} $videoWrapper needed for positioning of dialog
*/
function Dialog($container, $videoWrapper) {
var KEY_CODE_ESC = 27;
var KEY_CODE_ENTER = 13;
var KEY_CODE_SPACE = 32;
var self = this;
var titleId = 'dialog-title-' + H5P.createUUID();
// Initialize event inheritance
EventDispatcher.call(self);
/**
* Stops propagating an event
*
* @param {Event} event
*/
var stopEventPropagation = function (event) {
// k is used to stop and start an interactive video
if (event.which === 75) {
event.stopPropagation();
}
};
// Create DOM elements for dialog
var $wrapper = $('<div/>', {
'class': 'h5p-dialog-wrapper h5p-ie-transparent-background h5p-hidden',
on: {
click: function () {
if (!self.disableOverlay) {
self.close();
}
},
keyup: stopEventPropagation,
keydown: stopEventPropagation
}
});
var $dialog = $('<div/>', {
'class': 'h5p-dialog h5p-big',
'aria-labelledby': titleId,
on: {
click: function (event) {
event.stopPropagation();
},
keydown: function (event) {
var isClosable = $close.is(':visible');
if (event.which === KEY_CODE_ESC && isClosable) {
self.close();
}
}
}
}).appendTo($wrapper);
// Create title bar
var $titleBar = $('<div/>', {
'class': 'h5p-dialog-titlebar',
appendTo: $dialog
});
var $title = $('<div/>', {
'class': 'h5p-dialog-title',
id: titleId,
appendTo: $titleBar
});
var $close = $('<div/>', {
'role': 'button',
'class': 'h5p-dialog-close',
tabindex: '0',
title: H5P.t('close'),
on: {
click: function (event) {
if (event.which === 1) {
self.close();
}
},
keypress: function (event) {
if (event.which === KEY_CODE_SPACE || event.which === KEY_CODE_ENTER) {
self.close();
event.preventDefault();
}
}
},
appendTo: $titleBar
});
// Used instead of close
var $customButtons;
// Create inner DOM elements for dialog
var $inner = $('<div/>', {
'class': 'h5p-dialog-inner'
}).appendTo($dialog);
// Add all to DOM
$wrapper.appendTo($container);
/**
* Reset the dialog's positioning
*
* @private
*/
var resetPosition = function () {
// Reset positioning
$dialog.css({
left: '',
top: '',
height: '',
width: '',
fontSize: '',
bottom: ''
});
$inner.css({
width: '',
height: '',
overflow: ''
});
};
/**
* Display overlay.
*
* @private
* @param {function} next callback
*/
var showOverlay = function (next) {
$wrapper.show();
setTimeout(function () {
// Remove class on next tick to ensure css animation
$wrapper.removeClass('h5p-hidden');
if (next) {
next();
}
}, 0);
};
/**
* Close overlay.
*
* @private
* @param {function} next callback
*/
var hideOverlay = function (next) {
$wrapper.addClass('h5p-hidden');
setTimeout(function () {
// Hide when animation is done
$wrapper.hide();
if (next) {
next();
}
}, 200);
};
/**
* Opens a new dialog. Displays the given element.
*
* @param {H5P.jQuery} $element
* @param {string} [title] Label for the dialog
* @param {string} [classes] For styling
* @param {H5P.jQuery} [$buttons] Use custom buttons for dialog
*/
self.open = function ($element, title, classes, $buttons) {
showOverlay();
$inner.children().detach().end().append($element);
// Reset positioning
resetPosition();
$dialog.addClass('h5p-big');
$title.attr('class', 'h5p-dialog-title' + (classes ? ' ' + classes : ''));
// Add label
if (!title) {
title = '';
}
$title.html(title);
// Clean up after previous custom buttons
if ($customButtons) {
$customButtons.remove();
$close.show();
}
// Add new custom buttons
if ($buttons) {
$customButtons = $buttons;
// Hide default close button
$close.hide();
// Add custom buttons
$buttons.appendTo($titleBar);
}
self.resize();
self.trigger('open');
$dialog.one('transitionend', function() {
// Find visible enabled inputs:
var $inputs = $inner.find('input:visible:not(:disabled)');
var $tabbables = $inner.find('[tabindex]');
// Prioritize the focusing of inputs before other elements
if ($inputs.length) {
$inputs.get(0).focus();
}
// If other tabbables exist like h5p-text, focus on them
else if ($tabbables.length) {
$tabbables.get(0).focus();
}
});
};
self.resize = function () {
if (!$dialog.hasClass('h5p-big')) {
return;
}
var fontSize = toNum($inner.css('fontSize'));
var titleBarHeight = ($titleBar.outerHeight() / fontSize);
// Same as height
var maxHeight = $container.height();
// minus dialog margins
maxHeight -= Number($dialog.css('top').replace('px', '')) * 2;
$inner.css({
width: '100%',
maxHeight: ((maxHeight / fontSize) - titleBarHeight) + 'em',
marginTop: titleBarHeight + 'em'
});
$dialog.css({
bottom: 'auto',
maxHeight: ''
});
};
/**
* Adds a name to the dialog for identifying what it contains.
*
* @param {string} machineName Name of library inside dialog.
*/
self.addLibraryClass = function (machineName) {
$dialog.attr('data-lib', machineName);
};
/**
* Toggle class on the dialog Dom element
* @method toggleClass
* @param {String} cls Classname
* @param {Boolean} toggle
*/
self.toggleClass = function (cls, toggle) {
$dialog.toggleClass(cls, toggle);
};
self.isOpen = function () {
return $wrapper.is(':visible');
};
/**
* Reposition the currently open dialog relative to the given button.
*
* @param {H5P.jQuery} $button
* @param {Object} [size] Sets a size for the dialog, useful for images.
* @param {string|boolean} [type] Type of dialog. Possible values are
* 'medium' and 'big'. It also supports an older version of the function,
* i.e: type = true means 'medium'
*/
self.position = function ($button, size, type) {
// Still support old version of this function
if (type === true) {
type = 'medium';
}
resetPosition();
$dialog.removeClass('h5p-big h5p-medium');
var titleBarHeight = Number($inner[0].style.marginTop.replace('em', ''));
// Use a fixed size
if (size) {
var fontSizeRatio = 16 / toNum($container.css('fontSize'));
// Fixed width
if (size.width) {
size.width = (size.width * fontSizeRatio);
$dialog.css('width', size.width + 'em');
}
// Fixed height
if (size.height) {
size.height = (size.height * fontSizeRatio) + titleBarHeight;
$dialog.css('height', size.height + 'em');
$inner.css({
width: 'auto',
overflow: 'hidden'
});
}
}
if (type === 'medium') {
$dialog.addClass('h5p-medium');
}
if (type === 'big') {
$dialog.addClass('h5p-big');
$dialog.addClass('h5p-stretch');
}
var buttonWidth = $button.outerWidth(true);
var buttonPosition = $button.position();
var containerWidth = $container.width();
var containerHeight = $container.height();
// Position dialog horizontally
var left = buttonPosition.left;
var dialogWidth = $dialog.outerWidth(true);
if (type === 'medium' && dialogWidth > containerWidth) {
// If dialog is too big to fit within the container, display as h5p-big instead.
// Only medium dialogs can become big
$dialog.addClass('h5p-big');
return;
}
if (buttonPosition.left > (containerWidth / 2) - (buttonWidth / 2)) {
// Show on left
left -= dialogWidth - buttonWidth;
}
// Make sure the dialog is within the video on the right.
if ((left + dialogWidth) > containerWidth) {
left = containerWidth - dialogWidth;
}
var marginLeft = parseInt($videoWrapper.css('marginLeft'));
if (isNaN(marginLeft)) {
marginLeft = 0;
}
// And finally, make sure we're within bounds on the left hand side too...
if (left < marginLeft) {
left = marginLeft;
}
// Position dialog vertically
var marginTop = parseInt($videoWrapper.css('marginTop'));
if (isNaN(marginTop)) {
marginTop = 0;
}
// Set dialog size for dialogs which aren't stretched
if (type !== 'big') {
var top = (type === 'medium' ? 0 : (buttonPosition.top + marginTop));
var totalHeight = top + $dialog.outerHeight(true);
if (totalHeight > containerHeight) {
top -= totalHeight - containerHeight;
}
var maxHeight = $container.height() - top + $dialog.height() - $dialog.outerHeight(true);
var fontSize = toNum($container.css('fontSize'));
$dialog.css({
top: (top / (containerHeight / 100)) + '%',
left: (left / (containerWidth / 100)) + '%',
width: (window.getComputedStyle($dialog[0]).width / fontSize) + 'em',
maxHeight: (maxHeight / fontSize) + 'em'
});
$inner.css('maxHeight', ((maxHeight - $titleBar.outerHeight(true)) / fontSize) + 'em');
}
};
/**
* Find max available space inside dialog when positioning relative to
* given button.
*
* @param {H5P.jQuery} $button
* @param {Boolean} fullScreen True if dialog fills whole parent
* @returns {Object} Attrs: width, height
*/
self.getMaxSize = function ($button, fullScreen) {
var buttonWidth = $button.outerWidth(true);
var buttonPosition = $button.position();
var containerWidth = $container.width();
var max = {};
max.height = Number($inner.css('maxHeight').replace('px', ''));
// If border, extract that:
max.height -= Number($inner.css('border-width').replace('px', '')) * 2;
if (fullScreen) {
max.width = containerWidth;
}
else {
if (buttonPosition.left > (containerWidth / 2) - (buttonWidth / 2)) {
// Space to the left of the button minus margin
max.width = buttonPosition.left;
}
else {
// Space to the right of the button minus margin
max.width = (containerWidth - buttonPosition.left - buttonWidth);
}
}
// Use em
var fontSize = toNum($container.css('fontSize'));
max.width = (max.width / fontSize) * (fontSize / 16);
max.height = (max.height / fontSize) * (fontSize / 16);
return max;
};
/**
* Scroll to given position in current dialog.
*
* @param {number} to Scroll position
* @param {number} ms Time the animation takes.
*/
self.scroll = function (to, ms) {
$inner.stop().animate({
scrollTop: to
}, ms);
};
/**
* Close the currently open dialog.
*/
self.close = function (closeInstant) {
$wrapper.addClass('h5p-hidden');
if (closeInstant) {
$wrapper.hide();
self.disableOverlay = false;
$close.show();
}
else {
setTimeout(function () {
$wrapper.hide();
self.disableOverlay = false;
$close.show();
}, 201);
}
self.trigger('close');
// Let others reach to the hiding of this dialog
self.trigger('domHidden', {
'$dom': $wrapper,
'key': 'dialogClosed'
}, {'bubbles': true, 'external': true});
};
/**
* Open overlay only.
*/
self.openOverlay = function () {
self.disableOverlay = true;
$dialog.hide();
showOverlay();
};
/**
* Close overlay only.
*/
self.closeOverlay = function () {
$wrapper.addClass('h5p-hidden');
hideOverlay(function () {
$dialog.show();
self.disableOverlay = false;
});
};
/**
* Removes the close button from the current dialog.
*/
self.hideCloseButton = function () {
$close.hide();
};
/**
* Get width of dialog
* @returns {Number} Width of dialog
*/
self.getDialogWidth = function () {
return $dialog.width();
};
/**
* Reset dialog width
*/
self.removeStaticWidth = function () {
$dialog.css('width', '');
};
}
// Extends the event dispatcher
Dialog.prototype = Object.create(EventDispatcher.prototype);
Dialog.prototype.constructor = Dialog;
/**
* Converts css px value to number.
*
* @private
* @param {string} num
* @returns {Number}
*/
var toNum = function (num) {
return Number(num.replace('px',''));
};
return Dialog;
})(H5P.jQuery, H5P.EventDispatcher);
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists