define([ 'lodash', 'jquery', 'taoQtiItem/qtiCreator/widgets/states/factory', 'taoQtiItem/qtiCreator/widgets/helpers/deletingState', 'taoQtiItem/qtiCreator/helper/gridUnits', 'taoQtiItem/qtiCreator/editor/gridEditor/helper', 'taoQtiItem/qtiCreator/editor/gridEditor/content' ], function (_, $, stateFactory, deletingHelper, gridUnits, gridHelper, contentHelper) { const DeletingState = stateFactory.create( 'deleting', function init() { const element = this.widget.element; //array to store new col untis this.refactoredUnits = []; this.updateBody = false; //reference to the dom element(s) to be remove on delete this.$elementToRemove = this.getElementToRemove(); this.hideWidget(); this.showMessage(element); element.data('deleting', true); //trigger resizing if (this.updateBody) { //store reference to the item and its container: this.item = element.getRootElement(); this.$item = this.item.data('widget').$container.find('.qti-itemBody'); //call for resize action this.$item.trigger('resize.qti-widget'); } }, function exit() { this.showWidget(); deletingHelper.confirmDeletion(this.messageBox); this.widget.element.data('deleting', false); $('body').off('.deleting'); if (this.updateBody) { this.$item.trigger('resize.qti-widget'); } } ); /** * @todo move widget specific code to their respective location * * @returns {jQuery} container */ DeletingState.prototype.getElementToRemove = function () { const $container = this.widget.$container; //if is a choice widget: if ($container.hasClass('qti-choice')) { if ($container.prop('tagName') === 'TH') { //matchInteraction: if ($container.parent().parent().prop('tagName') === 'THEAD') { //hide col const $tbody = $container.closest('table.matrix').children('tbody'); const $tds = $tbody.children('tr').find('td:last'); return $container.add($tds); } else if ($container.parent().parent().prop('tagName') === 'TBODY') { //hide row return $container.parent(); } } else { return $container; } } /** * inline widget */ if ($container.hasClass('widget-inline')) { return $container.add(this.widget.$original); } /** * block widget */ let $col = $container.parent(); //check sub-column condition const $subCol = $container.parent('.colrow'); if ($subCol.length) { this.updateBody = true; const $colMulti = $subCol.parent(); if ($colMulti.find('.colrow').length === 1) { //this is the only sub-column remaining, hide the entire col $col = $colMulti; } else { //hide the whole sub-column only : return $subCol; } } //check if we should hide the col only or the whole row const $row = $col.parent('.grid-row'); if ($row.length) { this.updateBody = true; if ($row.children().length === 1) { //if it is the only col in the row, hide the entire row return $row; } else { //else, hide the current one ... return $col; } } else if ($container.hasClass('grid-row')) { //rubric block: this.updateBody = true; return $container; } //other block widgets: if ($container.hasClass('widget-block') || $container.hasClass('widget-blockInteraction')) { return $container; } }; const _isCol = function ($col) { const attrClass = $col.attr('class'); return attrClass && /col-([\d]+)/.test(attrClass); }; const _redistributeUnits = function ($col) { const $otherCols = $col.siblings(); let cols = []; $otherCols.each(function () { const $thisCol = $(this), units = $col.data('units'); cols.push({ elt: $thisCol, units: units }); }); cols = gridUnits.redistribute(cols); _.each(cols, function (col) { col.elt.removeClass(`col-${col.units}`).addClass(`col-${col.refactoredUnits}`); gridHelper.setUnitsFromClass(col.elt); }); //store results in the element for future ref? $col.data('redistributedUnits', cols); return cols; }; DeletingState.prototype.hideWidget = function () { const $elt = this.$elementToRemove; if ($elt.length) { $elt.hide(); if (_isCol($elt)) { //it is a column : redistribute the units of the columdn to the others this.refactoredUnits = _redistributeUnits($elt); } } }; DeletingState.prototype.showWidget = function () { const $elt = this.$elementToRemove; if ($elt.length && $.contains(document, $elt[0])) { $elt.show(); if (_isCol($elt)) { //restore the other units: _.each(this.refactoredUnits, function (col) { col.elt.removeClass(`col-${col.refactoredUnits}`).addClass(`col-${col.units}`); gridHelper.setUnitsFromClass(col.elt); }); } } }; DeletingState.prototype.showMessage = function () { const $messageBox = deletingHelper.createInfoBox([this.widget]); $messageBox .on('confirm.deleting', () => { this.deleteElement(); }) .on('undo.deleting', () => { try { this.widget.changeState('question'); } catch (e) { this.widget.changeState('active'); } }); this.messageBox = $messageBox; }; DeletingState.prototype.deleteElement = function () { this.refactoredUnits = []; // remove inner widgets const container = this.widget.element; if (container.getBody && container.getBody().elements) { _.each(_.values(container.getBody().elements), function (elt) { if (elt.metaData && elt.metaData.widget) { const widget = elt.metaData.widget; widget.destroy(); widget.element.remove(); } }); } this.$elementToRemove.remove(); //remove html from the dom this.widget.destroy(); //remove what remains of the widget (almost nothing), call this after element remove this.widget.element.remove(); //remove from model if (this.updateBody) { //need to update item body this.item.body(contentHelper.getContent(this.$item)); } if (this.$item) { this.$item.trigger('item.deleted'); } }; return DeletingState; });