From 8201c1392863eb9e13204854ad393c023fdeba94 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 4 May 2011 08:20:41 +0200 Subject: Popup: Update popup test --- tests/visual/menu/popup.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/visual/menu/popup.html b/tests/visual/menu/popup.html index 271002a20..52a5bdd98 100644 --- a/tests/visual/menu/popup.html +++ b/tests/visual/menu/popup.html @@ -76,7 +76,7 @@ width: 200px; height: 150px; border: 1px solid gray; border-radius: 5px; box-shadow: 3px 3px 5px -1px rgba(0, 0, 0, 0.5); background: lightgray; background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#ddd)); - font-size: 120%; text-align: center; line-height: 150px; + font-size: 120%; text-align: center; line-height: 150px; outline: none; } -- cgit v1.2.3 From f519bc0ebb3426cfaa0c918429781586abd87872 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 4 May 2011 08:31:14 +0200 Subject: Menubar review --- tests/visual/menu/menubar.js | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/visual/menu/menubar.js b/tests/visual/menu/menubar.js index cc3258d4a..a8265e69b 100644 --- a/tests/visual/menu/menubar.js +++ b/tests/visual/menu/menubar.js @@ -1,11 +1,11 @@ /* * jQuery UI menubar - * - * backported from Michael Lang's fork: http://www.nexul.com/prototypes/toolbar/demo.html + * + * TODO move to jquery.ui.menubar.js */ (function($) { -// TODO take non-menubar buttons into account +// TODO code formatting $.widget("ui.menubar", { options: { buttons: false, @@ -23,12 +23,14 @@ $.widget("ui.menubar", { this.element.addClass('ui-menubar ui-widget-header ui-helper-clearfix').attr("role", "menubar"); this._focusable(items); this._hoverable(items); + // TODO elm is used just once, so the each probably isn't nedded anymore items.next("ul").each(function(i, elm) { $(elm).menu({ select: function(event, ui) { ui.item.parents("ul.ui-menu:last").hide(); self._trigger( "select", event, ui ); self._close(); + // TODO what is this targetting? there's probably a better way to access it $(event.target).prev().focus(); } }).hide() @@ -60,6 +62,8 @@ $.widget("ui.menubar", { return; } event.preventDefault(); + // TODO can we simplify or extractthis check? especially the last two expressions + // there's a similar active[0] == menu[0] check in _open if (event.type == "click" && menu.is(":visible") && self.active && self.active[0] == menu[0]) { self._close(); return; @@ -90,19 +94,22 @@ $.widget("ui.menubar", { .attr("role", "menuitem") .attr("aria-haspopup", "true") .wrapInner(""); - + + // TODO review if these options are a good choice, maybe they can be merged if (o.menuIcon) { input.addClass("ui-state-default").append(""); input.removeClass("ui-button-text-only").addClass("ui-button-text-icon-secondary"); } if (!o.buttons) { + // TODO ui-menubar-link is added above, not needed here? input.addClass('ui-menubar-link').removeClass('ui-state-default'); }; }); self._bind({ keydown: function(event) { + // TODO merge the two ifs if (event.keyCode == $.ui.keyCode.ESCAPE) { if (self.active && self.active.menu("left", event) !== true) { var active = self.active; @@ -117,6 +124,7 @@ $.widget("ui.menubar", { self._close( event ); }, 100); }, + // TODO change order, focusin first focusin :function( event ) { clearTimeout(self.closeTimer); } @@ -150,8 +158,7 @@ $.widget("ui.menubar", { .removeAttr("aria-hidden", "true") .removeAttr("aria-expanded", "false") .removeAttr("tabindex") - .unbind("keydown", "blur") - ; + .unbind("keydown", "blur"); }, _close: function() { @@ -182,12 +189,13 @@ $.widget("ui.menubar", { }) .removeAttr("aria-hidden").attr("aria-expanded", "true") .menu("focus", event, menu.children("li").first()) + // TODO need a comment here why both events are triggered .focus() - .focusin() - ; + .focusin(); this.open = true; }, + // TODO refactor this and the next three methods _prev: function( event, button ) { button.attr("tabIndex", -1); var prev = button.parent().prevAll("li").children( ".ui-button" ).eq( 0 ); @@ -209,7 +217,8 @@ $.widget("ui.menubar", { firstItem.removeAttr("tabIndex")[0].focus(); } }, - + + // TODO rename to parent _left: function(event) { var prev = this.active.parent().prevAll("li:eq(0)").children( ".ui-menu" ).eq( 0 ); if (prev.length) { @@ -220,6 +229,7 @@ $.widget("ui.menubar", { } }, + // TODO rename to child (or something like that) _right: function(event) { var next = this.active.parent().nextAll("li:eq(0)").children( ".ui-menu" ).eq( 0 ); if (next.length) { -- cgit v1.2.3 From bba4cb2be68ae6ca71be987bf13f8c7834242221 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 4 May 2011 11:06:32 +0200 Subject: Popup: Partial fix for closing popup when trigger is clicked again. --- tests/visual/menu/popup.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/visual/menu/popup.js b/tests/visual/menu/popup.js index f57cba699..947888eec 100644 --- a/tests/visual/menu/popup.js +++ b/tests/visual/menu/popup.js @@ -39,6 +39,10 @@ $.widget( "ui.popup", { this._bind(this.options.trigger, { click: function( event ) { event.preventDefault(); + if (this.open) { + // let it propagate to close + return; + } var that = this; setTimeout(function() { that._open( event ); @@ -47,10 +51,14 @@ $.widget( "ui.popup", { }); this._bind(this.element, { - blur: "_close" + // TODO also triggered when open and clicking the trigger again + // figure out how to close in that case, while still closing on regular blur + //blur: "_close" }); this._bind({ + // TODO only triggerd on element if it can receive focus + // bind to document instead? keyup: function( event ) { if (event.keyCode == $.ui.keyCode.ESCAPE && this.element.is( ":visible" )) { this._close( event ); -- cgit v1.2.3 From b96126b398777b5ed2ecf795c234f99c544ee61c Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 4 May 2011 11:14:32 +0200 Subject: Popup: Rename _close to close and use it when selecting something within a popup. --- demos/tooltip/video-player.html | 8 ++++++-- tests/visual/menu/popup.html | 2 +- tests/visual/menu/popup.js | 10 +++++----- 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/demos/tooltip/video-player.html b/demos/tooltip/video-player.html index c890c76b4..2e2419760 100644 --- a/demos/tooltip/video-player.html +++ b/demos/tooltip/video-player.html @@ -24,8 +24,12 @@ }); $(".set").buttonset(); - // TODO hide the tooltip when clicking the button - $("ul").menu().popup({ + $("ul").menu({ + select: function() { + // would also execute some other action here + $(this).popup("close"); + } + }).popup({ trigger: $(".menu") }); diff --git a/tests/visual/menu/popup.html b/tests/visual/menu/popup.html index 52a5bdd98..2a712b00a 100644 --- a/tests/visual/menu/popup.html +++ b/tests/visual/menu/popup.html @@ -25,7 +25,7 @@ var selected = { select: function( event, ui ) { $( "
" ).text( "Selected: " + ui.item.text() ).appendTo( "#log" ); - $(this).hide(); + $(this).popup("close"); } }; diff --git a/tests/visual/menu/popup.js b/tests/visual/menu/popup.js index 947888eec..503bb93b7 100644 --- a/tests/visual/menu/popup.js +++ b/tests/visual/menu/popup.js @@ -34,7 +34,7 @@ $.widget( "ui.popup", { this.element .addClass("ui-popup") - this._close(); + this.close(); this._bind(this.options.trigger, { click: function( event ) { @@ -53,7 +53,7 @@ $.widget( "ui.popup", { this._bind(this.element, { // TODO also triggered when open and clicking the trigger again // figure out how to close in that case, while still closing on regular blur - //blur: "_close" + //blur: "close" }); this._bind({ @@ -61,7 +61,7 @@ $.widget( "ui.popup", { // bind to document instead? keyup: function( event ) { if (event.keyCode == $.ui.keyCode.ESCAPE && this.element.is( ":visible" )) { - this._close( event ); + this.close( event ); this.options.trigger.focus(); } } @@ -70,7 +70,7 @@ $.widget( "ui.popup", { this._bind(document, { click: function( event ) { if (this.open && !$(event.target).closest(".ui-popup").length) { - this._close( event ); + this.close( event ); } } }) @@ -114,7 +114,7 @@ $.widget( "ui.popup", { this._trigger( "open", event ); }, - _close: function( event ) { + close: function( event ) { this.element .hide() .attr( "aria-hidden", true ) -- cgit v1.2.3 From 018590064f43c4003fe7be767f5c1d666e38b22a Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 4 May 2011 11:20:04 +0200 Subject: Popup: Prevent SPACE key event on trigger from scrolling the page --- tests/visual/menu/popup.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tests') diff --git a/tests/visual/menu/popup.js b/tests/visual/menu/popup.js index 503bb93b7..a29904877 100644 --- a/tests/visual/menu/popup.js +++ b/tests/visual/menu/popup.js @@ -37,6 +37,12 @@ $.widget( "ui.popup", { this.close(); this._bind(this.options.trigger, { + keydown: function( event ) { + // prevent space-to-open to scroll the page + if (event.keyCode == $.ui.keyCode.SPACE) { + event.preventDefault() + } + }, click: function( event ) { event.preventDefault(); if (this.open) { -- cgit v1.2.3 From c7459df0622e8d1a4e5fcb56eac496eae60e5083 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 4 May 2011 11:21:30 +0200 Subject: Popup: Also expose open method --- tests/visual/menu/popup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/visual/menu/popup.js b/tests/visual/menu/popup.js index a29904877..dc81b694c 100644 --- a/tests/visual/menu/popup.js +++ b/tests/visual/menu/popup.js @@ -51,7 +51,7 @@ $.widget( "ui.popup", { } var that = this; setTimeout(function() { - that._open( event ); + that.open( event ); }, 1); } }); @@ -101,7 +101,7 @@ $.widget( "ui.popup", { } }, - _open: function( event ) { + open: function( event ) { var position = $.extend( {}, { of: this.options.trigger }, this.options.position ); -- cgit v1.2.3 From fd1b4f84feb92b5e0684b3fb66ccc0a57caafaab Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 4 May 2011 11:50:07 +0200 Subject: Menubar: Code formatting. A bit of cleanup: Replace self with that; replace an unnecessary each. --- tests/visual/menu/menubar.js | 288 +++++++++++++++++++++++-------------------- 1 file changed, 153 insertions(+), 135 deletions(-) (limited to 'tests') diff --git a/tests/visual/menu/menubar.js b/tests/visual/menu/menubar.js index a8265e69b..b9abacb9b 100644 --- a/tests/visual/menu/menubar.js +++ b/tests/visual/menu/menubar.js @@ -3,242 +3,260 @@ * * TODO move to jquery.ui.menubar.js */ -(function($) { +(function( $ ) { -// TODO code formatting -$.widget("ui.menubar", { +// TODO when mixing clicking menus and keyboard navigation, focus handling is broken +// there has to be just one item that has tabindex +$.widget( "ui.menubar", { options: { buttons: false, menuIcon: false }, _create: function() { - var self = this; - var items = this.items = this.element.children("li") - .addClass("ui-menubar-item") - .attr("role", "presentation") - .children("button, a"); - items.slice(1).attr("tabIndex", -1); - var o = this.options; - - this.element.addClass('ui-menubar ui-widget-header ui-helper-clearfix').attr("role", "menubar"); - this._focusable(items); - this._hoverable(items); - // TODO elm is used just once, so the each probably isn't nedded anymore - items.next("ul").each(function(i, elm) { - $(elm).menu({ - select: function(event, ui) { - ui.item.parents("ul.ui-menu:last").hide(); - self._trigger( "select", event, ui ); - self._close(); + var that = this; + var items = this.items = this.element.children( "li" ) + .addClass( "ui-menubar-item" ) + .attr( "role", "presentation" ) + .children( "button, a" ); + // let only the first item receive focus + items.slice(1).attr( "tabIndex", -1 ); + + this.element + .addClass( "ui-menubar ui-widget-header ui-helper-clearfix" ) + .attr( "role", "menubar" ); + this._focusable( items ); + this._hoverable( items ); + items.next( "ul" ) + .menu({ + select: function( event, ui ) { + ui.item.parents( "ul.ui-menu:last" ).hide(); + that._trigger( "select", event, ui ); + that._close(); // TODO what is this targetting? there's probably a better way to access it $(event.target).prev().focus(); } - }).hide() - .attr("aria-hidden", "true") - .attr("aria-expanded", "false") - .keydown(function(event) { - var menu = $(this); - if (menu.is(":hidden")) + }) + .hide() + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ) + .bind( "keydown.menubar", function( event ) { + var menu = $( this ); + if ( menu.is( ":hidden" ) ) return; - switch (event.keyCode) { + switch ( event.keyCode ) { case $.ui.keyCode.LEFT: - self._left(event); + that._left( event ); event.preventDefault(); break; case $.ui.keyCode.RIGHT: - self._right(event); + that._right( event ); event.preventDefault(); break; }; - }) - }); + }); items.each(function() { var input = $(this), - menu = input.next("ul"); + // TODO menu var is only used on two places, doesn't quite justify the .each + menu = input.next( "ul" ); - input.bind("click focus mouseenter", function(event) { + input.bind( "click.menubar focus.menubar mouseenter.menubar", function( event ) { // ignore triggered focus event - if (event.type == "focus" && !event.originalEvent) { + if ( event.type == "focus" && !event.originalEvent ) { return; } event.preventDefault(); // TODO can we simplify or extractthis check? especially the last two expressions // there's a similar active[0] == menu[0] check in _open - if (event.type == "click" && menu.is(":visible") && self.active && self.active[0] == menu[0]) { - self._close(); + if ( event.type == "click" && menu.is( ":visible" ) && that.active && that.active[0] == menu[0] ) { + that._close(); return; } - if ((self.open && event.type == "mouseenter") || event.type == "click") { - self._open(event, menu); - } + if ( ( that.open && event.type == "mouseenter" ) || event.type == "click" ) { + that._open( event, menu ); + } }) .bind( "keydown", function( event ) { switch ( event.keyCode ) { case $.ui.keyCode.SPACE: case $.ui.keyCode.UP: case $.ui.keyCode.DOWN: - self._open( event, $( this ).next() ); + that._open( event, $( this ).next() ); event.preventDefault(); break; case $.ui.keyCode.LEFT: - self._prev( event, $( this ) ); + that._prev( event, $( this ) ); event.preventDefault(); break; case $.ui.keyCode.RIGHT: - self._next( event, $( this ) ); + that._next( event, $( this ) ); event.preventDefault(); break; } }) - .addClass("ui-button ui-widget ui-button-text-only ui-menubar-link") - .attr("role", "menuitem") - .attr("aria-haspopup", "true") - .wrapInner(""); + .addClass( "ui-button ui-widget ui-button-text-only ui-menubar-link" ) + .attr( "role", "menuitem" ) + .attr( "aria-haspopup", "true" ) + .wrapInner( "" ); // TODO review if these options are a good choice, maybe they can be merged - if (o.menuIcon) { - input.addClass("ui-state-default").append(""); - input.removeClass("ui-button-text-only").addClass("ui-button-text-icon-secondary"); + if ( that.options.menuIcon ) { + input.addClass( "ui-state-default" ).append( "" ); + input.removeClass( "ui-button-text-only" ).addClass( "ui-button-text-icon-secondary" ); } - if (!o.buttons) { + if ( !that.options.buttons ) { // TODO ui-menubar-link is added above, not needed here? - input.addClass('ui-menubar-link').removeClass('ui-state-default'); + input.addClass( "ui-menubar-link" ).removeClass( "ui-state-default" ); }; }); - self._bind({ - keydown: function(event) { - // TODO merge the two ifs - if (event.keyCode == $.ui.keyCode.ESCAPE) { - if (self.active && self.active.menu("left", event) !== true) { - var active = self.active; - self.active.blur(); - self._close( event ); - active.prev().focus(); - } + that._bind( { + keydown: function( event ) { + if ( event.keyCode == $.ui.keyCode.ESCAPE && that.active && that.active.menu( "left", event ) !== true ) { + var active = that.active; + that.active.blur(); + that._close( event ); + active.prev().focus(); } }, - focusout : function( event ) { - self.closeTimer = setTimeout(function() { - self._close( event ); - }, 100); + focusin: function( event ) { + clearTimeout( that.closeTimer ); }, - // TODO change order, focusin first - focusin :function( event ) { - clearTimeout(self.closeTimer); + focusout: function( event ) { + that.closeTimer = setTimeout( function() { + that._close( event ); + }, 100); } }); }, _destroy : function() { - var items = this.element.children("li") - .removeClass("ui-menubar-item") - .removeAttr("role", "presentation") - .children("button, a"); + var items = this.element.children( "li" ) + .removeClass( "ui-menubar-item" ) + .removeAttr( "role", "presentation" ) + .children( "button, a" ); - this.element.removeClass('ui-menubar ui-widget-header ui-helper-clearfix').removeAttr("role", "menubar").unbind(".menubar");; - items.unbind("focusin focusout click focus mouseenter keydown"); + this.element + .removeClass( "ui-menubar ui-widget-header ui-helper-clearfix" ) + .removeAttr( "role", "menubar" ) + .unbind( ".menubar" ); items - .removeClass("ui-button ui-widget ui-button-text-only ui-menubar-link ui-state-default") - .removeAttr("role", "menuitem") - .removeAttr("aria-haspopup", "true") - .children("span.ui-button-text").each(function(i, e) { - var item = $(this); - item.parent().html(item.html()); + .unbind( ".menubar" ) + .removeClass( "ui-button ui-widget ui-button-text-only ui-menubar-link ui-state-default" ) + .removeAttr( "role", "menuitem" ) + .removeAttr( "aria-haspopup", "true" ) + // TODO unwrap? + .children( "span.ui-button-text" ).each(function( i, e ) { + var item = $( this ); + item.parent().html( item.html() ); }) .end() - .children(".ui-icon").remove(); + .children( ".ui-icon" ).remove(); - $(document).unbind(".menubar"); - - this.element.find(":ui-menu").menu("destroy") - .show() - .removeAttr("aria-hidden", "true") - .removeAttr("aria-expanded", "false") - .removeAttr("tabindex") - .unbind("keydown", "blur"); + this.element.find( ":ui-menu" ) + .menu( "destroy" ) + .show() + .removeAttr( "aria-hidden", "true" ) + .removeAttr( "aria-expanded", "false" ) + .removeAttr( "tabindex" ) + .unbind( ".menubar" ); }, _close: function() { - if (!this.active || !this.active.length) + if ( !this.active || !this.active.length ) return; - this.active.menu("closeAll").hide().attr("aria-hidden", "true").attr("aria-expanded", "false"); - this.active.prev().removeClass("ui-state-active").removeAttr("tabIndex"); + this.active + .menu( "closeAll" ) + .hide() + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ); + this.active + .prev() + .removeClass( "ui-state-active" ) + .removeAttr( "tabIndex" ); this.active = null; this.open = false; }, - _open: function(event, menu) { + _open: function( event, menu ) { // on a single-button menubar, ignore reopening the same menu - if (this.active && this.active[0] == menu[0]) { + if ( this.active && this.active[0] == menu[0] ) { return; } - // almost the same as _close above, but don't remove tabIndex - if (this.active) { - this.active.menu("closeAll").hide().attr("aria-hidden", "true").attr("aria-expanded", "false"); - this.active.prev().removeClass("ui-state-active"); + // TODO refactor, almost the same as _close above, but don't remove tabIndex + if ( this.active ) { + this.active + .menu( "closeAll" ) + .hide() + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ); + this.active + .prev() + .removeClass( "ui-state-active" ); } // set tabIndex -1 to have the button skipped on shift-tab when menu is open (it gets focus) - var button = menu.prev().addClass("ui-state-active").attr("tabIndex", -1); - this.active = menu.show().position({ - my: "left top", - at: "left bottom", - of: button - }) - .removeAttr("aria-hidden").attr("aria-expanded", "true") - .menu("focus", event, menu.children("li").first()) - // TODO need a comment here why both events are triggered - .focus() - .focusin(); + var button = menu.prev().addClass( "ui-state-active" ).attr( "tabIndex", -1 ); + this.active = menu + .show() + .position( { + my: "left top", + at: "left bottom", + of: button + }) + .removeAttr( "aria-hidden" ) + .attr( "aria-expanded", "true" ) + .menu("focus", event, menu.children( "li" ).first() ) + // TODO need a comment here why both events are triggered + .focus() + .focusin(); this.open = true; }, // TODO refactor this and the next three methods _prev: function( event, button ) { - button.attr("tabIndex", -1); - var prev = button.parent().prevAll("li").children( ".ui-button" ).eq( 0 ); - if (prev.length) { - prev.removeAttr("tabIndex")[0].focus(); + button.attr( "tabIndex", -1 ); + var prev = button.parent().prevAll( "li" ).children( ".ui-button" ).eq( 0 ); + if ( prev.length ) { + prev.removeAttr( "tabIndex" )[0].focus(); } else { - var lastItem = this.element.children("li:last").children(".ui-button:last"); - lastItem.removeAttr("tabIndex")[0].focus(); + var lastItem = this.element.children( "li:last" ).children( ".ui-button:last" ); + lastItem.removeAttr( "tabIndex" )[0].focus(); } }, _next: function( event, button ) { - button.attr("tabIndex", -1); - var next = button.parent().nextAll("li").children( ".ui-button" ).eq( 0 ); - if (next.length) { - next.removeAttr("tabIndex")[0].focus(); + button.attr( "tabIndex", -1 ); + var next = button.parent().nextAll( "li" ).children( ".ui-button" ).eq( 0 ); + if ( next.length ) { + next.removeAttr( "tabIndex")[0].focus(); } else { - var firstItem = this.element.children("li:first").children(".ui-button:first"); - firstItem.removeAttr("tabIndex")[0].focus(); + var firstItem = this.element.children( "li:first" ).children( ".ui-button:first" ); + firstItem.removeAttr( "tabIndex" )[0].focus(); } }, // TODO rename to parent - _left: function(event) { - var prev = this.active.parent().prevAll("li:eq(0)").children( ".ui-menu" ).eq( 0 ); - if (prev.length) { - this._open(event, prev); + _left: function( event ) { + var prev = this.active.parent().prevAll( "li:eq(0)" ).children( ".ui-menu" ).eq( 0 ); + if ( prev.length ) { + this._open( event, prev ); } else { - var lastItem = this.element.children("li:last").children(".ui-menu:first"); - this._open(event, lastItem); + var lastItem = this.element.children( "li:last" ).children( ".ui-menu:first" ); + this._open( event, lastItem ); } }, // TODO rename to child (or something like that) - _right: function(event) { - var next = this.active.parent().nextAll("li:eq(0)").children( ".ui-menu" ).eq( 0 ); - if (next.length) { - this._open(event, next); + _right: function( event ) { + var next = this.active.parent().nextAll( "li:eq(0)" ).children( ".ui-menu" ).eq( 0 ); + if ( next.length ) { + this._open( event, next ); } else { - var firstItem = this.element.children("li:first").children(".ui-menu:first"); - this._open(event, firstItem); + var firstItem = this.element.children( "li:first" ).children( ".ui-menu:first" ); + this._open( event, firstItem ); } } }); -}(jQuery)); +}( jQuery )); -- cgit v1.2.3 From fc97ccd398b60525fd9e4c0e9aa1f51048984394 Mon Sep 17 00:00:00 2001 From: Kato Kazuyoshi Date: Thu, 5 May 2011 04:07:43 +0900 Subject: Datepicker: Remove old "ui-datepicker-multi-N" before add new one. Fixed #6704 - Display overflow when multiple datepickers have different numberOfMonths. --- tests/unit/datepicker/datepicker_core.js | 8 ++++++++ ui/jquery.ui.datepicker.js | 3 +-- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 78f78ce38..badb837ed 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -116,8 +116,16 @@ test('baseStructure', function() { ok(child.is('div.ui-datepicker-group') && child.is('div.ui-datepicker-group-last'), 'Structure multi [2] - second month division'); child = dp.children(':eq(2)'); ok(child.is('div.ui-datepicker-row-break'), 'Structure multi [2] - row break'); + ok(dp.is('.ui-datepicker-multi-2'), 'Structure multi [2] - multi-2'); inp.datepicker('hide').datepicker('destroy'); + // Multi-month 3 + inp = init('#inp', {numberOfMonths: 3}); + inp.focus(); + ok(dp.is('.ui-datepicker-multi-3'), 'Structure multi [3] - multi-3'); + ok(! dp.is('.ui-datepicker-multi-2'), 'Structure multi [3] - Trac #6704'); + inp.datepicker('hide').datepicker('destroy'); + // Multi-month [2, 2] inp = init('#inp', {numberOfMonths: [2, 2]}); inp.focus(); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 3437d0bda..aa9caec8c 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -685,10 +685,9 @@ $.extend(Datepicker.prototype, { var numMonths = this._getNumberOfMonths(inst); var cols = numMonths[1]; var width = 17; + inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); if (cols > 1) inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em'); - else - inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + 'Class']('ui-datepicker-multi'); inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + -- cgit v1.2.3 From a891e81e06c7ce491ae9058aea2fa7fbd51eddb6 Mon Sep 17 00:00:00 2001 From: Kato Kazuyoshi Date: Thu, 5 May 2011 05:06:27 +0900 Subject: Datepicker: Greedy matching in month name. Fixed #7062 - $.datepicker.parseDate does not work for some locale date strings. --- tests/unit/datepicker/datepicker.html | 1 + tests/unit/datepicker/datepicker_options.js | 4 ++++ ui/jquery.ui.datepicker.js | 24 +++++++++++++++++------- 3 files changed, 22 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index 76082e780..fa346c6c9 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -12,6 +12,7 @@ + diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 4f1e9a164..a10d1ea45 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -827,6 +827,10 @@ test('parseDate', function() { equalsDate($.datepicker.parseDate('\'jour\' d \'de\' MM (\'\'DD\'\'), yy', 'jour 9 de Avril (\'Lundi\'), 2001', settings), new Date(2001, 4 - 1, 9), 'Parse date \'jour\' d \'de\' MM (\'\'DD\'\'), yy with settings'); + + var zh = $.datepicker.regional['zh-CN']; + equalsDate($.datepicker.parseDate('yy M d', '2011 十一 22', zh), + new Date(2011, 11 - 1, 22), 'Parse date yy M d with zh-CN'); }); test('parseDateErrors', function() { diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 3437d0bda..d49fb7781 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -996,14 +996,24 @@ $.extend(Datepicker.prototype, { }; // Extract a name from the string value and convert to an index var getName = function(match, shortNames, longNames) { - var names = (lookAhead(match) ? longNames : shortNames); - for (var i = 0; i < names.length; i++) { - if (value.substr(iValue, names[i].length).toLowerCase() == names[i].toLowerCase()) { - iValue += names[i].length; - return i + 1; + var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { + return [ [k, v] ]; + }).sort(function (a, b) { + return -(a[1].length - b[1].length); + }); + var index = -1; + $.each(names, function (i, pair) { + var name = pair[1]; + if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) { + index = pair[0]; + iValue += name.length; + return false; } - } - throw 'Unknown name at position ' + iValue; + }); + if (index != -1) + return index + 1; + else + throw 'Unknown name at position ' + iValue; }; // Confirm that a literal character matches the string value var checkLiteral = function() { -- cgit v1.2.3 From c73e40adbec6d3240e92b125e55eae38532ed359 Mon Sep 17 00:00:00 2001 From: gnarf Date: Wed, 4 May 2011 21:04:28 -0500 Subject: effects.tests: Adding 'size' effect to the visual effect tests --- tests/visual/effects.all.html | 6 ++++++ tests/visual/effects.all.js | 1 + 2 files changed, 7 insertions(+) (limited to 'tests') diff --git a/tests/visual/effects.all.html b/tests/visual/effects.all.html index 1fc35f700..5c2c418ae 100644 --- a/tests/visual/effects.all.html +++ b/tests/visual/effects.all.html @@ -145,6 +145,12 @@
+
  • +
    +

    Size

    +
    +
  • +
  • Slide down

    diff --git a/tests/visual/effects.all.js b/tests/visual/effects.all.js index 3ac8968b3..1c9c71efd 100644 --- a/tests/visual/effects.all.js +++ b/tests/visual/effects.all.js @@ -61,6 +61,7 @@ $(function() { effect("#puff", "puff", { times: 2 }); effect("#scale", "scale", {}); + effect("#size", "size", { from: { width: 300, height: 300 }}); $("#shake").bind("click", function() { $(this).addClass("current").effect("shake", {}, 100, function() { $(this).removeClass("current"); }); }); -- cgit v1.2.3 From d4bdd19429b82acebf37772669b796cc84e1674a Mon Sep 17 00:00:00 2001 From: gnarf Date: Wed, 4 May 2011 23:40:16 -0500 Subject: effects.test: adding a test for size using toggle --- tests/visual/effects.all.html | 8 +++++++- tests/visual/effects.all.js | 21 +++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/visual/effects.all.html b/tests/visual/effects.all.html index 5c2c418ae..fed35de8a 100644 --- a/tests/visual/effects.all.html +++ b/tests/visual/effects.all.html @@ -147,7 +147,13 @@
  • -

    Size

    +

    Size Default Show/Hide

    +
    +
  • + +
  • +
    +

    Size Toggle

  • diff --git a/tests/visual/effects.all.js b/tests/visual/effects.all.js index 1c9c71efd..17e2c6448 100644 --- a/tests/visual/effects.all.js +++ b/tests/visual/effects.all.js @@ -28,10 +28,10 @@ $(function() { var el = $(this); el.addClass("current").hide(duration, function() { setTimeout(function() { - el.show(duration, function() { el.removeClass("current") }); + el.show(duration, function() { el.removeClass("current"); }); }, wait); - }) - }) + }); + }); effect("#blindLeft", "blind", { direction: "left" }); effect("#blindUp", "blind", { direction: "up" }); @@ -61,7 +61,16 @@ $(function() { effect("#puff", "puff", { times: 2 }); effect("#scale", "scale", {}); - effect("#size", "size", { from: { width: 300, height: 300 }}); + effect("#size", "size", {}); + $("#sizeToggle").bind("click", function() { + var opts = { to: { width: 300, height: 300 }}; + $(this).addClass('current') + .toggle("size", opts, duration) + .delay(wait) + .toggle("size", opts, duration, function() { + $(this).removeClass("current"); + }); + }); $("#shake").bind("click", function() { $(this).addClass("current").effect("shake", {}, 100, function() { $(this).removeClass("current"); }); }); @@ -83,13 +92,13 @@ $(function() { $("#removeClass").click(function() { $(this).addClass("current").removeClass(function() { window.console && console.log(arguments); - return "current" + return "current"; }, duration); }); $("#toggleClass").click(function() { $(this).toggleClass(function() { window.console && console.log(arguments); - return "current" + return "current"; }, duration); }); }); -- cgit v1.2.3 From 993d37af1d04d586b8b977daf0da3588d63714d9 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Thu, 5 May 2011 14:20:56 +0200 Subject: Popup: Rename open flag to isOpen to avoid name conflict with open method. --- tests/visual/menu/popup.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/visual/menu/popup.js b/tests/visual/menu/popup.js index dc81b694c..08088c994 100644 --- a/tests/visual/menu/popup.js +++ b/tests/visual/menu/popup.js @@ -45,7 +45,7 @@ $.widget( "ui.popup", { }, click: function( event ) { event.preventDefault(); - if (this.open) { + if (this.isOpen) { // let it propagate to close return; } @@ -75,7 +75,7 @@ $.widget( "ui.popup", { this._bind(document, { click: function( event ) { - if (this.open && !$(event.target).closest(".ui-popup").length) { + if (this.isOpen && !$(event.target).closest(".ui-popup").length) { this.close( event ); } } @@ -116,7 +116,7 @@ $.widget( "ui.popup", { // take trigger out of tab order to allow shift-tab to skip trigger this.options.trigger.attr("tabindex", -1); - this.open = true; + this.isOpen = true; this._trigger( "open", event ); }, @@ -128,7 +128,7 @@ $.widget( "ui.popup", { this.options.trigger.attr("tabindex", 0); - this.open = false; + this.isOpen = false; this._trigger( "close", event ); } -- cgit v1.2.3 From 28017052a497c4fc62f6bb518e0f39e71ee034c4 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Fri, 6 May 2011 19:21:13 +0200 Subject: Popup: Fix the reopens-issue when clicking the trigger while popup is visible, while still handling an actualy blur properly. --- tests/visual/menu/popup.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/visual/menu/popup.js b/tests/visual/menu/popup.js index 08088c994..a8238adb0 100644 --- a/tests/visual/menu/popup.js +++ b/tests/visual/menu/popup.js @@ -39,6 +39,7 @@ $.widget( "ui.popup", { this._bind(this.options.trigger, { keydown: function( event ) { // prevent space-to-open to scroll the page + // TODO do this only for a:ui-button? if (event.keyCode == $.ui.keyCode.SPACE) { event.preventDefault() } @@ -50,6 +51,7 @@ $.widget( "ui.popup", { return; } var that = this; + clearTimeout( this.closeTimer ); setTimeout(function() { that.open( event ); }, 1); @@ -57,9 +59,14 @@ $.widget( "ui.popup", { }); this._bind(this.element, { - // TODO also triggered when open and clicking the trigger again - // figure out how to close in that case, while still closing on regular blur - //blur: "close" + blur: function( event ) { + var that = this; + // use a timer to allow click to clear it and letting that + // handle the closing instead of opening again + that.closeTimer = setTimeout( function() { + that.close( event ); + }, 100); + } }); this._bind({ -- cgit v1.2.3 From fbe982b9fbd7ac50fc08a8e539c7a7d9be5089b2 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Fri, 6 May 2011 19:28:18 +0200 Subject: Popup: If popup is a menu, focus the first menu item, as menubar does. --- tests/visual/menu/popup.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/visual/menu/popup.js b/tests/visual/menu/popup.js index a8238adb0..a5e42a884 100644 --- a/tests/visual/menu/popup.js +++ b/tests/visual/menu/popup.js @@ -120,6 +120,10 @@ $.widget( "ui.popup", { .position( position ) .focus(); + if (this.element.is(":ui-menu")) { + this.element.menu("focus", event, this.element.children( "li" ).first() ); + } + // take trigger out of tab order to allow shift-tab to skip trigger this.options.trigger.attr("tabindex", -1); -- cgit v1.2.3 From 2cf85da23fde6f067bf197f60b458d1afe78a6b5 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Fri, 6 May 2011 19:43:47 +0200 Subject: Popup/Tooltip: Fix tab order and add notifications (on select) in video-player demo. --- demos/tooltip/video-player.html | 63 +++++++++++++++++++++++++++-------------- tests/visual/menu/popup.js | 2 ++ 2 files changed, 43 insertions(+), 22 deletions(-) (limited to 'tests') diff --git a/demos/tooltip/video-player.html b/demos/tooltip/video-player.html index 2e2419760..473c6a6a3 100644 --- a/demos/tooltip/video-player.html +++ b/demos/tooltip/video-player.html @@ -14,25 +14,40 @@ + - - + diff --git a/tests/visual/menu/menubar.js b/tests/visual/menu/menubar.js deleted file mode 100644 index b9abacb9b..000000000 --- a/tests/visual/menu/menubar.js +++ /dev/null @@ -1,262 +0,0 @@ -/* - * jQuery UI menubar - * - * TODO move to jquery.ui.menubar.js - */ -(function( $ ) { - -// TODO when mixing clicking menus and keyboard navigation, focus handling is broken -// there has to be just one item that has tabindex -$.widget( "ui.menubar", { - options: { - buttons: false, - menuIcon: false - }, - _create: function() { - var that = this; - var items = this.items = this.element.children( "li" ) - .addClass( "ui-menubar-item" ) - .attr( "role", "presentation" ) - .children( "button, a" ); - // let only the first item receive focus - items.slice(1).attr( "tabIndex", -1 ); - - this.element - .addClass( "ui-menubar ui-widget-header ui-helper-clearfix" ) - .attr( "role", "menubar" ); - this._focusable( items ); - this._hoverable( items ); - items.next( "ul" ) - .menu({ - select: function( event, ui ) { - ui.item.parents( "ul.ui-menu:last" ).hide(); - that._trigger( "select", event, ui ); - that._close(); - // TODO what is this targetting? there's probably a better way to access it - $(event.target).prev().focus(); - } - }) - .hide() - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ) - .bind( "keydown.menubar", function( event ) { - var menu = $( this ); - if ( menu.is( ":hidden" ) ) - return; - switch ( event.keyCode ) { - case $.ui.keyCode.LEFT: - that._left( event ); - event.preventDefault(); - break; - case $.ui.keyCode.RIGHT: - that._right( event ); - event.preventDefault(); - break; - }; - }); - items.each(function() { - var input = $(this), - // TODO menu var is only used on two places, doesn't quite justify the .each - menu = input.next( "ul" ); - - input.bind( "click.menubar focus.menubar mouseenter.menubar", function( event ) { - // ignore triggered focus event - if ( event.type == "focus" && !event.originalEvent ) { - return; - } - event.preventDefault(); - // TODO can we simplify or extractthis check? especially the last two expressions - // there's a similar active[0] == menu[0] check in _open - if ( event.type == "click" && menu.is( ":visible" ) && that.active && that.active[0] == menu[0] ) { - that._close(); - return; - } - if ( ( that.open && event.type == "mouseenter" ) || event.type == "click" ) { - that._open( event, menu ); - } - }) - .bind( "keydown", function( event ) { - switch ( event.keyCode ) { - case $.ui.keyCode.SPACE: - case $.ui.keyCode.UP: - case $.ui.keyCode.DOWN: - that._open( event, $( this ).next() ); - event.preventDefault(); - break; - case $.ui.keyCode.LEFT: - that._prev( event, $( this ) ); - event.preventDefault(); - break; - case $.ui.keyCode.RIGHT: - that._next( event, $( this ) ); - event.preventDefault(); - break; - } - }) - .addClass( "ui-button ui-widget ui-button-text-only ui-menubar-link" ) - .attr( "role", "menuitem" ) - .attr( "aria-haspopup", "true" ) - .wrapInner( "" ); - - // TODO review if these options are a good choice, maybe they can be merged - if ( that.options.menuIcon ) { - input.addClass( "ui-state-default" ).append( "" ); - input.removeClass( "ui-button-text-only" ).addClass( "ui-button-text-icon-secondary" ); - } - - if ( !that.options.buttons ) { - // TODO ui-menubar-link is added above, not needed here? - input.addClass( "ui-menubar-link" ).removeClass( "ui-state-default" ); - }; - - }); - that._bind( { - keydown: function( event ) { - if ( event.keyCode == $.ui.keyCode.ESCAPE && that.active && that.active.menu( "left", event ) !== true ) { - var active = that.active; - that.active.blur(); - that._close( event ); - active.prev().focus(); - } - }, - focusin: function( event ) { - clearTimeout( that.closeTimer ); - }, - focusout: function( event ) { - that.closeTimer = setTimeout( function() { - that._close( event ); - }, 100); - } - }); - }, - - _destroy : function() { - var items = this.element.children( "li" ) - .removeClass( "ui-menubar-item" ) - .removeAttr( "role", "presentation" ) - .children( "button, a" ); - - this.element - .removeClass( "ui-menubar ui-widget-header ui-helper-clearfix" ) - .removeAttr( "role", "menubar" ) - .unbind( ".menubar" ); - - items - .unbind( ".menubar" ) - .removeClass( "ui-button ui-widget ui-button-text-only ui-menubar-link ui-state-default" ) - .removeAttr( "role", "menuitem" ) - .removeAttr( "aria-haspopup", "true" ) - // TODO unwrap? - .children( "span.ui-button-text" ).each(function( i, e ) { - var item = $( this ); - item.parent().html( item.html() ); - }) - .end() - .children( ".ui-icon" ).remove(); - - this.element.find( ":ui-menu" ) - .menu( "destroy" ) - .show() - .removeAttr( "aria-hidden", "true" ) - .removeAttr( "aria-expanded", "false" ) - .removeAttr( "tabindex" ) - .unbind( ".menubar" ); - }, - - _close: function() { - if ( !this.active || !this.active.length ) - return; - this.active - .menu( "closeAll" ) - .hide() - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ); - this.active - .prev() - .removeClass( "ui-state-active" ) - .removeAttr( "tabIndex" ); - this.active = null; - this.open = false; - }, - - _open: function( event, menu ) { - // on a single-button menubar, ignore reopening the same menu - if ( this.active && this.active[0] == menu[0] ) { - return; - } - // TODO refactor, almost the same as _close above, but don't remove tabIndex - if ( this.active ) { - this.active - .menu( "closeAll" ) - .hide() - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ); - this.active - .prev() - .removeClass( "ui-state-active" ); - } - // set tabIndex -1 to have the button skipped on shift-tab when menu is open (it gets focus) - var button = menu.prev().addClass( "ui-state-active" ).attr( "tabIndex", -1 ); - this.active = menu - .show() - .position( { - my: "left top", - at: "left bottom", - of: button - }) - .removeAttr( "aria-hidden" ) - .attr( "aria-expanded", "true" ) - .menu("focus", event, menu.children( "li" ).first() ) - // TODO need a comment here why both events are triggered - .focus() - .focusin(); - this.open = true; - }, - - // TODO refactor this and the next three methods - _prev: function( event, button ) { - button.attr( "tabIndex", -1 ); - var prev = button.parent().prevAll( "li" ).children( ".ui-button" ).eq( 0 ); - if ( prev.length ) { - prev.removeAttr( "tabIndex" )[0].focus(); - } else { - var lastItem = this.element.children( "li:last" ).children( ".ui-button:last" ); - lastItem.removeAttr( "tabIndex" )[0].focus(); - } - }, - - _next: function( event, button ) { - button.attr( "tabIndex", -1 ); - var next = button.parent().nextAll( "li" ).children( ".ui-button" ).eq( 0 ); - if ( next.length ) { - next.removeAttr( "tabIndex")[0].focus(); - } else { - var firstItem = this.element.children( "li:first" ).children( ".ui-button:first" ); - firstItem.removeAttr( "tabIndex" )[0].focus(); - } - }, - - // TODO rename to parent - _left: function( event ) { - var prev = this.active.parent().prevAll( "li:eq(0)" ).children( ".ui-menu" ).eq( 0 ); - if ( prev.length ) { - this._open( event, prev ); - } else { - var lastItem = this.element.children( "li:last" ).children( ".ui-menu:first" ); - this._open( event, lastItem ); - } - }, - - // TODO rename to child (or something like that) - _right: function( event ) { - var next = this.active.parent().nextAll( "li:eq(0)" ).children( ".ui-menu" ).eq( 0 ); - if ( next.length ) { - this._open( event, next ); - } else { - var firstItem = this.element.children( "li:first" ).children( ".ui-menu:first" ); - this._open( event, firstItem ); - } - } -}); - -}( jQuery )); diff --git a/tests/visual/menu/popup.html b/tests/visual/menu/popup.html index 2a712b00a..de27208b4 100644 --- a/tests/visual/menu/popup.html +++ b/tests/visual/menu/popup.html @@ -10,7 +10,7 @@ - + diff --git a/tests/visual/menu/popup.js b/tests/visual/menu/popup.js deleted file mode 100644 index 87a480741..000000000 --- a/tests/visual/menu/popup.js +++ /dev/null @@ -1,161 +0,0 @@ -/* - * jQuery UI popup utility - */ -(function($) { - -var idIncrement = 0; - -$.widget( "ui.popup", { - options: { - position: { - my: "left top", - at: "left bottom" - } - }, - _create: function() { - if ( !this.options.trigger ) { - this.options.trigger = this.element.prev(); - } - - if ( !this.element.attr( "id" ) ) { - this.element.attr( "id", "ui-popup-" + idIncrement++ ); - this.generatedId = true; - } - - if ( !this.element.attr( "role" ) ) { - // TODO alternatives to tooltip are dialog and menu, all three aren't generic popups - this.element.attr( "role", "tooltip" ); - this.generatedRole = true; - } - - this.options.trigger - .attr( "aria-haspopup", true ) - .attr( "aria-owns", this.element.attr( "id" ) ); - - this.element - .addClass("ui-popup") - this.close(); - - this._bind(this.options.trigger, { - keydown: function( event ) { - // prevent space-to-open to scroll the page, only hapens for anchor ui.button - if ( this.options.trigger.is( "a:ui-button" ) && event.keyCode == $.ui.keyCode.SPACE) { - event.preventDefault() - } - // TODO handle SPACE to open popup? only when not handled by ui.button - if ( event.keyCode == $.ui.keyCode.SPACE && this.options.trigger.is("a:not(:ui-button)") ) { - this.options.trigger.trigger( "click", event ); - } - // translate keydown to click - // opens popup and let's tooltip hide itself - if ( event.keyCode == $.ui.keyCode.DOWN ) { - this.options.trigger.trigger( "click", event ); - } - }, - click: function( event ) { - event.preventDefault(); - if (this.isOpen) { - // let it propagate to close - return; - } - var that = this; - clearTimeout( this.closeTimer ); - setTimeout(function() { - that.open( event ); - }, 1); - } - }); - - this._bind(this.element, { - // TODO use focusout so that element itself doesn't need to be focussable - blur: function( event ) { - var that = this; - // use a timer to allow click to clear it and letting that - // handle the closing instead of opening again - that.closeTimer = setTimeout( function() { - that.close( event ); - }, 100); - } - }); - - this._bind({ - // TODO only triggerd on element if it can receive focus - // bind to document instead? - // either element itself or a child should be focusable - keyup: function( event ) { - if (event.keyCode == $.ui.keyCode.ESCAPE && this.element.is( ":visible" )) { - this.close( event ); - // TODO move this to close()? would allow menu.select to call popup.close, and get focus back to trigger - this.options.trigger.focus(); - } - } - }); - - this._bind(document, { - click: function( event ) { - if (this.isOpen && !$(event.target).closest(".ui-popup").length) { - this.close( event ); - } - } - }) - }, - - _destroy: function() { - this.element - .show() - .removeClass( "ui-popup" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-expanded" ); - - this.options.trigger - .removeAttr( "aria-haspopup" ) - .removeAttr( "aria-owns" ); - - if ( this.generatedId ) { - this.element.removeAttr( "id" ); - } - if ( this.generatedRole ) { - this.element.removeAttr( "role" ); - } - }, - - open: function( event ) { - var position = $.extend( {}, { - of: this.options.trigger - }, this.options.position ); - - this.element - .show() - .attr( "aria-hidden", false ) - .attr( "aria-expanded", true ) - .position( position ) - // TODO find a focussable child, otherwise put focus on element, add tabIndex=0 if not focussable - .focus(); - - if (this.element.is(":ui-menu")) { - this.element.menu("focus", event, this.element.children( "li" ).first() ); - } - - // take trigger out of tab order to allow shift-tab to skip trigger - this.options.trigger.attr("tabindex", -1); - - this.isOpen = true; - this._trigger( "open", event ); - }, - - close: function( event ) { - this.element - .hide() - .attr( "aria-hidden", true ) - .attr( "aria-expanded", false ); - - this.options.trigger.attr("tabindex", 0); - - this.isOpen = false; - this._trigger( "close", event ); - } - - -}); - -}(jQuery)); diff --git a/ui/jquery.ui.menubar.js b/ui/jquery.ui.menubar.js new file mode 100644 index 000000000..2879d079c --- /dev/null +++ b/ui/jquery.ui.menubar.js @@ -0,0 +1,272 @@ +/* + * jQuery UI Menubar @VERSION + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menubar + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.position.js + * jquery.ui.menu.js + */ +(function( $ ) { + +// TODO when mixing clicking menus and keyboard navigation, focus handling is broken +// there has to be just one item that has tabindex +$.widget( "ui.menubar", { + options: { + buttons: false, + menuIcon: false + }, + _create: function() { + var that = this; + var items = this.items = this.element.children( "li" ) + .addClass( "ui-menubar-item" ) + .attr( "role", "presentation" ) + .children( "button, a" ); + // let only the first item receive focus + items.slice(1).attr( "tabIndex", -1 ); + + this.element + .addClass( "ui-menubar ui-widget-header ui-helper-clearfix" ) + .attr( "role", "menubar" ); + this._focusable( items ); + this._hoverable( items ); + items.next( "ul" ) + .menu({ + select: function( event, ui ) { + ui.item.parents( "ul.ui-menu:last" ).hide(); + that._trigger( "select", event, ui ); + that._close(); + // TODO what is this targetting? there's probably a better way to access it + $(event.target).prev().focus(); + } + }) + .hide() + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ) + .bind( "keydown.menubar", function( event ) { + var menu = $( this ); + if ( menu.is( ":hidden" ) ) + return; + switch ( event.keyCode ) { + case $.ui.keyCode.LEFT: + that._left( event ); + event.preventDefault(); + break; + case $.ui.keyCode.RIGHT: + that._right( event ); + event.preventDefault(); + break; + }; + }); + items.each(function() { + var input = $(this), + // TODO menu var is only used on two places, doesn't quite justify the .each + menu = input.next( "ul" ); + + input.bind( "click.menubar focus.menubar mouseenter.menubar", function( event ) { + // ignore triggered focus event + if ( event.type == "focus" && !event.originalEvent ) { + return; + } + event.preventDefault(); + // TODO can we simplify or extractthis check? especially the last two expressions + // there's a similar active[0] == menu[0] check in _open + if ( event.type == "click" && menu.is( ":visible" ) && that.active && that.active[0] == menu[0] ) { + that._close(); + return; + } + if ( ( that.open && event.type == "mouseenter" ) || event.type == "click" ) { + that._open( event, menu ); + } + }) + .bind( "keydown", function( event ) { + switch ( event.keyCode ) { + case $.ui.keyCode.SPACE: + case $.ui.keyCode.UP: + case $.ui.keyCode.DOWN: + that._open( event, $( this ).next() ); + event.preventDefault(); + break; + case $.ui.keyCode.LEFT: + that._prev( event, $( this ) ); + event.preventDefault(); + break; + case $.ui.keyCode.RIGHT: + that._next( event, $( this ) ); + event.preventDefault(); + break; + } + }) + .addClass( "ui-button ui-widget ui-button-text-only ui-menubar-link" ) + .attr( "role", "menuitem" ) + .attr( "aria-haspopup", "true" ) + .wrapInner( "" ); + + // TODO review if these options are a good choice, maybe they can be merged + if ( that.options.menuIcon ) { + input.addClass( "ui-state-default" ).append( "" ); + input.removeClass( "ui-button-text-only" ).addClass( "ui-button-text-icon-secondary" ); + } + + if ( !that.options.buttons ) { + // TODO ui-menubar-link is added above, not needed here? + input.addClass( "ui-menubar-link" ).removeClass( "ui-state-default" ); + }; + + }); + that._bind( { + keydown: function( event ) { + if ( event.keyCode == $.ui.keyCode.ESCAPE && that.active && that.active.menu( "left", event ) !== true ) { + var active = that.active; + that.active.blur(); + that._close( event ); + active.prev().focus(); + } + }, + focusin: function( event ) { + clearTimeout( that.closeTimer ); + }, + focusout: function( event ) { + that.closeTimer = setTimeout( function() { + that._close( event ); + }, 100); + } + }); + }, + + _destroy : function() { + var items = this.element.children( "li" ) + .removeClass( "ui-menubar-item" ) + .removeAttr( "role", "presentation" ) + .children( "button, a" ); + + this.element + .removeClass( "ui-menubar ui-widget-header ui-helper-clearfix" ) + .removeAttr( "role", "menubar" ) + .unbind( ".menubar" ); + + items + .unbind( ".menubar" ) + .removeClass( "ui-button ui-widget ui-button-text-only ui-menubar-link ui-state-default" ) + .removeAttr( "role", "menuitem" ) + .removeAttr( "aria-haspopup", "true" ) + // TODO unwrap? + .children( "span.ui-button-text" ).each(function( i, e ) { + var item = $( this ); + item.parent().html( item.html() ); + }) + .end() + .children( ".ui-icon" ).remove(); + + this.element.find( ":ui-menu" ) + .menu( "destroy" ) + .show() + .removeAttr( "aria-hidden", "true" ) + .removeAttr( "aria-expanded", "false" ) + .removeAttr( "tabindex" ) + .unbind( ".menubar" ); + }, + + _close: function() { + if ( !this.active || !this.active.length ) + return; + this.active + .menu( "closeAll" ) + .hide() + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ); + this.active + .prev() + .removeClass( "ui-state-active" ) + .removeAttr( "tabIndex" ); + this.active = null; + this.open = false; + }, + + _open: function( event, menu ) { + // on a single-button menubar, ignore reopening the same menu + if ( this.active && this.active[0] == menu[0] ) { + return; + } + // TODO refactor, almost the same as _close above, but don't remove tabIndex + if ( this.active ) { + this.active + .menu( "closeAll" ) + .hide() + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ); + this.active + .prev() + .removeClass( "ui-state-active" ); + } + // set tabIndex -1 to have the button skipped on shift-tab when menu is open (it gets focus) + var button = menu.prev().addClass( "ui-state-active" ).attr( "tabIndex", -1 ); + this.active = menu + .show() + .position( { + my: "left top", + at: "left bottom", + of: button + }) + .removeAttr( "aria-hidden" ) + .attr( "aria-expanded", "true" ) + .menu("focus", event, menu.children( "li" ).first() ) + // TODO need a comment here why both events are triggered + .focus() + .focusin(); + this.open = true; + }, + + // TODO refactor this and the next three methods + _prev: function( event, button ) { + button.attr( "tabIndex", -1 ); + var prev = button.parent().prevAll( "li" ).children( ".ui-button" ).eq( 0 ); + if ( prev.length ) { + prev.removeAttr( "tabIndex" )[0].focus(); + } else { + var lastItem = this.element.children( "li:last" ).children( ".ui-button:last" ); + lastItem.removeAttr( "tabIndex" )[0].focus(); + } + }, + + _next: function( event, button ) { + button.attr( "tabIndex", -1 ); + var next = button.parent().nextAll( "li" ).children( ".ui-button" ).eq( 0 ); + if ( next.length ) { + next.removeAttr( "tabIndex")[0].focus(); + } else { + var firstItem = this.element.children( "li:first" ).children( ".ui-button:first" ); + firstItem.removeAttr( "tabIndex" )[0].focus(); + } + }, + + // TODO rename to parent + _left: function( event ) { + var prev = this.active.parent().prevAll( "li:eq(0)" ).children( ".ui-menu" ).eq( 0 ); + if ( prev.length ) { + this._open( event, prev ); + } else { + var lastItem = this.element.children( "li:last" ).children( ".ui-menu:first" ); + this._open( event, lastItem ); + } + }, + + // TODO rename to child (or something like that) + _right: function( event ) { + var next = this.active.parent().nextAll( "li:eq(0)" ).children( ".ui-menu" ).eq( 0 ); + if ( next.length ) { + this._open( event, next ); + } else { + var firstItem = this.element.children( "li:first" ).children( ".ui-menu:first" ); + this._open( event, firstItem ); + } + } +}); + +}( jQuery )); diff --git a/ui/jquery.ui.popup.js b/ui/jquery.ui.popup.js new file mode 100644 index 000000000..784e5c655 --- /dev/null +++ b/ui/jquery.ui.popup.js @@ -0,0 +1,172 @@ +/* + * jQuery UI Popup @VERSION + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Popup + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.position.js + */ +(function($) { + +var idIncrement = 0; + +$.widget( "ui.popup", { + options: { + position: { + my: "left top", + at: "left bottom" + } + }, + _create: function() { + if ( !this.options.trigger ) { + this.options.trigger = this.element.prev(); + } + + if ( !this.element.attr( "id" ) ) { + this.element.attr( "id", "ui-popup-" + idIncrement++ ); + this.generatedId = true; + } + + if ( !this.element.attr( "role" ) ) { + // TODO alternatives to tooltip are dialog and menu, all three aren't generic popups + this.element.attr( "role", "tooltip" ); + this.generatedRole = true; + } + + this.options.trigger + .attr( "aria-haspopup", true ) + .attr( "aria-owns", this.element.attr( "id" ) ); + + this.element + .addClass("ui-popup") + this.close(); + + this._bind(this.options.trigger, { + keydown: function( event ) { + // prevent space-to-open to scroll the page, only hapens for anchor ui.button + if ( this.options.trigger.is( "a:ui-button" ) && event.keyCode == $.ui.keyCode.SPACE) { + event.preventDefault() + } + // TODO handle SPACE to open popup? only when not handled by ui.button + if ( event.keyCode == $.ui.keyCode.SPACE && this.options.trigger.is("a:not(:ui-button)") ) { + this.options.trigger.trigger( "click", event ); + } + // translate keydown to click + // opens popup and let's tooltip hide itself + if ( event.keyCode == $.ui.keyCode.DOWN ) { + this.options.trigger.trigger( "click", event ); + } + }, + click: function( event ) { + event.preventDefault(); + if (this.isOpen) { + // let it propagate to close + return; + } + var that = this; + clearTimeout( this.closeTimer ); + setTimeout(function() { + that.open( event ); + }, 1); + } + }); + + this._bind(this.element, { + // TODO use focusout so that element itself doesn't need to be focussable + blur: function( event ) { + var that = this; + // use a timer to allow click to clear it and letting that + // handle the closing instead of opening again + that.closeTimer = setTimeout( function() { + that.close( event ); + }, 100); + } + }); + + this._bind({ + // TODO only triggerd on element if it can receive focus + // bind to document instead? + // either element itself or a child should be focusable + keyup: function( event ) { + if (event.keyCode == $.ui.keyCode.ESCAPE && this.element.is( ":visible" )) { + this.close( event ); + // TODO move this to close()? would allow menu.select to call popup.close, and get focus back to trigger + this.options.trigger.focus(); + } + } + }); + + this._bind(document, { + click: function( event ) { + if (this.isOpen && !$(event.target).closest(".ui-popup").length) { + this.close( event ); + } + } + }) + }, + + _destroy: function() { + this.element + .show() + .removeClass( "ui-popup" ) + .removeAttr( "aria-hidden" ) + .removeAttr( "aria-expanded" ); + + this.options.trigger + .removeAttr( "aria-haspopup" ) + .removeAttr( "aria-owns" ); + + if ( this.generatedId ) { + this.element.removeAttr( "id" ); + } + if ( this.generatedRole ) { + this.element.removeAttr( "role" ); + } + }, + + open: function( event ) { + var position = $.extend( {}, { + of: this.options.trigger + }, this.options.position ); + + this.element + .show() + .attr( "aria-hidden", false ) + .attr( "aria-expanded", true ) + .position( position ) + // TODO find a focussable child, otherwise put focus on element, add tabIndex=0 if not focussable + .focus(); + + if (this.element.is(":ui-menu")) { + this.element.menu("focus", event, this.element.children( "li" ).first() ); + } + + // take trigger out of tab order to allow shift-tab to skip trigger + this.options.trigger.attr("tabindex", -1); + + this.isOpen = true; + this._trigger( "open", event ); + }, + + close: function( event ) { + this.element + .hide() + .attr( "aria-hidden", true ) + .attr( "aria-expanded", false ); + + this.options.trigger.attr("tabindex", 0); + + this.isOpen = false; + this._trigger( "close", event ); + } + + +}); + +}(jQuery)); -- cgit v1.2.3 From e6d1ab7bf40e7ecaaaea0d53407dc98a416cc054 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Sun, 8 May 2011 20:41:21 +0200 Subject: Popup and Menubar demos --- demos/demos.css | 3 +- demos/index.html | 4 + demos/menu/contextmenu.html | 48 +++----- demos/menu/default.html | 12 +- demos/menu/index.html | 2 +- demos/menubar/default.html | 234 +++++++++++++++++++++++++++++++++++++ demos/menubar/index.html | 16 +++ demos/popup/default.html | 83 +++++++++++++ demos/popup/index.html | 18 +++ demos/popup/popup-menu-table.html | 108 +++++++++++++++++ demos/popup/popup-menu.html | 98 ++++++++++++++++ tests/visual/menu/contextmenu.html | 191 ------------------------------ tests/visual/menu/menubar.html | 232 ------------------------------------ tests/visual/menu/popup.html | 176 ---------------------------- 14 files changed, 585 insertions(+), 640 deletions(-) create mode 100644 demos/menubar/default.html create mode 100644 demos/menubar/index.html create mode 100644 demos/popup/default.html create mode 100644 demos/popup/index.html create mode 100644 demos/popup/popup-menu-table.html create mode 100644 demos/popup/popup-menu.html delete mode 100644 tests/visual/menu/contextmenu.html delete mode 100644 tests/visual/menu/menubar.html delete mode 100644 tests/visual/menu/popup.html (limited to 'tests') diff --git a/demos/demos.css b/demos/demos.css index f5f2dbe64..cf6da8bd1 100644 --- a/demos/demos.css +++ b/demos/demos.css @@ -129,8 +129,7 @@ eventually we should convert the font sizes to ems -- using px for now to minimi .normal h3.demo-header { font-size:32px; padding:0 0 5px; border-bottom:1px solid #eee; text-transform: capitalize; } .normal h4.demo-subheader { font-size:10px; text-transform: uppercase; color:#999; padding:8px 0 3px; border:0; margin:0; } -.normal a:link, -.normal a:visited { color:#1b75bb; text-decoration:none; } +#demo-notes a, #demo-link a, #demo-source a { color:#1b75bb; text-decoration:none; } .normal a:hover, .normal a:active { color:#0b559b; } diff --git a/demos/index.html b/demos/index.html index 22dbfc5c5..b1cfcdd44 100644 --- a/demos/index.html +++ b/demos/index.html @@ -20,6 +20,8 @@ + + @@ -279,6 +281,8 @@
    Datepicker
    Dialog
    Menu
    +
    Menubar
    +
    Popup
    Progressbar
    Slider
    Spinner
    diff --git a/demos/menu/contextmenu.html b/demos/menu/contextmenu.html index 0fb98c140..115f15b24 100644 --- a/demos/menu/contextmenu.html +++ b/demos/menu/contextmenu.html @@ -3,44 +3,28 @@ jQuery UI Menu - Contextmenu demo - - - - - - - - - + + + + + + + + + + + +
    + + + + + + +
    + Log: +
    +
    +
    + +
    + +

    TODO

    + +
    + + + + diff --git a/demos/menubar/index.html b/demos/menubar/index.html new file mode 100644 index 000000000..3eebda2d0 --- /dev/null +++ b/demos/menubar/index.html @@ -0,0 +1,16 @@ + + + + + jQuery UI Menubar Demos + + + +
    +

    Examples

    + +
    + + diff --git a/demos/popup/default.html b/demos/popup/default.html new file mode 100644 index 000000000..71b3c8dd2 --- /dev/null +++ b/demos/popup/default.html @@ -0,0 +1,83 @@ + + + + jQuery UI Popup - Default demo + + + + + + + + + + + + + + +
    + Log In +
    +
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    + +
    + +

    A link to a login form that opens as a popup. [Not quite functional, focus handling needs to get better]

    + +
    + + + + diff --git a/demos/popup/index.html b/demos/popup/index.html new file mode 100644 index 000000000..e69365c98 --- /dev/null +++ b/demos/popup/index.html @@ -0,0 +1,18 @@ + + + + + jQuery UI Popup Demos + + + + + + diff --git a/demos/popup/popup-menu-table.html b/demos/popup/popup-menu-table.html new file mode 100644 index 000000000..a06a38434 --- /dev/null +++ b/demos/popup/popup-menu-table.html @@ -0,0 +1,108 @@ + + + + jQuery UI Popup - Menu as Popup in table demo + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameRelease YearAverage Rating
    Red Hot Chili Peppers: Funky Monks19933.6 + +
    Rod Stewart: Storyteller 1984-199119913.1
    Stevie Ray Vaughan and Double Trouble: Live at the El Mocambo 198319913.9
    Spike and Mike's Sick & Twisted Festival of Animation19972.6
    + +
    +
    + + +
    + +

    Poup menu in a table. Works okay standalone, not so much in the scrolling demo view. For that to work better, position() would have to take the closest scrolled parent into account for collision detection.

    + +
    + + + + diff --git a/demos/popup/popup-menu.html b/demos/popup/popup-menu.html new file mode 100644 index 000000000..7152d85bc --- /dev/null +++ b/demos/popup/popup-menu.html @@ -0,0 +1,98 @@ + + + + jQuery UI Popup - Popup Menu + + + + + + + + + + + + + + +
    + + + + + +
    +
    + + + +
    +
    + +
    +
    + + +
    + +

    Make the popup a menu (or the menu a popup) and you get context menus.

    + +
    + + + + diff --git a/tests/visual/menu/contextmenu.html b/tests/visual/menu/contextmenu.html deleted file mode 100644 index 63d9877a0..000000000 --- a/tests/visual/menu/contextmenu.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - Menu Visual Test: Default - - - - - - - - - - - - - - - - - - - - -
    - Log: -
    -
    - - - - - - diff --git a/tests/visual/menu/menubar.html b/tests/visual/menu/menubar.html deleted file mode 100644 index 3d7a3e59c..000000000 --- a/tests/visual/menu/menubar.html +++ /dev/null @@ -1,232 +0,0 @@ - - - - Menu Visual Test: Default - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameRelease YearAverage Rating
    Red Hot Chili Peppers: Funky Monks19933.6 - -
    Rod Stewart: Storyteller 1984-199119913.1
    Stevie Ray Vaughan and Double Trouble: Live at the El Mocambo 198319913.9
    Spike and Mike's Sick & Twisted Festival of Animation19972.6
    - -
    - Log: -
    -
    - - - diff --git a/tests/visual/menu/popup.html b/tests/visual/menu/popup.html deleted file mode 100644 index de27208b4..000000000 --- a/tests/visual/menu/popup.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - Visual Test for Popup Utility - - - - - - - - - - - - - - - -
    - Project members -
    - some form controls in here -
    -
    - - - - - -
    -
    - - -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameRelease YearAverage Rating
    Red Hot Chili Peppers: Funky Monks19933.6 - -
    Rod Stewart: Storyteller 1984-199119913.1
    Stevie Ray Vaughan and Double Trouble: Live at the El Mocambo 198319913.9
    Spike and Mike's Sick & Twisted Festival of Animation19972.6
    - -
    - Log: -
    -
    - - - -- cgit v1.2.3 From 0546cd57bbd0ccee25e96e1fb8be5f208b08dfd4 Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 9 May 2011 11:31:01 -0400 Subject: Tabs: Added tests for idPrefix, tabTemplate, panelTemplate. Fixes #7139 - Tabs: Deprecate templating (idPrefix, tabTemplate, panelTemplate options). --- tests/unit/tabs/tabs_deprecated.js | 45 +++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/unit/tabs/tabs_deprecated.js b/tests/unit/tabs/tabs_deprecated.js index 90c43037c..8d63409a8 100644 --- a/tests/unit/tabs/tabs_deprecated.js +++ b/tests/unit/tabs/tabs_deprecated.js @@ -20,7 +20,7 @@ test( "panel ids", function() { element.tabs( "option", "active", 2 ); }); -module("tabs (deprecated): options"); +module( "tabs (deprecated): options" ); test('ajaxOptions', function() { ok(false, "missing test - untested code is broken code."); @@ -30,16 +30,45 @@ test('cache', function() { ok(false, "missing test - untested code is broken code."); }); -test('idPrefix', function() { - ok(false, "missing test - untested code is broken code."); +test( "idPrefix", function() { + expect( 1 ); + + $( "#tabs2" ) + .one( "tabsbeforeload", function( event, ui ) { + ok( /^testing-\d+$/.test( ui.panel.attr( "id" ) ), "generated id" ); + event.preventDefault(); + }) + .tabs({ + idPrefix: "testing-", + active: 2 + }); }); -test('tabTemplate', function() { - ok(false, "missing test - untested code is broken code."); -}); +test( "tabTemplate + panelTemplate", function() { + // defaults are tested in the add method test + expect( 11 ); -test('panelTemplate', function() { - ok(false, "missing test - untested code is broken code."); + var element = $( "#tabs2" ).tabs({ + tabTemplate: "
  • #{label}
  • ", + panelTemplate: "
    " + }); + element.one( "tabsadd", function( event, ui ) { + var anchor = $( ui.tab ); + equal( ui.index, 5, "ui.index" ); + equal( anchor.text(), "New", "ui.tab" ); + equal( anchor.attr( "href" ), "http://example.com/#new", "tab href" ); + ok( anchor.parent().hasClass( "customTab" ), "tab custom class" ); + equal( ui.panel.id, "new", "ui.panel" ); + ok( $( ui.panel ).hasClass( "customPanel" ), "panel custom class" ); + }); + element.tabs( "add", "#new", "New" ); + var tab = element.find( ".ui-tabs-nav li" ).last(), + anchor = tab.find( "a" ); + equals( tab.text(), "New", "label" ); + ok( tab.hasClass( "customTab" ), "tab custom class" ); + equals( anchor.attr( "href" ), "http://example.com/#new", "href" ); + equals( anchor.attr( "aria-controls" ), "new", "aria-controls" ); + ok( element.find( "#new" ).hasClass( "customPanel" ), "panel custom class" ); }); test('cookie', function() { -- cgit v1.2.3 From 5ae44f8a3bdd858aa95c79b5938566ca0a67f373 Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 9 May 2011 12:52:00 -0400 Subject: Tabs: Refactored spinner implementation. Fixes #7134 - Tabs: Deprecate spinner option. --- tests/unit/tabs/tabs_deprecated.js | 37 ++++++++++----------------------- ui/jquery.ui.tabs.js | 42 ++++++++++++++++---------------------- 2 files changed, 29 insertions(+), 50 deletions(-) (limited to 'tests') diff --git a/tests/unit/tabs/tabs_deprecated.js b/tests/unit/tabs/tabs_deprecated.js index 8d63409a8..0094bc4f7 100644 --- a/tests/unit/tabs/tabs_deprecated.js +++ b/tests/unit/tabs/tabs_deprecated.js @@ -106,34 +106,19 @@ test('cookie', function() { }); +asyncTest( "spinner", function() { + expect( 2 ); -test('spinner', function() { - expect(4); - stop(); - - el = $('#tabs2'); - - el.tabs({ - selected: 2, - load: function() { - // spinner: default spinner - setTimeout(function() { - equals($('li:eq(2) > a > span', el).length, 1, "should restore tab markup after spinner is removed"); - equals($('li:eq(2) > a > span', el).html(), '3', "should restore tab label after spinner is removed"); - el.tabs('destroy'); - el.tabs({ - selected: 2, - spinner: '', - load: function() { - // spinner: image - equals($('li:eq(2) > a > span', el).length, 1, "should restore tab markup after spinner is removed"); - equals($('li:eq(2) > a > span', el).html(), '3', "should restore tab label after spinner is removed"); - start(); - } - }); - }, 1); - } + var element = $( "#tabs2" ).tabs(); + + element.one( "tabsbeforeload", function( event, ui ) { + equals( element.find( ".ui-tabs-nav li:eq(2) em" ).length, 1, "beforeload" ); + }); + element.one( "tabsload", function( event, ui ) { + equals( element.find( ".ui-tabs-nav li:eq(2) em" ).length, 0, "load" ); + start(); }); + element.tabs( "option", "active", 2 ); }); test( "selected", function() { diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index 58c181670..f0661b3ad 100644 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -743,34 +743,28 @@ if ( $.uiBackCompat !== false ) { }( jQuery, jQuery.ui.tabs.prototype ) ); // spinner - (function( $, prototype ) { - $.extend( prototype.options, { + $.widget( "ui.tabs", $.ui.tabs, { + options: { spinner: "Loading…" - }); - - var _create = prototype._create; - prototype._create = function() { - _create.call( this ); - var self = this; - - this.element.bind( "tabsbeforeload", function( event, ui ) { - if ( self.options.spinner ) { - var span = $( "span", ui.tab ); - if ( span.length ) { - span.data( "label.tabs", span.html() ).html( self.options.spinner ); + }, + _create: function() { + this._super( "_create" ); + this._bind({ + tabsbeforeload: function( event, ui ) { + if ( !this.options.spinner ) { + return; } + + var span = ui.tab.find( "span" ), + html = span.html(); + span.html( this.options.spinner ); + ui.jqXHR.complete(function() { + span.html( html ); + }); } - ui.jqXHR.complete( function() { - if ( self.options.spinner ) { - var span = $( "span", ui.tab ); - if ( span.length ) { - span.html( span.data( "label.tabs" ) ).removeData( "label.tabs" ); - } - } - }); }); - }; - }( jQuery, jQuery.ui.tabs.prototype ) ); + } + }); // enable/disable events (function( $, prototype ) { -- cgit v1.2.3 From 9549686cb35b877740aca388286d71ad04311a2d Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 9 May 2011 14:45:57 -0400 Subject: Tabs: Added test for ajaxOptions. Partial fix for #7131 - Tabs: Add beforeload event; deprecate ajaxOptions and cache options. Thanks gnarf for the unit test idea. --- tests/unit/tabs/tabs_deprecated.js | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/unit/tabs/tabs_deprecated.js b/tests/unit/tabs/tabs_deprecated.js index 0094bc4f7..e5f7b7568 100644 --- a/tests/unit/tabs/tabs_deprecated.js +++ b/tests/unit/tabs/tabs_deprecated.js @@ -22,8 +22,23 @@ test( "panel ids", function() { module( "tabs (deprecated): options" ); -test('ajaxOptions', function() { - ok(false, "missing test - untested code is broken code."); +asyncTest( "ajaxOptions", function() { + expect( 1 ); + + var element = $( "#tabs2" ).tabs({ + ajaxOptions: { + converters: { + "text html": function() { + return "test"; + } + } + } + }); + element.one( "tabsload", function( event, ui ) { + equals( ui.panel.html(), "test" ); + start(); + }); + element.tabs( "option", "active", 2 ); }); test('cache', function() { @@ -419,4 +434,8 @@ test( "url", function() { element.tabs( "option", "active", 3 ); }); +test( "abort", function() { + ok( false, "missing test - untested code is broken code." ); +}); + }( jQuery ) ); -- cgit v1.2.3 From 7157af2550b1b26fb71a7fac17ea67f36f117f7e Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 9 May 2011 15:04:01 -0400 Subject: Tabs: Added tests for cache option. Fixes #7131 - Tabs: Add beforeload event; deprecate ajaxOptions and cache options. --- tests/unit/tabs/tabs_deprecated.js | 30 ++++++++++++++++++++++++++++-- ui/jquery.ui.tabs.js | 2 +- 2 files changed, 29 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/unit/tabs/tabs_deprecated.js b/tests/unit/tabs/tabs_deprecated.js index e5f7b7568..49e89b7a0 100644 --- a/tests/unit/tabs/tabs_deprecated.js +++ b/tests/unit/tabs/tabs_deprecated.js @@ -41,8 +41,34 @@ asyncTest( "ajaxOptions", function() { element.tabs( "option", "active", 2 ); }); -test('cache', function() { - ok(false, "missing test - untested code is broken code."); +asyncTest( "cache", function() { + expect( 5 ); + + var element = $( "#tabs2" ).tabs({ + cache: true + }); + element.one( "tabsshow", function( event, ui ) { + tabs_state( element, 0, 0, 1, 0, 0 ); + }); + element.one( "tabsload", function( event, ui ) { + ok( true, "tabsload" ); + + setTimeout(function() { + element.tabs( "option", "active", 0 ); + tabs_state( element, 1, 0, 0, 0, 0 ); + + element.one( "tabsshow", function( event, ui ) { + tabs_state( element, 0, 0, 1, 0, 0 ); + }); + element.one( "tabsload", function( event, ui ) { + ok( false, "should be cached" ); + }); + element.tabs( "option", "active", 2 ); + start(); + }, 1 ); + }); + element.tabs( "option", "active", 2 ); + tabs_state( element, 0, 0, 1, 0, 0 ); }); test( "idPrefix", function() { diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index f0661b3ad..8da11367e 100644 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -705,7 +705,7 @@ if ( $.uiBackCompat !== false ) { } }); - ui.jqXHR.success( function() { + ui.jqXHR.success(function() { if ( self.options.cache ) { $.data( ui.tab[ 0 ], "cache.tabs", true ); } -- cgit v1.2.3 From 0adeb9b0e1b2883eb008917333effe12ad20a64d Mon Sep 17 00:00:00 2001 From: David Petersen Date: Mon, 9 May 2011 15:42:24 -0400 Subject: Tabs: Add tabsload event tests. --- tests/unit/tabs/tabs_events.js | 62 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/unit/tabs/tabs_events.js b/tests/unit/tabs/tabs_events.js index 28925a2b9..d64005f8b 100644 --- a/tests/unit/tabs/tabs_events.js +++ b/tests/unit/tabs/tabs_events.js @@ -191,8 +191,66 @@ test( "beforeLoad", function() { equals( panel.html(), "

    testing

    ", "panel html after" ); }); -test( "load", function() { - ok( false, "missing test - untested code is broken code." ); +asyncTest( "load", function() { + expect( 21 ); + + var tab, panelId, panel, + element = $( "#tabs2" ); + + // init + element.one( "tabsload", function( event, ui ) { + tab = element.find( ".ui-tabs-nav a" ).eq( 2 ); + panelId = tab.attr( "aria-controls" ); + panel = $( "#" + panelId ); + + ok( !( "originalEvent" in event ), "originalEvent" ); + equals( ui.tab.size(), 1, "tab size" ); + strictEqual( ui.tab[ 0 ], tab[ 0 ], "tab" ); + equals( ui.panel.size(), 1, "panel size" ); + strictEqual( ui.panel[ 0 ], panel[ 0 ], "panel" ); + equals( ui.panel.find( "p" ).length, 1, "panel html" ); + tabs_state( element, 0, 0, 1, 0, 0 ); + tabsload1(); + }); + element.tabs({ active: 2 }); + + function tabsload1() { + // .option() + element.one( "tabsload", function( event, ui ) { + tab = element.find( ".ui-tabs-nav a" ).eq( 3 ); + panelId = tab.attr( "aria-controls" ); + panel = $( "#" + panelId ); + + ok( !( "originalEvent" in event ), "originalEvent" ); + equals( ui.tab.size(), 1, "tab size" ); + strictEqual( ui.tab[ 0 ], tab[ 0 ], "tab" ); + equals( ui.panel.size(), 1, "panel size" ); + strictEqual( ui.panel[ 0 ], panel[ 0 ], "panel" ); + equals( ui.panel.find( "p" ).length, 1, "panel html" ); + tabs_state( element, 0, 0, 0, 1, 0 ); + tabsload2(); + }); + element.tabs( "option", "active", 3 ); + } + + function tabsload2() { + // click, change panel content + element.one( "tabsload", function( event, ui ) { + tab = element.find( ".ui-tabs-nav a" ).eq( 4 ); + panelId = tab.attr( "aria-controls" ); + panel = $( "#" + panelId ); + + equals( event.originalEvent.type, "click", "originalEvent" ); + equals( ui.tab.size(), 1, "tab size" ); + strictEqual( ui.tab[ 0 ], tab[ 0 ], "tab" ); + equals( ui.panel.size(), 1, "panel size" ); + strictEqual( ui.panel[ 0 ], panel[ 0 ], "panel" ); + equals( ui.panel.find( "p" ).length, 1, "panel html" ); + tabs_state( element, 0, 0, 0, 0, 1 ); + start(); + }); + element.find( ".ui-tabs-nav a" ).eq( 4 ).click(); + } }); }( jQuery ) ); -- cgit v1.2.3 From 9ea6db634f392b5432e03f893cd48a9c2e15cbb5 Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 9 May 2011 16:04:33 -0400 Subject: Tabs: Only trigger tabsload on success. --- tests/unit/tabs/tabs_deprecated.js | 7 +++++-- ui/jquery.ui.tabs.js | 5 ++--- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/unit/tabs/tabs_deprecated.js b/tests/unit/tabs/tabs_deprecated.js index 49e89b7a0..a9f1f032f 100644 --- a/tests/unit/tabs/tabs_deprecated.js +++ b/tests/unit/tabs/tabs_deprecated.js @@ -156,8 +156,11 @@ asyncTest( "spinner", function() { equals( element.find( ".ui-tabs-nav li:eq(2) em" ).length, 1, "beforeload" ); }); element.one( "tabsload", function( event, ui ) { - equals( element.find( ".ui-tabs-nav li:eq(2) em" ).length, 0, "load" ); - start(); + // wait until after the load finishes before checking for the spinner to be removed + setTimeout(function() { + equals( element.find( ".ui-tabs-nav li:eq(2) em" ).length, 0, "load" ); + start(); + }, 1 ); }); element.tabs( "option", "active", 2 ); }); diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index 8da11367e..e7d4e3513 100644 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -621,6 +621,7 @@ $.widget( "ui.tabs", { this.xhr .success(function( response ) { panel.html( response ); + self._trigger( "load", event, eventData ); }) .complete(function( jqXHR, status ) { if ( status === "abort" ) { @@ -631,13 +632,11 @@ $.widget( "ui.tabs", { // "tabs" queue must not contain more than two elements, // which are the callbacks for the latest clicked tab... self.element.queue( "tabs", self.element.queue( "tabs" ).splice( -2, 2 ) ); - - delete this.xhr; } self.lis.eq( index ).removeClass( "ui-tabs-loading" ); - self._trigger( "load", event, eventData ); + delete self.xhr; }); } -- cgit v1.2.3 From f53d11785339543de7878add5ff25476246fa0b8 Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 9 May 2011 16:54:51 -0400 Subject: Tabs: Added test for abort method. Fixes #7133 - Tabs: Deprecate abort method. --- tests/unit/tabs/tabs_deprecated.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/unit/tabs/tabs_deprecated.js b/tests/unit/tabs/tabs_deprecated.js index a9f1f032f..144825007 100644 --- a/tests/unit/tabs/tabs_deprecated.js +++ b/tests/unit/tabs/tabs_deprecated.js @@ -463,8 +463,18 @@ test( "url", function() { element.tabs( "option", "active", 3 ); }); -test( "abort", function() { - ok( false, "missing test - untested code is broken code." ); +asyncTest( "abort", function() { + expect( 1 ); + + var element = $( "#tabs2" ).tabs(); + element.one( "tabsbeforeload", function( event, ui ) { + ui.jqXHR.error(function( jqXHR, status ) { + equals( status, "abort", "aborted" ); + start(); + }); + }); + element.tabs( "option", "active", 2 ); + element.tabs( "abort" ); }); }( jQuery ) ); -- cgit v1.2.3 From ea01e7fc50bb9480ee92dd3989dbdeb89cb71562 Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 9 May 2011 17:01:11 -0400 Subject: Tabs: Added tests for event option. --- tests/unit/tabs/tabs_options.js | 51 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/unit/tabs/tabs_options.js b/tests/unit/tabs/tabs_options.js index 691186276..7e2d9baf5 100644 --- a/tests/unit/tabs/tabs_options.js +++ b/tests/unit/tabs/tabs_options.js @@ -149,8 +149,55 @@ test('disabled', function() { same(el.tabs('option', 'disabled'), false, "should not disable any tab"); // ... }); -test('event', function() { - ok(false, "missing test - untested code is broken code."); +test( "{ event: null }", function() { + expect( 5 ); + + var element = $( "#tabs1" ).tabs({ + event: null + }); + tabs_state( element, 1, 0, 0 ); + + element.tabs( "option", "active", 1 ); + equal( element.tabs( "option", "active" ), 1 ); + tabs_state( element, 0, 1, 0 ); + + // ensure default click handler isn't bound + element.find( ".ui-tabs-nav a" ).eq( 2 ).click(); + equal( element.tabs( "option", "active" ), 1 ); + tabs_state( element, 0, 1, 0 ); +}); + +test( "{ event: custom }", function() { + expect( 11 ); + + var element = $( "#tabs1" ).tabs({ + event: "custom1 custom2" + }); + tabs_state( element, 1, 0, 0 ); + + element.find( ".ui-tabs-nav a" ).eq( 1 ).trigger( "custom1" ); + equal( element.tabs( "option", "active" ), 1 ); + tabs_state( element, 0, 1, 0 ); + + // ensure default click handler isn't bound + element.find( ".ui-tabs-nav a" ).eq( 2 ).trigger( "click" ); + equal( element.tabs( "option", "active" ), 1 ); + tabs_state( element, 0, 1, 0 ); + + element.find( ".ui-tabs-nav a" ).eq( 2 ).trigger( "custom2" ); + equal( element.tabs( "option", "active" ), 2 ); + tabs_state( element, 0, 0, 1 ); + + element.tabs( "option", "event", "custom3" ); + + // ensure old event handlers are unbound + element.find( ".ui-tabs-nav a" ).eq( 1 ).trigger( "custom1" ); + equal( element.tabs( "option", "active" ), 2 ); + tabs_state( element, 0, 0, 1 ); + + element.find( ".ui-tabs-nav a" ).eq( 1 ).trigger( "custom3" ); + equal( element.tabs( "option", "active" ), 1 ); + tabs_state( element, 0, 1, 0 ); }); test('fx', function() { -- cgit v1.2.3 From 6a9b789bc7f3ef99036974c1c06695aef091a994 Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 9 May 2011 17:10:36 -0400 Subject: Tabs: Updated tests for disabled option. --- tests/unit/tabs/tabs_options.js | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'tests') diff --git a/tests/unit/tabs/tabs_options.js b/tests/unit/tabs/tabs_options.js index 7e2d9baf5..97fd87bf6 100644 --- a/tests/unit/tabs/tabs_options.js +++ b/tests/unit/tabs/tabs_options.js @@ -133,20 +133,28 @@ test( "{ collapsible: true }", function() { tabs_state( element, 0, 0, 0 ); }); -test('disabled', function() { - expect(4); +test( "disabled", function() { + expect( 10 ); - el = $('#tabs1').tabs(); - same(el.tabs('option', 'disabled'), false, "should not disable any tab by default"); + // fully enabled by default + var element = $( "#tabs1" ).tabs(); + tabs_disabled( element, false ); + + // disable single tab + element.tabs( "option", "disabled", [ 1 ] ); + tabs_disabled( element, [ 1 ] ); - el.tabs('option', 'disabled', [ 1 ]); - same(el.tabs('option', 'disabled'), [ 1 ], "should set property"); // everything else is being tested in methods module... + // disabled active tab + element.tabs( "option", "disabled", [ 0, 1 ] ); + tabs_disabled( element, [ 0, 1 ] ); - el.tabs('option', 'disabled', [ 0, 1 ]); - same(el.tabs('option', 'disabled'), [ 0, 1 ], "should disable given tabs, even selected one"); // ... + // disable all tabs + element.tabs( "option", "disabled", [ 0, 1, 2 ] ); + tabs_disabled( element, true ); - el.tabs('option', 'disabled', [ ]); - same(el.tabs('option', 'disabled'), false, "should not disable any tab"); // ... + // enable all tabs + element.tabs( "option", "disabled", [] ); + tabs_disabled( element, false ); }); test( "{ event: null }", function() { @@ -200,8 +208,6 @@ test( "{ event: custom }", function() { tabs_state( element, 0, 1, 0 ); }); -test('fx', function() { - ok(false, "missing test - untested code is broken code."); -}); +// TODO: add animation tests })(jQuery); -- cgit v1.2.3 From 0f7075e2811489a5aeba13a763be602ef1aeea72 Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 9 May 2011 17:38:34 -0400 Subject: Tabs: Added tests for beforeload event on init. --- tests/unit/tabs/tabs_events.js | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/unit/tabs/tabs_events.js b/tests/unit/tabs/tabs_events.js index d64005f8b..2fabaafca 100644 --- a/tests/unit/tabs/tabs_events.js +++ b/tests/unit/tabs/tabs_events.js @@ -138,15 +138,32 @@ test( "activate", function() { }); test( "beforeLoad", function() { - expect( 21 ); + expect( 32 ); var tab, panelId, panel, - element = $( "#tabs2" ).tabs(); + element = $( "#tabs2" ); - // TODO: init -// element.one( "tabsbeforeload", function( event, ui ) { -// }); -// element.tabs({ active: 2 }); + // init + element.one( "tabsbeforeload", function( event, ui ) { + tab = element.find( ".ui-tabs-nav a" ).eq( 2 ); + panelId = tab.attr( "aria-controls" ); + panel = $( "#" + panelId ); + + ok( !( "originalEvent" in event ), "originalEvent" ); + ok( "abort" in ui.jqXHR, "jqXHR" ); + ok( ui.ajaxSettings.url, "data/test.html", "ajaxSettings.url" ); + equals( ui.tab.size(), 1, "tab size" ); + strictEqual( ui.tab[ 0 ], tab[ 0 ], "tab" ); + equals( ui.panel.size(), 1, "panel size" ); + strictEqual( ui.panel[ 0 ], panel[ 0 ], "panel" ); + equals( ui.panel.html(), "", "panel html" ); + event.preventDefault(); + tabs_state( element, 0, 0, 1, 0, 0 ); + }); + element.tabs({ active: 2 }); + tabs_state( element, 0, 0, 1, 0, 0 ); + equals( panel.html(), "", "panel html after" ); + element.tabs( "destroy" ); // .option() element.one( "tabsbeforeload", function( event, ui ) { @@ -165,6 +182,7 @@ test( "beforeLoad", function() { event.preventDefault(); tabs_state( element, 1, 0, 0, 0, 0 ); }); + element.tabs(); element.tabs( "option", "active", 2 ); tabs_state( element, 0, 0, 1, 0, 0 ); equals( panel.html(), "", "panel html after" ); -- cgit v1.2.3 From bd6672d2571f69d5e2ed819e13514580648aaa13 Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 9 May 2011 17:41:43 -0400 Subject: Tabs: Updated tests for destroy method. --- tests/unit/tabs/tabs_methods.js | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'tests') diff --git a/tests/unit/tabs/tabs_methods.js b/tests/unit/tabs/tabs_methods.js index a6e60a4b3..221b0d39d 100644 --- a/tests/unit/tabs/tabs_methods.js +++ b/tests/unit/tabs/tabs_methods.js @@ -2,19 +2,10 @@ module( "tabs: methods" ); -test('destroy', function() { - expect(6); - - el = $('#tabs1').tabs({ collapsible: true }); - $('li:eq(2)', el).simulate('mouseover').find('a').focus(); - el.tabs('destroy'); - - ok( el.is(':not(.ui-tabs, .ui-widget, .ui-widget-content, .ui-corner-all, .ui-tabs-collapsible)'), 'remove classes from container'); - ok( $('ul', el).is(':not(.ui-tabs-nav, .ui-helper-reset, .ui-helper-clearfix, .ui-widget-header, .ui-corner-all)'), 'remove classes from list' ); - ok( $('div:eq(1)', el).is(':not(.ui-tabs-panel, .ui-widget-content, .ui-corner-bottom)'), 'remove classes to panel' ); - ok( $('li:eq(0)', el).is(':not(.ui-tabs-active, .ui-state-active, .ui-corner-top)'), 'remove classes from active li'); - ok( $('li:eq(1)', el).is(':not(.ui-state-default, .ui-corner-top)'), 'remove classes from inactive li'); - ok( $('li:eq(2)', el).is(':not(.ui-state-hover, .ui-state-focus)'), 'remove classes from mouseovered or focused li'); +test( "destroy", function() { + domEqual( "#tabs1", function() { + $( "#tabs1" ).tabs().tabs( "destroy" ); + }); }); test( "enable", function() { -- cgit v1.2.3 From a205c2c8b8498f82f87a723f49c1fe746e47c667 Mon Sep 17 00:00:00 2001 From: Scott González Date: Tue, 10 May 2011 08:47:00 -0400 Subject: Tabs: Moved tests out of tickets file. --- tests/unit/tabs/tabs.html | 1 - tests/unit/tabs/tabs_core.js | 28 +++++++++++++++++++++++++++ tests/unit/tabs/tabs_deprecated.html | 1 - tests/unit/tabs/tabs_options.js | 2 +- tests/unit/tabs/tabs_tickets.js | 37 ------------------------------------ 5 files changed, 29 insertions(+), 40 deletions(-) delete mode 100644 tests/unit/tabs/tabs_tickets.js (limited to 'tests') diff --git a/tests/unit/tabs/tabs.html b/tests/unit/tabs/tabs.html index 565a0b427..34ec28bc4 100644 --- a/tests/unit/tabs/tabs.html +++ b/tests/unit/tabs/tabs.html @@ -24,7 +24,6 @@ - -