Skip to content

Commit 556b271

Browse files
committed
Widget: Support mixins
Fixes #12601 Closes jquerygh-1554
1 parent ae25cdb commit 556b271

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

tests/unit/widget/core.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,85 @@ test( "._superApply()", function() {
476476
delete $.fn.testWidget2;
477477
});
478478

479+
test( "mixins", function() {
480+
expect( 5 );
481+
482+
var mixin1 = {
483+
foo: function() {
484+
equal( method, "foo", "Methods from first mixin are copied over" );
485+
}
486+
};
487+
var mixin2 = {
488+
bar: function() {
489+
equal( method, "bar", "Methods from second mixin are copied over" );
490+
}
491+
};
492+
var prototype = {
493+
baz: function() {
494+
equal( method, "baz", "Methods from protoype are copied over" );
495+
}
496+
};
497+
var existingBar = mixin2.bar;
498+
var method;
499+
500+
$.widget( "ui.testWidget", [ mixin1, mixin2, prototype ] );
501+
method = "foo";
502+
$.ui.testWidget.prototype.foo();
503+
method = "bar";
504+
$.ui.testWidget.prototype.bar();
505+
method = "baz";
506+
$.ui.testWidget.prototype.baz();
507+
508+
mixin1.foo = function() {
509+
ok( false, "Changes to a mixin don't change the prototype" );
510+
};
511+
method = "foo";
512+
$.ui.testWidget.prototype.foo();
513+
514+
$.ui.testWidget.prototype.bar = function() {};
515+
strictEqual( mixin2.bar, existingBar, "Changes to a prototype don't change the mixin" );
516+
});
517+
518+
test( "mixins with inheritance", function() {
519+
expect( 4 );
520+
521+
var mixin1 = {
522+
foo: function() {
523+
equal( method, "foo", "Methods from first mixin are copied over" );
524+
}
525+
};
526+
var mixin2 = {
527+
bar: function() {
528+
equal( method, "bar", "Methods from second mixin are copied over" );
529+
}
530+
};
531+
var parentPrototype = {
532+
baz: function() {
533+
equal( method, "baz", "Methods from parent protoype are copied over" );
534+
}
535+
};
536+
var childPrototype = {
537+
qux: function() {
538+
equal( method, "qux", "Methods from child protoype are copied over" );
539+
}
540+
};
541+
var method;
542+
543+
$.widget( "ui.testWidget", [ mixin1, parentPrototype ] );
544+
$.widget( "ui.testWidget2", $.ui.testWidget, [ mixin2, childPrototype ] );
545+
method = "foo";
546+
$.ui.testWidget2.prototype.foo();
547+
method = "bar";
548+
$.ui.testWidget2.prototype.bar();
549+
method = "baz";
550+
$.ui.testWidget2.prototype.baz();
551+
method = "qux";
552+
$.ui.testWidget2.prototype.qux();
553+
554+
delete $.ui.testWidget2;
555+
delete $.fn.testWidget2;
556+
});
557+
479558
test( ".option() - getter", function() {
480559
expect( 6 );
481560
$.widget( "ui.testWidget", {

ui/widget.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ $.widget = function( name, base, prototype ) {
6262
base = $.Widget;
6363
}
6464

65+
if ( $.isArray( prototype ) ) {
66+
prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
67+
}
68+
6569
// create selector for plugin
6670
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
6771
return !!$.data( elem, fullName );

0 commit comments

Comments
 (0)