mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2024-12-29 09:22:22 -05:00
Fix #1015: Improve handling of already inserted children in#insertChildren()
This commit is contained in:
parent
99f4ef7204
commit
d8d61ff160
3 changed files with 82 additions and 42 deletions
|
@ -2350,14 +2350,9 @@ new function() { // Injection scope for hit-test functions shared with project
|
|||
if (_proto && !(item instanceof _proto)) {
|
||||
items.splice(i, 1);
|
||||
} else {
|
||||
// If the item is removed and inserted it again further
|
||||
// above, the index needs to be adjusted accordingly.
|
||||
var owner = item._getOwner(),
|
||||
shift = owner === this && item._index < index;
|
||||
// Notify parent of change. Don't notify item itself yet,
|
||||
// as we're doing so when adding it to the new owner below.
|
||||
if (owner && item._remove(false, true) && shift)
|
||||
index--;
|
||||
item._remove(false, true);
|
||||
}
|
||||
}
|
||||
Base.splice(children, items, index, 0);
|
||||
|
@ -2387,6 +2382,32 @@ new function() { // Injection scope for hit-test functions shared with project
|
|||
// through _getOwner() in the various Item#insert*() methods.
|
||||
_insertItem: '#insertChild',
|
||||
|
||||
/**
|
||||
* Private helper method used by {@link #insertAbove(item)} and
|
||||
* {@link #insertBelow(item)}, to insert this item in relation to a
|
||||
* specified other item.
|
||||
*
|
||||
* @param {Item} item the item in relation to which which it should be
|
||||
* inserted
|
||||
* @param {Number} offset the offset at which the item should be inserted
|
||||
* @return {Item} the inserted item, or `null` if inserting was not possible
|
||||
*/
|
||||
_insertAt: function(item, offset, _preserve) {
|
||||
var res = this;
|
||||
if (res !== item) {
|
||||
var owner = item && item._getOwner();
|
||||
if (owner) {
|
||||
// Notify parent of change. Don't notify item itself yet,
|
||||
// as we're doing so when adding it to the new owner below.
|
||||
res._remove(false, true);
|
||||
owner._insertItem(item._index + offset, res, _preserve);
|
||||
} else {
|
||||
res = null;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
},
|
||||
|
||||
/**
|
||||
* Inserts this item above the specified item.
|
||||
*
|
||||
|
@ -2394,9 +2415,7 @@ new function() { // Injection scope for hit-test functions shared with project
|
|||
* @return {Item} the inserted item, or `null` if inserting was not possible
|
||||
*/
|
||||
insertAbove: function(item, _preserve) {
|
||||
var owner = item && item._getOwner();
|
||||
return owner ? owner._insertItem(item._index + 1, this, _preserve)
|
||||
: null;
|
||||
return this._insertAt(item, 1, _preserve);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -2406,8 +2425,7 @@ new function() { // Injection scope for hit-test functions shared with project
|
|||
* @return {Item} the inserted item, or `null` if inserting was not possible
|
||||
*/
|
||||
insertBelow: function(item, _preserve) {
|
||||
var owner = item && item._getOwner();
|
||||
return owner ? owner._insertItem(item._index, this, _preserve) : null;
|
||||
return this._insertAt(item, 0, _preserve);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -352,6 +352,8 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
|
|||
*/
|
||||
insertLayer: function(index, layer) {
|
||||
if (layer instanceof Layer) {
|
||||
// Notify parent of change. Don't notify item itself yet,
|
||||
// as we're doing so when adding it to the new owner below.
|
||||
layer._remove(false, true);
|
||||
Base.splice(this._children, [layer], index, 0);
|
||||
layer._setProject(this, true);
|
||||
|
|
|
@ -59,37 +59,57 @@ test('Item Order', function() {
|
|||
test('Item#insertAbove(item) / Item#insertBelow(item)', function() {
|
||||
var item0, item1, item2;
|
||||
|
||||
function testMove(command, indexes) {
|
||||
paper.project.clear();
|
||||
new Layer();
|
||||
item0 = new Group();
|
||||
item1 = new Group();
|
||||
item2 = new Group();
|
||||
command();
|
||||
var str = getFunctionMessage(command);
|
||||
equals(item0.index, indexes[0], str + ': item0.index');
|
||||
equals(item1.index, indexes[1], str + ': item1.index');
|
||||
equals(item2.index, indexes[2], str + ': item2.index');
|
||||
function testType(ctor) {
|
||||
function testMove(command, indexes) {
|
||||
paper.project.clear();
|
||||
if (ctor !== Layer)
|
||||
new Layer();
|
||||
item0 = new ctor();
|
||||
item1 = new ctor();
|
||||
item2 = new ctor();
|
||||
command();
|
||||
var str = getFunctionMessage(command);
|
||||
var name = item0.className.toLowerCase();
|
||||
equals(item0.index, indexes[0], str + ': ' + name + '0.index');
|
||||
equals(item1.index, indexes[1], str + ': ' + name + '1.index');
|
||||
equals(item2.index, indexes[2], str + ': ' + name + '2.index');
|
||||
}
|
||||
|
||||
testMove(function() { item0.insertBelow(item0); }, [0,1,2]);
|
||||
testMove(function() { item0.insertBelow(item1); }, [0,1,2]);
|
||||
testMove(function() { item0.insertBelow(item2); }, [1,0,2]);
|
||||
testMove(function() { item1.insertBelow(item0); }, [1,0,2]);
|
||||
testMove(function() { item1.insertBelow(item1); }, [0,1,2]);
|
||||
testMove(function() { item1.insertBelow(item2); }, [0,1,2]);
|
||||
|
||||
testMove(function() { item2.insertBelow(item0); }, [1,2,0]);
|
||||
testMove(function() { item2.insertBelow(item1); }, [0,2,1]);
|
||||
testMove(function() { item2.insertBelow(item2); }, [0,1,2]);
|
||||
|
||||
testMove(function() { item0.insertAbove(item0); }, [0,1,2]);
|
||||
testMove(function() { item0.insertAbove(item1); }, [1,0,2]);
|
||||
testMove(function() { item0.insertAbove(item2); }, [2,0,1]);
|
||||
testMove(function() { item1.insertAbove(item0); }, [0,1,2]);
|
||||
testMove(function() { item1.insertAbove(item1); }, [0,1,2]);
|
||||
testMove(function() { item1.insertAbove(item2); }, [0,2,1]);
|
||||
testMove(function() { item2.insertAbove(item0); }, [0,2,1]);
|
||||
testMove(function() { item2.insertAbove(item1); }, [0,1,2]);
|
||||
testMove(function() { item2.insertAbove(item2); }, [0,1,2]);
|
||||
}
|
||||
|
||||
testMove(function() { item0.insertBelow(item0); }, [0,1,2]);
|
||||
testMove(function() { item0.insertBelow(item1); }, [0,1,2]);
|
||||
testMove(function() { item0.insertBelow(item2); }, [1,0,2]);
|
||||
testMove(function() { item1.insertBelow(item0); }, [1,0,2]);
|
||||
testMove(function() { item1.insertBelow(item1); }, [0,1,2]);
|
||||
testMove(function() { item1.insertBelow(item2); }, [0,1,2]);
|
||||
|
||||
testMove(function() { item2.insertBelow(item0); }, [1,2,0]);
|
||||
testMove(function() { item2.insertBelow(item1); }, [0,2,1]);
|
||||
testMove(function() { item2.insertBelow(item2); }, [0,1,2]);
|
||||
|
||||
testMove(function() { item0.insertAbove(item0); }, [0,1,2]);
|
||||
testMove(function() { item0.insertAbove(item1); }, [1,0,2]);
|
||||
testMove(function() { item0.insertAbove(item2); }, [2,0,1]);
|
||||
testMove(function() { item1.insertAbove(item0); }, [0,1,2]);
|
||||
testMove(function() { item1.insertAbove(item1); }, [0,1,2]);
|
||||
testMove(function() { item1.insertAbove(item2); }, [0,2,1]);
|
||||
testMove(function() { item2.insertAbove(item0); }, [0,2,1]);
|
||||
testMove(function() { item2.insertAbove(item1); }, [0,1,2]);
|
||||
testMove(function() { item2.insertAbove(item2); }, [0,1,2]);
|
||||
testType(Group);
|
||||
testType(Layer);
|
||||
});
|
||||
|
||||
test('Item#insertChild() with already inserted children', function() {
|
||||
var item1 = new Group(),
|
||||
item2 = new Group(),
|
||||
item3 = new Group(),
|
||||
item4 = new Group(),
|
||||
newIndex = 1,
|
||||
oldIndex = item4.index;
|
||||
item4.parent.insertChild(1, item4);
|
||||
equals(function() { return item4.index; }, newIndex);
|
||||
item4.parent.insertChild(oldIndex, item4);
|
||||
equals(function() { return item4.index; }, oldIndex);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue