mirror of
https://github.com/konvajs/konva.git
synced 2025-06-28 15:23:44 +08:00
bug fix - when setting a custom attr that points to self, the setAttrs method no longer gets stuck in a recursive loop throwing a stack overflow error. Also, objects that were instantiated from a class (non-literal objects) are no longer serializable
This commit is contained in:
parent
fd6bdb570c
commit
44ba6f7e5b
26
dist/kinetic-core.js
vendored
26
dist/kinetic-core.js
vendored
@ -148,7 +148,7 @@ Kinetic.GlobalObject = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
* utilities
|
* cherry-picked and modified utilities from underscore.js
|
||||||
*/
|
*/
|
||||||
_isElement: function(obj) {
|
_isElement: function(obj) {
|
||||||
return !!(obj && obj.nodeType == 1);
|
return !!(obj && obj.nodeType == 1);
|
||||||
@ -166,6 +166,14 @@ Kinetic.GlobalObject = {
|
|||||||
_isNumber: function(obj) {
|
_isNumber: function(obj) {
|
||||||
return toString.call(obj) == '[object Number]';
|
return toString.call(obj) == '[object Number]';
|
||||||
},
|
},
|
||||||
|
_hasMethods: function(obj) {
|
||||||
|
var names = [];
|
||||||
|
for(var key in obj) {
|
||||||
|
if(this._isFunction(obj[key]))
|
||||||
|
names.push(key);
|
||||||
|
}
|
||||||
|
return names.length > 0;
|
||||||
|
},
|
||||||
/*
|
/*
|
||||||
* The argument can be:
|
* The argument can be:
|
||||||
* - an integer (will be applied to both x and y)
|
* - an integer (will be applied to both x and y)
|
||||||
@ -513,10 +521,10 @@ Kinetic.Node.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if property is an object, then add an empty object
|
* if property is a pure object (no methods), then add an empty object
|
||||||
* to the node and then traverse
|
* to the node and then traverse
|
||||||
*/
|
*/
|
||||||
if(go._isObject(val) && !go._isArray(val) && !go._isElement(val)) {
|
if(go._isObject(val) && !go._isArray(val) && !go._isElement(val) && !go._hasMethods(val)) {
|
||||||
if(obj[key] === undefined) {
|
if(obj[key] === undefined) {
|
||||||
obj[key] = {};
|
obj[key] = {};
|
||||||
}
|
}
|
||||||
@ -1628,12 +1636,12 @@ Kinetic.Stage.prototype = {
|
|||||||
|
|
||||||
var cleanAttrs = node.attrs;
|
var cleanAttrs = node.attrs;
|
||||||
|
|
||||||
// remove function, image, and DOM attrs
|
// remove function, image, DOM, and objects with methods
|
||||||
for (var key in cleanAttrs) {
|
for(var key in cleanAttrs) {
|
||||||
var val = cleanAttrs[key];
|
var val = cleanAttrs[key];
|
||||||
if (go._isFunction(val) || go._isElement(val)) {
|
if(go._isFunction(val) || go._isElement(val) || go._hasMethods(val)) {
|
||||||
cleanAttrs[key] = undefined;
|
cleanAttrs[key] = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.attrs = cleanAttrs;
|
obj.attrs = cleanAttrs;
|
||||||
|
4
dist/kinetic-core.min.js
vendored
4
dist/kinetic-core.min.js
vendored
File diff suppressed because one or more lines are too long
@ -120,7 +120,7 @@ Kinetic.GlobalObject = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
* utilities
|
* cherry-picked and modified utilities from underscore.js
|
||||||
*/
|
*/
|
||||||
_isElement: function(obj) {
|
_isElement: function(obj) {
|
||||||
return !!(obj && obj.nodeType == 1);
|
return !!(obj && obj.nodeType == 1);
|
||||||
@ -138,6 +138,14 @@ Kinetic.GlobalObject = {
|
|||||||
_isNumber: function(obj) {
|
_isNumber: function(obj) {
|
||||||
return toString.call(obj) == '[object Number]';
|
return toString.call(obj) == '[object Number]';
|
||||||
},
|
},
|
||||||
|
_hasMethods: function(obj) {
|
||||||
|
var names = [];
|
||||||
|
for(var key in obj) {
|
||||||
|
if(this._isFunction(obj[key]))
|
||||||
|
names.push(key);
|
||||||
|
}
|
||||||
|
return names.length > 0;
|
||||||
|
},
|
||||||
/*
|
/*
|
||||||
* The argument can be:
|
* The argument can be:
|
||||||
* - an integer (will be applied to both x and y)
|
* - an integer (will be applied to both x and y)
|
||||||
|
@ -157,10 +157,10 @@ Kinetic.Node.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if property is an object, then add an empty object
|
* if property is a pure object (no methods), then add an empty object
|
||||||
* to the node and then traverse
|
* to the node and then traverse
|
||||||
*/
|
*/
|
||||||
if(go._isObject(val) && !go._isArray(val) && !go._isElement(val)) {
|
if(go._isObject(val) && !go._isArray(val) && !go._isElement(val) && !go._hasMethods(val)) {
|
||||||
if(obj[key] === undefined) {
|
if(obj[key] === undefined) {
|
||||||
obj[key] = {};
|
obj[key] = {};
|
||||||
}
|
}
|
||||||
|
12
src/Stage.js
12
src/Stage.js
@ -185,12 +185,12 @@ Kinetic.Stage.prototype = {
|
|||||||
|
|
||||||
var cleanAttrs = node.attrs;
|
var cleanAttrs = node.attrs;
|
||||||
|
|
||||||
// remove function, image, and DOM attrs
|
// remove function, image, DOM, and objects with methods
|
||||||
for (var key in cleanAttrs) {
|
for(var key in cleanAttrs) {
|
||||||
var val = cleanAttrs[key];
|
var val = cleanAttrs[key];
|
||||||
if (go._isFunction(val) || go._isElement(val)) {
|
if(go._isFunction(val) || go._isElement(val) || go._hasMethods(val)) {
|
||||||
cleanAttrs[key] = undefined;
|
cleanAttrs[key] = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.attrs = cleanAttrs;
|
obj.attrs = cleanAttrs;
|
||||||
|
@ -1167,6 +1167,47 @@ Test.prototype.tests = {
|
|||||||
});
|
});
|
||||||
//stage.start();
|
//stage.start();
|
||||||
},
|
},
|
||||||
|
'SHAPE - add shape with custom attr pointing to self': function(containerId) {
|
||||||
|
var stage = new Kinetic.Stage({
|
||||||
|
container: containerId,
|
||||||
|
width: 578,
|
||||||
|
height: 200
|
||||||
|
});
|
||||||
|
var layer = new Kinetic.Layer();
|
||||||
|
circle = new Kinetic.Circle({
|
||||||
|
x: stage.getWidth() / 2,
|
||||||
|
y: stage.getHeight() / 2,
|
||||||
|
radius: 70,
|
||||||
|
fill: 'green',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 4,
|
||||||
|
centerOffset: {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
},
|
||||||
|
scale: {
|
||||||
|
x: 2,
|
||||||
|
y: 2
|
||||||
|
}
|
||||||
|
});
|
||||||
|
layer.add(circle);
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add custom attr that points to self. The setAttrs method should
|
||||||
|
* not inifinitely recurse causing a stack overflow
|
||||||
|
*/
|
||||||
|
circle.setAttrs({
|
||||||
|
self: circle
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* serialize the stage. The json should succeed because objects that have
|
||||||
|
* methods, such as self, are not serialized, and will therefore avoid
|
||||||
|
* circular json errors.
|
||||||
|
*/
|
||||||
|
var json = stage.toJSON();
|
||||||
|
},
|
||||||
'SHAPE - set fill after instantiation': function(containerId) {
|
'SHAPE - set fill after instantiation': function(containerId) {
|
||||||
var stage = new Kinetic.Stage({
|
var stage = new Kinetic.Stage({
|
||||||
container: containerId,
|
container: containerId,
|
||||||
|
Loading…
Reference in New Issue
Block a user