Linux moodl-moodle-3s8bw1nuh5yqd9-5b875fdd66-8hs4m 4.4.0-186-generic #216-Ubuntu SMP Wed Jul 1 05:34:05 UTC 2020 x86_64
Apache/2.4.41 (Ubuntu)
: 10.39.0.36 | : 10.36.0.0
Cant Read [ /etc/named.conf ]
7.4.3
www-data
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
README
+ Create Folder
+ Create File
/
var /
moodledata /
filedir /
fa /
96 /
[ HOME SHELL ]
Name
Size
Permission
Action
fa96c2a080714ab2cef0dbc29dd319...
33.78
KB
-rw-rw-rw-
Delete
Unzip
Zip
${this.title}
Close
Code Editor : fa96c2a080714ab2cef0dbc29dd3191df2c83185
H5P.DragNBar = (function (EventDispatcher) { var nextInstanceIndex = 0; /** * Constructor. Initializes the drag and drop menu bar. * * @class * @param {Array} buttons * @param {H5P.jQuery} $container * @param {H5P.jQuery} $dialogContainer * @param {object} [options] Collection of options * @param {boolean} [options.disableEditor=false] Determines if DragNBar should be displayed in view or editor mode * @param {boolean} [options.enableCopyPaste=true] Determines if copy & paste is supported * @param {H5P.jQuery} [options.$blurHandlers] When clicking these element(s) dnb focus will be lost * @param {object} [options.libraries] Libraries to check against for paste notification */ function DragNBar(buttons, $container, $dialogContainer, options) { var self = this; EventDispatcher.call(this); this.overflowThreshold = 13; // How many buttons to display before we add the more button. this.buttons = buttons; this.$container = $container; this.$dialogContainer = $dialogContainer; this.dnd = new H5P.DragNDrop(this, $container); this.dnd.snap = 10; this.newElement = false; var defaultOptions = { disableEditor: false, enableCopyPaste: true }; options = H5P.jQuery.extend(defaultOptions, options); this.enableCopyPaste = options.enableCopyPaste; this.isEditor = !options.disableEditor; this.$blurHandlers = options.$blurHandlers ? options.$blurHandlers : undefined; this.libraries = options.libraries; this.instanceIndex = nextInstanceIndex++; /** * Keeps track of created DragNBar elements * @type {Array} */ this.elements = []; // Create a popup dialog this.dialog = new H5P.DragNBarDialog($dialogContainer, $container); // Fix for forcing redraw on $container, to avoid "artifcats" on safari this.$container.addClass('hardware-accelerated'); if (this.isEditor) { this.transformButtonActive = false; this.initEditor(); this.initClickListeners(); H5P.$window.resize(function () { self.resize(); }); } /** * Add button group. * * @private * @param {object[]} Buttons. * @param {H5P.jQuery} $button Button to add button group to. * @param {object} [options] Options. * @param {string} [options.title] Title for the group. */ this.addButtonGroup = function (buttons, $button, options) { const $buttonGroup = H5P.jQuery('<li class="h5p-dragnbar-li h5p-dragnbar-button-group" data-label="Image"></li>'); // Add optional title to the group if (options && options.title && options.title !=='') { H5P.jQuery('<div class="h5p-dragnbar-button-title">' + options.title + '</div>') .appendTo($buttonGroup); } // Container for buttons const $buttonGroupButtons = H5P.jQuery('<ul class="h5p-dragnbar-button-buttons h5p-dragnbar-ul"></ul>') .appendTo($buttonGroup); // Add buttons buttons.forEach(function (button) { self.addButton(button, $buttonGroupButtons); }); $buttonGroup.insertAfter($button.parent()); return $buttonGroup; }; } // Inherit support for events DragNBar.prototype = Object.create(EventDispatcher.prototype); DragNBar.prototype.constructor = DragNBar; return DragNBar; })(H5P.EventDispatcher); /** * Initializes editor functionality of DragNBar */ H5P.DragNBar.prototype.initEditor = function () { var that = this; this.dnr = new H5P.DragNResize(this.$container); this.dnr.snap = 10; // Update coordinates when element is resized this.dnr.on('moveResizing', function () { var offset = that.$element.offset(); var position = that.$element.position(); that.updateCoordinates(offset.left, offset.top, position.left, position.top); }); // Set pressed to not lose focus at the end of resize this.dnr.on('stoppedResizing', function () { that.pressed = true; // Delete pressed after dnbelement has been refocused so it will lose focus on single click. setTimeout(function () { delete that.pressed; }, 10); }); /** * Show transform panel listeners */ this.dnr.on('showTransformPanel', function () { TransformPanel(true); }); this.dnd.on('showTransformPanel', function () { TransformPanel(true); }); /** * Hide transform panel listeners */ this.dnr.on('hideTransformPanel', function () { if (!that.transformButtonActive) { TransformPanel(false); } }); this.dnd.on('hideTransformPanel', function () { if (!that.transformButtonActive) { TransformPanel(false); } }); /** * Trigger a context menu transform to either show or hide * the transform panel. * * @param {boolean} show */ function TransformPanel(show) { if (that.focusedElement) { that.focusedElement.contextMenu.trigger('contextMenuTransform', {showTransformPanel: show}); } } this.dnd.startMovingCallback = function () { that.dnd.min = {x: 0, y: 0}; that.dnd.max = { x: that.$container.width() - that.$element.outerWidth(), y: that.$container.height() - that.$element.outerHeight() }; if (that.newElement) { that.dnd.adjust.x = 10; that.dnd.adjust.y = 10; that.dnd.min.y -= that.$list.height(); } return true; }; this.dnd.stopMovingCallback = function () { var pos = {}; if (that.newElement) { that.$container.css('overflow', ''); if (Math.round(parseFloat(that.$element.css('top'))) < 0) { // Try to center element, but avoid overlapping pos.x = (that.dnd.max.x / 2); pos.y = (that.dnd.max.y / 2); that.avoidOverlapping(pos, that.$element); } } if (pos.x === undefined || pos.y === undefined ) { pos.x = Math.round(parseFloat(that.$element.css('left'))); pos.y = Math.round(parseFloat(that.$element.css('top'))); } that.stopMoving(pos.x, pos.y); that.newElement = false; delete that.dnd.min; delete that.dnd.max; }; }; /** * Tries to position the given element close to the requested coordinates. * Element can be skipped to check if spot is available. * * @param {object} pos * @param {number} pos.x * @param {number} pos.y * @param {(H5P.jQuery|Object)} element object with width&height if ran before insertion. */ H5P.DragNBar.prototype.avoidOverlapping = function (pos, $element) { // Determine size of element var size = $element; if (size instanceof H5P.jQuery) { size = window.getComputedStyle(size[0]); size = { width: parseFloat(size.width), height: parseFloat(size.height) }; } else { $element = undefined; } // Determine how much they can be manuvered var containerStyle = window.getComputedStyle(this.$container[0]); var manX = parseFloat(containerStyle.width) - size.width; var manY = parseFloat(containerStyle.height) - size.height; var limit = 16; var attempts = 0; while (attempts < limit && this.elementOverlaps(pos.x, pos.y, $element)) { // Try to place randomly inside container if (manX > 0) { pos.x = Math.floor(Math.random() * manX); } if (manY > 0) { pos.y = Math.floor(Math.random() * manY); } attempts++; } }; /** * Determine if moving the given element to its new position will cause it to * cover another element. This can make new or pasted elements difficult to see. * Element can be skipped to check if spot is available. * * @param {number} x * @param {number} y * @param {H5P.jQuery} [$element] * @returns {boolean} */ H5P.DragNBar.prototype.elementOverlaps = function (x, y, $element) { var self = this; // Use snap grid x = Math.round(x / 10); y = Math.round(y / 10); for (var i = 0; i < self.elements.length; i++) { var element = self.elements[i]; if ($element !== undefined && element.$element === $element) { continue; } if (x === Math.round(parseFloat(element.$element.css('left')) / 10) && y === Math.round(parseFloat(element.$element.css('top')) / 10)) { return true; // Stop loop } } return false; }; // Key coordinates var SHIFT = 16; var CTRL = 17; var DELETE = 46; var BACKSPACE = 8; var C = 67; var V = 86; var LEFT = 37; var UP = 38; var RIGHT = 39; var DOWN = 40; // Keep track of key state var ctrlDown = false; // How many pixels to move var snapAmount = 1; /** * Handle keydown events for the entire frame */ H5P.DragNBar.keydownHandler = function (event) { var self = event.data.instance; var activeElement = document.activeElement; // Don't care about keys if parent editor is not in focus // This means all editors using drag-n-bar need to set a tabindex // (it's not done inside this library) if (self.$dialogContainer.find(activeElement).length === 0 && self.$dialogContainer.get(0) !== activeElement) { return; } if (event.which === CTRL) { ctrlDown = true; if (self.dnd.snap !== undefined) { // Disable snapping delete self.dnd.snap; } } if (event.which === SHIFT) { snapAmount = self.dnd.snap; } if (event.which === LEFT && self.focusedElement) { if (activeElement.contentEditable === 'true' || activeElement.value !== undefined) { return; } event.preventDefault(); self.moveWithKeys(-snapAmount, 0); } else if (event.which === UP && self.focusedElement) { if (activeElement.contentEditable === 'true' || activeElement.value !== undefined) { return; } event.preventDefault(); self.moveWithKeys(0, -snapAmount); } else if (event.which === RIGHT && self.focusedElement) { if (activeElement.contentEditable === 'true' || activeElement.value !== undefined) { return; } event.preventDefault(); self.moveWithKeys(snapAmount, 0); } else if (event.which === DOWN && self.focusedElement) { if (activeElement.contentEditable === 'true' || activeElement.value !== undefined) { return; } event.preventDefault(); self.moveWithKeys(0, snapAmount); } else if (event.which === C && ctrlDown && self.focusedElement && self.$container.is(':visible')) { self.copyHandler(event); } else if (event.which === V && ctrlDown && window.localStorage && self.$container.is(':visible')) { self.pasteHandler(event); } else if ((event.which === DELETE || event.which === BACKSPACE) && self.focusedElement && self.$container.is(':visible') && activeElement.tagName.toLowerCase() !== 'input') { if (self.pressed === undefined) { self.focusedElement.contextMenu.trigger('contextMenuRemove'); event.preventDefault(); // Prevent browser navigating back } } }; /** * Copy object. * @param {Event} event - Event to check for copyable content. */ H5P.DragNBar.prototype.copyHandler = function (event) { if (!this.enableCopyPaste) { return; } var self = event === undefined ? this : event.data.instance; // Copy element params to clipboard var elementSize = window.getComputedStyle(self.focusedElement.$element[0]); var width = parseFloat(elementSize.width); var height = parseFloat(elementSize.height) / width; width = width / (parseFloat(window.getComputedStyle(self.$container[0]).width) / 100); height *= width; self.focusedElement.toClipboard(width, height); H5P.externalDispatcher.trigger('datainclipboard', {reset: false}); }; /** * Paste object. * @param {Event} event - Event to check for pastable content. */ H5P.DragNBar.prototype.pasteHandler = function (event) { var self = event === undefined ? this : event.data.instance; var activeElement = document.activeElement; // Don't paste if parent editor is not in focus if (!this.enableCopyPaste || self.preventPaste || self.dialog.isOpen() || activeElement.contentEditable === 'true' || activeElement.value !== undefined) { return; } if (self.$pasteButton.hasClass('disabled')) { // Inform user why pasting is not possible const pasteCheck = H5PEditor.canPastePlus(H5P.getClipboard(), this.libraries); if (pasteCheck.canPaste !== true) { if (pasteCheck.reason === 'pasteTooOld' || pasteCheck.reason === 'pasteTooNew') { self.confirmPasteError(pasteCheck.description, 0, function () {}); } else { H5PEditor.attachToastTo( self.$pasteButton.get(0), pasteCheck.description, {position: {horizontal: 'center', vertical: 'above', noOverflowX: true}} ); } return; } } var clipboardData = localStorage.getItem('h5pClipboard'); if (clipboardData) { // Parse try { clipboardData = JSON.parse(clipboardData); } catch (err) { console.error('Unable to parse JSON from clipboard.', err); return; } // Update file URLs H5P.DragNBar.updateFileUrls(clipboardData.specific, function (path) { var isTmpFile = (path.substr(-4,4) === '#tmp'); if (!isTmpFile && clipboardData.contentId) { // Comes from existing content let prefix; if (H5PEditor.contentId) { // .. to existing content prefix = '../' + clipboardData.contentId + '/'; } else { // .. to new content prefix = (H5PEditor.contentRelUrl ? H5PEditor.contentRelUrl : '../content/') + clipboardData.contentId + '/'; } return path.substr(0, prefix.length) === prefix ? path : prefix + path; } return path; // Will automatically be looked for in tmp folder }); if (clipboardData.generic) { // Use reference instead of key clipboardData.generic = clipboardData.specific[clipboardData.generic]; // Avoid multiple content with same ID delete clipboardData.generic.subContentId; } self.trigger('paste', clipboardData); } }; /** * Set state of paste button. * @param {boolean} canPaste - If true, button will be enabled */ H5P.DragNBar.prototype.setCanPaste = function (canPaste) { canPaste = canPaste || false; if (this.$pasteButton) { this.$pasteButton.toggleClass('disabled', !canPaste); } }; /** * Confirm replace if there is content selected * * @param {number} top Offset * @param {function} next Next callback */ H5P.DragNBar.prototype.confirmPasteError = function (message, top, next) { // Confirm changing library var confirmReplace = new H5P.ConfirmationDialog({ headerText: H5PEditor.t('core', 'pasteError'), dialogText: message, cancelText: ' ', confirmText: H5PEditor.t('core', 'ok') }).appendTo(document.body); confirmReplace.on('confirmed', next); confirmReplace.show(top); }; /** * Handle keypress events for the entire frame */ H5P.DragNBar.keypressHandler = function (event) { var self = event.data.instance; if (event.which === BACKSPACE && self.focusedElement && self.$container.is(':visible') && document.activeElement.tagName.toLowerCase() !== 'input') { event.preventDefault(); // Prevent browser navigating back } }; /** * Handle keyup events for the entire frame */ H5P.DragNBar.keyupHandler = function (event) { var self = event.data.instance; if (event.which === CTRL) { // Update key state ctrlDown = false; // Enable snapping self.dnd.snap = 10; } if (event.which === SHIFT) { snapAmount = 1; } if (self.focusedElement && (event.which === LEFT || event.which === UP || event.which === RIGHT || event.which === DOWN)) { // Store position of element after moving var position = self.getElementSizeNPosition(); self.stopMoving(Math.round(position.left), Math.round(position.top)); } }; /** * Handle click events for the entire frame */ H5P.DragNBar.clickHandler = function (event) { var self = event.data.instance; // Remove pressed on click delete self.pressed; }; /** * Initialize click listeners */ H5P.DragNBar.prototype.initClickListeners = function () { var self = this; var index = self.instanceIndex; // Register event listeners var eventData = { instance: self }; H5P.$body.on('keydown.dnb' + index, eventData, H5P.DragNBar.keydownHandler) .on('keypress.dnb' + index, eventData, H5P.DragNBar.keypressHandler) .on('keyup.dnb' + index, eventData, H5P.DragNBar.keyupHandler) .on('click.dnb' + index, eventData, H5P.DragNBar.clickHandler); // Set blur handler element if option has been specified var $blurHandlers = this.$container; if (this.$blurHandlers) { $blurHandlers = this.$blurHandlers; } function handleBlur() { // Remove coordinates picker if we didn't press an element. if (self.pressed !== undefined) { delete self.pressed; } else { self.blurAll(); if (self.focusedElement !== undefined) { delete self.focusedElement; } } } $blurHandlers .keydown(function (e) { if (e.which === 9) { // pressed tab handleBlur(); } }) .click(handleBlur); }; /** * Update file URLs. Useful when copying between different contents. * * @param {object} params Reference * @param {function} handler Modifies the path to work when pasted */ H5P.DragNBar.updateFileUrls = function (params, handler) { for (var prop in params) { if (params.hasOwnProperty(prop) && params[prop] instanceof Object) { var obj = params[prop]; if (obj.path !== undefined && obj.mime !== undefined) { obj.path = handler(obj.path); } else { H5P.DragNBar.updateFileUrls(obj, handler); } } } }; /** * Attaches the menu bar to the given wrapper. * * @param {jQuery} $wrapper * @returns {undefined} */ H5P.DragNBar.prototype.attach = function ($wrapper) { var self = this; $wrapper.html(''); $wrapper.addClass('h5peditor-dragnbar'); var $list = H5P.jQuery('<ul class="h5p-dragnbar-ul"></ul>').appendTo($wrapper); this.$list = $list; for (var i = 0; i < this.buttons.length; i++) { var button = this.buttons[i]; if (i === this.overflowThreshold) { const $buttonMore = H5P.jQuery('<li class="h5p-dragnbar-li"><a href="#" title="' + H5PEditor.t('H5P.DragNBar', 'moreElements') + '" class="h5p-dragnbar-a h5p-dragnbar-more-button"></a><ul class="h5p-dragnbar-li-ul"></ul></li>'); $list = $buttonMore .appendTo($list) .click(function (e) { $list.stop().slideToggle(300); e.preventDefault(); }) .children(':first') .next(); // Close "more" on click somewhere else H5P.jQuery(document).click(function (event) { if (!H5P.jQuery(event.target).is($buttonMore.find('.h5p-dragnbar-more-button')) && $list.css('display') !== 'none') { $list.stop().slideToggle(300); } }); } this.addButton(button, $list); } if (this.enableCopyPaste) { // Paste button this.$pasteButton = H5P.jQuery( '<li class="h5p-dragnbar-li paste-button disabled">' + '<a href="#" class="h5p-dragnbar-a h5p-dragnbar-paste-button" />' + '</li>' ); H5P.jQuery('<span>', { 'class': 'h5p-dragnbar-tooltip', 'text': H5PEditor.t('H5P.DragNBar', 'paste') }).appendTo(this.$pasteButton); this.$pasteButton.find('.h5p-dragnbar-paste-button').click(function (event) { event.preventDefault(); // Avoid anchor click making window scroll self.pasteHandler(); }); if (this.buttons.length > this.overflowThreshold) { this.$pasteButton.insertAfter($list.parent()); } else { this.$pasteButton.appendTo($list); } } this.containTooltips(); }; /** * Add button. * * @param {type} button * @param {Function} button.createElement Function for creating element * @param {type} $list * @returns {undefined} */ H5P.DragNBar.prototype.addButton = function (button, $list) { var that = this; const hasTitle = (button.title && button.title !== ''); const ariaLabel = hasTitle ? ' aria-label="' + button.title + '"' : ''; var $button = H5P.jQuery( '<li class="h5p-dragnbar-li" data-label="Image">' + '<a href="#" class="h5p-dragnbar-a h5p-dragnbar-' + button.id + '-button"' + ariaLabel + '></a>' + '</li>' ).appendTo($list); // Prevent empty tooltips (would show on Firefox) if (hasTitle) { H5P.jQuery('<span/>', { 'class': 'h5p-dragnbar-tooltip', 'text': button.title }).appendTo($button); } let $buttonGroup; if (button.type === 'group') { // Create dropdown button group $buttonGroup = this.addButtonGroup(button.buttons, $button, {title: button.titleGroup}); $buttonGroup.addClass('h5peditor-dragnbar-gone'); // Close group on click somewhere else H5P.jQuery(document).click(function (event) { const hitButton = H5P.jQuery(event.target).is($button); // Closing handled by button itself const hitButtonGroup = H5P.jQuery(event.target).closest('.h5p-dragnbar-button-group').length === 1; if (!hitButton && !hitButtonGroup) { $buttonGroup.toggleClass('h5peditor-dragnbar-gone', true); $button.find('.h5p-dragnbar-tooltip').toggleClass('h5peditor-dragnbar-gone', false); } }); } $button .hover(function () { that.containTooltips(); }) .children() .click(function () { return false; }).mousedown(function (event) { if (event.which !== 1) { return; } // Switch between normal button and dropdown button group if (button.type === 'group') { if ($buttonGroup !== undefined) { // Set position here, because content types might add buttons out of order const offset = parseFloat($button.closest('.h5p-dragnbar').css('padding-left')); const position = $button.position().left - $buttonGroup.position().left - offset; if (position > 0) { $buttonGroup.css('left', position); } // Show dropdown and hide buttons tooltip $buttonGroup.toggleClass('h5peditor-dragnbar-gone'); $button.find('.h5p-dragnbar-tooltip').toggleClass('h5peditor-dragnbar-gone'); } } else { that.newElement = true; that.pressed = true; var createdElement = button.createElement(); that.$element = createdElement; that.$container.css('overflow', 'visible'); // y = 0 will make sure this press is regarded as outside of canvas to place element correctly that.dnd.press(that.$element, event.pageX, 0); that.focus(that.$element); } }); }; /** * Contain tooltips. * * @returns {undefined} */ H5P.DragNBar.prototype.containTooltips = function () { var that = this; var containerWidth = that.$container.outerWidth(); this.$list.find('.h5p-dragnbar-tooltip').each(function () { // Get correct offset even if element is a child var width = H5P.jQuery(this).outerWidth(); var parentWidth = H5P.jQuery(this).parents('.h5p-dragnbar-li').last().outerWidth(); // Center the tooltip H5P.jQuery(this).css('left', -(width / 2) + (parentWidth / 2) + 'px'); var offsetLeft = H5P.jQuery(this).position().left += H5P.jQuery(this).parents('.h5p-dragnbar-li').last().position().left; // If outside left edge if (offsetLeft <= 0) { H5P.jQuery(this).css('left', 0); } // If outside right edge if (offsetLeft + width > containerWidth) { H5P.jQuery(this).css('left', -(width - parentWidth)); } }); }; /** * Change container. * * @param {jQuery} $container * @returns {undefined} */ H5P.DragNBar.prototype.setContainer = function ($container) { this.$container = $container; if (this.dnd) { this.dnd.$container = $container; } if (this.dnr) { this.dnr.$container = $container; } }; /** * Handler for when the dragging stops. Makes sure the element is inside its container. * * @param {Number} left * @param {Number} top * @returns {undefined} */ H5P.DragNBar.prototype.stopMoving = function (left, top) { // Calculate percentage top = top / (this.$container.height() / 100); left = left / (this.$container.width() / 100); this.$element.css({top: top + '%', left: left + '%'}); // Give others the result if (this.stopMovingCallback !== undefined) { this.stopMovingCallback(left, top); } }; /** * @typedef SizeNPosition * @type Object * @property {number} width Outer width of the element * @property {number} height Outer height of the element * @property {number} left The X Coordinate * @property {number} top The Y Coordinate * @property {number} containerWidth Inner width of the container * @property {number} containerHeight Inner height of the container */ /** * * Only works when element is inside this.$container. This is assumed and no * are done. * * @param {H5P.jQuery} [$element] Defaults to focused element. * @throws 'No element given' if $element is missing * @return {SizeNPosition} */ H5P.DragNBar.prototype.getElementSizeNPosition = function ($element) { $element = $element || this.focusedElement.$element; if (!$element || !$element.length) { throw 'No element given'; } // Always use outer size for element var size = $element[0].getBoundingClientRect(); // Always use position relative to container for element var position = window.getComputedStyle($element[0]); // We include container inner size as well var containerSize = window.getComputedStyle(this.$container[0]); // Start preparing return value var sizeNPosition = { width: parseFloat(size.width), height: parseFloat(size.height), left: parseFloat(position.left), top: parseFloat(position.top), containerWidth: parseFloat(containerSize.width), containerHeight: parseFloat(containerSize.height) }; if (position.left.substr(-1, 1) === '%' || position.top.substr(-1, 1) === '%') { // Some browsers(Safari) gets percentage value instead of pixel value. // Container inner size must be used to calculate such values. sizeNPosition.left *= (sizeNPosition.containerWidth / 100); sizeNPosition.top *= (sizeNPosition.containerHeight / 100); } return sizeNPosition; }; /** * Makes it possible to move dnb elements by adding to it's x and y * * @param {number} x Amount to move on x-axis. * @param {number} y Amount to move on y-axis. */ H5P.DragNBar.prototype.moveWithKeys = function (x, y) { /** * Ensure that the given value is within the given boundaries. * * @private * @param {number} value * @param {number} min * @param {number} max * @return {number} */ var withinBoundaries = function (value, min, max) { if (value < min) { value = min; } if (value > max) { value = max; } return value; }; // Get size and position of current elemet in focus var sizeNPosition = this.getElementSizeNPosition(); // Change position sizeNPosition.left += x; sizeNPosition.top += y; // Check that values are within boundaries sizeNPosition.left = withinBoundaries(sizeNPosition.left, 0, sizeNPosition.containerWidth - sizeNPosition.width); sizeNPosition.top = withinBoundaries(sizeNPosition.top, 0, sizeNPosition.containerHeight - sizeNPosition.height); // Determine new position style this.$element.css({ left: sizeNPosition.left + 'px', top: sizeNPosition.top + 'px', }); this.dnd.trigger('showTransformPanel'); // Update position of context menu this.updateCoordinates(sizeNPosition.left, sizeNPosition.top, sizeNPosition.left, sizeNPosition.top); }; /** * Makes it possible to focus and move the element around. * Must be inside $container. * * @param {H5P.jQuery} $element * @param {Object} [options] * @param {H5P.DragNBarElement} [options.dnbElement] Register new element with dnbelement * @param {boolean} [options.disableResize] Resize disabled * @param {boolean} [options.lock] Lock ratio during resize * @param {string} [clipboardData] * @returns {H5P.DragNBarElement} Reference to added dnbelement */ H5P.DragNBar.prototype.add = function ($element, clipboardData, options) { var self = this; options = options || {}; if (this.isEditor && !options.disableResize) { this.dnr.add($element, options); } var newElement = null; // Check if element already exist if (options.dnbElement) { // Set element as added element options.dnbElement.setElement($element); newElement = options.dnbElement; } else { options.element = $element; options.disableCopy = !this.enableCopyPaste; newElement = new H5P.DragNBarElement(this, clipboardData, options); this.elements.push(newElement); } $element.addClass('h5p-dragnbar-element'); if (this.isEditor) { if (newElement.contextMenu) { newElement.contextMenu.on('contextMenuCopy', function () { self.copyHandler(); }); } if ($element.attr('tabindex') === undefined) { // Make it possible to tab between elements. $element.attr('tabindex', '0'); } $element.mousedown(function (event) { if (event.which !== 1) { return; } self.pressed = true; self.focus($element); if (self.dnr.active !== true) { // Moving can be stopped if the mousedown is doing something else self.dnd.press($element, event.pageX, event.pageY); } }); } $element.focus(function () { self.focus($element); }); return newElement; }; /** * Remove given element in the UI. * * @param {H5P.DragNBarElement} dnbElement */ H5P.DragNBar.prototype.removeElement = function (dnbElement) { dnbElement.removeElement(); }; /** * Select the given element in the UI. * * @param {jQuery} $element * @returns {undefined} */ H5P.DragNBar.prototype.focus = function ($element) { var self = this; // Blur last focused if (this.focusedElement && this.focusedElement.$element !== $element) { this.focusedElement.blur(); this.focusedElement.hideContextMenu(); } if (!$element.is(':visible')) { return; // Do not focus invisible items (fixes FF refocus issue) } // Keep track of the element we have in focus self.$element = $element; this.dnd.setElement($element); // Show and update coordinates picker this.focusedElement = this.getDragNBarElement($element); if (this.focusedElement) { this.focusedElement.showContextMenu(); this.focusedElement.focus(); self.updateCoordinates(); } // Wait for potential recreation of element setTimeout(function () { self.updateCoordinates(); if (self.focusedElement && self.focusedElement.contextMenu && self.focusedElement.contextMenu.canResize) { self.focusedElement.contextMenu.updateDimensions(); } }, 0); }; /** * Get dnbElement from $element * @param {jQuery} $element * @returns {H5P.DragNBarElement} dnbElement with matching $element */ H5P.DragNBar.prototype.getDragNBarElement = function ($element) { var foundElement; // Find object with matching element this.elements.forEach(function (element) { if (element.getElement().is($element)) { foundElement = element; } }); return foundElement; }; /** * Deselect all elements in the UI. * * @returns {undefined} */ H5P.DragNBar.prototype.blurAll = function () { this.elements.forEach(function (element) { element.blur(); }); delete this.focusedElement; }; /** * Resize DnB, make sure context menu is positioned correctly. */ H5P.DragNBar.prototype.resize = function () { var self = this; this.updateCoordinates(); if (self.focusedElement) { self.focusedElement.resizeContextMenu(self.$element.offset().left - self.$element.parent().offset().left); } }; /** * Update the coordinates of context menu. * * @param {Number} [left] * @param {Number} [top] * @param {Number} [x] * @param {Number} [y] * @returns {undefined} */ H5P.DragNBar.prototype.updateCoordinates = function (left, top, x, y) { if (!this.focusedElement) { return; } var containerPosition = this.$container.position(); if (left && top && x && y) { left = x + containerPosition.left; top = y + containerPosition.top; this.focusedElement.updateCoordinates(left, top, x, y); } else { var position = this.$element.position(); this.focusedElement.updateCoordinates(position.left + containerPosition.left, position.top + containerPosition.top, position.left, position.top); } }; /** * Creates element data to store in the clipboard. * * @param {string} from Source of the element * @param {object} params Element options * @param {string} [generic] Which part of the parameters can be used by other libraries * @returns {string} JSON */ H5P.DragNBar.clipboardify = function (from, params, generic) { var clipboardData = { from: from, specific: params }; if (H5PEditor.contentId) { clipboardData.contentId = H5PEditor.contentId; } // Add the generic part if (params[generic]) { clipboardData.generic = generic; } return clipboardData; }; /** * Make sure the given element is inside the container. * * @param {SizeNPosition} sizeNPosition For the element * @returns {SizeNPosition} Only the properties which require change */ H5P.DragNBar.fitElementInside = function (sizeNPosition) { var style = {}; if (sizeNPosition.left < 0) { // Element sticks out of the left side style.left = sizeNPosition.left = 0; } if (sizeNPosition.width + sizeNPosition.left > sizeNPosition.containerWidth) { // Element sticks out of the right side style.left = sizeNPosition.containerWidth - sizeNPosition.width; if (style.left < 0) { // Element is wider than the container style.left = 0; style.width = sizeNPosition.containerWidth; } } if (sizeNPosition.top < 0) { // Element sticks out of the top side style.top = sizeNPosition.top = 0; } if (sizeNPosition.height + sizeNPosition.top > sizeNPosition.containerHeight) { // Element sticks out of the bottom side style.top = sizeNPosition.containerHeight - sizeNPosition.height; if (style.top < 0) { // Element is higher than the container style.top = 0; style.height = sizeNPosition.containerHeight; } } return style; }; /** * Clean up any event listeners */ H5P.DragNBar.prototype.remove = function () { var index = this.instanceIndex; H5P.$body.off('keydown.dnb' + index, H5P.DragNBar.keydownHandler) .off('keypress.dnb' + index, H5P.DragNBar.keypressHandler) .off('keyup.dnb' + index, H5P.DragNBar.keyupHandler) .off('click.dnb' + index, H5P.DragNBar.clickHandler); };
Close