initialize: function( initial, options ) {
this._value = initial; // @todo: potentially change this to a this.set() call.
this.callbacks = $.Callbacks();
+ this._dirty = false;
$.extend( this, options || {} );
to = this.validate( to );
// Bail if the sanitized value is null or unchanged.
- if ( null === to || this._value === to )
+ if ( null === to || _.isEqual( from, to ) ) {
return this;
+ }
this._value = to;
+ this._dirty = true;
this.callbacks.fireWith( this, [ to, from ] );
if ( this.element.is('input') ) {
type = this.element.prop('type');
- if ( api.Element.synchronizer[ type ] )
+ if ( api.Element.synchronizer[ type ] ) {
synchronizer = api.Element.synchronizer[ type ];
- if ( 'text' === type || 'password' === type )
+ }
+ if ( 'text' === type || 'password' === type ) {
this.events += ' keyup';
+ } else if ( 'range' === type ) {
+ this.events += ' input propertychange';
+ }
} else if ( this.element.is('textarea') ) {
this.events += ' keyup';
}
this.add( 'channel', params.channel );
this.add( 'url', params.url || '' );
- this.add( 'targetWindow', params.targetWindow || defaultTarget );
this.add( 'origin', this.url() ).link( this.url ).setter( function( to ) {
return to.replace( /([^:]+:\/\/[^\/]+).*/, '$1' );
});
+ // first add with no value
+ this.add( 'targetWindow', null );
+ // This avoids SecurityErrors when setting a window object in x-origin iframe'd scenarios.
+ this.targetWindow.set = function( to ) {
+ var from = this._value;
+
+ to = this._setter.apply( this, arguments );
+ to = this.validate( to );
+
+ if ( null === to || from === to ) {
+ return this;
+ }
+
+ this._value = to;
+ this._dirty = true;
+
+ this.callbacks.fireWith( this, [ to, from ] );
+
+ return this;
+ };
+ // now set it
+ this.targetWindow( params.targetWindow || defaultTarget );
+
+
// Since we want jQuery to treat the receive function as unique
// to this instance, we give the function a new guid.
//