AutorÃa | Ultima modificación | Ver Log |
/* global ns */H5PEditor.ListEditor = (function ($) {/*** Draws the list.** @class* @param {List} list*/function ListEditor(list) {var self = this;var entity = list.getEntity();// Create list htmlvar $list = $('<ul/>', {id: list.getId(),'aria-describedby': list.getDescriptionId(),'class': 'h5p-ul'});// Create add buttonvar $button = ns.createButton(list.getImportance(), H5PEditor.t('core', 'addEntity', {':entity': entity}), function () {list.addItem();}, true);// Used when dragging items aroundvar adjustX, adjustY, marginTop, formOffset;/*** @private* @param {jQuery} $item* @param {jQuery} $placeholder* @param {Number} x* @param {Number} y*/var moveItem = function ($item, $placeholder, x, y) {var currentIndex;// Adjust so the mouse is placed on top of the icon.x = x - adjustX;y = y - adjustY;$item.css({top: y - marginTop - formOffset.top,left: x - formOffset.left});// Try to move up.var $prev = $item.prev().prev();if ($prev.length && y < $prev.offset().top + ($prev.height() / 2)) {$prev.insertAfter($item);currentIndex = $item.index();list.moveItem(currentIndex, currentIndex - 1);return;}// Try to move down.var $next = $item.next();if ($next.length && y + $item.height() > $next.offset().top + ($next.height() / 2)) {$next.insertBefore($placeholder);currentIndex = $item.index() - 2;list.moveItem(currentIndex, currentIndex + 1);}};/*** Default confirm handler.** @param {Object} item Content parameters* @param {number} id Index of element being removed* @param {Object} buttonOffset Delete button offset, useful for positioning dialog* @param {function} confirm Run to confirm delete*/self.defaultConfirmHandler = function (item, id, buttonOffset, confirm) {// Create default confirmation dialog for removing list itemconst confirmRemovalDialog = new H5P.ConfirmationDialog({dialogText: H5PEditor.t('core', 'confirmRemoval', {':type': entity})}).appendTo(document.body);// Remove list item on confirmationconfirmRemovalDialog.on('confirmed', confirm);confirmRemovalDialog.show(buttonOffset.top);};// Use the default confirmation handler by defaultlet confirmHandler = self.defaultConfirmHandler;/*** Set a custom confirmation handler callback (instead of the default dialog)** @public* @param {function} confirmHandler*/self.setConfirmHandler = function (handler) {confirmHandler = handler;};/*** Adds UI items to the widget.** @public* @param {Object} item*/self.addItem = function (item) {var $placeholder, mouseDownAt;var $item = $('<li/>', {'class' : 'h5p-li',});/*** Mouse move callback** @private* @param {Object} event*/var move = function (event) {if (mouseDownAt) {// Have not started moving yetif (! (event.pageX > mouseDownAt.x + 5 || event.pageX < mouseDownAt.x - 5 ||event.pageY > mouseDownAt.y + 5 || event.pageY < mouseDownAt.y - 5) ) {return; // Not ready to start moving}// Prevent wysiwyg becoming unresponsiveH5PEditor.Html.removeWysiwyg();// Prepare to start movingmouseDownAt = null;var offset = $item.offset();adjustX = event.pageX - offset.left;adjustY = event.pageY - offset.top;marginTop = parseInt($item.css('marginTop'));formOffset = $list.offsetParent().offset();// TODO: Couldn't formOffset and margin be added?var width = $item.width();var height = $item.height();$item.addClass('moving').css({width: width,height: height});$placeholder = $('<li/>', {'class': 'placeholder h5p-li',css: {width: width,height: height}}).insertBefore($item);}moveItem($item, $placeholder, event.pageX, event.pageY);};/*** Mouse button release callback** @private*/var up = function () {// Stop listening for mouse move eventsH5P.$window.unbind('mousemove', move).unbind('mouseup', up);// Enable text select againH5P.$body.css({'-moz-user-select': '','-webkit-user-select': '','user-select': '','-ms-user-select': ''}).attr('unselectable', 'off')[0].onselectstart = H5P.$body[0].ondragstart = null;if (!mouseDownAt) {// Not your regular click, we have been moving$item.removeClass('moving').css({width: 'auto',height: 'auto'});$placeholder.remove();if (item instanceof H5PEditor.Group) {// Avoid groups expand/collapse togglingitem.preventToggle = true;}}};/*** Mouse button down callback** @private*/var down = function (event) {if (event.which !== 1) {return; // Only allow left mouse button}mouseDownAt = {x: event.pageX,y: event.pageY};// Start listening for mouse move eventsH5P.$window.mousemove(move).mouseup(up);// Prevent text selectH5P.$body.css({'-moz-user-select': 'none','-webkit-user-select': 'none','user-select': 'none','-ms-user-select': 'none'}).attr('unselectable', 'on')[0].onselectstart = H5P.$body[0].ondragstart = function () {return false;};};/*** Order current list item up** @private*/var moveItemUp = function () {var $prev = $item.prev();if (!$prev.length) {return; // Cannot move item further up}// Prevent wysiwyg becoming unresponsiveH5PEditor.Html.removeWysiwyg();var currentIndex = $item.index();$prev.insertAfter($item);list.moveItem(currentIndex, currentIndex - 1);};/*** Order current ist item down** @private*/var moveItemDown = function () {var $next = $item.next();if (!$next.length) {return; // Cannot move item further down}// Prevent wysiwyg becoming unresponsiveH5PEditor.Html.removeWysiwyg();var currentIndex = $item.index();$next.insertBefore($item);list.moveItem(currentIndex, currentIndex + 1);};// List item title barvar $titleBar = $('<div/>', {'class': 'list-item-title-bar',appendTo: $item});// Container for list actionsvar $listActions = $('<div/>', {class: 'list-actions',appendTo: $titleBar});// Append order buttonvar $orderGroup = $('<div/>', {class : 'order-group',appendTo: $listActions});H5PEditor.createButton('order-up', H5PEditor.t('core', 'orderItemUp'), moveItemUp).appendTo($orderGroup);H5PEditor.createButton('order-down', H5PEditor.t('core', 'orderItemDown'), moveItemDown).appendTo($orderGroup);H5PEditor.createButton('remove', H5PEditor.t('core', 'removeItem'), function () {confirmHandler(item, $item.index(), $(this).offset(), function () {list.removeItem($item.index());$item.remove();});}).appendTo($listActions);// Append new field item to content wrapperif (item instanceof H5PEditor.Group) {// Append to itemitem.appendTo($item);$item.addClass('listgroup');$titleBar.addClass(list.getImportance());// Move label$item.children('.field').children('.title').appendTo($titleBar).addClass('h5peditor-label');// Handle expand and collapseitem.on('expanded', function () {$item.addClass('expanded').removeClass('collapsed');});item.on('collapsed', function () {$item.removeClass('expanded').addClass('collapsed');});}else {// Append content wrappervar $content = $('<div/>', {'class' : 'content'}).appendTo($item);// Add importance to items not in groups$titleBar.addClass(list.getImportance());// Append fielditem.appendTo($content);if (item.field.label !== 0) {// Try to find and move the label to the title barconst $label = $content.children('.field').find('.h5peditor-label:first');if ($label.length !== 0) {$titleBar.append($('<label/>', {'class': 'h5peditor-label','for': $label.parent().attr('for'),html: $label.html()}));$label.hide();}}}// Append item to list$item.appendTo($list);if (item instanceof H5PEditor.Group && item.field.expanded !== false) {// Good UX: automatically expand groups if not explicitly disabled by semanticsitem.expand();}$titleBar.children('.h5peditor-label').mousedown(down);};/*** Determine if child is a text field** @param {Object} child* @returns {boolean} True if child is a text field*/self.isTextField = function (child) {var widget = ns.getWidgetName(child.field);return widget === 'html' || widget === 'text';};/*** Puts this widget at the end of the given container.** @public* @param {jQuery} $container*/self.appendTo = function ($container) {$list.appendTo($container);$button.appendTo($container);};/*** Remove this widget from the editor DOM.** @public*/self.remove = function () {$list.remove();$button.remove();};}return ListEditor;})(H5P.jQuery);