diff options
95 files changed, 2919 insertions, 1632 deletions
@@ -8,19 +8,19 @@ 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 commiters +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 + 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] + 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] + git checkout 1-8-stable + git cherry-pick -x [sha-of-commit] diff --git a/build/build.xml b/build/build.xml index bd6144f29..154e7f60c 100644 --- a/build/build.xml +++ b/build/build.xml @@ -160,42 +160,46 @@ <mkdir dir="${min.dir}" /> <mkdir dir="${min.dir}/i18n/" /> <mkdir dir="${dist.dir}/themes/base/minified" /> - - <apply executable="java" parallel="false"> - <fileset dir="${dist.dir}/ui" includes="*.js" /> - <arg line="-jar" /> - <arg path="${closure-jar}" /> - <arg value="--warning_level" /> - <arg value="QUIET" /> - <arg value="--js_output_file" /> - <targetfile /> - <arg value="--js" /> - <mapper type="glob" from="*.js" to="${min.dir}/*.min.js" /> - </apply> - - <apply executable="java" parallel="false"> - <fileset dir="${dist.dir}/ui/i18n" includes="*.js" /> - <arg line="-jar" /> - <arg path="${closure-jar}" /> - <arg value="--warning_level" /> - <arg value="QUIET" /> - <arg value="--js_output_file" /> - <targetfile /> - <arg value="--js" /> - <mapper type="glob" from="*.js" to="${min.dir}/i18n/*.min.js" /> - </apply> - - <apply executable="java" parallel="false"> - <fileset dir="${dist.dir}/themes/base" includes="*.css" /> - <arg line="-jar" /> - <arg path="${yuicompressor-jar}" /> - <arg line="--charset utf-8" /> - <arg line="-v" /> - <srcfile /> - <arg line="-o" /> - <mapper type="glob" from="*.css" to="${dist.dir}/themes/base/minified/*.min.css" /> - <targetfile/> - </apply> + + <parallel threadsperprocessor="1"> + + <apply executable="java" parallel="false"> + <fileset dir="${dist.dir}/ui" includes="*.js" /> + <arg line="-jar" /> + <arg path="${closure-jar}" /> + <arg value="--warning_level" /> + <arg value="QUIET" /> + <arg value="--js_output_file" /> + <targetfile /> + <arg value="--js" /> + <mapper type="glob" from="*.js" to="${min.dir}/*.min.js" /> + </apply> + + <apply executable="java" parallel="false"> + <fileset dir="${dist.dir}/ui/i18n" includes="*.js" /> + <arg line="-jar" /> + <arg path="${closure-jar}" /> + <arg value="--warning_level" /> + <arg value="QUIET" /> + <arg value="--js_output_file" /> + <targetfile /> + <arg value="--js" /> + <mapper type="glob" from="*.js" to="${min.dir}/i18n/*.min.js" /> + </apply> + + <apply executable="java" parallel="false"> + <fileset dir="${dist.dir}/themes/base" includes="*.css" /> + <arg line="-jar" /> + <arg path="${yuicompressor-jar}" /> + <arg line="--charset utf-8" /> + <arg line="-v" /> + <srcfile /> + <arg line="-o" /> + <mapper type="glob" from="*.css" to="${dist.dir}/themes/base/minified/*.min.css" /> + <targetfile/> + </apply> + + </parallel> <replaceregexp match=".css" replace=".min.css" flags="g"> <fileset dir="${dist.dir}/themes/base/minified/"> @@ -258,53 +262,56 @@ <mkdir dir="${docs.dir}" /> <property name="url" value="http://docs.jquery.com/action/render/UI/API/${release.version}/" /> - <get src="${url}Draggable" dest="${docs.dir}draggable.html" /> - <get src="${url}Droppable" dest="${docs.dir}droppable.html" /> - <get src="${url}Resizable" dest="${docs.dir}resizable.html" /> - <get src="${url}Selectable" dest="${docs.dir}selectable.html" /> - <get src="${url}Sortable" dest="${docs.dir}sortable.html" /> - - <get src="${url}Accordion" dest="${docs.dir}accordion.html" /> - <get src="${url}Autocomplete" dest="${docs.dir}autocomplete.html" /> - <get src="${url}Button" dest="${docs.dir}button.html" /> - <get src="${url}Datepicker" dest="${docs.dir}datepicker.html" /> - <get src="${url}Dialog" dest="${docs.dir}dialog.html" /> - <get src="${url}Menu" dest="${docs.dir}menu.html" /> - <get src="${url}Progressbar" dest="${docs.dir}progressbar.html" /> - <get src="${url}Slider" dest="${docs.dir}slider.html" /> - <get src="${url}Spinner" dest="${docs.dir}spinner.html" /> - <get src="${url}Tooltip" dest="${docs.dir}tooltip.html" /> - <get src="${url}Tabs" dest="${docs.dir}tabs.html" /> - - <get src="${url}Position" dest="${docs.dir}position.html" /> - - <get src="http://docs.jquery.com/action/render/UI/Effects/animate" dest="${docs.dir}animate.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/addClass" dest="${docs.dir}addClass.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/effect" dest="${docs.dir}effect.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/hide" dest="${docs.dir}hide.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/removeClass" dest="${docs.dir}removeClass.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/show" dest="${docs.dir}show.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/switchClass" dest="${docs.dir}switchClass.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/toggle" dest="${docs.dir}toggle.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/toggleClass" dest="${docs.dir}toggleClass.html" /> - - - <get src="http://docs.jquery.com/action/render/UI/Effects/Blind" dest="${docs.dir}effect-blind.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/Clip" dest="${docs.dir}effect-clip.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/Drop" dest="${docs.dir}effect-drop.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/Explode" dest="${docs.dir}effect-explode.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/Fade" dest="${docs.dir}effect-fade.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/Fold" dest="${docs.dir}effect-fold.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/Puff" dest="${docs.dir}effect-puff.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/Slide" dest="${docs.dir}effect-slide.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/Scale" dest="${docs.dir}effect-scale.html" /> - - <get src="http://docs.jquery.com/action/render/UI/Effects/Bounce" dest="${docs.dir}effect-bounce.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/Highlight" dest="${docs.dir}effect-highlight.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/Pulsate" dest="${docs.dir}effect-pulsate.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/Shake" dest="${docs.dir}effect-shake.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/Size" dest="${docs.dir}effect-size.html" /> - <get src="http://docs.jquery.com/action/render/UI/Effects/Transfer" dest="${docs.dir}effect-transfer.html" /> + <parallel threadcount="8"> + + <get src="${url}Draggable" dest="${docs.dir}draggable.html" /> + <get src="${url}Droppable" dest="${docs.dir}droppable.html" /> + <get src="${url}Resizable" dest="${docs.dir}resizable.html" /> + <get src="${url}Selectable" dest="${docs.dir}selectable.html" /> + <get src="${url}Sortable" dest="${docs.dir}sortable.html" /> + + <get src="${url}Accordion" dest="${docs.dir}accordion.html" /> + <get src="${url}Autocomplete" dest="${docs.dir}autocomplete.html" /> + <get src="${url}Button" dest="${docs.dir}button.html" /> + <get src="${url}Datepicker" dest="${docs.dir}datepicker.html" /> + <get src="${url}Dialog" dest="${docs.dir}dialog.html" /> + <get src="${url}Menu" dest="${docs.dir}menu.html" /> + <get src="${url}Progressbar" dest="${docs.dir}progressbar.html" /> + <get src="${url}Slider" dest="${docs.dir}slider.html" /> + <get src="${url}Spinner" dest="${docs.dir}spinner.html" /> + <get src="${url}Tooltip" dest="${docs.dir}tooltip.html" /> + <get src="${url}Tabs" dest="${docs.dir}tabs.html" /> + + <get src="${url}Position" dest="${docs.dir}position.html" /> + + <get src="http://docs.jquery.com/action/render/UI/Effects/animate" dest="${docs.dir}animate.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/addClass" dest="${docs.dir}addClass.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/effect" dest="${docs.dir}effect.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/hide" dest="${docs.dir}hide.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/removeClass" dest="${docs.dir}removeClass.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/show" dest="${docs.dir}show.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/switchClass" dest="${docs.dir}switchClass.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/toggle" dest="${docs.dir}toggle.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/toggleClass" dest="${docs.dir}toggleClass.html" /> + + + <get src="http://docs.jquery.com/action/render/UI/Effects/Blind" dest="${docs.dir}effect-blind.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/Clip" dest="${docs.dir}effect-clip.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/Drop" dest="${docs.dir}effect-drop.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/Explode" dest="${docs.dir}effect-explode.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/Fade" dest="${docs.dir}effect-fade.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/Fold" dest="${docs.dir}effect-fold.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/Puff" dest="${docs.dir}effect-puff.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/Slide" dest="${docs.dir}effect-slide.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/Scale" dest="${docs.dir}effect-scale.html" /> + + <get src="http://docs.jquery.com/action/render/UI/Effects/Bounce" dest="${docs.dir}effect-bounce.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/Highlight" dest="${docs.dir}effect-highlight.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/Pulsate" dest="${docs.dir}effect-pulsate.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/Shake" dest="${docs.dir}effect-shake.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/Size" dest="${docs.dir}effect-size.html" /> + <get src="http://docs.jquery.com/action/render/UI/Effects/Transfer" dest="${docs.dir}effect-transfer.html" /> + </parallel> </target> <target name="themes-download"> diff --git a/demos/autocomplete/categories.html b/demos/autocomplete/categories.html index 17ec6495d..d2a1bc5bd 100644 --- a/demos/autocomplete/categories.html +++ b/demos/autocomplete/categories.html @@ -47,7 +47,7 @@ { label: "andreas andersson", category: "People" }, { label: "andreas johnson", category: "People" } ]; - + $( "#search" ).catcomplete({ delay: 0, source: data @@ -59,7 +59,7 @@ <div class="demo"> <label for="search">Search: </label> - <input id="search" /> + <input id="search"> </div><!-- End demo --> diff --git a/demos/autocomplete/combobox.html b/demos/autocomplete/combobox.html index 5fb3ffef9..b228c1cbb 100644 --- a/demos/autocomplete/combobox.html +++ b/demos/autocomplete/combobox.html @@ -14,9 +14,16 @@ <script src="../../ui/jquery.ui.tooltip.js"></script> <link rel="stylesheet" href="../demos.css"> <style> - .ui-button { margin-left: -1px; } - .ui-button-icon-only .ui-button-text { padding: 0.35em; } - .ui-autocomplete-input { margin: 0; padding: 0.4em 0 0.4em 0.45em; } + .ui-button { + margin-left: -1px; + } + .ui-button-icon-only .ui-button-text { + padding: 0.35em; + } + .ui-autocomplete-input { + margin: 0; + padding: 0.4em 0 0.4em 0.45em; + } </style> <script> (function( $ ) { @@ -90,7 +97,7 @@ .addClass( "ui-widget ui-widget-content ui-corner-left" ); input.data( "autocomplete" )._renderItem = function( ul, item ) { - return $( "<li></li>" ) + return $( "<li>" ) .data( "item.autocomplete", item ) .append( "<a>" + item.label + "</a>" ) .appendTo( ul ); diff --git a/demos/autocomplete/custom-data.html b/demos/autocomplete/custom-data.html index a4edc4fcc..a5782cab9 100644 --- a/demos/autocomplete/custom-data.html +++ b/demos/autocomplete/custom-data.html @@ -67,7 +67,7 @@ } }) .data( "autocomplete" )._renderItem = function( ul, item ) { - return $( "<li></li>" ) + return $( "<li>" ) .data( "item.autocomplete", item ) .append( "<a>" + item.label + "<br>" + item.desc + "</a>" ) .appendTo( ul ); @@ -79,9 +79,9 @@ <div class="demo"> <div id="project-label">Select a project (type "j" for a start):</div> - <img id="project-icon" src="images/transparent_1x1.png" class="ui-state-default"/> - <input id="project"/> - <input type="hidden" id="project-id"/> + <img id="project-icon" src="images/transparent_1x1.png" class="ui-state-default"> + <input id="project"> + <input type="hidden" id="project-id"> <p id="project-description"></p> </div><!-- End demo --> diff --git a/demos/autocomplete/default.html b/demos/autocomplete/default.html index 80e7642d4..bbd0889cf 100644 --- a/demos/autocomplete/default.html +++ b/demos/autocomplete/default.html @@ -49,7 +49,7 @@ <div class="ui-widget"> <label for="tags">Tags: </label> - <input id="tags" /> + <input id="tags"> </div> </div><!-- End demo --> diff --git a/demos/autocomplete/folding.html b/demos/autocomplete/folding.html index f3e45502b..8ebf0d0a6 100644 --- a/demos/autocomplete/folding.html +++ b/demos/autocomplete/folding.html @@ -46,7 +46,7 @@ <div class="ui-widget"> <form> <label for="developer">Developer: </label> - <input id="developer" /> + <input id="developer"> </form> </div> diff --git a/demos/autocomplete/maxheight.html b/demos/autocomplete/maxheight.html index c4f9769c3..f87f03171 100644 --- a/demos/autocomplete/maxheight.html +++ b/demos/autocomplete/maxheight.html @@ -60,12 +60,12 @@ </script> </head> <body> - + <div class="demo"> <div class="ui-widget"> <label for="tags">Tags: </label> - <input id="tags" /> + <input id="tags"> </div> </div><!-- End demo --> diff --git a/demos/autocomplete/multiple-remote.html b/demos/autocomplete/multiple-remote.html index 9351e8f3b..16472a36c 100644 --- a/demos/autocomplete/multiple-remote.html +++ b/demos/autocomplete/multiple-remote.html @@ -12,7 +12,9 @@ <script src="../../ui/jquery.ui.autocomplete.js"></script> <link rel="stylesheet" href="../demos.css"> <style> - .ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; } + .ui-autocomplete-loading { + background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; + } </style> <script> $(function() { @@ -69,7 +71,7 @@ <div class="ui-widget"> <label for="birds">Birds: </label> - <input id="birds" size="50" /> + <input id="birds" size="50"> </div> </div><!-- End demo --> diff --git a/demos/autocomplete/multiple.html b/demos/autocomplete/multiple.html index 4e67bf7e7..f5f249c41 100644 --- a/demos/autocomplete/multiple.html +++ b/demos/autocomplete/multiple.html @@ -84,7 +84,7 @@ <div class="ui-widget"> <label for="tags">Tag programming languages: </label> - <input id="tags" size="50" /> + <input id="tags" size="50"> </div> </div><!-- End demo --> diff --git a/demos/autocomplete/remote-jsonp.html b/demos/autocomplete/remote-jsonp.html index 1cc71d1e3..bfcbc0607 100644 --- a/demos/autocomplete/remote-jsonp.html +++ b/demos/autocomplete/remote-jsonp.html @@ -12,14 +12,16 @@ <script src="../../ui/jquery.ui.autocomplete.js"></script> <link rel="stylesheet" href="../demos.css"> <style> - .ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; } + .ui-autocomplete-loading { + background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; + } #city { width: 25em; } </style> <script> $(function() { function log( message ) { - $( "<div/>" ).text( message ).prependTo( "#log" ); - $( "#log" ).attr( "scrollTop", 0 ); + $( "<div>" ).text( message ).prependTo( "#log" ); + $( "#log" ).scrollTop( 0 ); } $( "#city" ).autocomplete({ @@ -65,7 +67,7 @@ <div class="ui-widget"> <label for="city">Your city: </label> - <input id="city" /> + <input id="city"> Powered by <a href="http://geonames.org">geonames.org</a> </div> diff --git a/demos/autocomplete/remote-with-cache.html b/demos/autocomplete/remote-with-cache.html index d7aabd72a..3d7a818ed 100644 --- a/demos/autocomplete/remote-with-cache.html +++ b/demos/autocomplete/remote-with-cache.html @@ -12,7 +12,9 @@ <script src="../../ui/jquery.ui.autocomplete.js"></script> <link rel="stylesheet" href="../demos.css"> <style> - .ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; } + .ui-autocomplete-loading { + background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; + } </style> <script> $(function() { @@ -44,7 +46,7 @@ <div class="ui-widget"> <label for="birds">Birds: </label> - <input id="birds" /> + <input id="birds"> </div> </div><!-- End demo --> diff --git a/demos/autocomplete/remote.html b/demos/autocomplete/remote.html index 5538b2822..3229c5cd8 100644 --- a/demos/autocomplete/remote.html +++ b/demos/autocomplete/remote.html @@ -12,13 +12,15 @@ <script src="../../ui/jquery.ui.autocomplete.js"></script> <link rel="stylesheet" href="../demos.css"> <style> - .ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; } + .ui-autocomplete-loading { + background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; + } </style> <script> $(function() { function log( message ) { - $( "<div/>" ).text( message ).prependTo( "#log" ); - $( "#log" ).attr( "scrollTop", 0 ); + $( "<div>" ).text( message ).prependTo( "#log" ); + $( "#log" ).scrollTop( 0 ); } $( "#birds" ).autocomplete({ @@ -39,7 +41,7 @@ <div class="ui-widget"> <label for="birds">Birds: </label> - <input id="birds" /> + <input id="birds"> </div> <div class="ui-widget" style="margin-top:2em; font-family:Arial"> diff --git a/demos/autocomplete/search.php b/demos/autocomplete/search.php index cbe78a52a..835772dee 100644 --- a/demos/autocomplete/search.php +++ b/demos/autocomplete/search.php @@ -1,4 +1,6 @@ <?php + +sleep( 3 ); // no term passed - just exit early with no response if (empty($_GET['term'])) exit ; $q = strtolower($_GET["term"]); diff --git a/demos/button/default.html b/demos/button/default.html index 1ea3fa796..969ec6838 100644 --- a/demos/button/default.html +++ b/demos/button/default.html @@ -11,7 +11,7 @@ <link rel="stylesheet" href="../demos.css"> <script> $(function() { - $( "button, input:submit, a", ".demo" ).button(); + $( "input:submit, a, button", ".demo" ).button(); $( "a", ".demo" ).click(function() { return false; }); }); </script> diff --git a/demos/index.html b/demos/index.html index b1cfcdd44..53a2557a2 100644 --- a/demos/index.html +++ b/demos/index.html @@ -300,6 +300,7 @@ <dd><a href="show/index.html">Show</a></dd> <dt>Utilities</dt> <dd><a href="position/index.html">Position</a></dd> + <dd><a href="widget/index.html">Widget</a></dd> <dt>About jQuery UI</dt> <dd><a href="http://jqueryui.com/docs/Getting_Started">Getting Started</a></dd> <dd><a href="http://jqueryui.com/docs/Upgrade_Guide">Upgrade Guide</a></dd> diff --git a/demos/menu/contextmenu.html b/demos/menu/contextmenu.html index 115f15b24..7513bca28 100644 --- a/demos/menu/contextmenu.html +++ b/demos/menu/contextmenu.html @@ -37,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> diff --git a/demos/menu/default.html b/demos/menu/default.html index 7a1dd99e7..40386112f 100644 --- a/demos/menu/default.html +++ b/demos/menu/default.html @@ -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/menubar/default.html b/demos/menubar/default.html index be49b4589..79662bd9f 100644 --- a/demos/menubar/default.html +++ b/demos/menubar/default.html @@ -70,92 +70,92 @@ <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> @@ -178,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> diff --git a/demos/spinner/currency.html b/demos/spinner/currency.html index 8288e4c3d..1e9b37d08 100644 --- a/demos/spinner/currency.html +++ b/demos/spinner/currency.html @@ -27,7 +27,7 @@ max: 2500,
step: 25,
start: 1000,
- numberformat: "C"
+ numberFormat: "C"
});
});
diff --git a/demos/spinner/decimal.html b/demos/spinner/decimal.html index 0a38fc51f..cdc659298 100644 --- a/demos/spinner/decimal.html +++ b/demos/spinner/decimal.html @@ -18,7 +18,7 @@ $(function() {
$("#spinner").spinner({
step: 0.01,
- numberformat: "n"
+ numberFormat: "n"
});
$("#culture").change(function() {
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/custom-animation.html b/demos/tooltip/custom-animation.html index ef8857979..c7d1aa5b8 100644 --- a/demos/tooltip/custom-animation.html +++ b/demos/tooltip/custom-animation.html @@ -1,59 +1,61 @@ <!doctype html> <html lang="en"> <head> + <meta charset="utf-8"> <title>jQuery UI Tooltip - Custom animation 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.position.js"></script> - <script type="text/javascript" src="../../ui/jquery.ui.tooltip.js"></script> - <link type="text/css" href="../demos.css" rel="stylesheet" /> - <script type="text/javascript"> + <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css"> + <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.tooltip.js"></script> + <script src="../../ui/jquery.effects.core.js"></script> + <script src="../../ui/jquery.effects.explode.js"></script> + <link rel="stylesheet" href="../demos.css"> + <script> $(function() { - $(".demo").tooltip({ + $( "#show-option" ).tooltip({ show: { effect: "slideDown", delay: 250 - }, + } + }); + $( "#hide-option" ).tooltip({ hide: { - effect: "hide", + effect: "explode", delay: 250 } }); + $( "#open-event" ).tooltip({ + show: null, + position: { + my: "left top", + at: "left bottom" + }, + open: function( event, ui ) { + ui.tooltip.animate({ top: ui.tooltip.position().top + 10 }, "fast" ); + } + }); }); </script> - <style> - label { display: inline-block; width: 5em; } - </style> </head> <body> <div class="demo"> - <p><a href="#" title="That's what this widget is">Tooltips</a> can be attached to any element. When you hover - the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip. - </p> - <p>But as it's not a native tooltip, it can be styled. Any themes built with - <a href="http://themeroller.com" title="ThemeRoller, jQuery UI's theme builder application">ThemeRoller</a> - will also style tooltip's accordingly.</p> - <p>Tooltip's are also useful for form elements, to show some additional information in the context of each field.</p> - <p><label for="age">Your age:</label><input id="age" title="We ask for your age only for statistical purposes." /></p> - <p>Click the field to see the tooltip; when you tab out of the field, it gets hidden.</p> +<p>There are various ways to customize the animation of a tooltip.</p> +<p>You can use the <a id="show-option" href="http://jqueryui.com/demos/tooltip/#option-show" title="slide down on show">show</a> and +<a id="hide-option" href="http://jqueryui.com/demos/tooltip/#option-hide" title="explode on hide">hide</a> options.</p> +<p>You can also use the <a id="open-event" href="http://jqueryui.com/demos/tooltip/#event-open" title="move down on show">open event</a>.</p> </div><!-- End demo --> <div class="demo-description"> - -<p>This demo shows how to customize animations. The tooltip is shown, after a -delay of 250ms, using a slide down animation, and hidden, after another delay, -without an animation.</p> - +<p>This demo shows how to customize animations using the show and hide options, +as well as the open event.</p> </div><!-- End demo-description --> - - </body> </html> diff --git a/demos/tooltip/custom-content.html b/demos/tooltip/custom-content.html new file mode 100644 index 000000000..e84a7104b --- /dev/null +++ b/demos/tooltip/custom-content.html @@ -0,0 +1,85 @@ +<!doctype html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>jQuery UI Tooltip - Custom content</title> + <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css"> + <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.tooltip.js"></script> + <link rel="stylesheet" href="../demos.css"> + <style> + .photo { + width: 300px; + text-align: center; + } + .photo .ui-widget-header { + margin: 1em 0; + } + .map { + width: 350px; + height: 350px; + } + </style> + <script> + $(function() { + $( ".demo" ).tooltip({ + items: "img, [data-geo], [title]", + content: function() { + var element = $( this ); + if ( element.is( "[data-geo]" ) ) { + return "<img class='map' src='http://maps.google.com/maps/api/staticmap?" + + "zoom=11&size=350x350&maptype=terrain&sensor=false¢er=" + + element.text() + "'>"; + } + if ( element.is( "[title]" ) ) { + return element.attr( "title" ); + } + if ( element.is( "img" ) ) { + return element.attr( "alt" ); + } + } + }); + }); + </script> +</head> +<body> + +<div class="demo"> + +<div class="ui-widget photo"> + <div class="ui-widget-header ui-corner-all"> + <h2>St. Stephen's Cathedral</h2> + <h3><a href="http://maps.google.com/maps?q=vienna,+austria&z=11" data-geo>Vienna, Austria</a></h3> + </div> + <a href="http://en.wikipedia.org/wiki/File:Wien_Stefansdom_DSC02656.JPG"> + <img src="images/st-stephens.jpg" alt="St. Stephen's Cathedral" class="ui-corner-all"> + </a> +</div> + +<div class="ui-widget photo"> + <div class="ui-widget-header ui-corner-all"> + <h2>Tower Bridge</h2> + <h3><a href="http://maps.google.com/maps?q=london,+england&z=11" data-geo>London, England</a></h3> + </div> + <a href="http://en.wikipedia.org/wiki/File:Tower_bridge_London_Twilight_-_November_2006.jpg"> + <img src="images/tower-bridge.jpg" alt="Tower Bridge" class="ui-corner-all"> + </a> +</div> + +<p>All images are part of <a href="http://commons.wikimedia.org/wiki/Main_Page">Wikimedia Commons</a> +and are licensed under <a href="http://creativecommons.org/licenses/by-sa/3.0/deed.en" title="Creative Commons Attribution-ShareAlike 3.0">CC BY-SA 3.0</a> by the copyright holder.</p> + +</div><!-- End demo --> + + + +<div class="demo-description"> +<p>Shows how to combine different event delegated tooltips into a single instance, by customizing the items and content options.</p> +<p>We realize you may want to interact with the map tooltips. This is a planned feature for a future version.</p> +</div><!-- End demo-description --> + +</body> +</html> diff --git a/demos/tooltip/default.html b/demos/tooltip/default.html index 9d5502f2b..cfb61f2eb 100644 --- a/demos/tooltip/default.html +++ b/demos/tooltip/default.html @@ -1,48 +1,47 @@ <!doctype html> <html lang="en"> <head> - <title>jQuery UI Tooltip - 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.position.js"></script> - <script type="text/javascript" src="../../ui/jquery.ui.tooltip.js"></script> - <link type="text/css" href="../demos.css" rel="stylesheet" /> - <script type="text/javascript"> + <meta charset="utf-8"> + <title>jQuery UI Tooltip - Default functionality</title> + <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css"> + <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.tooltip.js"></script> + <link rel="stylesheet" href="../demos.css"> + <script> $(function() { - $(".demo").tooltip(); + $( ".demo" ).tooltip(); }); </script> <style> - label { display: inline-block; width: 5em; } + label { + display: inline-block; + width: 5em; + } </style> </head> <body> <div class="demo"> - <p><a href="#" title="That's what this widget is">Tooltips</a> can be attached to any element. When you hover - the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip. - </p> - <p>But as it's not a native tooltip, it can be styled. Any themes built with - <a href="http://themeroller.com" title="ThemeRoller, jQuery UI's theme builder application">ThemeRoller</a> - will also style tooltip's accordingly.</p> - <p>Tooltip's are also useful for form elements, to show some additional information in the context of each field.</p> - <p><label for="age">Your age:</label><input id="age" title="We ask for your age only for statistical purposes." /></p> - <p>Click the field to see the tooltip; when you tab out of the field, it gets hidden.</p> +<p><a href="#" title="That's what this widget is">Tooltips</a> can be attached to any element. When you hover +the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip.</p> +<p>But as it's not a native tooltip, it can be styled. Any themes built with +<a href="http://themeroller.com" title="ThemeRoller: jQuery UI's theme builder application">ThemeRoller</a> +will also style tooltips accordingly.</p> +<p>Tooltips are also useful for form elements, to show some additional information in the context of each field.</p> +<p><label for="age">Your age:</label><input id="age" title="We ask for your age only for statistical purposes."></p> +<p>Hover the field to see the tooltip.</p> </div><!-- End demo --> <div class="demo-description"> - <p>Hover the links above or use the tab key to cycle the focus on each element.</p> - </div><!-- End demo-description --> - - </body> </html> diff --git a/demos/tooltip/delegation-mixbag.html b/demos/tooltip/delegation-mixbag.html deleted file mode 100644 index 9c524dabe..000000000 --- a/demos/tooltip/delegation-mixbag.html +++ /dev/null @@ -1,73 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <title>jQuery UI Tooltip - 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.position.js"></script> - <script type="text/javascript" src="../../ui/jquery.ui.tooltip.js"></script> - <link type="text/css" href="../demos.css" rel="stylesheet" /> - <script type="text/javascript"> - $(function() { - $(".demo").tooltip({ - items: "[href], [title]", - content: function(response) { - var href = $(this).attr("href"); - if (/^#/.test(href)) { - return $(href).html(); - } else if (href) { - $.get(href, response); - return "loading..."; - } - return this.title; - } - }); - $("#footnotes").hide(); - }); - </script> - <style> - label { display: inline-block; width: 5em; } - </style> -</head> -<body> - -<div class="demo"> - <ul> - <li> - <a href="#footnote1">I'm a link to a footnote.</a> - </li> - <li> - <a href="#footnote2">I'm another link to a footnote.</a> - </li> - </ul> - <input title="This is just an input, nothing special" /> - - <ul> - <li> - <a href="ajax/content1.html">Link to ajax content, with tooltip preview!</a> - </li> - <li> - <a href="ajax/content2.html">Another link to ajax content, with tooltip preview!</a> - </li> - </ul> - - <div id="footnotes"> - <div id="footnote1">This is <strong>the</strong> footnote, including other elements</div> - <div id="footnote2">This is <strong>the other</strong> footnote, including other elements</div> - </div> -</div><!-- End demo --> - - - -<div class="demo-description"> - -<p>Show how to combine different event delegated tooltips into a single instance, by customizing the items and content options.</p> - -</div><!-- End demo-description --> - - - -</body> -</html> diff --git a/demos/tooltip/forms.html b/demos/tooltip/forms.html index 983b56bdf..0f91736b2 100644 --- a/demos/tooltip/forms.html +++ b/demos/tooltip/forms.html @@ -1,71 +1,87 @@ <!doctype html> <html lang="en"> <head> + <meta charset="utf-8"> <title>jQuery UI Tooltip - 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.position.js"></script> - <script type="text/javascript" src="../../ui/jquery.ui.tooltip.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 rel="stylesheet" href="../../themes/base/jquery.ui.all.css"> + <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.tooltip.js"></script> + <script src="../../ui/jquery.ui.button.js"></script> + <link rel="stylesheet" href="../demos.css"> + <style> + label { + display: inline-block; width: 5em; + } + fieldset div { + margin-bottom: 2em; + } + fieldset .help { + display: inline-block; + } + .ui-tooltip { + width: 210px; + } + </style> + <script> $(function() { - $("[title]").tooltip().unbind(".tooltip"); - $("<button/>").text("Show help").button().toggle(function() { - $(":ui-tooltip").tooltip("open"); - }, function() { - $(":ui-tooltip").tooltip("close"); - }).appendTo("form"); + var tooltips = $( "[title]" ) + .click(function() { + $( this ).tooltip( $( this ).attr( "title" ) ? "open" : "close" ); + }) + .bind( "mouseover focusin mouseleave blur click", function( event ) { + event.stopImmediatePropagation(); + }) + .tooltip(); + $( "<button>" ) + .text( "Show help" ) + .button() + .toggle( + function() { + tooltips.tooltip( "open" ); + }, + function() { + tooltips.tooltip( "close" ); + } + ) + .appendTo( "form" ); }); </script> - <style> - label { display: inline-block; width: 5em; } - .ui-icon { display: inline-block; } - fieldset div { - margin-bottom: 2em; - } - .ui-tooltip { width: 210px; } - </style> </head> <body> <div class="demo"> - <form> - <fieldset> - <div> - <label for="firstname">Firstname</label> - <input id="firstname" name="firstname" /> - <span title="Please provide your firstname." class="ui-state-default ui-corner-all ui-icon ui-icon-help">?</span> - </div> - <div> - <label for="lastname">Lastname</label> - <input id="lastname" name="lastname" /> - <span title="Please provide also your lastname." class="ui-state-default ui-corner-all ui-icon ui-icon-help">?</span> - </div> - <div> - <label for="address">Address</label> - <input id="address" name="address" /> - <span title="Your home or work address." class="ui-state-default ui-corner-all ui-icon ui-icon-help">?</span> - </div> - </fieldset> - </form> +<form> + <fieldset> + <div> + <label for="firstname">Firstname</label> + <input id="firstname" name="firstname"> + <span title="Please provide your firstname." class="help ui-state-default ui-corner-all ui-icon ui-icon-help">?</span> + </div> + <div> + <label for="lastname">Lastname</label> + <input id="lastname" name="lastname"> + <span title="Please provide also your lastname." class="help ui-state-default ui-corner-all ui-icon ui-icon-help">?</span> + </div> + <div> + <label for="address">Address</label> + <input id="address" name="address"> + <span title="Your home or work address." class="help ui-state-default ui-corner-all ui-icon ui-icon-help">?</span> + </div> + </fieldset> +</form> </div><!-- End demo --> <div class="demo-description"> - <p>Use the button below to display the help texts. Click again to hide them. Default hover and focus events are removed to show tooltip only programmatically.</p> - <p>A fixed width is defined in CSS to make the tooltips look consistent when displayed all at once.</p> - </div><!-- End demo-description --> - - </body> </html> diff --git a/demos/tooltip/images/st-stephens.jpg b/demos/tooltip/images/st-stephens.jpg Binary files differnew file mode 100644 index 000000000..30fc36d67 --- /dev/null +++ b/demos/tooltip/images/st-stephens.jpg diff --git a/demos/tooltip/images/tower-bridge.jpg b/demos/tooltip/images/tower-bridge.jpg Binary files differnew file mode 100644 index 000000000..d1e14d6d2 --- /dev/null +++ b/demos/tooltip/images/tower-bridge.jpg diff --git a/demos/tooltip/index.html b/demos/tooltip/index.html index 4ad189ed2..6e7c6836e 100644 --- a/demos/tooltip/index.html +++ b/demos/tooltip/index.html @@ -1,8 +1,9 @@ <!doctype html> <html lang="en"> <head> + <meta charset="utf-8"> <title>jQuery UI Tooltip Demos</title> - <link type="text/css" href="../demos.css" rel="stylesheet" /> + <link rel="stylesheet" href="../demos.css"> </head> <body> @@ -13,7 +14,7 @@ <li><a href="forms.html">Forms with tooltips</a></li> <li><a href="tracking.html">Track the mouse</a></li> <li><a href="custom-animation.html">Custom animation</a></li> - <li><a href="delegation-mixbag.html">Delegation Mixbag</a></li> + <li><a href="custom-content.html">Custom content</a></li> <li><a href="video-player.html">Video Player</a></li> </ul> </div> diff --git a/demos/tooltip/tracking.html b/demos/tooltip/tracking.html index dd5dc9d92..4cddb4437 100644 --- a/demos/tooltip/tracking.html +++ b/demos/tooltip/tracking.html @@ -1,64 +1,64 @@ <!doctype html> <html lang="en"> <head> - <title>jQuery UI Tooltip - 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.position.js"></script> - <script type="text/javascript" src="../../ui/jquery.ui.tooltip.js"></script> - <link type="text/css" href="../demos.css" rel="stylesheet" /> - <script type="text/javascript"> + <meta charset="utf-8"> + <title>jQuery UI Tooltip - Track the mouse</title> + <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css"> + <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.tooltip.js"></script> + <link rel="stylesheet" href="../demos.css"> + <style> + label { + display: inline-block; + width: 5em; + } + </style> + <script> $(function() { - $(".demo").tooltip({ - open: function() { + $( ".demo" ).tooltip({ + open: function( event ) { var tooltip = $( ".ui-tooltip" ); - $(document).mousemove(function( event ) { - tooltip.position( { + function position( event ) { + tooltip.position({ my: "left+25 center", at: "right+25 center", of: event }); - }) + } + $( document ).bind( "mousemove.tooltip-position", position ); // trigger once to override element-relative positioning - .mousemove(); + position( event ); }, close: function() { - $(document).unbind( "mousemove" ); + $( document ).unbind( "mousemove.tooltip-position" ); } }); }); </script> - <style> - label { display: inline-block; width: 5em; } - </style> </head> <body> <div class="demo"> - <p><a href="#" title="That's what this widget is">Tooltips</a> can be attached to any element. When you hover - the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip. - </p> - <p>But as it's not a native tooltip, it can be styled. Any themes built with - <a href="http://themeroller.com" title="ThemeRoller, jQuery UI's theme builder application">ThemeRoller</a> - will also style tooltip's accordingly.</p> - <p>Tooltip's are also useful for form elements, to show some additional information in the context of each field.</p> - <p><label for="age">Your age:</label><input id="age" title="We ask for your age only for statistical purposes." /></p> - <p>Click the field to see the tooltip; when you tab out of the field, it gets hidden.</p> +<p><a href="#" title="That's what this widget is">Tooltips</a> can be attached to any element. When you hover +the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip.</p> +<p>But as it's not a native tooltip, it can be styled. Any themes built with +<a href="http://themeroller.com" title="ThemeRoller: jQuery UI's theme builder application">ThemeRoller</a> +will also style tooltips accordingly.</p> +<p>Tooltips are also useful for form elements, to show some additional information in the context of each field.</p> +<p><label for="age">Your age:</label><input id="age" title="We ask for your age only for statistical purposes."></p> +<p>Hover the field to see the tooltip.</p> </div><!-- End demo --> <div class="demo-description"> - <p>Here the tooltips are positioned relative to the mouse, and follow the mouse while it moves above the element.</p> - </div><!-- End demo-description --> - - </body> </html> diff --git a/demos/tooltip/video-player.html b/demos/tooltip/video-player.html index 56003ab5a..1d8458abb 100644 --- a/demos/tooltip/video-player.html +++ b/demos/tooltip/video-player.html @@ -1,64 +1,105 @@ <!doctype html> <html lang="en"> <head> + <meta charset="utf-8"> <title>jQuery UI Tooltip - Video Player 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.position.js"></script> - <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="../../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"> + <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css"> + <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.tooltip.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 src="../../ui/jquery.effects.core.js"></script> + <script src="../../ui/jquery.effects.blind.js"></script> + <link rel="stylesheet" href="../demos.css"> + <style> + .player { + width: 500px; + height: 300px; + border: 2px groove gray; + background: rgb(200, 200, 200); + text-align: center; + line-height: 300px; + } + /* TODO load from jquery.ui.popup.css */ + .ui-popup { + position: absolute; + z-index: 5000; + } + .ui-tooltip { + border: 1px solid white; + 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> + <script> $(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(); - }); + var msg = "Selected " + $.trim( input.data( "tooltip-title" ) || 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 + $( "ul" ).menu({ + select: function( event, ui ) { + // TODO should probably be handled by popup, see ESCAPE key handler // affects key handling - $(this).prev().focus(); - notify(ui.item); + $( this ).prev().focus(); + notify( ui.item ); } }).popup(); - $("button").each(function() { - $(this).button({ + $( "button" ).each(function() { + var button = $( this ).button({ icons: { - primary: $(this).data("icon") + primary: $( this ).data( "icon" ) }, - text: !!$(this).attr("title") - }).click(function() { - // TODO don't notify if the button is opening a popup - notify(this); + text: !!$( this ).attr( "title" ) }); + if ( button.next().is( ":ui-popup" ) ) { + button.click(function( event ) { + $( ".demo" ).tooltip( "close", event ); + }); + } else { + button.click(function() { + notify( button ); + }); + } }); - $(".set").buttonset({ + $( ".set" ).buttonset({ items: "button" }); - - $(".demo").tooltip({ + $( ".demo" ).tooltip({ position: { my: "center top", at: "center bottom+5", @@ -72,63 +113,43 @@ }); }); </script> - <style> - .player { width: 500px; height: 300px; border: 2px groove gray; background: rgb(200, 200, 200); text-align: center; line-height: 300px; } - /* TODO load from jquery.ui.popup.css */ - .ui-popup { position: absolute; z-index: 5000; } - - .ui-tooltip { - border: 1px solid white; - 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> <div class="demo"> - <div class="player">Here Be Video (HTML5?)</div> - <div class="tools"> - <span class="set"> - <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> - <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> - <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> +<div class="player">Here Be Video (HTML5?)</div> +<div class="tools"> + <span class="set"> + <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> + <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> + <ul> + <li> + <a href="#">Favorites</a> + </li> + <li> + <a href="#">Watch Later</a> + </li> + <li> + <a href="#">New Playlist...</a> + </li> + </ul> </div> - </div> + <button title="Share this video">Share</button> + <button data-icon="ui-icon-alert">Flag as inappropiate</button> +</div> </div><!-- End demo --> <div class="demo-description"> - <p>A fake video player with like/share/stats button, each with a custom-styled tooltip.</p> - </div><!-- End demo-description --> - - </body> </html> diff --git a/demos/widget/default.html b/demos/widget/default.html new file mode 100644 index 000000000..c2b520983 --- /dev/null +++ b/demos/widget/default.html @@ -0,0 +1,165 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>jQuery UI Widget - Default functionality</title> + <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css"> + <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> + <link rel="stylesheet" href="../demos.css"> + <style> + .custom-colorize { + font-size: 25px; + width: 75px; + height: 75px; + } + </style> + <script> + $(function() { + // the widget definition, where "custom" is the namespace, + // "colorize" the widget name + $.widget( "custom.colorize", { + // default options + options: { + red: 255, + green: 0, + blue: 0, + + // callbacks + change: null, + random: null + }, + + // the constructor + _create: function() { + this.element + // add a class for theming + .addClass( "custom-colorize" ) + // prevent double click to select text + .disableSelection(); + + // bind click events to random method + this._bind({ + // _bind won't call random when widget is disabled + click: "random" + }); + this._refresh(); + }, + + // called when created, and later when changing options + _refresh: function() { + this.element.css( "background-color", "rgb(" + + this.options.red +"," + + this.options.green + "," + + this.options.blue + ")" + ); + + // trigger a callback/event + this._trigger( "change" ); + }, + + // a public method to change the color to a random value + // can be called directly via .colorize( "random" ) + random: function( event ) { + var colors = { + red: Math.floor( Math.random() * 256 ), + green: Math.floor( Math.random() * 256 ), + blue: Math.floor( Math.random() * 256 ) + }; + + // trigger an event, check if it's canceled + if ( this._trigger( "random", event, colors ) !== false ) { + this.option( colors ); + } + }, + + // events bound via _bind are removed automatically + // revert other modifications here + _destroy: function() { + this.element + .removeClass( "custom-colorize" ) + .enableSelection() + .css( "background-color", "transparent" ); + }, + + // _setOptions is called with a hash of all options that are changing + // always refresh when changing options + _setOptions: function() { + // _super and _superApply handle keeping the right this-context + this._superApply( "_setOptions", arguments ); + this._refresh(); + }, + + // _setOption is called for each individual option that is changing + _setOption: function( key, value ) { + // prevent invalid color values + if ( /red|green|blue/.test(key) && (value < 0 || value > 255) ) { + return; + } + this._super( "_setOption", key, value ); + } + }); + + // initialize with default options + $( "#my-widget1" ).colorize(); + + // initialize with two customized options + $( "#my-widget2" ).colorize({ + red: 60, + blue: 60 + }); + + // initialize with custom green value + // and a random callback to allow only colors with enough green + $( "#my-widget3" ).colorize( { + green: 128, + random: function( event, ui ) { + return ui.green > 128; + } + }); + + // click to toggle enabled/disabled + $( "#disable" ).toggle(function() { + // use the custom selector created for each widget to find all instances + $( ":custom-colorize" ).colorize( "disable" ); + }, function() { + $( ":custom-colorize" ).colorize( "enable" ); + }); + + // click to set options after initalization + $( "#black" ).click( function() { + $( ":custom-colorize" ).colorize( "option", { + red: 0, + green: 0, + blue: 0 + }); + }); + }); + </script> +</head> +<body> + +<div class="demo"> + +<div> + <div id="my-widget1">color me</div> + <div id="my-widget2">color me</div> + <div id="my-widget3">color me</div> + <button id="disable">Toglge disabled option</button> + <button id="black">Go black</button> +</div> + +</div><!-- End demo --> + + + +<div class="demo-description"> +<p>This demo shows a simple custom widget built using the widget factory (jquery.ui.widget.js).</p> +<p>The three boxes are initialized in different ways. Clicking them changes their background color. View source to see how it works, its heavily commented</p> +<p><a href="http://wiki.jqueryui.com/w/page/12138135/Widget-factory">For more details on the widget factory, visit the jQuery UI planning wiki.</a></p> +</div><!-- End demo-description --> + +</body> +</html> diff --git a/demos/widget/index.html b/demos/widget/index.html new file mode 100644 index 000000000..1ecb4feea --- /dev/null +++ b/demos/widget/index.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>jQuery UI Widget Demo</title> + <link rel="stylesheet" href="../demos.css"> +</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/external/qunit.css b/external/qunit.css index 78a7d7e3d..b3c6db523 100644 --- a/external/qunit.css +++ b/external/qunit.css @@ -1,7 +1,17 @@ +/** + * QUnit - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2011 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + /** Font Family and Sizes */ #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { - font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial; + font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; } #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } @@ -27,7 +37,7 @@ font-size: 1.5em; line-height: 1em; font-weight: normal; - + border-radius: 15px 15px 0 0; -moz-border-radius: 15px 15px 0 0; -webkit-border-top-right-radius: 15px; @@ -95,13 +105,13 @@ #qunit-tests ol { margin-top: 0.5em; padding: 0.5em; - + background-color: #fff; - + border-radius: 15px; -moz-border-radius: 15px; -webkit-border-radius: 15px; - + box-shadow: inset 0px 2px 13px #999; -moz-box-shadow: inset 0px 2px 13px #999; -webkit-box-shadow: inset 0px 2px 13px #999; @@ -164,7 +174,7 @@ #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } #qunit-tests .pass .test-name { color: #366097; } - + #qunit-tests .pass .test-actual, #qunit-tests .pass .test-expected { color: #999999; } diff --git a/external/qunit.js b/external/qunit.js index 870287148..d56936ee2 100644 --- a/external/qunit.js +++ b/external/qunit.js @@ -1,6 +1,6 @@ -/* +/** * QUnit - A JavaScript Unit Testing Framework - * + * * http://docs.jquery.com/QUnit * * Copyright (c) 2011 John Resig, Jörn Zaefferer @@ -78,7 +78,7 @@ Test.prototype = { // allow utility functions to access the current test environment // TODO why?? QUnit.current_testEnvironment = this.testEnvironment; - + try { if ( !config.pollution ) { saveGlobal(); @@ -114,8 +114,8 @@ Test.prototype = { }, teardown: function() { try { - checkPollution(); this.testEnvironment.teardown.call(this.testEnvironment); + checkPollution(); } catch(e) { QUnit.ok( false, "Teardown failed on " + this.testName + ": " + e.message ); } @@ -124,7 +124,7 @@ Test.prototype = { if ( this.expected && this.expected != this.assertions.length ) { QUnit.ok( false, "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" ); } - + var good = 0, bad = 0, tests = id("qunit-tests"); @@ -154,9 +154,9 @@ Test.prototype = { // store result when possible if ( QUnit.config.reorder && defined.sessionStorage ) { if (bad) { - sessionStorage.setItem("qunit-" + this.module + "-" + this.testName, bad) + sessionStorage.setItem("qunit-" + this.module + "-" + this.testName, bad); } else { - sessionStorage.removeItem("qunit-" + this.testName); + sessionStorage.removeItem("qunit-" + this.module + "-" + this.testName); } } @@ -166,17 +166,17 @@ Test.prototype = { var b = document.createElement("strong"); b.innerHTML = this.name + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>"; - + var a = document.createElement("a"); a.innerHTML = "Rerun"; a.href = QUnit.url({ filter: getText([b]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") }); - + addEvent(b, "click", function() { var next = b.nextSibling.nextSibling, display = next.style.display; next.style.display = display === "none" ? "block" : "none"; }); - + addEvent(b, "dblclick", function(e) { var target = e && e.target ? e.target : window.event.srcElement; if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) { @@ -217,7 +217,7 @@ Test.prototype = { total: this.assertions.length } ); }, - + queue: function() { var test = this; synchronize(function() { @@ -246,7 +246,7 @@ Test.prototype = { synchronize(run); }; } - + }; var QUnit = { @@ -265,7 +265,7 @@ var QUnit = { QUnit.test(testName, expected, callback, true); }, - + test: function(testName, expected, callback, async) { var name = '<span class="test-name">' + testName + '</span>', testEnvironmentArg; @@ -286,13 +286,13 @@ var QUnit = { if ( !validTest(config.currentModule + ": " + testName) ) { return; } - + var test = new Test(name, testName, expected, testEnvironmentArg, async, callback); test.module = config.currentModule; test.moduleTestEnvironment = config.currentModuleTestEnviroment; test.queue(); }, - + /** * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. */ @@ -337,7 +337,7 @@ var QUnit = { notEqual: function(actual, expected, message) { QUnit.push(expected != actual, actual, expected, message); }, - + deepEqual: function(actual, expected, message) { QUnit.push(QUnit.equiv(actual, expected), actual, expected, message); }, @@ -356,34 +356,34 @@ var QUnit = { raises: function(block, expected, message) { var actual, ok = false; - + if (typeof expected === 'string') { message = expected; expected = null; } - + try { block(); } catch (e) { actual = e; } - + if (actual) { // we don't want to validate thrown error if (!expected) { ok = true; - // expected is a regexp + // expected is a regexp } else if (QUnit.objectType(expected) === "regexp") { ok = expected.test(actual); - // expected is a constructor + // expected is a constructor } else if (actual instanceof expected) { ok = true; - // expected is a validation function which returns true is validation passed + // expected is a validation function which returns true is validation passed } else if (expected.call({}, actual) === true) { ok = true; } } - + QUnit.ok(ok, message); }, @@ -412,7 +412,7 @@ var QUnit = { process(); } }, - + stop: function(timeout) { config.semaphore++; config.blocking = true; @@ -438,7 +438,7 @@ var config = { // block until document ready blocking: true, - + // by default, run previously failed tests first // very useful in combination with "Hide passed tests" checked reorder: true, @@ -519,7 +519,7 @@ extend(QUnit, { if ( result ) { result.parentNode.removeChild( result ); } - + if ( tests ) { result = document.createElement( "p" ); result.id = "qunit-testresult"; @@ -528,23 +528,23 @@ extend(QUnit, { result.innerHTML = 'Running...<br/> '; } }, - + /** * Resets the test setup. Useful for tests that modify the DOM. - * + * * If jQuery is available, uses jQuery's html(), otherwise just innerHTML. */ reset: function() { if ( window.jQuery ) { - jQuery( "#main, #qunit-fixture" ).html( config.fixture ); + jQuery( "#qunit-fixture" ).html( config.fixture ); } else { - var main = id( 'main' ) || id( 'qunit-fixture' ); + var main = id( 'qunit-fixture' ); if ( main ) { main.innerHTML = config.fixture; } } }, - + /** * Trigger an event on an element. * @@ -564,12 +564,12 @@ extend(QUnit, { elem.fireEvent("on"+type); } }, - + // Safe object type checking is: function( type, obj ) { return QUnit.objectType( obj ) == type; }, - + objectType: function( obj ) { if (typeof obj === "undefined") { return "undefined"; @@ -603,7 +603,7 @@ extend(QUnit, { } return undefined; }, - + push: function(result, actual, expected, message) { var details = { result: result, @@ -611,7 +611,7 @@ extend(QUnit, { actual: actual, expected: expected }; - + message = escapeHtml(message) || (result ? "okay" : "failed"); message = '<span class="test-message">' + message + "</span>"; expected = escapeHtml(QUnit.jsDump.parse(expected)); @@ -629,15 +629,15 @@ extend(QUnit, { } } output += "</table>"; - + QUnit.log(details); - + config.current.assertions.push({ result: !!result, message: output }); }, - + url: function( params ) { params = extend( extend( {}, QUnit.urlParams ), params ); var querystring = "?", @@ -648,7 +648,7 @@ extend(QUnit, { } return window.location.pathname + querystring.slice( 0, -1 ); }, - + // Logging callbacks; all receive a single argument with the listed properties // run test/logs.html for any related changes begin: function() {}, @@ -672,7 +672,7 @@ if ( typeof document === "undefined" || document.readyState === "complete" ) { addEvent(window, "load", function() { QUnit.begin({}); - + // Initialize the config, saving the execution queue var oldconfig = extend({}, config); QUnit.init(); @@ -695,7 +695,7 @@ addEvent(window, "load", function() { window.location = QUnit.url( params ); }); } - + var toolbar = id("qunit-testrunner-toolbar"); if ( toolbar ) { var filter = document.createElement("input"); @@ -730,7 +730,7 @@ addEvent(window, "load", function() { toolbar.appendChild( label ); } - var main = id('main') || id('qunit-fixture'); + var main = id('qunit-fixture'); if ( main ) { config.fixture = main.innerHTML; } @@ -774,13 +774,19 @@ function done() { banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass"); } - if ( tests ) { + if ( tests ) { id( "qunit-testresult" ).innerHTML = html; } + if ( typeof document !== "undefined" && document.title ) { + // show ✖ for good, ✔ for bad suite result in title + // use escape sequences in case file gets loaded with non-utf-8-charset + document.title = (config.stats.bad ? "\u2716" : "\u2714") + " " + document.title; + } + QUnit.done( { failed: config.stats.bad, - passed: passed, + passed: passed, total: config.stats.all, runtime: runtime } ); @@ -794,7 +800,7 @@ function validTest( name ) { return true; } - not = filter.charAt( 0 ) === "!"; + var not = filter.charAt( 0 ) === "!"; if ( not ) { filter = filter.slice( 1 ); } @@ -869,7 +875,7 @@ function process() { function saveGlobal() { config.pollution = []; - + if ( config.noglobals ) { for ( var key in window ) { config.pollution.push( key ); @@ -880,17 +886,15 @@ function saveGlobal() { function checkPollution( name ) { var old = config.pollution; saveGlobal(); - - var newGlobals = diff( old, config.pollution ); + + var newGlobals = diff( config.pollution, old ); if ( newGlobals.length > 0 ) { ok( false, "Introduced global variable(s): " + newGlobals.join(", ") ); - config.current.expected++; } - var deletedGlobals = diff( config.pollution, old ); + var deletedGlobals = diff( old, config.pollution ); if ( deletedGlobals.length > 0 ) { ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") ); - config.current.expected++; } } @@ -968,7 +972,7 @@ QUnit.equiv = function () { } } } - + var callbacks = function () { // for string, boolean, number and null @@ -1022,13 +1026,13 @@ QUnit.equiv = function () { // b could be an object literal here if ( ! (QUnit.objectType(b) === "array")) { return false; - } - + } + len = a.length; if (len !== b.length) { // safe and faster return false; } - + //track reference to avoid circular references parents.push(a); for (i = 0; i < len; i++) { @@ -1061,7 +1065,7 @@ QUnit.equiv = function () { callers.push(a.constructor); //track reference to avoid circular references parents.push(a); - + for (i in a) { // be strict: don't ensures hasOwnProperty and go deep loop = false; for(j=0;j<parents.length;j++){ @@ -1127,7 +1131,7 @@ QUnit.jsDump = (function() { return '"' + str.toString().replace(/"/g, '\\"') + '"'; }; function literal( o ) { - return o + ''; + return o + ''; }; function join( pre, arr, post ) { var s = jsDump.separator(), @@ -1140,21 +1144,21 @@ QUnit.jsDump = (function() { return [ pre, inner + arr, base + post ].join(s); }; function array( arr ) { - var i = arr.length, ret = Array(i); + var i = arr.length, ret = Array(i); this.up(); while ( i-- ) - ret[i] = this.parse( arr[i] ); + ret[i] = this.parse( arr[i] ); this.down(); return join( '[', ret, ']' ); }; - + var reName = /^function (\w+)/; - + var jsDump = { parse:function( obj, type ) { //type is used mostly internally, you can fix a (custom)type in advance var parser = this.parsers[ type || this.typeOf(obj) ]; - type = typeof parser; - + type = typeof parser; + return type == 'function' ? parser.call( this, obj ) : type == 'string' ? parser : this.parsers.error; @@ -1205,7 +1209,7 @@ QUnit.jsDump = (function() { this.parsers[name] = parser; }, // The next 3 are exposed so you can use them - quote:quote, + quote:quote, literal:literal, join:join, // @@ -1224,7 +1228,7 @@ QUnit.jsDump = (function() { if ( name ) ret += ' ' + name; ret += '('; - + ret = [ ret, QUnit.jsDump.parse( fn, 'functionArgs' ), '){'].join(''); return join( ret, QUnit.jsDump.parse(fn,'functionCode'), '}' ); }, @@ -1242,10 +1246,10 @@ QUnit.jsDump = (function() { node:function( node ) { var open = QUnit.jsDump.HTML ? '<' : '<', close = QUnit.jsDump.HTML ? '>' : '>'; - + var tag = node.nodeName.toLowerCase(), ret = open + tag; - + for ( var a in QUnit.jsDump.DOMAttrs ) { var val = node[QUnit.jsDump.DOMAttrs[a]]; if ( val ) @@ -1255,8 +1259,8 @@ QUnit.jsDump = (function() { }, functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function var l = fn.length; - if ( !l ) return ''; - + if ( !l ) return ''; + var args = Array(l); while ( l-- ) args[l] = String.fromCharCode(97+l);//97 is 'a' @@ -1313,34 +1317,34 @@ function getText( elems ) { * * More Info: * http://ejohn.org/projects/javascript-diff-algorithm/ - * + * * Usage: QUnit.diff(expected, actual) - * + * * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over" */ QUnit.diff = (function() { function diff(o, n){ var ns = new Object(); var os = new Object(); - + for (var i = 0; i < n.length; i++) { - if (ns[n[i]] == null) + if (ns[n[i]] == null) ns[n[i]] = { rows: new Array(), o: null }; ns[n[i]].rows.push(i); } - + for (var i = 0; i < o.length; i++) { - if (os[o[i]] == null) + if (os[o[i]] == null) os[o[i]] = { rows: new Array(), n: null }; os[o[i]].rows.push(i); } - + for (var i in ns) { if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) { n[ns[i].rows[0]] = { @@ -1353,7 +1357,7 @@ QUnit.diff = (function() { }; } } - + for (var i = 0; i < n.length - 1; i++) { if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && n[i + 1] == o[n[i].row + 1]) { @@ -1367,7 +1371,7 @@ QUnit.diff = (function() { }; } } - + for (var i = n.length - 1; i > 0; i--) { if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && n[i - 1] == o[n[i].row - 1]) { @@ -1381,20 +1385,20 @@ QUnit.diff = (function() { }; } } - + return { o: o, n: n }; } - + return function(o, n){ o = o.replace(/\s+$/, ''); n = n.replace(/\s+$/, ''); var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/)); var str = ""; - + var oSpace = o.match(/\s+/g); if (oSpace == null) { oSpace = [" "]; @@ -1409,7 +1413,7 @@ QUnit.diff = (function() { else { nSpace.push(" "); } - + if (out.n.length == 0) { for (var i = 0; i < out.o.length; i++) { str += '<del>' + out.o[i] + oSpace[i] + "</del>"; @@ -1421,14 +1425,14 @@ QUnit.diff = (function() { str += '<del>' + out.o[n] + oSpace[n] + "</del>"; } } - + for (var i = 0; i < out.n.length; i++) { if (out.n[i].text == null) { str += '<ins>' + out.n[i] + nSpace[i] + "</ins>"; } else { var pre = ""; - + for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) { pre += '<del>' + out.o[n] + oSpace[n] + "</del>"; } @@ -1436,7 +1440,7 @@ QUnit.diff = (function() { } } } - + return str; }; })(); diff --git a/tests/jquery.simulate.js b/tests/jquery.simulate.js index a88b6cbe4..bb82624d3 100644 --- a/tests/jquery.simulate.js +++ b/tests/jquery.simulate.js @@ -123,10 +123,10 @@ $.extend($.simulate.prototype, { this.simulateEvent(target, "click", coord); }, findCenter: function(el) { - var el = $(this.target), o = el.offset(); + var el = $(this.target), o = el.offset(), d = $(document); return { - x: o.left + el.outerWidth() / 2, - y: o.top + el.outerHeight() / 2 + x: o.left + el.outerWidth() / 2 - d.scrollLeft(), + y: o.top + el.outerHeight() / 2 - d.scrollTop() }; } }); diff --git a/tests/unit/autocomplete/autocomplete_events.js b/tests/unit/autocomplete/autocomplete_events.js index eb009064c..c884733d6 100644 --- a/tests/unit/autocomplete/autocomplete_events.js +++ b/tests/unit/autocomplete/autocomplete_events.js @@ -203,6 +203,7 @@ 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({ @@ -218,5 +219,6 @@ test("blur without selection", function() { start(); }, 50); }); +*/ })(jQuery); diff --git a/tests/unit/button/button_core.js b/tests/unit/button/button_core.js index 5b30aa860..692c40320 100644 --- a/tests/unit/button/button_core.js +++ b/tests/unit/button/button_core.js @@ -67,4 +67,18 @@ test("buttonset", function() { ok( set.children("label:eq(2)").is(".ui-button.ui-corner-right:not(.ui-corner-all)") ); }); +test("buttonset (rtl)", function() { + var parent = $("#radio1").parent(); + // Set to rtl + parent.attr("dir", "rtl"); + + var set = $("#radio1").buttonset(); + ok( set.is(".ui-buttonset") ); + same( set.children(".ui-button").length, 3 ); + same( set.children("input:radio.ui-helper-hidden-accessible").length, 3 ); + ok( set.children("label:eq(0)").is(".ui-button.ui-corner-right:not(.ui-corner-all)") ); + ok( set.children("label:eq(1)").is(".ui-button:not(.ui-corner-all)") ); + ok( set.children("label:eq(2)").is(".ui-button.ui-corner-left:not(.ui-corner-all)") ); +}); + })(jQuery); diff --git a/tests/unit/button/button_tickets.js b/tests/unit/button/button_tickets.js index 79bbfeb5c..9a7ccae43 100644 --- a/tests/unit/button/button_tickets.js +++ b/tests/unit/button/button_tickets.js @@ -20,6 +20,14 @@ test( "#6262 - buttonset not applying ui-corner to invisible elements", function ok( set.find( "label:eq(2)" ).is( ".ui-button.ui-corner-right" ) ); }); +test( "#6711 Checkbox/Radiobutton do not Show Focused State when using Keyboard Navigation", function() { + var check = $( "#check" ).button(), + label = $( "label[for='check']" ); + ok( !label.is( ".ui-state-focus" ) ); + check.focus(); + ok( label.is( ".ui-state-focus" ) ); +}); + test( "#7092 - button creation that requires a matching label does not find label in all cases", function() { var group = $( "<span><label for='t7092a'/><input type='checkbox' id='t7092a'/></span>" ); group.find( "input:checkbox" ).button(); diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index fa346c6c9..d0c2c8c8c 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -49,6 +49,7 @@ <div id="qunit-fixture"> <p><input type="text" id="inp"/><input type="text" id="alt"/><div id="inl"></div></p> + <p><input type="text" id="inp2"/></p> </div> </body> diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js index 84ca2f98e..bf48c9c8a 100644 --- a/tests/unit/datepicker/datepicker_events.js +++ b/tests/unit/datepicker/datepicker_events.js @@ -112,6 +112,11 @@ test('events', function() { inp.val('02/04/2008').datepicker('show'). simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_END}); equals(selectedDate, '', 'Callback close date - ctrl+end'); + + var inp2 = init('#inp2'); + inp2.datepicker().datepicker('option', {onClose: callback}).datepicker('show'); + inp.datepicker('show'); + equals(selectedThis, inp2[0], 'Callback close this'); }); })(jQuery); diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index 8d078f099..7ef977604 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -102,16 +102,19 @@ test('enableDisable', function() { ok(inp.next('img').css('opacity') == 1, 'Enable/disable image - image now enabled'); inp.datepicker('destroy'); // Inline - var inl = init('#inl'); + var inl = init('#inl', {changeYear: true}); var dp = $('.ui-datepicker-inline', inl); ok(!inl.datepicker('isDisabled'), 'Enable/disable inline - initially marked as enabled'); ok(!dp.children().is('.ui-state-disabled'), 'Enable/disable inline - not visually disabled initially'); + ok(!dp.find('select').attr('disabled'), 'Enable/disable inline - form element enabled initially'); inl.datepicker('disable'); ok(inl.datepicker('isDisabled'), 'Enable/disable inline - now marked as disabled'); ok(dp.children().is('.ui-state-disabled'), 'Enable/disable inline - visually disabled'); + ok(dp.find('select').attr('disabled'), 'Enable/disable inline - form element disabled'); inl.datepicker('enable'); ok(!inl.datepicker('isDisabled'), 'Enable/disable inline - now marked as enabled'); ok(!dp.children().is('.ui-state-disabled'), 'Enable/disable inline - not visiually disabled'); + ok(!dp.find('select').attr('disabled'), 'Enable/disable inline - form element enabled'); inl.datepicker('destroy'); }); diff --git a/tests/unit/datepicker/datepicker_tickets.js b/tests/unit/datepicker/datepicker_tickets.js index 7e6dc5f00..d5249f905 100644 --- a/tests/unit/datepicker/datepicker_tickets.js +++ b/tests/unit/datepicker/datepicker_tickets.js @@ -24,4 +24,18 @@ test('beforeShowDay-getDate', function() { inp.datepicker('hide'); }); +test('Ticket 6827: formatDate day of year calculation is wrong during day lights savings time', function(){ + var time = $.datepicker.formatDate("oo", new Date("2010/03/30 12:00:00 CDT")); + equals(time, "089"); +}); + +test('Ticket #7244: date parser does not fail when too many numbers are passed into the date function', function() { + expect(1); + try{ + var date = $.datepicker.parseDate('dd/mm/yy', '18/04/19881'); + }catch(e){ + ok("invalid date detected"); + } +}); + })(jQuery); diff --git a/tests/unit/effects/effects.html b/tests/unit/effects/effects.html new file mode 100644 index 000000000..84fecd9cc --- /dev/null +++ b/tests/unit/effects/effects.html @@ -0,0 +1,76 @@ +<!doctype html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>jQuery UI Core Test Suite</title> + + <script src="../../../jquery-1.5.1.js"></script> + <script> + $.uiBackCompat = false; + </script> + <script src="../../../ui/jquery.effects.core.js"></script> + <script src="../../../ui/jquery.effects.blind.js"></script> + <script src="../../../ui/jquery.effects.bounce.js"></script> + <script src="../../../ui/jquery.effects.clip.js"></script> + <script src="../../../ui/jquery.effects.drop.js"></script> + <script src="../../../ui/jquery.effects.explode.js"></script> + <script src="../../../ui/jquery.effects.fade.js"></script> + <script src="../../../ui/jquery.effects.fold.js"></script> + <script src="../../../ui/jquery.effects.highlight.js"></script> + <script src="../../../ui/jquery.effects.pulsate.js"></script> + <script src="../../../ui/jquery.effects.scale.js"></script> + <script src="../../../ui/jquery.effects.shake.js"></script> + <script src="../../../ui/jquery.effects.slide.js"></script> + <script src="../../../ui/jquery.effects.transfer.js"></script> + + <link rel="stylesheet" href="../../../external/qunit.css"> + <script src="../../../external/qunit.js"></script> + <script src="../../jquery.simulate.js"></script> + <script src="../testsuite.js"></script> + <script src="effects_core.js"></script> + + <script src="../swarminject.js"></script> + + <style type="text/css"> + .hidden { + display: none; + } + .test { + background: #000; + border: 0; + width: 100px; + height: 100px; + } + .testAddBorder { + border: 10px solid #000; + } + .testChildren, + .testChangeBackground { + background: #fff; + } + .test h2 { + font-size: 10px; + } + .testChildren h2 { + font-size: 20px; + } + </style> +</head> +<body> + +<h1 id="qunit-header">jQuery UI Effects Test Suite</h1> +<h2 id="qunit-banner"></h2> +<div id="qunit-testrunner-toolbar"></div> +<h2 id="qunit-userAgent"></h2> +<ol id="qunit-tests"> +</ol> + +<div id="qunit-fixture"> + <div class="hidden test"></div> + <div class="animateClass test"> + <h2>Child Element Test</h2> + </div> +</div> + +</body> +</html> diff --git a/tests/unit/effects/effects_core.js b/tests/unit/effects/effects_core.js new file mode 100644 index 000000000..ed9fbf9ba --- /dev/null +++ b/tests/unit/effects/effects_core.js @@ -0,0 +1,111 @@ +(function($) { + +function present( value, array, message ) { + QUnit.push( jQuery.inArray( value, array ) !== -1 , value, array, message ); +} + +function notPresent( value, array, message ) { + QUnit.push( jQuery.inArray( value, array ) === -1 , value, array, message ); +} + +// minDuration is used for "short" animate tests where we are only concerned about the final +var minDuration = 15, + + // duration is used for "long" animates where we plan on testing properties during animation + duration = 200, + + // mid is used for testing in the "middle" of the "duration" animations + mid = duration / 2; + +module( "effects.core" ); + +$.each( $.effects.effect, function( effect ) { + if ( effect === "transfer" ) { + return; + } + module( "effect."+effect ); + asyncTest( "show/hide", function() { + var hidden = $( "div.hidden" ); + expect( 8 ); + + var count = 0, + test = 0; + + function queueTest( fn ) { + count++; + var point = count; + return function( next ) { + test++; + equal( point, test, "Queue function fired in order" ); + if ( fn ) { + fn(); + } else { + setTimeout( next, minDuration ); + } + }; + } + + hidden.queue( queueTest() ).show( effect, minDuration, queueTest(function() { + equal( hidden.css("display"), "block", "Hidden is shown after .show(\"" +effect+ "\", time)" ); + })).queue( queueTest() ).hide( effect, minDuration, queueTest(function() { + equal( hidden.css("display"), "none", "Back to hidden after .hide(\"" +effect+ "\", time)" ); + })).queue( queueTest(function(next) { + deepEqual( hidden.queue(), ["inprogress"], "Only the inprogress sentinel remains"); + start(); + })); + }); +}); + +module("animateClass"); + +asyncTest( "animateClass works with borderStyle", function() { + var test = $("div.animateClass"), + count = 0; + expect(3); + test.toggleClass("testAddBorder", minDuration, function() { + test.toggleClass("testAddBorder", minDuration, function() { + equal( test.css("borderLeftStyle"), "none", "None border set" ); + start(); + }); + equal( test.css("borderLeftStyle"), "solid", "None border not immedately set" ); + }); + equal( test.css("borderLeftStyle"), "solid", "Solid border immedately set" ); +}); + +asyncTest( "animateClass works with colors", function() { + var test = $("div.animateClass"), + count = 0; + expect(2); + test.toggleClass("testChangeBackground", duration, function() { + present( test.css("backgroundColor"), [ "#ffffff", "#fff", "rgb(255, 255, 255)" ], "Color is final" ); + start(); + }); + setTimeout(function() { + var color = test.css("backgroundColor"); + notPresent( color, [ "#000000", "#ffffff", "#000", "#fff", "rgb(0, 0, 0)", "rgb(255,255,255)" ], + "Color is not endpoints in middle." ); + }, mid); +}); + +asyncTest( "animateClass works with children", function() { + var test = $("div.animateClass"), + h2 = test.find("h2"); + + expect(4); + setTimeout(function() { + notPresent( h2.css("fontSize"), ["10px","20px"], "Font size is neither endpoint when in middle."); + }, mid); + test.toggleClass("testChildren", { children: true, duration: duration, complete: function() { + equal( h2.css("fontSize"), "20px", "Text size is final during complete"); + test.toggleClass("testChildren", duration, function() { + equal( h2.css("fontSize"), "10px", "Text size revertted after class removed"); + + start(); + }); + setTimeout(function() { + equal( h2.css("fontSize"), "20px", "Text size unchanged during animate with children: undefined" ); + }, mid); + }}); +}); + +})(jQuery); diff --git a/tests/unit/index.html b/tests/unit/index.html index a677023dc..5282d3f27 100644 --- a/tests/unit/index.html +++ b/tests/unit/index.html @@ -59,6 +59,11 @@ <li><a href="position/position.html">Position</a></li> </ul> +<h2>Effects</h2> +<ul> + <li><a href="effects/effects.html">Effects</a></li> +</ul> + </body> </html> diff --git a/tests/unit/spinner/spinner_defaults.js b/tests/unit/spinner/spinner_defaults.js index f6081b1f3..c9a7d5f62 100644 --- a/tests/unit/spinner/spinner_defaults.js +++ b/tests/unit/spinner/spinner_defaults.js @@ -4,7 +4,7 @@ commonWidgetTests( "spinner", { incremental: true,
max: null,
min: null,
- numberformat: null,
+ numberFormat: null,
page: 10,
step: null,
value: null,
diff --git a/tests/unit/spinner/spinner_options.js b/tests/unit/spinner/spinner_options.js index 3db7e5c55..398780ad2 100644 --- a/tests/unit/spinner/spinner_options.js +++ b/tests/unit/spinner/spinner_options.js @@ -5,26 +5,26 @@ module("spinner: options");
-test("numberformat, number", function() {
+test("numberFormat, number", function() {
var el = $("#spin").spinner({
value: "1",
- numberformat: "n"
+ numberFormat: "n"
});
equal(el.val(), "1.00");
});
-test("numberformat, number, simple", function() {
+test("numberFormat, number, simple", function() {
var el = $("#spin").spinner({
value: "1",
- numberformat: "n0"
+ numberFormat: "n0"
});
equal(el.val(), "1");
});
-test("numberformat, currency", function() {
+test("numberFormat, currency", function() {
var el = $("#spin").spinner({
value: "1",
- numberformat: "C"
+ numberFormat: "C"
});
equal(el.val(), "$1.00");
});
@@ -111,7 +111,7 @@ test("step, 2", function() { test("step, 0.7", function() {
var el = $("#spin").spinner({
step: 0.7,
- numberformat: "n1"
+ numberFormat: "n1"
});
equals(el.val(), "0.0", "value initialized to");
diff --git a/tests/unit/tabs/tabs.html b/tests/unit/tabs/tabs.html index 34ec28bc4..60f5e972e 100644 --- a/tests/unit/tabs/tabs.html +++ b/tests/unit/tabs/tabs.html @@ -81,16 +81,6 @@ same( actual, expected ); } </script> - <script> - // disable this stale testsuite for testswarm only - var url = window.location.search; - url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) ); - if ( url && url.indexOf("http") == 0 ) { - // reset config to kill previous tests; make sure testsuite.js is loaded afterwards to init the testswarm script - QUnit.init(); - test("tabs", function() { ok(true, "disabled tabs testsuite"); }); - } - </script> <script src="../swarminject.js"></script> </head> <body> diff --git a/tests/unit/tabs/tabs_deprecated.html b/tests/unit/tabs/tabs_deprecated.html index 89d08f4d0..ed6518be3 100644 --- a/tests/unit/tabs/tabs_deprecated.html +++ b/tests/unit/tabs/tabs_deprecated.html @@ -80,16 +80,6 @@ same( actual, expected ); } </script> - <script> - // disable this stale testsuite for testswarm only - var url = window.location.search; - url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) ); - if ( url && url.indexOf("http") == 0 ) { - // reset config to kill previous tests; make sure testsuite.js is loaded afterwards to init the testswarm script - QUnit.init(); - test("tabs", function() { ok(true, "disabled tabs testsuite"); }); - } - </script> <script src="../swarminject.js"></script> </head> <body> diff --git a/tests/unit/tabs/tabs_deprecated.js b/tests/unit/tabs/tabs_deprecated.js index 4b50df405..1323c774a 100644 --- a/tests/unit/tabs/tabs_deprecated.js +++ b/tests/unit/tabs/tabs_deprecated.js @@ -35,7 +35,7 @@ asyncTest( "ajaxOptions", function() { } }); element.one( "tabsload", function( event, ui ) { - equals( ui.panel.html(), "test" ); + equals( $( ui.panel ).html(), "test" ); start(); }); element.tabs( "option", "active", 2 ); @@ -220,6 +220,62 @@ test( "selected", function() { module( "tabs (deprecated): events" ); +asyncTest( "load", function() { + expect( 15 ); + + 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" ); + strictEqual( ui.tab, tab[ 0 ], "tab" ); + strictEqual( ui.panel, 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" ); + strictEqual( ui.tab, tab[ 0 ], "tab" ); + strictEqual( ui.panel, 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" ); + strictEqual( ui.tab, tab[ 0 ], "tab" ); + strictEqual( ui.panel, 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(); + } +}); + test( "enable", function() { expect( 3 ); diff --git a/tests/unit/tabs/tabs_events.js b/tests/unit/tabs/tabs_events.js index 2fabaafca..12c9bb87b 100644 --- a/tests/unit/tabs/tabs_events.js +++ b/tests/unit/tabs/tabs_events.js @@ -209,66 +209,68 @@ test( "beforeLoad", function() { equals( panel.html(), "<p>testing</p>", "panel html after" ); }); -asyncTest( "load", function() { - expect( 21 ); +if ( $.uiBackCompat === false ) { + 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 }); + var tab, panelId, panel, + element = $( "#tabs2" ); - function tabsload1() { - // .option() + // init element.one( "tabsload", function( event, ui ) { - tab = element.find( ".ui-tabs-nav a" ).eq( 3 ); + 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, 0, 1, 0 ); - tabsload2(); + tabs_state( element, 0, 0, 1, 0, 0 ); + tabsload1(); }); - element.tabs( "option", "active", 3 ); - } + element.tabs({ active: 2 }); - 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 ); + 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 ); - 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(); - } -}); + 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 221b0d39d..ec21e2de7 100644 --- a/tests/unit/tabs/tabs_methods.js +++ b/tests/unit/tabs/tabs_methods.js @@ -145,8 +145,93 @@ test( "refresh", function() { tabs_disabled( element, false ); }); -test('load', function() { - ok(false, "missing test - untested code is broken code."); +asyncTest( "load", function() { + expect( 30 ); + + var element = $( "#tabs2" ).tabs(); + + // load content of inactive tab + // useful for preloading content with custom caching + element.one( "tabsbeforeload", function( event, ui ) { + var 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" ); + tabs_state( element, 1, 0, 0, 0, 0 ); + }); + element.one( "tabsload", function( event, ui ) { + // TODO: remove wrapping in 2.0 + var uiTab = $( ui.tab ), + uiPanel = $( ui.panel ); + + var tab = element.find( ".ui-tabs-nav a" ).eq( 3 ), + panelId = tab.attr( "aria-controls" ), + panel = $( "#" + panelId ); + + ok( !( "originalEvent" in event ), "originalEvent" ); + equals( uiTab.size(), 1, "tab size" ); + strictEqual( uiTab[ 0 ], tab[ 0 ], "tab" ); + equals( uiPanel.size(), 1, "panel size" ); + strictEqual( uiPanel[ 0 ], panel[ 0 ], "panel" ); + equals( uiPanel.find( "p" ).length, 1, "panel html" ); + tabs_state( element, 1, 0, 0, 0, 0 ); + setTimeout( tabsload1, 1 ); + }); + element.tabs( "load", 3 ); + tabs_state( element, 1, 0, 0, 0, 0 ); + + function tabsload1() { + // no need to test details of event (tested in events tests) + element.one( "tabsbeforeload", function() { + ok( true, "tabsbeforeload invoked" ); + }); + element.one( "tabsload", function() { + ok( true, "tabsload invoked" ); + setTimeout( tabsload2, 1 ); + }); + element.tabs( "option", "active", 3 ); + tabs_state( element, 0, 0, 0, 1, 0 ); + } + + function tabsload2() { + // reload content of active tab + element.one( "tabsbeforeload", function( event, ui ) { + var 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" ); + tabs_state( element, 0, 0, 0, 1, 0 ); + }); + element.one( "tabsload", function( event, ui ) { + // TODO: remove wrapping in 2.0 + var uiTab = $( ui.tab ), + uiPanel = $( ui.panel ); + + var tab = element.find( ".ui-tabs-nav a" ).eq( 3 ), + panelId = tab.attr( "aria-controls" ), + panel = $( "#" + panelId ); + + ok( !( "originalEvent" in event ), "originalEvent" ); + equals( uiTab.size(), 1, "tab size" ); + strictEqual( uiTab[ 0 ], tab[ 0 ], "tab" ); + equals( uiPanel.size(), 1, "panel size" ); + strictEqual( uiPanel[ 0 ], panel[ 0 ], "panel" ); + tabs_state( element, 0, 0, 0, 1, 0 ); + start(); + }); + element.tabs( "load", 3 ); + tabs_state( element, 0, 0, 0, 1, 0 ); + } }); }( jQuery ) ); diff --git a/tests/unit/testsuite.js b/tests/unit/testsuite.js index c1f394ed9..3d9e64d60 100644 --- a/tests/unit/testsuite.js +++ b/tests/unit/testsuite.js @@ -61,7 +61,7 @@ window.commonWidgetTests = function( widget, settings ) { testWidgetOverrides( widget ); testBasicUsage( widget ); test( "version", function() { - ok( "version" in $.ui[ widget ], "version property exists" ); + ok( "version" in $.ui[ widget ].prototype, "version property exists" ); }); } diff --git a/tests/unit/tooltip/tooltip.html b/tests/unit/tooltip/tooltip.html index 189c75261..21eff51fd 100644 --- a/tests/unit/tooltip/tooltip.html +++ b/tests/unit/tooltip/tooltip.html @@ -1,30 +1,29 @@ -<!DOCTYPE html> +<!doctype html> <html lang="en"> <head> - <meta charset="UTF-8" /> + <meta charset="utf-8"> <title>jQuery UI Tooltip Test Suite</title> - <link type="text/css" href="../../../themes/base/jquery.ui.tooltip.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.position.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.tooltip.js"></script> - - <link rel="stylesheet" href="../../../external/qunit.css" type="text/css"/> - <script type="text/javascript" src="../../../external/qunit.js"></script> - <script type="text/javascript" src="../../jquery.simulate.js"></script> - <script type="text/javascript" src="../testsuite.js"></script> - - <script type="text/javascript" src="tooltip_core.js"></script> - <script type="text/javascript" src="tooltip_defaults.js"></script> - <script type="text/javascript" src="tooltip_events.js"></script> - <script type="text/javascript" src="tooltip_methods.js"></script> - <script type="text/javascript" src="tooltip_options.js"></script> - - <script type="text/javascript" src="../swarminject.js"></script> - + <link rel="stylesheet" href="../../../themes/base/jquery.ui.tooltip.css"> + + <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.tooltip.js"></script> + + <link rel="stylesheet" href="../../../external/qunit.css"> + <script src="../../../external/qunit.js"></script> + <script src="../../jquery.simulate.js"></script> + <script src="../testsuite.js"></script> + + <script src="tooltip_defaults.js"></script> + <script src="tooltip_core.js"></script> + <script src="tooltip_events.js"></script> + <script src="tooltip_methods.js"></script> + <script src="tooltip_options.js"></script> + + <script src="../swarminject.js"></script> </head> <body> @@ -32,16 +31,15 @@ <h2 id="qunit-banner"></h2> <div id="qunit-testrunner-toolbar"></div> <h2 id="qunit-userAgent"></h2> -<ol id="qunit-tests"> -</ol> - +<ol id="qunit-tests"></ol> <div id="qunit-fixture"> - <div> - <a id="tooltipped1" href="#" title="anchortitle">anchor</a> - <input title="inputtitle" /> - <span id="fixture-span" data-tooltip="text">span</span> - </div> + +<div> + <a id="tooltipped1" href="#" title="anchortitle">anchor</a> + <input title="inputtitle"> + <span id="fixture-span" title="title-text">span</span> </div> +</div> </body> </html> diff --git a/tests/unit/tooltip/tooltip_core.js b/tests/unit/tooltip/tooltip_core.js index 247927df4..d18b85398 100644 --- a/tests/unit/tooltip/tooltip_core.js +++ b/tests/unit/tooltip/tooltip_core.js @@ -1,11 +1,26 @@ -/* - * tooltip_core.js - */ +(function( $ ) { +module( "tooltip: core" ); -(function($) { +test( "markup structure", function() { + expect( 6 ); + var element = $( "#tooltipped1" ).tooltip(), + tooltip = $( ".ui-tooltip" ); -module("tooltip: core"); + equal( element.attr( "aria-describedby" ), undefined, "no aria-describedby on init" ); + equal( tooltip.length, 0, "no tooltip on init" ); + element.tooltip( "open" ); + tooltip = $( "#" + element.attr( "aria-describedby" ) ); + equal( tooltip.length, 1, "tooltip exists" ); + ok( tooltip.hasClass( "ui-tooltip" ), "tooltip is .ui-tooltip" ); + equal( tooltip.length, 1, ".ui-tooltip exists" ); + equal( tooltip.find( ".ui-tooltip-content" ).length, 1, + ".ui-tooltip-content exists" ); +}); -})(jQuery); +test( "accessibility", function() { + // TODO: add tests +}); + +}( jQuery ) ); diff --git a/tests/unit/tooltip/tooltip_defaults.js b/tests/unit/tooltip/tooltip_defaults.js index 5f304f497..4b687bdcb 100644 --- a/tests/unit/tooltip/tooltip_defaults.js +++ b/tests/unit/tooltip/tooltip_defaults.js @@ -1,15 +1,20 @@ commonWidgetTests( "tooltip", { defaults: { + content: function() {}, disabled: false, + hide: true, items: "[title]", - content: $.ui.tooltip.prototype.options.content, position: { my: "left+15 center", - at: "right center" + at: "right center", + collision: "flip fit" }, + show: true, tooltipClass: null, // callbacks - create: null + close: null, + create: null, + open: null } }); diff --git a/tests/unit/tooltip/tooltip_events.js b/tests/unit/tooltip/tooltip_events.js index 5c915ae30..29220705f 100644 --- a/tests/unit/tooltip/tooltip_events.js +++ b/tests/unit/tooltip/tooltip_events.js @@ -1,54 +1,81 @@ -/* - * tooltip_events.js - */ -(function($) { - -module("tooltip: events"); - -test("programmatic triggers", function() { - expect(2); - var e = $("#tooltipped1").tooltip({ - open: function(event, ui) { - same( event.type, "tooltipopen" ); - }, - close: function(event, ui) { - same( event.type, "tooltipclose" ); - } - }); - e.tooltip("open").tooltip("close"); - e.tooltip("destroy"); +(function( $ ) { + +module( "tooltip: events" ); + +test( "programmatic triggers", function() { + expect( 4 ); + var tooltip, + element = $( "#tooltipped1" ).tooltip(); + + element.one( "tooltipopen", function( event, ui ) { + tooltip = ui.tooltip; + ok( !( "originalEvent" in event ), "open" ); + strictEqual( ui.tooltip[0], + $( "#" + element.attr( "aria-describedby" ) )[0], "ui.tooltip" ); + }); + element.tooltip( "open" ); + + element.one( "tooltipclose", function( event, ui ) { + ok( !( "originalEvent" in event ), "close" ); + strictEqual( ui.tooltip[0], tooltip[0], "ui.tooltip" ); + }); + element.tooltip( "close" ); +}); + +test( "mouse events", function() { + expect( 2 ); + var element = $( "#tooltipped1" ).tooltip(); + + element.one( "tooltipopen", function( event ) { + same( event.originalEvent.type, "mouseover" ); + }); + element.trigger( "mouseover" ); + + element.one( "tooltipclose", function( event ) { + same( event.originalEvent.type, "mouseleave" ); + }); + element.trigger( "mouseleave" ); }); -test("mouse events", function() { - expect(4); - var e = $("#tooltipped1").tooltip({ - open: function(event, ui) { - same( event.type, "tooltipopen" ); - same( event.originalEvent.type, "mouseover" ); - }, - close: function(event, ui) { - same( event.type, "tooltipclose" ); - same( event.originalEvent.type, "mouseleave" ); - } - }); - e.trigger("mouseover").trigger("mouseleave"); - e.tooltip("destroy"); +test( "focus events", function() { + expect( 2 ); + var element = $( "#tooltipped1" ).tooltip(); + + element.one( "tooltipopen", function( event ) { + same( event.originalEvent.type, "focusin" ); + }); + element.trigger( "focusin" ); + + element.one( "tooltipclose", function( event ) { + same( event.originalEvent.type, "blur" ); + }); + element.trigger( "blur" ); }); -test("focus events", function() { - expect(4); - var e = $("#tooltipped1").tooltip({ - open: function(event, ui) { - same( event.type, "tooltipopen" ); - same( event.originalEvent.type, "focusin" ); - }, - close: function(event, ui) { - same( event.type, "tooltipclose" ); - same( event.originalEvent.type, "blur" ); - } - }); - e.trigger("focus").trigger("blur"); - e.tooltip("destroy"); +test( "mixed events", function() { + expect( 2 ); + var element = $( "#tooltipped1" ).tooltip(); + + element.one( "tooltipopen", function( event ) { + same( event.originalEvent.type, "focusin" ); + }); + element[0].focus(); + + element.one( "tooltipopen", function() { + ok( false, "open triggered while already open" ); + }); + element.trigger( "mouseover" ); + + element.bind( "tooltipclose", function( event ) { + ok( false, "close triggered while still focused" ); + }); + element.trigger( "mouseleave" ); + element.unbind( "tooltipclose" ); + + element.one( "tooltipclose", function( event ) { + same( event.originalEvent.type, "blur" ); + }); + element[0].blur(); }); -})(jQuery); +}( jQuery ) ); diff --git a/tests/unit/tooltip/tooltip_methods.js b/tests/unit/tooltip/tooltip_methods.js index 496a5fdb7..798d55896 100644 --- a/tests/unit/tooltip/tooltip_methods.js +++ b/tests/unit/tooltip/tooltip_methods.js @@ -1,22 +1,57 @@ -/* - * tooltip_methods.js - */ -(function($) { +(function( $ ) { +module( "tooltip: methods" ); -module("tooltip: methods"); +test( "destroy", function() { + expect( 2 ); + domEqual( "#tooltipped1", function() { + $( "#tooltipped1" ).tooltip().tooltip( "destroy" ); + }); -test("destroy", function() { - var beforeHtml = $("#tooltipped1").parent().html(); - var afterHtml = $("#tooltipped1").tooltip().tooltip("destroy").parent().html(); - equal( afterHtml, beforeHtml ); + // make sure that open tooltips are removed on destroy + $( "#tooltipped1" ).tooltip().tooltip( "open" ).tooltip( "destroy" ); + equal( $( ".ui-tooltip" ).length, 0 ); }); -test("open", function() { - var e = $("#tooltipped1").tooltip(); - e.tooltip("open"); - ok( $(".ui-tooltip").is(":visible") ); - $(":ui-tooltip").tooltip("destroy"); +test( "open/close", function() { + expect( 3 ); + $.fx.off = true; + var element = $( "#tooltipped1" ).tooltip(); + equal( $( ".ui-tooltip" ).length, 0, "no tooltip on init" ); + + element.tooltip( "open" ); + var tooltip = $( "#" + element.attr( "aria-describedby" ) ); + ok( tooltip.is( ":visible" ) ); + + element.tooltip( "close" ); + ok( tooltip.is( ":hidden" ) ); + $.fx.off = false; +}); + +test( "enable/disable", function() { + expect( 7 ); + $.fx.off = true; + var element = $( "#tooltipped1" ).tooltip(); + equal( $( ".ui-tooltip" ).length, 0, "no tooltip on init" ); + + element.tooltip( "open" ); + var tooltip = $( "#" + element.attr( "aria-describedby" ) ); + ok( tooltip.is( ":visible" ) ); + + element.tooltip( "disable" ); + equal( $( ".ui-tooltip" ).length, 0, "no tooltip when disabled" ); + equal( tooltip.attr( "title" ), "", "title removed on disable" ); + + element.tooltip( "open" ); + equal( $( ".ui-tooltip" ).length, 0, "open does nothing when disabled" ); + + element.tooltip( "enable" ); + equal( element.attr( "title" ), "anchortitle", "title restored on enable" ); + + element.tooltip( "open" ); + tooltip = $( "#" + element.attr( "aria-describedby" ) ); + ok( tooltip.is( ":visible" ) ); + $.fx.off = false; }); /* @@ -29,5 +64,4 @@ test("widget", function() { }); */ - -})(jQuery); +}( jQuery ) ); diff --git a/tests/unit/tooltip/tooltip_options.js b/tests/unit/tooltip/tooltip_options.js index 37a468489..04bb4c6a4 100644 --- a/tests/unit/tooltip/tooltip_options.js +++ b/tests/unit/tooltip/tooltip_options.js @@ -1,66 +1,73 @@ -/* - * tooltip_options.js - */ -(function($) { - -module("tooltip: options", { - teardown: function() { - $(":ui-tooltip").tooltip("destroy"); - } -}); +(function( $ ) { +module( "tooltip: options" ); -test("option: items", function() { - var event = $.Event("mouseenter"); - event.target = $("[data-tooltip]"); - $("#qunit-fixture").tooltip({ - items: "[data-tooltip]", - content: function() { - return $(this).attr("data-tooltip"); - } - }).tooltip("open", event); - same( $( "#" + $("#fixture-span").attr("aria-describedby") ).text(), "text" ); +test( "content: default", function() { + var element = $( "#tooltipped1" ).tooltip().tooltip( "open" ); + same( $( "#" + element.attr( "aria-describedby" ) ).text(), "anchortitle" ); }); -test("content: default", function() { - $("#tooltipped1").tooltip().tooltip("open"); - same( $( "#" + $("#tooltipped1").attr("aria-describedby") ).text(), "anchortitle" ); -}); - -test("content: return string", function() { - $("#tooltipped1").tooltip({ +test( "content: return string", function() { + var element = $( "#tooltipped1" ).tooltip({ content: function() { return "customstring"; } - }).tooltip("open"); - same( $( "#" + $("#tooltipped1").attr("aria-describedby") ).text(), "customstring" ); + }).tooltip( "open" ); + same( $( "#" + element.attr( "aria-describedby" ) ).text(), "customstring" ); }); -test("content: return jQuery", function() { - $("#tooltipped1").tooltip({ +test( "content: return jQuery", function() { + var element = $( "#tooltipped1" ).tooltip({ content: function() { - return $("<div></div>").html("cu<b>s</b>tomstring"); + return $( "<div>" ).html( "cu<b>s</b>tomstring" ); } - }).tooltip("open"); - same( $( "#" + $("#tooltipped1").attr("aria-describedby") ).text(), "customstring" ); + }).tooltip( "open" ); + same( $( "#" + element.attr( "aria-describedby" ) ).text(), "customstring" ); }); -/* -TODO broken, probably related to async content -test("content: callback string", function() { - stop(); - $("#tooltipped1").tooltip({ - content: function(response) { - response("customstring2"); +asyncTest( "content: sync + async callback", function() { + expect( 2 ); + var element = $( "#tooltipped1" ).tooltip({ + content: function( response ) { setTimeout(function() { - //console.log($("#tooltipped1").attr("aria-describedby")) - same( $( "#" + $("#tooltipped1").attr("aria-describedby") ).text(), "customstring2" ); - start(); - }, 100) + same( $( "#" + element.attr("aria-describedby") ).text(), "loading..." ); + + response( "customstring2" ); + setTimeout(function() { + same( $( "#" + element.attr("aria-describedby") ).text(), "customstring2" ); + start(); + }, 13 ); + }, 13 ); + return "loading..."; } - }).tooltip("open"); - + }).tooltip( "open" ); +}); + +test( "items", function() { + expect( 2 ); + var element = $( "#qunit-fixture" ).tooltip({ + items: "#fixture-span" + }); + + var event = $.Event( "mouseenter" ); + event.target = $( "#fixture-span" )[ 0 ]; + element.tooltip( "open", event ); + same( $( "#" + $( "#fixture-span" ).attr( "aria-describedby" ) ).text(), "title-text" ); + + // make sure default [title] doesn't get used + event.target = $( "#tooltipped1" )[ 0 ]; + element.tooltip( "open", event ); + same( $( "#tooltipped1" ).attr( "aria-describedby" ), undefined ); + + element.tooltip( "destroy" ); +}); + +test( "tooltipClass", function() { + expect( 1 ) + var element = $( "#tooltipped1" ).tooltip({ + tooltipClass: "custom" + }).tooltip( "open" ); + ok( $( "#" + element.attr( "aria-describedby" ) ).hasClass( "custom" ) ); }); -*/ -})(jQuery); +}( jQuery ) ); diff --git a/tests/unit/widget/widget.html b/tests/unit/widget/widget.html index e74abb317..b06aa19f8 100644 --- a/tests/unit/widget/widget.html +++ b/tests/unit/widget/widget.html @@ -14,6 +14,8 @@ <script src="../testsuite.js"></script> <script src="widget_core.js"></script> + <script src="widget_extend.js"></script> + <script src="widget_animation.js"></script> <script src="../swarminject.js"></script> </head> diff --git a/tests/unit/widget/widget_animation.js b/tests/unit/widget/widget_animation.js new file mode 100644 index 000000000..8ef55aa11 --- /dev/null +++ b/tests/unit/widget/widget_animation.js @@ -0,0 +1,257 @@ + +module( "widget animation", (function() { + var show = $.fn.show, + fadeIn = $.fn.fadeIn, + slideDown = $.fn.slideDown; + return { + setup: function() { + $.widget( "ui.testWidget", { + _create: function() { + this.element.hide(); + }, + show: function( fn ) { + this._show( this.element, this.options.show, fn ); + } + }); + $.effects = { effect: { testEffect: $.noop } }; + }, + teardown: function() { + delete $.ui.testWidget; + delete $.effects.effect.testEffect; + $.fn.show = show; + $.fn.fadeIn = fadeIn; + $.fn.slideDown = slideDown; + } + }; +}())); + +asyncTest( "show: null", function() { + expect( 4 ); + + var element = $( "#widget" ).testWidget(), + hasRun = false; + $.fn.show = function() { + ok( true, "show called" ); + equal( arguments.length, 0, "no args passed to show" ); + }; + + element + .delay( 50 ) + .queue(function( next ) { + ok( !hasRun, "queue before show" ); + next(); + }) + .testWidget( "show", function() { + hasRun = true; + }) + .queue(function( next ) { + ok( hasRun, "queue after show" ); + start(); + next(); + }); +}); + +asyncTest( "show: true", function() { + expect( 4 ); + + var element = $( "#widget" ).testWidget({ + show: true + }), + hasRun = false; + $.fn.fadeIn = function( duration, easing, complete ) { + return this.queue(function( next ) { + strictEqual( duration, undefined, "duration" ); + strictEqual( easing, undefined, "easing" ); + complete(); + next(); + }); + }; + + element + .delay( 50 ) + .queue(function( next ) { + ok( !hasRun, "queue before show" ); + next(); + }) + .testWidget( "show", function() { + hasRun = true; + }) + .queue(function( next ) { + ok( hasRun, "queue after show" ); + start(); + next(); + }); +}); + +asyncTest( "show: number", function() { + expect( 4 ); + + var element = $( "#widget" ).testWidget({ + show: 123 + }), + hasRun = false; + $.fn.fadeIn = function( duration, easing, complete ) { + return this.queue(function( next ) { + strictEqual( duration, 123, "duration" ); + strictEqual( easing, undefined, "easing" ); + complete(); + next(); + }); + }; + + element + .delay( 50 ) + .queue(function( next ) { + ok( !hasRun, "queue before show" ); + next(); + }) + .testWidget( "show", function() { + hasRun = true; + }) + .queue(function( next ) { + ok( hasRun, "queue after show" ); + start(); + next(); + }); +}); + +asyncTest( "show: core animation", function() { + expect( 4 ); + + var element = $( "#widget" ).testWidget({ + show: "slideDown" + }), + hasRun = false; + $.fn.slideDown = function( duration, easing, complete ) { + return this.queue(function( next ) { + strictEqual( duration, undefined, "duration" ); + strictEqual( easing, undefined, "easing" ); + complete(); + next(); + }); + }; + + element + .delay( 50 ) + .queue(function( next ) { + ok( !hasRun, "queue before show" ); + next(); + }) + .testWidget( "show", function() { + hasRun = true; + }) + .queue(function( next ) { + ok( hasRun, "queue after show" ); + start(); + next(); + }); +}); + +asyncTest( "show: effect", function() { + expect( 5 ); + + var element = $( "#widget" ).testWidget({ + show: "testEffect" + }), + hasRun = false; + $.fn.show = function( options ) { + return this.queue(function( next ) { + equal( options.effect, "testEffect", "effect" ); + ok( !("duration" in options), "duration" ); + ok( !("easing" in options), "easing" ); + options.complete(); + next(); + }); + }; + + element + .delay( 50 ) + .queue(function( next ) { + ok( !hasRun, "queue before show" ); + next(); + }) + .testWidget( "show", function() { + hasRun = true; + }) + .queue(function( next ) { + ok( hasRun, "queue after show" ); + start(); + next(); + }); +}); + +asyncTest( "show: object(core animation)", function() { + expect( 4 ); + + var element = $( "#widget" ).testWidget({ + show: { + effect: "slideDown", + duration: 123, + easing: "testEasing" + } + }), + hasRun = false; + $.fn.slideDown = function( duration, easing, complete ) { + return this.queue(function( next ) { + equal( duration, 123, "duration" ); + equal( easing, "testEasing", "easing" ); + complete(); + next(); + }); + }; + + element + .delay( 50 ) + .queue(function( next ) { + ok( !hasRun, "queue before show" ); + next(); + }) + .testWidget( "show", function() { + hasRun = true; + }) + .queue(function( next ) { + ok( hasRun, "queue after show" ); + start(); + next(); + }); +}); + +asyncTest( "show: object(effect)", function() { + expect( 3 ); + + var element = $( "#widget" ).testWidget({ + show: { + effect: "testEffect", + duration: 123, + easing: "testEasing" + } + }), + hasRun = false; + $.fn.show = function( options ) { + return this.queue(function( next ) { + deepEqual( options, { + effect: "testEffect", + duration: 123, + easing: "testEasing", + complete: options.complete + }); + options.complete(); + next(); + }); + }; + + element + .delay( 50 ) + .queue(function( next ) { + ok( !hasRun, "queue before show" ); + next(); + }) + .testWidget( "show", function() { + hasRun = true; + }) + .queue(function( next ) { + ok( hasRun, "queue after show" ); + start(); + next(); + }); +}); diff --git a/tests/unit/widget/widget_core.js b/tests/unit/widget/widget_core.js index b1c27b104..40fd97ba5 100644 --- a/tests/unit/widget/widget_core.js +++ b/tests/unit/widget/widget_core.js @@ -413,6 +413,7 @@ test( ".option() - getter", function() { qux: [ "quux", "quuux" ] }); + same( div.testWidget( "option", "x" ), null, "non-existent option" ); same( div.testWidget( "option", "foo"), "bar", "single option - string" ); same( div.testWidget( "option", "baz"), 5, "single option - number" ); same( div.testWidget( "option", "qux"), [ "quux", "quuux" ], @@ -431,6 +432,24 @@ test( ".option() - getter", function() { "modifying returned options hash does not modify plugin instance" ); }); +test( ".option() - deep option getter", function() { + $.widget( "ui.testWidget", {} ); + var div = $( "<div>" ).testWidget({ + foo: { + bar: "baz", + qux: { + quux: "xyzzy" + } + } + }); + equal( div.testWidget( "option", "foo.bar" ), "baz", "one level deep - string" ); + deepEqual( div.testWidget( "option", "foo.qux" ), { quux: "xyzzy" }, + "one level deep - object" ); + equal( div.testWidget( "option", "foo.qux.quux" ), "xyzzy", "two levels deep - string" ); + equal( div.testWidget( "option", "x.y" ), null, "top level non-existent" ); + equal( div.testWidget( "option", "foo.x.y" ), null, "one level deep - non-existent" ); +}); + test( ".option() - delegate to ._setOptions()", function() { var calls = []; $.widget( "ui.testWidget", { 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/themes/base/jquery.ui.resizable.css b/themes/base/jquery.ui.resizable.css index 2c1de870e..ed6395230 100644 --- a/themes/base/jquery.ui.resizable.css +++ b/themes/base/jquery.ui.resizable.css @@ -8,12 +8,7 @@ * http://docs.jquery.com/UI/Resizable#theming */ .ui-resizable { position: relative;} -.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; - /* http://bugs.jqueryui.com/ticket/7233 - - Resizable: resizable handles fail to work in IE if transparent and content overlaps - */ - background-image:url(data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=); -} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } diff --git a/themes/base/jquery.ui.tabs.css b/themes/base/jquery.ui.tabs.css index d4c039f30..b6429cf72 100644 --- a/themes/base/jquery.ui.tabs.css +++ b/themes/base/jquery.ui.tabs.css @@ -9,9 +9,9 @@ */ .ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ .ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } -.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 0; margin: 1px .2em 0 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } .ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } -.ui-tabs .ui-tabs-nav li.ui-tabs-active { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-active { margin-bottom: -1px; padding-bottom: 1px; } .ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; } .ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ .ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } diff --git a/themes/base/jquery.ui.theme.css b/themes/base/jquery.ui.theme.css index 7d4398465..be2676909 100644 --- a/themes/base/jquery.ui.theme.css +++ b/themes/base/jquery.ui.theme.css @@ -237,16 +237,11 @@ ----------------------------------*/ /* Corner radius */ -.ui-corner-tl { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; } -.ui-corner-tr { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; } -.ui-corner-bl { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; } -.ui-corner-br { -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; } -.ui-corner-top { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; } -.ui-corner-bottom { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; } -.ui-corner-right { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; } -.ui-corner-left { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; } -.ui-corner-all { -moz-border-radius: 4px/*{cornerRadius}*/; -webkit-border-radius: 4px/*{cornerRadius}*/; border-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; -khtml-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; -khtml-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; } /* Overlays */ .ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityOverlay}*/; } -.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; border-radius: 8px/*{cornerRadiusShadow}*/; }
\ No newline at end of file +.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -khtml-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; border-radius: 8px/*{cornerRadiusShadow}*/; }
\ No newline at end of file diff --git a/ui/jquery.effects.blind.js b/ui/jquery.effects.blind.js index 7a59d8a75..8ef544faa 100644 --- a/ui/jquery.effects.blind.js +++ b/ui/jquery.effects.blind.js @@ -31,7 +31,12 @@ $.effects.effect.blind = function( o ) { animation = {}, wrapper, distance; - $.effects.save( el, props ); + // if already wrapped, the wrapper's properties are my property. #6245 + if ( el.parent().is( ".ui-effects-wrapper" ) ) { + $.effects.save( el.parent(), props ); + } else { + $.effects.save( el, props ); + } el.show(); wrapper = $.effects.createWrapper( el ).css({ overflow: "hidden" diff --git a/ui/jquery.effects.bounce.js b/ui/jquery.effects.bounce.js index bb386a4f4..9e1117ce9 100644 --- a/ui/jquery.effects.bounce.js +++ b/ui/jquery.effects.bounce.js @@ -79,10 +79,8 @@ $.effects.effect.bounce = function(o) { 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 ); + .animate( downAnim, speed, easing ); distance = hide ? distance * 2 : distance / 2; } @@ -92,24 +90,25 @@ $.effects.effect.bounce = function(o) { upAnim = { opacity: 0 }; upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; - el.animate( upAnim, speed, easing, function(){ - el.hide(); - finish(); - }); + el.animate( upAnim, speed, easing ); } - - function finish() { + + el.queue( function( next ) { + if ( hide ) { + el.hide(); + } $.effects.restore( el, props ); $.effects.removeWrapper( el ); if ( o.complete ) { o.complete.apply( el[ 0 ] ); } - } + next(); + }); // 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 ) ) ); + [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); } next(); diff --git a/ui/jquery.effects.core.js b/ui/jquery.effects.core.js index 581fb0861..7650aa8f4 100644 --- a/ui/jquery.effects.core.js +++ b/ui/jquery.effects.core.js @@ -20,8 +20,8 @@ $.effects = { /******************************************************************************/ // override the animation for color styles -$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', - 'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'], +$.each(["backgroundColor", "borderBottomColor", "borderLeftColor", + "borderRightColor", "borderTopColor", "borderColor", "color", "outlineColor"], function(i, attr) { $.fx.step[attr] = function(fx) { if (!fx.colorInit) { @@ -30,10 +30,10 @@ function(i, attr) { fx.colorInit = true; } - fx.elem.style[attr] = 'rgb(' + - Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' + - Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' + - Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')'; + fx.elem.style[attr] = "rgb(" + + Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + "," + + Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + "," + + Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ")"; }; }); @@ -46,7 +46,7 @@ function getRGB(color) { var result; // Check if we're already dealing with an array of colors - if ( color && color.constructor == Array && color.length == 3 ) + if ( color && color.constructor === Array && color.length === 3 ) return color; // Look for rgb(num,num,num) @@ -67,7 +67,7 @@ function getRGB(color) { // Look for rgba(0, 0, 0, 0) == transparent in Safari 3 if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) - return colors['transparent']; + return colors["transparent"]; // Otherwise, we're most likely dealing with a named color return colors[$.trim(color).toLowerCase()]; @@ -80,7 +80,7 @@ function getColor(elem, attr) { color = $.curCSS(elem, attr); // Keep going until we find an element that has color, or we hit the body - if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") ) + if ( color != "" && color !== "transparent" || $.nodeName(elem, "body") ) break; attr = "backgroundColor"; @@ -146,7 +146,7 @@ var colors = { /****************************** CLASS ANIMATIONS ******************************/ /******************************************************************************/ -var classAnimationActions = [ 'add', 'remove', 'toggle' ], +var classAnimationActions = [ "add", "remove", "toggle" ], shorthandStyles = { border: 1, borderBottom: 1, @@ -157,7 +157,18 @@ var classAnimationActions = [ 'add', 'remove', 'toggle' ], borderWidth: 1, margin: 1, padding: 1 + }, + // prefix used for storing data on .data() + dataSpace = "ec.storage."; + +$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function(_, prop) { + $.fx.step[ prop ] = function( fx ) { + if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { + jQuery.style( fx.elem, prop, fx.end ); + fx.setAttr = true; + } }; +}); function getElementStyles() { var style = document.defaultView @@ -173,55 +184,34 @@ function getElementStyles() { len = style.length; while ( len-- ) { key = style[ len ]; - if ( typeof style[ key ] == 'string' ) { - camelCase = key.replace( /\-(\w)/g, function( all, letter ) { - return letter.toUpperCase(); - }); - newStyle[ camelCase ] = style[ key ]; + if ( typeof style[ key ] === "string" ) { + newStyle[ $.camelCase( key ) ] = style[ key ]; } } } else { for ( key in style ) { - if ( typeof style[ key ] === 'string' ) { + if ( typeof style[ key ] === "string" ) { newStyle[ key ] = style[ key ]; } } } - + return newStyle; } -function filterStyles( styles ) { - var name, value; - for ( name in styles ) { - value = styles[ name ]; - if ( - // ignore null and undefined values - value == null || - // ignore functions (when does this occur?) - $.isFunction( value ) || - // shorthand styles that need to be expanded - name in shorthandStyles || - // ignore scrollbars (break in IE) - ( /scrollbar/ ).test( name ) || - - // only colors or values that can be converted to numbers - ( !( /color/i ).test( name ) && isNaN( parseFloat( value ) ) ) - ) { - delete styles[ name ]; - } - } - - return styles; -} function styleDifference( oldStyle, newStyle ) { - var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459 - name; + var diff = {}, + name, value; for ( name in newStyle ) { - if ( oldStyle[ name ] != newStyle[ name ] ) { - diff[ name ] = newStyle[ name ]; + value = newStyle[ name ]; + if ( oldStyle[ name ] != value ) { + if ( !shorthandStyles[ name ] ) { + if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { + diff[ name ] = value; + } + } } } @@ -229,48 +219,77 @@ function styleDifference( oldStyle, newStyle ) { } $.effects.animateClass = function( value, duration, easing, callback ) { - if ( $.isFunction( easing ) ) { - callback = easing; - easing = null; - } - - return this.queue(function() { - var that = $( this ), - originalStyleAttr = that.attr( 'style' ) || ' ', - originalStyle = filterStyles( getElementStyles.call( this ) ), - newStyle, - className = that.attr( 'class' ); + var o = $.speed( duration, easing, callback ); + + return this.queue( function() { + var animated = $( this ), + baseClass = animated.attr( "class" ), + finalClass, + allAnimations = o.children ? animated.find( "*" ).andSelf() : animated; + + // map the animated objects to store the original styles. + allAnimations = allAnimations.map(function() { + var el = $( this ); + return { + el: el, + originalStyleAttr: el.attr( "style" ) || " ", + start: getElementStyles.call( this ) + }; + }); + // apply class change $.each( classAnimationActions, function(i, action) { if ( value[ action ] ) { - that[ action + 'Class' ]( value[ action ] ); + animated[ action + "Class" ]( value[ action ] ); } }); - newStyle = filterStyles( getElementStyles.call( this ) ); - that.attr( 'class', className ); - - that.animate( styleDifference( originalStyle, newStyle ), { - queue: false, - duration: duration, - easing: easing, - complete: function() { - $.each( classAnimationActions, function( i, action ) { - if ( value[ action ] ) { - that[ action + 'Class' ]( value[ action ] ); - } - }); - // work around bug in IE by clearing the cssText before setting it - if ( typeof that.attr( 'style' ) == 'object' ) { - that.attr( 'style' ).cssText = ''; - that.attr( 'style' ).cssText = originalStyleAttr; - } else { - that.attr( 'style', originalStyleAttr ); + finalClass = animated.attr( "class" ); + + // map all animated objects again - calculate new styles and diff + allAnimations = allAnimations.map(function() { + this.end = getElementStyles.call( this.el[ 0 ] ); + this.diff = styleDifference( this.start, this.end ); + return this; + }); + + // apply original class + animated.attr( "class", baseClass ); + + // map all animated objects again - this time collecting a promise + allAnimations = allAnimations.map(function() { + var styleInfo = this, + dfd = $.Deferred(); + + this.el.animate( this.diff, { + duration: o.duration, + easing: o.easing, + queue: false, + complete: function() { + dfd.resolve( styleInfo ); } - if ( callback ) { - callback.apply( this, arguments ); + }); + return dfd.promise(); + }); + + // once all animations have completed: + $.when.apply( $, allAnimations.get() ).done(function() { + + // set the final class + animated.attr( "class", finalClass ); + + // for each animated element + $.each( arguments, function() { + if ( typeof this.el.attr( "style" ) === "object" ) { + this.el.attr( "style" ).cssText = ""; + this.el.attr( "style" ).cssText = this.originalStyleAttr; + } else { + this.el.attr( "style", this.originalStyleAttr ); } - $.dequeue( this ); - } + }); + + // this is guarnteed to be there if you use jQuery.speed() + // it also handles dequeuing the next anim... + o.complete.call( animated[ 0 ] ); }); }); }; @@ -278,21 +297,21 @@ $.effects.animateClass = function( value, duration, easing, callback ) { $.fn.extend({ _addClass: $.fn.addClass, addClass: function( classNames, speed, easing, callback ) { - return speed ? + return speed ? $.effects.animateClass.apply( this, [{ add: classNames }, speed, easing, callback ]) : this._addClass(classNames); }, _removeClass: $.fn.removeClass, removeClass: function( classNames, speed, easing, callback ) { - return speed ? + return speed ? $.effects.animateClass.apply( this, [{ remove: classNames }, speed, easing, callback ]) : this._removeClass(classNames); }, _toggleClass: $.fn.toggleClass, toggleClass: function( classNames, force, speed, easing, callback ) { - if ( typeof force == "boolean" || force === undefined ) { + if ( typeof force === "boolean" || force === undefined ) { if ( !speed ) { // without speed parameter; return this._toggleClass( classNames, force ); @@ -300,15 +319,15 @@ $.fn.extend({ return $.effects.animateClass.apply( this, [( force ? { add:classNames } : { remove:classNames }), speed, easing, callback ]); } } else { - // without switch parameter; + // without force parameter; return $.effects.animateClass.apply( this, [{ toggle: classNames }, force, speed, easing ]); } }, switchClass: function( remove, add, speed, easing, callback) { - return $.effects.animateClass.apply( this, [{ - add: add, - remove: remove + return $.effects.animateClass.apply( this, [{ + add: add, + remove: remove }, speed, easing, callback ]); } }); @@ -326,7 +345,7 @@ $.extend( $.effects, { save: function( element, set ) { for( var i=0; i < set.length; i++ ) { if ( set[ i ] !== null ) { - element.data( "ec.storage." + set[ i ], element[ 0 ].style[ set[ i ] ] ); + element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); } } }, @@ -335,32 +354,32 @@ $.extend( $.effects, { restore: function( element, set ) { for( var i=0; i < set.length; i++ ) { if ( set[ i ] !== null ) { - element.css( set[ i ], element.data( "ec.storage." + set[ i ] ) ); + element.css( set[ i ], element.data( dataSpace + set[ i ] ) ); } } }, setMode: function( el, mode ) { - if (mode == 'toggle') { - mode = el.is( ':hidden' ) ? 'show' : 'hide'; + if (mode === "toggle") { + mode = el.is( ":hidden" ) ? "show" : "hide"; } return mode; }, // Translates a [top,left] array into a baseline value // this should be a little more flexible in the future to handle a string & hash - getBaseline: function( origin, original ) { + getBaseline: function( origin, original ) { var y, x; switch ( origin[ 0 ] ) { - case 'top': y = 0; break; - case 'middle': y = 0.5; break; - case 'bottom': y = 1; break; + case "top": y = 0; break; + case "middle": y = 0.5; break; + case "bottom": y = 1; break; default: y = origin[ 0 ] / original.height; }; switch ( origin[ 1 ] ) { - case 'left': x = 0; break; - case 'center': x = 0.5; break; - case 'right': x = 1; break; + case "left": x = 0; break; + case "center": x = 0.5; break; + case "right": x = 1; break; default: x = origin[ 1 ] / original.width; }; return { @@ -373,7 +392,7 @@ $.extend( $.effects, { createWrapper: function( element ) { // if the element is already wrapped, return it - if ( element.parent().is( '.ui-effects-wrapper' )) { + if ( element.parent().is( ".ui-effects-wrapper" )) { return element.parent(); } @@ -381,14 +400,14 @@ $.extend( $.effects, { var props = { width: element.outerWidth(true), height: element.outerHeight(true), - 'float': element.css( 'float' ) + "float": element.css( "float" ) }, - wrapper = $( '<div></div>' ) - .addClass( 'ui-effects-wrapper' ) + wrapper = $( "<div></div>" ) + .addClass( "ui-effects-wrapper" ) .css({ - fontSize: '100%', - background: 'transparent', - border: 'none', + fontSize: "100%", + background: "transparent", + border: "none", margin: 0, padding: 0 }); @@ -397,26 +416,26 @@ $.extend( $.effects, { wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element // transfer positioning properties to the wrapper - if ( element.css( 'position' ) == 'static' ) { - wrapper.css({ position: 'relative' }); - element.css({ position: 'relative' }); + if ( element.css( "position" ) === "static" ) { + wrapper.css({ position: "relative" }); + element.css({ position: "relative" }); } else { $.extend( props, { - position: element.css( 'position' ), - zIndex: element.css( 'z-index' ) + position: element.css( "position" ), + zIndex: element.css( "z-index" ) }); - $.each([ 'top', 'left', 'bottom', 'right' ], function(i, pos) { + $.each([ "top", "left", "bottom", "right" ], function(i, pos) { props[ pos ] = element.css( pos ); if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { - props[ pos ] = 'auto'; + props[ pos ] = "auto"; } }); element.css({ - position: 'relative', + position: "relative", top: 0, left: 0, - right: 'auto', - bottom: 'auto' + right: "auto", + bottom: "auto" }); } @@ -424,7 +443,7 @@ $.extend( $.effects, { }, removeWrapper: function( element ) { - if ( element.parent().is( '.ui-effects-wrapper' ) ) + if ( element.parent().is( ".ui-effects-wrapper" ) ) return element.parent().replaceWith( element ); return element; }, @@ -432,7 +451,7 @@ $.extend( $.effects, { setTransition: function( element, list, factor, value ) { value = value || {}; $.each( list, function(i, x){ - unit = element.cssUnit( x ); + var unit = element.cssUnit( x ); if ( unit[ 0 ] > 0 ) value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; }); return value; @@ -463,7 +482,7 @@ function _normalizeArguments( effect, options, speed, callback ) { } // catch (effect, speed, ?) - if ( $.type( options ) == 'number' || $.fx.speeds[ options ]) { + if ( $.type( options ) === "number" || $.fx.speeds[ options ]) { callback = speed; speed = options; options = {}; @@ -479,9 +498,9 @@ function _normalizeArguments( effect, options, speed, callback ) { if ( options ) { $.extend( effect, options ); } - + speed = speed || options.duration; - effect.duration = $.fx.off ? 0 : typeof speed == 'number' + effect.duration = $.fx.off ? 0 : typeof speed === "number" ? speed : speed in $.fx.speeds ? $.fx.speeds[ speed ] : $.fx.speeds._default; effect.complete = callback || options.complete; @@ -494,7 +513,7 @@ function standardSpeed( speed ) { if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { return true; } - + // invalid strings - treat as "normal" speed if ( typeof speed === "string" && !$.effects.effect[ speed ] ) { // TODO: remove in 2.0 (#7115) @@ -503,7 +522,7 @@ function standardSpeed( speed ) { } return true; } - + return false; } @@ -549,7 +568,7 @@ $.fn.extend({ return this._show.apply( this, arguments ); } else { var args = _normalizeArguments.apply( this, arguments ); - args.mode = 'show'; + args.mode = "show"; return this.effect.call( this, args ); } }, @@ -560,7 +579,7 @@ $.fn.extend({ return this._hide.apply( this, arguments ); } else { var args = _normalizeArguments.apply( this, arguments ); - args.mode = 'hide'; + args.mode = "hide"; return this.effect.call( this, args ); } }, @@ -572,7 +591,7 @@ $.fn.extend({ return this.__toggle.apply( this, arguments ); } else { var args = _normalizeArguments.apply( this, arguments ); - args.mode = 'toggle'; + args.mode = "toggle"; return this.effect.call( this, args ); } }, @@ -582,7 +601,7 @@ $.fn.extend({ var style = this.css( key ), val = []; - $.each( [ 'em', 'px', '%', 'pt' ], function( i, unit ) { + $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { if ( style.indexOf( unit ) > 0 ) val = [ parseFloat( style ), unit ]; }); @@ -637,7 +656,7 @@ $.fn.extend({ $.easing.jswing = $.easing.swing; $.extend( $.easing, { - def: 'easeOutQuad', + def: "easeOutQuad", swing: function ( x, t, b, c, d ) { return $.easing[ $.easing.def ]( x, t, b, c, d ); }, @@ -718,9 +737,9 @@ $.extend( $.easing, { a = c; if ( t == 0 ) return b; if ( ( t /= d ) == 1 ) return b+c; - if ( a < Math.abs( c ) ) { - a = c; - s = p / 4; + if ( a < Math.abs( c ) ) { + a = c; + s = p / 4; } else { s = p / ( 2 * Math.PI ) * Math.asin( c / a ); } @@ -733,8 +752,8 @@ $.extend( $.easing, { if ( t == 0 ) return b; if ( ( t /= d ) == 1 ) return b+c; if ( a < Math.abs( c ) ) { - a = c; - s = p / 4; + a = c; + s = p / 4; } else { s = p / ( 2 * Math.PI ) * Math.asin( c / a ); } @@ -746,7 +765,7 @@ $.extend( $.easing, { a = c; if ( t == 0 ) return b; if ( ( t /= d / 2 ) == 2 ) return b+c; - if ( a < Math.abs( c ) ) { + if ( a < Math.abs( c ) ) { a = c; s = p / 4; } else { diff --git a/ui/jquery.effects.fade.js b/ui/jquery.effects.fade.js index 5fa0319c0..ff1cba5f8 100644 --- a/ui/jquery.effects.fade.js +++ b/ui/jquery.effects.fade.js @@ -13,19 +13,26 @@ (function( $, undefined ) { $.effects.effect.fade = function( o ) { - return this.queue( function() { + return this.queue( function( next ) { var el = $( this ), - mode = $.effects.setMode( el, o.mode || 'hide' ); + mode = $.effects.setMode( el, o.mode || 'toggle' ), + hide = mode === "hide"; + el.show(); el.animate({ - opacity: mode + opacity: hide ? 0 : 1 }, { queue: false, duration: o.duration, easing: o.easing, complete: function() { - $.isFunction( o.complete ) && o.complete.apply( this, arguments ); - el.dequeue(); + if ( hide ) { + el.hide(); + } + if ( o.complete ) { + o.complete.call( this ); + } + next(); } }); }); diff --git a/ui/jquery.effects.pulsate.js b/ui/jquery.effects.pulsate.js index 3325c251f..a0ddf51fd 100644 --- a/ui/jquery.effects.pulsate.js +++ b/ui/jquery.effects.pulsate.js @@ -15,11 +15,12 @@ $.effects.effect.pulsate = function( o ) { return this.queue( function( next ) { var elem = $( this ), - mode = $.effects.setMode( elem, o.mode || "effect" ), - show = mode === "show" || elem.is( ":hidden" ), + mode = $.effects.setMode( elem, o.mode || "show" ), + show = mode === "show", + hide = mode === "hide", showhide = ( show || mode === "hide" ), - // showing or hiding adds an extra "half" animation + // showing or hiding leaves of the "last" animation anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), duration = o.duration / anims, animateTo = 0, @@ -27,7 +28,7 @@ $.effects.effect.pulsate = function( o ) { queuelen = queue.length, i; - if ( show ) { + if ( show || !elem.is(':visible')) { elem.css( "opacity", 0 ).show(); animateTo = 1; } @@ -42,19 +43,22 @@ $.effects.effect.pulsate = function( o ) { elem.animate({ opacity: animateTo - }, duration, o.easing, function() { - if ( animateTo === 0 ) { + }, duration, o.easing); + + elem.queue( function( next ) { + if ( hide ) { elem.hide(); } if ( o.complete ) { o.complete.apply( this ); } + next(); }); // 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 ) ) ); + [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); } next(); }); diff --git a/ui/jquery.effects.scale.js b/ui/jquery.effects.scale.js index 8f25ca9a8..00f0151af 100644 --- a/ui/jquery.effects.scale.js +++ b/ui/jquery.effects.scale.js @@ -25,6 +25,7 @@ $.effects.effect.puff = function( o ) { $.extend(o, { effect: 'scale', + queue: false, fade: true, mode: mode, percent: mode == 'hide' ? percent : 100, @@ -36,13 +37,13 @@ $.effects.effect.puff = function( o ) { } }); - elem.effect( o ).dequeue(); + elem.effect( o ); }); }; $.effects.effect.scale = function( o ) { - return this.queue( function() { + return this[ o.queue === false ? "each" : "queue" ]( function() { // Create element var el = $( this ), @@ -53,7 +54,9 @@ $.effects.effect.scale = function( o ) { origin = o.origin, original = { height: el.height(), - width: el.width() + width: el.width(), + outerHeight: el.outerHeight(), + outerWidth: el.outerWidth() }, factor = { y: direction != 'horizontal' ? (percent / 100) : 1, @@ -62,6 +65,7 @@ $.effects.effect.scale = function( o ) { // We are going to pass this effect to the size effect: options.effect = "size"; + options.queue = false; // Set default origin and restore for show/hide if ( mode != 'effect' ) { @@ -72,7 +76,9 @@ $.effects.effect.scale = function( o ) { options.from = o.from || ( mode == 'show' ? { height: 0, width: 0 } : original ); options.to = { height: original.height * factor.y, - width: original.width * factor.x + width: original.width * factor.x, + outerHeight: original.outerHeight * factor.y, + outerWidth: original.outerWidth * factor.x }; if ( options.fade ) { // Fade option to support puff @@ -87,14 +93,14 @@ $.effects.effect.scale = function( o ) { }; // Animate - el.effect(options).dequeue(); + el.effect(options); }); }; $.effects.effect.size = function( o ) { - return this.queue( function() { + return this[ o.queue === false ? "each" : "queue" ]( function() { // Create element var el = $( this ), props = [ 'position', 'top', 'bottom', 'left', 'right', 'width', 'height', 'overflow', 'opacity' ], @@ -113,24 +119,21 @@ $.effects.effect.size = function( o ) { restore = o.restore || false, scale = o.scale || 'both', origin = o.origin, - original = { - height: el.height(), - width: el.width() - }, - baseline, factor; + original, baseline, factor; + + if ( mode === "show" ) { + el.show(); + } + original = { + height: el.height(), + width: el.width(), + outerHeight: el.outerHeight(), + outerWidth: el.outerWidth() + }; el.from = o.from || original; el.to = o.to || original; - // Adjust - if (origin) { // Calculate baseline shifts - baseline = $.effects.getBaseline( origin, original ); - el.from.top = ( original.height - el.from.height ) * baseline.y; - el.from.left = ( original.width - el.from.width ) * baseline.x; - el.to.top = ( original.height - el.to.height ) * baseline.y; - el.to.left = ( original.width - el.to.width ) * baseline.x; - } - // Set scaling factor factor = { from: { @@ -147,14 +150,14 @@ $.effects.effect.size = function( o ) { if ( scale == 'box' || scale == 'both' ) { // Vertical props scaling - if ( factor.from.y != factor.to.y ) { + if ( factor.from.y !== factor.to.y ) { props = props.concat( vProps ); el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); }; // Horizontal props scaling - if ( factor.from.x != factor.to.x ) { + if ( factor.from.x !== factor.to.x ) { props = props.concat( hProps ); el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); @@ -165,7 +168,7 @@ $.effects.effect.size = function( o ) { if ( scale == 'content' || scale == 'both' ) { // Vertical props scaling - if ( factor.from.y != factor.to.y ) { + if ( factor.from.y !== factor.to.y ) { props = props.concat( cProps ); el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); @@ -177,6 +180,16 @@ $.effects.effect.size = function( o ) { $.effects.createWrapper( el ); el.css( 'overflow', 'hidden' ).css( el.from ); + // Adjust + if (origin) { // Calculate baseline shifts + baseline = $.effects.getBaseline( origin, original ); + el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; + el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; + el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; + el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; + } + el.css( el.from ); // set top & left + // Animate if ( scale == 'content' || scale == 'both' ) { // Scale the children diff --git a/ui/jquery.effects.shake.js b/ui/jquery.effects.shake.js index a1ba1577c..550329ca4 100644 --- a/ui/jquery.effects.shake.js +++ b/ui/jquery.effects.shake.js @@ -17,46 +17,60 @@ $.effects.effect.shake = function( o ) { return this.queue( function() { var el = $( this ), - props = [ 'position', 'top', 'bottom', 'left', 'right' ], - mode = $.effects.setMode( el, o.mode || 'effect' ), - direction = o.direction || 'left', + props = [ "position", "top", "bottom", "left", "right" ], + mode = $.effects.setMode( el, o.mode || "effect" ), + direction = o.direction || "left", distance = o.distance || 20, times = o.times || 3, - speed = o.duration || 140, - ref = (direction == 'up' || direction == 'down') ? 'top' : 'left', - motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg', + anims = times * 2 + 1, + speed = o.duration, + ref = (direction == "up" || direction == "down") ? "top" : "left", + motion = (direction == "up" || direction == "left") ? "pos" : "neg", animation = {}, animation1 = {}, animation2 = {}, - i; + i, - // Adjust - $.effects.save( el, props ); - el.show(); - $.effects.createWrapper( el ); // Create Wrapper + // we will need to re-assemble the queue to stack our animations in place + queue = el.queue(), + queuelen = queue.length; + + + $.effects.save( el, props ); + el.show(); + $.effects.createWrapper( el ); // Animation - animation[ ref ] = ( motion == 'pos' ? '-=' : '+=' ) + distance; - animation1[ ref ] = ( motion == 'pos' ? '+=' : '-=' ) + distance * 2; - animation2[ ref ] = ( motion == 'pos' ? '-=' : '+=' ) + distance * 2; + animation[ ref ] = ( motion == "pos" ? "-=" : "+=" ) + distance; + animation1[ ref ] = ( motion == "pos" ? "+=" : "-=" ) + distance * 2; + animation2[ ref ] = ( motion == "pos" ? "-=" : "+=" ) + distance * 2; // Animate el.animate( animation, speed, o.easing ); // Shakes - for ( i = 1; i < times; i++ ) { + for ( i = 1; i < times; i++ ) { el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); }; el .animate( animation1, speed, o.easing ) - .animate( animation, speed / 2, o.easing, function() { + .animate( animation, speed / 2, o.easing ) + .queue( function( next ) { + if ( mode === "hide" ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + $.isFunction( o.complete ) && o.complete.apply( this, arguments ); + next(); + }); - // Last shake - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - $.isFunction( o.complete ) && o.complete.apply( this, arguments ); - }) - .dequeue(); + // 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 + 1 ) ) ); + } + el.dequeue(); }); }; diff --git a/ui/jquery.ui.accordion.js b/ui/jquery.ui.accordion.js index 0cc1f9e2a..7602ae9bc 100644 --- a/ui/jquery.ui.accordion.js +++ b/ui/jquery.ui.accordion.js @@ -15,6 +15,7 @@ // TODO: use ui-accordion-header-active class and fix styling $.widget( "ui.accordion", { + version: "@VERSION", options: { active: 0, animated: "slide", @@ -432,7 +433,6 @@ $.widget( "ui.accordion", { }); $.extend( $.ui.accordion, { - version: "@VERSION", animations: { slide: function( options, additions ) { var showOverflow = options.toShow.css( "overflow" ), @@ -486,9 +486,11 @@ $.extend( $.ui.accordion, { $.each( fxAttrs, function( i, prop ) { hideProps[ prop ] = "hide"; - var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ ); + var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ ), + // work around bug when a panel has no height - #7335 + propVal = prop === "height" && parts[ 1 ] === "0" ? 1 : parts[ 1 ]; showProps[ prop ] = { - value: parts[ 1 ], + value: propVal, unit: parts[ 2 ] || "px" }; }); diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js index b3d7598c1..e39b4649e 100644 --- a/ui/jquery.ui.autocomplete.js +++ b/ui/jquery.ui.autocomplete.js @@ -19,6 +19,7 @@ var requestIndex = 0; $.widget( "ui.autocomplete", { + version: "@VERSION", defaultElement: "<input>", options: { appendTo: "body", @@ -47,7 +48,8 @@ $.widget( "ui.autocomplete", { _create: function() { var self = this, doc = this.element[ 0 ].ownerDocument, - suppressKeyPress; + suppressKeyPress, + suppressInput; this.valueMethod = this.element[ this.element.is( "input" ) ? "val" : "text" ]; @@ -62,29 +64,31 @@ $.widget( "ui.autocomplete", { }) .bind( "keydown.autocomplete", function( event ) { if ( self.options.disabled || self.element.attr( "readonly" ) ) { - suppressKeyPress = true; + suppressKeyPress = true; + suppressInput = true; return; } suppressKeyPress = false; + suppressInput = false; var keyCode = $.ui.keyCode; switch( event.keyCode ) { case keyCode.PAGE_UP: - suppressKeyPress = true; + suppressKeyPress = true; self._move( "previousPage", event ); break; case keyCode.PAGE_DOWN: - suppressKeyPress = true; + suppressKeyPress = true; self._move( "nextPage", event ); break; case keyCode.UP: - suppressKeyPress = true; + 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; + suppressKeyPress = true; self._move( "next", event ); // prevent moving cursor to end of text field in some browsers event.preventDefault(); @@ -110,15 +114,8 @@ $.widget( "ui.autocomplete", { self.close( event ); break; default: - // keypress is triggered before the input value is changed - clearTimeout( self.searching ); - self.searching = setTimeout(function() { - // only search if the value has changed - if ( self.term != self._value() ) { - self.selectedItem = null; - self.search( null, event ); - } - }, self.options.delay ); + // search timeout should be triggered before the input value is changed + self._searchTimeout( event ); break; } }) @@ -126,7 +123,7 @@ $.widget( "ui.autocomplete", { if ( suppressKeyPress ) { suppressKeyPress = false; event.preventDefault(); - return; + return; } // replicate some key handlers to allow them to repeat in Firefox and Opera @@ -148,7 +145,15 @@ $.widget( "ui.autocomplete", { // prevent moving cursor to end of text field in some browsers event.preventDefault(); break; - } + } + }) + .bind( "input.autocomplete", function(event) { + if ( suppressInput ) { + suppressInput = false; + event.preventDefault(); + return; + } + self._searchTimeout( event ); }) .bind( "focus.autocomplete", function() { if ( self.options.disabled ) { @@ -317,6 +322,17 @@ $.widget( "ui.autocomplete", { } }, + _searchTimeout: function( event ) { + var self = this; + self.searching = setTimeout(function() { + // only search if the value has changed + if ( self.term != self.element.val() ) { + self.selectedItem = null; + self.search( null, event ); + } + }, self.options.delay ); + }, + search: function( value, event ) { value = value != null ? value : this._value(); @@ -365,7 +381,6 @@ $.widget( "ui.autocomplete", { this.menu.element.hide(); this.menu.blur(); this._trigger( "close", event ); - this.menu.isNewMenu = true; } }, @@ -461,7 +476,6 @@ $.widget( "ui.autocomplete", { }); $.extend( $.ui.autocomplete, { - version: "@VERSION", escapeRegex: function( value ) { return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); }, diff --git a/ui/jquery.ui.button.js b/ui/jquery.ui.button.js index 031ac2091..482cdc24c 100644 --- a/ui/jquery.ui.button.js +++ b/ui/jquery.ui.button.js @@ -13,17 +13,15 @@ */ (function( $, undefined ) { -var lastActive, +var lastActive, startXPos, startYPos, clickDragged, baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", stateClasses = "ui-state-hover ui-state-active ", typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", - formResetHandler = function( event ) { - $( ":ui-button", event.target.form ).each(function() { - var inst = $( this ).data( "button" ); - setTimeout(function() { - inst.refresh(); - }, 1 ); - }); + formResetHandler = function() { + var buttons = $( this ).find( ":ui-button" ); + setTimeout(function() { + buttons.button( "refresh" ); + }, 1 ); }, radioGroup = function( radio ) { var name = radio.name, @@ -43,6 +41,7 @@ var lastActive, }; $.widget( "ui.button", { + version: "@VERSION", defaultElement: "<button>", options: { disabled: null, @@ -97,28 +96,54 @@ $.widget( "ui.button", { } $( this ).removeClass( hoverClass ); }) - .bind( "focus.button", function() { - // no need to check disabled, focus won't be triggered anyway - $( this ).addClass( focusClass ); - }) - .bind( "blur.button", function() { - $( this ).removeClass( focusClass ); - }) .bind( "click.button", function( event ) { if ( options.disabled ) { + event.preventDefault(); event.stopImmediatePropagation(); } }); + this.element + .bind( "focus.button", function() { + // no need to check disabled, focus won't be triggered anyway + self.buttonElement.addClass( focusClass ); + }) + .bind( "blur.button", function() { + self.buttonElement.removeClass( focusClass ); + }); + if ( toggleButton ) { this.element.bind( "change.button", function() { + if ( clickDragged ) { + return; + } self.refresh(); }); + // if mouse moves between mousedown and mouseup (drag) set clickDragged flag + // prevents issue where button state changes but checkbox/radio checked state + // does not in Firefox (see ticket #6970) + this.buttonElement + .bind( "mousedown.button", function( event ) { + if ( options.disabled ) { + return; + } + clickDragged = false; + startXPos = event.pageX; + startYPos = event.pageY; + }) + .bind( "mouseup.button", function( event ) { + if ( options.disabled ) { + return; + } + if ( startXPos !== event.pageX || startYPos !== event.pageY ) { + clickDragged = true; + } + }); } if ( this.type === "checkbox" ) { this.buttonElement.bind( "click.button", function() { - if ( options.disabled ) { + if ( options.disabled || clickDragged ) { return false; } $( this ).toggleClass( "ui-state-active" ); @@ -126,7 +151,7 @@ $.widget( "ui.button", { }); } else if ( this.type === "radio" ) { this.buttonElement.bind( "click.button", function() { - if ( options.disabled ) { + if ( options.disabled || clickDragged ) { return false; } $( this ).addClass( "ui-state-active" ); @@ -185,6 +210,7 @@ $.widget( "ui.button", { // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can // be overridden by individual plugins this._setOption( "disabled", options.disabled ); + this._resetButton(); }, _determineButtonType: function() { @@ -250,6 +276,7 @@ $.widget( "ui.button", { } else { this.element.removeAttr( "disabled" ); } + return; } this._resetButton(); }, @@ -352,6 +379,8 @@ $.widget( "ui.buttonset", { }, refresh: function() { + var ltr = this.element.css( "direction" ) === "ltr"; + this.buttons = this.element.find( this.options.items ) .filter( ":ui-button" ) .button( "refresh" ) @@ -364,10 +393,10 @@ $.widget( "ui.buttonset", { }) .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) .filter( ":first" ) - .addClass( "ui-corner-left" ) + .addClass( ltr ? "ui-corner-left" : "ui-corner-right" ) .end() .filter( ":last" ) - .addClass( "ui-corner-right" ) + .addClass( ltr ? "ui-corner-right" : "ui-corner-left" ) .end() .end(); }, @@ -384,6 +413,4 @@ $.widget( "ui.buttonset", { } }); -$.ui.buttonset.version = "@VERSION"; - }( jQuery ) ); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 12323672a..4c73bdfd8 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -364,6 +364,8 @@ $.extend(Datepicker.prototype, { else if (nodeName == 'div' || nodeName == 'span') { var inline = $target.children('.' + this._inlineClass); inline.children().removeClass('ui-state-disabled'); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). + removeAttr("disabled"); } this._disabledInputs = $.map(this._disabledInputs, function(value) { return (value == target ? null : value); }); // delete entry @@ -387,6 +389,8 @@ $.extend(Datepicker.prototype, { else if (nodeName == 'div' || nodeName == 'span') { var inline = $target.children('.' + this._inlineClass); inline.children().addClass('ui-state-disabled'); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). + attr("disabled", "disabled"); } this._disabledInputs = $.map(this._disabledInputs, function(value) { return (value == target ? null : value); }); // delete entry @@ -455,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); } }, @@ -609,6 +614,9 @@ $.extend(Datepicker.prototype, { return; var inst = $.datepicker._getInst(input); if ($.datepicker._curInst && $.datepicker._curInst != inst) { + if ( $.datepicker._datepickerShowing ) { + $.datepicker._triggerOnClose($.datepicker._curInst); + } $.datepicker._curInst.dpDiv.stop(true, true); } var beforeShow = $.datepicker._get(inst, 'beforeShow'); @@ -702,7 +710,7 @@ $.extend(Datepicker.prototype, { var origyearshtml = inst.yearshtml; setTimeout(function(){ //assure that inst.yearshtml didn't change. - if( origyearshtml === inst.yearshtml ){ + if( origyearshtml === inst.yearshtml && inst.yearshtml ){ inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml); } origyearshtml = inst.yearshtml = null; @@ -754,6 +762,14 @@ $.extend(Datepicker.prototype, { return [position.left, position.top]; }, + /* Trigger custom callback of onClose. */ + _triggerOnClose: function(inst) { + var onClose = this._get(inst, 'onClose'); + if (onClose) + onClose.apply((inst.input ? inst.input[0] : null), + [(inst.input ? inst.input.val() : ''), inst]); + }, + /* Hide the date picker from view. @param input element - the input field attached to the date picker */ _hideDatepicker: function(input) { @@ -776,10 +792,7 @@ $.extend(Datepicker.prototype, { (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess); if (!showAnim) postProcess(); - var onClose = this._get(inst, 'onClose'); - if (onClose) - onClose.apply((inst.input ? inst.input[0] : null), - [(inst.input ? inst.input.val() : ''), inst]); // trigger custom callback + $.datepicker._triggerOnClose(inst); this._datepickerShowing = false; this._lastInput = null; if (this._inDialog) { @@ -1069,6 +1082,9 @@ $.extend(Datepicker.prototype, { checkLiteral(); } } + if (iValue < value.length){ + throw "Extra/unparsed characters found in date: " + value.substring(iValue); + } if (year == -1) year = new Date().getFullYear(); else if (year < 100) @@ -1180,7 +1196,7 @@ $.extend(Datepicker.prototype, { break; case 'o': output += formatNumber('o', - (date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000, 3); + Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); break; case 'm': output += formatNumber('m', date.getMonth() + 1, 2); @@ -1601,14 +1617,9 @@ $.extend(Datepicker.prototype, { '>' + year + '</option>'; } inst.yearshtml += '</select>'; - //when showing there is no need for later update - if( ! $.browser.mozilla ){ - html += inst.yearshtml; - inst.yearshtml = null; - } else { - // will be replaced later with inst.yearshtml - html += '<select class="ui-datepicker-year"><option value="' + drawYear + '" selected="selected">' + drawYear + '</option></select>'; - } + + html += inst.yearshtml; + inst.yearshtml = null; } } html += this._get(inst, 'yearSuffix'); diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js index 2138a9a58..0eba39842 100644 --- a/ui/jquery.ui.dialog.js +++ b/ui/jquery.ui.dialog.js @@ -36,6 +36,7 @@ var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ", }; $.widget("ui.dialog", { + version: "@VERSION", options: { autoOpen: true, buttons: {}, @@ -190,6 +191,10 @@ $.widget("ui.dialog", { }, close: function( event ) { + if ( !this._isOpen ) { + return self; + } + var self = this, maxZ, thisZ; @@ -197,13 +202,13 @@ $.widget("ui.dialog", { return; } + self._isOpen = false; + if ( self.overlay ) { self.overlay.destroy(); } self.uiDialog.unbind( "keypress.ui-dialog" ); - self._isOpen = false; - if ( self.options.hide ) { self.uiDialog.hide( self.options.hide, function() { self._trigger( "close", event ); @@ -281,10 +286,10 @@ $.widget("ui.dialog", { options = self.options, uiDialog = self.uiDialog; - self.overlay = options.modal ? new $.ui.dialog.overlay( self ) : null; self._size(); self._position( options.position ); uiDialog.show( options.show ); + self.overlay = options.modal ? new $.ui.dialog.overlay( self ) : null; self.moveToTop( true ); // prevent tabbing out of modal dialogs @@ -369,8 +374,7 @@ $.widget("ui.dialog", { _makeDraggable: function() { var self = this, options = self.options, - doc = $( document ), - heightBeforeDrag; + doc = $( document ); function filteredUi( ui ) { return { @@ -384,9 +388,7 @@ $.widget("ui.dialog", { handle: ".ui-dialog-titlebar", containment: "document", start: function( event, ui ) { - heightBeforeDrag = options.height === "auto" ? "auto" : $( this ).height(); $( this ) - .height( $( this ).height() ) .addClass( "ui-dialog-dragging" ); self._trigger( "dragStart", event, filteredUi( ui ) ); }, @@ -399,8 +401,7 @@ $.widget("ui.dialog", { ui.position.top - doc.scrollTop() ]; $( this ) - .removeClass( "ui-dialog-dragging" ) - .height( heightBeforeDrag ); + .removeClass( "ui-dialog-dragging" ); self._trigger( "dragStop", event, filteredUi( ui ) ); $.ui.dialog.overlay.resize(); } @@ -655,8 +656,6 @@ $.widget("ui.dialog", { }); $.extend($.ui.dialog, { - version: "@VERSION", - uuid: 0, maxZ: 0, @@ -742,7 +741,7 @@ $.extend( $.ui.dialog.overlay, { $( [ document, window ] ).unbind( ".dialog-overlay" ); } - $el.remove(); + $el.height( 0 ).width( 0 ).remove(); // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) var maxZ = 0; @@ -755,8 +754,8 @@ $.extend( $.ui.dialog.overlay, { height: function() { var scrollHeight, offsetHeight; - // handle IE 6 - if ( $.browser.msie && $.browser.version < 7 ) { + // handle IE + if ( $.browser.msie ) { scrollHeight = Math.max( document.documentElement.scrollHeight, document.body.scrollHeight @@ -780,8 +779,8 @@ $.extend( $.ui.dialog.overlay, { width: function() { var scrollWidth, offsetWidth; - // handle IE 6 - if ( $.browser.msie && $.browser.version < 7 ) { + // handle IE + if ( $.browser.msie ) { scrollWidth = Math.max( document.documentElement.scrollWidth, document.body.scrollWidth diff --git a/ui/jquery.ui.draggable.js b/ui/jquery.ui.draggable.js index 774ea4380..6475ebd61 100644 --- a/ui/jquery.ui.draggable.js +++ b/ui/jquery.ui.draggable.js @@ -15,6 +15,7 @@ (function( $, undefined ) { $.widget("ui.draggable", $.ui.mouse, { + version: "@VERSION", widgetEventPrefix: "drag", options: { addClasses: true, @@ -163,6 +164,10 @@ $.widget("ui.draggable", $.ui.mouse, { this.helper.addClass("ui-draggable-dragging"); this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position + + //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) + if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event); + return true; }, @@ -229,6 +234,9 @@ $.widget("ui.draggable", $.ui.mouse, { }); //Remove frame helpers } + //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) + if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event); + return $.ui.mouse.prototype._mouseUp.call(this, event); }, @@ -261,7 +269,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)); @@ -355,8 +363,8 @@ $.widget("ui.draggable", $.ui.mouse, { var o = this.options; if(o.containment == 'parent') o.containment = this.helper[0].parentNode; if(o.containment == 'document' || o.containment == 'window') this.containment = [ - (o.containment == 'document' ? 0 : $(window).scrollLeft()) - this.offset.relative.left - this.offset.parent.left, - (o.containment == 'document' ? 0 : $(window).scrollTop()) - this.offset.relative.top - this.offset.parent.top, + o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, + o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top ]; @@ -436,10 +444,11 @@ $.widget("ui.draggable", $.ui.mouse, { } if(o.grid) { - var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; + //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) + var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; - var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; + var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; } @@ -494,10 +503,6 @@ $.widget("ui.draggable", $.ui.mouse, { }); -$.extend($.ui.draggable, { - version: "@VERSION" -}); - $.ui.plugin.add("draggable", "connectToSortable", { start: function(event, ui) { @@ -580,7 +585,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.droppable.js b/ui/jquery.ui.droppable.js index b8a93cd46..3942c6b8f 100644 --- a/ui/jquery.ui.droppable.js +++ b/ui/jquery.ui.droppable.js @@ -16,6 +16,7 @@ (function( $, undefined ) { $.widget("ui.droppable", { + version: "@VERSION", widgetEventPrefix: "drop", options: { accept: '*', @@ -146,10 +147,6 @@ $.widget("ui.droppable", { }); -$.extend($.ui.droppable, { - version: "@VERSION" -}); - $.ui.intersect = function(draggable, droppable, toleranceMode) { if (!droppable.offset) return false; @@ -238,6 +235,12 @@ $.ui.ddmanager = { return dropped; }, + dragStart: function( draggable, event ) { + //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) + draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { + if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); + }); + }, drag: function(draggable, event) { //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. @@ -279,6 +282,11 @@ $.ui.ddmanager = { } }); + }, + dragStop: function( draggable, event ) { + draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); + //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) + if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); } }; diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 3cc25062c..03e14f124 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -16,9 +16,9 @@ var idIncrement = 0; $.widget("ui.menu", { + version: "@VERSION", defaultElement: "<ul>", delay: 150, - isNewMenu: true, options: { position: { my: "left top", @@ -46,8 +46,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 ); @@ -55,8 +53,7 @@ $.widget("ui.menu", { self.select( event ); }) .bind( "mouseover.menu", function( event ) { - if ( self.options.disabled || self.isNewMenu ) { - self.isNewMenu = false; + if ( self.options.disabled ) { return; } var target = $( event.target ).closest( ".ui-menu-item" ); @@ -237,15 +234,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 ); } } @@ -410,7 +407,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 ) { @@ -423,6 +421,4 @@ $.widget("ui.menu", { } }); -$.ui.menu.version = "@VERSION"; - }( jQuery )); diff --git a/ui/jquery.ui.menubar.js b/ui/jquery.ui.menubar.js index 2879d079c..a0e9afb3c 100644 --- a/ui/jquery.ui.menubar.js +++ b/ui/jquery.ui.menubar.js @@ -18,10 +18,11 @@ // TODO when mixing clicking menus and keyboard navigation, focus handling is broken // there has to be just one item that has tabindex $.widget( "ui.menubar", { - options: { - buttons: false, - menuIcon: false - }, + version: "@VERSION", + options: { + buttons: false, + menuIcon: false + }, _create: function() { var that = this; var items = this.items = this.element.children( "li" ) @@ -68,13 +69,13 @@ $.widget( "ui.menubar", { var input = $(this), // TODO menu var is only used on two places, doesn't quite justify the .each menu = input.next( "ul" ); - + input.bind( "click.menubar focus.menubar mouseenter.menubar", function( event ) { // ignore triggered focus event if ( event.type == "focus" && !event.originalEvent ) { return; } - event.preventDefault(); + event.preventDefault(); // TODO can we simplify or extractthis check? especially the last two expressions // there's a similar active[0] == menu[0] check in _open if ( event.type == "click" && menu.is( ":visible" ) && that.active && that.active[0] == menu[0] ) { @@ -84,7 +85,7 @@ $.widget( "ui.menubar", { if ( ( that.open && event.type == "mouseenter" ) || event.type == "click" ) { that._open( event, menu ); } - }) + }) .bind( "keydown", function( event ) { switch ( event.keyCode ) { case $.ui.keyCode.SPACE: @@ -113,11 +114,11 @@ $.widget( "ui.menubar", { input.addClass( "ui-state-default" ).append( "<span class='ui-button-icon-secondary ui-icon ui-icon-triangle-1-s'></span>" ); input.removeClass( "ui-button-text-only" ).addClass( "ui-button-text-icon-secondary" ); } - + if ( !that.options.buttons ) { // TODO ui-menubar-link is added above, not needed here? input.addClass( "ui-menubar-link" ).removeClass( "ui-state-default" ); - }; + }; }); that._bind( { @@ -139,18 +140,18 @@ $.widget( "ui.menubar", { } }); }, - + _destroy : function() { var items = this.element.children( "li" ) .removeClass( "ui-menubar-item" ) .removeAttr( "role", "presentation" ) .children( "button, a" ); - + this.element .removeClass( "ui-menubar ui-widget-header ui-helper-clearfix" ) .removeAttr( "role", "menubar" ) .unbind( ".menubar" ); - + items .unbind( ".menubar" ) .removeClass( "ui-button ui-widget ui-button-text-only ui-menubar-link ui-state-default" ) @@ -172,7 +173,7 @@ $.widget( "ui.menubar", { .removeAttr( "tabindex" ) .unbind( ".menubar" ); }, - + _close: function() { if ( !this.active || !this.active.length ) return; @@ -188,7 +189,7 @@ $.widget( "ui.menubar", { this.active = null; this.open = false; }, - + _open: function( event, menu ) { // on a single-button menubar, ignore reopening the same menu if ( this.active && this.active[0] == menu[0] ) { @@ -222,7 +223,7 @@ $.widget( "ui.menubar", { .focusin(); this.open = true; }, - + // TODO refactor this and the next three methods _prev: function( event, button ) { button.attr( "tabIndex", -1 ); @@ -234,7 +235,7 @@ $.widget( "ui.menubar", { lastItem.removeAttr( "tabIndex" )[0].focus(); } }, - + _next: function( event, button ) { button.attr( "tabIndex", -1 ); var next = button.parent().nextAll( "li" ).children( ".ui-button" ).eq( 0 ); @@ -256,7 +257,7 @@ $.widget( "ui.menubar", { this._open( event, lastItem ); } }, - + // TODO rename to child (or something like that) _right: function( event ) { var next = this.active.parent().nextAll( "li:eq(0)" ).children( ".ui-menu" ).eq( 0 ); diff --git a/ui/jquery.ui.mouse.js b/ui/jquery.ui.mouse.js index 0bd38db85..582eaf9c0 100644 --- a/ui/jquery.ui.mouse.js +++ b/ui/jquery.ui.mouse.js @@ -18,6 +18,7 @@ $(document).mousedown(function(e) { }); $.widget("ui.mouse", { + version: "@VERSION", options: { cancel: ':input,option', distance: 1, @@ -58,7 +59,7 @@ $.widget("ui.mouse", { var self = this, btnIsLeft = (event.which == 1), - elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false); + elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).closest(this.options.cancel).length : false); if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { return true; } diff --git a/ui/jquery.ui.popup.js b/ui/jquery.ui.popup.js index 10361a35c..c90755fbb 100644 --- a/ui/jquery.ui.popup.js +++ b/ui/jquery.ui.popup.js @@ -17,6 +17,7 @@ var idIncrement = 0; $.widget( "ui.popup", { + version: "@VERSION", options: { position: { my: "left top", diff --git a/ui/jquery.ui.progressbar.js b/ui/jquery.ui.progressbar.js index e3b25cfd7..187470681 100644 --- a/ui/jquery.ui.progressbar.js +++ b/ui/jquery.ui.progressbar.js @@ -14,6 +14,7 @@ (function( $, undefined ) { $.widget( "ui.progressbar", { + version: "@VERSION", options: { value: 0, max: 100 @@ -100,8 +101,4 @@ $.widget( "ui.progressbar", { } }); -$.extend( $.ui.progressbar, { - version: "@VERSION" -}); - })( jQuery ); diff --git a/ui/jquery.ui.resizable.js b/ui/jquery.ui.resizable.js index e0579ef84..673a8fd75 100644 --- a/ui/jquery.ui.resizable.js +++ b/ui/jquery.ui.resizable.js @@ -15,6 +15,7 @@ (function( $, undefined ) { $.widget("ui.resizable", $.ui.mouse, { + version: "@VERSION", widgetEventPrefix: "resize", options: { alsoResize: false, @@ -293,6 +294,8 @@ $.widget("ui.resizable", $.ui.mouse, { // Calculate the attrs that will be change var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff; + // Put this in the mouseDrag handler since the user can start pressing shift while resizing + this._updateVirtualBoundaries(event.shiftKey); if (this._aspectRatio || event.shiftKey) data = this._updateRatio(data, event); @@ -351,6 +354,32 @@ $.widget("ui.resizable", $.ui.mouse, { }, + _updateVirtualBoundaries: function(forceAspectRatio) { + var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b; + + b = { + minWidth: isNumber(o.minWidth) ? o.minWidth : 0, + maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, + minHeight: isNumber(o.minHeight) ? o.minHeight : 0, + maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity + }; + + if(this._aspectRatio || forceAspectRatio) { + // We want to create an enclosing box whose aspect ration is the requested one + // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension + pMinWidth = b.minHeight * this.aspectRatio; + pMinHeight = b.minWidth / this.aspectRatio; + pMaxWidth = b.maxHeight * this.aspectRatio; + pMaxHeight = b.maxWidth / this.aspectRatio; + + if(pMinWidth > b.minWidth) b.minWidth = pMinWidth; + if(pMinHeight > b.minHeight) b.minHeight = pMinHeight; + if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth; + if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight; + } + this._vBoundaries = b; + }, + _updateCache: function(data) { var o = this.options; this.offset = this.helper.offset(); @@ -364,8 +393,8 @@ $.widget("ui.resizable", $.ui.mouse, { var o = this.options, cpos = this.position, csize = this.size, a = this.axis; - if (data.height) data.width = (csize.height * this.aspectRatio); - else if (data.width) data.height = (csize.width / this.aspectRatio); + if (isNumber(data.height)) data.width = (data.height * this.aspectRatio); + else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio); if (a == 'sw') { data.left = cpos.left + (csize.width - data.width); @@ -381,7 +410,7 @@ $.widget("ui.resizable", $.ui.mouse, { _respectSize: function(data, event) { - var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis, + var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis, ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height); @@ -520,10 +549,6 @@ $.widget("ui.resizable", $.ui.mouse, { }); -$.extend($.ui.resizable, { - version: "@VERSION" -}); - /* * Resizable Extensions */ diff --git a/ui/jquery.ui.selectable.js b/ui/jquery.ui.selectable.js index fa7d01122..75f1cee66 100644 --- a/ui/jquery.ui.selectable.js +++ b/ui/jquery.ui.selectable.js @@ -15,6 +15,7 @@ (function( $, undefined ) { $.widget("ui.selectable", $.ui.mouse, { + version: "@VERSION", options: { appendTo: 'body', autoRefresh: true, @@ -259,8 +260,4 @@ $.widget("ui.selectable", $.ui.mouse, { }); -$.extend($.ui.selectable, { - version: "@VERSION" -}); - })(jQuery); diff --git a/ui/jquery.ui.slider.js b/ui/jquery.ui.slider.js index eb6545f62..978155370 100644 --- a/ui/jquery.ui.slider.js +++ b/ui/jquery.ui.slider.js @@ -19,7 +19,7 @@ var numPages = 5; $.widget( "ui.slider", $.ui.mouse, { - + version: "@VERSION", widgetEventPrefix: "slide", options: { @@ -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 + this.range = $( "<div></div>" ) .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" ); + .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 ( $( ".ui-slider-handle", this.element ).length === 0 ) { - $( "<a href='#'></a>" ) - .appendTo( this.element ) - .addClass( "ui-slider-handle" ); + for ( var i = existingHandles.length; i < handleCount; i += 1 ) { + handles.push( handle ); } - 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" ); - } - } - - 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 ); @@ -677,8 +659,4 @@ $.widget( "ui.slider", $.ui.mouse, { }); -$.extend( $.ui.slider, { - version: "@VERSION" -}); - }(jQuery)); diff --git a/ui/jquery.ui.sortable.js b/ui/jquery.ui.sortable.js index 78349669a..99798a915 100644 --- a/ui/jquery.ui.sortable.js +++ b/ui/jquery.ui.sortable.js @@ -15,6 +15,7 @@ (function( $, undefined ) { $.widget("ui.sortable", $.ui.mouse, { + version: "@VERSION", widgetEventPrefix: "sort", options: { appendTo: "parent", @@ -983,7 +984,7 @@ $.widget("ui.sortable", $.ui.mouse, { // We first have to update the dom position of the actual currentItem // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) - if(!this._noFinalSort && this.currentItem[0].parentNode) this.placeholder.before(this.currentItem); + if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem); this._noFinalSort = null; if(this.helper[0] == this.currentItem[0]) { @@ -1069,8 +1070,4 @@ $.widget("ui.sortable", $.ui.mouse, { }); -$.extend($.ui.sortable, { - version: "@VERSION" -}); - })(jQuery); diff --git a/ui/jquery.ui.spinner.js b/ui/jquery.ui.spinner.js index b8cca7dcd..b4cefc982 100644 --- a/ui/jquery.ui.spinner.js +++ b/ui/jquery.ui.spinner.js @@ -11,284 +11,297 @@ * jquery.ui.core.js * jquery.ui.widget.js */ -(function($) { +(function( $ ) { -$.widget('ui.spinner', { +$.widget( "ui.spinner", { + version: "@VERSION", defaultElement: "<input>", - widgetEventPrefix: "spin", + widgetEventPrefix: "spin", options: { incremental: true, max: null, min: null, - numberformat: null, + numberFormat: null, page: 10, step: null, value: null }, - + _create: function() { this._draw(); this._markupOptions(); this._mousewheel(); this._aria(); }, - + _markupOptions: function() { - var _this = this; + var that = this; $.each({ min: -Number.MAX_VALUE, max: Number.MAX_VALUE, step: 1 - }, function(attr, defaultValue) { - if (_this.options[attr] === null) { - var value = _this.element.attr(attr); - _this.options[attr] = typeof value == "string" && value.length > 0 ? _this._parse(value) : defaultValue; + }, function( attr, defaultValue ) { + if ( that.options[ attr ] === null ) { + var value = that.element.attr( attr ); + that.options[ attr ] = typeof value === "string" && value.length > 0 ? + that._parse( value ) : + defaultValue; } }); - this.value(this.options.value !== null ? this.options.value : this.element.val() || 0); + this.value( this.options.value !== null ? this.options.value : this.element.val() || 0 ); }, - + _draw: function() { var self = this, options = self.options; var uiSpinner = this.uiSpinner = self.element - .addClass('ui-spinner-input') - .attr('autocomplete', 'off') - .wrap(self._uiSpinnerHtml()) + .addClass( "ui-spinner-input" ) + .attr( "autocomplete", "off" ) + .wrap( self._uiSpinnerHtml() ) .parent() // add buttons - .append(self._buttonHtml()) + .append( self._buttonHtml() ) // add behaviours + .disableSelection() + // TODO: user ._hoverable .hover(function() { - if (!options.disabled) { - $(this).addClass('ui-state-hover'); + if ( !options.disabled ) { + $( this ).addClass( "ui-state-hover" ); } self.hovered = true; }, function() { - $(this).removeClass('ui-state-hover'); + $( this ).removeClass( "ui-state-hover" ); self.hovered = false; }); + // TODO: use ._bind() this.element .attr( "role", "spinbutton" ) - .bind('keydown.spinner', function(event) { - if (self.options.disabled) { + .bind( "keydown.spinner", function( event ) { + if ( options.disabled ) { return; } - if (self._start(event)) { - return self._keydown(event); + if ( self._start( event ) ) { + return self._keydown( event ); } return true; }) - .bind('keyup.spinner', function(event) { - if (self.options.disabled) { + .bind( "keyup.spinner", function( event ) { + if ( options.disabled ) { return; } - if (self.spinning) { - self._stop(event); - self._change(event); + if ( self.spinning ) { + self._stop( event ); + self._change( event ); } }) - .bind('focus.spinner', function() { - uiSpinner.addClass('ui-state-active'); + .bind( "focus.spinner", function() { + uiSpinner.addClass( "ui-state-active" ); self.focused = true; }) - .bind('blur.spinner', function(event) { - self.value(self.element.val()); - if (!self.hovered) { - uiSpinner.removeClass('ui-state-active'); - } + .bind( "blur.spinner", function( event ) { + self.value( self.element.val() ); + if ( !self.hovered ) { + uiSpinner.removeClass( "ui-state-active" ); + } self.focused = false; }); // button bindings - this.buttons = uiSpinner.find('.ui-spinner-button') - .attr("tabIndex", -1) + this.buttons = uiSpinner.find( ".ui-spinner-button" ) + .attr( "tabIndex", -1 ) .button() - .removeClass("ui-corner-all") - .bind('mousedown', function(event) { - if (self.options.disabled) { + .removeClass( "ui-corner-all" ) + .bind( "mousedown", function( event ) { + if ( options.disabled ) { return; } - if (self._start(event) === false) { + if ( self._start( event ) === false ) { return false; } - self._repeat(null, $(this).hasClass('ui-spinner-up') ? 1 : -1, event); + self._repeat( null, $( this ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); }) - .bind('mouseup', function(event) { - if (self.options.disabled) { + .bind( "mouseup", function( event ) { + if ( options.disabled ) { return; } - if (self.spinning) { - self._stop(event); - self._change(event); + if ( self.spinning ) { + self._stop( event ); + self._change( event ); } }) - .bind("mouseenter", function() { - if (self.options.disabled) { + .bind( "mouseenter", function() { + if ( self.options.disabled ) { return; } // button will add ui-state-active if mouse was down while mouseleave and kept down - if ($(this).hasClass("ui-state-active")) { - if (self._start(event) === false) { + if ( $( this ).hasClass( "ui-state-active" ) ) { + if ( self._start( event ) === false ) { return false; } - self._repeat(null, $(this).hasClass('ui-spinner-up') ? 1 : -1, event); + self._repeat( null, $( this ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); } }) - .bind("mouseleave", function() { - if (self.spinning) { - self._stop(event); - self._change(event); + .bind( "mouseleave", function() { + if ( self.spinning ) { + self._stop( event ); + self._change( event ); } }); - + // disable spinner if element was already disabled - if (options.disabled) { + if ( options.disabled ) { this.disable(); } }, - - _keydown: function(event) { - var o = this.options, - KEYS = $.ui.keyCode; - - switch (event.keyCode) { - case KEYS.UP: - this._repeat(null, 1, event); + + _keydown: function( event ) { + var options = this.options, + keyCode = $.ui.keyCode; + + switch ( event.keyCode ) { + case keyCode.UP: + this._repeat( null, 1, event ); return false; - case KEYS.DOWN: - this._repeat(null, -1, event); + case keyCode.DOWN: + this._repeat( null, -1, event ); return false; - case KEYS.PAGE_UP: - this._repeat(null, this.options.page, event); + case keyCode.PAGE_UP: + this._repeat( null, options.page, event ); return false; - case KEYS.PAGE_DOWN: - this._repeat(null, -this.options.page, event); + case keyCode.PAGE_DOWN: + this._repeat( null, -options.page, event ); return false; - - case KEYS.ENTER: - this.value(this.element.val()); + case keyCode.ENTER: + this.value( this.element.val() ); } - + return true; }, - + _mousewheel: function() { // need the delta normalization that mousewheel plugin provides - if (!$.fn.mousewheel) { + if ( !$.fn.mousewheel ) { return; } var self = this; - this.element.bind("mousewheel.spinner", function(event, delta) { - if (self.options.disabled || !delta) { + this.element.bind( "mousewheel.spinner", function( event, delta ) { + if ( self.options.disabled || !delta ) { return; } - if (!self.spinning && !self._start(event)) { + if ( !self.spinning && !self._start( event ) ) { return false; } - self._spin((delta > 0 ? 1 : -1) * self.options.step, event); - clearTimeout(self.timeout); + self._spin( (delta > 0 ? 1 : -1) * self.options.step, event ); + clearTimeout( self.timeout ); self.timeout = setTimeout(function() { - if (self.spinning) { - self._stop(event); - self._change(event); + if ( self.spinning ) { + self._stop( event ); + self._change( event ); } }, 100); event.preventDefault(); }); }, - + _uiSpinnerHtml: function() { - return '<span class="ui-spinner ui-state-default ui-widget ui-widget-content ui-corner-all"></span>'; + return "<span class='ui-spinner ui-state-default ui-widget ui-widget-content ui-corner-all'></span>"; }, - + _buttonHtml: function() { - return '<a class="ui-spinner-button ui-spinner-up ui-corner-tr"><span class="ui-icon ui-icon-triangle-1-n">▲</span></a>' + - '<a class="ui-spinner-button ui-spinner-down ui-corner-br"><span class="ui-icon ui-icon-triangle-1-s">▼</span></a>'; + return "" + + "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + + "<span class='ui-icon ui-icon-triangle-1-n'>▲</span>" + + "</a>" + + "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + + "<span class='ui-icon ui-icon-triangle-1-s'>▼</span>" + + "</a>"; }, - - _start: function(event) { - if (!this.spinning && this._trigger('start', event) !== false) { - if (!this.counter) { - this.counter = 1; - } - this.spinning = true; - return true; + + _start: function( event ) { + if ( !this.spinning && this._trigger( "start", event ) === false ) { + return false; + } + + if ( !this.counter ) { + this.counter = 1; } - return false; + this.spinning = true; + return true; }, - - _repeat: function(i, steps, event) { + + _repeat: function( i, steps, event ) { var self = this; i = i || 500; - clearTimeout(this.timer); + clearTimeout( this.timer ); this.timer = setTimeout(function() { - self._repeat(40, steps, event); - }, i); - - self._spin(steps * self.options.step, event); + self._repeat( 40, steps, event ); + }, i ); + + self._spin( steps * self.options.step, event ); }, - - _spin: function(step, event) { - if (!this.counter) { + + _spin: function( step, event ) { + if ( !this.counter ) { this.counter = 1; } - + // TODO refactor, maybe figure out some non-linear math var newVal = this.value() + step * (this.options.incremental && this.counter > 20 ? this.counter > 100 ? this.counter > 200 - ? 100 + ? 100 : 10 : 2 : 1); - - if (this._trigger('spin', event, { value: newVal }) !== false) { - this.value(newVal); - this.counter++; + + if ( this._trigger( "spin", event, { value: newVal } ) !== false) { + this.value( newVal ); + this.counter++; } }, - - _stop: function(event) { + + _stop: function( event ) { this.counter = 0; - if (this.timer) { - window.clearTimeout(this.timer); + if ( this.timer ) { + clearTimeout( this.timer ); } this.element.focus(); this.spinning = false; - this._trigger('stop', event); + this._trigger( "stop", event ); }, - - _change: function(event) { - this._trigger('change', event); + + _change: function( event ) { + this._trigger( "change", event ); }, - - _setOption: function(key, value) { - if (key == 'value') { - value = this._parse(value); - if (value < this.options.min) { + + _setOption: function( key, value ) { + if ( key === "value") { + value = this._parse( value ); + if ( value < this.options.min ) { value = this.options.min; } - if (value > this.options.max) { + if ( value > this.options.max ) { value = this.options.max; } } - if (key == 'disabled') { - if (value) { - this.element.attr("disabled", true); - this.buttons.button("disable"); + + if ( key === "disabled" ) { + if ( value ) { + this.element.attr( "disabled", true ); + this.buttons.button( "disable" ); } else { - this.element.removeAttr("disabled"); - this.buttons.button("enable"); + this.element.removeAttr( "disabled" ); + this.buttons.button( "enable" ); } } + this._super( "_setOption", key, value ); }, - + _setOptions: function( options ) { this._super( "_setOptions", options ); if ( "value" in options ) { @@ -296,67 +309,65 @@ $.widget('ui.spinner', { } this._aria(); }, - + _aria: function() { - this.element - .attr('aria-valuemin', this.options.min) - .attr('aria-valuemax', this.options.max) - .attr('aria-valuenow', this.options.value); + this.element.attr({ + "aria-valuemin": this.options.min, + "aria-valuemax": this.options.max, + "aria-valuenow": this.options.value + }); }, - - _parse: function(val) { - var input = val; - if (typeof val == 'string') { - val = $.global && this.options.numberformat ? $.global.parseFloat(val) : +val; + + _parse: function( val ) { + if ( typeof val === "string" ) { + val = $.global && this.options.numberFormat ? $.global.parseFloat( val ) : +val; } - return isNaN(val) ? null : val; + return isNaN( val ) ? null : val; }, - - _format: function(num) { - this.element.val( $.global && this.options.numberformat ? $.global.format(num, this.options.numberformat) : num ); + + _format: function( num ) { + this.element.val( $.global && this.options.numberFormat ? $.global.format( num, this.options.numberFormat ) : num ); }, - + destroy: function() { this.element - .removeClass('ui-spinner-input') - .removeAttr('disabled') - .removeAttr('autocomplete') - .removeAttr('role') - .removeAttr('aria-valuemin') - .removeAttr('aria-valuemax') - .removeAttr('aria-valuenow'); + .removeClass( "ui-spinner-input" ) + .removeAttr( "disabled" ) + .removeAttr( "autocomplete" ) + .removeAttr( "role" ) + .removeAttr( "aria-valuemin" ) + .removeAttr( "aria-valuemax" ) + .removeAttr( "aria-valuenow" ); this._super( "destroy" ); - this.uiSpinner.replaceWith(this.element); + this.uiSpinner.replaceWith( this.element ); }, - - stepUp: function(steps) { - this._spin((steps || 1) * this.options.step); + + stepUp: function( steps ) { + this._spin( (steps || 1) * this.options.step ); }, - - stepDown: function(steps) { - this._spin((steps || 1) * -this.options.step); + + stepDown: function( steps ) { + this._spin( (steps || 1) * -this.options.step ); }, - - pageUp: function(pages) { - this.stepUp((pages || 1) * this.options.page); + + pageUp: function( pages ) { + this.stepUp( (pages || 1) * this.options.page ); }, - - pageDown: function(pages) { - this.stepDown((pages || 1) * this.options.page); + + pageDown: function( pages ) { + this.stepDown( (pages || 1) * this.options.page ); }, - - value: function(newVal) { - if (!arguments.length) { - return this._parse(this.element.val()); + + value: function( newVal ) { + if ( !arguments.length ) { + return this._parse( this.element.val() ); } - this.option('value', newVal); + this.option( "value", newVal ); }, - + widget: function() { return this.uiSpinner; } }); -$.ui.spinner.version = "@VERSION"; - -})(jQuery); +}( jQuery ) ); diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index cce50d3e7..515a93ae0 100644 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -13,18 +13,13 @@ */ (function( $, undefined ) { -var tabId = 0, - listId = 0; - +var tabId = 0; function getNextTabId() { return ++tabId; } -function getNextListId() { - return ++listId; -} - $.widget( "ui.tabs", { + version: "@VERSION", options: { active: null, collapsible: false, @@ -150,7 +145,7 @@ $.widget( "ui.tabs", { _sanitizeSelector: function( hash ) { // we need this because an id may contain a ":" - return hash ? hash.replace( /:/g, "\\:" ) : ""; + return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@[\]^`{|}~]/g, "\\$&" ) : ""; }, refresh: function() { @@ -292,61 +287,13 @@ $.widget( "ui.tabs", { } }, - // Reset certain styles left over from animation - // and prevent IE's ClearType bug... + // TODO: remove once jQuery core properly removes filters - see #4621 _resetStyle: function ( $el, fx ) { - $el.css( "display", "" ); if ( !$.support.opacity && fx.opacity ) { $el[ 0 ].style.removeAttribute( "filter" ); } }, - _showTab: function( event, eventData ) { - var that = this; - - $( eventData.newTab ).closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); - - if ( that.showFx ) { - that.running = true; - eventData.newPanel - // TODO: why are we hiding? old code? - .hide() - .animate( that.showFx, that.showFx.duration || "normal", function() { - that._resetStyle( $( this ), that.showFx ); - that.running = false; - that._trigger( "activate", event, eventData ); - }); - } else { - eventData.newPanel.show(); - that._trigger( "activate", event, eventData ); - } - }, - - // TODO: combine with _showTab() - _hideTab: function( event, eventData ) { - var that = this; - - if ( that.hideFx ) { - that.running = true; - eventData.oldPanel.animate( that.hideFx, that.hideFx.duration || "normal", function() { - that.running = false; - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); - that._resetStyle( $( this ), that.hideFx ); - that.element.dequeue( "tabs" ); - if ( !eventData.newPanel.length ) { - that._trigger( "activate", event, eventData ); - } - }); - } else { - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); - eventData.oldPanel.hide(); - that.element.dequeue( "tabs" ); - if ( !eventData.newPanel.length ) { - that._trigger( "activate", event, eventData ); - } - } - }, - _setupEvents: function( event ) { // attach tab event handler, unbind to avoid duplicates from former tabifying... this.anchors.unbind( ".tabs" ); @@ -401,52 +348,60 @@ $.widget( "ui.tabs", { that.xhr.abort(); } - // if tab may be closed - if ( options.collapsible ) { - if ( collapsing ) { - options.active = false; + if ( !toHide.length && !toShow.length ) { + throw "jQuery UI Tabs: Mismatching fragment identifier."; + } - that.element.queue( "tabs", function() { - that._hideTab( event, eventData ); - }).dequeue( "tabs" ); + if ( toShow.length ) { - 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 ); - // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 - that.load( that.anchors.index( clicked ), event ); + clicked[ 0 ].blur(); + } + that._toggle( event, eventData ); + }, - clicked[ 0 ].blur(); - return; - } + // handles show/hide for selecting tabs + _toggle: function( event, eventData ) { + var that = this, + options = that.options, + toShow = eventData.newPanel, + toHide = eventData.oldPanel; + + that.running = true; + + function complete() { + that.running = false; + that._trigger( "activate", event, eventData ); } - // show new tab - if ( toShow.length ) { - if ( toHide.length ) { - that.element.queue( "tabs", function() { - that._hideTab( event, eventData ); - }); - } - that.element.queue( "tabs", function() { - that._showTab( event, eventData ); - }); + function show() { + eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); - that.load( that.anchors.index( clicked ), event ); - } else { - throw "jQuery UI Tabs: Mismatching fragment identifier."; + if ( toShow.length && that.showFx ) { + toShow + .animate( that.showFx, that.showFx.duration || "normal", function() { + that._resetStyle( $( this ), that.showFx ); + complete(); + }); + } else { + toShow.show(); + complete(); + } } - // 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(); + // start out by hiding, then showing, then completing + if ( toHide.length && that.hideFx ) { + toHide.animate( that.hideFx, that.hideFx.duration || "normal", function() { + eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); + that._resetStyle( $( this ), that.hideFx ); + show(); + }); + } else { + eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); + toHide.hide(); + show(); } }, @@ -569,24 +524,19 @@ $.widget( "ui.tabs", { load: function( index, event ) { index = this._getIndex( index ); var self = this, - o = this.options, - a = this.anchors.eq( index )[ 0 ], - panel = self._getPanelForTab( a ), + options = this.options, + anchor = this.anchors.eq( index ), + panel = self._getPanelForTab( anchor ), // TODO until #3808 is fixed strip fragment identifier from url // (IE fails to load from such url) - url = $( a ).attr( "href" ).replace( /#.*$/, "" ), + url = anchor.attr( "href" ).replace( /#.*$/, "" ), eventData = { - tab: $( a ), + tab: anchor, panel: panel }; - if ( this.xhr ) { - this.xhr.abort(); - } - // not remote if ( !url ) { - this.element.dequeue( "tabs" ); return; } @@ -599,7 +549,6 @@ $.widget( "ui.tabs", { }); if ( this.xhr ) { - // load remote from here on this.lis.eq( index ).addClass( "ui-tabs-loading" ); this.xhr @@ -609,24 +558,17 @@ $.widget( "ui.tabs", { }) .complete(function( jqXHR, status ) { if ( status === "abort" ) { - // stop possibly running animations - self.element.queue( [] ); self.panels.stop( false, true ); - - // "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 ) ); } self.lis.eq( index ).removeClass( "ui-tabs-loading" ); - delete self.xhr; + if ( jqXHR === self.xhr ) { + delete self.xhr; + } }); } - // last, so that load event is fired before show... - self.element.dequeue( "tabs" ); - return this; }, @@ -636,10 +578,6 @@ $.widget( "ui.tabs", { } }); -$.extend( $.ui.tabs, { - version: "@VERSION" -}); - // DEPRECATED if ( $.uiBackCompat !== false ) { @@ -677,7 +615,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(); @@ -825,20 +763,30 @@ if ( $.uiBackCompat !== false ) { li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true ); li.find( "a" ).attr( "aria-controls", id ); + var doInsertAfter = index >= this.lis.length; + // try to find an existing element before creating a new one var panel = this.element.find( "#" + id ); if ( !panel.length ) { panel = this._createPanel( id ); + if ( doInsertAfter ) { + if ( index > 0 ) { + panel.insertAfter( this.panels.eq( -1 ) ); + } else { + panel.appendTo( this.element ); + } + } else { + panel.insertBefore( this.panels[ index ] ); + } } panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide(); - if ( index >= this.lis.length ) { + if ( doInsertAfter ) { li.appendTo( this.list ); - panel.appendTo( this.list[ 0 ].parentNode ); } else { li.insertBefore( this.lis[ index ] ); - panel.insertBefore( this.panels[ index ] ); } + options.disabled = $.map( options.disabled, function( n ) { return n >= index ? ++n : n; }); @@ -970,7 +918,7 @@ if ( $.uiBackCompat !== 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 ) { @@ -1008,6 +956,10 @@ if ( $.uiBackCompat !== false ) { }( jQuery, jQuery.ui.tabs.prototype ) ); // cookie option + 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 } @@ -1052,6 +1004,18 @@ if ( $.uiBackCompat !== false ) { } } }); + + // load event + $.widget( "ui.tabs", $.ui.tabs, { + _trigger: function( type, event, data ) { + var _data = $.extend( {}, data ); + if ( type === "load" ) { + _data.panel = _data.panel[ 0 ]; + _data.tab = _data.tab[ 0 ]; + } + return this._super( "_trigger", type, event, _data ); + } + }); } })( jQuery ); diff --git a/ui/jquery.ui.tooltip.js b/ui/jquery.ui.tooltip.js index a8a44f1c0..f19061bc3 100644 --- a/ui/jquery.ui.tooltip.js +++ b/ui/jquery.ui.tooltip.js @@ -12,136 +12,205 @@ * jquery.ui.widget.js * jquery.ui.position.js */ -(function($) { +(function( $ ) { var increments = 0; -$.widget("ui.tooltip", { +$.widget( "ui.tooltip", { + version: "@VERSION", options: { - tooltipClass: null, - items: "[title]", content: function() { return $( this ).attr( "title" ); }, + hide: true, + items: "[title]", position: { my: "left+15 center", - at: "right center" - } + at: "right center", + collision: "flip fit" + }, + show: true, + tooltipClass: null, + + // callbacks + close: null, + open: null }, + _create: function() { - this._bind( { + this._bind({ mouseover: "open", focusin: "open" }); + + // IDs of generated tooltips, needed for destroy + this.tooltips = {}; }, - - enable: function() { - this.options.disabled = false; + + _setOption: function( key, value ) { + if ( key === "disabled" ) { + this[ value ? "_disable" : "_enable" ](); + this.options[ key ] = value; + // disable element style changes + return; + } + this._super( "_setOption", key, value ); }, - - disable: function() { - // only set option, disable element style changes - this.options.disabled = true; + + _disable: function() { + var that = this; + + // close open tooltips + $.each( this.tooltips, function( id, element ) { + var event = $.Event( "blur" ); + event.target = event.currentTarget = element[0]; + that.close( event, true ); + }); + + // remove title attributes to prevent native tooltips + this.element.find( this.options.items ).andSelf().each(function() { + var element = $( this ); + if ( element.is( "[title]" ) ) { + element + .data( "tooltip-title", element.attr( "title" ) ) + .attr( "title", "" ); + } + }); }, - - open: function(event) { - var target = $(event && event.target || this.element).closest(this.options.items); - if ( !target.length ) { + + _enable: function() { + // restore title attributes + this.element.find( this.options.items ).andSelf().each(function() { + var element = $( this ); + if ( element.data( "tooltip-title" ) ) { + element.attr( "title", element.data( "tooltip-title" ) ); + } + }); + }, + + open: function( event ) { + var content, + that = this, + target = $( event ? event.target : this.element ) + .closest( this.options.items ); + + // if aria-describedby exists, then the tooltip is already open + if ( !target.length || target.attr( "aria-describedby" ) ) { return; } - var self = this; - if ( !target.data("tooltip-title") ) { - target.data("tooltip-title", target.attr("title")); + + if ( !target.data( "tooltip-title" ) ) { + target.data( "tooltip-title", target.attr( "title" ) ); } - var content = this.options.content.call(target[0], function(response) { - // IE may instantly serve a cached response, need to give it a chance to finish with _open before that + + content = this.options.content.call( target[0], function( response ) { + // IE may instantly serve a cached response for ajax requests + // delay this call to _open so the other call to _open runs first setTimeout(function() { - // when undefined, it got removeAttr, then ignore (ajax response) - // intially its an empty string, so not undefined - // TODO is there a better approach to enable ajax tooltips to have two updates? - if (target.attr( "aria-describedby" ) !== undefined) { - self._open(event, target, response); - } - }, 13); + that._open( event, target, response ); + }, 1 ); }); - if (content) { - self._open(event, target, content); + if ( content ) { + that._open( event, target, content ); } }, - + _open: function( event, target, content ) { - if ( !content ) + if ( !content ) { return; + } - target.attr("title", ""); - - if ( this.options.disabled ) - return; + // if we have a title, clear it to prevent the native tooltip + // we have to check first to avoid defining a title if none exists + // (we don't want to cause an element to start matching [title]) + // TODO: document why we don't use .removeAttr() + if ( target.is( "[title]" ) ) { + target.attr( "title", "" ); + } // ajaxy tooltip can update an existing one var tooltip = this._find( target ); - if (!tooltip.length) { - tooltip = this._tooltip(); + if ( !tooltip.length ) { + tooltip = this._tooltip( target ); target.attr( "aria-describedby", tooltip.attr( "id" ) ); } - tooltip.find(".ui-tooltip-content").html( content ); - tooltip.position( $.extend({ - of: target - }, this.options.position ) ).hide(); + tooltip.find( ".ui-tooltip-content" ).html( content ); + tooltip + .stop( true ) + .position( $.extend({ + of: target + }, this.options.position ) ) + .hide(); - tooltip.stop( true ); this._show( tooltip, this.options.show ); - this._trigger( "open", event ); + this._trigger( "open", event, { tooltip: tooltip } ); this._bind( target, { mouseleave: "close", - blur: "close", - click: "close" + blur: "close" }); }, - - close: function( event ) { - var target = $( event && event.currentTarget || this.element ); - target.attr( "title", target.data( "tooltip-title" ) ); - - if ( this.options.disabled ) + + close: function( event, force ) { + var that = this, + target = $( event ? event.currentTarget : this.element ), + tooltip = this._find( target ); + + // don't close if the element has focus + // this prevents the tooltip from closing if you hover while focused + if ( !force && document.activeElement === target[0] ) { return; + } + + // only set title if we had one before (see comment in _open()) + if ( target.data( "tooltip-title" ) ) { + target.attr( "title", target.data( "tooltip-title" ) ); + } - var tooltip = this._find( target ); target.removeAttr( "aria-describedby" ); - + tooltip.stop( true ); this._hide( tooltip, this.options.hide, function() { $( this ).remove(); + delete that.tooltips[ this.id ]; }); - + target.unbind( "mouseleave.tooltip blur.tooltip" ); - - this._trigger( "close", event ); + + this._trigger( "close", event, { tooltip: tooltip } ); }, - _tooltip: function() { - var tooltip = $( "<div></div>" ) - .attr( "id", "ui-tooltip-" + increments++ ) - .attr( "role", "tooltip" ) - .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content" ); - if (this.options.tooltipClass) { - tooltip.addClass(this.options.tooltipClass); - } - $( "<div></div>" ) + _tooltip: function( element ) { + var id = "ui-tooltip-" + increments++, + tooltip = $( "<div>" ) + .attr({ + id: id, + role: "tooltip" + }) + .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + + ( this.options.tooltipClass || "" ) ); + $( "<div>" ) .addClass( "ui-tooltip-content" ) .appendTo( tooltip ); tooltip.appendTo( document.body ); + if ( $.fn.bgiframe ) { + tooltip.bgiframe(); + } + this.tooltips[ id ] = element; return tooltip; }, _find: function( target ) { var id = target.attr( "aria-describedby" ); - return id ? $( document.getElementById( id ) ) : $(); + return id ? $( "#" + id ) : $(); + }, + + _destroy: function() { + $.each( this.tooltips, function( id ) { + $( "#" + id ).remove(); + }); } }); -$.ui.tooltip.version = "@VERSION"; - -})(jQuery);
\ No newline at end of file +}( jQuery ) ); diff --git a/ui/jquery.ui.widget.js b/ui/jquery.ui.widget.js index a74e6b77b..59d110b6a 100644 --- a/ui/jquery.ui.widget.js +++ b/ui/jquery.ui.widget.js @@ -49,13 +49,13 @@ $.widget = function( name, base, prototype ) { if ( arguments.length ) { this._createWidget( options, element ); } - }, $[ namespace ][ name ] ); + }, $[ namespace ][ name ], { version: prototype.version } ); var basePrototype = new base(); // 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 ) { @@ -116,7 +133,7 @@ $.widget.bridge = function( name, object ) { } var methodValue = instance[ options ].apply( instance, args ); if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue.jquery ? + returnValue = methodValue && methodValue.jquery ? returnValue.pushStack( methodValue.get() ) : methodValue; return false; @@ -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,25 +235,29 @@ $.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" ) { - if ( value === undefined ) { - return this.options[ key ]; - } // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } options = {}; 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 ] ]; } - curOption[ parts.pop() ] = value; + key = parts.pop(); + if ( value === undefined ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; } else { + if ( value === undefined ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } options[ key ] = value; } } @@ -358,11 +379,22 @@ $.Widget.prototype = { $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + var hasOptions, + effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; options = options || {}; - var hasOptions = !$.isEmptyObject( options ), - effectName = options.effect || defaultEffect; + if ( typeof options === "number" ) { + options = { duration: options }; + } + hasOptions = !$.isEmptyObject( options ); options.complete = callback; - if (options.delay) { + if ( options.delay ) { element.delay( options.delay ); } if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) { @@ -370,11 +402,12 @@ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { } else if ( effectName !== method && element[ effectName ] ) { element[ effectName ]( options.duration, options.easing, callback ); } else { - element.queue( function() { + element.queue(function( next ) { $( this )[ method ](); if ( callback ) { callback.call( element[ 0 ] ); } + next(); }); } }; |