diff --git a/lib/bootstrap.js b/lib/bootstrap.js index f7466e99..6ca1eb4b 100644 --- a/lib/bootstrap.js +++ b/lib/bootstrap.js @@ -229,6 +229,38 @@ var Base = new function() { // Bootstrap scope }, new obj.constructor()); } + /** + * Checks if two values or objects are equals to each other, by using their + * equals() methods if available, and also comparing elements of arrays. + */ + function equals(obj1, obj2) { + if (obj1 == obj2 || obj1 != null && obj1.equals && obj1.equals(obj2)) + return true; + if (isArray(obj1) && isArray(obj2)) { + if (obj1.length !== obj2.length) + return false; + for (var i = 0, l = obj1.length; i < l; i++) { + if (!Base.equals(obj1, obj2)) + return false; + } + return true; + } else if (typeof obj1 === 'object' && typeof obj2 === 'object') { + function checkKeys(o1, o2) { + for (var i in o1) + if (typeof o2[i] === 'undefined') + return false; + return true; + } + if (!checkKeys(obj1, obj2) || !checkKeys(obj2, obj1)) + return false; + for (var i in obj1) + if (obj1.hasOwnProperty(i) && !Base.equals(obj1[i], obj2[i])) + return false; + return true; + } + return false; + } + // Inject into new ctor object that's passed to inject(), and then returned return inject(function() {}, { inject: function(src/*, ... */) { @@ -284,14 +316,6 @@ var Base = new function() { // Bootstrap scope // Pass true for enumerable, so inject() and extend() can be passed on // to subclasses of Base through Base.inject() / extend(). }, true).inject({ - /** - * Returns true if the object contains a property with the given name, - * false otherwise. - * Just like in .each, objects only contained in the prototype(s) are - * filtered. - */ - has: has, - /** * Injects the fields from the given object, adding this.base() * functionality @@ -330,6 +354,7 @@ var Base = new function() { // Bootstrap scope // Expose some local privates as Base generics. each: each, clone: clone, + equals: equals, // Base.create does something different from Object.create, it only // works on constructors and uses their prototype. create: function(ctor) { diff --git a/src/style/Style.js b/src/style/Style.js index d741ab92..409bd981 100644 --- a/src/style/Style.js +++ b/src/style/Style.js @@ -70,7 +70,7 @@ var Style = Item.extend({ }; Base.each(src._defaults, function(value, key) { - var isColor = !!key.match(/Color$/), + var isColor = /Color$/.test(key), part = Base.capitalize(key), set = 'set' + part, get = 'get' + part; @@ -85,8 +85,7 @@ var Style = Item.extend({ children[i][styleKey][set](value); } else { var old = this['_' + key]; - if (old != value && !(old && old.equals - && old.equals(value))) { + if (!Base.equals(old, value)) { if (isColor) { if (old) delete old._owner; @@ -115,8 +114,7 @@ var Style = Item.extend({ var childStyle = children[i][styleKey][get](); if (!style) { style = childStyle; - } else if (style != childStyle && !(style - && style.equals && style.equals(childStyle))) { + } else if (!Base.equals(style, childStyle)) { // If there is another item with a different // style, the style is not defined: // PORT: Change this in Scriptographer