From d6ff58305de50954fd68506f3cde4c411c0f72ac Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Tue, 19 Feb 2013 14:35:11 -0700 Subject: [PATCH] Using a dedicated object for value storage Without this, we are limited in the key names that we can accept from users. And because of compiler renaming, we don't know ahead of time what the limitations are (e.g. the key 'a' may clobber the 'set' method). --- src/ol/object.js | 21 +++++++++++++++------ test/spec/ol/object.test.js | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/ol/object.js b/src/ol/object.js index dbb5f95aea..af7a0a9edb 100644 --- a/src/ol/object.js +++ b/src/ol/object.js @@ -39,6 +39,13 @@ ol.ObjectProperty = { */ ol.Object = function(opt_values) { goog.base(this); + + /** + * @private + * @type {Object.} + */ + this.values_ = {}; + if (goog.isDef(opt_values)) { this.setValues(opt_values); } @@ -164,6 +171,7 @@ ol.Object.prototype.changed = goog.nullFunction; * @return {*} Value. */ ol.Object.prototype.get = function(key) { + var value; var accessors = ol.Object.getAccessors(this); if (accessors.hasOwnProperty(key)) { var accessor = accessors[key]; @@ -171,13 +179,14 @@ ol.Object.prototype.get = function(key) { var targetKey = accessor.key; var getterName = ol.Object.getGetterName(targetKey); if (target[getterName]) { - return target[getterName](); + value = target[getterName](); } else { - return target.get(targetKey); + value = target.get(targetKey); } - } else { - return this[key]; + } else if (this.values_.hasOwnProperty(key)) { + value = this.values_[key]; } + return value; }; @@ -225,7 +234,7 @@ ol.Object.prototype.set = function(key, value) { target.set(targetKey, value); } } else { - this[key] = value; + this.values_[key] = value; this.notifyInternal_(key); } }; @@ -266,7 +275,7 @@ ol.Object.prototype.unbind = function(key) { var value = this.get(key); var accessors = ol.Object.getAccessors(this); delete accessors[key]; - this[key] = value; + this.values_[key] = value; } }; diff --git a/test/spec/ol/object.test.js b/test/spec/ol/object.test.js index 3dd69c04e8..bb195088dd 100644 --- a/test/spec/ol/object.test.js +++ b/test/spec/ol/object.test.js @@ -34,6 +34,37 @@ describe('ol.Object', function() { }); }); + describe('#get()', function() { + + it('does not return values that are not explicitly set', function() { + var o = new ol.Object(); + expect(o.get('constructor')).toBeUndefined(); + expect(o.get('hasOwnProperty')).toBeUndefined(); + expect(o.get('isPrototypeOf')).toBeUndefined(); + expect(o.get('propertyIsEnumerable')).toBeUndefined(); + expect(o.get('toLocaleString')).toBeUndefined(); + expect(o.get('toString')).toBeUndefined(); + expect(o.get('valueOf')).toBeUndefined(); + }); + + }); + + describe('#set()', function() { + it('can be used with arbitrary names', function() { + var o = new ol.Object(); + + o.set('set', 'sat'); + expect(o.get('set')).toBe('sat'); + + o.set('get', 'got'); + expect(o.get('get')).toBe('got'); + + o.set('toString', 'string'); + expect(o.get('toString')).toBe('string'); + expect(typeof o.toString).toBe('function'); + }); + }); + describe('setValues', function() { it('sets multiple values at once', function() { @@ -309,7 +340,7 @@ describe('ol.Object', function() { describe('setter', function() { beforeEach(function() { o.setX = function(x) { - this.x = x; + this.set('x', x); }; spyOn(o, 'setX').andCallThrough(); }); @@ -327,8 +358,8 @@ describe('ol.Object', function() { var o2 = new ol.Object(); o2.bindTo('x', o); o2.set('x', 1); - expect(o.get('x')).toEqual(1); expect(o.setX).toHaveBeenCalled(); + expect(o.get('x')).toEqual(1); }); }); });