diff --git a/src/color/Color.js b/src/color/Color.js index f5e1d2f2..ab16f827 100644 --- a/src/color/Color.js +++ b/src/color/Color.js @@ -354,35 +354,8 @@ var Color = this.Color = Base.extend(new function() { */ _changed: function() { this._cssString = null; - // Loop through the items that use this color and notify them about - // the style change, so they can redraw. - for (var i = 0, l = this._owners && this._owners.length; i < l; i++) - this._owners[i]._changed(Change.STYLE); - }, - - /** - * Called by PathStyle whenever this color is used to define an item's style - * This is required to pass on _changed() notifications to the _owners. - */ - _addOwner: function(item) { - if (!this._owners) - this._owners = []; - this._owners.push(item); - }, - - /** - * Called by PathStyle whenever this color stops being used to define an - * item's style. - * TODO: Should we remove owners that are not used anymore for good, e.g. - * in an Item#destroy() method? - */ - _removeOwner: function(item) { - var index = this._owners ? this._owners.indexOf(item) : -1; - if (index != -1) { - this._owners.splice(index, 1); - if (this._owners.length == 0) - delete this._owners; - } + if (this._owner) + this._owner._changed(Change.STYLE); }, /** diff --git a/src/color/Gradient.js b/src/color/Gradient.js index 6978c334..50783091 100644 --- a/src/color/Gradient.js +++ b/src/color/Gradient.js @@ -90,18 +90,17 @@ var Gradient = this.Gradient = Base.extend(/** @lends Gradient# */{ // If this gradient already contains stops, first remove // this gradient as their owner. if (this.stops) { - for (var i = 0, l = this._stops.length; i < l; i++) { - this._stops[i]._removeOwner(this); - } + for (var i = 0, l = this._stops.length; i < l; i++) + delete this._stops[i]._owner; } if (stops.length < 2) throw new Error( 'Gradient stop list needs to contain at least two stops.'); - this._stops = GradientStop.readAll(stops); + this._stops = GradientStop.readAll(stops, 0, true); // clone // Now reassign ramp points if they were not specified. for (var i = 0, l = this._stops.length; i < l; i++) { var stop = this._stops[i]; - stop._addOwner(this); + stop._owner = this; if (stop._defaultRamp) stop.setRampPoint(i / (l - 1)); } diff --git a/src/color/GradientStop.js b/src/color/GradientStop.js index d186eb66..40326cf2 100644 --- a/src/color/GradientStop.js +++ b/src/color/GradientStop.js @@ -59,33 +59,10 @@ var GradientStop = this.GradientStop = Base.extend(/** @lends GradientStop# */{ // Loop through the gradients that use this stop and notify them about // the change, so they can notify their gradient colors, which in turn // will notify the items they are used in: - for (var i = 0, l = this._owners && this._owners.length; i < l; i++) - this._owners[i]._changed(Change.STYLE); + if (this._owner) + this._owner._changed(Change.STYLE); }, - /** - * Called by Gradient whenever this stop is used. This is required to pass - * on _changed() notifications to the _owners. - */ - _addOwner: function(gradient) { - if (!this._owners) - this._owners = []; - this._owners.push(gradient); - }, - - /** - * Called by Gradient whenever this GradientStop is no longer used by it. - */ - _removeOwner: function(gradient) { - var index = this._owners ? this._owners.indexOf(gradient) : -1; - if (index != -1) { - this._owners.splice(index, 1); - if (this._owners.length == 0) - delete this._owners; - } - }, - - /** * The ramp-point of the gradient stop as a value between {@code 0} and * {@code 1}. @@ -165,12 +142,12 @@ var GradientStop = this.GradientStop = Base.extend(/** @lends GradientStop# */{ }, setColor: function(color) { - // If the stop already contained a color, - // remove it as an owner: - if (this._color) - this._color._removeOwner(this); + // Make sure newly set colors are cloned, since they can only have + // one owner. this._color = Color.read(arguments); - this._color._addOwner(this); + if (this._color === color) + this._color = color.clone(); + this._color._owner = this; this._changed(); }, diff --git a/src/style/Style.js b/src/style/Style.js index fe41600d..32540d56 100644 --- a/src/style/Style.js +++ b/src/style/Style.js @@ -70,7 +70,8 @@ var Style = Item.extend({ // injected into this class using this.base() further down. src[set] = function(value) { var children = this._item && this._item._children; - value = isColor ? Color.read(arguments) : value; + // Clone color objects since they reference their owner + value = isColor ? Color.read(arguments, 0, 0, true) : value; if (children) { for (var i = 0, l = children.length; i < l; i++) children[i][styleKey][set](value); @@ -78,13 +79,14 @@ var Style = Item.extend({ var old = this['_' + key]; if (old != value && !(old && old.equals && old.equals(value))) { - this['_' + key] = value; if (isColor) { if (old) - old._removeOwner(this._item); - if (value) - value._addOwner(this._item); + delete old._owner; + if (value) { + value._owner = this._item; + } } + this['_' + key] = value; // Notify the item of the style change STYLE is // always set, additional flags come from _flags, // as used for STROKE: