mirror of
https://github.com/jquery/jquery-ui.git
synced 2024-11-21 11:04:24 +00:00
Widget: Allow redefining a widget after other widgets have inherited from it.
This commit is contained in:
parent
e496cde384
commit
8cd4a8330c
@ -281,7 +281,7 @@ test( "enable", function() {
|
|||||||
|
|
||||||
var element = $( "#tabs1" ).tabs({
|
var element = $( "#tabs1" ).tabs({
|
||||||
disabled: [ 0, 1 ],
|
disabled: [ 0, 1 ],
|
||||||
enable: function ( event, ui ) {
|
enable: function( event, ui ) {
|
||||||
equals( ui.tab, element.find( ".ui-tabs-nav a" )[ 1 ], "ui.tab" );
|
equals( ui.tab, element.find( ".ui-tabs-nav a" )[ 1 ], "ui.tab" );
|
||||||
equals( ui.panel, element.find( ".ui-tabs-panel" )[ 1 ], "ui.panel" );
|
equals( ui.panel, element.find( ".ui-tabs-panel" )[ 1 ], "ui.panel" );
|
||||||
equals( ui.index, 1, "ui.index" );
|
equals( ui.index, 1, "ui.index" );
|
||||||
@ -296,7 +296,7 @@ test( "disable", function() {
|
|||||||
expect( 3 );
|
expect( 3 );
|
||||||
|
|
||||||
var element = $( "#tabs1" ).tabs({
|
var element = $( "#tabs1" ).tabs({
|
||||||
disable: function ( event, ui ) {
|
disable: function( event, ui ) {
|
||||||
equals( ui.tab, element.find( ".ui-tabs-nav a" )[ 1 ], "ui.tab" );
|
equals( ui.tab, element.find( ".ui-tabs-nav a" )[ 1 ], "ui.tab" );
|
||||||
equals( ui.panel, element.find( ".ui-tabs-panel" )[ 1 ], "ui.panel" );
|
equals( ui.panel, element.find( ".ui-tabs-panel" )[ 1 ], "ui.panel" );
|
||||||
equals( ui.index, 1, "ui.index" );
|
equals( ui.index, 1, "ui.index" );
|
||||||
|
@ -1050,11 +1050,54 @@ test( "redefine", function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var instance = new $.ui.testWidget();
|
var instance = new $.ui.testWidget({});
|
||||||
instance.method( "foo" );
|
instance.method( "foo" );
|
||||||
equal( $.ui.testWidget.foo, "bar", "static properties remain" );
|
equal( $.ui.testWidget.foo, "bar", "static properties remain" );
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test( "redefine deep prototype chain", function() {
|
||||||
|
expect( 8 );
|
||||||
|
$.widget( "ui.testWidget", {
|
||||||
|
method: function( str ) {
|
||||||
|
strictEqual( this, instance, "original invoked with correct this" );
|
||||||
|
equal( str, "level 4", "original invoked with correct parameter" );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$.widget( "ui.testWidget2", $.ui.testWidget, {
|
||||||
|
method: function( str ) {
|
||||||
|
strictEqual( this, instance, "testWidget2 invoked with correct this" );
|
||||||
|
equal( str, "level 2", "testWidget2 invoked with correct parameter" );
|
||||||
|
this._super( "level 3" );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$.widget( "ui.testWidget3", $.ui.testWidget2, {
|
||||||
|
method: function( str ) {
|
||||||
|
strictEqual( this, instance, "testWidget3 invoked with correct this" );
|
||||||
|
equal( str, "level 1", "testWidget3 invoked with correct parameter" );
|
||||||
|
this._super( "level 2" );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// redefine testWidget after other widgets have inherited from it
|
||||||
|
// this tests whether the inheriting widgets get updated prototype chains
|
||||||
|
$.widget( "ui.testWidget", $.ui.testWidget, {
|
||||||
|
method: function( str ) {
|
||||||
|
strictEqual( this, instance, "new invoked with correct this" );
|
||||||
|
equal( str, "level 3", "new invoked with correct parameter" );
|
||||||
|
this._super( "level 4" );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// redefine testWidget3 after it has been automatically redefined
|
||||||
|
// this tests whether we properly handle _super() when the topmost prototype
|
||||||
|
// doesn't have the method defined
|
||||||
|
$.widget( "ui.testWidget3", $.ui.testWidget3, {} );
|
||||||
|
|
||||||
|
var instance = new $.ui.testWidget3({});
|
||||||
|
instance.method( "level 1" );
|
||||||
|
|
||||||
|
delete $.ui.testWidget3;
|
||||||
|
delete $.ui.testWidget2;
|
||||||
|
});
|
||||||
|
|
||||||
asyncTest( "_delay", function() {
|
asyncTest( "_delay", function() {
|
||||||
expect( 6 );
|
expect( 6 );
|
||||||
var order = 0,
|
var order = 0,
|
||||||
|
192
ui/jquery.ui.tabs.js
vendored
192
ui/jquery.ui.tabs.js
vendored
@ -596,27 +596,21 @@ if ( $.uiBackCompat !== false ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// url method
|
// url method
|
||||||
(function( $, prototype ) {
|
$.widget( "ui.tabs", $.ui.tabs, {
|
||||||
prototype.url = function( index, url ) {
|
url: function( index, url ) {
|
||||||
this.anchors.eq( index ).attr( "href", url );
|
this.anchors.eq( index ).attr( "href", url );
|
||||||
};
|
}
|
||||||
}( jQuery, jQuery.ui.tabs.prototype ) );
|
|
||||||
|
|
||||||
// ajaxOptions and cache options
|
|
||||||
(function( $, prototype ) {
|
|
||||||
$.extend( prototype.options, {
|
|
||||||
ajaxOptions: null,
|
|
||||||
cache: false
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var _create = prototype._create,
|
// ajaxOptions and cache options
|
||||||
_setOption = prototype._setOption,
|
$.widget( "ui.tabs", $.ui.tabs, {
|
||||||
_destroy = prototype._destroy,
|
options: {
|
||||||
oldurl = prototype.url || $.noop;
|
ajaxOptions: null,
|
||||||
|
cache: false
|
||||||
|
},
|
||||||
|
|
||||||
$.extend( prototype, {
|
|
||||||
_create: function() {
|
_create: function() {
|
||||||
_create.call( this );
|
this._super();
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
@ -653,29 +647,28 @@ if ( $.uiBackCompat !== false ) {
|
|||||||
if ( key === "cache" && value === false ) {
|
if ( key === "cache" && value === false ) {
|
||||||
this.anchors.removeData( "cache.tabs" );
|
this.anchors.removeData( "cache.tabs" );
|
||||||
}
|
}
|
||||||
_setOption.apply( this, arguments );
|
this._super( key, value );
|
||||||
},
|
},
|
||||||
|
|
||||||
_destroy: function() {
|
_destroy: function() {
|
||||||
this.anchors.removeData( "cache.tabs" );
|
this.anchors.removeData( "cache.tabs" );
|
||||||
_destroy.call( this );
|
this._super();
|
||||||
},
|
},
|
||||||
|
|
||||||
url: function( index, url ){
|
url: function( index, url ){
|
||||||
this.anchors.eq( index ).removeData( "cache.tabs" );
|
this.anchors.eq( index ).removeData( "cache.tabs" );
|
||||||
oldurl.apply( this, arguments );
|
this._superApply( arguments );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}( jQuery, jQuery.ui.tabs.prototype ) );
|
|
||||||
|
|
||||||
// abort method
|
// abort method
|
||||||
(function( $, prototype ) {
|
$.widget( "ui.tabs", $.ui.tabs, {
|
||||||
prototype.abort = function() {
|
abort: function() {
|
||||||
if ( this.xhr ) {
|
if ( this.xhr ) {
|
||||||
this.xhr.abort();
|
this.xhr.abort();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}( jQuery, jQuery.ui.tabs.prototype ) );
|
});
|
||||||
|
|
||||||
// spinner
|
// spinner
|
||||||
$.widget( "ui.tabs", $.ui.tabs, {
|
$.widget( "ui.tabs", $.ui.tabs, {
|
||||||
@ -702,16 +695,13 @@ if ( $.uiBackCompat !== false ) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// enable/disable events
|
// enable/disable events
|
||||||
(function( $, prototype ) {
|
$.widget( "ui.tabs", $.ui.tabs, {
|
||||||
$.extend( prototype.options, {
|
options: {
|
||||||
enable: null,
|
enable: null,
|
||||||
disable: null
|
disable: null
|
||||||
});
|
},
|
||||||
|
|
||||||
var enable = prototype.enable,
|
enable: function( index ) {
|
||||||
disable = prototype.disable;
|
|
||||||
|
|
||||||
prototype.enable = function( index ) {
|
|
||||||
var options = this.options,
|
var options = this.options,
|
||||||
trigger;
|
trigger;
|
||||||
|
|
||||||
@ -720,14 +710,14 @@ if ( $.uiBackCompat !== false ) {
|
|||||||
trigger = true;
|
trigger = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
enable.apply( this, arguments );
|
this._superApply( arguments );
|
||||||
|
|
||||||
if ( trigger ) {
|
if ( trigger ) {
|
||||||
this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
|
this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
prototype.disable = function( index ) {
|
disable: function( index ) {
|
||||||
var options = this.options,
|
var options = this.options,
|
||||||
trigger;
|
trigger;
|
||||||
|
|
||||||
@ -736,23 +726,23 @@ if ( $.uiBackCompat !== false ) {
|
|||||||
trigger = true;
|
trigger = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
disable.apply( this, arguments );
|
this._superApply( arguments );
|
||||||
|
|
||||||
if ( trigger ) {
|
if ( trigger ) {
|
||||||
this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
|
this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}( jQuery, jQuery.ui.tabs.prototype ) );
|
});
|
||||||
|
|
||||||
// add/remove methods and events
|
// add/remove methods and events
|
||||||
(function( $, prototype ) {
|
$.widget( "ui.tabs", $.ui.tabs, {
|
||||||
$.extend( prototype.options, {
|
options: {
|
||||||
add: null,
|
add: null,
|
||||||
remove: null,
|
remove: null,
|
||||||
tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
|
tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
|
||||||
});
|
},
|
||||||
|
|
||||||
prototype.add = function( url, label, index ) {
|
add: function( url, label, index ) {
|
||||||
if ( index === undefined ) {
|
if ( index === undefined ) {
|
||||||
index = this.anchors.length;
|
index = this.anchors.length;
|
||||||
}
|
}
|
||||||
@ -803,9 +793,9 @@ if ( $.uiBackCompat !== false ) {
|
|||||||
|
|
||||||
this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
|
this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
|
||||||
return this;
|
return this;
|
||||||
};
|
},
|
||||||
|
|
||||||
prototype.remove = function( index ) {
|
remove: function( index ) {
|
||||||
index = this._getIndex( index );
|
index = this._getIndex( index );
|
||||||
var options = this.options,
|
var options = this.options,
|
||||||
tab = this.lis.eq( index ).remove(),
|
tab = this.lis.eq( index ).remove(),
|
||||||
@ -832,125 +822,117 @@ if ( $.uiBackCompat !== false ) {
|
|||||||
|
|
||||||
this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) );
|
this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) );
|
||||||
return this;
|
return this;
|
||||||
};
|
}
|
||||||
}( jQuery, jQuery.ui.tabs.prototype ) );
|
|
||||||
|
|
||||||
// length method
|
|
||||||
(function( $, prototype ) {
|
|
||||||
prototype.length = function() {
|
|
||||||
return this.anchors.length;
|
|
||||||
};
|
|
||||||
}( jQuery, jQuery.ui.tabs.prototype ) );
|
|
||||||
|
|
||||||
// panel ids (idPrefix option + title attribute)
|
|
||||||
(function( $, prototype ) {
|
|
||||||
$.extend( prototype.options, {
|
|
||||||
idPrefix: "ui-tabs-"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var _tabId = prototype._tabId;
|
// length method
|
||||||
prototype._tabId = function( a ) {
|
$.widget( "ui.tabs", $.ui.tabs, {
|
||||||
|
length: function() {
|
||||||
|
return this.anchors.length;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// panel ids (idPrefix option + title attribute)
|
||||||
|
$.widget( "ui.tabs", $.ui.tabs, {
|
||||||
|
options: {
|
||||||
|
idPrefix: "ui-tabs-"
|
||||||
|
},
|
||||||
|
|
||||||
|
_tabId: function( a ) {
|
||||||
return $( a ).attr( "aria-controls" ) ||
|
return $( a ).attr( "aria-controls" ) ||
|
||||||
a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
|
a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
|
||||||
this.options.idPrefix + getNextTabId();
|
this.options.idPrefix + getNextTabId();
|
||||||
};
|
}
|
||||||
}( jQuery, jQuery.ui.tabs.prototype ) );
|
|
||||||
|
|
||||||
// _createPanel method
|
|
||||||
(function( $, prototype ) {
|
|
||||||
$.extend( prototype.options, {
|
|
||||||
panelTemplate: "<div></div>"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var _createPanel = prototype._createPanel;
|
// _createPanel method
|
||||||
prototype._createPanel = function( id ) {
|
$.widget( "ui.tabs", $.ui.tabs, {
|
||||||
|
options: {
|
||||||
|
panelTemplate: "<div></div>"
|
||||||
|
},
|
||||||
|
|
||||||
|
_createPanel: function( id ) {
|
||||||
return $( this.options.panelTemplate )
|
return $( this.options.panelTemplate )
|
||||||
.attr( "id", id )
|
.attr( "id", id )
|
||||||
.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
|
.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
|
||||||
.data( "destroy.tabs", true );
|
.data( "destroy.tabs", true );
|
||||||
};
|
}
|
||||||
}( jQuery, jQuery.ui.tabs.prototype ) );
|
});
|
||||||
|
|
||||||
// selected option
|
// selected option
|
||||||
(function( $, prototype ) {
|
$.widget( "ui.tabs", $.ui.tabs, {
|
||||||
var _create = prototype._create,
|
_create: function() {
|
||||||
_setOption = prototype._setOption,
|
|
||||||
_eventHandler = prototype._eventHandler;
|
|
||||||
|
|
||||||
prototype._create = function() {
|
|
||||||
var options = this.options;
|
var options = this.options;
|
||||||
if ( options.active === null && options.selected !== undefined ) {
|
if ( options.active === null && options.selected !== undefined ) {
|
||||||
options.active = options.selected === -1 ? false : options.selected;
|
options.active = options.selected === -1 ? false : options.selected;
|
||||||
}
|
}
|
||||||
_create.call( this );
|
this._super();
|
||||||
options.selected = options.active;
|
options.selected = options.active;
|
||||||
if ( options.selected === false ) {
|
if ( options.selected === false ) {
|
||||||
options.selected = -1;
|
options.selected = -1;
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
prototype._setOption = function( key, value ) {
|
_setOption: function( key, value ) {
|
||||||
if ( key !== "selected" ) {
|
if ( key !== "selected" ) {
|
||||||
return _setOption.apply( this, arguments );
|
return this._super( key, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
var options = this.options;
|
var options = this.options;
|
||||||
_setOption.call( this, "active", value === -1 ? false : value );
|
this._super( "active", value === -1 ? false : value );
|
||||||
options.selected = options.active;
|
options.selected = options.active;
|
||||||
if ( options.selected === false ) {
|
if ( options.selected === false ) {
|
||||||
options.selected = -1;
|
options.selected = -1;
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
prototype._eventHandler = function( event ) {
|
_eventHandler: function( event ) {
|
||||||
_eventHandler.apply( this, arguments );
|
this._superApply( arguments );
|
||||||
this.options.selected = this.options.active;
|
this.options.selected = this.options.active;
|
||||||
if ( this.options.selected === false ) {
|
if ( this.options.selected === false ) {
|
||||||
this.options.selected = -1;
|
this.options.selected = -1;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}( jQuery, jQuery.ui.tabs.prototype ) );
|
});
|
||||||
|
|
||||||
// show and select event
|
// show and select event
|
||||||
(function( $, prototype ) {
|
$.widget( "ui.tabs", $.ui.tabs, {
|
||||||
$.extend( prototype.options, {
|
options: {
|
||||||
show: null,
|
show: null,
|
||||||
select: null
|
select: null
|
||||||
});
|
},
|
||||||
var _create = prototype._create,
|
_create: function() {
|
||||||
_trigger = prototype._trigger;
|
this._super();
|
||||||
|
|
||||||
prototype._create = function() {
|
|
||||||
_create.call( this );
|
|
||||||
if ( this.options.active !== false ) {
|
if ( this.options.active !== false ) {
|
||||||
this._trigger( "show", null, this._ui(
|
this._trigger( "show", null, this._ui(
|
||||||
this.active[ 0 ], this._getPanelForTab( this.active )[ 0 ] ) );
|
this.active[ 0 ], this._getPanelForTab( this.active )[ 0 ] ) );
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
prototype._trigger = function( type, event, data ) {
|
_trigger: function( type, event, data ) {
|
||||||
var ret = _trigger.apply( this, arguments );
|
var ret = this._superApply( arguments );
|
||||||
if ( !ret ) {
|
if ( !ret ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( type === "beforeActivate" && data.newTab.length ) {
|
if ( type === "beforeActivate" && data.newTab.length ) {
|
||||||
ret = _trigger.call( this, "select", event, {
|
ret = this._super( "select", event, {
|
||||||
tab: data.newTab[ 0],
|
tab: data.newTab[ 0],
|
||||||
panel: data.newPanel[ 0 ],
|
panel: data.newPanel[ 0 ],
|
||||||
index: data.newTab.closest( "li" ).index()
|
index: data.newTab.closest( "li" ).index()
|
||||||
});
|
});
|
||||||
} else if ( type === "activate" && data.newTab.length ) {
|
} else if ( type === "activate" && data.newTab.length ) {
|
||||||
ret = _trigger.call( this, "show", event, {
|
ret = this._super( "show", event, {
|
||||||
tab: data.newTab[ 0 ],
|
tab: data.newTab[ 0 ],
|
||||||
panel: data.newPanel[ 0 ],
|
panel: data.newPanel[ 0 ],
|
||||||
index: data.newTab.closest( "li" ).index()
|
index: data.newTab.closest( "li" ).index()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
return ret;
|
||||||
}( jQuery, jQuery.ui.tabs.prototype ) );
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// select method
|
// select method
|
||||||
(function( $, prototype ) {
|
$.widget( "ui.tabs", $.ui.tabs, {
|
||||||
prototype.select = function( index ) {
|
select: function( index ) {
|
||||||
index = this._getIndex( index );
|
index = this._getIndex( index );
|
||||||
if ( index === -1 ) {
|
if ( index === -1 ) {
|
||||||
if ( this.options.collapsible && this.options.selected !== -1 ) {
|
if ( this.options.collapsible && this.options.selected !== -1 ) {
|
||||||
@ -960,8 +942,8 @@ if ( $.uiBackCompat !== false ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
|
this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
|
||||||
};
|
}
|
||||||
}( jQuery, jQuery.ui.tabs.prototype ) );
|
});
|
||||||
|
|
||||||
// cookie option
|
// cookie option
|
||||||
var listId = 0;
|
var listId = 0;
|
||||||
|
74
ui/jquery.ui.widget.js
vendored
74
ui/jquery.ui.widget.js
vendored
@ -23,8 +23,9 @@ $.cleanData = function( elems ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$.widget = function( name, base, prototype ) {
|
$.widget = function( name, base, prototype ) {
|
||||||
var namespace = name.split( "." )[ 0 ],
|
var fullName, existingConstructor, constructor, basePrototype,
|
||||||
fullName;
|
namespace = name.split( "." )[ 0 ];
|
||||||
|
|
||||||
name = name.split( "." )[ 1 ];
|
name = name.split( "." )[ 1 ];
|
||||||
fullName = namespace + "-" + name;
|
fullName = namespace + "-" + name;
|
||||||
|
|
||||||
@ -39,12 +40,11 @@ $.widget = function( name, base, prototype ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$[ namespace ] = $[ namespace ] || {};
|
$[ namespace ] = $[ namespace ] || {};
|
||||||
// create the constructor using $.extend() so we can carry over any
|
existingConstructor = $[ namespace ][ name ];
|
||||||
// static properties stored on the existing constructor (if there is one)
|
constructor = $[ namespace ][ name ] = function( options, element ) {
|
||||||
$[ namespace ][ name ] = $.extend( function( options, element ) {
|
|
||||||
// allow instantiation without "new" keyword
|
// allow instantiation without "new" keyword
|
||||||
if ( !this._createWidget ) {
|
if ( !this._createWidget ) {
|
||||||
return new $[ namespace ][ name ]( options, element );
|
return new constructor( options, element );
|
||||||
}
|
}
|
||||||
|
|
||||||
// allow instantiation without initializing for simple inheritance
|
// allow instantiation without initializing for simple inheritance
|
||||||
@ -52,9 +52,19 @@ $.widget = function( name, base, prototype ) {
|
|||||||
if ( arguments.length ) {
|
if ( arguments.length ) {
|
||||||
this._createWidget( options, element );
|
this._createWidget( options, element );
|
||||||
}
|
}
|
||||||
}, $[ namespace ][ name ], { version: prototype.version } );
|
};
|
||||||
|
// extend with the existing constructor to carry over any static properties
|
||||||
|
$.extend( constructor, existingConstructor, {
|
||||||
|
version: prototype.version,
|
||||||
|
// copy the object used to create the prototype in case we need to
|
||||||
|
// redefine the widget later
|
||||||
|
_proto: $.extend( {}, prototype ),
|
||||||
|
// track widgets that inherit from this widget in case this widget is
|
||||||
|
// redefined after a widget inherits from it
|
||||||
|
_childConstructors: []
|
||||||
|
});
|
||||||
|
|
||||||
var basePrototype = new base();
|
basePrototype = new base();
|
||||||
// we need to make the options hash a property directly on the new instance
|
// we need to make the options hash a property directly on the new instance
|
||||||
// otherwise we'll modify the options hash on the prototype that we're
|
// otherwise we'll modify the options hash on the prototype that we're
|
||||||
// inheriting from
|
// inheriting from
|
||||||
@ -83,17 +93,41 @@ $.widget = function( name, base, prototype ) {
|
|||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
};
|
};
|
||||||
}());
|
})();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$[ namespace ][ name ].prototype = $.widget.extend( basePrototype, {
|
constructor.prototype = $.widget.extend( basePrototype, {
|
||||||
|
// TODO: remove support for widgetEventPrefix
|
||||||
|
// always use the name + a colon as the prefix, e.g., draggable:start
|
||||||
|
// don't prefix for widgets that aren't DOM-based
|
||||||
|
widgetEventPrefix: name
|
||||||
|
}, prototype, {
|
||||||
|
constructor: constructor,
|
||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
widgetName: name,
|
widgetName: name,
|
||||||
widgetEventPrefix: name,
|
|
||||||
widgetBaseClass: fullName
|
widgetBaseClass: fullName
|
||||||
}, prototype );
|
});
|
||||||
|
|
||||||
$.widget.bridge( name, $[ namespace ][ name ] );
|
// If this widget is being redefined then we need to find all widgets that
|
||||||
|
// are inheriting from it and redefine all of them so that they inherit from
|
||||||
|
// the new version of this widget. We're essentially trying to replace one
|
||||||
|
// level in the prototype chain.
|
||||||
|
if ( existingConstructor ) {
|
||||||
|
$.each( existingConstructor._childConstructors, function( i, child ) {
|
||||||
|
var childPrototype = child.prototype;
|
||||||
|
|
||||||
|
// redefine the child widget using the same prototype that was
|
||||||
|
// originally used, but inherit from the new version of the base
|
||||||
|
$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
|
||||||
|
});
|
||||||
|
// remove the list of existing child constructors from the old constructor
|
||||||
|
// so the old child constructors can be garbage collected
|
||||||
|
delete existingConstructor._childConstructors;
|
||||||
|
} else {
|
||||||
|
base._childConstructors.push( constructor );
|
||||||
|
}
|
||||||
|
|
||||||
|
$.widget.bridge( name, constructor );
|
||||||
};
|
};
|
||||||
|
|
||||||
$.widget.extend = function( target ) {
|
$.widget.extend = function( target ) {
|
||||||
@ -157,18 +191,8 @@ $.widget.bridge = function( name, object ) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
$.Widget = function( options, element ) {
|
$.Widget = function( options, element ) {};
|
||||||
// allow instantiation without "new" keyword
|
$.Widget._childConstructors = [];
|
||||||
if ( !this._createWidget ) {
|
|
||||||
return new $[ namespace ][ name ]( options, element );
|
|
||||||
}
|
|
||||||
|
|
||||||
// allow instantiation without initializing for simple inheritance
|
|
||||||
// must use "new" keyword (the code above always passes args)
|
|
||||||
if ( arguments.length ) {
|
|
||||||
this._createWidget( options, element );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$.Widget.prototype = {
|
$.Widget.prototype = {
|
||||||
widgetName: "widget",
|
widgetName: "widget",
|
||||||
|
Loading…
Reference in New Issue
Block a user