diff --git a/examples/JSON/Gradients.html b/examples/JSON/Gradients.html
index bf14c15a..f115312a 100644
--- a/examples/JSON/Gradients.html
+++ b/examples/JSON/Gradients.html
@@ -6,15 +6,20 @@
diff --git a/src/core/Base.js b/src/core/Base.js
index 05932ab0..b88f9f65 100644
--- a/src/core/Base.js
+++ b/src/core/Base.js
@@ -392,7 +392,7 @@ Base.inject(/** @lends Base# */{
* The passed json data is recoursively traversed and converted, leaves
* first
*/
- deserialize: function(json, create, _data) {
+ deserialize: function(json, create, _data, _isDictionary) {
var res = json,
isRoot = !_data;
// A _data side-car to deserialize that can hold any kind of
@@ -405,22 +405,24 @@ Base.inject(/** @lends Base# */{
// deserialize all elements of the array.
var type = json[0],
// Handle stored dictionary specially, since we need to
- // keep is a lookup table to retrieve referenced items from.
+ // keep a lookup table to retrieve referenced items from.
isDictionary = type === 'dictionary';
- if (!isDictionary) {
- // First see if this is perhaps a dictionary reference, and
- // if so return its definition instead.
- if (_data.dictionary && json.length == 1 && /^#/.test(type))
- return _data.dictionary[type];
- type = Base.exports[type];
- }
+ // First see if this is perhaps a dictionary reference, and
+ // if so return its definition instead.
+ if (json.length == 1 && /^#/.test(type))
+ return _data.dictionary[type];
+ type = Base.exports[type];
res = [];
+ // We need to set the dictionary object before further
+ // deserialization, because serialized symbols may contain
+ // references to serialized gradients
+ if (_isDictionary)
+ _data.dictionary = res;
// Skip first type entry for arguments
for (var i = type ? 1 : 0, l = json.length; i < l; i++)
- res.push(Base.deserialize(json[i], create, _data));
- if (isDictionary) {
- _data.dictionary = res[0];
- } else if (type) {
+ res.push(Base.deserialize(json[i], create, _data,
+ isDictionary));
+ if (type) {
// Create serialized type and pass collected arguments to
// constructor().
var args = res;
@@ -436,6 +438,9 @@ Base.inject(/** @lends Base# */{
}
} else if (Base.isPlainObject(json)) {
res = {};
+ // See above why we have to set this before Base.deserialize()
+ if (_isDictionary)
+ _data.dictionary = res;
for (var key in json)
res[key] = Base.deserialize(json[key], create, _data);
}
diff --git a/src/item/Item.js b/src/item/Item.js
index cd3ca661..6f2da27a 100644
--- a/src/item/Item.js
+++ b/src/item/Item.js
@@ -91,7 +91,7 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
// Allow setting another project than the currently active one.
project = hasProps && props.project || paper.project;
if (!internal)
- this._id = Item._id = (Item._id || 0) + 1;
+ this._id = UID.get();
// Inherit the applyMatrix setting from paper.settings.applyMatrix
this._applyMatrix = this._canApplyMatrix && paper.settings.applyMatrix;
// Handle matrix before everything else, to avoid issues with
diff --git a/src/paper.js b/src/paper.js
index 4368f234..2562d95f 100644
--- a/src/paper.js
+++ b/src/paper.js
@@ -51,6 +51,7 @@ var paper = new function(undefined) {
/*#*/ include('util/Formatter.js');
/*#*/ include('util/Numerical.js');
+/*#*/ include('util/UID.js');
// Include Paper classes, which are later injected into PaperScope by setting
// them on the 'this' object, e.g.:
diff --git a/src/path/CurveLocation.js b/src/path/CurveLocation.js
index 6c7c24bd..ea83c170 100644
--- a/src/path/CurveLocation.js
+++ b/src/path/CurveLocation.js
@@ -44,6 +44,9 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
initialize: function CurveLocation(curve, parameter, point, _curve2,
_parameter2, _point2, _distance) {
// Define this CurveLocation's unique id.
+ // NOTE: We do not use the same pool as the rest of the library here,
+ // since this is only required to be unique at runtime among other
+ // CurveLocation objects.
this._id = CurveLocation._id = (CurveLocation._id || 0) + 1;
this._curve = curve;
// Also store references to segment1 and segment2, in case path
diff --git a/src/project/Symbol.js b/src/project/Symbol.js
index a75f407a..1fa2d4de 100644
--- a/src/project/Symbol.js
+++ b/src/project/Symbol.js
@@ -61,7 +61,7 @@ var Symbol = Base.extend(/** @lends Symbol# */{
*/
initialize: function Symbol(item, dontCenter) {
// Define this Symbols's unique id.
- this._id = Symbol._id = (Symbol._id || 0) + 1;
+ this._id = UID.get();
this.project = paper.project;
this.project.symbols.push(this);
if (item)
diff --git a/src/style/Color.js b/src/style/Color.js
index 97ee5c1e..90d590c6 100644
--- a/src/style/Color.js
+++ b/src/style/Color.js
@@ -608,9 +608,6 @@ var Color = Base.extend(new function() {
}
// Default fallbacks: rgb, black
this._type = type || 'rgb';
- // Define this gradient Color's unique id.
- if (type === 'gradient')
- this._id = Color._id = (Color._id || 0) + 1;
if (!components) {
// Produce a components array now, and parse values. Even if no
// values are defined, parsers are still called to produce
diff --git a/src/style/Gradient.js b/src/style/Gradient.js
index 1f244f08..c739accc 100644
--- a/src/style/Gradient.js
+++ b/src/style/Gradient.js
@@ -66,8 +66,8 @@ var Gradient = Base.extend(/** @lends Gradient# */{
// DOCS: Document #initialize()
initialize: function Gradient(stops, radial) {
- // Define this Gradient's unique id.
- this._id = Gradient._id = (Gradient._id || 0) + 1;
+ // Use UID here since Gradients are exported through dictionary.add().
+ this._id = UID.get();
if (stops && this._set(stops))
stops = radial = null;
if (!this._stops)
diff --git a/src/util/UID.js b/src/util/UID.js
new file mode 100644
index 00000000..22725bfe
--- /dev/null
+++ b/src/util/UID.js
@@ -0,0 +1,30 @@
+/*
+ * Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
+ * http://paperjs.org/
+ *
+ * Copyright (c) 2011 - 2014, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ *
+ * Distributed under the MIT license. See LICENSE file for details.
+ *
+ * All rights reserved.
+ */
+
+/**
+ * @name UID
+ * @namespace
+ * @private
+ */
+var UID = {
+ _id: 1,
+
+ /**
+ * Returns the next unique id.
+ * @method get
+ * @return {Number} The next unique id
+ * @static
+ **/
+ get: function() {
+ return this._id++;
+ }
+};