From e07784ec89d3581890e613a3a97b031454fe2876 Mon Sep 17 00:00:00 2001 From: Alexander Schmitz Date: Mon, 2 Feb 2015 19:21:44 -0500 Subject: [PATCH 01/36] Build: Add qunit-assert-classes plug-in for classes tests --- Gruntfile.js | 3 ++ bower.json | 1 + external/qunit-assert-classes/LICENSE.txt | 22 +++++++++ .../qunit-assert-classes.js | 47 +++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 external/qunit-assert-classes/LICENSE.txt create mode 100644 external/qunit-assert-classes/qunit-assert-classes.js diff --git a/Gruntfile.js b/Gruntfile.js index 3e66e2e37d3..d91dedb9bc4 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -229,6 +229,9 @@ grunt.initConfig({ "qunit/qunit.css": "qunit/qunit/qunit.css", "qunit/LICENSE.txt": "qunit/LICENSE.txt", + "qunit-assert-classes/qunit-assert-classes.js": "qunit-assert-classes/qunit-assert-classes.js", + "qunit-assert-classes/LICENSE.txt": "qunit-assert-classes/LICENSE", + "jquery-mousewheel/jquery.mousewheel.js": "jquery-mousewheel/jquery.mousewheel.js", "jquery-mousewheel/LICENSE.txt": "jquery-mousewheel/LICENSE.txt", diff --git a/bower.json b/bower.json index 38a9f77ee54..9b6b71b6f36 100644 --- a/bower.json +++ b/bower.json @@ -15,6 +15,7 @@ "jquery-simulate": "1.0.0", "jshint": "2.4.4", "qunit": "1.17.1", + "qunit-assert-classes": "0.1.5", "jquery-1.7.0": "jquery#1.7.0", "jquery-1.7.1": "jquery#1.7.1", diff --git a/external/qunit-assert-classes/LICENSE.txt b/external/qunit-assert-classes/LICENSE.txt new file mode 100644 index 00000000000..938db036815 --- /dev/null +++ b/external/qunit-assert-classes/LICENSE.txt @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Alexander Schmitz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/external/qunit-assert-classes/qunit-assert-classes.js b/external/qunit-assert-classes/qunit-assert-classes.js new file mode 100644 index 00000000000..f61046bc85b --- /dev/null +++ b/external/qunit-assert-classes/qunit-assert-classes.js @@ -0,0 +1,47 @@ +( function( QUnit ) { + function inArray( haystack, needle ) { + for ( var i = 0; i < haystack.length; i++ ) { + if ( haystack[ i ] === needle ) { + return true; + } + } + return false; + } + function check( element, classes, stateVal, message ) { + var i, result, classAttribute, elementClassArray, + classArray = classes.split( " " ), + missing = [], + found = []; + + if ( element.jquery && element.length !== 1 ) { + throw( "Class checks can only be performed on a single element on a collection" ); + } + element = element.jquery ? element[ 0 ] : element; + classAttribute = element.getAttribute( "class" ); + message = message || "Element must " + ( stateVal? "" : "not " ) + "have classes"; + if ( classAttribute ) { + elementClassArray = classAttribute.split( " " ); + for( i = 0; i < classArray.length; i++ ) { + if ( !inArray( elementClassArray, classArray[ i ] ) ) { + missing.push( classArray[ i ] ); + } else { + found.push( classArray[ i ] ); + } + } + } else { + missing = classArray; + } + + result = stateVal ? !missing.length : !found.length; + QUnit.push( result, classes, result ? classes : found.join( " " ), message ); + } + + QUnit.extend( QUnit.assert, { + hasClasses: function( element, classes, message ) { + check( element, classes, true, message ); + }, + lacksClasses: function( element, classes, message ) { + check( element, classes, false, message ); + } + }); +})( QUnit ); \ No newline at end of file From fb4c29a546917c2ef1c8375762f21434a6319a90 Mon Sep 17 00:00:00 2001 From: Alexander Schmitz Date: Wed, 3 Dec 2014 11:20:20 -0500 Subject: [PATCH 02/36] Widget: Add classes option and _add/_remove/_toggleClass methods --- tests/unit/accordion/accordion_common.js | 1 + .../unit/autocomplete/autocomplete_common.js | 1 + tests/unit/button/button_common.js | 1 + tests/unit/dialog/dialog_common.js | 1 + tests/unit/draggable/draggable_common.js | 1 + tests/unit/droppable/droppable_common.js | 1 + tests/unit/menu/menu_common.js | 1 + tests/unit/progressbar/progressbar_common.js | 1 + tests/unit/resizable/resizable_common.js | 1 + tests/unit/selectable/selectable_common.js | 1 + tests/unit/selectmenu/selectmenu_common.js | 1 + tests/unit/slider/slider_common.js | 1 + tests/unit/sortable/sortable_common.js | 1 + tests/unit/spinner/spinner_common.js | 1 + tests/unit/tabs/tabs_common.js | 1 + tests/unit/tooltip/tooltip_common.js | 1 + tests/unit/widget/widget.html | 2 + tests/unit/widget/widget_classes.js | 143 ++++++++++++++++++ tests/unit/widget/widget_core.js | 5 +- ui/widget.js | 121 +++++++++++++-- 20 files changed, 272 insertions(+), 15 deletions(-) create mode 100644 tests/unit/widget/widget_classes.js diff --git a/tests/unit/accordion/accordion_common.js b/tests/unit/accordion/accordion_common.js index ef24cf25ec5..70e04e8475b 100644 --- a/tests/unit/accordion/accordion_common.js +++ b/tests/unit/accordion/accordion_common.js @@ -2,6 +2,7 @@ TestHelpers.commonWidgetTests( "accordion", { defaults: { active: 0, animate: {}, + classes: {}, collapsible: false, disabled: false, event: "click", diff --git a/tests/unit/autocomplete/autocomplete_common.js b/tests/unit/autocomplete/autocomplete_common.js index 63b24d384b9..b82ec1d1c50 100644 --- a/tests/unit/autocomplete/autocomplete_common.js +++ b/tests/unit/autocomplete/autocomplete_common.js @@ -2,6 +2,7 @@ TestHelpers.commonWidgetTests( "autocomplete", { defaults: { appendTo: null, autoFocus: false, + classes: {}, delay: 300, disabled: false, messages: { diff --git a/tests/unit/button/button_common.js b/tests/unit/button/button_common.js index ef22d30114f..1564a1beeee 100644 --- a/tests/unit/button/button_common.js +++ b/tests/unit/button/button_common.js @@ -1,5 +1,6 @@ TestHelpers.commonWidgetTests( "button", { defaults: { + classes: {}, disabled: null, icons: { primary: null, diff --git a/tests/unit/dialog/dialog_common.js b/tests/unit/dialog/dialog_common.js index fc10fabaab6..87f7f7d1578 100644 --- a/tests/unit/dialog/dialog_common.js +++ b/tests/unit/dialog/dialog_common.js @@ -3,6 +3,7 @@ TestHelpers.commonWidgetTests( "dialog", { appendTo: "body", autoOpen: true, buttons: [], + classes: {}, closeOnEscape: true, closeText: "Close", disabled: false, diff --git a/tests/unit/draggable/draggable_common.js b/tests/unit/draggable/draggable_common.js index 5abd09e4935..00193bdaf4f 100644 --- a/tests/unit/draggable/draggable_common.js +++ b/tests/unit/draggable/draggable_common.js @@ -3,6 +3,7 @@ TestHelpers.commonWidgetTests( "draggable", { appendTo: "parent", axis: false, cancel: "input,textarea,button,select,option", + classes: {}, connectToSortable: false, containment: false, cursor: "auto", diff --git a/tests/unit/droppable/droppable_common.js b/tests/unit/droppable/droppable_common.js index c112def3cf4..bd56aa35f9b 100644 --- a/tests/unit/droppable/droppable_common.js +++ b/tests/unit/droppable/droppable_common.js @@ -3,6 +3,7 @@ TestHelpers.commonWidgetTests( "droppable", { accept: "*", activeClass: false, addClasses: true, + classes: {}, disabled: false, greedy: false, hoverClass: false, diff --git a/tests/unit/menu/menu_common.js b/tests/unit/menu/menu_common.js index ae0ab988785..942e9e9f954 100644 --- a/tests/unit/menu/menu_common.js +++ b/tests/unit/menu/menu_common.js @@ -1,5 +1,6 @@ TestHelpers.commonWidgetTests( "menu", { defaults: { + classes: {}, disabled: false, icons: { submenu: "ui-icon-caret-1-e" diff --git a/tests/unit/progressbar/progressbar_common.js b/tests/unit/progressbar/progressbar_common.js index 0768576f568..c603b4efd2b 100644 --- a/tests/unit/progressbar/progressbar_common.js +++ b/tests/unit/progressbar/progressbar_common.js @@ -1,5 +1,6 @@ TestHelpers.commonWidgetTests( "progressbar", { defaults: { + classes: {}, disabled: false, max: 100, value: 0, diff --git a/tests/unit/resizable/resizable_common.js b/tests/unit/resizable/resizable_common.js index c261ac5b9c8..a68103101bc 100644 --- a/tests/unit/resizable/resizable_common.js +++ b/tests/unit/resizable/resizable_common.js @@ -7,6 +7,7 @@ TestHelpers.commonWidgetTests( "resizable", { aspectRatio: false, autoHide: false, cancel: "input,textarea,button,select,option", + classes: {}, containment: false, delay: 0, disabled: false, diff --git a/tests/unit/selectable/selectable_common.js b/tests/unit/selectable/selectable_common.js index d00a47be593..0f9adf54018 100644 --- a/tests/unit/selectable/selectable_common.js +++ b/tests/unit/selectable/selectable_common.js @@ -3,6 +3,7 @@ TestHelpers.commonWidgetTests("selectable", { appendTo: "body", autoRefresh: true, cancel: "input,textarea,button,select,option", + classes: {}, delay: 0, disabled: false, distance: 0, diff --git a/tests/unit/selectmenu/selectmenu_common.js b/tests/unit/selectmenu/selectmenu_common.js index bc245f96266..cb8712e7b5a 100644 --- a/tests/unit/selectmenu/selectmenu_common.js +++ b/tests/unit/selectmenu/selectmenu_common.js @@ -1,6 +1,7 @@ TestHelpers.commonWidgetTests( "selectmenu", { defaults: { appendTo: null, + classes: {}, disabled: null, icons: { button: "ui-icon-triangle-1-s" diff --git a/tests/unit/slider/slider_common.js b/tests/unit/slider/slider_common.js index 6d7278de6a2..a72071f793d 100644 --- a/tests/unit/slider/slider_common.js +++ b/tests/unit/slider/slider_common.js @@ -2,6 +2,7 @@ TestHelpers.commonWidgetTests( "slider", { defaults: { animate: false, cancel: "input,textarea,button,select,option", + classes: {}, delay: 0, disabled: false, distance: 0, diff --git a/tests/unit/sortable/sortable_common.js b/tests/unit/sortable/sortable_common.js index 86850a658c3..6733714a755 100644 --- a/tests/unit/sortable/sortable_common.js +++ b/tests/unit/sortable/sortable_common.js @@ -3,6 +3,7 @@ TestHelpers.commonWidgetTests( "sortable", { appendTo: "parent", axis: false, cancel: "input,textarea,button,select,option", + classes: {}, connectWith: false, containment: false, cursor: "auto", diff --git a/tests/unit/spinner/spinner_common.js b/tests/unit/spinner/spinner_common.js index b494e3ca34d..871af7db447 100644 --- a/tests/unit/spinner/spinner_common.js +++ b/tests/unit/spinner/spinner_common.js @@ -1,5 +1,6 @@ TestHelpers.commonWidgetTests( "spinner", { defaults: { + classes: {}, culture: null, disabled: false, icons: { diff --git a/tests/unit/tabs/tabs_common.js b/tests/unit/tabs/tabs_common.js index a589515f806..8f6bbc67bc9 100644 --- a/tests/unit/tabs/tabs_common.js +++ b/tests/unit/tabs/tabs_common.js @@ -1,6 +1,7 @@ TestHelpers.commonWidgetTests( "tabs", { defaults: { active: null, + classes: {}, collapsible: false, disabled: false, event: "click", diff --git a/tests/unit/tooltip/tooltip_common.js b/tests/unit/tooltip/tooltip_common.js index 2d6ea91eccd..0611d724cec 100644 --- a/tests/unit/tooltip/tooltip_common.js +++ b/tests/unit/tooltip/tooltip_common.js @@ -1,5 +1,6 @@ TestHelpers.commonWidgetTests( "tooltip", { defaults: { + classes: {}, content: function() {}, disabled: false, hide: true, diff --git a/tests/unit/widget/widget.html b/tests/unit/widget/widget.html index 2b764abab9e..ac106ea3294 100644 --- a/tests/unit/widget/widget.html +++ b/tests/unit/widget/widget.html @@ -9,6 +9,7 @@ + + diff --git a/tests/unit/widget/widget_classes.js b/tests/unit/widget/widget_classes.js new file mode 100644 index 00000000000..0202d26831c --- /dev/null +++ b/tests/unit/widget/widget_classes.js @@ -0,0 +1,143 @@ +(function( $ ) { + +module( "widget factory classes", { + setup: function() { + $.widget( "ui.classesWidget", { + options: { + classes: { + "ui-classes-widget": "ui-theme-widget", + "ui-classes-element": "ui-theme-element ui-theme-element-2" + } + }, + _create: function() { + this.span = $( "" ) + .appendTo( this.element ); + + this.element.wrap( "
" ); + + this.wrapper = this.element.parent(); + + this._addClass( "ui-classes-element", "ui-core-element" ) + ._addClass( "ui-classes-element-2" ) + ._addClass( null, "ui-core-element-null" ) + ._addClass( this.span, null, "ui-core-span-null" ) + ._addClass( this.span, "ui-classes-span", "ui-core-span" ) + ._addClass( this.wrapper, "ui-classes-widget" ); + + }, + toggleClasses: function( bool ) { + this._toggleClass( "ui-classes-element", "ui-core-element", bool ) + ._toggleClass( "ui-classes-element-2", null, bool ) + ._toggleClass( null, "ui-core-element-null", bool ) + ._toggleClass( this.span, null, "ui-core-span-null", bool ) + ._toggleClass( this.span, "ui-classes-span", "ui-core-span", bool ) + ._toggleClass( this.wrapper, "ui-classes-widget", null, bool ); + }, + removeClasses: function() { + this._removeClass( "ui-classes-element", "ui-core-element" ) + ._removeClass( "ui-classes-element-2" ) + ._removeClass( null, "ui-core-element-null" ) + ._removeClass( this.span, null, "ui-core-span-null" ) + ._removeClass( this.span, "ui-classes-span", "ui-core-span" ) + ._removeClass( this.wrapper, "ui-classes-widget" ); + }, + _destroy: function() { + this.span.remove(); + this.element.unwrap(); + } + }); + }, + teardown: function() { + delete $.ui.classesWidget; + delete $.fn.classesWidget; + } +}); + +function elementHasClasses( widget, method, assert ) { + var toggle = method === "toggle" ? ( ", true" ) : ""; + + assert.hasClasses( widget, "ui-classes-element ui-theme-element ui-theme-element-2", + "_" + method + "Class works with ( keys, extra" + toggle + " )" ); + assert.hasClasses( widget, "ui-classes-element-2", + "_" + method + "Class works with ( keys, null" + toggle + " )" ); + assert.hasClasses( widget, "ui-core-element-null", + "_" + method + "Class works with ( null, extra" + toggle + " )" ); + assert.hasClasses( widget.parent(), "ui-classes-widget ui-theme-widget", + "_" + method + "Class works with ( element, null, extra" + toggle + " )" ); + assert.hasClasses( widget.find( "span" ), "ui-classes-span ui-core-span", + "_" + method + "Class works with ( element, keys, extra" + toggle + " )" ); + assert.hasClasses( widget.find( "span" ), "ui-core-span-null", + "_" + method + "Class works with ( element, keys, null" + toggle + " )" ); +} +function elementLacksClasses( widget, method, assert ) { + var toggle = method === "toggle" ? ( ", false" ) : ""; + + assert.lacksClasses( widget, "ui-classes-element ui-theme-element ui-theme-element-2", + "_" + method + "Class works with ( keys, extra" + toggle + " )" ); + assert.lacksClasses( widget, "ui-classes-element-2", + "_" + method + "Class works with ( keys, null" + toggle + " )" ); + assert.lacksClasses( widget, "ui-core-element-null", + "_" + method + "Class works with ( null, extra" + toggle + " )" ); + assert.lacksClasses( widget.parent(), "ui-classes-widget ui-theme-widget", + "_" + method + "Class works with ( element, null, extra" + toggle + " )" ); + assert.lacksClasses( widget.find( "span" ), "ui-classes-span ui-core-span", + "_" + method + "Class works with ( element, keys, extra" + toggle + " )" ); + assert.lacksClasses( widget.find( "span" ), "ui-core-span-null", + "_" + method + "Class works with ( element, keys, null" + toggle + " )" ); +} + +test( ".option() - classes setter", function( assert ) { + expect( 11 ); + + var testWidget = $.ui.classesWidget(); + + elementHasClasses( testWidget.element, "add", assert ); + + testWidget.option({ + classes: { + "ui-classes-span": "custom-theme-span", + "ui-classes-widget": "ui-theme-widget custom-theme-widget", + "ui-classes-element": "ui-theme-element-2" + } + }); + + assert.lacksClasses( testWidget.element, "ui-theme-element", + "Removing a class from the value removes the class" ); + + testWidget.option( "classes.ui-classes-element", "" ); + assert.hasClasses( testWidget.element, "ui-classes-element", + "Setting to empty value leaves structure class" ); + assert.lacksClasses( testWidget.element, "ui-theme-element-2", + "Setting empty value removes previous value classes" ); + assert.hasClasses( testWidget.span, "ui-classes-span custom-theme-span", + "Adding a class to an empty value works as expected" ); + assert.hasClasses( testWidget.wrapper, "ui-classes-widget custom-theme-widget", + "Appending a class to the current value works as expected" ); +}); + +test( ".destroy() - class removal", function() { + expect( 1 ); + + domEqual( "#widget", function() { + $( "#widget" ).classesWidget().classesWidget( "destroy" ); + }); +}); + +test( "._add/_remove/_toggleClass()", function( assert ) { + expect( 24 ); + + var widget = $( "#widget" ).classesWidget(); + + elementHasClasses( widget, "add", assert ); + + widget.classesWidget( "toggleClasses", false ); + elementLacksClasses( widget, "toggle", assert ); + + widget.classesWidget( "toggleClasses", true ); + elementHasClasses( widget, "toggle", assert ); + + widget.classesWidget( "removeClasses" ); + elementLacksClasses( widget, "remove", assert ); +}); + +}( jQuery ) ); diff --git a/tests/unit/widget/widget_core.js b/tests/unit/widget/widget_core.js index 2b88e39ef22..4e5b023490a 100644 --- a/tests/unit/widget/widget_core.js +++ b/tests/unit/widget/widget_core.js @@ -227,6 +227,7 @@ test( "merge multiple option arguments", function() { $.widget( "ui.testWidget", { _create: function() { deepEqual( this.options, { + classes: {}, create: null, disabled: false, option1: "value1", @@ -281,6 +282,7 @@ test( "._getCreateOptions()", function() { }, _create: function() { deepEqual( this.options, { + classes: {}, create: null, disabled: false, option1: "override1", @@ -485,10 +487,11 @@ test( ".option() - getter", function() { options = div.testWidget( "option" ); deepEqual( options, { + baz: 5, + classes: {}, create: null, disabled: false, foo: "bar", - baz: 5, qux: [ "quux", "quuux" ] }, "full options hash returned" ); options.foo = "notbar"; diff --git a/ui/widget.js b/ui/widget.js index 33e0d156e4d..4999048f6f0 100644 --- a/ui/widget.js +++ b/ui/widget.js @@ -250,6 +250,7 @@ $.Widget.prototype = { widgetEventPrefix: "", defaultElement: "
", options: { + classes: {}, disabled: false, // callbacks @@ -264,6 +265,7 @@ $.Widget.prototype = { this.bindings = $(); this.hoverable = $(); this.focusable = $(); + this.classesElementLookup = {}; if ( element !== this ) { $.data( element, this.widgetFullName, this ); @@ -297,7 +299,13 @@ $.Widget.prototype = { _init: $.noop, destroy: function() { + var that = this; + this._destroy(); + $.each( this.classesElementLookup, function( key, value ) { + that._removeClass( value, key ); + }); + // we can probably remove the unbind calls in 2.0 // all event bindings should go through this._on() this.element @@ -305,15 +313,10 @@ $.Widget.prototype = { .removeData( this.widgetFullName ); this.widget() .unbind( this.eventNamespace ) - .removeAttr( "aria-disabled" ) - .removeClass( - this.widgetFullName + "-disabled " + - "ui-state-disabled" ); + .removeAttr( "aria-disabled" ); // clean up events and states this.bindings.unbind( this.eventNamespace ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); }, _destroy: $.noop, @@ -370,21 +373,54 @@ $.Widget.prototype = { return this; }, _setOption: function( key, value ) { + if ( key === "classes" ) { + this._setOptionClasses( value ); + } + this.options[ key ] = value; if ( key === "disabled" ) { - this.widget() - .toggleClass( this.widgetFullName + "-disabled", !!value ); + this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); // If the widget is becoming disabled, then nothing is interactive if ( value ) { - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); + this._removeClass( this.hoverable, null, "ui-state-hover" ); + this._removeClass( this.focusable, null, "ui-state-focus" ); } } return this; }, + _setOptionClasses: function( value ) { + var classKey, elements, currentElements; + + for ( classKey in value ) { + currentElements = this.classesElementLookup[ classKey ]; + if ( value[ classKey ] === this.options.classes[ classKey ] || + !currentElements || + !currentElements.length ) { + continue; + } + + // We are doing this to create a new jQuery object because the _removeClass() call + // on the next line is going to destroy the reference to the current elements being + // tracked. We need to save a copy of this collection so that we can add the new classes + // below. + elements = $( currentElements.get() ); + this._removeClass( currentElements, classKey ); + + // We don't use _addClass() here, because that uses this.options.classes + // for generating the string of classes. We want to use the value passed in from + // _setOption(), this is the new value of the classes option which was passed to + // _setOption(). We pass this value directly to _classes(). + elements.addClass( this._classes({ + element: elements, + keys: classKey, + classes: value, + add: true + })); + } + }, enable: function() { return this._setOptions({ disabled: false }); @@ -393,6 +429,63 @@ $.Widget.prototype = { return this._setOptions({ disabled: true }); }, + _classes: function( options ) { + var full = [], + that = this; + + options = $.extend({ + element: this.element, + classes: this.options.classes || {} + }, options ); + + function processClassString( classes, checkOption ) { + var current, i; + for ( i = 0; i < classes.length; i++ ) { + current = that.classesElementLookup[ classes[ i ] ] || $(); + if ( options.add ) { + current = $( $.unique( current.get().concat( options.element.get() ) ) ); + } else { + current = $( current.not( options.element ).get() ); + } + that.classesElementLookup[ classes[ i ] ] = current; + full.push( classes[ i ] ); + if ( checkOption && options.classes[ classes[ i ] ] ) { + full.push( options.classes[ classes[ i ] ] ); + } + } + } + + if ( options.keys ) { + processClassString( options.keys.match( /\S+/g ) || [], true ); + } + if ( options.extra ) { + processClassString( options.extra.match( /\S+/g ) || [] ); + } + + return full.join( " " ); + }, + + _removeClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, false ); + }, + + _addClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, true ); + }, + + _toggleClass: function( element, keys, extra, add ) { + add = ( typeof add === "boolean" ) ? add : extra; + var shift = ( typeof element === "string" || element === null ), + options = { + extra: shift ? keys : extra, + keys: shift ? element : keys, + element: shift ? this.element : element, + add: add + }; + options.element.toggleClass( this._classes( options ), add ); + return this; + }, + _on: function( suppressDisabledCheck, element, handlers ) { var delegateElement, instance = this; @@ -469,10 +562,10 @@ $.Widget.prototype = { this.hoverable = this.hoverable.add( element ); this._on( element, { mouseenter: function( event ) { - $( event.currentTarget ).addClass( "ui-state-hover" ); + this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); }, mouseleave: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-hover" ); + this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); } }); }, @@ -481,10 +574,10 @@ $.Widget.prototype = { this.focusable = this.focusable.add( element ); this._on( element, { focusin: function( event ) { - $( event.currentTarget ).addClass( "ui-state-focus" ); + this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); }, focusout: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-focus" ); + this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); } }); }, From a8cfc3050b62c32b26b5fd74609a83d39f681cba Mon Sep 17 00:00:00 2001 From: Alexander Schmitz Date: Wed, 3 Dec 2014 11:23:19 -0500 Subject: [PATCH 03/36] Accordion: Add classes option --- tests/unit/accordion/accordion.html | 1 + tests/unit/accordion/accordion_common.js | 6 +- tests/unit/accordion/accordion_core.js | 28 ++++-- ui/accordion.js | 115 +++++++++++------------ 4 files changed, 81 insertions(+), 69 deletions(-) diff --git a/tests/unit/accordion/accordion.html b/tests/unit/accordion/accordion.html index 0a8755fd34b..9ea2d364539 100644 --- a/tests/unit/accordion/accordion.html +++ b/tests/unit/accordion/accordion.html @@ -9,6 +9,7 @@ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ +
...
+
+ Please share some personal information + + +
+
+

Some more (optional) information

+ +
+
+
+
+
+ + diff --git a/tests/unit/dialog/dialog_deprecated.js b/tests/unit/dialog/dialog_deprecated.js new file mode 100644 index 00000000000..6a26c229ebc --- /dev/null +++ b/tests/unit/dialog/dialog_deprecated.js @@ -0,0 +1,28 @@ +(function( $ ) { + +module( "dialog (deprecated): options" ); + +test( "dialogClass", function() { + expect( 6 ); + + var element = $( "
" ).dialog(), + widget = element.dialog( "widget" ); + equal( widget.is( ".foo" ), false, "dialogClass not specified. class not added" ); + element.remove(); + + element = $( "
" ).dialog({ dialogClass: "foo" }); + widget = element.dialog( "widget" ); + equal( widget.is( ".foo" ), true, "dialogClass in init, foo class added" ); + element.dialog( "option", "dialogClass", "foobar" ); + equal( widget.is( ".foo" ), false, "dialogClass changed, previous one was removed" ); + equal( widget.is( ".foobar" ), true, "dialogClass changed, new one was added" ); + element.remove(); + + element = $( "
" ).dialog({ dialogClass: "foo bar" }); + widget = element.dialog( "widget" ); + equal( widget.is( ".foo" ), true, "dialogClass in init, two classes. foo class added" ); + equal( widget.is( ".bar" ), true, "dialogClass in init, two classes. bar class added" ); + element.remove(); +}); + +})( jQuery ); diff --git a/tests/unit/dialog/dialog_options.js b/tests/unit/dialog/dialog_options.js index 3e5444c67e2..77ca09703a7 100644 --- a/tests/unit/dialog/dialog_options.js +++ b/tests/unit/dialog/dialog_options.js @@ -224,26 +224,6 @@ test("closeText", function() { element.remove(); }); -test("dialogClass", function() { - expect( 6 ); - - var element = $("
").dialog(); - equal(element.dialog("widget").is(".foo"), false, "dialogClass not specified. foo class added"); - element.remove(); - - element = $("
").dialog({ dialogClass: "foo" }); - equal(element.dialog("widget").is(".foo"), true, "dialogClass in init. foo class added"); - element.dialog( "option", "dialogClass", "foobar" ); - equal( element.dialog("widget").is(".foo"), false, "dialogClass changed, previous one was removed" ); - equal( element.dialog("widget").is(".foobar"), true, "dialogClass changed, new one was added" ); - element.remove(); - - element = $("
").dialog({ dialogClass: "foo bar" }); - equal(element.dialog("widget").is(".foo"), true, "dialogClass in init, two classes. foo class added"); - equal(element.dialog("widget").is(".bar"), true, "dialogClass in init, two classes. bar class added"); - element.remove(); -}); - test("draggable", function() { expect(4); diff --git a/ui/dialog.js b/ui/dialog.js index 0775fbe8df9..3eecde43f27 100644 --- a/ui/dialog.js +++ b/ui/dialog.js @@ -37,15 +37,18 @@ } }(function( $ ) { -return $.widget( "ui.dialog", { +$.widget( "ui.dialog", { version: "@VERSION", options: { appendTo: "body", autoOpen: true, buttons: [], + classes: { + "ui-dialog": "ui-corner-all", + "ui-dialog-titlebar": "ui-corner-all" + }, closeOnEscape: true, closeText: "Close", - dialogClass: "", draggable: true, hide: null, height: "auto", @@ -122,9 +125,10 @@ return $.widget( "ui.dialog", { this.element .show() .removeAttr( "title" ) - .addClass( "ui-dialog-content ui-widget-content" ) .appendTo( this.uiDialog ); + this._addClass( "ui-dialog-content", "ui-widget-content" ); + this._createTitlebar(); this._createButtonPane(); @@ -163,7 +167,6 @@ return $.widget( "ui.dialog", { this.element .removeUniqueId() - .removeClass( "ui-dialog-content ui-widget-content" ) .css( this.originalCss ) // Without detaching first, the following becomes really slow .detach(); @@ -336,8 +339,6 @@ return $.widget( "ui.dialog", { _createWrapper: function() { this.uiDialog = $("
") - .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + - this.options.dialogClass ) .hide() .attr({ // Setting tabIndex makes the div focusable @@ -346,6 +347,7 @@ return $.widget( "ui.dialog", { }) .appendTo( this._appendTo() ); + this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" ); this._on( this.uiDialog, { keydown: function( event ) { if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && @@ -395,9 +397,9 @@ return $.widget( "ui.dialog", { _createTitlebar: function() { var uiDialogTitle; - this.uiDialogTitlebar = $( "
" ) - .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" ) - .prependTo( this.uiDialog ); + this.uiDialogTitlebar = $( "
" ); + this._addClass( this.uiDialogTitlebar, + "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" ); this._on( this.uiDialogTitlebar, { mousedown: function( event ) { // Don't prevent click on close button (#8838) @@ -421,8 +423,9 @@ return $.widget( "ui.dialog", { }, text: false }) - .addClass( "ui-dialog-titlebar-close" ) .appendTo( this.uiDialogTitlebar ); + + this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" ); this._on( this.uiDialogTitlebarClose, { click: function( event ) { event.preventDefault(); @@ -430,12 +433,12 @@ return $.widget( "ui.dialog", { } }); - uiDialogTitle = $( "" ) - .uniqueId() - .addClass( "ui-dialog-title" ) - .prependTo( this.uiDialogTitlebar ); + uiDialogTitle = $( "" ).uniqueId().prependTo( this.uiDialogTitlebar ); + this._addClass( uiDialogTitle, "ui-dialog-title" ); this._title( uiDialogTitle ); + this.uiDialogTitlebar.prependTo( this.uiDialog ); + this.uiDialog.attr({ "aria-labelledby": uiDialogTitle.attr( "id" ) }); @@ -449,12 +452,13 @@ return $.widget( "ui.dialog", { }, _createButtonPane: function() { - this.uiDialogButtonPane = $( "
" ) - .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); + this.uiDialogButtonPane = $( "
" ); + this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane", + "ui-widget-content ui-helper-clearfix" ); this.uiButtonSet = $( "
" ) - .addClass( "ui-dialog-buttonset" ) .appendTo( this.uiDialogButtonPane ); + this._addClass( this.uiButtonSet, "ui-dialog-buttonset" ); this._createButtons(); }, @@ -468,7 +472,7 @@ return $.widget( "ui.dialog", { this.uiButtonSet.empty(); if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { - this.uiDialog.removeClass( "ui-dialog-buttons" ); + this._removeClass( this.uiDialog, "ui-dialog-buttons" ); return; } @@ -494,7 +498,7 @@ return $.widget( "ui.dialog", { .button( buttonOptions ) .appendTo( that.uiButtonSet ); }); - this.uiDialog.addClass( "ui-dialog-buttons" ); + this._addClass( this.uiDialog, "ui-dialog-buttons" ); this.uiDialogButtonPane.appendTo( this.uiDialog ); }, @@ -514,7 +518,7 @@ return $.widget( "ui.dialog", { handle: ".ui-dialog-titlebar", containment: "document", start: function( event, ui ) { - $( this ).addClass( "ui-dialog-dragging" ); + that._addClass( $( this ), "ui-dialog-dragging" ); that._blockFrames(); that._trigger( "dragStart", event, filteredUi( ui ) ); }, @@ -531,7 +535,7 @@ return $.widget( "ui.dialog", { "top" + (top >= 0 ? "+" : "") + top, of: that.window }; - $( this ).removeClass( "ui-dialog-dragging" ); + that._removeClass( $( this ), "ui-dialog-dragging" ); that._unblockFrames(); that._trigger( "dragStop", event, filteredUi( ui ) ); } @@ -568,7 +572,7 @@ return $.widget( "ui.dialog", { minHeight: this._minHeight(), handles: resizeHandles, start: function( event, ui ) { - $( this ).addClass( "ui-dialog-resizing" ); + that._addClass( $( this ), "ui-dialog-resizing" ); that._blockFrames(); that._trigger( "resizeStart", event, filteredUi( ui ) ); }, @@ -588,7 +592,7 @@ return $.widget( "ui.dialog", { "top" + (top >= 0 ? "+" : "") + top, of: that.window }; - $( this ).removeClass( "ui-dialog-resizing" ); + that._removeClass( $( this ), "ui-dialog-resizing" ); that._unblockFrames(); that._trigger( "resizeStop", event, filteredUi( ui ) ); } @@ -676,12 +680,6 @@ return $.widget( "ui.dialog", { var isDraggable, isResizable, uiDialog = this.uiDialog; - if ( key === "dialogClass" ) { - uiDialog - .removeClass( this.options.dialogClass ) - .addClass( value ); - } - if ( key === "disabled" ) { return; } @@ -850,8 +848,9 @@ return $.widget( "ui.dialog", { } this.overlay = $( "
" ) - .addClass( "ui-widget-overlay ui-front" ) .appendTo( this._appendTo() ); + + this._addClass( this.overlay, null, "ui-widget-overlay ui-front" ); this._on( this.overlay, { mousedown: "_keepFocus" }); @@ -881,4 +880,30 @@ return $.widget( "ui.dialog", { } }); +// DEPRECATED +// TODO: switch return back to widget declaration at top of file when this is removed +if ( $.uiBackCompat !== false ) { + + // Backcompat for dialogClass option + $.widget( "ui.dialog", $.ui.dialog, { + options: { + dialogClass: "" + }, + _createWrapper: function() { + this._super(); + this.uiDialog.addClass( this.options.dialogClass ); + }, + _setOption: function( key, value ) { + if ( key === "dialogClass" ) { + this.uiDialog + .removeClass( this.options.dialogClass ) + .addClass( value ); + } + this._superApply( arguments ); + } + }); +} + +return $.ui.dialog; + })); From c18bd1e26fcc4f1394480182c159b4cbd0bb5a86 Mon Sep 17 00:00:00 2001 From: Alexander Schmitz Date: Thu, 1 Jan 2015 12:10:26 -0500 Subject: [PATCH 06/36] Draggable: Add classes option --- ui/draggable.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ui/draggable.js b/ui/draggable.js index c57a3517c98..83ad6487a55 100644 --- a/ui/draggable.js +++ b/ui/draggable.js @@ -71,10 +71,10 @@ $.widget("ui.draggable", $.ui.mouse, { this._setPositionRelative(); } if (this.options.addClasses){ - this.element.addClass("ui-draggable"); + this._addClass( "ui-draggable" ); } if (this.options.disabled){ - this.element.addClass("ui-draggable-disabled"); + this._addClass( "ui-draggable-disabled" ); } this._setHandleClassName(); @@ -94,7 +94,6 @@ $.widget("ui.draggable", $.ui.mouse, { this.destroyOnClear = true; return; } - this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); this._removeHandleClassName(); this._mouseDestroy(); }, @@ -170,7 +169,7 @@ $.widget("ui.draggable", $.ui.mouse, { //Create and append the visible helper this.helper = this._createHelper(event); - this.helper.addClass("ui-draggable-dragging"); + this._addClass( this.helper, "ui-draggable-dragging" ); //Cache the helper size this._cacheHelperProportions(); @@ -352,11 +351,11 @@ $.widget("ui.draggable", $.ui.mouse, { _setHandleClassName: function() { this.handleElement = this.options.handle ? this.element.find( this.options.handle ) : this.element; - this.handleElement.addClass( "ui-draggable-handle" ); + this._addClass( this.handleElement, "ui-draggable-handle" ); }, _removeHandleClassName: function() { - this.handleElement.removeClass( "ui-draggable-handle" ); + this._removeClass( this.handleElement, "ui-draggable-handle" ); }, _createHelper: function(event) { @@ -660,7 +659,7 @@ $.widget("ui.draggable", $.ui.mouse, { }, _clear: function() { - this.helper.removeClass("ui-draggable-dragging"); + this._removeClass( this.helper, "ui-draggable-dragging" ); if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { this.helper.remove(); } From 414e84f4d008f9e71e198242f7451a328babd7d7 Mon Sep 17 00:00:00 2001 From: Alexander Schmitz Date: Thu, 1 Jan 2015 12:11:06 -0500 Subject: [PATCH 07/36] Droppable: Add classes option --- demos/droppable/accepted-elements.html | 6 +- demos/droppable/photo-manager.html | 8 +- demos/droppable/propagation.html | 12 ++- demos/droppable/revert.html | 6 +- demos/droppable/shopping-cart.html | 6 +- demos/droppable/visual-feedback.html | 10 ++- tests/unit/droppable/droppable.html | 3 + tests/unit/droppable/droppable_common.js | 2 - .../droppable/droppable_common_deprecated.js | 21 +++++ .../unit/droppable/droppable_deprecated.html | 47 ++++++++++ ui/droppable.js | 89 ++++++++++++++----- 11 files changed, 169 insertions(+), 41 deletions(-) create mode 100644 tests/unit/droppable/droppable_common_deprecated.js create mode 100644 tests/unit/droppable/droppable_deprecated.html diff --git a/demos/droppable/accepted-elements.html b/demos/droppable/accepted-elements.html index 19db546508d..2a50295260d 100644 --- a/demos/droppable/accepted-elements.html +++ b/demos/droppable/accepted-elements.html @@ -20,8 +20,10 @@ $( "#draggable, #draggable-nonvalid" ).draggable(); $( "#droppable" ).droppable({ accept: "#draggable", - activeClass: "ui-state-hover", - hoverClass: "ui-state-active", + classes: { + "ui-droppable-active": "ui-state-active", + "ui-droppable-hover": "ui-state-hover" + }, drop: function( event, ui ) { $( this ) .addClass( "ui-state-highlight" ) diff --git a/demos/droppable/photo-manager.html b/demos/droppable/photo-manager.html index 6323e5d7baa..6a8cf33d18b 100644 --- a/demos/droppable/photo-manager.html +++ b/demos/droppable/photo-manager.html @@ -47,7 +47,9 @@ // let the trash be droppable, accepting the gallery items $trash.droppable({ accept: "#gallery > li", - activeClass: "ui-state-highlight", + classes: { + "ui-droppable-active": "ui-state-highlight" + }, drop: function( event, ui ) { deleteImage( ui.draggable ); } @@ -56,7 +58,9 @@ // let the gallery be droppable as well, accepting items from the trash $gallery.droppable({ accept: "#trash li", - activeClass: "custom-state-active", + classes: { + "ui-droppable-active": "custom-state-active" + }, drop: function( event, ui ) { recycleImage( ui.draggable ); } diff --git a/demos/droppable/propagation.html b/demos/droppable/propagation.html index 60cf7cb377e..99fb2171187 100644 --- a/demos/droppable/propagation.html +++ b/demos/droppable/propagation.html @@ -21,8 +21,10 @@ $( "#draggable" ).draggable(); $( "#droppable, #droppable-inner" ).droppable({ - activeClass: "ui-state-hover", - hoverClass: "ui-state-active", + classes: { + "ui-droppable-active": "ui-state-active", + "ui-droppable-hover": "ui-state-hover" + }, drop: function( event, ui ) { $( this ) .addClass( "ui-state-highlight" ) @@ -34,8 +36,10 @@ $( "#droppable2, #droppable2-inner" ).droppable({ greedy: true, - activeClass: "ui-state-hover", - hoverClass: "ui-state-active", + classes: { + "ui-droppable-active": "ui-state-active", + "ui-droppable-hover": "ui-state-hover" + }, drop: function( event, ui ) { $( this ) .addClass( "ui-state-highlight" ) diff --git a/demos/droppable/revert.html b/demos/droppable/revert.html index 74ccb6fc545..f34801e90a6 100644 --- a/demos/droppable/revert.html +++ b/demos/droppable/revert.html @@ -21,8 +21,10 @@ $( "#draggable2" ).draggable({ revert: "invalid" }); $( "#droppable" ).droppable({ - activeClass: "ui-state-default", - hoverClass: "ui-state-hover", + classes: { + "ui-droppable-active": "ui-state-active", + "ui-droppable-hover": "ui-state-hover" + }, drop: function( event, ui ) { $( this ) .addClass( "ui-state-highlight" ) diff --git a/demos/droppable/shopping-cart.html b/demos/droppable/shopping-cart.html index 0304004edc7..747c23a836e 100644 --- a/demos/droppable/shopping-cart.html +++ b/demos/droppable/shopping-cart.html @@ -28,8 +28,10 @@ helper: "clone" }); $( "#cart ol" ).droppable({ - activeClass: "ui-state-default", - hoverClass: "ui-state-hover", + classes: { + "ui-droppable-active": "ui-state-active", + "ui-droppable-hover": "ui-state-hover" + }, accept: ":not(.ui-sortable-helper)", drop: function( event, ui ) { $( this ).find( ".placeholder" ).remove(); diff --git a/demos/droppable/visual-feedback.html b/demos/droppable/visual-feedback.html index 9b197c56e07..9852f371b05 100644 --- a/demos/droppable/visual-feedback.html +++ b/demos/droppable/visual-feedback.html @@ -20,7 +20,9 @@ $(function() { $( "#draggable" ).draggable(); $( "#droppable" ).droppable({ - hoverClass: "ui-state-hover", + classes: { + "ui-droppable-hover": "ui-state-hover" + }, drop: function( event, ui ) { $( this ) .addClass( "ui-state-highlight" ) @@ -32,7 +34,9 @@ $( "#draggable2" ).draggable(); $( "#droppable2" ).droppable({ accept: "#draggable2", - activeClass: "ui-state-default", + classes: { + "ui-droppable-active": "ui-state-default" + }, drop: function( event, ui ) { $( this ) .addClass( "ui-state-highlight" ) @@ -66,7 +70,7 @@

Feedback on activating draggable:

-

Change the droppable's appearance on hover, or when the droppable is active (an acceptable draggable is dropped on it). Use the hoverClass or activeClass options to specify respective classes.

+

Change the droppable's appearance on hover, or when the droppable is active (an acceptable draggable is dropped on it). Set the values of the ui-droppable-hover or ui-droppable-active properties on the classes option to specify the respective classes.

diff --git a/tests/unit/droppable/droppable.html b/tests/unit/droppable/droppable.html index 03ff888e87b..52dc3d543da 100644 --- a/tests/unit/droppable/droppable.html +++ b/tests/unit/droppable/droppable.html @@ -5,6 +5,9 @@ jQuery UI Droppable Test Suite + diff --git a/tests/unit/droppable/droppable_common.js b/tests/unit/droppable/droppable_common.js index bd56aa35f9b..87d3ca1dba5 100644 --- a/tests/unit/droppable/droppable_common.js +++ b/tests/unit/droppable/droppable_common.js @@ -1,12 +1,10 @@ TestHelpers.commonWidgetTests( "droppable", { defaults: { accept: "*", - activeClass: false, addClasses: true, classes: {}, disabled: false, greedy: false, - hoverClass: false, scope: "default", tolerance: "intersect", diff --git a/tests/unit/droppable/droppable_common_deprecated.js b/tests/unit/droppable/droppable_common_deprecated.js new file mode 100644 index 00000000000..bd56aa35f9b --- /dev/null +++ b/tests/unit/droppable/droppable_common_deprecated.js @@ -0,0 +1,21 @@ +TestHelpers.commonWidgetTests( "droppable", { + defaults: { + accept: "*", + activeClass: false, + addClasses: true, + classes: {}, + disabled: false, + greedy: false, + hoverClass: false, + scope: "default", + tolerance: "intersect", + + // callbacks + activate: null, + create: null, + deactivate: null, + drop: null, + out: null, + over: null + } +}); diff --git a/tests/unit/droppable/droppable_deprecated.html b/tests/unit/droppable/droppable_deprecated.html new file mode 100644 index 00000000000..5af53a2f7b5 --- /dev/null +++ b/tests/unit/droppable/droppable_deprecated.html @@ -0,0 +1,47 @@ + + + + + jQuery UI Droppable Test Suite + + + + + + + + + + + + + + + + + + + + +
+
+ +
Draggable
+
Droppable
+
Droppable
+
 
+ +
+ + diff --git a/ui/droppable.js b/ui/droppable.js index a164f5522b6..98be34bab28 100644 --- a/ui/droppable.js +++ b/ui/droppable.js @@ -36,10 +36,8 @@ $.widget( "ui.droppable", { widgetEventPrefix: "drop", options: { accept: "*", - activeClass: false, addClasses: true, greedy: false, - hoverClass: false, scope: "default", tolerance: "intersect", @@ -80,7 +78,7 @@ $.widget( "ui.droppable", { this._addToManager( o.scope ); - o.addClasses && this.element.addClass( "ui-droppable" ); + o.addClasses && this._addClass( "ui-droppable" ); }, @@ -103,8 +101,6 @@ $.widget( "ui.droppable", { var drop = $.ui.ddmanager.droppables[ this.options.scope ]; this._splice( drop ); - - this.element.removeClass( "ui-droppable ui-droppable-disabled" ); }, _setOption: function( key, value ) { @@ -125,9 +121,8 @@ $.widget( "ui.droppable", { _activate: function( event ) { var draggable = $.ui.ddmanager.current; - if ( this.options.activeClass ) { - this.element.addClass( this.options.activeClass ); - } + + this._addActiveClass(); if ( draggable ){ this._trigger( "activate", event, this.ui( draggable ) ); } @@ -135,9 +130,8 @@ $.widget( "ui.droppable", { _deactivate: function( event ) { var draggable = $.ui.ddmanager.current; - if ( this.options.activeClass ) { - this.element.removeClass( this.options.activeClass ); - } + + this._removeActiveClass(); if ( draggable ){ this._trigger( "deactivate", event, this.ui( draggable ) ); } @@ -153,9 +147,7 @@ $.widget( "ui.droppable", { } if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { - if ( this.options.hoverClass ) { - this.element.addClass( this.options.hoverClass ); - } + this._addHoverClass(); this._trigger( "over", event, this.ui( draggable ) ); } @@ -171,9 +163,7 @@ $.widget( "ui.droppable", { } if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { - if ( this.options.hoverClass ) { - this.element.removeClass( this.options.hoverClass ); - } + this._removeHoverClass(); this._trigger( "out", event, this.ui( draggable ) ); } @@ -204,12 +194,9 @@ $.widget( "ui.droppable", { } if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { - if ( this.options.activeClass ) { - this.element.removeClass( this.options.activeClass ); - } - if ( this.options.hoverClass ) { - this.element.removeClass( this.options.hoverClass ); - } + this._removeActiveClass(); + this._removeHoverClass(); + this._trigger( "drop", event, this.ui( draggable ) ); return this.element; } @@ -225,8 +212,25 @@ $.widget( "ui.droppable", { position: c.position, offset: c.positionAbs }; - } + }, + // Extension points just to make backcompat sane and avoid duplicating logic + // TODO: Remove in 1.13 along with call to it below + _addHoverClass: function() { + this._addClass( "ui-droppable-hover" ); + }, + + _removeHoverClass: function() { + this._removeClass( "ui-droppable-hover" ); + }, + + _addActiveClass: function() { + this._addClass( "ui-droppable-active" ); + }, + + _removeActiveClass: function() { + this._removeClass( "ui-droppable-active" ); + } }); var intersect = (function() { @@ -413,6 +417,43 @@ $.ui.ddmanager = { } }; +// DEPRECATED +// TODO: switch return back to widget declaration at top of file when this is removed +if ( $.uiBackCompat !== false ) { + + // Backcompat for activeClass and hoverClass options + $.widget( "ui.droppable", $.ui.droppable, { + options: { + hoverClass: false, + activeClass: false + }, + _addActiveClass: function() { + this._super(); + if ( this.options.activeClass ) { + this.element.addClass( this.options.activeClass ); + } + }, + _removeActiveClass: function() { + this._super(); + if ( this.options.activeClass ) { + this.element.removeClass( this.options.activeClass ); + } + }, + _addHoverClass: function() { + this._super(); + if ( this.options.hoverClass ) { + this.element.addClass( this.options.hoverClass ); + } + }, + _removeHoverClass: function() { + this._super(); + if ( this.options.hoverClass ) { + this.element.removeClass( this.options.hoverClass ); + } + } + }); +} + return $.ui.droppable; })); From 587d58442921c643152c9693ad2edb50c19a84e9 Mon Sep 17 00:00:00 2001 From: Alexander Schmitz Date: Wed, 3 Dec 2014 11:24:44 -0500 Subject: [PATCH 08/36] Menu: Add classes option --- tests/unit/menu/menu.html | 15 ++++- tests/unit/menu/menu_core.js | 24 ++++--- ui/menu.js | 118 +++++++++++++++++------------------ 3 files changed, 88 insertions(+), 69 deletions(-) diff --git a/tests/unit/menu/menu.html b/tests/unit/menu/menu.html index 56115c3343c..114382587c5 100644 --- a/tests/unit/menu/menu.html +++ b/tests/unit/menu/menu.html @@ -9,6 +9,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ anchor + + aria-describedby + span + baz +
+ +
+ +
+ +
+ + diff --git a/tests/unit/tooltip/tooltip_deprecated.js b/tests/unit/tooltip/tooltip_deprecated.js new file mode 100644 index 00000000000..426f583ec6d --- /dev/null +++ b/tests/unit/tooltip/tooltip_deprecated.js @@ -0,0 +1,13 @@ +(function( $ ) { + +module( "tooltip: (deprecated) options" ); + +test( "tooltipClass", function() { + expect( 1 ); + var element = $( "#tooltipped1" ).tooltip({ + tooltipClass: "custom" + }).tooltip( "open" ); + ok( $( "#" + element.data( "ui-tooltip-id" ) ).hasClass( "custom" ) ); +}); + +}( jQuery ) ); diff --git a/tests/unit/tooltip/tooltip_options.js b/tests/unit/tooltip/tooltip_options.js index 32f7395446a..1d9d6b3f09d 100644 --- a/tests/unit/tooltip/tooltip_options.js +++ b/tests/unit/tooltip/tooltip_options.js @@ -166,14 +166,6 @@ test( "items", function() { element.tooltip( "destroy" ); }); -test( "tooltipClass", function() { - expect( 1 ); - var element = $( "#tooltipped1" ).tooltip({ - tooltipClass: "custom" - }).tooltip( "open" ); - ok( $( "#" + element.data( "ui-tooltip-id" ) ).hasClass( "custom" ) ); -}); - test( "track + show delay", function() { expect( 2 ); var event, diff --git a/tests/visual/tooltip/tooltip.html b/tests/visual/tooltip/tooltip.html index 8d5364d783c..034021cd8ec 100644 --- a/tests/visual/tooltip/tooltip.html +++ b/tests/visual/tooltip/tooltip.html @@ -22,10 +22,14 @@ // custom class, replaces ui-widget-content $( "#context2" ).tooltip({ - tooltipClass: "ui-widget-header" + classes: { + "ui-tooltip": "ui-corner-all ui-widget-header" + } }); $( "#right1" ).tooltip({ - tooltipClass: "ui-state-error" + classes: { + "ui-tooltip": "ui-corner-all ui-state-error" + } }); // synchronous content @@ -63,7 +67,9 @@ // custom position $( "#right2" ).tooltip({ - tooltipClass: "ui-state-highlight", + classes: { + "ui-tooltip": "ui-corner-all ui-state-highlight" + }, position: { my: "center top", at: "center bottom+10" diff --git a/ui/tooltip.js b/ui/tooltip.js index 2c28cc073e0..5708015d92b 100644 --- a/ui/tooltip.js +++ b/ui/tooltip.js @@ -33,9 +33,12 @@ } }(function( $ ) { -return $.widget( "ui.tooltip", { +$.widget( "ui.tooltip", { version: "@VERSION", options: { + classes: { + "ui-tooltip": "ui-corner-all ui-widget-shadow" + }, content: function() { // support: IE<9, Opera in jQuery <1.7 // .text() can't accept undefined, so coerce to a string @@ -52,7 +55,6 @@ return $.widget( "ui.tooltip", { collision: "flipfit flip" }, show: true, - tooltipClass: null, track: false, // callbacks @@ -109,8 +111,8 @@ return $.widget( "ui.tooltip", { "aria-live": "assertive", "aria-relevant": "additions" }) - .addClass( "ui-helper-hidden-accessible" ) .appendTo( this.document[ 0 ].body ); + this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); }, _setOption: function( key, value ) { @@ -419,16 +421,12 @@ return $.widget( "ui.tooltip", { }, _tooltip: function( element ) { - var tooltip = $( "
" ) - .attr( "role", "tooltip" ) - // TODO move to classes option - .addClass( "ui-tooltip ui-widget ui-widget-shadow ui-corner-all ui-widget-content " + - ( this.options.tooltipClass || "" ) ), + var tooltip = $( "
" ).attr( "role", "tooltip" ), + content = $( "
" ).appendTo( tooltip ), id = tooltip.uniqueId().attr( "id" ); - $( "
" ) - .addClass( "ui-tooltip-content" ) - .appendTo( tooltip ); + this._addClass( content, "ui-tooltip-content" ); + this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); tooltip.appendTo( this.document[0].body ); @@ -476,4 +474,25 @@ return $.widget( "ui.tooltip", { } }); +// DEPRECATED +// TODO: Switch return back to widget declaration at top of file when this is removed +if ( $.uiBackCompat !== false ) { + + // Backcompat for tooltipClass option + $.widget( "ui.tooltip", $.ui.tooltip, { + options: { + tooltipClass: null + }, + _tooltip: function() { + var tooltipData = this._superApply( arguments ); + if ( this.options.tooltipClass ) { + tooltipData.tooltip.addClass( this.options.tooltipClass ); + } + return tooltipData; + } + }); +} + +return $.ui.tooltip; + })); From 0d918c73d439d1ea20db0ffa5fb0902deef0263a Mon Sep 17 00:00:00 2001 From: Alexander Schmitz Date: Fri, 30 Jan 2015 09:53:26 -0500 Subject: [PATCH 18/36] Accordion: Use new has/lacksClasses assertions for all class checks --- tests/unit/accordion/accordion_core.js | 23 +++++++++++------------ tests/unit/accordion/accordion_methods.js | 7 ++++--- tests/unit/accordion/accordion_options.js | 12 ++++++------ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/unit/accordion/accordion_core.js b/tests/unit/accordion/accordion_core.js index 081ca78af95..80e8723aa01 100644 --- a/tests/unit/accordion/accordion_core.js +++ b/tests/unit/accordion/accordion_core.js @@ -6,7 +6,6 @@ var setupTeardown = TestHelpers.accordion.setupTeardown, module( "accordion: core", setupTeardown() ); $.each( { div: "#list1", ul: "#navigation", dl: "#accordion-dl" }, function( type, selector ) { - test( "markup structure: " + type, function( assert ) { expect( 10 ); var element = $( selector ).accordion(), @@ -114,7 +113,7 @@ test( "accessibility", function () { }); -asyncTest( "keyboard support", function() { +asyncTest( "keyboard support", function( assert ) { expect( 13 ); var element = $( "#list1" ).accordion(), headers = element.find( ".ui-accordion-header" ), @@ -123,23 +122,23 @@ asyncTest( "keyboard support", function() { equal( headers.filter( ".ui-state-focus" ).length, 0, "no headers focused on init" ); headers.eq( 0 ).simulate( "focus" ); setTimeout(function() { - ok( headers.eq( 0 ).is( ".ui-state-focus" ), "first header has focus" ); + assert.hasClasses( headers.eq( 0 ), "ui-state-focus", "first header has focus" ); headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.DOWN } ); - ok( headers.eq( 1 ).is( ".ui-state-focus" ), "DOWN moves focus to next header" ); + assert.hasClasses( headers.eq( 1 ), "ui-state-focus", "DOWN moves focus to next header" ); headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.RIGHT } ); - ok( headers.eq( 2 ).is( ".ui-state-focus" ), "RIGHT moves focus to next header" ); + assert.hasClasses( headers.eq( 2 ), "ui-state-focus", "RIGHT moves focus to next header" ); headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.DOWN } ); - ok( headers.eq( 0 ).is( ".ui-state-focus" ), "DOWN wraps focus to first header" ); + assert.hasClasses( headers.eq( 0 ), "ui-state-focus", "DOWN wraps focus to first header" ); headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.UP } ); - ok( headers.eq( 2 ).is( ".ui-state-focus" ), "UP wraps focus to last header" ); + assert.hasClasses( headers.eq( 2 ), "ui-state-focus", "UP wraps focus to last header" ); headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.LEFT } ); - ok( headers.eq( 1 ).is( ".ui-state-focus" ), "LEFT moves focus to previous header" ); + assert.hasClasses( headers.eq( 1 ), "ui-state-focus", "LEFT moves focus to previous header" ); headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.HOME } ); - ok( headers.eq( 0 ).is( ".ui-state-focus" ), "HOME moves focus to first header" ); + assert.hasClasses( headers.eq( 0 ), "ui-state-focus", "HOME moves focus to first header" ); headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.END } ); - ok( headers.eq( 2 ).is( ".ui-state-focus" ), "END moves focus to last header" ); + assert.hasClasses( headers.eq( 2 ), "ui-state-focus", "END moves focus to last header" ); headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.ENTER } ); equal( element.accordion( "option", "active" ) , 2, "ENTER activates panel" ); @@ -148,9 +147,9 @@ asyncTest( "keyboard support", function() { anchor.simulate( "focus" ); setTimeout(function() { - ok( !headers.eq( 1 ).is( ".ui-state-focus" ), "header loses focus when focusing inside the panel" ); + assert.lacksClasses( headers.eq( 1 ), "ui-state-focus", "header loses focus when focusing inside the panel" ); anchor.simulate( "keydown", { keyCode: keyCode.UP, ctrlKey: true } ); - ok( headers.eq( 1 ).is( ".ui-state-focus" ), "CTRL+UP moves focus to header" ); + assert.hasClasses( headers.eq( 1 ), "ui-state-focus", "CTRL+UP moves focus to header" ); start(); }, 1 ); }, 1 ); diff --git a/tests/unit/accordion/accordion_methods.js b/tests/unit/accordion/accordion_methods.js index 1e809b310c2..b599263322c 100644 --- a/tests/unit/accordion/accordion_methods.js +++ b/tests/unit/accordion/accordion_methods.js @@ -13,15 +13,16 @@ test( "destroy", function() { }); }); -test( "enable/disable", function() { +test( "enable/disable", function( assert ) { expect( 7 ); var element = $( "#list1" ).accordion(); state( element, 1, 0, 0 ); element.accordion( "disable" ); - ok( element.hasClass( "ui-state-disabled" ), "element gets ui-state-disabled" ); + assert.hasClasses( element, "ui-state-disabled" ); + equal( element.attr( "aria-disabled" ), "true", "element gets aria-disabled" ); - ok( element.hasClass( "ui-accordion-disabled" ), "element gets ui-accordion-disabled" ); + assert.hasClasses( element, "ui-accordion-disabled" ); // event does nothing element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "click" ); diff --git a/tests/unit/accordion/accordion_options.js b/tests/unit/accordion/accordion_options.js index 214753e40bf..689c6facef3 100644 --- a/tests/unit/accordion/accordion_options.js +++ b/tests/unit/accordion/accordion_options.js @@ -349,13 +349,13 @@ test( "{ header: default }", function() { state( $( "#navigation" ).accordion(), 1, 0, 0); }); -test( "{ header: custom }", function() { +test( "{ header: custom }", function( assert ) { expect( 6 ); var element = $( "#navigationWrapper" ).accordion({ header: "h2" }); element.find( "h2" ).each(function() { - ok( $( this ).hasClass( "ui-accordion-header" ) ); + assert.hasClasses( this, "ui-accordion-header" ); }); equal( element.find( ".ui-accordion-header" ).length, 3 ); state( element, 1, 0, 0 ); @@ -449,15 +449,15 @@ test( "{ icons: false }", function() { icons( false ); }); -test( "{ icons: hash }", function() { +test( "{ icons: hash }", function( assert ) { expect( 3 ); var element = $( "#list1" ).accordion({ icons: { activeHeader: "a1", header: "h1" } }); - ok( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ).hasClass( "a1" ) ); + assert.hasClasses( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ), "a1" ); element.accordion( "option", "icons", { activeHeader: "a2", header: "h2" } ); - ok( !element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ).hasClass( "a1" ) ); - ok( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ).hasClass( "a2" ) ); + assert.lacksClasses( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ), "a1"); + assert.hasClasses( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ), "a2" ); }); }( jQuery ) ); From b29cae3bc2dadd5e0098014b1090057b3f9c6096 Mon Sep 17 00:00:00 2001 From: Alexander Schmitz Date: Fri, 30 Jan 2015 09:56:42 -0500 Subject: [PATCH 19/36] Autocomplete: Use new has/lacksClasses assertions for all class checks --- tests/unit/autocomplete/autocomplete_methods.js | 4 ++-- tests/unit/autocomplete/autocomplete_options.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/unit/autocomplete/autocomplete_methods.js b/tests/unit/autocomplete/autocomplete_methods.js index 1bfa1055428..bbd016ff29b 100644 --- a/tests/unit/autocomplete/autocomplete_methods.js +++ b/tests/unit/autocomplete/autocomplete_methods.js @@ -34,12 +34,12 @@ test( "search, close", function() { ok( menu.is( ":hidden" ), "menu is hidden after close" ); }); -test( "widget", function() { +test( "widget", function( assert ) { expect( 2 ); var element = $( "#autocomplete" ).autocomplete(), widgetElement = element.autocomplete( "widget" ); equal( widgetElement.length, 1, "one element" ); - ok( widgetElement.is( ".ui-menu" ), "menu element" ); + assert.hasClasses( widgetElement, "ui-menu" ); }); }( jQuery ) ); diff --git a/tests/unit/autocomplete/autocomplete_options.js b/tests/unit/autocomplete/autocomplete_options.js index 4b4957222b4..af9a424e9a3 100644 --- a/tests/unit/autocomplete/autocomplete_options.js +++ b/tests/unit/autocomplete/autocomplete_options.js @@ -115,7 +115,7 @@ asyncTest( "delay", function() { }, 50 ); }); -asyncTest( "disabled", function() { +asyncTest( "disabled", function( assert ) { expect( 5 ); var element = $( "#autocomplete" ).autocomplete({ source: data, @@ -126,9 +126,9 @@ asyncTest( "disabled", function() { ok( menu.is( ":hidden" ) ); - ok( !element.is( ".ui-state-disabled" ), "element doesn't get ui-state-disabled" ); + assert.lacksClasses( element, "ui-state-disabled" ); + assert.hasClasses( menu, "ui-autocomplete-disabled" ); ok( !element.attr( "aria-disabled" ), "element doesn't get aria-disabled" ); - ok( menu.is( ".ui-autocomplete-disabled" ), "element gets ui-autocomplete-disabled" ); setTimeout(function() { ok( menu.is( ":hidden" ) ); From 67e84335283ca4369d4989f9ec3dfb7dc65ac09f Mon Sep 17 00:00:00 2001 From: Alexander Schmitz Date: Mon, 2 Feb 2015 19:25:52 -0500 Subject: [PATCH 20/36] Button: Use new has/lacksClasses assertions for all class checks --- tests/unit/button/button.html | 1 + tests/unit/button/button_core.js | 100 +++++++++++++++------------- tests/unit/button/button_events.js | 4 +- tests/unit/button/button_options.js | 22 +++--- 4 files changed, 66 insertions(+), 61 deletions(-) diff --git a/tests/unit/button/button.html b/tests/unit/button/button.html index abda5c987f0..679c316bfb7 100644 --- a/tests/unit/button/button.html +++ b/tests/unit/button/button.html @@ -9,6 +9,7 @@ + - + diff --git a/tests/unit/dialog/dialog_deprecated.js b/tests/unit/dialog/dialog_deprecated.js index 6a26c229ebc..55c18045739 100644 --- a/tests/unit/dialog/dialog_deprecated.js +++ b/tests/unit/dialog/dialog_deprecated.js @@ -2,26 +2,25 @@ module( "dialog (deprecated): options" ); -test( "dialogClass", function() { - expect( 6 ); +test( "dialogClass", function( assert ) { + expect( 5 ); var element = $( "
" ).dialog(), widget = element.dialog( "widget" ); - equal( widget.is( ".foo" ), false, "dialogClass not specified. class not added" ); + assert.lacksClasses( widget, "foo", "dialogClass not specified. class not added" ); element.remove(); element = $( "
" ).dialog({ dialogClass: "foo" }); widget = element.dialog( "widget" ); - equal( widget.is( ".foo" ), true, "dialogClass in init, foo class added" ); + assert.hasClasses( widget, "foo", "dialogClass in init, foo class added" ); element.dialog( "option", "dialogClass", "foobar" ); - equal( widget.is( ".foo" ), false, "dialogClass changed, previous one was removed" ); - equal( widget.is( ".foobar" ), true, "dialogClass changed, new one was added" ); + assert.lacksClasses( widget, "foo", "dialogClass changed, previous one was removed" ); + assert.hasClasses( widget, "foobar", "dialogClass changed, new one was added" ); element.remove(); element = $( "
" ).dialog({ dialogClass: "foo bar" }); widget = element.dialog( "widget" ); - equal( widget.is( ".foo" ), true, "dialogClass in init, two classes. foo class added" ); - equal( widget.is( ".bar" ), true, "dialogClass in init, two classes. bar class added" ); + assert.hasClasses( widget, "foo bar", "dialogClass in init, two classes." ); element.remove(); }); diff --git a/tests/unit/dialog/dialog_methods.js b/tests/unit/dialog/dialog_methods.js index ea4a7002a22..c012f80a540 100644 --- a/tests/unit/dialog/dialog_methods.js +++ b/tests/unit/dialog/dialog_methods.js @@ -100,13 +100,12 @@ test("#4980: Destroy should place element back in original DOM position", functi ok($.contains(container[0], modal[0]), "dialog(destroy) should place element back in original DOM position"); }); -test( "enable/disable disabled", function() { - expect( 4 ); +test( "enable/disable disabled", function( assert ) { + expect( 3 ); var element = $( "
" ).dialog(); element.dialog( "disable" ); equal(element.dialog( "option", "disabled" ), false, "disable method doesn't do anything" ); - ok( !element.dialog( "widget" ).hasClass( "ui-dialog-disabled" ), "disable method doesn't add ui-dialog-disabled class" ); - ok( !element.dialog( "widget" ).hasClass( "ui-state-disabled" ), "disable method doesn't add ui-state-disabled class" ); + assert.lacksClasses( element, "ui-dialog-disabled ui-state-disabled" ); ok( !element.dialog( "widget" ).attr( "aria-disabled" ), "disable method doesn't add aria-disabled" ); }); diff --git a/tests/unit/dialog/dialog_options.js b/tests/unit/dialog/dialog_options.js index 77ca09703a7..3b18df5601d 100644 --- a/tests/unit/dialog/dialog_options.js +++ b/tests/unit/dialog/dialog_options.js @@ -78,7 +78,7 @@ test("autoOpen", function() { element.remove(); }); -test("buttons", function() { +test("buttons", function( assert ) { expect(21); var btn, i, newButtons, @@ -105,8 +105,8 @@ test("buttons", function() { i++; }); - ok(btn.parent().hasClass("ui-dialog-buttonset"), "buttons in container"); - ok(element.parent().hasClass("ui-dialog-buttons"), "dialog wrapper adds class about having buttons"); + assert.hasClasses( btn.parent(), "ui-dialog-buttonset" ); + assert.hasClasses( element.parent(), "ui-dialog-buttons" ); btn.trigger("click"); @@ -136,12 +136,11 @@ test("buttons", function() { btn = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); equal(btn.length, 0, "all buttons have been removed"); equal(element.find(".ui-dialog-buttonset").length, 0, "buttonset has been removed"); - equal(element.parent().hasClass("ui-dialog-buttons"), false, "dialog wrapper removes class about having buttons"); - + assert.lacksClasses( element.parent(), "ui-dialog-buttons" ); element.remove(); }); -test("buttons - advanced", function() { +test("buttons - advanced", function( assert ) { expect( 7 ); var buttons, @@ -166,7 +165,7 @@ test("buttons - advanced", function() { equal(buttons.length, 1, "correct number of buttons"); equal(buttons.attr("id"), "my-button-id", "correct id"); equal(buttons.text(), "a button", "correct label"); - ok(buttons.hasClass("additional-class"), "additional classes added"); + assert.hasClasses( buttons, "additional-class" ); deepEqual( buttons.button("option", "icons"), { primary: "ui-icon-cancel", secondary: null } ); equal( buttons.button( "option", "text" ), false ); buttons.click(); From 3e411a486a8aa5225a8731c128b1861f55b19fe2 Mon Sep 17 00:00:00 2001 From: Alexander Schmitz Date: Fri, 30 Jan 2015 09:57:30 -0500 Subject: [PATCH 22/36] Draggable: Use new has/lacksClasses assertions for all class checks --- tests/unit/dialog/dialog_methods.js | 2 +- tests/unit/draggable/draggable.html | 1 + tests/unit/draggable/draggable_core.js | 23 +++++++++++------------ tests/unit/draggable/draggable_methods.js | 6 +++--- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/unit/dialog/dialog_methods.js b/tests/unit/dialog/dialog_methods.js index c012f80a540..c92f1f1b4a7 100644 --- a/tests/unit/dialog/dialog_methods.js +++ b/tests/unit/dialog/dialog_methods.js @@ -105,7 +105,7 @@ test( "enable/disable disabled", function( assert ) { var element = $( "
" ).dialog(); element.dialog( "disable" ); equal(element.dialog( "option", "disabled" ), false, "disable method doesn't do anything" ); - assert.lacksClasses( element, "ui-dialog-disabled ui-state-disabled" ); + assert.lacksClasses( element, "ui-dialog-disabled ui-state-disabled", "disable method doesn't add classes" ); ok( !element.dialog( "widget" ).attr( "aria-disabled" ), "disable method doesn't add aria-disabled" ); }); diff --git a/tests/unit/draggable/draggable.html b/tests/unit/draggable/draggable.html index eb4985adc37..a8fdf91ca5b 100644 --- a/tests/unit/draggable/draggable.html +++ b/tests/unit/draggable/draggable.html @@ -68,6 +68,7 @@ + + + + + + - - - - - - - - - - - - - -
-

Products

-
-

T-Shirts

-
-
    -
  • Lolcat Shirt
  • -
  • Cheezeburger Shirt
  • -
  • Buckit Shirt
  • -
-
-

Bags

-
-
    -
  • Zebra Striped
  • -
  • Black Leather
  • -
  • Alligator Leather
  • -
-
-

Gadgets

-
-
    -
  • iPhone
  • -
  • iPod
  • -
  • iPad
  • -
-
-
-
- -
-

Shopping Cart

-
-
    -
  1. Add your items here
  2. -
-
-
- -
-

Demonstrate how to use an accordion to structure products into a catalog and make use of drag and drop for adding them to a shopping cart, where they are sortable.

-
- -