diff --git a/tests/unit/widget/widget_core.js b/tests/unit/widget/widget_core.js index 364838e3f20..9980d562eeb 100644 --- a/tests/unit/widget/widget_core.js +++ b/tests/unit/widget/widget_core.js @@ -9,6 +9,51 @@ module( "widget factory", { } }); +test( "widget namespaces", function() { + var fail = function(msg) { ok(false, msg); }; + + var uiPrototype = { + _create: function() { fail( "This widget should not have been instantiated" ); } + }; + + var customPrototype = { + _create: function() { ok( true, "Second defined widget is the one that takes over default scope" ) } + } + + $.widget( "ui.testWidget", uiPrototype ); + $.widget( "custom.testWidget", customPrototype ); + + var elem = $( "
" ).testWidget(); + + ok( $.isFunction( $.ui.testWidget ), "constructor was created in the ui namespace" ); + ok( $.isFunction( $.custom.testWidget ), "constructor was created in the custom namespace" ); + equals( uiPrototype._create, $.ui.testWidget.prototype._create, "ui widget is in the ui namespace" ); + equals( customPrototype._create, $.custom.testWidget.prototype._create, "custom namespace is maintained" ); + + // Now make sure we can explicitly pick the one we want + var which = "neither"; + $.ui.testWidget.prototype._create = function(){ which = "ui"; }; + var elem2 = $( "
" ).ui_testWidget(); + equals( which, "ui" , "creating a namespaced widget makes the correct one" ); + + which = "neither"; + $.custom.testWidget.prototype._create = function(){ which = "custom"; }; + var elem3 = $( "
" ).custom_testWidget(); + equals( which, "custom", "creating a namespaced widget makes the correct one" ); + + // Now make sure we can explicitly pick the one we want via the chained version of namespace. + var which = "neither"; + $.ui.testWidget.prototype._create = function(){ which = "ui"; }; + var elem2 = $( "
" ).ui().testWidget(); + equals( which, "ui" , "creating a namespaced widget with the namespace function makes the correct one" ); + + which = "neither"; + $.custom.testWidget.prototype._create = function(){ which = "custom"; }; + var elem3 = $( "
" ).custom().testWidget(); + equals( which, "custom", "creating a namespaced widget with the namespace function makes the correct one" ); + +}); + test( "widget creation", function() { var myPrototype = { _create: function() {}, @@ -236,7 +281,35 @@ test( ".option() - delegate to ._setOptions()", function() { "_setOptions called with multiple options" ); }); -test( ".option() - delegate to ._setOption()", function() { +test( ".option() - getter - custom namespace", function() { + $.widget( "custom.testWidget", { + _create: function() {} + }); + + var div = $( "
" ).custom_testWidget({ + foo: "bar", + baz: 5, + qux: [ "quux", "quuux" ] + }); + + same( div.custom_testWidget( "option", "foo"), "bar", "single option - string" ); + same( div.custom_testWidget( "option", "baz"), 5, "single option - number" ); + same( div.custom_testWidget( "option", "qux"), [ "quux", "quuux" ], + "single option - array" ); + + var options = div.custom_testWidget( "option" ); + same( options, { + disabled: false, + foo: "bar", + baz: 5, + qux: [ "quux", "quuux" ] + }, "full options hash returned" ); + options.foo = "notbar"; + same( div.custom_testWidget( "option", "foo"), "bar", + "modifying returned options hash does not modify plugin instance" ); +}); + +test( ".option() - setter", function() { var calls = []; $.widget( "ui.testWidget", { _create: function() {}, diff --git a/ui/jquery.ui.widget.js b/ui/jquery.ui.widget.js index bc6408125c7..02a1faa72f3 100644 --- a/ui/jquery.ui.widget.js +++ b/ui/jquery.ui.widget.js @@ -75,11 +75,11 @@ $.widget = function( name, base, prototype ) { widgetBaseClass: fullName }, prototype ); - $.widget.bridge( name, $[ namespace ][ name ] ); + $.widget.bridge( name, namespace, $[ namespace ][ name ] ); }; -$.widget.bridge = function( name, object ) { - $.fn[ name ] = function( options ) { +$.widget.bridge = function( name, namespace, object ) { + var bridgeFn = function( options ) { var isMethodCall = typeof options === "string", args = Array.prototype.slice.call( arguments, 1 ), returnValue = this; @@ -111,18 +111,39 @@ $.widget.bridge = function( name, object ) { } }); } else { + // Make each element of the jquery list an instance of this widget this.each(function() { - var instance = $.data( this, name ); + var instance = $.data( this, namespace + "." + name ); if ( instance ) { instance.option( options || {} )._init(); } else { - $.data( this, name, new object( options, this ) ); + var instance = new object( options, this ); + $.data( this, name, instance ); + $.data( this, namespace + "." + name, instance ); } }); } return returnValue; }; + + // Check to see if we aren't the first widget to come this way. + if ( $.isFunction( $.fn[ namespace ] ) ) { + $.fn[ namespace ][ name ] = bridgeFn; + } else { + // Store off the jquery instance so we can get at it in the namespaceFn + var jquery_obj = this; + var namespaceFn = function() { + this[ name ] = bridgeFn; + return this; + } + $.fn[ namespace ] = namespaceFn; + } + + // Attach the bridge function to both the raw name - example: `$.sortable()` + // And also attach it to a namespaced name - example: `$.ui_sortable()` + $.fn[ name ] = bridgeFn; + $.fn[ namespace + "_" + name ] = bridgeFn; }; $.Widget = function( options, element ) {