diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 24c9d7e..1af8911 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1045,23 +1045,6 @@ function template_preprocess_item_list(&$variables) { } /** - * Returns HTML for an indentation div; used for drag and drop tables. - * - * @param $variables - * An associative array containing: - * - size: Optional. The number of indentations to create. - * - * @ingroup themeable - */ -function theme_indentation($variables) { - $output = ''; - for ($n = 0; $n < $variables['size']; $n++) { - $output .= '
 
'; - } - return $output; -} - -/** * Prepares variables for container templates. * * Default template: container.html.twig. @@ -1714,7 +1697,7 @@ function drupal_common_theme() { ), 'indentation' => array( 'variables' => array('size' => 1), - 'function' => 'theme_indentation', + 'template' => 'indentation', ), // From theme.maintenance.inc. 'maintenance_page' => array( diff --git a/core/misc/tabledrag.js b/core/misc/tabledrag.js index 8754b98..74facc7 100644 --- a/core/misc/tabledrag.js +++ b/core/misc/tabledrag.js @@ -195,7 +195,7 @@ * * @type {number} */ - this.indentCount = 1; + this.indentDepth = 1; // Find the width of indentations to measure mouse movements against. // Because the table doesn't need to start with any indentations, we // manually append 2 indentations in the first draggable row, measure @@ -204,12 +204,32 @@ var testRow = $('').addClass('draggable').appendTo(table); var testCell = $('').appendTo(testRow).prepend(indent).prepend(indent); var $indentation = testCell.find('.js-indentation'); + var backgroundPos = $indentation.css('background-position'); /** + * The width of an indent in pixels * * @type {number} */ - this.indentAmount = $indentation.get(1).offsetLeft - $indentation.get(0).offsetLeft; + this.indentAmount = Math.abs($indentation.get(1).offsetLeft - $indentation.get(0).offsetLeft) * this.rtl; + + /** + * The tree background image y position and x increment and origin. + * + * @type {object} + * + * @prop {string} y + * @prop {number} dx + * @prop {number} ox + * @prop {bool} rtl + */ + this.indentPixels = { + y: backgroundPos.substring(backgroundPos.indexOf(' ') + 1), + dx: this.indentAmount * this.rtl, + ox: (this.rtl == 1 ? 0 : -800), + rtl: (this.rtl == 1) ? 0 : true + }; + testRow.remove(); } @@ -454,7 +474,7 @@ if ($indentationLast.length) { $indentationLast.after(handle); // Update the total width of indentation in this entire table. - self.indentCount = Math.max($item.find('.js-indentation').length, self.indentCount); + self.indentDepth = Math.max($item.find('.js-indentation').first().data('indent'), self.indentDepth); } else { $item.find('td').eq(0).prepend(handle); @@ -496,7 +516,7 @@ handle.on('keydown', function (event) { // If a rowObject doesn't yet exist and this isn't the tab key. if (event.keyCode !== 9 && !self.rowObject) { - self.rowObject = new self.row(item, 'keyboard', self.indentEnabled, self.maxDepth, true); + self.rowObject = new self.row(item, 'keyboard', self.indentEnabled, self.maxDepth, true, self.indentPixels); } var keyChange = false; @@ -529,7 +549,7 @@ if ($(item).is('.tabledrag-root')) { // Swap with the previous top-level row. groupHeight = 0; - while (previousRow && $previousRow.find('.js-indentation').length) { + while (previousRow && $previousRow.find('.js-indentation').first().data('indent')) { $previousRow = $(previousRow).prev('tr:first-of-type'); previousRow = $previousRow.get(0); groupHeight += $previousRow.is(':hidden') ? 0 : previousRow.offsetHeight; @@ -580,7 +600,7 @@ if ($(item).is('.tabledrag-root')) { // Swap with the next group (necessarily a top-level one). groupHeight = 0; - var nextGroup = new self.row(nextRow, 'keyboard', self.indentEnabled, self.maxDepth, false); + var nextGroup = new self.row(nextRow, 'keyboard', self.indentEnabled, self.maxDepth, false, self.indentPixels); if (nextGroup) { $(nextGroup.group).each(function () { groupHeight += $(this).is(':hidden') ? 0 : this.offsetHeight; @@ -666,7 +686,7 @@ } // Create a new rowObject for manipulation of this row. - self.rowObject = new self.row(item, 'pointer', self.indentEnabled, self.maxDepth, true); + self.rowObject = new self.row(item, 'pointer', self.indentEnabled, self.maxDepth, true, self.indentPixels); // Save the position of the table. self.table.topY = $(self.table).offset().top; @@ -735,8 +755,8 @@ // restricted according to the rows around this row. var indentChange = self.rowObject.indent(indentDiff); // Update table and pointer indentations. - self.dragObject.indentPointerPos.x += self.indentAmount * indentChange * self.rtl; - self.indentCount = Math.max(self.indentCount, self.rowObject.indents); + self.dragObject.indentPointerPos.x += self.indentAmount * indentChange; + self.indentDepth = Math.max(self.indentDepth, self.rowObject.indents); } return false; @@ -947,7 +967,7 @@ sourceRow = changedRow; if ($previousRow.is('.draggable') && $previousRow.find('.' + group).length) { if (this.indentEnabled) { - if ($previousRow.find('.js-indentations').length === $changedRow.find('.js-indentations').length) { + if ($previousRow.find('.js-indentation').first().data('indent') === $changedRow.find('.js-indentation').first().data('indent')) { sourceRow = previousRow; } } @@ -957,7 +977,7 @@ } else if ($nextRow.is('.draggable') && $nextRow.find('.' + group).length) { if (this.indentEnabled) { - if ($nextRow.find('.js-indentations').length === $changedRow.find('.js-indentations').length) { + if ($nextRow.find('.js-indentation').first().data('indent') === $changedRow.find('.js-indentation').first().data('indent')) { sourceRow = nextRow; } } @@ -971,7 +991,7 @@ else if (rowSettings.relationship === 'parent') { $previousRow = $changedRow.prev('tr'); previousRow = $previousRow; - while ($previousRow.length && $previousRow.find('.js-indentation').length >= this.rowObject.indents) { + while ($previousRow.length && $previousRow.find('.js-indentation').first().data('indent') >= this.rowObject.indents) { $previousRow = $previousRow.prev('tr'); previousRow = $previousRow; } @@ -1015,7 +1035,7 @@ switch (rowSettings.action) { case 'depth': // Get the depth of the target row. - targetElement.value = $(sourceElement).closest('tr').find('.js-indentation').length; + targetElement.value = $(sourceElement).closest('tr').find('.js-indentation').first().data('indent'); break; case 'match': @@ -1171,28 +1191,32 @@ * @param {bool} addClasses * Whether we want to add classes to this row to indicate child * relationships. + * @param {object} indentPixels + * The pixel indentation for the menu tree per indent level. */ - Drupal.tableDrag.prototype.row = function (tableRow, method, indentEnabled, maxDepth, addClasses) { + Drupal.tableDrag.prototype.row = function (tableRow, method, indentEnabled, maxDepth, addClasses, indentPixels) { var $tableRow = $(tableRow); this.element = tableRow; this.method = method; this.group = [tableRow]; - this.groupDepth = $tableRow.find('.js-indentation').length; + this.groupDepth = $tableRow.find('.js-indentation').first().data('indent'); this.changed = false; this.table = $tableRow.closest('table')[0]; this.indentEnabled = indentEnabled; this.maxDepth = maxDepth; + this.indentPixels = indentPixels; // Direction the row is being moved. this.direction = ''; if (this.indentEnabled) { - this.indents = $tableRow.find('.js-indentation').length; + this.indents = $tableRow.find('.js-indentation').first().data('indent'); this.children = this.findChildren(addClasses); this.group = $.merge(this.group, this.children); // Find the depth of this entire group. for (var n = 0; n < this.group.length; n++) { - this.groupDepth = Math.max($(this.group[n]).find('.js-indentation').length, this.groupDepth); + this.groupDepth = Math.max($(this.group[n]).find('.js-indentation').first().data('indent'), this.groupDepth); } + this.treeIndent(this.indents); } }; @@ -1211,22 +1235,21 @@ var rows = []; var child = 0; - function rowIndentation(indentNum, el) { + function rowIndentation(i, el) { var self = $(el); + var indentNum = self.data('indent'); + if (child === 1 && (indentNum === parentIndentation)) { self.addClass('tree-child-first'); } - if (indentNum === parentIndentation) { + if (indentNum >= parentIndentation) { self.addClass('tree-child'); } - else if (indentNum > parentIndentation) { - self.addClass('tree-child-horizontal'); - } } while (currentRow.length) { // A greater indentation indicates this is a child. - if (currentRow.find('.js-indentation').length > parentIndentation) { + if (currentRow.find('.js-indentation').first().data('indent') > parentIndentation) { child++; rows.push(currentRow[0]); if (addClasses) { @@ -1239,7 +1262,7 @@ currentRow = currentRow.next('tr.draggable'); } if (addClasses && rows.length) { - $(rows[rows.length - 1]).find('.js-indentation:nth-child(' + (parentIndentation + 1) + ')').addClass('tree-child-last'); + $(rows[rows.length - 1]).find('.js-indentation').addClass('tree-child-last'); } return rows; }; @@ -1322,7 +1345,7 @@ // Minimum indentation: // Do not orphan the next row. - minIndent = nextRow ? $(nextRow).find('.js-indentation').length : 0; + minIndent = nextRow ? $(nextRow).find('.js-indentation').first().data('indent') : 0; // Maximum indentation: if (!prevRow || $prevRow.is(':not(.draggable)') || $(this.element).is('.tabledrag-root')) { @@ -1334,7 +1357,7 @@ } else { // Do not go deeper than as a child of the previous row. - maxIndent = $prevRow.find('.js-indentation').length + ($prevRow.is('.tabledrag-leaf') ? 0 : 1); + maxIndent = $prevRow.find('.js-indentation').first().data('indent') + ($prevRow.is('.tabledrag-leaf') ? 0 : 1); // Limit by the maximum allowed depth for the table. if (this.maxDepth) { maxIndent = Math.min(maxIndent, this.maxDepth - (this.groupDepth - this.indents)); @@ -1368,22 +1391,26 @@ indent = Math.max(indent, this.interval.min); indent = Math.min(indent, this.interval.max); indentDiff = indent - this.indents; + this.indents = indent; - for (var n = 1; n <= Math.abs(indentDiff); n++) { - // Add or remove indentations. - if (indentDiff < 0) { - $group.find('.js-indentation:first-of-type').remove(); - this.indents--; - } - else { - $group.find('td:first-of-type').prepend(Drupal.theme('tableDragIndentation')); - this.indents++; - } - } if (indentDiff) { // Update indentation for this row. this.changed = true; this.groupDepth += indentDiff; + + // Update the indentation for the child rows + var rowIndent; + $group.find('.js-indentation:first-of-type').each(function(i, el) { + el = $(el); + rowIndent = el.data('indent'); + rowIndent += indentDiff; + el.data('indent', rowIndent); + // We need to reflect this in the DOM as well, so the CSS reflects the change. + el.attr('data-indent', rowIndent); + }); + + this.treeIndent(indent); + this.onIndent(); } @@ -1414,7 +1441,7 @@ // Either add immediately if this is a flat table, or check to ensure // that this row has the same level of indentation. if (this.indentEnabled) { - checkRowIndentation = checkRow.find('.js-indentation').length; + checkRowIndentation = checkRow.find('.js-indentation').first().data('indent'); } if (!(this.indentEnabled) || (checkRowIndentation === rowIndentation)) { @@ -1449,8 +1476,7 @@ $(this.children[n]).find('.js-indentation') .removeClass('tree-child') .removeClass('tree-child-first') - .removeClass('tree-child-last') - .removeClass('tree-child-horizontal'); + .removeClass('tree-child-last'); } } }; @@ -1467,6 +1493,33 @@ }; /** + * Change background image indent on drag if it's changed. + */ + Drupal.tableDrag.prototype.row.prototype.treeIndent = function (indent) { + var indentPixels = this.indentPixels; + var indentDivs = $(this.table).find('.tree-child-first,.tree-child,.tree-child-last'); + var backgroundX = indentPixels.ox + indent * indentPixels.dx; + var background = backgroundX + 'px ' + indentPixels.y; + + if (indentPixels.rtl) { + // It would be nice here to just use background-position edge offsets, ie + // align relative to the right egde of div js-indentation. However some + // older browsers, eg Safari 6.1, do not support them. + indentDivs.each(function(i, el) { + var el = $(el); + var relIndent = el.data('indent') - indent; + backgroundX = indentPixels.ox + relIndent * indentPixels.dx; + background = backgroundX + 'px ' + indentPixels.y; + + el.css('background-position', background); + }); + } + else { + indentDivs.css('background-position', background); + } + }; + + /** * Stub function. Allows a custom handler when a row is indented. * * @return {?bool} @@ -1499,7 +1552,7 @@ * @return {string} */ tableDragIndentation: function () { - return '
 
'; + return '
 
'; }, /** diff --git a/core/misc/tree-bottom.png b/core/misc/tree-bottom.png deleted file mode 100644 index a558045..0000000 --- a/core/misc/tree-bottom.png +++ /dev/null @@ -1,3 +0,0 @@ -PNG - - IHDRPQ8#ɛ PLTEU6tRNS@f&IDAT8cX040`QQQASC1@(b1'6xIENDB` \ No newline at end of file diff --git a/core/misc/tree.png b/core/misc/tree.png deleted file mode 100644 index 89ea235..0000000 --- a/core/misc/tree.png +++ /dev/null @@ -1,3 +0,0 @@ -PNG - - IHDRPQ8#ɛ PLTEU6tRNS@f'IDAT8OcX040`QQQAhTpTr 9 I"IENDB` \ No newline at end of file diff --git a/core/misc/tree.svg b/core/misc/tree.svg new file mode 100644 index 0000000..d51588f --- /dev/null +++ b/core/misc/tree.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/core/modules/system/css/components/tabledrag.module.css b/core/modules/system/css/components/tabledrag.module.css index 39d7fb1..3069296 100644 --- a/core/modules/system/css/components/tabledrag.module.css +++ b/core/modules/system/css/components/tabledrag.module.css @@ -72,14 +72,27 @@ a.tabledrag-handle:focus .handle { text-align: left; } .indentation { - float: left; /* LTR */ - height: 1.7em; - margin: -0.4em 0.2em -0.4em -0.4em; /* LTR */ - padding: 0.42em 0 0.42em 0.6em; /* LTR */ - width: 20px; + float: left; + width: 0em; } [dir="rtl"] .indentation { float: right; - margin: -0.4em -0.4em -0.4em 0.2em; - padding: 0.42em 0.6em 0.42em 0; } +.indentation[data-indent="1"] { padding-left: 20px; } +.indentation[data-indent="2"] { padding-left: 40px; } +.indentation[data-indent="3"] { padding-left: 60px; } +.indentation[data-indent="4"] { padding-left: 80px; } +.indentation[data-indent="5"] { padding-left: 100px; } +.indentation[data-indent="6"] { padding-left: 120px; } +.indentation[data-indent="7"] { padding-left: 140px; } +.indentation[data-indent="8"] { padding-left: 160px; } +.indentation[data-indent="9"] { padding-left: 180px; } +[dir="rtl"] .indentation[data-indent="1"] { padding-left: 0; padding-right: 20px; } +[dir="rtl"] .indentation[data-indent="2"] { padding-left: 0; padding-right: 40px; } +[dir="rtl"] .indentation[data-indent="3"] { padding-left: 0; padding-right: 60px; } +[dir="rtl"] .indentation[data-indent="4"] { padding-left: 0; padding-right: 80px; } +[dir="rtl"] .indentation[data-indent="5"] { padding-left: 0; padding-right: 100px; } +[dir="rtl"] .indentation[data-indent="6"] { padding-left: 0; padding-right: 120px; } +[dir="rtl"] .indentation[data-indent="7"] { padding-left: 0; padding-right: 140px; } +[dir="rtl"] .indentation[data-indent="8"] { padding-left: 0; padding-right: 160px; } +[dir="rtl"] .indentation[data-indent="9"] { padding-left: 0; padding-right: 180px; } diff --git a/core/modules/system/css/components/tree-child.module.css b/core/modules/system/css/components/tree-child.module.css index 71bb8c8..0ad0db6 100644 --- a/core/modules/system/css/components/tree-child.module.css +++ b/core/modules/system/css/components/tree-child.module.css @@ -4,15 +4,15 @@ */ div.tree-child { - background: url(../../../../misc/tree.png) no-repeat 11px center; /* LTR */ + padding: 0 0; + background: url(../../../../misc/tree.svg) repeat-y left 10px; /* LTR */ + background-size: 800px 50px; + line-height: 20px; } div.tree-child-last { - background: url(../../../../misc/tree-bottom.png) no-repeat 11px center; /* LTR */ + line-height: 11px; } [dir="rtl"] div.tree-child, [dir="rtl"] div.tree-child-last { - background-position: -65px center; -} -div.tree-child-horizontal { - background: url(../../../../misc/tree.png) no-repeat -11px center; + background-position: right 10px; } diff --git a/core/modules/system/templates/indentation.html.twig b/core/modules/system/templates/indentation.html.twig index e07e3c1..d102929 100644 --- a/core/modules/system/templates/indentation.html.twig +++ b/core/modules/system/templates/indentation.html.twig @@ -3,18 +3,12 @@ * @file * Default theme implementation for a set of indentation divs. * - * These
tags are used for drag and drop tables. + * This
tag is used for drag and drop tables. * * Available variables: - * - size: Optional. The number of indentations to create. + * - size: Optional. The width of indentation. * * @ingroup themeable */ #} - -{% for i in 1..size if size > 0 %}
 
{% endfor %} +