From 73d2c34088d75d182b40a48acf8c98c975899781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Thu, 17 Oct 2013 13:08:54 +0200 Subject: [PATCH] Implement item-level #equals() method and clean up other equals methods. --- src/basic/Matrix.js | 6 +++--- src/basic/Rectangle.js | 2 +- src/item/Item.js | 24 ++++++++++++++++++++++++ src/item/PlacedSymbol.js | 4 ++++ src/item/Raster.js | 4 ++++ src/item/Shape.js | 7 +++++++ src/path/Path.js | 4 ++++ src/path/Segment.js | 2 +- src/style/Color.js | 3 ++- src/style/Gradient.js | 6 ++++-- src/style/GradientStop.js | 2 +- src/style/Style.js | 6 ++++++ src/text/TextItem.js | 17 ++++++++++------- 13 files changed, 71 insertions(+), 16 deletions(-) diff --git a/src/basic/Matrix.js b/src/basic/Matrix.js index 375bbbbc..070db9db 100644 --- a/src/basic/Matrix.js +++ b/src/basic/Matrix.js @@ -112,9 +112,9 @@ var Matrix = Base.extend(/** @lends Matrix# */{ * @return {Boolean} {@true if the matrices are equal} */ equals: function(mx) { - return mx === this || mx && this._a == mx._a && this._b == mx._b - && this._c == mx._c && this._d == mx._d && this._tx == mx._tx - && this._ty == mx._ty + return mx === this || mx && this._a === mx._a && this._b === mx._b + && this._c === mx._c && this._d === mx._d + && this._tx === mx._tx && this._ty === mx._ty || false; }, diff --git a/src/basic/Rectangle.js b/src/basic/Rectangle.js index 6c00d89b..00efdaa5 100644 --- a/src/basic/Rectangle.js +++ b/src/basic/Rectangle.js @@ -205,7 +205,7 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{ rect = Rectangle.read(arguments); return rect === this || rect && this.x === rect.x && this.y === rect.y - && this.width === rect.width && this.height=== rect.height + && this.width === rect.width && this.height === rect.height || false; }, diff --git a/src/item/Item.js b/src/item/Item.js index a1573af2..14529515 100644 --- a/src/item/Item.js +++ b/src/item/Item.js @@ -1233,6 +1233,30 @@ var Item = Base.extend(Callback, /** @lends Item# */{ return this._parent ? this._parent.isInserted() : false; }, + equals: function(item) { + // Note: We do not compare name and selected state. + return item === this || item && this._class === item._class + && this._style.equals(item._style) + && this._matrix.equals(item._matrix) + && this._locked === item._locked + && this._visible === item._visible + && this._blendMode === item._blendMode + && this._opacity === item._opacity + && this._clipMask === item._clipMask + && this._guide === item._guide + && this._equals(item) + || false; + }, + + /** + * A private helper for #equals(), to be overridden in sub-classes. When it + * is called, item is always defined, of the same class as `this` and has + * equal general state attributes such as matrix, style, opacity, etc. + */ + _equals: function(item) { + return Base.equals(this._children, item._children); + }, + /** * Clones the item within the same project and places the copy above the * item. diff --git a/src/item/PlacedSymbol.js b/src/item/PlacedSymbol.js index e2304782..bc66aea2 100644 --- a/src/item/PlacedSymbol.js +++ b/src/item/PlacedSymbol.js @@ -79,6 +79,10 @@ var PlacedSymbol = Item.extend(/** @lends PlacedSymbol# */{ this.setSymbol(arg0 instanceof Symbol ? arg0 : new Symbol(arg0)); }, + _equals: function(item) { + return this._symbol === item._symbol; + }, + /** * The symbol that the placed symbol refers to. * diff --git a/src/item/Raster.js b/src/item/Raster.js index 6134e2dd..8daa6ac5 100644 --- a/src/item/Raster.js +++ b/src/item/Raster.js @@ -92,6 +92,10 @@ var Raster = Item.extend(/** @lends Raster# */{ this._size = new Size(); }, + _equals: function(item) { + return this.getSource() === item.getSource(); + }, + clone: function(insert) { var param = { insert: false }, image = this._image; diff --git a/src/item/Shape.js b/src/item/Shape.js index 104131ef..336ee538 100644 --- a/src/item/Shape.js +++ b/src/item/Shape.js @@ -31,6 +31,13 @@ var Shape = Item.extend(/** @lends Shape# */{ this._initialize(props, center); }, + _equals: function(item) { + return this._shape === item._shape + && this._size.equals(item._size) + // Radius can be a number or size: + && Base.equals(this._radius, item._radius); + }, + clone: function(insert) { return this._clone(new Shape(this._shape, this.getPosition(true), this._size.clone(), diff --git a/src/path/Path.js b/src/path/Path.js index 7c85d6fa..8853eee7 100644 --- a/src/path/Path.js +++ b/src/path/Path.js @@ -96,6 +96,10 @@ var Path = PathItem.extend(/** @lends Path# */{ this._initialize(!segments && arg); }, + _equals: function(item) { + return Base.equals(this._segments, item._segments); + }, + clone: function(insert) { var copy = this._clone(new Path({ segments: this._segments, diff --git a/src/path/Segment.js b/src/path/Segment.js index 20c4d0fa..82622896 100644 --- a/src/path/Segment.js +++ b/src/path/Segment.js @@ -478,7 +478,7 @@ var Segment = Base.extend(/** @lends Segment# */{ }, equals: function(segment) { - return segment === this || segment + return segment === this || segment && this._class === segment._class && this._point.equals(segment._point) && this._handleIn.equals(segment._handleIn) && this._handleOut.equals(segment._handleOut) diff --git a/src/style/Color.js b/src/style/Color.js index 01c33a14..c79f1124 100644 --- a/src/style/Color.js +++ b/src/style/Color.js @@ -740,7 +740,8 @@ var Color = Base.extend(new function() { equals: function(color) { if (Base.isPlainValue(color)) color = Color.read(arguments); - return color === this || color && this._type === color._type + return color === this || color && this._class === color._class + && this._type === color._type && this._alpha === color._alpha && Base.equals(this._components, color._components) || false; diff --git a/src/style/Gradient.js b/src/style/Gradient.js index af36bc45..d13b9dd9 100644 --- a/src/style/Gradient.js +++ b/src/style/Gradient.js @@ -180,8 +180,10 @@ var Gradient = Base.extend(/** @lends Gradient# */{ * @return {Boolean} {@true they are equal} */ equals: function(gradient) { - if (gradient && gradient.constructor == this.constructor - && this._stops.length == gradient._stops.length) { + if (gradient === this) + return true; + if (gradient && this._class === gradient._class + && this._stops.length === gradient._stops.length) { for (var i = 0, l = this._stops.length; i < l; i++) { if (!this._stops[i].equals(gradient._stops[i])) return false; diff --git a/src/style/GradientStop.js b/src/style/GradientStop.js index 63b6b2d9..fc1baae7 100644 --- a/src/style/GradientStop.js +++ b/src/style/GradientStop.js @@ -174,7 +174,7 @@ var GradientStop = Base.extend(/** @lends GradientStop# */{ }, equals: function(stop) { - return stop === this || stop instanceof GradientStop + return stop === this || stop && this._class === stop._class && this._color.equals(stop._color) && this._rampPoint == stop._rampPoint || false; diff --git a/src/style/Style.js b/src/style/Style.js index ffff0393..08654952 100644 --- a/src/style/Style.js +++ b/src/style/Style.js @@ -235,6 +235,12 @@ var Style = Base.extend(new function() { } }, + equals: function(style) { + return style === this || style && this._class === style._class + && Base.equals(this._values, style._values) + || false; + }, + getLeading: function getLeading() { // Override leading to return fontSize * 1.2 by default. var leading = getLeading.base.call(this); diff --git a/src/text/TextItem.js b/src/text/TextItem.js index ddab6695..af424ea0 100644 --- a/src/text/TextItem.js +++ b/src/text/TextItem.js @@ -44,11 +44,20 @@ var TextItem = Item.extend(/** @lends TextItem# */{ this._initialize(hasProps && arg, !hasProps && Point.read(arguments)); }, + _equals: function(item) { + return this._content === item._content; + }, + + _clone: function _clone(copy) { + copy.setContent(this._content); + return _clone.base.call(this, copy); + }, + /** * The text contents of the text item. * - * @name TextItem#content * @type String + * @bean * * @example {@paperscript} * // Setting the content of a PointText item: @@ -75,12 +84,6 @@ var TextItem = Item.extend(/** @lends TextItem# */{ * text.content = 'Your position is: ' + event.point.toString(); * } */ - - _clone: function _clone(copy) { - copy.setContent(this._content); - return _clone.base.call(this, copy); - }, - getContent: function() { return this._content; },