From 2cf6cd7a1474c48aab352e19b4aa4a75375ee74c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Tue, 16 Jun 2015 14:30:40 +0200 Subject: [PATCH] Correctly clone all attributes in Shape#toPath() and Path#toShape() Also write documentation for both methods. Closes #622. --- src/item/Item.js | 44 +++++++++++++++++++++++++++++--------------- src/item/Shape.js | 26 ++++++++++++++++++-------- src/path/Path.js | 22 +++++++++++++--------- src/text/TextItem.js | 4 ++-- 4 files changed, 62 insertions(+), 34 deletions(-) diff --git a/src/item/Item.js b/src/item/Item.js index 74591787..e1624125 100644 --- a/src/item/Item.js +++ b/src/item/Item.js @@ -1486,36 +1486,50 @@ var Item = Base.extend(Emitter, /** @lends Item# */{ return this._clone(new this.constructor(Item.NO_INSERT), insert); }, - _clone: function(copy, insert) { + /** + * Clones the item within the same project and places the copy above the + * item. + * + * @param {Boolean} [insert=true] specifies whether the copy should be + * inserted into the DOM. When set to {@code true}, it is inserted above the + * original. + * @return {Item} the newly cloned item + */ + _clone: function(copy, insert, includeMatrix) { + var keys = ['_locked', '_visible', '_blendMode', '_opacity', + '_clipMask', '_guide'], + children = this._children; // Copy over style copy.setStyle(this._style); - // If this item has children, clone and append each of them: - if (this._children) { - // Clone all children and add them to the copy. tell #addChild we're - // cloning, as needed by CompoundPath#insertChild(). - for (var i = 0, l = this._children.length; i < l; i++) - copy.addChild(this._children[i].clone(false), true); + // Clone all children and add them to the copy. tell #addChild we're + // cloning, as needed by CompoundPath#insertChild(). + for (var i = 0, l = children && children.length; i < l; i++) { + copy.addChild(children[i].clone(false), true); } - // Insert is true by default. - if (insert || insert === undefined) - copy.insertAbove(this); // Only copy over these fields if they are actually defined in 'this', // meaning the default value has been overwritten (default is on // prototype). - var keys = ['_locked', '_visible', '_blendMode', '_opacity', - '_clipMask', '_guide', '_applyMatrix']; for (var i = 0, l = keys.length; i < l; i++) { var key = keys[i]; if (this.hasOwnProperty(key)) copy[key] = this[key]; } // Use Matrix#initialize to easily copy over values. - copy._matrix.initialize(this._matrix); - // Copy over _data as well. - copy._data = this._data ? Base.clone(this._data) : null; + if (includeMatrix !== false) + copy._matrix.initialize(this._matrix); + // In case of Path#toShape(), we can't just set _applyMatrix as + // Shape won't allow it. Using the setter instead takes care of it. + // NOTE: This will also bake in the matrix that we just initialized, + // in case #applyMatrix is true. + copy.setApplyMatrix(this._applyMatrix); // Copy over the selection state, use setSelected so the item // is also added to Project#selectedItems if it is selected. copy.setSelected(this._selected); + // Copy over _data as well. + copy._data = this._data ? Base.clone(this._data) : null; + // Insert is true by default. + if (insert || insert === undefined) + copy.insertAbove(this); // Clone the name too, but make sure we're not overriding the original // in the same parent, by passing true for the unique parameter. if (this._name) diff --git a/src/item/Shape.js b/src/item/Shape.js index d970b11f..f999d5bf 100644 --- a/src/item/Shape.js +++ b/src/item/Shape.js @@ -157,19 +157,29 @@ var Shape = Item.extend(/** @lends Shape# */{ return false; }, - // DOCS: #toPath([insert=true]) + /** + * Creates a new path item with same geometry as this shape item, and + * inherits all settings from it, similar to {@link Item#clone()}. + * + * @param {Boolean} [insert=true] specifies whether the new path should be + * inserted into the DOM. When set to {@code true}, it is inserted above the + * shape item. + * @return {Shape} the newly created path item with the same geometry as + * this shape item. + * @see Path#toShape(insert) + */ toPath: function(insert) { - var path = new Path[Base.capitalize(this._type)]({ + var path = this._clone(new Path[Base.capitalize(this._type)]({ center: new Point(), size: this._size, radius: this._radius, insert: false - }); - path.setStyle(this._style); - path.transform(this._matrix); - // Insert is true by default. - if (insert || insert === undefined) - path.insertAbove(this); + }), insert); + // The created path will inherit #applyMatrix from this Shape, hence it + // will always be false. + // Respect the setting of paper.settings.applyMatrix for new paths: + if (paper.settings.applyMatrix) + path.setApplyMatrix(true); return path; }, diff --git a/src/path/Path.js b/src/path/Path.js index f8fd4d62..28b5b17f 100644 --- a/src/path/Path.js +++ b/src/path/Path.js @@ -1356,9 +1356,17 @@ var Path = PathItem.extend(/** @lends Path# */{ return this; }, - - // DOCS: toShape - + /** + * Attempts to create a new shape item with same geometry as this path item, + * and inherits all settings from it, similar to {@link Item#clone()}. + * + * @param {Boolean} [insert=true] specifies whether the new shape should be + * inserted into the DOM. When set to {@code true}, it is inserted above the + * path item. + * @return {Shape} the newly created shape item with the same geometry as + * this path item if it can be matched, {@code null} otherwise. + * @see Shape#toPath(insert) + */ toShape: function(insert) { if (!this._closed) return null; @@ -1419,18 +1427,14 @@ var Path = PathItem.extend(/** @lends Path# */{ if (type) { var center = this.getPosition(true), - shape = new type({ + shape = this._clone(new type({ center: center, size: size, radius: radius, insert: false - }); + }), insert, false); // Determine and apply the shape's angle of rotation. shape.rotate(topCenter.subtract(center).getAngle() + 90); - shape.setStyle(this._style); - // Insert is true by default. - if (insert || insert === undefined) - shape.insertAbove(this); return shape; } return null; diff --git a/src/text/TextItem.js b/src/text/TextItem.js index b3bb88ae..824bf561 100644 --- a/src/text/TextItem.js +++ b/src/text/TextItem.js @@ -50,9 +50,9 @@ var TextItem = Item.extend(/** @lends TextItem# */{ return this._content === item._content; }, - _clone: function _clone(copy, insert) { + _clone: function _clone(copy, insert, includeMatrix) { copy.setContent(this._content); - return _clone.base.call(this, copy, insert); + return _clone.base.call(this, copy, insert, includeMatrix); }, /**