From 6fc08c6417d88b2010c4bff861cf33b13d0abc57 Mon Sep 17 00:00:00 2001 From: Jonathan Puckey Date: Fri, 17 Jun 2011 16:58:22 +0200 Subject: [PATCH 1/2] Item: implement #addChild(item), #insertChild(index, item), #insertAbove(item) and #insertBelow(item) Deprecate: #moveAbove, #moveBelow, #appendTop, #appendBottom. --- src/item/Group.js | 4 +- src/item/Item.js | 105 +++++++++++++++++++++++++++------------ src/item/Layer.js | 10 ++++ src/path/CompoundPath.js | 6 +-- test/tests/Item.js | 36 +++++++------- test/tests/Layer.js | 20 ++++---- test/tests/PathStyle.js | 14 +++--- 7 files changed, 123 insertions(+), 72 deletions(-) diff --git a/src/item/Group.js b/src/item/Group.js index 8a47a29c..92de17cd 100644 --- a/src/item/Group.js +++ b/src/item/Group.js @@ -51,8 +51,8 @@ var Group = this.Group = Item.extend({ * var path = new Path.Circle(event.point, 5); * path.fillColor = 'black'; * - * // Move the path to the top of the group's children list: - * group.appendTop(path); + * // Add the path to the group's children list: + * group.addChild(path); * } * * function onFrame(event) { diff --git a/src/item/Item.js b/src/item/Item.js index f9d54278..136b6e14 100644 --- a/src/item/Item.js +++ b/src/item/Item.js @@ -32,7 +32,7 @@ var Item = this.Item = Base.extend({ // If _project is already set, the item was already moved into the DOM // hierarchy. Used by Layer, where it's added to project.layers instead if (!this._project) - paper.project.activeLayer.appendTop(this); + paper.project.activeLayer.addChild(this); this._style = PathStyle.create(this); this.setStyle(this._project.getCurrentStyle()); }, @@ -73,9 +73,9 @@ var Item = this.Item = Base.extend({ * // Set the name of the path: * path.name = 'example'; * - * // Create a group and move path into it: + * // Create a group and add path to it as a child: * var group = new Group(); - * group.appendTop(path); + * group.addChild(path); * * // The path can be accessed by name: * group.children['example'].fillColor = 'red'; @@ -388,7 +388,7 @@ var Item = this.Item = Base.extend({ * console.log(path.parent == project.activeLayer); // true * * var group = new Group(); - * group.appendTop(path); + * group.addChild(path); * * // Now the parent of the path has become the group: * console.log(path.parent == group); // true @@ -398,7 +398,7 @@ var Item = this.Item = Base.extend({ }, // DOCS: add comment to Item#children about not playing around with the - // array directly - use appendTop etc instead. + // array directly - use addChild etc instead. /** * The children items contained within this item. Items that define a * {@link #name} can also be accessed by name. @@ -412,7 +412,7 @@ var Item = this.Item = Base.extend({ * * // Create a group and move the path into it: * var group = new Group(); - * group.appendTop(path); + * group.addChild(path); * * // Access the path through the group's children array: * group.children[0].fillColor = 'red'; @@ -425,7 +425,7 @@ var Item = this.Item = Base.extend({ * * // Create a group and move the path into it: * var group = new Group(); - * group.appendTop(path); + * group.addChild(path); * * // The path can be accessed by name: * group.children['example'].fillColor = 'orange'; @@ -447,7 +447,7 @@ var Item = this.Item = Base.extend({ setChildren: function(items) { this.removeChildren(); for (var i = 0, l = items && items.length; i < l; i++) - this.appendTop(items[i]); + this.addChild(items[i]); }, /** @@ -573,9 +573,9 @@ var Item = this.Item = Base.extend({ copyTo: function(itemOrProject) { var copy = this.clone(); if (itemOrProject.layers) { - itemOrProject.activeLayer.appendTop(copy); + itemOrProject.activeLayer.addChild(copy); } else { - itemOrProject.appendTop(copy); + itemOrProject.addChild(copy); } return copy; }, @@ -609,7 +609,7 @@ var Item = this.Item = Base.extend({ // If this item has children, clone and append each of them: if (this._children) { for (var i = 0, l = this._children.length; i < l; i++) - copy.appendTop(this._children[i].clone()); + copy.addChild(this._children[i].clone()); } // Only copy over these fields if they are actually defined in 'this' // TODO: Consider moving this to Base once it's useful in more than one @@ -621,8 +621,8 @@ var Item = this.Item = Base.extend({ if (this.hasOwnProperty(key)) copy[key] = this[key]; } - // Move the clone above the original, at the same position. - copy.moveAbove(this); + // Insert the clone above the original, at the same position. + copy.insertAbove(this); // Only set name once the copy is moved, to avoid setting and unsettting // name related structures. if (this._name) @@ -1361,21 +1361,6 @@ var Item = this.Item = Base.extend({ } }, new function() { - function append(top) { - return function(item) { - item._removeFromParent(); - if (this._children) { - Base.splice(this._children, [item], top ? undefined : 0, 0); - item._parent = this; - item._setProject(this._project); - if (item._name) - item.setName(item._name); - return true; - } - return false; - }; - } - function move(above) { return function(item) { // first remove the item from its parent's children list @@ -1397,24 +1382,78 @@ var Item = this.Item = Base.extend({ /** * {@grouptitle Hierarchy Operations} + * Adds the specified item as a child of the item at the end of the + * its children list. You can use this function for groups, compound + * paths and layers. + * + * @param {Item} item The item that will be added as a child + */ + addChild: function(item) { + return this.insertChild(undefined, item); + }, + + /** + * Inserts the specified item as a child of the item at the specified + * index in its {@link #children} list. You can use this function for + * groups, compound paths and layers. + * + * @param {Number} index + * @param {Item} item The item that will be appended as a child + */ + insertChild: function(index, item) { + item._removeFromParent(); + if (this._children) { + Base.splice(this._children, [item], index, 0); + item._parent = this; + item._setProject(this._project); + if (item._name) + item.setName(item._name); + return true; + } + return false; + }, + + /** + * Inserts this item above the specified item. + * + * @function + * @param {Item} item The item above which it should be moved + * @return {Boolean} {@true it was inserted} + */ + insertAbove: move(true), + + /** + * Inserts this item below the specified item. + * + * @function + * @param {Item} item The item above which it should be moved + * @return {Boolean} {@true it was inserted} + */ + insertBelow: move(false), + + /** * Inserts the specified item as a child of the item by appending it to * the list of children and moving it above all other children. You can * use this function for groups, compound paths and layers. * - * @function * @param {Item} item The item that will be appended as a child + * @deprecated use {@link #addChild(item)} instead. */ - appendTop: append(true), + appendTop: function(item) { + return this.addChild(item); + }, /** * Inserts the specified item as a child of this item by appending it to * the list of children and moving it below all other children. You can * use this function for groups, compound paths and layers. * - * @function * @param {Item} item The item that will be appended as a child + * @deprecated use {@link #insertChild(index, item)} instead. */ - appendBottom: append(false), + appendBottom: function(item) { + return this.insertChild(0, item); + }, /** * Moves this item above the specified item. @@ -1422,6 +1461,7 @@ var Item = this.Item = Base.extend({ * @function * @param {Item} item The item above which it should be moved * @return {Boolean} {@true it was moved} + * @deprecated use {@link #insertAbove(item)} instead. */ moveAbove: move(true), @@ -1431,6 +1471,7 @@ var Item = this.Item = Base.extend({ * @function * @param {Item} item the item below which it should be moved * @return {Boolean} {@true it was moved} + * @deprecated use {@link #insertBelow(item)} instead. */ moveBelow: move(false) }; diff --git a/src/item/Layer.js b/src/item/Layer.js index 3d4aa6f9..73d3c23f 100644 --- a/src/item/Layer.js +++ b/src/item/Layer.js @@ -96,8 +96,18 @@ var Layer = this.Layer = Group.extend({ } return { + insertAbove: move(true), + + insertBelow: move(false), + + /** + * @deprecated + */ moveAbove: move(true), + /** + * @deprecated + */ moveBelow: move(false) }; }); diff --git a/src/path/CompoundPath.js b/src/path/CompoundPath.js index e54e9ad9..e137cb26 100644 --- a/src/path/CompoundPath.js +++ b/src/path/CompoundPath.js @@ -56,7 +56,7 @@ var CompoundPath = this.CompoundPath = PathItem.extend({ // TODO: Should this be handled in appendTop / Bottom instead? if (path._clockwise === undefined) path.setClockwise(i < l - 1); - this.appendTop(path); + this.addChild(path); } }, @@ -70,7 +70,7 @@ var CompoundPath = this.CompoundPath = PathItem.extend({ simplify: function() { if (this._children.length == 1) { var child = this._children[0]; - child.moveAbove(this); + child.insertAbove(this); this.remove(); return child; } @@ -118,7 +118,7 @@ var CompoundPath = this.CompoundPath = PathItem.extend({ // all implementing classes. moveTo: function(point) { var path = new Path(); - this.appendTop(path); + this.addChild(path); path.moveTo.apply(path, arguments); }, diff --git a/test/tests/Item.js b/test/tests/Item.js index 6cbb5e75..1de5c25a 100644 --- a/test/tests/Item.js +++ b/test/tests/Item.js @@ -42,10 +42,10 @@ test('clone()', function() { }, true); }); -test('appendTop(item)', function() { +test('addChild(item)', function() { var project = paper.project; var path = new Path(); - project.activeLayer.appendTop(path); + project.activeLayer.addChild(path); equals(function() { return project.activeLayer.children.length; }, 1); @@ -55,11 +55,11 @@ test('item.parent / item.isChild / item.isParent', function() { var project = paper.project; var secondDoc = new Project(); var path = new Path(); - project.activeLayer.appendTop(path); + project.activeLayer.addChild(path); equals(function() { return project.activeLayer.children.indexOf(path) != -1; }, true); - secondDoc.activeLayer.appendTop(path); + secondDoc.activeLayer.addChild(path); equals(function() { return project.activeLayer.isChild(path); }, false); @@ -92,34 +92,34 @@ test('item.lastChild / item.firstChild', function() { }, true); }); -test('appendBottom(item)', function() { +test('insertChild(0, item)', function() { var project = paper.project; var path = new Path(); var secondPath = new Path(); - project.activeLayer.appendBottom(secondPath); + project.activeLayer.insertChild(0, secondPath); equals(function() { return secondPath.index < path.index; }, true); }); -test('moveAbove(item)', function() { +test('insertAbove(item)', function() { var project = paper.project; var path = new Path(); var secondPath = new Path(); - path.moveAbove(secondPath); + path.insertAbove(secondPath); equals(function() { return project.activeLayer.lastChild == path; }, true); }); -test('moveBelow(item)', function() { +test('insertBelow(item)', function() { var project = paper.project; var firstPath = new Path(); var secondPath = new Path(); equals(function() { return secondPath.index > firstPath.index; }, true); - secondPath.moveBelow(firstPath); + secondPath.insertBelow(firstPath); equals(function() { return secondPath.index < firstPath.index; }, true); @@ -161,7 +161,7 @@ test('isGroupedWith', function() { equals(function() { return path.isGroupedWith(secondPath); }, false); - secondGroup.appendTop(path); + secondGroup.addChild(path); equals(function() { return path.isGroupedWith(secondPath); }, true); @@ -180,11 +180,11 @@ test('isGroupedWith', function() { equals(function() { return path.isGroupedWith(secondGroup); }, false); - paper.project.activeLayer.appendTop(path); + paper.project.activeLayer.addChild(path); equals(function() { return path.isGroupedWith(secondPath); }, false); - paper.project.activeLayer.appendTop(secondPath); + paper.project.activeLayer.addChild(secondPath); equals(function() { return path.isGroupedWith(secondPath); }, false); @@ -229,18 +229,18 @@ test('Check item#project when moving items across projects', function() { var doc1 = new Project(); var path = new Path(); var group = new Group(); - group.appendTop(new Path()); + group.addChild(new Path()); equals(function() { return path.project == doc1; }, true); var doc2 = new Project(); - doc2.activeLayer.appendTop(path); + doc2.activeLayer.addChild(path); equals(function() { return path.project == doc2; }, true); - doc2.activeLayer.appendTop(group); + doc2.activeLayer.addChild(group); equals(function() { return group.children[0].project == doc2; }, true); @@ -355,7 +355,7 @@ test('Named child access 2', function() { var group = new Group(); - group.appendTop(path2); + group.addChild(path2); equals(function() { return paper.project.activeLayer.children['test'] == path; @@ -373,7 +373,7 @@ test('Named child access 2', function() { return group._namedChildren['test'].length == 1; }, true); - paper.project.activeLayer.appendTop(path2); + paper.project.activeLayer.addChild(path2); equals(function() { return group._namedChildren['test'] === undefined; diff --git a/test/tests/Layer.js b/test/tests/Layer.js index 28533867..5935e1c3 100644 --- a/test/tests/Layer.js +++ b/test/tests/Layer.js @@ -15,14 +15,14 @@ test('previousSibling / nextSibling', function() { // previousSibling: var path = new Path(); var thirdLayer = new Layer(); - secondLayer.appendBottom(thirdLayer); + secondLayer.insertChild(0, thirdLayer); equals(function() { return secondLayer.children.length; }, 2); equals(function() { return thirdLayer.nextSibling == path; }, true); - secondLayer.appendTop(thirdLayer); + secondLayer.addChild(thirdLayer); equals(function() { return thirdLayer.nextSibling == null; }, true); @@ -33,17 +33,17 @@ test('previousSibling / nextSibling', function() { return project.layers.length == 2; }, true); - firstLayer.appendTop(secondLayer); + firstLayer.addChild(secondLayer); equals(function() { return project.layers.length == 1; }, true); }); -test('moveAbove / moveBelow', function() { +test('insertAbove / insertBelow', function() { var project = paper.project; var firstLayer = project.activeLayer; var secondLayer = new Layer(); - secondLayer.moveBelow(firstLayer); + secondLayer.insertBelow(firstLayer); equals(function() { return secondLayer.previousSibling == null; }, true); @@ -52,10 +52,10 @@ test('moveAbove / moveBelow', function() { }, true); var path = new Path(); - firstLayer.appendTop(path); + firstLayer.addChild(path); // move the layer above the path, inside the firstLayer: - secondLayer.moveAbove(path); + secondLayer.insertAbove(path); equals(function() { return secondLayer.previousSibling == path; }, true); @@ -68,7 +68,7 @@ test('moveAbove / moveBelow', function() { }, 1); }); -test('appendTop / appendBottom / nesting', function() { +test('addChild / appendBottom / nesting', function() { var project = paper.project; var firstLayer = project.activeLayer; var secondLayer = new Layer(); @@ -76,7 +76,7 @@ test('appendTop / appendBottom / nesting', function() { equals(function() { return project.layers.length; }, 2); - firstLayer.appendTop(secondLayer); + firstLayer.addChild(secondLayer); equals(function() { return secondLayer.parent == firstLayer; }, true); @@ -89,7 +89,7 @@ test('appendTop / appendBottom / nesting', function() { }, true); // Now move secondLayer bellow the first again, in which case it should // reappear in project.layers - secondLayer.moveBelow(firstLayer); + secondLayer.insertBelow(firstLayer); // There should be two layers now in project.layers again now equals(function() { return project.layers.length; diff --git a/test/tests/PathStyle.js b/test/tests/PathStyle.js index 1731030f..75465685 100644 --- a/test/tests/PathStyle.js +++ b/test/tests/PathStyle.js @@ -56,7 +56,7 @@ test('setting path styles to an object', function() { test('setting group styles to an object', function() { var group = new Group(); var path = new Path(); - group.appendTop(path); + group.addChild(path); group.style = { fillColor: 'red', strokeColor: 'green' @@ -69,13 +69,13 @@ test('getting group styles', function() { var group = new Group(); var path = new Path(); path.fillColor = 'red'; - group.appendTop(path); + group.addChild(path); compareRGBColors(group.fillColor, 'red', 'group.fillColor'); var secondPath = new Path(); secondPath.fillColor = 'black'; - group.appendTop(secondPath); + group.addChild(secondPath); // the group now contains two paths with different fillColors and therefore // should return undefined: @@ -92,12 +92,12 @@ test('setting group styles', function() { var group = new Group(); var path = new Path(); path.fillColor = 'red'; - group.appendTop(path); + group.addChild(path); var secondPath = new Path(); secondPath.fillColor = 'blue'; secondPath.strokeColor = 'red'; - group.appendTop(secondPath); + group.addChild(secondPath); // Change the fill color of the group: group.fillColor = 'black'; @@ -115,14 +115,14 @@ test('setting group styles 2', function() { var group = new Group(); var path = new Path(); path.fillColor = 'red'; - group.appendTop(path); + group.addChild(path); compareRGBColors(group.fillColor, 'red', 'group.fillColor'); var secondPath = new Path(); secondPath.fillColor = 'blue'; secondPath.strokeColor = 'red'; - group.appendTop(secondPath); + group.addChild(secondPath); compareRGBColors(secondPath.fillColor, 'blue', 'secondPath.fillColor'); compareRGBColors(secondPath.strokeColor, 'red', 'secondPath.strokeColor'); From e6ac8af3aa8fff962c680f284e7ccf888ebd2e87 Mon Sep 17 00:00:00 2001 From: Jonathan Puckey Date: Fri, 17 Jun 2011 16:59:24 +0200 Subject: [PATCH 2/2] Improve Item#children documentation. --- src/item/Item.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/item/Item.js b/src/item/Item.js index 136b6e14..6c85b7ea 100644 --- a/src/item/Item.js +++ b/src/item/Item.js @@ -403,6 +403,12 @@ var Item = this.Item = Base.extend({ * The children items contained within this item. Items that define a * {@link #name} can also be accessed by name. * + * Please note: The children array should not be modified directly + * using array functions. To remove single items from the children list, use + * {@link Item#remove()}, to remove all items from the children list, use + * {@link Item#removeChildren()}. To add items to the children list, use + * {@link Item#addChild(item)} or {@link Item#insertChild(index, item)}. + * * @type Item[] * @bean *