diff --git a/src/ol/object.js b/src/ol/object.js index 4bca4e75ca..cbef3af6c6 100644 --- a/src/ol/object.js +++ b/src/ol/object.js @@ -10,6 +10,7 @@ goog.provide('ol.ObjectEventType'); goog.require('goog.array'); goog.require('goog.events'); +goog.require('goog.events.Event'); goog.require('goog.functions'); goog.require('goog.object'); goog.require('ol.Observable'); @@ -19,11 +20,34 @@ goog.require('ol.Observable'); * @enum {string} */ ol.ObjectEventType = { + BEFORECHANGE: 'beforechange', CHANGE: 'change' }; +/** + * Object representing a property change event. + * + * @param {string} type The event type. + * @param {string} key The property name. + * @extends {goog.events.Event} + * @constructor + */ +ol.ObjectEvent = function(type, key) { + goog.base(this, type); + + /** + * The name of the property whose value is changing. + * @type {string} + */ + this.key = key; + +}; +goog.inherits(ol.ObjectEvent, goog.events.Event); + + + /** * @constructor * @param {ol.Object} target @@ -331,7 +355,7 @@ ol.Object.prototype.notify = function(key) { ol.Object.prototype.notifyInternal_ = function(key) { var eventType = ol.Object.getChangeEventType(key); this.dispatchEvent(eventType); - this.dispatchEvent(ol.ObjectEventType.CHANGE); + this.dispatchEvent(new ol.ObjectEvent(ol.ObjectEventType.CHANGE, key)); }; @@ -342,6 +366,7 @@ ol.Object.prototype.notifyInternal_ = function(key) { * @todo stability experimental */ ol.Object.prototype.set = function(key, value) { + this.dispatchEvent(new ol.ObjectEvent(ol.ObjectEventType.BEFORECHANGE, key)); var accessors = ol.Object.getAccessors(this); if (accessors.hasOwnProperty(key)) { var accessor = accessors[key]; diff --git a/test/spec/ol/object.test.js b/test/spec/ol/object.test.js index 1c59d6f273..9a53c6d40f 100644 --- a/test/spec/ol/object.test.js +++ b/test/spec/ol/object.test.js @@ -121,7 +121,11 @@ describe('ol.Object', function() { it('dispatches generic change events to bound objects', function() { o.notify('k'); - expect(listener2).to.be.called(); + expect(listener2.calledOnce).to.be(true); + var args = listener2.firstCall.args; + expect(args).to.have.length(1); + var event = args[0]; + expect(event.key).to.be('k'); }); it('dispatches events to bound objects', function() { @@ -157,7 +161,25 @@ describe('ol.Object', function() { it('dispatches generic change events to object', function() { o.set('k', 1); - expect(listener2).to.be.called(); + expect(listener2.calledOnce).to.be(true); + var args = listener2.firstCall.args; + expect(args).to.have.length(1); + var event = args[0]; + expect(event.key).to.be('k'); + }); + + it('dispatches beforechange events to object', function() { + o.set('k', 1); + + var oldValue; + var beforeListener = sinon.spy(function(event) { + oldValue = o2.get(event.key); + }); + o.on('beforechange', beforeListener); + + o.set('k', 2); + expect(beforeListener.calledOnce).to.be(true); + expect(oldValue).to.be(1); }); it('dispatches events to bound object', function() { @@ -175,8 +197,32 @@ describe('ol.Object', function() { it('dispatches generic change events to object bound to', function() { o2.set('k', 2); - expect(listener2).to.be.called(); + expect(listener2.calledOnce).to.be(true); + var args = listener2.firstCall.args; + expect(args).to.have.length(1); + var event = args[0]; + expect(event.key).to.be('k'); }); + + it('dispatches beforechange before changing bound objects', function() { + o2.set('k', 1); + + var oldValue; + var beforeListener = sinon.spy(function(event) { + oldValue = o2.get(event.key); + }); + o.on('beforechange', beforeListener); + + o2.set('k', 2); + expect(beforeListener.calledOnce).to.be(true); + var args = listener2.firstCall.args; + expect(args).to.have.length(1); + var event = args[0]; + expect(event.key).to.be('k'); + + expect(oldValue).to.be(1); + }); + }); describe('bind', function() {