diff options
47 files changed, 1480 insertions, 1049 deletions
@@ -7,3 +7,20 @@ If you want to use jQuery UI, go to [jqueryui.com](http://jqueryui.com) to get s If you are interested in helping developing jQuery UI, you are in the right place. To discuss development with team members and the community, visit the [Developing jQuery UI Forum](http://forum.jquery.com/developing-jquery-ui). + +For committers +--- +When looking at pull requests, first check for [proper commit messages](http://wiki.jqueryui.com/w/page/12137724/Bug-Fixing-Guide). + +Unless everything is fine and you can merge directly via GitHub's interface, fetch the remote first: + + git remote add [username] [his-fork.git] -f + +If you want just one commit and edit the commit message: + + git cherry-pick -e [sha-of-commit] + +If it should go to the stable brach, cherry-pick it to stable: + + git checkout 1-8-stable + git cherry-pick -x [sha-of-commit] diff --git a/demos/autocomplete/combobox.html b/demos/autocomplete/combobox.html index ded809e1e..5fb3ffef9 100644 --- a/demos/autocomplete/combobox.html +++ b/demos/autocomplete/combobox.html @@ -16,7 +16,7 @@ <style> .ui-button { margin-left: -1px; } .ui-button-icon-only .ui-button-text { padding: 0.35em; } - .ui-autocomplete-input { margin: 0; padding: 0.48em 0 0.47em 0.45em; } + .ui-autocomplete-input { margin: 0; padding: 0.4em 0 0.4em 0.45em; } </style> <script> (function( $ ) { @@ -26,6 +26,32 @@ select = this.element.hide(), selected = select.children( ":selected" ), value = selected.val() ? selected.text() : ""; + + function removeIfInvalid(element) { + var value = $( element ).val(), + matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( value ) + "$", "i" ), + valid = false; + select.children( "option" ).each(function() { + if ( $( this ).text().match( matcher ) ) { + this.selected = valid = true; + return false; + } + }); + if ( !valid ) { + // remove invalid value, as it didn't match anything + $( element ) + .val( "" ) + .attr( "title", value + " didn't match any item" ) + .tooltip( "open" ); + select.val( "" ); + setTimeout(function() { + input.tooltip( "close" ).attr( "title", "" ); + }, 2500 ); + input.data( "autocomplete" ).term = ""; + return false; + } + } + var input = this.input = $( "<input>" ) .insertAfter( select ) .val( value ) @@ -57,30 +83,8 @@ }); }, change: function( event, ui ) { - if ( !ui.item ) { - var value = $( this ).val(), - matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( value ) + "$", "i" ), - valid = false; - select.children( "option" ).each(function() { - if ( $( this ).text().match( matcher ) ) { - this.selected = valid = true; - return false; - } - }); - if ( !valid ) { - // remove invalid value, as it didn't match anything - $( this ) - .val( "" ) - .attr( "title", value + " didn't match any item" ) - .tooltip( "open" ); - select.val( "" ); - setTimeout(function() { - input.tooltip( "close" ).attr( "title", "" ); - }, 2500 ); - input.data( "autocomplete" ).term = ""; - return false; - } - } + if ( !ui.item ) + return removeIfInvalid( this ); } }) .addClass( "ui-widget ui-widget-content ui-corner-left" ); @@ -109,6 +113,7 @@ // close if already visible if ( input.autocomplete( "widget" ).is( ":visible" ) ) { input.autocomplete( "close" ); + removeIfInvalid( input ); return; } @@ -124,10 +129,9 @@ .tooltip({ position: { of: this.button - } - }) - .tooltip( "widget" ) - .addClass( "ui-state-highlight" ); + }, + tooltipClass: "ui-state-highlight" + }); }, destroy: function() { diff --git a/demos/autocomplete/maxheight.html b/demos/autocomplete/maxheight.html index fc0b4840c..c4f9769c3 100644 --- a/demos/autocomplete/maxheight.html +++ b/demos/autocomplete/maxheight.html @@ -8,6 +8,7 @@ <script src="../../ui/jquery.ui.core.js"></script> <script src="../../ui/jquery.ui.widget.js"></script> <script src="../../ui/jquery.ui.position.js"></script> + <script src="../../ui/jquery.ui.menu.js"></script> <script src="../../ui/jquery.ui.autocomplete.js"></script> <link rel="stylesheet" href="../demos.css"> <style> 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 @@ <script src="../ui/jquery.ui.draggable.js"></script> <script src="../ui/jquery.ui.droppable.js"></script> <script src="../ui/jquery.ui.menu.js"></script> + <script src="../ui/jquery.ui.menubar.js"></script> + <script src="../ui/jquery.ui.popup.js"></script> <script src="../ui/jquery.ui.position.js"></script> <script src="../ui/jquery.ui.progressbar.js"></script> <script src="../ui/jquery.ui.resizable.js"></script> @@ -279,6 +281,8 @@ <dd><a href="datepicker/index.html">Datepicker</a></dd> <dd><a href="dialog/index.html">Dialog</a></dd> <dd><a href="menu/index.html">Menu</a></dd> + <dd><a href="menubar/index.html">Menubar</a></dd> + <dd><a href="popup/index.html">Popup</a></dd> <dd><a href="progressbar/index.html">Progressbar</a></dd> <dd><a href="slider/index.html">Slider</a></dd> <dd><a href="spinner/index.html">Spinner</a></dd> diff --git a/demos/menu/contextmenu.html b/demos/menu/contextmenu.html index 0fb98c140..7513bca28 100644 --- a/demos/menu/contextmenu.html +++ b/demos/menu/contextmenu.html @@ -3,44 +3,28 @@ <head> <meta charset="UTF-8" /> <title>jQuery UI Menu - Contextmenu demo</title> - <link type="text/css" href="../../themes/base/jquery.ui.all.css" rel="stylesheet" /> - <script type="text/javascript" src="../../jquery-1.5.1.js"></script> - <script type="text/javascript" src="../../ui/jquery.ui.core.js"></script> - <script type="text/javascript" src="../../ui/jquery.ui.position.js"></script> - <script type="text/javascript" src="../../ui/jquery.ui.widget.js"></script> - <script type="text/javascript" src="../../ui/jquery.ui.menu.js"></script> - <script type="text/javascript" src="../../ui/jquery.ui.button.js"></script> - <link type="text/css" href="../demos.css" rel="stylesheet" /> - <script type="text/javascript"> + <link href="../../themes/base/jquery.ui.all.css" rel="stylesheet" /> + <script src="../../jquery-1.5.1.js"></script> + <script src="../../ui/jquery.ui.core.js"></script> + <script src="../../ui/jquery.ui.position.js"></script> + <script src="../../ui/jquery.ui.widget.js"></script> + <script src="../../ui/jquery.ui.menu.js"></script> + <script src="../../ui/jquery.ui.button.js"></script> + <script src="../../ui/jquery.ui.popup.js"></script> + <link href="../demos.css" rel="stylesheet" /> + <script> $(function() { $(".demo button").button({ icons: { primary: "ui-icon-home", secondary: "ui-icon-triangle-1-s" } - }).each(function() { - $(this).next().menu({ - select: function(event, ui) { - $(this).hide(); - $("#log").append("<div>Selected " + ui.item.text() + "</div>"); - } - }).hide(); - }).click(function(event) { - var menu = $(this).next(); - if (menu.is(":visible")) { - menu.hide(); - return false; + }).next().menu({ + select: function(event, ui) { + $(this).hide(); + $("#log").append("<div>Selected " + ui.item.text() + "</div>"); } - menu.menu("blur").show().position({ - my: "left top", - at: "right top", - of: this - }); - $(document).one("click", function() { - menu.hide(); - }); - return false; - }) + }).popup(); }); </script> <style> @@ -53,14 +37,14 @@ <button>Select a city</button> <ul> - <li><a href="#">Amsterdam</a></li> - <li><a href="#">Anaheim</a></li> - <li><a href="#">Cologne</a></li> - <li><a href="#">Frankfurt</a></li> - <li><a href="#">Magdeburg</a></li> - <li><a href="#">Munich</a></li> - <li><a href="#">Utrecht</a></li> - <li><a href="#">Zurich</a></li> + <li><a href="#Amsterdam">Amsterdam</a></li> + <li><a href="#Anaheim">Anaheim</a></li> + <li><a href="#Cologne">Cologne</a></li> + <li><a href="#Frankfurt">Frankfurt</a></li> + <li><a href="#Magdeburg">Magdeburg</a></li> + <li><a href="#Munich">Munich</a></li> + <li><a href="#Utrecht">Utrecht</a></li> + <li><a href="#Zurich">Zurich</a></li> </ul> <div id="log"></div> @@ -69,7 +53,7 @@ <div class="demo-description"> -<p>A simple contextmenu: Click the button, or tab to it and hit space to open the menu. Use the mouse or cursor keys to select an item, click it or hit enter to select it.</p> +<p>TODO update - A simple contextmenu: Click the button, or tab to it and hit space to open the menu. Use the mouse or cursor keys to select an item, click it or hit enter to select it.</p> <p>The keyboard handling is part of the menu. Using the input option to menu is configured to add the key event handlers to the button, as that button gets focused when clicked.</p> diff --git a/demos/menu/default.html b/demos/menu/default.html index 2d9dddf28..40386112f 100644 --- a/demos/menu/default.html +++ b/demos/menu/default.html @@ -4,12 +4,12 @@ <meta charset="UTF-8" /> <title>jQuery UI Menu - Default demo</title> <link type="text/css" href="../../themes/base/jquery.ui.all.css" rel="stylesheet" /> - <script type="text/javascript" src="../../jquery-1.5.1.js"></script> - <script type="text/javascript" src="../../ui/jquery.ui.core.js"></script> - <script type="text/javascript" src="../../ui/jquery.ui.widget.js"></script> - <script type="text/javascript" src="../../ui/jquery.ui.menu.js"></script> - <link type="text/css" href="../demos.css" rel="stylesheet" /> - <script type="text/javascript"> + <script src="../../jquery-1.5.1.js"></script> + <script src="../../ui/jquery.ui.core.js"></script> + <script src="../../ui/jquery.ui.widget.js"></script> + <script src="../../ui/jquery.ui.menu.js"></script> + <link href="../demos.css" rel="stylesheet" /> + <script> $(function() { $(".demo ul").menu(); }); @@ -23,21 +23,21 @@ <div class="demo"> <ul> - <li><a href="#">Aberdeen</a></li> - <li><a href="#">Ada</a></li> - <li><a href="#">Adamsville</a></li> - <li><a href="#">Addyston</a></li> - <li><a href="#">Adelphi</a></li> - <li><a href="#">Adena</a></li> - <li><a href="#">Adrian</a></li> - <li><a href="#">Akron</a></li> - <li><a href="#">Albany</a></li> - <li><a href="#">Alexandria</a></li> - <li><a href="#">Alger</a></li> - <li><a href="#">Alledonia</a></li> - <li><a href="#">Alliance</a></li> - <li><a href="#">Alpha</a></li> - <li><a href="#">Alvada</a></li> + <li><a href="#Aberdeen">Aberdeen</a></li> + <li><a href="#Ada">Ada</a></li> + <li><a href="#Adamsville">Adamsville</a></li> + <li><a href="#Addyston">Addyston</a></li> + <li><a href="#Adelphi">Adelphi</a></li> + <li><a href="#Adena">Adena</a></li> + <li><a href="#Adrian">Adrian</a></li> + <li><a href="#Akron">Akron</a></li> + <li><a href="#Albany">Albany</a></li> + <li><a href="#Alexandria">Alexandria</a></li> + <li><a href="#Alger">Alger</a></li> + <li><a href="#Alledonia">Alledonia</a></li> + <li><a href="#Alliance">Alliance</a></li> + <li><a href="#Alpha">Alpha</a></li> + <li><a href="#Alvada">Alvada</a></li> </ul> </div><!-- End demo --> diff --git a/demos/menu/index.html b/demos/menu/index.html index cfc12bc1d..3088f9d7d 100644 --- a/demos/menu/index.html +++ b/demos/menu/index.html @@ -3,7 +3,7 @@ <head> <meta charset="UTF-8" /> <title>jQuery UI Menu Demos</title> - <link type="text/css" href="../demos.css" rel="stylesheet" /> + <link href="../demos.css" rel="stylesheet" /> </head> <body> <div class="demos-nav"> diff --git a/tests/visual/menu/menubar.html b/demos/menubar/default.html index d2185e97c..79662bd9f 100644 --- a/tests/visual/menu/menubar.html +++ b/demos/menubar/default.html @@ -1,27 +1,18 @@ <!DOCTYPE html> <html> <head> - <title>Menu Visual Test: Default</title> - <link rel="stylesheet" href="../visual.css" type="text/css" /> - <link rel="stylesheet" href="../../../themes/base/jquery.ui.all.css" type="text/css" title="ui-theme" /> - <script type="text/javascript" src="../../../jquery-1.5.1.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.core.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.button.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.menu.js"></script> - <script type="text/javascript" src="menubar.js"></script> - <!-- - <script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script> - --> - <script type="text/javascript"> + <title>jQuery UI Menubar - Default demo</title> + <link rel="stylesheet" href="../demos.css" type="text/css" /> + <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css" type="text/css" title="ui-theme" /> + <script src="../../jquery-1.5.1.js"></script> + <script src="../../ui/jquery.ui.core.js"></script> + <script src="../../ui/jquery.ui.widget.js"></script> + <script src="../../ui/jquery.ui.position.js"></script> + <script src="../../ui/jquery.ui.button.js"></script> + <script src="../../ui/jquery.ui.menu.js"></script> + <script src="../../ui/jquery.ui.menubar.js"></script> + <script> $(function() { - $.fn.themeswitcher && $('<div/>').css({ - position: "absolute", - right: 10, - top: 10 - }).appendTo(document.body).themeswitcher(); - $("td:has(.menubar)").clone().appendTo("tbody tr:not(:first)"); $("#bar1, .menubar").menubar({ @@ -40,7 +31,6 @@ }); </script> <style type="text/css"> - body { font-size:62.5%; } #bar1, #bar2 { margin: 0 0 4em; } /* style for this page only */ .ui-menu { width: 200px; position: absolute; outline: none; z-index: 9999; } .ui-menu .ui-icon { float: right; } @@ -64,7 +54,7 @@ .ui-menubar-item { float: left; } - + /* table { border-collapse: collapse; } @@ -72,102 +62,105 @@ padding: 0.5em; border: 1px solid black; } + */ </style> </head> <body> +<div class="demo"> <ul id="bar1" class="menubar"> <li> - <a href="#">File</a> + <a href="#File">File</a> <ul> - <li><a href="#">Open...</a></li> + <li><a href="#Open...">Open...</a></li> <li class="ui-state-disabled">Open recent...</li> - <li><a href="#">Save</a></li> - <li><a href="#">Save as...</a></li> - <li><a href="#">Close</a></li> - <li><a href="#">Quit</a></li> + <li><a href="#Save">Save</a></li> + <li><a href="#Save as...">Save as...</a></li> + <li><a href="#Close">Close</a></li> + <li><a href="#Quit">Quit</a></li> </ul> </li> <li> - <a href="#">Edit</a> + <a href="#Edit">Edit</a> <ul> - <li><a href="#">Copy</a></li> - <li><a href="#">Cut</a></li> + <li><a href="#Copy">Copy</a></li> + <li><a href="#Cut">Cut</a></li> <li class="ui-state-disabled">Paste</li> </ul> </li> <li> - <a href="#">View</a> + <a href="#View">View</a> <ul> - <li><a href="#">Fullscreen</a></li> - <li><a href="#">Fit into view</a></li> + <li><a href="#Fullscreen">Fullscreen</a></li> + <li><a href="#Fit into view">Fit into view</a></li> <li> - <a href="#">Encoding</a> + <a href="#Encoding">Encoding</a> <ul> - <li><a href="#">Auto-detect</a></li> - <li><a href="#">UTF-8</a></li> + <li><a href="#Auto-detect">Auto-detect</a></li> + <li><a href="#UTF-8">UTF-8</a></li> <li> - <a href="#">UTF-16</a> + <a href="#UTF-16">UTF-16</a> <ul> - <li><a href="#">Option 1</a></li> - <li><a href="#">Option 2</a></li> - <li><a href="#">Option 3</a></li> - <li><a href="#">Option 4</a></li> + <li><a href="#Option 1">Option 1</a></li> + <li><a href="#Option 2">Option 2</a></li> + <li><a href="#Option 3">Option 3</a></li> + <li><a href="#Option 4">Option 4</a></li> </ul> </li> </ul> </li> - <li><a href="#">Customize...</a></li> + <li><a href="#Customize...">Customize...</a></li> </ul> </li> </ul> <ul id="bar2" class="menubar-icons"> <li> - <a href="#">File</a> + <a href="#File">File</a> <ul> - <li><a href="#">Open...</a></li> + <li><a href="#Open...">Open...</a></li> <li class="ui-state-disabled">Open recent...</li> - <li><a href="#">Save</a></li> - <li><a href="#">Save as...</a></li> - <li><a href="#">Close</a></li> - <li><a href="#">Quit</a></li> + <li><a href="#Save">Save</a></li> + <li><a href="#Save as...">Save as...</a></li> + <li><a href="#Close">Close</a></li> + <li><a href="#Quit">Quit</a></li> </ul> </li> <li> - <a href="#">Edit</a> + <a href="#Edit">Edit</a> <ul> - <li><a href="#">Copy</a></li> - <li><a href="#">Cut</a></li> + <li><a href="#Copy">Copy</a></li> + <li><a href="#Cut">Cut</a></li> <li class="ui-state-disabled">Paste</li> </ul> </li> <li> - <a href="#">View</a> + <a href="#View">View</a> <ul> - <li><a href="#">Fullscreen</a></li> - <li><a href="#">Fit into view</a></li> + <li><a href="#Fullscreen">Fullscreen</a></li> + <li><a href="#Fit into view">Fit into view</a></li> <li> - <a href="#">Encoding</a> + <a href="#Encoding">Encoding</a> <ul> - <li><a href="#">Auto-detect</a></li> - <li><a href="#">UTF-8</a></li> + <li><a href="#Auto-detect">Auto-detect</a></li> + <li><a href="#UTF-8">UTF-8</a></li> <li> - <a href="#">UTF-16</a> + <a href="#UTF-16">UTF-16</a> <ul> - <li><a href="#">Option 1</a></li> - <li><a href="#">Option 2</a></li> - <li><a href="#">Option 3</a></li> - <li><a href="#">Option 4</a></li> + <li><a href="#Option 1">Option 1</a></li> + <li><a href="#Option 2">Option 2</a></li> + <li><a href="#Option 3">Option 3</a></li> + <li><a href="#Option 4">Option 4</a></li> </ul> </li> </ul> </li> - <li><a href="#">Customize...</a></li> + <li><a href="#Customize...">Customize...</a></li> </ul> </li> </ul> +<!-- <table id="movies" class="ui-widget"> <thead> <tr> @@ -185,19 +178,19 @@ <td class="ui-widget-content"> <ul class="menubar"> <li> - <a href="#">Options</a> + <a href="#Options">Options</a> <ul> - <li><a href="#">Order...</a></li> + <li><a href="#Order...">Order...</a></li> <li class="ui-state-disabled">Write a Review...</li> - <li><a href="#">Find Similar Movies...</a></li> + <li><a href="#Find Similar Movies...">Find Similar Movies...</a></li> <li> - <a href="#">Rate</a> + <a href="#Rate">Rate</a> <ul> - <li><a href="#">5 stars</a></li> - <li><a href="#">4 stars</a></li> - <li><a href="#">3 stars</a></li> - <li><a href="#">2 stars</a></li> - <li><a href="#">1 stars</a></li> + <li><a href="#5 stars">5 stars</a></li> + <li><a href="#4 stars">4 stars</a></li> + <li><a href="#3 stars">3 stars</a></li> + <li><a href="#2 stars">2 stars</a></li> + <li><a href="#1 stars">1 stars</a></li> </ul> </li> </ul> @@ -222,11 +215,20 @@ </tr> </tbody> </table> +--> <div class="ui-widget" style="margin-top:2em; font-family:Arial"> Log: - <div id="log" style="height: 400px; width: 300px; overflow: auto;" class="ui-widget-content"></div> + <div id="log" style="height: 100px; width: 300px; overflow: auto;" class="ui-widget-content"></div> </div> +</div> + +<div class="demo-description"> + +<p>TODO</p> + +</div><!-- End demo-description --> + </body> </html> 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 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8" /> + <title>jQuery UI Menubar Demos</title> + <link href="../demos.css" rel="stylesheet" /> +</head> +<body> + <div class="demos-nav"> + <h4>Examples</h4> + <ul> + <li class="demo-config-on"><a href="default.html">Default functionality</a></li> + </ul> + </div> +</body> +</html> 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 @@ +<!DOCTYPE html> +<html> +<head> + <title>jQuery UI Popup - Default demo</title> + <link rel="stylesheet" href="../demos.css" /> + <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css" title="ui-theme" /> + <script src="../../jquery-1.5.1.js"></script> + <script src="../../ui/jquery.ui.core.js"></script> + <script src="../../ui/jquery.ui.widget.js"></script> + <script src="../../ui/jquery.ui.position.js"></script> + <script src="../../ui/jquery.ui.button.js"></script> + <script src="../../ui/jquery.ui.menu.js"></script> + <script src="../../ui/jquery.ui.popup.js"></script> + <script> + $(function() { + var selected = { + select: function( event, ui ) { + $( "<div/>" ).text( "Selected: " + ui.item.text() ).appendTo( "#log" ); + $(this).popup("close"); + } + }; + + $("#login-form").popup() + .find(":submit").button().click(function(event) { + event.preventDefault(); + }); + }); + </script> + <style type="text/css"> + .ui-popup { position: absolute; z-index: 5000; } + .ui-menu { width: 200px; } + + /* + table { + border-collapse: collapse; + } + th, td { + padding: 0.5em; + border: 1px solid black; + } + */ + + #login-form { + width: 16em; border: 1px solid gray; border-radius: 5px; + padding: 1em; + 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: 1.3em; outline: none; + } + #login-form label { display: inline-block; width: 5em; } + #login-form .submit { margin-left: 5em; } + </style> +</head> +<body> + +<div class="demo"> + <a href="#login-form">Log In</a> + <div id="login-form" class="ui-widget-content" tabIndex="0"> + <form> + <div> + <label>Username</label> + <input type="username" /> + </div> + <div> + <label>Password</label> + <input type="password" /> + </div> + <div> + <input type="submit" class="submit" value="Login" /> + </div> + </form> + </div> +</div> + +<div class="demo-description"> + +<p>A link to a login form that opens as a popup. [Not quite functional, focus handling needs to get better]</p> + +</div><!-- End demo-description --> + + +</body> +</html> 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 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8" /> + <title>jQuery UI Popup Demos</title> + <link href="../demos.css" rel="stylesheet" /> +</head> +<body> + <div class="demos-nav"> + <h4>Examples</h4> + <ul> + <li class="demo-config-on"><a href="default.html">Default functionality</a></li> + <li><a href="popup-menu.html">Menu's as popup</a></li> + <li><a href="popup-menu-table.html">Menu's as popup in a table</a></li> + </ul> + </div> +</body> +</html> 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 @@ +<!DOCTYPE html> +<html> +<head> + <title>jQuery UI Popup - Menu as Popup in table demo</title> + <link rel="stylesheet" href="../demos.css" /> + <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css" title="ui-theme" /> + <script src="../../jquery-1.5.1.js"></script> + <script src="../../ui/jquery.ui.core.js"></script> + <script src="../../ui/jquery.ui.widget.js"></script> + <script src="../../ui/jquery.ui.position.js"></script> + <script src="../../ui/jquery.ui.button.js"></script> + <script src="../../ui/jquery.ui.menu.js"></script> + <script src="../../ui/jquery.ui.popup.js"></script> + <script> + $(function() { + var selected = { + select: function( event, ui ) { + $( "<div/>" ).text( "Selected: " + ui.item.text() ).appendTo( "#log" ); + $(this).popup("close"); + } + }; + + $(".demo td:has(.menubar)").clone().appendTo(".demo tbody tr:not(:first)"); + $("table .menubar > ul").menu(selected).popup().prev().button(); + }); + </script> + <style type="text/css"> + .ui-popup { position: absolute; z-index: 5000; } + .ui-menu { width: 200px; } + + .demo table { + border-collapse: collapse; + } + .demo th, .demo td { + padding: 0.5em; + } + </style> +</head> +<body> + +<div class="demo"> + + <table id="movies" class="ui-widget"> + <thead> + <tr> + <th data-field="Name" class="ui-widget-header">Name</th> + <th data-field="ReleaseYear" class="ui-widget-header">Release Year</th> + <th data-field="AverageRating" class="ui-widget-header">Average Rating</th> + <th class="ui-widget-header"></th> + </tr> + </thead> + <tbody> + <tr> + <td class="ui-widget-content">Red Hot Chili Peppers: Funky Monks</td> + <td class="ui-widget-content">1993</td> + <td class="ui-widget-content">3.6</td> + <td class="ui-widget-content"> + <div class="menubar"> + <a href="#">Options</a> + <ul> + <li><a href="#">Order...</a></li> + <li class="ui-state-disabled">Write a Review...</li> + <li><a href="#">Find Similar Movies...</a></li> + <li> + <a href="#">Rate</a> + <ul> + <li><a href="#">5 stars</a></li> + <li><a href="#">4 stars</a></li> + <li><a href="#">3 stars</a></li> + <li><a href="#">2 stars</a></li> + <li><a href="#">1 stars</a></li> + </ul> + </li> + </ul> + </div> + </td> + </tr> + <tr> + <td class="ui-widget-content">Rod Stewart: Storyteller 1984-1991</td> + <td class="ui-widget-content">1991</td> + <td class="ui-widget-content">3.1</td> + </tr> + <tr> + <td class="ui-widget-content">Stevie Ray Vaughan and Double Trouble: Live at the El Mocambo 1983</td> + <td class="ui-widget-content">1991</td> + <td class="ui-widget-content">3.9</td> + </tr> + <tr> + <td class="ui-widget-content">Spike and Mike's Sick & Twisted Festival of Animation</td> + <td class="ui-widget-content">1997</td> + <td class="ui-widget-content">2.6</td> + </tr> + </tbody> + </table> + + <div id="log"></div> +</div> + + +<div class="demo-description"> + +<p>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.</p> + +</div><!-- End demo-description --> + + +</body> +</html> 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 @@ +<!DOCTYPE html> +<html> +<head> + <title>jQuery UI Popup - Popup Menu</title> + <link rel="stylesheet" href="../demos.css" /> + <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css" title="ui-theme" /> + <script src="../../jquery-1.5.1.js"></script> + <script src="../../ui/jquery.ui.core.js"></script> + <script src="../../ui/jquery.ui.widget.js"></script> + <script src="../../ui/jquery.ui.position.js"></script> + <script src="../../ui/jquery.ui.button.js"></script> + <script src="../../ui/jquery.ui.menu.js"></script> + <script src="../../ui/jquery.ui.popup.js"></script> + <script> + $(function() { + function log( msg ) { + $( "<div/>" ).text( msg ).appendTo( "#log" ); + } + var selected = { + select: function( event, ui ) { + log( "Selected: " + ui.item.text() ); + $(this).popup("close"); + } + }; + + $("#button1").button() + .next().menu(selected).popup(); + + $( "#rerun" ) + .button() + .click(function() { + log( "Selected: " + $( this ).text() ); + }) + .next() + .button({ + text: false, + icons: { + primary: "ui-icon-triangle-1-s" + } + }) + .next() + .menu(selected) + .popup({ + trigger: $("#select") + }) + .parent() + .buttonset({ + items: "button" + }); + }); + </script> + <style type="text/css"> + .ui-popup { position: absolute; z-index: 5000; } + .ui-menu { width: 200px; } + </style> +</head> +<body> + +<div class="demo"> + + <button id="button1">Show context menu 1</button> + <ul> + <li><a href="#">Amsterdam</a></li> + <li><a href="#">Anaheim</a></li> + <li><a href="#">Cologne</a></li> + <li><a href="#">Frankfurt</a></li> + <li><a href="#">Magdeburg</a></li> + <li><a href="#">Munich</a></li> + <li><a href="#">Utrecht</a></li> + <li><a href="#">Zurich</a></li> + </ul> + + + <div> + <div> + <button id="rerun">Run last action</button> + <button id="select">Select an action</button> + <ul> + <li><a href="#">Open...</a></li> + <li><a href="#">Save</a></li> + <li><a href="#">Delete</a></li> + </ul> + </div> + </div> + + <div id="log"></div> +</div> + + +<div class="demo-description"> + +<p>Make the popup a menu (or the menu a popup) and you get context menus.</p> + +</div><!-- End demo-description --> + + +</body> +</html> diff --git a/demos/resizable/constrain-area.html b/demos/resizable/constrain-area.html index a7003352c..33539f940 100644 --- a/demos/resizable/constrain-area.html +++ b/demos/resizable/constrain-area.html @@ -10,7 +10,7 @@ <script src="../../ui/jquery.ui.mouse.js"></script> <script src="../../ui/jquery.ui.resizable.js"></script> <link rel="stylesheet" href="../demos.css"> - <style\> + <style> #container { width: 300px; height: 300px; } #container h3 { text-align: center; margin: 0; margin-bottom: 10px; } #resizable { background-position: top left; width: 150px; height: 150px; } diff --git a/demos/tabs/manipulation.html b/demos/tabs/manipulation.html index 8b8ddf4e6..4b79ac714 100644 --- a/demos/tabs/manipulation.html +++ b/demos/tabs/manipulation.html @@ -22,21 +22,15 @@ </style> <script> $(function() { - var $tab_title_input = $( "#tab_title"), - $tab_content_input = $( "#tab_content" ); - var tab_counter = 2; - - // tabs init with a custom tab template and an "add" callback filling in the content - var $tabs = $( "#tabs").tabs({ - tabTemplate: "<li><a href='#{href}'>#{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>", - add: function( event, ui ) { - var tab_content = $tab_content_input.val() || "Tab " + tab_counter + " content."; - $( ui.panel ).append( "<p>" + tab_content + "</p>" ); - } - }); + var tabTitle = $( "#tab_title" ), + tabContent = $( "#tab_content" ), + tabTemplate = "<li><a href='#{href}'>#{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>", + tabCounter = 2; + + var tabs = $( "#tabs" ).tabs(); // modal dialog init: custom buttons and a "close" callback reseting the form inside - var $dialog = $( "#dialog" ).dialog({ + var dialog = $( "#dialog" ).dialog({ autoOpen: false, modal: true, buttons: { @@ -48,40 +42,43 @@ $( this ).dialog( "close" ); } }, - open: function() { - $tab_title_input.focus(); - }, close: function() { - $form[ 0 ].reset(); + form[ 0 ].reset(); } }); // addTab form: calls addTab function on submit and closes the dialog - var $form = $( "form", $dialog ).submit(function() { + var form = dialog.find( "form" ).submit(function( event ) { addTab(); - $dialog.dialog( "close" ); - return false; + dialog.dialog( "close" ); + event.preventDefault(); }); - // actual addTab function: adds new tab using the title input from the form above + // actual addTab function: adds new tab using the input from the form above function addTab() { - var tab_title = $tab_title_input.val() || "Tab " + tab_counter; - $tabs.tabs( "add", "#tabs-" + tab_counter, tab_title ); - tab_counter++; + var label = tabTitle.val() || "Tab " + tabCounter, + id = "tabs-" + tabCounter, + li = $( tabTemplate.replace( /#\{href\}/g, "#" + id ).replace( /#\{label\}/g, label ) ), + tabContentHtml = tabContent.val() || "Tab " + tabCounter + " content."; + + tabs.find( ".ui-tabs-nav" ).append( li ); + tabs.append( "<div id='" + id + "'><p>" + tabContentHtml + "</p></div>" ); + tabs.tabs( "refresh" ); + tabCounter++; } // addTab button: just opens the dialog $( "#add_tab" ) .button() .click(function() { - $dialog.dialog( "open" ); + dialog.dialog( "open" ); }); // close icon: removing the tab on click - // note: closable tabs gonna be an option in the future - see http://dev.jqueryui.com/ticket/3924 $( "#tabs span.ui-icon-close" ).live( "click", function() { - var index = $( "li", $tabs ).index( $( this ).parent() ); - $tabs.tabs( "remove", index ); + $( this ).closest( "li" ).remove(); + $( "#" + $( this ).prev().attr( "aria-controls" ) ).remove(); + tabs.tabs( "refresh" ); }); }); </script> diff --git a/demos/tooltip/video-player.html b/demos/tooltip/video-player.html index 2e2419760..56003ab5a 100644 --- a/demos/tooltip/video-player.html +++ b/demos/tooltip/video-player.html @@ -10,29 +10,54 @@ <script type="text/javascript" src="../../ui/jquery.ui.tooltip.js"></script> <script type="text/javascript" src="../../ui/jquery.ui.button.js"></script> <script type="text/javascript" src="../../ui/jquery.ui.menu.js"></script> - <script type="text/javascript" src="../../tests/visual/menu/popup.js"></script> + <script type="text/javascript" src="../../ui/jquery.ui.popup.js"></script> + <script type="text/javascript" src="../../ui/jquery.effects.core.js"></script> + <script type="text/javascript" src="../../ui/jquery.effects.blind.js"></script> <link type="text/css" href="../demos.css" rel="stylesheet" /> <script type="text/javascript"> $(function() { + function notify( input ) { + var msg = "Selected " + $.trim($(input).text()); + $("<div/>").appendTo(document.body).text(msg).addClass("notification ui-state-default ui-corner-bottom").position({ + my: "center top", + at: "center top", + of: window + }).show({ + effect: "blind" + }).delay(1000).hide({ + effect: "blind", + duration: "slow" + }, function() { + $(this).remove(); + }); + } + $("ul").menu({ + select: function(event, ui) { + // TODO stop button from handling the click + $(this).popup("close"); + // TODO should probably be handled by poup, see ESCAPE key handler + // affects key handling + $(this).prev().focus(); + notify(ui.item); + } + }).popup(); + $("button").each(function() { $(this).button({ icons: { primary: $(this).data("icon") }, text: !!$(this).attr("title") + }).click(function() { + // TODO don't notify if the button is opening a popup + notify(this); }); }); - $(".set").buttonset(); - - $("ul").menu({ - select: function() { - // would also execute some other action here - $(this).popup("close"); - } - }).popup({ - trigger: $(".menu") + $(".set").buttonset({ + items: "button" }); + $(".demo").tooltip({ position: { my: "center top", @@ -57,6 +82,10 @@ background: rgba(20, 20, 20, 1); color: white; } + + .set { display: inline-block; } + + .notification { position: absolute; display: inline-block; font-size: 2em; padding: .5em; box-shadow: 2px 2px 5px -2px rgba(0,0,0,0.5); } </style> </head> <body> @@ -69,23 +98,23 @@ <button data-icon="ui-icon-circle-arrow-n" title="I like this">Like</button> <button data-icon="ui-icon-circle-arrow-s">I dislike this</button> </span> - <span class="set"> + <div class="set"> <button data-icon="ui-icon-circle-plus" title="Add to Watch Later">Add to</button> <button class="menu" data-icon="ui-icon-triangle-1-s">Add to favorites or playlist</button> - </span> + <ul> + <li> + <a href="#">Favorites</a> + </li> + <li> + <a href="#">Watch Later</a> + </li> + <li> + <a href="#">New Playlist...</a> + </li> + </ul> + </div> <button title="Share this video">Share</button> <button data-icon="ui-icon-alert">Flag as inappropiate</button> - <ul> - <li> - <a href="#">Favorites</a> - </li> - <li> - <a href="#">Watch Later</a> - </li> - <li> - <a href="#">New Playlist...</a> - </li> - </ul> </div> </div> diff --git a/tests/unit/autocomplete/autocomplete_events.js b/tests/unit/autocomplete/autocomplete_events.js index 35103d89b..c884733d6 100644 --- a/tests/unit/autocomplete/autocomplete_events.js +++ b/tests/unit/autocomplete/autocomplete_events.js @@ -203,4 +203,22 @@ test("cancel select", function() { }, 50); }); +/* TODO previous fix broke more than it fixed, disabling this for now - messed up regular menu select event +test("blur without selection", function() { + expect(1); + var ac = $("#autocomplete").autocomplete({ + delay: 0, + source: data + }); + stop(); + ac.val("j").keydown(); + setTimeout(function() { + $( ".ui-menu-item" ).first().simulate("mouseover"); + ac.simulate("keydown", { keyCode: $.ui.keyCode.TAB }); + same( ac.val(), "j" ); + start(); + }, 50); +}); +*/ + })(jQuery); diff --git a/tests/unit/tabs/spinner.gif b/tests/unit/tabs/spinner.gif Binary files differdeleted file mode 100644 index 822747576..000000000 --- a/tests/unit/tabs/spinner.gif +++ /dev/null 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 @@ <script src="tabs_events.js"></script> <script src="tabs_methods.js"></script> <script src="tabs_options.js"></script> - <script src="tabs_tickets.js"></script> <script> function tabs_state( tabs ) { diff --git a/tests/unit/tabs/tabs_core.js b/tests/unit/tabs/tabs_core.js index c9b16e3a8..98cb617ec 100644 --- a/tests/unit/tabs/tabs_core.js +++ b/tests/unit/tabs/tabs_core.js @@ -63,4 +63,32 @@ test( "accessibility", function() { // TODO: add tests }); +test( "#3627 - Ajax tab with url containing a fragment identifier fails to load", function() { + expect( 1 ); + + var element = $( "#tabs2" ).tabs({ + active: 2, + beforeLoad: function( event, ui ) { + event.preventDefault(); + ok( /test.html$/.test( ui.ajaxSettings.url ), "should ignore fragment identifier" ); + } + }); +}); + +test( "#4033 - IE expands hash to full url and misinterprets tab as ajax", function() { + expect( 2 ); + + var element = $( "<div><ul><li><a href='#tab'>Tab</a></li></ul><div id='tab'></div></div>" ); + element.appendTo( "#main" ); + element.tabs({ + beforeLoad: function( event, ui ) { + event.preventDefault(); + ok( false, 'should not be an ajax tab'); + } + }); + + equals( element.find( ".ui-tabs-nav a" ).attr( "aria-controls" ), "tab", "aria-contorls attribute is correct" ); + tabs_state( element, 1 ); +}); + }( jQuery ) ); diff --git a/tests/unit/tabs/tabs_deprecated.html b/tests/unit/tabs/tabs_deprecated.html index e71fea3d4..89d08f4d0 100644 --- a/tests/unit/tabs/tabs_deprecated.html +++ b/tests/unit/tabs/tabs_deprecated.html @@ -22,7 +22,6 @@ <script src="tabs_events.js"></script> <script src="tabs_methods.js"></script> <script src="tabs_options.js"></script> - <script src="tabs_tickets.js"></script> <script src="tabs_deprecated.js"></script> <script> diff --git a/tests/unit/tabs/tabs_deprecated.js b/tests/unit/tabs/tabs_deprecated.js index 90c43037c..4b50df405 100644 --- a/tests/unit/tabs/tabs_deprecated.js +++ b/tests/unit/tabs/tabs_deprecated.js @@ -1,6 +1,6 @@ (function( $ ) { -module("tabs (deprecated): core"); +module( "tabs (deprecated): core" ); test( "panel ids", function() { expect( 2 ); @@ -20,91 +20,149 @@ 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."); -}); +asyncTest( "ajaxOptions", function() { + expect( 1 ); -test('cache', function() { - ok(false, "missing test - untested code is broken code."); + 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('idPrefix', function() { - ok(false, "missing test - untested code is broken code."); -}); +asyncTest( "cache", function() { + expect( 5 ); -test('tabTemplate', function() { - ok(false, "missing test - untested code is broken code."); + 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('panelTemplate', 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('cookie', function() { - expect(6); +test( "tabTemplate + panelTemplate", function() { + // defaults are tested in the add method test + expect( 11 ); + + var element = $( "#tabs2" ).tabs({ + tabTemplate: "<li class='customTab'><a href='http://example.com/#{href}'>#{label}</a></li>", + panelTemplate: "<div class='customPanel'></div>" + }); + 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" ); +}); - el = $('#tabs1'); - var cookieName = 'tabs_test', cookieObj = { name: cookieName }; - $.cookie(cookieName, null); // blank state - var cookie = function() { - return parseInt($.cookie(cookieName), 10); - }; +test( "cookie", function() { + expect( 6 ); - el.tabs({ cookie: cookieObj }); - equals(cookie(), 0, 'initial cookie value'); + var element = $( "#tabs1" ), + cookieName = "tabs_test", + cookieObj = { name: cookieName }; + $.cookie( cookieName, null ); + function cookie() { + return parseInt( $.cookie( cookieName ), 10 ); + } - el.tabs('destroy'); - el.tabs({ active: 1, cookie: cookieObj }); - equals(cookie(), 1, 'initial cookie value, from active property'); + element.tabs({ cookie: cookieObj }); + equals( cookie(), 0, "initial cookie value" ); - el.tabs('option', 'active', 2); - equals(cookie(), 2, 'cookie value updated after activating'); + element.tabs( "destroy" ); + element.tabs({ active: 1, cookie: cookieObj }); + equals( cookie(), 1, "initial cookie value, from active property" ); - el.tabs('destroy'); - $.cookie(cookieName, 1); - el.tabs({ cookie: cookieObj }); - equals(cookie(), 1, 'initial cookie value, from existing cookie'); + element.tabs( "option", "active", 2 ); + equals( cookie(), 2, "cookie value updated after activating" ); - el.tabs('destroy'); - el.tabs({ cookie: cookieObj, collapsible: true }); - el.tabs('option', 'active', false); - equals(cookie(), -1, 'cookie value for all tabs unselected'); + element.tabs( "destroy" ); + $.cookie( cookieName, 1 ); + element.tabs({ cookie: cookieObj }); + equals( cookie(), 1, "initial cookie value, from existing cookie" ); - el.tabs('destroy'); - ok($.cookie(cookieName) === null, 'erase cookie after destroy'); + element.tabs( "destroy" ); + element.tabs({ cookie: cookieObj, collapsible: true }); + element.tabs( "option", "active", false ); + equals( cookie(), -1, "cookie value for all tabs unselected" ); + element.tabs( "destroy" ); + ok( $.cookie( cookieName ) === null, "erase cookie after destroy" ); }); +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: '<img src="spinner.gif" alt="">', - 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 ) { + // 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 ); }); test( "selected", function() { @@ -193,45 +251,85 @@ test( "disable", function() { element.tabs( "disable", 1 ); }); -test('show', function() { - expect(5); - var uiObj, eventObj; - el = $('#tabs1').tabs({ - show: function(event, ui) { - uiObj = ui; - eventObj = event; - } +test( "show", function() { + expect( 13 ); + + var element = $( "#tabs1" ).tabs({ + active: false, + collapsible: true + }), + tabs = element.find( ".ui-tabs-nav a" ), + panels = element.find( ".ui-tabs-panel" ); + + // from collapsed + element.one( "tabsshow", function( event, ui ) { + ok( !( "originalEvent" in event ), "originalEvent" ); + strictEqual( ui.tab, tabs[ 0 ], "ui.tab" ); + strictEqual( ui.panel, panels[ 0 ], "ui.panel" ); + equal( ui.index, 0, "ui.index" ); + tabs_state( element, 1, 0, 0 ); }); - ok(uiObj !== undefined, 'trigger callback after initialization'); - equals(uiObj.tab, $('a', el)[0], 'contain tab as DOM anchor element'); - equals(uiObj.panel, $('div', el)[0], 'contain panel as DOM div element'); - equals(uiObj.index, 0, 'contain index'); + element.tabs( "option", "active", 0 ); + tabs_state( element, 1, 0, 0 ); - el.find( "li:eq(1) a" ).simulate( "click" ); - equals( eventObj.originalEvent.type, "click", "show triggered by click" ); + // switching tabs + element.one( "tabsshow", function( event, ui ) { + equals( event.originalEvent.type, "click", "originalEvent" ); + strictEqual( ui.tab, tabs[ 1 ], "ui.tab" ); + strictEqual( ui.panel, panels[ 1 ], "ui.panel" ); + equal( ui.index, 1, "ui.index" ); + tabs_state( element, 0, 1, 0 ); + }); + tabs.eq( 1 ).click(); + tabs_state( element, 0, 1, 0 ); + // collapsing + element.one( "tabsshow", function( event, ui ) { + ok( false, "collapsing" ); + }); + element.tabs( "option", "active", false ); + tabs_state( element, 0, 0, 0 ); }); -test('select', function() { - expect(7); +test( "select", function() { + expect( 13 ); - var eventObj; - el = $('#tabs1').tabs({ - select: function(event, ui) { - ok(true, 'select triggered after initialization'); - equals(this, el[0], "context of callback"); - equals(event.type, 'tabsselect', 'event type in callback'); - equals(ui.tab, el.find('a')[1], 'contain tab as DOM anchor element'); - equals(ui.panel, el.find('div')[1], 'contain panel as DOM div element'); - equals(ui.index, 1, 'contain index'); - evenObj = event; - } + var element = $( "#tabs1" ).tabs({ + active: false, + collapsible: true + }), + tabs = element.find( ".ui-tabs-nav a" ), + panels = element.find( ".ui-tabs-panel" ); + + // from collapsed + element.one( "tabsselect", function( event, ui ) { + ok( !( "originalEvent" in event ), "originalEvent" ); + strictEqual( ui.tab, tabs[ 0 ], "ui.tab" ); + strictEqual( ui.panel, panels[ 0 ], "ui.panel" ); + equal( ui.index, 0, "ui.index" ); + tabs_state( element, 0, 0, 0 ); + }); + element.tabs( "option", "active", 0 ); + tabs_state( element, 1, 0, 0 ); + + // switching tabs + element.one( "tabsselect", function( event, ui ) { + equals( event.originalEvent.type, "click", "originalEvent" ); + strictEqual( ui.tab, tabs[ 1 ], "ui.tab" ); + strictEqual( ui.panel, panels[ 1 ], "ui.panel" ); + equal( ui.index, 1, "ui.index" ); + tabs_state( element, 1, 0, 0 ); }); - el.tabs('select', 1); + tabs.eq( 1 ).click(); + tabs_state( element, 0, 1, 0 ); - el.find( "li:eq(1) a" ).simulate( "click" ); - equals( evenObj.originalEvent.type, "click", "select triggered by click" ); + // collapsing + element.one( "tabsselect", function( event, ui ) { + ok( false, "collapsing" ); + }); + element.tabs( "option", "active", false ); + tabs_state( element, 0, 0, 0 ); }); module( "tabs (deprecated): methods" ); @@ -405,4 +503,18 @@ test( "url", function() { element.tabs( "option", "active", 3 ); }); +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 ) ); diff --git a/tests/unit/tabs/tabs_events.js b/tests/unit/tabs/tabs_events.js index 28925a2b9..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" ); + + // init + element.one( "tabsbeforeload", function( event, ui ) { + tab = element.find( ".ui-tabs-nav a" ).eq( 2 ); + panelId = tab.attr( "aria-controls" ); + panel = $( "#" + panelId ); - // TODO: init -// element.one( "tabsbeforeload", function( event, ui ) { -// }); -// element.tabs({ active: 2 }); + 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" ); @@ -191,8 +209,66 @@ test( "beforeLoad", function() { equals( panel.html(), "<p>testing</p>", "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 ) ); 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() { diff --git a/tests/unit/tabs/tabs_options.js b/tests/unit/tabs/tabs_options.js index 691186276..8d61c47ef 100644 --- a/tests/unit/tabs/tabs_options.js +++ b/tests/unit/tabs/tabs_options.js @@ -133,28 +133,81 @@ 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', 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('fx', function() { - ok(false, "missing test - untested code is broken code."); +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 ); }); -})(jQuery); +// TODO: add animation tests + +}( jQuery ) ); diff --git a/tests/unit/tabs/tabs_tickets.js b/tests/unit/tabs/tabs_tickets.js deleted file mode 100644 index d7a59cb5b..000000000 --- a/tests/unit/tabs/tabs_tickets.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * tabs_tickets.js - */ -(function($) { - -module("tabs: tickets"); - -test('#3627 - Ajax tab with url containing a fragment identifier fails to load', function() { - // http://dev.jqueryui.com/ticket/3627 - expect(1); - - el = $('#tabs2').tabs({ - active: 2, - beforeLoad: function( event, ui ) { - event.preventDefault(); - ok(/test.html$/.test( ui.ajaxSettings.url ), 'should ignore fragment identifier'); - } - }); -}); - -test('#4033 - IE expands hash to full url and misinterprets tab as ajax', function() { - // http://dev.jqueryui.com/ticket/4033 - expect(1); - - el = $('<div><ul><li><a href="#tab">Tab</a></li></ul><div id="tab"></div></div>'); - el.appendTo('#main'); - el.tabs({ - beforeLoad: function( event, ui ) { - event.preventDefault(); - ok( false, 'should not be an ajax tab'); - } - }); - - equals($('a', el).attr('aria-controls'), 'tab', 'aria-contorls attribute is correct'); -}); - -})(jQuery); diff --git a/tests/unit/widget/widget.html b/tests/unit/widget/widget.html index e74abb317..183537612 100644 --- a/tests/unit/widget/widget.html +++ b/tests/unit/widget/widget.html @@ -14,6 +14,7 @@ <script src="../testsuite.js"></script> <script src="widget_core.js"></script> + <script src="widget_extend.js"></script> <script src="../swarminject.js"></script> </head> diff --git a/tests/unit/widget/widget_extend.js b/tests/unit/widget/widget_extend.js new file mode 100644 index 000000000..fb78ecfb7 --- /dev/null +++ b/tests/unit/widget/widget_extend.js @@ -0,0 +1,104 @@ +test( "$.widget.extend()", function() { + expect( 26 ); + + var settings = { xnumber1: 5, xnumber2: 7, xstring1: "peter", xstring2: "pan" }, + options = { xnumber2: 1, xstring2: "x", xxx: "newstring" }, + optionsCopy = { xnumber2: 1, xstring2: "x", xxx: "newstring" }, + merged = { xnumber1: 5, xnumber2: 1, xstring1: "peter", xstring2: "x", xxx: "newstring" }, + deep1 = { foo: { bar: true } }, + deep1copy = { foo: { bar: true } }, + deep2 = { foo: { baz: true }, foo2: document }, + deep2copy = { foo: { baz: true }, foo2: document }, + deepmerged = { foo: { bar: true, baz: true }, foo2: document }, + arr = [1, 2, 3], + nestedarray = { arr: arr }, + ret; + + $.widget.extend( settings, options ); + deepEqual( settings, merged, "Check if extended: settings must be extended" ); + deepEqual( options, optionsCopy, "Check if not modified: options must not be modified" ); + + $.widget.extend( deep1, deep2 ); + deepEqual( deep1.foo, deepmerged.foo, "Check if foo: settings must be extended" ); + deepEqual( deep2.foo, deep2copy.foo, "Check if not deep2: options must not be modified" ); + equal( deep1.foo2, document, "Make sure that a deep clone was not attempted on the document" ); + + strictEqual( $.widget.extend({}, nestedarray).arr, arr, "Don't clone arrays" ); + ok( $.isPlainObject( $.widget.extend({ arr: arr }, { arr: {} }).arr ), "Cloned object heve to be an plain object" ); + + var empty = {}; + var optionsWithLength = { foo: { length: -1 } }; + $.widget.extend( empty, optionsWithLength ); + deepEqual( empty.foo, optionsWithLength.foo, "The length property must copy correctly" ); + + empty = {}; + var optionsWithDate = { foo: { date: new Date } }; + $.widget.extend( empty, optionsWithDate ); + deepEqual( empty.foo, optionsWithDate.foo, "Dates copy correctly" ); + + var myKlass = function() {}; + var customObject = new myKlass(); + var optionsWithCustomObject = { foo: { date: customObject } }; + empty = {}; + $.widget.extend( empty, optionsWithCustomObject ); + strictEqual( empty.foo.date, customObject, "Custom objects copy correctly (no methods)" ); + + // Makes the class a little more realistic + myKlass.prototype = { someMethod: function(){} }; + empty = {}; + $.widget.extend( empty, optionsWithCustomObject ); + strictEqual( empty.foo.date, customObject, "Custom objects copy correctly" ); + + ret = $.widget.extend({ foo: 4 }, { foo: new Number(5) } ); + equal( ret.foo, 5, "Wrapped numbers copy correctly" ); + + var nullUndef; + nullUndef = $.widget.extend( {}, options, { xnumber2: null } ); + strictEqual( nullUndef.xnumber2, null, "Check to make sure null values are copied"); + + nullUndef = $.widget.extend( {}, options, { xnumber2: undefined } ); + strictEqual( nullUndef.xnumber2, options.xnumber2, "Check to make sure undefined values are not copied"); + + nullUndef = $.widget.extend( {}, options, { xnumber0: null } ); + strictEqual( nullUndef.xnumber0, null, "Check to make sure null values are inserted"); + + var target = {}; + var recursive = { foo:target, bar:5 }; + $.widget.extend( target, recursive ); + deepEqual( target, { foo: {}, bar: 5 }, "Check to make sure a recursive obj doesn't go never-ending loop by not copying it over" ); + + ret = $.widget.extend( { foo: [] }, { foo: [0] } ); // 1907 + equal( ret.foo.length, 1, "Check to make sure a value with coersion 'false' copies over when necessary to fix #1907" ); + + ret = $.widget.extend( { foo: "1,2,3" }, { foo: [1, 2, 3] } ); + strictEqual( typeof ret.foo, "object", "Check to make sure values equal with coersion (but not actually equal) overwrite correctly" ); + + ret = $.widget.extend( { foo:"bar" }, { foo:null } ); + strictEqual( typeof ret.foo, "object", "Make sure a null value doesn't crash with deep extend, for #1908" ); + + var obj = { foo:null }; + $.widget.extend( obj, { foo:"notnull" } ); + equal( obj.foo, "notnull", "Make sure a null value can be overwritten" ); + + var defaults = { xnumber1: 5, xnumber2: 7, xstring1: "peter", xstring2: "pan" }, + defaultsCopy = { xnumber1: 5, xnumber2: 7, xstring1: "peter", xstring2: "pan" }, + options1 = { xnumber2: 1, xstring2: "x" }, + options1Copy = { xnumber2: 1, xstring2: "x" }, + options2 = { xstring2: "xx", xxx: "newstringx" }, + options2Copy = { xstring2: "xx", xxx: "newstringx" }, + merged2 = { xnumber1: 5, xnumber2: 1, xstring1: "peter", xstring2: "xx", xxx: "newstringx" }; + + var settings = $.widget.extend( {}, defaults, options1, options2 ); + deepEqual( settings, merged2, "Check if extended: settings must be extended" ); + deepEqual( defaults, defaultsCopy, "Check if not modified: options1 must not be modified" ); + deepEqual( options1, options1Copy, "Check if not modified: options1 must not be modified" ); + deepEqual( options2, options2Copy, "Check if not modified: options2 must not be modified" ); + + var input = { + key: [ 1, 2, 3 ] + } + var output = $.widget.extend( {}, input ); + deepEqual( input, output, "don't clone arrays" ); + input.key[0] = 10; + deepEqual( input, output, "don't clone arrays" ); +}); diff --git a/tests/visual/effects.all.html b/tests/visual/effects.all.html index 1fc35f700..fed35de8a 100644 --- a/tests/visual/effects.all.html +++ b/tests/visual/effects.all.html @@ -146,6 +146,18 @@ </li> <li> + <div class="effect" id="size"> + <p>Size Default Show/Hide</p> + </div> + </li> + + <li> + <div class="effect" id="sizeToggle"> + <p>Size Toggle</p> + </div> + </li> + + <li> <div class="effect" id="slideDown"> <p>Slide down</p> </div> diff --git a/tests/visual/effects.all.js b/tests/visual/effects.all.js index 3ac8968b3..a28c41a89 100644 --- a/tests/visual/effects.all.js +++ b/tests/visual/effects.all.js @@ -14,12 +14,14 @@ $(function() { $(el).bind("click", function() { - $(this).addClass("current").hide(n, o, duration, function() { - var self = this; - window.setTimeout(function() { - $(self).show(n, o, duration, function() { $(this).removeClass("current"); }); - }, wait); - }); + $(this).addClass("current") + // delaying the initial animation makes sure that the queue stays in tact + .delay( 10 ) + .hide( n, o, duration ) + .delay( wait ) + .show( n, o, duration, function() { + $( this ).removeClass("current"); + }); }); }; @@ -28,10 +30,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,6 +63,16 @@ $(function() { effect("#puff", "puff", { times: 2 }); effect("#scale", "scale", {}); + 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"); }); }); @@ -82,13 +94,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); }); }); 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 @@ -<!doctype html> -<html> -<head> - <title>Menu Visual Test: Default</title> - <link rel="stylesheet" href="../visual.css" type="text/css" /> - <link rel="stylesheet" href="../../../themes/base/jquery.ui.all.css" type="text/css" title="ui-theme" /> - <script type="text/javascript" src="../../../jquery-1.5.1.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.core.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.menu.js"></script> - <!-- - <script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script> - --> - <script type="text/javascript"> - $(function() { - $.fn.themeswitcher && $('<div/>').css({ - position: "absolute", - right: 10, - top: 10 - }).appendTo(document.body).themeswitcher(); - - // TODO close other menus when opening a new one - $("button").each(function() { - $(this).next().menu({ - /* top-alignment - position: function(item) { - return { - my: "left top", - at: "right top", - of: item.parent() - } - }, - */ - select: function(event, ui) { - $(this).hide().prev().focus(); - $("#log").append("<div>Selected " + ui.item.text() + "</div>"); - } - }).hide(); - - // equal height - //menu.find("ul").height(menu.height()); - }).click(function(event) { - // required to prevent the click handler below from handling this event - event.stopPropagation(); - var menu = $("#menu" + this.id).menu("blur").show().position({ - my: "left top", - at: "right top", - of: event.pageX > 0 ? event : this - }).focus(); - $(document).one("click", function() { - menu.menu("closeAll").menu("widget").hide(); - }) - }).next().keydown(function(event) { - var menu = $(this).data("menu"); - if (menu.widget().is(":hidden")) - return; - event.stopPropagation(); - switch (event.keyCode) { - case $.ui.keyCode.TAB: - menu.closeAll(); - menu.widget().hide(); - $(this).prev().focus() - break; - case $.ui.keyCode.ESCAPE: - menu.closeAll(); - menu.widget().hide(); - $(this).prev().focus() - break; - default: - - } - }); - }); - </script> - <style> - body { font-size:62.5%; } - .ui-menu { width: 200px; position: absolute; } - #menu3 { height: 200px; overflow: auto; } - </style> -</head> -<body> - -<button id="1">Show context menu 1</button> -<ul id="menu1"> - <li><a href="#">Amsterdam</a></li> - <li><a href="#">Anaheim</a></li> - <li><a href="#">Cologne</a></li> - <li><a href="#">Frankfurt</a></li> - <li><a href="#">Magdeburg</a></li> - <li><a href="#">Munich</a></li> - <li><a href="#">Utrecht</a></li> - <li><a href="#">Zurich</a></li> -</ul> - -<button id="2">Show context menu 2</button> -<ul id="menu2"> - <li> - <a id="a1" href="#">Amsterdam</a> - <ul> - <li><a id="b1" href="#">Aberdeen</a></li> - <li><a id="b2" href="#">Ada</a></li> - <li> - <a href="#">Adamsville</a> - <ul> - <li><a href="#">Anaheim</a></li> - <li> - <a href="#">Cologne</a> - <ul> - <li><a href="#">Mberdeen</a></li> - <li><a href="#">Mda</a></li> - <li><a href="#">Mdamsville</a></li> - <li><a href="#">Mddyston</a></li> - <li><a href="#">Mmesville</a></li> - </ul> - </li> - <li><a href="#">Frankfurt</a></li> - </ul> - </li> - <li><a href="#">Addyston</a></li> - <li><a href="#">Amesville</a></li> - </ul> - </li> - <li><a id="a2" href="#">Anaheim</a></li> - <li><a id="a3" href="#">Cologne</a></li> - <li><a href="#">Frankfurt</a></li> - <li> - <a href="#">Magdeburg</a> - <ul> - <li><a href="#">Mberdeen</a></li> - <li><a href="#">Mda</a></li> - <li><a href="#">Mdamsville</a></li> - <li><a href="#">Mddyston</a></li> - <li><a href="#">Mmesville</a></li> - </ul> - </li> - <li><a href="#">Munich</a></li> - <li><a href="#">Utrecht</a></li> - <li><a href="#">Zurich</a></li> -</ul> - - -<div class="ui-widget" style="margin-top:2em; font-family:Arial"> - Log: - <div id="log" style="height: 400px; width: 300px; overflow: auto;" class="ui-widget-content"></div> -</div> - -<button id="3">Show context menu 3</button> -<ul id="menu3"> - <li><a href="#">Aberdeen</a></li> - <li><a href="#">Ada</a></li> - <li><a href="#">Adamsville</a></li> - <li><a href="#">Addyston</a></li> - <li><a href="#">Adelphi</a></li> - <li><a href="#">Adena</a></li> - <li><a href="#">Adrian</a></li> - <li><a href="#">Akron</a></li> - <li><a href="#">Albany</a></li> - <li><a href="#">Alexandria</a></li> - <li><a href="#">Alger</a></li> - <li><a href="#">Alledonia</a></li> - <li><a href="#">Alliance</a></li> - <li><a href="#">Alpha</a></li> - <li><a href="#">Alvada</a></li> - <li><a href="#">Alvordton</a></li> - <li><a href="#">Amanda</a></li> - <li><a href="#">Amelia</a></li> - <li><a href="#">Amesville</a></li> - <li><a href="#">Aberdeen</a></li> - <li><a href="#">Ada</a></li> - <li><a href="#">Adamsville</a></li> - <li><a href="#">Addyston</a></li> - <li><a href="#">Adelphi</a></li> - <li><a href="#">Adena</a></li> - <li><a href="#">Adrian</a></li> - <li><a href="#">Akron</a></li> - <li><a href="#">Albany</a></li> - <li><a href="#">Alexandria</a></li> - <li><a href="#">Alger</a></li> - <li><a href="#">Alledonia</a></li> - <li><a href="#">Alliance</a></li> - <li><a href="#">Alpha</a></li> - <li><a href="#">Alvada</a></li> - <li><a href="#">Alvordton</a></li> - <li><a href="#">Amanda</a></li> - <li><a href="#">Amelia</a></li> - <li><a href="#">Amesville</a></li> -</ul> - -</body> -</html> diff --git a/tests/visual/menu/popup.html b/tests/visual/menu/popup.html deleted file mode 100644 index 2a712b00a..000000000 --- a/tests/visual/menu/popup.html +++ /dev/null @@ -1,176 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <title>Visual Test for Popup Utility</title> - <link rel="stylesheet" href="../visual.css" type="text/css" /> - <link rel="stylesheet" href="../../../themes/base/jquery.ui.all.css" type="text/css" title="ui-theme" /> - <script type="text/javascript" src="../../../jquery-1.5.1.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.core.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.button.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.menu.js"></script> - <script type="text/javascript" src="popup.js"></script> - <!-- - <script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script> - --> - <script type="text/javascript"> - $(function() { - $.fn.themeswitcher && $('<div/>').css({ - position: "absolute", - right: 10, - top: 10 - }).appendTo(document.body).themeswitcher(); - - var selected = { - select: function( event, ui ) { - $( "<div/>" ).text( "Selected: " + ui.item.text() ).appendTo( "#log" ); - $(this).popup("close"); - } - }; - - $("#members-popup").popup(); - - $("#button1").button(); - $("#menu1").menu(selected).popup(); - - $( "#rerun" ) - .button() - .click(function() { - alert( "Running the last action" ); - }) - .next() - .button({ - text: false, - icons: { - primary: "ui-icon-triangle-1-s" - } - }) - .parent() - .buttonset() - .next() - .menu(selected) - .popup({ - trigger: $("#select") - }); - - $("td:has(.menubar)").clone().appendTo("tbody tr:not(:first)"); - $("table .menubar > ul").menu(selected).popup().prev().button(); - }); - </script> - <style type="text/css"> - body { font-size:62.5%; } - - .ui-popup { position: absolute; z-index: 5000; } - .ui-menu { width: 200px; } - - table { - border-collapse: collapse; - } - th, td { - padding: 0.5em; - border: 1px solid black; - } - - #members-popup { - 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; outline: none; - } - </style> -</head> -<body> - -<div> - <a href="#members-popup">Project members</a> - <div id="members-popup" tabIndex="0"> - some form controls in here - </div> -</div> - -<button id="button1">Show context menu 1</button> -<ul id="menu1"> - <li><a href="#">Amsterdam</a></li> - <li><a href="#">Anaheim</a></li> - <li><a href="#">Cologne</a></li> - <li><a href="#">Frankfurt</a></li> - <li><a href="#">Magdeburg</a></li> - <li><a href="#">Munich</a></li> - <li><a href="#">Utrecht</a></li> - <li><a href="#">Zurich</a></li> -</ul> - - -<div> - <div> - <button id="rerun">Run last action</button> - <button id="select">Select an action</button> - </div> - <ul> - <li><a href="#">Open...</a></li> - <li><a href="#">Save</a></li> - <li><a href="#">Delete</a></li> - </ul> -</div> - -<table id="movies" class="ui-widget"> - <thead> - <tr> - <th data-field="Name" class="ui-widget-header">Name</th> - <th data-field="ReleaseYear" class="ui-widget-header">Release Year</th> - <th data-field="AverageRating" class="ui-widget-header">Average Rating</th> - <th class="ui-widget-header"></th> - </tr> - </thead> - <tbody> - <tr> - <td class="ui-widget-content">Red Hot Chili Peppers: Funky Monks</td> - <td class="ui-widget-content">1993</td> - <td class="ui-widget-content">3.6</td> - <td class="ui-widget-content"> - <div class="menubar"> - <a href="#">Options</a> - <ul> - <li><a href="#">Order...</a></li> - <li class="ui-state-disabled">Write a Review...</li> - <li><a href="#">Find Similar Movies...</a></li> - <li> - <a href="#">Rate</a> - <ul> - <li><a href="#">5 stars</a></li> - <li><a href="#">4 stars</a></li> - <li><a href="#">3 stars</a></li> - <li><a href="#">2 stars</a></li> - <li><a href="#">1 stars</a></li> - </ul> - </li> - </ul> - </div> - </td> - </tr> - <tr> - <td class="ui-widget-content">Rod Stewart: Storyteller 1984-1991</td> - <td class="ui-widget-content">1991</td> - <td class="ui-widget-content">3.1</td> - </tr> - <tr> - <td class="ui-widget-content">Stevie Ray Vaughan and Double Trouble: Live at the El Mocambo 1983</td> - <td class="ui-widget-content">1991</td> - <td class="ui-widget-content">3.9</td> - </tr> - <tr> - <td class="ui-widget-content">Spike and Mike's Sick & Twisted Festival of Animation</td> - <td class="ui-widget-content">1997</td> - <td class="ui-widget-content">2.6</td> - </tr> - </tbody> -</table> - -<div class="ui-widget" style="margin-top:2em; font-family:Arial"> - Log: - <div id="log" style="height: 400px; width: 300px; overflow: auto;" class="ui-widget-content"></div> -</div> - -</body> -</html> diff --git a/ui/jquery.effects.bounce.js b/ui/jquery.effects.bounce.js index 8da0feb76..bb386a4f4 100644 --- a/ui/jquery.effects.bounce.js +++ b/ui/jquery.effects.bounce.js @@ -12,89 +12,107 @@ */ (function( $, undefined ) { -var rshowhide = /show|hide/; - $.effects.effect.bounce = function(o) { - return this.queue(function() { - - // Create element + return this.queue( function( next ) { var el = $( this ), - props = [ 'position', 'top', 'bottom', 'left', 'right' ], + props = [ "position", "top", "bottom", "left", "right" ], + // defaults: - mode = $.effects.setMode( el, o.mode || 'effect' ), - direction = o.direction || 'up', - distance = o.distance || 20, - times = o.times || 5, - speed = (o.duration || 250), + mode = $.effects.setMode( el, o.mode || "effect" ), + hide = mode === "hide", + show = mode === "show", + direction = o.direction || "up", + distance = o.distance, + times = o.times || 5, + + // number of internal animations + anims = times * 2 + ( show || hide ? 1 : 0 ), + speed = o.duration / anims, + easing = o.easing, + // utility: - ref = ( direction == 'up' || direction == 'down' ) ? 'top' : 'left', - motion = ( direction == 'up' || direction == 'left' ), // true is positive - i, animation, animation1, animation2; - + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + motion = ( direction === "up" || direction === "left" ), + i, + upAnim, + downAnim, + + // we will need to re-assemble the queue to stack our animations in place + queue = el.queue(), + queuelen = queue.length; + // Avoid touching opacity to prevent clearType and PNG issues in IE - if ( rshowhide.test( mode ) ) { - props.push( 'opacity' ); + if ( show || hide ) { + props.push( "opacity" ); } $.effects.save( el, props ); el.show(); $.effects.createWrapper( el ); // Create Wrapper + // default distance for the BIGGEST bounce is the outer Distance / 3 if ( !distance ) { - distance = el[ ref == 'top' ? 'outerHeight' : 'outerWidth' ]({ margin:true }) / 3; + distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; } - if ( mode == 'show' ) el.css( 'opacity', 0 ).css( ref, motion ? -distance : distance ); // Shift - if ( mode == 'hide' ) distance = distance / (times * 2); - if ( mode != 'hide' ) times--; - - // Animate - if ( mode == 'show' ) { - animation = { - opacity: 1 - }; - animation[ ref ] = ( motion ? '+=' : '-=' ) + distance; - el.animate( animation, speed / 2, o.easing); - distance = distance / 2; - times--; - }; - - // Bounces - for (i = 0; i < times; i++) { - animation1 = {}; - animation2 = {}; - animation1[ ref ] = ( motion ? '-=' : '+=' ) + distance; - animation2[ ref ] = ( motion ? '+=' : '-=' ) + distance; - el.animate( animation1, speed / 2, o.easing ).animate( animation2, speed / 2, o.easing ); - distance = ( mode == 'hide' ) ? distance * 2 : distance / 2; + + if ( show ) { + downAnim = { opacity: 1 }; + downAnim[ ref ] = 0; + + // if we are showing, force opacity 0 and set the initial position + // then do the "first" animation + el.css( "opacity", 0 ) + .css( ref, motion ? -distance*2 : distance*2 ) + .animate( downAnim, speed, easing ); + } + + // start at the smallest distance if we are hiding + if ( hide ) { + distance = distance / Math.pow( 2, times - 1 ); } - // Last Bounce - if ( mode == 'hide' ) { - animation = { - opacity: 0 - }; - animation[ ref ] = ( motion ? '-=' : '+=' ) + distance; - el.animate( animation, speed / 2, o.easing, function(){ + downAnim = {}; + downAnim[ ref ] = 0; + // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here + for ( i = 0; i < times; i++ ) { + upAnim = {}; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + + // add the finish callback to the last animation if we aren't hiding + el.animate( upAnim, speed, easing ) + .animate( downAnim, speed, easing, + ( ( i === times - 1 ) && !hide ) ? finish : undefined ); + + distance = hide ? distance * 2 : distance / 2; + } + + // Last Bounce when Hiding + if ( hide ) { + upAnim = { opacity: 0 }; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + + el.animate( upAnim, speed, easing, function(){ el.hide(); - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - $.isFunction( o.complete ) && o.complete.apply( this, arguments ); + finish(); }); - } else { - animation1 = {}; - animation2 = {}; - animation1[ ref ] = ( motion ? '-=' : '+=' ) + distance; - animation2[ ref ] = ( motion ? '+=' : '-=' ) + distance; - el - .animate( animation1, speed / 2, o.easing ) - .animate( animation2, speed / 2, o.easing, function() { - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - $.isFunction( o.complete ) && o.complete.apply( this, arguments ); - }); } - el.dequeue(); + + function finish() { + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + if ( o.complete ) { + o.complete.apply( el[ 0 ] ); + } + } + + // inject all the animations we just queued to be first in line (after "inprogress") + if ( queuelen > 1) { + queue.splice.apply( queue, + [ 1, 0 ].concat( queue.splice( queuelen, anims ) ) ); + } + next(); + }); }; diff --git a/ui/jquery.effects.pulsate.js b/ui/jquery.effects.pulsate.js index b168b6ef5..3325c251f 100644 --- a/ui/jquery.effects.pulsate.js +++ b/ui/jquery.effects.pulsate.js @@ -13,39 +13,50 @@ (function( $, undefined ) { $.effects.effect.pulsate = function( o ) { - return this.queue( function() { + return this.queue( function( next ) { var elem = $( this ), - mode = $.effects.setMode( elem, o.mode || 'show' ), - times = ( ( o.times || 5 ) * 2 ) - 1, - duration = o.duration / 2, - isVisible = elem.is( ':visible' ), + mode = $.effects.setMode( elem, o.mode || "effect" ), + show = mode === "show" || elem.is( ":hidden" ), + showhide = ( show || mode === "hide" ), + + // showing or hiding adds an extra "half" animation + anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), + duration = o.duration / anims, animateTo = 0, + queue = elem.queue(), + queuelen = queue.length, i; - if ( !isVisible ) { - elem.css('opacity', 0).show(); + if ( show ) { + elem.css( "opacity", 0 ).show(); animateTo = 1; } - if ( ( mode == 'hide' && isVisible ) || ( mode == 'show' && !isVisible ) ) { - times--; - } - - for ( i = 0; i < times; i++ ) { - elem.animate({ - opacity: animateTo + // anims - 1 opacity "toggles" + for ( i = 1; i < anims; i++ ) { + elem.animate({ + opacity: animateTo }, duration, o.easing ); - animateTo = ( animateTo + 1 ) % 2; + animateTo = 1 - animateTo; } - elem.animate({ - opacity: animateTo + elem.animate({ + opacity: animateTo }, duration, o.easing, function() { - if (animateTo == 0) { + if ( animateTo === 0 ) { elem.hide(); } - (o.complete && o.complete.apply(this, arguments)); - }).dequeue(); + if ( o.complete ) { + o.complete.apply( this ); + } + }); + + // We just queued up "anims" animations, we need to put them next in the queue + if ( queuelen > 1) { + queue.splice.apply( queue, + [ 1, 0 ].concat( queue.splice( queuelen, anims ) ) ); + } + next(); }); }; diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js index 526eb3869..0e62ccfdb 100644 --- a/ui/jquery.ui.autocomplete.js +++ b/ui/jquery.ui.autocomplete.js @@ -62,6 +62,7 @@ $.widget( "ui.autocomplete", { }) .bind( "keydown.autocomplete", function( event ) { if ( self.options.disabled || self.element.attr( "readonly" ) ) { + suppressKeyPress = true; return; } @@ -69,17 +70,21 @@ $.widget( "ui.autocomplete", { var keyCode = $.ui.keyCode; switch( event.keyCode ) { case keyCode.PAGE_UP: + suppressKeyPress = true; self._move( "previousPage", event ); break; case keyCode.PAGE_DOWN: + suppressKeyPress = true; self._move( "nextPage", event ); break; case keyCode.UP: + suppressKeyPress = true; self._move( "previous", event ); // prevent moving cursor to beginning of text field in some browsers event.preventDefault(); break; case keyCode.DOWN: + suppressKeyPress = true; self._move( "next", event ); // prevent moving cursor to end of text field in some browsers event.preventDefault(); @@ -121,7 +126,29 @@ $.widget( "ui.autocomplete", { if ( suppressKeyPress ) { suppressKeyPress = false; event.preventDefault(); + return; } + + // replicate some key handlers to allow them to repeat in Firefox and Opera + var keyCode = $.ui.keyCode; + switch( event.keyCode ) { + case keyCode.PAGE_UP: + self._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + self._move( "nextPage", event ); + break; + case keyCode.UP: + self._move( "previous", event ); + // prevent moving cursor to beginning of text field in some browsers + event.preventDefault(); + break; + case keyCode.DOWN: + self._move( "next", event ); + // prevent moving cursor to end of text field in some browsers + event.preventDefault(); + break; + } }) .bind( "focus.autocomplete", function() { if ( self.options.disabled ) { diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 98baf65ab..e9955ce79 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -459,7 +459,8 @@ $.extend(Datepicker.prototype, { inst.settings.maxDate = this._formatDate(inst, maxDate); this._attachments($(target), inst); this._autoSize(inst); - this._setDateDatepicker(target, date); + this._setDate(inst, date); + this._updateAlternate(inst); this._updateDatepicker(inst); } }, @@ -652,7 +653,6 @@ $.extend(Datepicker.prototype, { var showAnim = $.datepicker._get(inst, 'showAnim'); var duration = $.datepicker._get(inst, 'duration'); var postProcess = function() { - $.datepicker._datepickerShowing = true; var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only if( !! cover.length ){ var borders = $.datepicker._getBorders(inst.dpDiv); @@ -661,6 +661,7 @@ $.extend(Datepicker.prototype, { } }; inst.dpDiv.zIndex($(input).zIndex()+1); + $.datepicker._datepickerShowing = true; // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) @@ -1493,7 +1494,7 @@ $.extend(Datepicker.prototype, { if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth) inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; - var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate + var numRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows calender += '<tr>'; diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js index 8423d1164..2138a9a58 100644 --- a/ui/jquery.ui.dialog.js +++ b/ui/jquery.ui.dialog.js @@ -281,7 +281,7 @@ $.widget("ui.dialog", { options = self.options, uiDialog = self.uiDialog; - self.overlay = options.modal ? new $.ui.dialog.overlay( self ) : null; + self.overlay = options.modal ? new $.ui.dialog.overlay( self ) : null; self._size(); self._position( options.position ); uiDialog.show( options.show ); diff --git a/ui/jquery.ui.draggable.js b/ui/jquery.ui.draggable.js index 774ea4380..d7bc09578 100644 --- a/ui/jquery.ui.draggable.js +++ b/ui/jquery.ui.draggable.js @@ -261,7 +261,7 @@ $.widget("ui.draggable", $.ui.mouse, { _createHelper: function(event) { var o = this.options; - var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element); + var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element); if(!helper.parents('body').length) helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); @@ -580,7 +580,7 @@ $.ui.plugin.add("draggable", "connectToSortable", { //Now we fake the start of dragging for the sortable instance, //by cloning the list group item, appending it to the sortable and using it as inst.currentItem //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) - this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true); + this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true); this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it this.instance.options.helper = function() { return ui.helper[0]; }; diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 0841018af..41b2e7a1a 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -45,8 +45,6 @@ $.widget("ui.menu", { if ( !item.length ) { return; } - // temporary - event.preventDefault(); // it's possible to click an item without hovering it (#7085) if ( !self.active || ( self.active[ 0 ] !== item[ 0 ] ) ) { self.focus( event, item ); @@ -235,15 +233,15 @@ $.widget("ui.menu", { if ( this._hasScroll() ) { var borderTop = parseFloat( $.curCSS( this.element[0], "borderTopWidth", true) ) || 0, - paddingtop = parseFloat( $.curCSS( this.element[0], "paddingTop", true) ) || 0, - offset = item.offset().top - this.element.offset().top - borderTop - paddingtop, - scroll = this.element.attr( "scrollTop" ), + paddingTop = parseFloat( $.curCSS( this.element[0], "paddingTop", true) ) || 0, + offset = item.offset().top - this.element.offset().top - borderTop - paddingTop, + scroll = this.element.scrollTop(), elementHeight = this.element.height(), itemHeight = item.height(); if ( offset < 0 ) { - this.element.attr( "scrollTop", scroll + offset ); + this.element.scrollTop( scroll + offset ); } else if ( offset + itemHeight > elementHeight ) { - this.element.attr( "scrollTop", scroll + offset - elementHeight + itemHeight ); + this.element.scrollTop( scroll + offset - elementHeight + itemHeight ); } } @@ -408,7 +406,8 @@ $.widget("ui.menu", { }, _hasScroll: function() { - return this.element.height() < this.element.attr( "scrollHeight" ); + // TODO: just use .prop() when we drop support for jQuery <1.6 + return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]( "scrollHeight" ); }, select: function( event ) { diff --git a/tests/visual/menu/menubar.js b/ui/jquery.ui.menubar.js index b9abacb9b..2879d079c 100644 --- a/tests/visual/menu/menubar.js +++ b/ui/jquery.ui.menubar.js @@ -1,7 +1,17 @@ /* - * jQuery UI menubar - * - * TODO move to jquery.ui.menubar.js + * 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( $ ) { diff --git a/ui/jquery.ui.mouse.js b/ui/jquery.ui.mouse.js index bfe4a7578..0bd38db85 100644 --- a/ui/jquery.ui.mouse.js +++ b/ui/jquery.ui.mouse.js @@ -12,6 +12,11 @@ */ (function( $, undefined ) { +var mouseHandled = false; +$(document).mousedown(function(e) { + mouseHandled = false; +}); + $.widget("ui.mouse", { options: { cancel: ':input,option', @@ -44,9 +49,7 @@ $.widget("ui.mouse", { _mouseDown: function(event) { // don't let more than one widget handle mouseStart - // TODO: figure out why we have to use originalEvent - event.originalEvent = event.originalEvent || {}; - if (event.originalEvent.mouseHandled) { return; } + if(mouseHandled) {return}; // we may have missed mouseup (out of window) (this._mouseStarted && this._mouseUp(event)); @@ -92,7 +95,8 @@ $.widget("ui.mouse", { .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); event.preventDefault(); - event.originalEvent.mouseHandled = true; + + mouseHandled = true; return true; }, diff --git a/tests/visual/menu/popup.js b/ui/jquery.ui.popup.js index 08088c994..10361a35c 100644 --- a/tests/visual/menu/popup.js +++ b/ui/jquery.ui.popup.js @@ -1,5 +1,16 @@ /* - * jQuery UI popup utility + * 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($) { @@ -38,10 +49,21 @@ $.widget( "ui.popup", { this._bind(this.options.trigger, { keydown: function( event ) { - // prevent space-to-open to scroll the page - if (event.keyCode == $.ui.keyCode.SPACE) { + // 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 ) { + // prevent scrolling + event.preventDefault(); + this.options.trigger.trigger( "click", event ); + } }, click: function( event ) { event.preventDefault(); @@ -50,6 +72,7 @@ $.widget( "ui.popup", { return; } var that = this; + clearTimeout( this.closeTimer ); setTimeout(function() { that.open( event ); }, 1); @@ -57,17 +80,25 @@ $.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" + // 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(); } } @@ -111,8 +142,13 @@ $.widget( "ui.popup", { .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); diff --git a/ui/jquery.ui.resizable.js b/ui/jquery.ui.resizable.js index 1e1706a9d..e0579ef84 100644 --- a/ui/jquery.ui.resizable.js +++ b/ui/jquery.ui.resizable.js @@ -176,10 +176,12 @@ $.widget("ui.resizable", $.ui.mouse, { $(this.element) .addClass("ui-resizable-autohide") .hover(function() { + if (o.disabled) return; $(this).removeClass("ui-resizable-autohide"); self._handles.show(); }, function(){ + if (o.disabled) return; if (!self.resizing) { $(this).addClass("ui-resizable-autohide"); self._handles.hide(); diff --git a/ui/jquery.ui.slider.js b/ui/jquery.ui.slider.js index eb6545f62..f0b01d7c0 100644 --- a/ui/jquery.ui.slider.js +++ b/ui/jquery.ui.slider.js @@ -36,7 +36,11 @@ $.widget( "ui.slider", $.ui.mouse, { _create: function() { var self = this, - o = this.options; + o = this.options, + existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), + handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", + handleCount = ( o.values && o.values.length ) || 1, + handles = []; this._keySliding = false; this._mouseSliding = false; @@ -50,57 +54,35 @@ $.widget( "ui.slider", $.ui.mouse, { " ui-slider-" + this.orientation + " ui-widget" + " ui-widget-content" + - " ui-corner-all" ); - - if ( o.disabled ) { - this.element.addClass( "ui-slider-disabled ui-disabled" ); - } + " ui-corner-all" + + ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) ); this.range = $([]); if ( o.range ) { if ( o.range === true ) { - this.range = $( "<div></div>" ); if ( !o.values ) { o.values = [ this._valueMin(), this._valueMin() ]; } if ( o.values.length && o.values.length !== 2 ) { o.values = [ o.values[0], o.values[0] ]; } - } else { - this.range = $( "<div></div>" ); - } - - this.range - .appendTo( this.element ) - .addClass( "ui-slider-range" ); - - if ( o.range === "min" || o.range === "max" ) { - this.range.addClass( "ui-slider-range-" + o.range ); } - // note: this isn't the most fittingly semantic framework class for this element, - // but worked best visually with a variety of themes - this.range.addClass( "ui-widget-header" ); - } - - if ( $( ".ui-slider-handle", this.element ).length === 0 ) { - $( "<a href='#'></a>" ) + this.range = $( "<div></div>" ) .appendTo( this.element ) - .addClass( "ui-slider-handle" ); + .addClass( "ui-slider-range" + + // note: this isn't the most fittingly semantic framework class for this element, + // but worked best visually with a variety of themes + " ui-widget-header" + + ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) ); } - if ( o.values && o.values.length ) { - while ( $(".ui-slider-handle", this.element).length < o.values.length ) { - $( "<a href='#'></a>" ) - .appendTo( this.element ) - .addClass( "ui-slider-handle" ); - } + for ( var i = existingHandles.length; i < handleCount; i += 1 ) { + handles.push( handle ); } - this.handles = $( ".ui-slider-handle", this.element ) - .addClass( "ui-state-default" + - " ui-corner-all" ); + this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( self.element ) ); this.handle = this.handles.eq( 0 ); diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index 58c181670..76f4fb274 100755..100644 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -13,17 +13,11 @@ */ (function( $, undefined ) { -var tabId = 0, - listId = 0; - +var tabId = 0 function getNextTabId() { return ++tabId; } -function getNextListId() { - return ++listId; -} - $.widget( "ui.tabs", { options: { active: null, @@ -108,15 +102,7 @@ $.widget( "ui.tabs", { var panel = that._getPanelForTab( this.active ); panel.show(); - this.lis.eq( options.active ).addClass( "ui-tabs-active ui-state-active" ); - - // TODO: we need to remove this or add it to accordion - // seems to be expected behavior that the activate callback is fired - that.element.queue( "tabs", function() { - that._trigger( "activate", null, that._ui( that.active[ 0 ], panel[ 0 ] ) ); - }); - this.load( options.active ); } else { this.active = $(); @@ -161,14 +147,6 @@ $.widget( "ui.tabs", { return hash ? hash.replace( /:/g, "\\:" ) : ""; }, - _ui: function( tab, panel ) { - return { - tab: tab, - panel: panel, - index: this.anchors.index( tab ) - }; - }, - refresh: function() { var self = this, options = this.options, @@ -417,52 +395,26 @@ $.widget( "ui.tabs", { that.xhr.abort(); } - // if tab may be closed - if ( options.collapsible ) { - if ( collapsing ) { - options.active = false; - - that.element.queue( "tabs", function() { - that._hideTab( event, eventData ); - }).dequeue( "tabs" ); - - clicked[ 0 ].blur(); - return; - } else if ( !toHide.length ) { - that.element.queue( "tabs", function() { - that._showTab( event, eventData ); - }); - - // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 - that.load( that.anchors.index( clicked ), event ); - - clicked[ 0 ].blur(); - return; - } + if ( !toHide.length && !toShow.length ) { + throw "jQuery UI Tabs: Mismatching fragment identifier."; } - // show new tab + if ( toHide.length ) { + that.element.queue( "tabs", function() { + that._hideTab( event, eventData ); + }); + } if ( toShow.length ) { - if ( toHide.length ) { - that.element.queue( "tabs", function() { - that._hideTab( event, eventData ); - }); - } that.element.queue( "tabs", function() { that._showTab( event, eventData ); }); + // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 that.load( that.anchors.index( clicked ), event ); - } else { - throw "jQuery UI Tabs: Mismatching fragment identifier."; - } - // Prevent IE from keeping other link focussed when using the back button - // and remove dotted border from clicked link. This is controlled via CSS - // in modern browsers; blur() removes focus from address bar in Firefox - // which can become a usability - if ( $.browser.msie ) { clicked[ 0 ].blur(); + } else { + that.element.dequeue( "tabs" ); } }, @@ -621,6 +573,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 +584,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; }); } @@ -660,6 +611,15 @@ $.extend( $.ui.tabs, { // DEPRECATED if ( $.uiBackCompat !== false ) { + // helper method for a lot of the back compat extensions + $.ui.tabs.prototype._ui = function( tab, panel ) { + return { + tab: tab, + panel: panel, + index: this.anchors.index( tab ) + }; + }; + // url method (function( $, prototype ) { prototype.url = function( index, url ) { @@ -685,7 +645,7 @@ if ( $.uiBackCompat !== false ) { var self = this; - this.element.bind( "tabsbeforeload", function( event, ui ) { + this.element.bind( "tabsbeforeload.tabs", function( event, ui ) { // tab is already cached if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) { event.preventDefault(); @@ -705,7 +665,7 @@ if ( $.uiBackCompat !== false ) { } }); - ui.jqXHR.success( function() { + ui.jqXHR.success(function() { if ( self.options.cache ) { $.data( ui.tab[ 0 ], "cache.tabs", true ); } @@ -743,34 +703,28 @@ if ( $.uiBackCompat !== false ) { }( jQuery, jQuery.ui.tabs.prototype ) ); // spinner - (function( $, prototype ) { - $.extend( prototype.options, { + $.widget( "ui.tabs", $.ui.tabs, { + options: { spinner: "<em>Loading…</em>" - }); - - 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 ) { @@ -975,21 +929,33 @@ if ( $.uiBackCompat !== false ) { show: null, select: null }); - var _trigger = prototype._trigger; + var _create = prototype._create, + _trigger = prototype._trigger; + prototype._create = function() { + _create.call( this ); + if ( this.options.active !== false ) { + this._trigger( "show", null, this._ui( + this.active[ 0 ], this._getPanelForTab( this.active )[ 0 ] ) ); + } + } prototype._trigger = function( type, event, data ) { var ret = _trigger.apply( this, arguments ); if ( !ret ) { return false; } - if ( type === "beforeActivate" ) { + if ( type === "beforeActivate" && data.newTab.length ) { ret = _trigger.call( this, "select", event, { tab: data.newTab[ 0], panel: data.newPanel[ 0 ], index: data.newTab.closest( "li" ).index() }); - } else if ( type === "activate" ) { - ret = _trigger.call( this, "show", event, data ); + } else if ( type === "activate" && data.newTab.length ) { + ret = _trigger.call( this, "show", event, { + tab: data.newTab[ 0 ], + panel: data.newPanel[ 0 ], + index: data.newTab.closest( "li" ).index() + }); } }; }( jQuery, jQuery.ui.tabs.prototype ) ); @@ -1010,57 +976,54 @@ if ( $.uiBackCompat !== false ) { }( jQuery, jQuery.ui.tabs.prototype ) ); // cookie option - (function( $, prototype ) { - $.extend( prototype.options, { + var listId = 0; + function getNextListId() { + return ++listId; + } + $.widget( "ui.tabs", $.ui.tabs, { + options: { cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } - }); - - var _create = prototype._create, - _refresh = prototype._refresh, - _eventHandler = prototype._eventHandler, - _destroy = prototype._destroy; - - prototype._create = function() { - var o = this.options; - if ( o.active === undefined ) { - if ( typeof o.active !== "number" && o.cookie ) { - o.active = parseInt( this._cookie(), 10 ); + }, + _create: function() { + var options = this.options, + active; + if ( options.active == null && options.cookie ) { + active = parseInt( this._cookie(), 10 ); + if ( active === -1 ) { + active = false; } + options.active = active; } - _create.call( this ); - }; - - prototype._cookie = function() { - var cookie = this.cookie || - ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() ); - return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) ); - }; - - prototype._refresh = function() { - _refresh.call( this ); - - // set or update cookie after init and add/remove respectively + this._super( "_create" ); + }, + _cookie: function( active ) { + var cookie = [ this.cookie || + ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() ) ]; + if ( arguments.length ) { + cookie.push( active === false ? -1 : active ); + cookie.push( this.options.cookie ); + } + return $.cookie.apply( null, cookie ); + }, + _refresh: function() { + this._super( "_refresh" ); if ( this.options.cookie ) { this._cookie( this.options.active, this.options.cookie ); } - }; - - prototype._eventHandler = function( event ) { - _eventHandler.apply( this, arguments ); - + }, + _eventHandler: function( event ) { + this._superApply( "_eventHandler", arguments ); if ( this.options.cookie ) { this._cookie( this.options.active, this.options.cookie ); } - }; - - prototype._destroy = function() { - _destroy.call( this ); - + }, + _destroy: function() { + this._super( "_destroy" ); if ( this.options.cookie ) { this._cookie( null, this.options.cookie ); } - }; - }( jQuery, jQuery.ui.tabs.prototype ) ); + } + }); } })( jQuery ); diff --git a/ui/jquery.ui.widget.js b/ui/jquery.ui.widget.js index a74e6b77b..4167fd4e5 100644 --- a/ui/jquery.ui.widget.js +++ b/ui/jquery.ui.widget.js @@ -55,7 +55,7 @@ $.widget = function( name, base, prototype ) { // we need to make the options hash a property directly on the new instance // otherwise we'll modify the options hash on the prototype that we're // inheriting from - basePrototype.options = $.extend( true, {}, basePrototype.options ); + basePrototype.options = $.widget.extend( {}, basePrototype.options ); $.each( prototype, function( prop, value ) { if ( $.isFunction( value ) ) { prototype[ prop ] = (function() { @@ -83,7 +83,7 @@ $.widget = function( name, base, prototype ) { }()); } }); - $[ namespace ][ name ].prototype = $.extend( true, basePrototype, { + $[ namespace ][ name ].prototype = $.widget.extend( basePrototype, { namespace: namespace, widgetName: name, widgetEventPrefix: name, @@ -93,6 +93,23 @@ $.widget = function( name, base, prototype ) { $.widget.bridge( name, $[ namespace ][ name ] ); }; +$.widget.extend = function( target ) { + var input = slice.call( arguments, 1 ), + inputIndex = 0, + inputLength = input.length, + key, + value; + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if (input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { + target[ key ] = $.isPlainObject( value ) ? $.widget.extend( {}, target[ key ], value ) : value; + } + } + } + return target; +}; + $.widget.bridge = function( name, object ) { $.fn[ name ] = function( options ) { var isMethodCall = typeof options === "string", @@ -101,7 +118,7 @@ $.widget.bridge = function( name, object ) { // allow multiple hashes to be passed on init options = !isMethodCall && args.length ? - $.extend.apply( null, [ true, options ].concat(args) ) : + $.widget.extend.apply( null, [ options ].concat(args) ) : options; if ( isMethodCall ) { @@ -163,7 +180,7 @@ $.Widget.prototype = { _createWidget: function( options, element ) { element = $( element || this.defaultElement || this )[ 0 ]; this.element = $( element ); - this.options = $.extend( true, {}, + this.options = $.widget.extend( {}, this.options, this._getCreateOptions(), options ); @@ -218,7 +235,7 @@ $.Widget.prototype = { if ( arguments.length === 0 ) { // don't return a reference to the internal hash - return $.extend( {}, this.options ); + return $.widget.extend( {}, this.options ); } if ( typeof key === "string" ) { @@ -230,7 +247,7 @@ $.Widget.prototype = { parts = key.split( "." ); key = parts.shift(); if ( parts.length ) { - curOption = options[ key ] = $.extend( true, {}, this.options[ key ] ); + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); for ( i = 0; i < parts.length - 1; i++ ) { curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; curOption = curOption[ parts[ i ] ]; |