diff --git a/src/item/Item.js b/src/item/Item.js index 299c13cb..fd6c844a 100644 --- a/src/item/Item.js +++ b/src/item/Item.js @@ -105,10 +105,9 @@ var Item = Base.extend(Emitter, /** @lends Item# */{ // is false, or if the props are setting a different parent anyway. if (internal || hasProps && props.insert === false) { this._setProject(project); - } else if (hasProps && props.parent) { - props.parent.addChild(this); } else { - this._addToProject(project); + (hasProps && props.parent || project) + ._insertItem(undefined, this, true, true); } // Filter out Item.NO_INSERT before _set(), for performance reasons. if (hasProps && props !== Item.NO_INSERT) { @@ -122,16 +121,6 @@ var Item = Base.extend(Emitter, /** @lends Item# */{ return hasProps; }, - /* - * Private helper used in the constructor function to add the created item - * to the project scene graph. Overridden in Layer. - */ - _addToProject: function(project) { - // Create a new layer if there is no active one. This will - // automatically make it the new activeLayer. - (project._activeLayer || new Layer()).addChild(this); - }, - _events: Base.each(['onMouseDown', 'onMouseUp', 'onMouseDrag', 'onClick', 'onDoubleClick', 'onMouseMove', 'onMouseEnter', 'onMouseLeave'], function(name) { @@ -1540,20 +1529,6 @@ var Item = Base.extend(Emitter, /** @lends Item# */{ this.setName(name); }, - /** - * When passed a project, copies the item to the project, - * or duplicates it within the same project. When passed an item, - * copies the item into the specified item. - * - * @param {Project|Layer|Group|CompoundPath} owner the item or project to - * copy the item to - * @return {Item} the new copy of the item - */ - copyTo: function(owner) { - // Pass false fo insert, since we're inserting at a specific location. - return owner.addChild(this.clone(false)); - }, - /** * Rasterizes the item into a newly created Raster object. The item itself * is not removed after rasterization. @@ -2257,12 +2232,9 @@ var Item = Base.extend(Emitter, /** @lends Item# */{ return items; }, - // Private helper for #insertAbove() / #insertBelow() - _insertSibling: function(index, item, _preserve) { - return this._parent - ? this._parent.insertChild(index, item, _preserve) - : null; - }, + // Internal alias, so both Project and Item can be used in #copyTo(), and + // through _getOwner() in the various Item#insert*() methods. + _insertItem: '#insertChild', /** * Inserts this item above the specified item. @@ -2271,7 +2243,9 @@ var Item = Base.extend(Emitter, /** @lends Item# */{ * @return {Item} the inserted item, or `null` if inserting was not possible */ insertAbove: function(item, _preserve) { - return item._insertSibling(item._index + 1, this, _preserve); + var owner = item && item._getOwner(); + return owner ? owner._insertItem(item._index + 1, this, _preserve) + : null; }, /** @@ -2281,7 +2255,8 @@ var Item = Base.extend(Emitter, /** @lends Item# */{ * @return {Item} the inserted item, or `null` if inserting was not possible */ insertBelow: function(item, _preserve) { - return item._insertSibling(item._index, this, _preserve); + var owner = item && item._getOwner(); + return owner ? owner._insertItem(item._index, this, _preserve) : null; }, /** @@ -2289,7 +2264,7 @@ var Item = Base.extend(Emitter, /** @lends Item# */{ */ sendToBack: function() { var owner = this._getOwner(); - return owner ? owner.insertChild(0, this) : null; + return owner ? owner._insertItem(0, this) : null; }, /** @@ -2297,7 +2272,7 @@ var Item = Base.extend(Emitter, /** @lends Item# */{ */ bringToFront: function() { var owner = this._getOwner(); - return owner ? owner.addChild(this) : null; + return owner ? owner._insertItem(undefined, this) : null; }, /** @@ -2343,6 +2318,20 @@ var Item = Base.extend(Emitter, /** @lends Item# */{ */ moveBelow: '#insertBelow', + /** + * When passed a project, copies the item to the project, + * or duplicates it within the same project. When passed an item, + * copies the item into the specified item. + * + * @param {Project|Layer|Group|CompoundPath} owner the item or project to + * copy the item to + * @return {Item} the new copy of the item + */ + copyTo: function(owner) { + // Pass false for insert, since we're inserting at a specific location. + return owner._insertItem(undefined, this.clone(false)); + }, + /** * If this is a group, layer or compound-path with only one child-item, * the child-item is moved outside and the parent is erased. Otherwise, the diff --git a/src/item/Layer.js b/src/item/Layer.js index a830fe0b..0f69f7a7 100644 --- a/src/item/Layer.js +++ b/src/item/Layer.js @@ -66,16 +66,6 @@ var Layer = Group.extend(/** @lends Layer# */{ Group.apply(this, arguments); }, - /** - * Private helper used in the constructor function to add the newly created - * item to the project scene graph. - */ - _addToProject: function(project) { - project.addChild(this); - // When inserted, also activate the layer by default. - this.activate(); - }, - /** * Private helper to return the owner, either the parent, or the project * for top-level layers. @@ -132,15 +122,6 @@ var Layer = Group.extend(/** @lends Layer# */{ this._project._activeLayer = this; }, - // Private helper for #insertAbove() / #insertBelow() - _insertSibling: function _insertSibling(index, item, _preserve) { - // If the item is a layer and contained within Project#layers, use - // our own version of move(). - return !this._parent - ? this._project.insertChild(index, item, _preserve) - : _insertSibling.base.call(this, index, item, _preserve); - }, - _hitTestSelf: function() { return null; } diff --git a/src/project/Project.js b/src/project/Project.js index 06d654a5..940109e7 100644 --- a/src/project/Project.js +++ b/src/project/Project.js @@ -243,10 +243,7 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{ }, // TODO: Implement setSelectedItems? - // Project#insertChild() and #addChild() are helper functions called in - // Item#copyTo(), Layer#initialize(), Layer#_insertSibling() - // They are called the same as the functions on Item so duck-typing works. - insertChild: function(index, item, _preserve) { + insertLayer: function(index, item) { if (item instanceof Layer) { item._remove(false, true); Base.splice(this._children, [item], index, 0); @@ -258,22 +255,30 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{ // Also activate this layer if there was none before if (!this._activeLayer) this._activeLayer = item; - } else if (item instanceof Item) { - // Anything else than layers needs to be added to a layer first - (this._activeLayer - // NOTE: If there is no layer and this project is not the active - // one, passing insert: false and calling addChild on the - // project will handle it correctly. - || this.insertChild(index, new Layer(Item.NO_INSERT))) - .insertChild(index, item, _preserve); } else { item = null; } return item; }, - addChild: function(item, _preserve) { - return this.insertChild(undefined, item, _preserve); + addLayer: function(item) { + return this.insertLayer(undefined, item); + }, + + // Project#_insertItem() and Item#_insertItem() are helper functions called + // in Item#copyTo(), and through _getOwner() in the various Item#insert*() + // methods. They are called the same to facilitate so duck-typing. + _insertItem: function(index, item, _preserve, _created) { + item = this.insertLayer(index, item) + // Anything else than layers needs to be added to a layer first. + // If none exists yet, create one now, then add the item to it. + || (this._activeLayer || this._insertItem(undefined, + new Layer(Item.NO_INSERT), true, true)) + .insertChild(index, item, _preserve); + // If a layer was newly created, also activate it. + if (_created && item.activate) + item.activate(); + return item; }, _updateSelection: function(item) {