diff --git a/packages/joint-core/src/dia/HighlighterView.mjs b/packages/joint-core/src/dia/HighlighterView.mjs index ced89ed00..6cc3443e7 100644 --- a/packages/joint-core/src/dia/HighlighterView.mjs +++ b/packages/joint-core/src/dia/HighlighterView.mjs @@ -1,6 +1,6 @@ import * as mvc from '../mvc/index.mjs'; import V from '../V/index.mjs'; -import { isPlainObject, result } from '../util/util.mjs'; +import { isNumber, isPlainObject, result } from '../util/util.mjs'; function toArray(obj) { if (!obj) return []; @@ -106,8 +106,8 @@ export const HighlighterView = mvc.View.extend({ this.transform(); return; } - const { vel: cellViewRoot, paper } = cellView; - const { layer: layerName } = options; + const { paper } = cellView; + const { layer: layerName, z } = options; if (layerName) { let vGroup; if (detachedTransformGroup) { @@ -117,12 +117,30 @@ export const HighlighterView = mvc.View.extend({ vGroup = V('g').addClass('highlight-transform').append(el); } this.transformGroup = vGroup; - paper.getLayerView(layerName).insertSortedNode(vGroup.node, options.z); + paper.getLayerView(layerName).insertSortedNode(vGroup.node, z); } else { - // TODO: prepend vs append - if (!el.parentNode || el.nextSibling) { - // Not appended yet or not the last child - cellViewRoot.append(el); + const children = cellView.el.children; + + const index = Math.max(z, 0); + const beforeChild = children[index]; + + // If the provided `z` is a number and there is an element on the index, + // we need to insert the highlighter before the element on the index. + // Otherwise, the highlighter will be appended as the last child. + const toBeInserted = isNumber(z) && beforeChild; + const isElementAtTargetPosition = toBeInserted + // If the element is being inserted, check if it is not already at the correct position. + ? el === beforeChild + // If the element is being appended, check if it is not already last child. + : !el.nextElementSibling; + + // If the element is already mounted and does not require repositioning, do nothing. + if (el.parentNode && isElementAtTargetPosition) return; + + if (toBeInserted) { + cellView.el.insertBefore(el, beforeChild); + } else { + cellView.el.appendChild(el); } } }, diff --git a/packages/joint-core/test/jointjs/dia/HighlighterView.js b/packages/joint-core/test/jointjs/dia/HighlighterView.js index fb7c58e1c..664a1f70c 100644 --- a/packages/joint-core/test/jointjs/dia/HighlighterView.js +++ b/packages/joint-core/test/jointjs/dia/HighlighterView.js @@ -279,7 +279,22 @@ QUnit.module('HighlighterView', function(hooks) { }); - QUnit.test('z', function(assert) { + QUnit.test('z - cell view', function(assert) { + + const h1 = joint.dia.HighlighterView.add(elementView, 'body', 'highlighter-id-1', { + z: 0 + }); + + const h2 = joint.dia.HighlighterView.add(elementView, 'body', 'highlighter-id-2', { + z: 1 + }); + + assert.equal(elementView.el.children[0], h1.el); + assert.equal(elementView.el.children[1], h2.el); + + }); + + QUnit.test('z - paper layer', function(assert) { var layer = joint.dia.Paper.Layers.FRONT; var h1 = joint.dia.HighlighterView.add(elementView, 'body', 'highlighter-id-1', { layer: layer, z: 2 }); var h2 = joint.dia.HighlighterView.add(elementView, 'body', 'highlighter-id-2', { layer: layer, z: 3 });