aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Nagel <info@felixnagel.com>2015-12-02 18:20:54 +0100
committerFelix Nagel <info@felixnagel.com>2015-12-02 18:30:05 +0100
commitc10ef0a170218ae64abaee54518b09068eadb51e (patch)
tree8ff6c9cb8e0f4a8846a3b272a26e65fef946ae3c
parent7ed45541096b58c56c4fc40b1a0ca9c10b2fe229 (diff)
parent6c738d961d9918f75a3043a49ab21ac79bca45ae (diff)
downloadjquery-ui-c10ef0a170218ae64abaee54518b09068eadb51e.tar.gz
jquery-ui-c10ef0a170218ae64abaee54518b09068eadb51e.zip
Merge branch 'master' into datepicker
-rw-r--r--.csslintrc1
-rw-r--r--.travis.yml3
-rw-r--r--AUTHORS.txt24
-rw-r--r--Gruntfile.js38
-rw-r--r--build/release-test.js47
-rw-r--r--build/release.js50
-rw-r--r--build/tasks/testswarm.js11
-rw-r--r--demos/bootstrap.js4
-rw-r--r--demos/button/checkbox.html38
-rw-r--r--demos/button/default.html33
-rw-r--r--demos/button/icons.html83
-rw-r--r--demos/button/index.html4
-rw-r--r--demos/button/radio.html33
-rw-r--r--demos/button/splitbutton.html70
-rw-r--r--demos/button/toolbar.html115
-rw-r--r--demos/checkboxradio/default.html63
-rw-r--r--demos/checkboxradio/images/jquery-mobile.pngbin0 -> 6296 bytes
-rw-r--r--demos/checkboxradio/images/jquery-ui.pngbin0 -> 7044 bytes
-rw-r--r--demos/checkboxradio/images/jquery.pngbin0 -> 7206 bytes
-rw-r--r--demos/checkboxradio/images/qunit.pngbin0 -> 6740 bytes
-rw-r--r--demos/checkboxradio/images/sizzle.pngbin0 -> 8875 bytes
-rw-r--r--demos/checkboxradio/index.html18
-rw-r--r--demos/checkboxradio/no-icons.html65
-rw-r--r--demos/checkboxradio/product-selector.html138
-rw-r--r--demos/checkboxradio/radiogroup.html33
-rw-r--r--demos/controlgroup/default.html86
-rw-r--r--demos/controlgroup/index.html17
-rw-r--r--demos/controlgroup/splitbutton.html48
-rw-r--r--demos/controlgroup/toolbar.html277
-rw-r--r--demos/draggable/constrain-movement.html4
-rw-r--r--demos/index.html2
-rw-r--r--demos/tooltip/video-player.html8
-rw-r--r--demos/widget/default.html1
-rw-r--r--package.json1
-rw-r--r--tests/lib/bootstrap.js2
-rw-r--r--tests/lib/common.js4
-rw-r--r--tests/lib/qunit.js2
-rw-r--r--tests/unit/autocomplete/core.js24
-rw-r--r--tests/unit/button/button.html48
-rw-r--r--tests/unit/button/common-deprecated.js27
-rw-r--r--tests/unit/button/common.js12
-rw-r--r--tests/unit/button/core.js221
-rw-r--r--tests/unit/button/deprecated.html61
-rw-r--r--tests/unit/button/deprecated.js196
-rw-r--r--tests/unit/button/events.js31
-rw-r--r--tests/unit/button/methods.js51
-rw-r--r--tests/unit/button/options.js231
-rw-r--r--tests/unit/checkboxradio/all.html26
-rw-r--r--tests/unit/checkboxradio/checkboxradio.html76
-rw-r--r--tests/unit/checkboxradio/common.js22
-rw-r--r--tests/unit/checkboxradio/core.js136
-rw-r--r--tests/unit/checkboxradio/events.js42
-rw-r--r--tests/unit/checkboxradio/methods.js96
-rw-r--r--tests/unit/checkboxradio/options.js205
-rw-r--r--tests/unit/controlgroup/all.html26
-rw-r--r--tests/unit/controlgroup/common.js28
-rw-r--r--tests/unit/controlgroup/controlgroup.html41
-rw-r--r--tests/unit/controlgroup/core.js76
-rw-r--r--tests/unit/controlgroup/methods.js150
-rw-r--r--tests/unit/controlgroup/options.js109
-rw-r--r--tests/unit/date/core.js2
-rw-r--r--tests/unit/dialog/options.js25
-rw-r--r--tests/unit/draggable/core.js23
-rw-r--r--tests/unit/draggable/draggable.html24
-rw-r--r--tests/unit/draggable/options.js2
-rw-r--r--tests/unit/index.html2
-rw-r--r--tests/unit/selectmenu/core.js30
-rw-r--r--tests/unit/selectmenu/methods.js12
-rw-r--r--tests/unit/selectmenu/selectmenu.html7
-rw-r--r--tests/unit/slider/methods.js52
-rw-r--r--tests/unit/sortable/options.js2
-rw-r--r--tests/unit/subsuite.js2
-rw-r--r--tests/unit/tabs/helper.js5
-rw-r--r--tests/visual/button/button.html89
-rw-r--r--tests/visual/button/performance.html21
-rw-r--r--tests/visual/checkboxradio/checkboxradio.html65
-rw-r--r--tests/visual/index.html5
-rw-r--r--themes/base/accordion.css12
-rw-r--r--themes/base/base.css2
-rw-r--r--themes/base/button.css100
-rw-r--r--themes/base/checkboxradio.css34
-rw-r--r--themes/base/controlgroup.css65
-rw-r--r--themes/base/core.css12
-rw-r--r--[-rwxr-xr-x]themes/base/images/ui-icons_444444_256x240.pngbin6992 -> 6992 bytes
-rw-r--r--[-rwxr-xr-x]themes/base/images/ui-icons_555555_256x240.pngbin6988 -> 6988 bytes
-rw-r--r--[-rwxr-xr-x]themes/base/images/ui-icons_777620_256x240.pngbin4549 -> 4549 bytes
-rw-r--r--[-rwxr-xr-x]themes/base/images/ui-icons_777777_256x240.pngbin6999 -> 6999 bytes
-rw-r--r--[-rwxr-xr-x]themes/base/images/ui-icons_cc0000_256x240.pngbin4549 -> 4549 bytes
-rw-r--r--[-rwxr-xr-x]themes/base/images/ui-icons_ffffff_256x240.pngbin6299 -> 6299 bytes
-rw-r--r--themes/base/selectmenu.css21
-rw-r--r--themes/base/spinner.css23
-rw-r--r--themes/base/theme.css57
-rw-r--r--ui/core.js15
-rw-r--r--ui/effects/effect-transfer.js4
-rw-r--r--ui/form-reset-mixin.js14
-rw-r--r--ui/jquery-1-7.js2
-rw-r--r--ui/position.js2
-rw-r--r--ui/widget.js2
-rw-r--r--ui/widgets/accordion.js6
-rw-r--r--ui/widgets/autocomplete.js47
-rw-r--r--ui/widgets/button.js605
-rw-r--r--ui/widgets/checkboxradio.js277
-rw-r--r--ui/widgets/controlgroup.js251
-rw-r--r--ui/widgets/dialog.js27
-rw-r--r--ui/widgets/draggable.js6
-rw-r--r--ui/widgets/menu.js6
-rw-r--r--ui/widgets/mouse.js16
-rw-r--r--ui/widgets/progressbar.js6
-rw-r--r--ui/widgets/resizable.js33
-rw-r--r--ui/widgets/selectable.js2
-rw-r--r--ui/widgets/selectmenu.js24
-rw-r--r--ui/widgets/slider.js6
-rw-r--r--ui/widgets/sortable.js2
-rw-r--r--ui/widgets/spinner.js40
-rw-r--r--ui/widgets/tabs.js6
-rw-r--r--ui/widgets/tooltip.js9
116 files changed, 3857 insertions, 1503 deletions
diff --git a/.csslintrc b/.csslintrc
index 5d9db072c..4273f5cc6 100644
--- a/.csslintrc
+++ b/.csslintrc
@@ -1,6 +1,7 @@
{
"adjoining-classes": false,
"box-model": false,
+ "box-sizing": false,
"compatible-vendor-prefixes": false,
"duplicate-background-images": false,
"import": false,
diff --git a/.travis.yml b/.travis.yml
index 6ef04eb80..25350d712 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,6 @@
+sudo: false
language: node_js
node_js:
- - "0.10"
+ - "0.12"
before_script:
- npm install -g grunt-cli
diff --git a/AUTHORS.txt b/AUTHORS.txt
index 47fbf79b9..2e124d3d4 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -289,3 +289,27 @@ Simen Bekkhus <sbekkhus91@gmail.com>
Chen Eshchar <eshcharc@gmail.com>
Bruno Pérel <brunoperel@gmail.com>
Mohammed Alshehri <m@dralshehri.com>
+Lisa Seacat DeLuca <ldeluca@us.ibm.com>
+Anne-Gaelle Colom <coloma@westminster.ac.uk>
+Adam Foster <slimfoster@gmail.com>
+Luke Page <luke.a.page@gmail.com>
+Daniel Owens <daniel@matchstickmixup.com>
+Michael Orchard <morchard@scottlogic.co.uk>
+Marcus Warren <marcus@envoke.com>
+Nils Heuermann <nils@world-of-scripts.de>
+Marco Ziech <marco@ziech.net>
+Patricia Juarez <patrixd@gmail.com>
+Ben Mosher <me@benmosher.com>
+Ablay Keldibek <atomio.ak@gmail.com>
+Thomas Applencourt <thomas.applencourt@irsamc.ups-tlse.fr>
+Jiabao Wu <jiabao.foss@gmail.com>
+Eric Lee Carraway <github@ericcarraway.com>
+Victor Homyakov <vkhomyackov@gmail.com>
+Myeongjin Lee <aranet100@gmail.com>
+Liran Sharir <lsharir@gmail.com>
+Weston Ruter <weston@xwp.co>
+Mani Mishra <manimishra902@gmail.com>
+Hannah Methvin <hannahmethvin@gmail.com>
+Leonardo Balter <leonardo.balter@gmail.com>
+Benjamin Albert <benjamin_a5@yahoo.com>
+Michał Gołębiowski <m.goleb@gmail.com>
diff --git a/Gruntfile.js b/Gruntfile.js
index 7426b7fb4..b7ace6cfd 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -24,6 +24,31 @@ var
allI18nFiles = expandFiles( "ui/i18n/*.js" ),
+ cssFiles = [
+ "core",
+ "accordion",
+ "autocomplete",
+ "button",
+ "checkboxradio",
+ "controlgroup",
+ "datepicker",
+ "dialog",
+ "draggable",
+ "menu",
+ "progressbar",
+ "resizable",
+ "selectable",
+ "selectmenu",
+ "sortable",
+ "slider",
+ "spinner",
+ "tabs",
+ "tooltip",
+ "theme"
+ ].map(function( component ) {
+ return "themes/base/" + component + ".css";
+ }),
+
// minified files
minify = {
options: {
@@ -113,6 +138,18 @@ grunt.initConfig({
dist: "<%= pkg.name %>-<%= pkg.version %>"
},
compare_size: compareFiles,
+ concat: {
+ css: {
+ options: {
+ banner: createBanner( cssFiles ),
+ stripBanners: {
+ block: true
+ }
+ },
+ src: cssFiles,
+ dest: "dist/jquery-ui.css"
+ }
+ },
requirejs: {
js: {
options: {
@@ -436,6 +473,7 @@ grunt.registerTask( "compile-globalize", function() {
});
grunt.registerTask( "default", [ "lint", "requirejs", "test" ]);
+grunt.registerTask( "jenkins", [ "default", "concat" ]);
grunt.registerTask( "lint", [ "asciilint", "jshint", "jscs", "csslint", "htmllint" ]);
grunt.registerTask( "test", [ "qunit" ]);
grunt.registerTask( "sizer", [ "requirejs:js", "uglify:main", "compare_size:all" ]);
diff --git a/build/release-test.js b/build/release-test.js
new file mode 100644
index 000000000..be5227a43
--- /dev/null
+++ b/build/release-test.js
@@ -0,0 +1,47 @@
+var shell = require( "shelljs" );
+var Release = {
+ define: function( props ) {
+ for ( var key in props ) {
+ Release[ key ] = props[ key ];
+ }
+ },
+ exec: function( _options, errorMessage ) {
+ var result,
+ command = _options.command || _options,
+ options = {};
+
+ if ( _options.silent ) {
+ options.silent = true;
+ }
+
+ errorMessage = errorMessage || "Error executing command: " + command;
+
+ result = shell.exec( command, options );
+ if ( result.code !== 0 ) {
+ Release.abort( errorMessage );
+ }
+
+ return result.output;
+ },
+ abort: function() {
+ console.error.apply( console, arguments );
+ process.exit( 1 );
+ },
+ newVersion: require( "../package" ).version
+};
+
+var script = require( "./release" );
+script( Release );
+
+// Ignores actual version installed, should be good enough for a test
+if ( shell.exec( "npm ls --depth 0 | grep download.jqueryui.com" ).code === 1 ) {
+ shell.exec( "npm install " + script.dependencies.join( " " ) );
+}
+
+// If AUTHORS.txt is outdated, this will update it
+// Very annoying during an actual release
+shell.exec( "grunt update-authors" );
+
+Release.generateArtifacts( function() {
+ console.log( "Done generating artifacts, verify output, should be in dist/cdn" );
+} );
diff --git a/build/release.js b/build/release.js
index 48915b08d..b868cbebd 100644
--- a/build/release.js
+++ b/build/release.js
@@ -1,5 +1,6 @@
module.exports = function( Release ) {
+var crypto = require( "crypto" );
var shell = require( "shelljs" ),
path = require( "path" ),
fs = require( "fs" );
@@ -34,23 +35,41 @@ function replaceAtVersion() {
return matches;
}
+function addManifest( packager ) {
+ var output = packager.builtFiles;
+ output.MANIFEST = Object.keys( output ).sort( function( a, b ) {
+ return a.localeCompare( b );
+ } ).map( function( filepath ) {
+ var md5 = crypto.createHash( "md5" );
+ md5.update( output[ filepath ] );
+ return filepath + " " + md5.digest( "hex" );
+ } ).join( "\n" );
+}
+
function buildCDNPackage( callback ) {
console.log( "Building CDN package" );
- var downloadBuilder = require( "download.jqueryui.com" ),
- jqueryUi = new downloadBuilder.JqueryUi( path.resolve( "." ) ),
- builder = new downloadBuilder.Builder( jqueryUi, ":all:" ),
- packer = new downloadBuilder.ThemesPacker( builder, {
- includeJs: true
+ var JqueryUi = require( "download.jqueryui.com/lib/jquery-ui" );
+ var Package = require( "download.jqueryui.com/lib/package-1-12-themes" );
+ var Packager = require( "node-packager" );
+ var jqueryUi = new JqueryUi( path.resolve( "." ) );
+ var target = fs.createWriteStream( "../" + jqueryUi.pkg.name + "-" + jqueryUi.pkg.version + "-cdn.zip" );
+ var packager = new Packager( jqueryUi.files().cache, Package, {
+ components: jqueryUi.components().map( function( component ) {
+ return component.name;
} ),
- target = "../" + jqueryUi.pkg.name + "-" + jqueryUi.pkg.version + "-cdn.zip";
-
- // Zip dir structure must be flat, override default base folder
- packer.basedir = "";
- packer.zipTo( target, function( error ) {
- if ( error ) {
- Release.abort( "Failed to zip CDN package", error );
- }
- callback();
+ jqueryUi: jqueryUi,
+ themeVars: null
+ } );
+ packager.ready.then( function() {
+ addManifest( packager );
+ packager.toZip( target, {
+ basedir: ""
+ }, function( error ) {
+ if ( error ) {
+ Release.abort( "Failed to zip CDN package", error );
+ }
+ callback();
+ } );
} );
}
@@ -91,6 +110,7 @@ Release.define( {
};
module.exports.dependencies = [
- "download.jqueryui.com@2.0.15",
+ "download.jqueryui.com@2.1.2",
+ "node-packager@0.0.6",
"shelljs@0.2.6"
];
diff --git a/build/tasks/testswarm.js b/build/tasks/testswarm.js
index b889c6c36..1ef2f0e92 100644
--- a/build/tasks/testswarm.js
+++ b/build/tasks/testswarm.js
@@ -3,7 +3,7 @@ module.exports = function( grunt ) {
"use strict";
var versions = {
- "compat-git": "compat-git",
+ "git": "git",
"1.11": "1.11.0 1.11.1 1.11.2 1.11.3",
"1.10": "1.10.0 1.10.2",
"1.9": "1.9.0 1.9.1",
@@ -39,9 +39,16 @@ function submit( commit, runs, configFile, extra, done ) {
var testName,
testswarm = require( "testswarm" ),
config = grunt.file.readJSON( configFile ).jqueryui,
+ browserSets = config.browserSets,
commitUrl = "https://github.com/jquery/jquery-ui/commit/" + commit;
if ( extra ) {
+
+ // jquery-git doesn't support IE 8.
+ if ( extra === "core git" ) {
+ browserSets = "jquery-ui-future";
+ }
+
extra = " (" + extra + ")";
}
@@ -61,7 +68,7 @@ function submit( commit, runs, configFile, extra, done ) {
name: "Commit <a href='" + commitUrl + "'>" + commit.substr( 0, 10 ) + "</a>" + extra,
runs: runs,
runMax: config.runMax,
- browserSets: config.browserSets,
+ browserSets: browserSets,
timeout: 1000 * 60 * 30
}, function( error, passed ) {
if ( error ) {
diff --git a/demos/bootstrap.js b/demos/bootstrap.js
index 602afa3e7..0a109ef9e 100644
--- a/demos/bootstrap.js
+++ b/demos/bootstrap.js
@@ -31,6 +31,8 @@ var widgets = [
"autocomplete",
"button",
"calendar",
+ "checkboxradio",
+ "controlgroup",
"datepicker",
"dialog",
"draggable",
@@ -113,7 +115,7 @@ require( modules, function() {
document.documentElement.className = "";
newScript.text = "( function() { " + script.innerHTML + " } )();";
- document.head.appendChild( newScript ).parentNode.removeChild( newScript );
+ document.body.appendChild( newScript ).parentNode.removeChild( newScript );
} );
} )();
diff --git a/demos/button/checkbox.html b/demos/button/checkbox.html
deleted file mode 100644
index 87abbf90f..000000000
--- a/demos/button/checkbox.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery UI Button - Checkboxes</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <script src="../../external/jquery/jquery.js"></script>
- <script src="../../ui/core.js"></script>
- <script src="../../ui/widget.js"></script>
- <script src="../../ui/button.js"></script>
- <link rel="stylesheet" href="../demos.css">
- <script>
- $(function() {
- $( "#check" ).button();
- $( "#format" ).buttonset();
- });
- </script>
- <style>
- #format { margin-top: 2em; }
- </style>
-</head>
-<body>
-
-<input type="checkbox" id="check" /><label for="check">Toggle</label>
-
-<div id="format">
- <input type="checkbox" id="check1" /><label for="check1">B</label>
- <input type="checkbox" id="check2" /><label for="check2">I</label>
- <input type="checkbox" id="check3" /><label for="check3">U</label>
-</div>
-
-<div class="demo-description">
-<p>A checkbox is styled as a toggle button with the button widget. The label element associated with the checkbox is used for the button text.</p>
-<p>This demo also demonstrates three checkboxes styled as a button set by calling <code>.buttonset()</code> on a common container.</p>
-</div>
-</body>
-</html>
diff --git a/demos/button/default.html b/demos/button/default.html
index 88c666e9a..644dcd225 100644
--- a/demos/button/default.html
+++ b/demos/button/default.html
@@ -5,31 +5,34 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Button - Default functionality</title>
<link rel="stylesheet" href="../../themes/base/all.css">
- <script src="../../external/jquery/jquery.js"></script>
- <script src="../../ui/core.js"></script>
- <script src="../../ui/widget.js"></script>
- <script src="../../ui/button.js"></script>
<link rel="stylesheet" href="../demos.css">
- <script>
- $(function() {
- $( "input[type=submit], a, button" )
- .button()
- .on( "click", function( event ) {
- event.preventDefault();
- });
- });
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js">
+ $( ".widget input[type=submit], .widget a, .widget button" ).button();
+ $( "button, input, a" ).click( function( event ) {
+ event.preventDefault();
+ } );
</script>
</head>
<body>
+<div class="widget">
+ <h1>Widget Buttons</h1>
+ <button>A button element</button>
-<button>A button element</button>
+ <input type="submit" value="A submit button">
-<input type="submit" value="A submit button">
+ <a href="#">An anchor</a>
+</div>
+<h1>CSS Buttons</h1>
+<button class="ui-button ui-widget ui-corner-all">A button element</button>
+
+<input class="ui-button ui-widget ui-corner-all" type="submit" value="A submit button">
-<a href="#">An anchor</a>
+<a class="ui-button ui-widget ui-corner-all" href="#">An anchor</a>
<div class="demo-description">
<p>Examples of the markup that can be used for buttons: A button element, an input of type submit and an anchor.</p>
+<p>Buttons can be styled via the button widget or by adding the classes yourself. This avoids the JavaScript overhead if you don't need any of the methods provided by the button widget.</p>
</div>
</body>
</html>
diff --git a/demos/button/icons.html b/demos/button/icons.html
index 0744218b2..f3d4a3852 100644
--- a/demos/button/icons.html
+++ b/demos/button/icons.html
@@ -5,44 +5,59 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Button - Icons</title>
<link rel="stylesheet" href="../../themes/base/all.css">
- <script src="../../external/jquery/jquery.js"></script>
- <script src="../../ui/core.js"></script>
- <script src="../../ui/widget.js"></script>
- <script src="../../ui/button.js"></script>
<link rel="stylesheet" href="../demos.css">
- <script>
- $(function() {
- $( "button:first" ).button({
- icons: {
- primary: "ui-icon-locked"
- },
- text: false
- }).next().button({
- icons: {
- primary: "ui-icon-locked"
- }
- }).next().button({
- icons: {
- primary: "ui-icon-gear",
- secondary: "ui-icon-triangle-1-s"
- }
- }).next().button({
- icons: {
- primary: "ui-icon-gear",
- secondary: "ui-icon-triangle-1-s"
- },
- text: false
- });
- });
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js">
+ $( ".widget button" )
+ .eq( 0 ).button()
+ .end().eq( 1 ).button( {
+ icon: "ui-icon-gear",
+ showLabel: false
+ } ).end().eq( 2 ).button( {
+ icon: "ui-icon-gear"
+ } ).end().eq( 3 ).button( {
+ icon: "ui-icon-gear",
+ iconPosition: "end"
+ } ).end().eq( 4 ).button( {
+ icon: "ui-icon-gear",
+ iconPosition: "top"
+ } ).end().eq( 5 ).button( {
+ icon: "ui-icon-gear",
+ iconPosition: "bottom"
+ } );
</script>
</head>
<body>
-
-<button>Button with icon only</button>
-<button>Button with icon on the left</button>
-<button>Button with two icons</button>
-<button>Button with two icons and no text</button>
-
+<div class="widget">
+ <h1>Widget</h1>
+ <button>Button with only text</button>
+ <button>Button with icon only</button>
+ <button>Button with icon on the left</button>
+ <button>Button with icon on the right</button>
+ <button>Button with icon on the top</button>
+ <button>Button with icon on the bottom</button>
+</div>
+<div class="css">
+ <h1>CSS</h1>
+ <button class="ui-button ui-widget ui-corner-all">
+ Button with only text
+ </button>
+ <button class="ui-button ui-widget ui-corner-all ui-button-icon-only" title="Button with icon only">
+ <span class="ui-icon ui-icon-gear"></span> Button with icon only
+ </button>
+ <button class="ui-button ui-widget ui-corner-all">
+ <span class="ui-icon ui-icon-gear"></span> Button with icon on the left
+ </button>
+ <button class="ui-button ui-widget ui-corner-all">
+ Button with icon on the right <span class="ui-icon ui-icon-gear"></span>
+ </button>
+ <button class="ui-button ui-widget ui-corner-all">
+ <span class="ui-icon ui-icon-gear ui-widget-icon-block"></span> Button with icon on the top
+ </button>
+ <button class="ui-button ui-widget ui-corner-all">
+ Button with icon on the bottom <span class="ui-icon ui-icon-gear ui-widget-icon-block"></span>
+ </button>
+</div>
<div class="demo-description">
<p>Some buttons with various combinations of text and icons.</p>
</div>
diff --git a/demos/button/index.html b/demos/button/index.html
index 5e1b8b7b3..55eacffd8 100644
--- a/demos/button/index.html
+++ b/demos/button/index.html
@@ -9,11 +9,7 @@
<ul>
<li><a href="default.html">Default functionality</a></li>
- <li><a href="radio.html">Radios</a></li>
- <li><a href="checkbox.html">Checkboxes</a></li>
<li><a href="icons.html">Icons</a></li>
- <li><a href="toolbar.html">Toolbar</a></li>
- <li><a href="splitbutton.html">Split Button</a></li>
</ul>
</body>
diff --git a/demos/button/radio.html b/demos/button/radio.html
deleted file mode 100644
index 86c55a39a..000000000
--- a/demos/button/radio.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery UI Button - Radios</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <script src="../../external/jquery/jquery.js"></script>
- <script src="../../ui/core.js"></script>
- <script src="../../ui/widget.js"></script>
- <script src="../../ui/button.js"></script>
- <link rel="stylesheet" href="../demos.css">
- <script>
- $(function() {
- $( "#radio" ).buttonset();
- });
- </script>
-</head>
-<body>
-
-<form>
- <div id="radio">
- <input type="radio" id="radio1" name="radio" /><label for="radio1">Choice 1</label>
- <input type="radio" id="radio2" name="radio" checked="checked" /><label for="radio2">Choice 2</label>
- <input type="radio" id="radio3" name="radio" /><label for="radio3">Choice 3</label>
- </div>
-</form>
-
-<div class="demo-description">
-<p>A set of three radio buttons transformed into a button set.</p>
-</div>
-</body>
-</html>
diff --git a/demos/button/splitbutton.html b/demos/button/splitbutton.html
deleted file mode 100644
index 6b7562d68..000000000
--- a/demos/button/splitbutton.html
+++ /dev/null
@@ -1,70 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery UI Button - Split button</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <script src="../../external/jquery/jquery.js"></script>
- <script src="../../ui/core.js"></script>
- <script src="../../ui/widget.js"></script>
- <script src="../../ui/button.js"></script>
- <script src="../../ui/position.js"></script>
- <script src="../../ui/menu.js"></script>
- <link rel="stylesheet" href="../demos.css">
- <style>
- .ui-menu { position: absolute; width: 100px; }
- </style>
- <script>
- $(function() {
- $( "#rerun" )
- .button()
- .on( "click", function() {
- alert( "Running the last action" );
- })
- .next()
- .button({
- text: false,
- icons: {
- primary: "ui-icon-triangle-1-s"
- }
- })
- .on( "click", function() {
- var menu = $( this ).parent().next().show().position({
- my: "left top",
- at: "left bottom",
- of: this
- });
- $( document ).one( "click", function() {
- menu.hide();
- });
- return false;
- })
- .parent()
- .buttonset()
- .next()
- .hide()
- .menu();
- });
- </script>
-</head>
-<body>
-
-<div>
- <div>
- <button id="rerun">Run last action</button>
- <button id="select">Select an action</button>
- </div>
- <ul>
- <li><div>Open...</div></li>
- <li><div>Save</div></li>
- <li><div>Delete</div></li>
- </ul>
-</div>
-
-<div class="demo-description">
-<p>An example of a split button built with two buttons: A plain button with just text, one with only a primary icon
-and no text. Both are grouped together in a set.</p>
-</div>
-</body>
-</html>
diff --git a/demos/button/toolbar.html b/demos/button/toolbar.html
deleted file mode 100644
index f2c242f1f..000000000
--- a/demos/button/toolbar.html
+++ /dev/null
@@ -1,115 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery UI Button - Toolbar</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <script src="../../external/jquery/jquery.js"></script>
- <script src="../../ui/core.js"></script>
- <script src="../../ui/widget.js"></script>
- <script src="../../ui/button.js"></script>
- <link rel="stylesheet" href="../demos.css">
- <style>
- #toolbar {
- padding: 4px;
- display: inline-block;
- }
- </style>
- <script>
- $(function() {
- $( "#beginning" ).button({
- text: false,
- icons: {
- primary: "ui-icon-seek-start"
- }
- });
- $( "#rewind" ).button({
- text: false,
- icons: {
- primary: "ui-icon-seek-prev"
- }
- });
- $( "#play" ).button({
- text: false,
- icons: {
- primary: "ui-icon-play"
- }
- })
- .on( "click", function() {
- var options;
- if ( $( this ).text() === "play" ) {
- options = {
- label: "pause",
- icons: {
- primary: "ui-icon-pause"
- }
- };
- } else {
- options = {
- label: "play",
- icons: {
- primary: "ui-icon-play"
- }
- };
- }
- $( this ).button( "option", options );
- });
- $( "#stop" ).button({
- text: false,
- icons: {
- primary: "ui-icon-stop"
- }
- })
- .on( "click", function() {
- $( "#play" ).button( "option", {
- label: "play",
- icons: {
- primary: "ui-icon-play"
- }
- });
- });
- $( "#forward" ).button({
- text: false,
- icons: {
- primary: "ui-icon-seek-next"
- }
- });
- $( "#end" ).button({
- text: false,
- icons: {
- primary: "ui-icon-seek-end"
- }
- });
- $( "#shuffle" ).button();
- $( "#repeat" ).buttonset();
- });
- </script>
-</head>
-<body>
-
-<div id="toolbar" class="ui-widget-header ui-corner-all">
- <button id="beginning">go to beginning</button>
- <button id="rewind">rewind</button>
- <button id="play">play</button>
- <button id="stop">stop</button>
- <button id="forward">fast forward</button>
- <button id="end">go to end</button>
-
- <input type="checkbox" id="shuffle" /><label for="shuffle">Shuffle</label>
-
- <span id="repeat">
- <input type="radio" id="repeat0" name="repeat" checked="checked" /><label for="repeat0">No Repeat</label>
- <input type="radio" id="repeat1" name="repeat" /><label for="repeat1">Once</label>
- <input type="radio" id="repeatall" name="repeat" /><label for="repeatall">All</label>
- </span>
-</div>
-
-<div class="demo-description">
-<p>
- A mediaplayer toolbar. Take a look at the underlying markup: A few button elements,
- an input of type checkbox for the Shuffle button, and three inputs of type radio for the Repeat options.
-</p>
-</div>
-</body>
-</html>
diff --git a/demos/checkboxradio/default.html b/demos/checkboxradio/default.html
new file mode 100644
index 000000000..064967c12
--- /dev/null
+++ b/demos/checkboxradio/default.html
@@ -0,0 +1,63 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Checkboxradio - Default functionality</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js">
+ $( "input" ).checkboxradio();
+ </script>
+</head>
+<body>
+<div class="widget">
+ <h1>Checkbox and radio button widgets</h1>
+
+ <h2>Radio Group</h2>
+ <fieldset>
+ <legend>Select a Location: </legend>
+ <label for="radio-1">New York</label>
+ <input type="radio" name="radio-1" id="radio-1">
+ <label for="radio-2">Paris</label>
+ <input type="radio" name="radio-1" id="radio-2">
+ <label for="radio-3">London</label>
+ <input type="radio" name="radio-1" id="radio-3">
+ </fieldset>
+
+ <h2>Checkbox</h2>
+ <fieldset>
+ <legend>Hotel Ratings: </legend>
+ <label for="checkbox-1">2 Star</label>
+ <input type="checkbox" name="checkbox-1" id="checkbox-1">
+ <label for="checkbox-2">3 Star</label>
+ <input type="checkbox" name="checkbox-2" id="checkbox-2">
+ <label for="checkbox-3">4 Star</label>
+ <input type="checkbox" name="checkbox-3" id="checkbox-3">
+ <label for="checkbox-4">5 Star</label>
+ <input type="checkbox" name="checkbox-4" id="checkbox-4">
+ </fieldset>
+
+ <h2>Checkbox nested in label</h2>
+ <fieldset>
+ <legend>Bed Type: </legend>
+ <label for="checkbox-nested-1">2 Double
+ <input type="checkbox" name="checkbox-nested-1" id="checkbox-nested-1">
+ </label>
+ <label for="checkbox-nested-2">2 Queen
+ <input type="checkbox" name="checkbox-nested-2" id="checkbox-nested-2">
+ </label>
+ <label for="checkbox-nested-3">1 Queen
+ <input type="checkbox" name="checkbox-nested-3" id="checkbox-nested-3">
+ </label>
+ <label for="checkbox-nested-4">1 King
+ <input type="checkbox" name="checkbox-nested-4" id="checkbox-nested-4">
+ </label>
+ </fieldset>
+</div>
+
+<div class="demo-description">
+ <p>Examples of the markup that can be used with checkboxes and radio buttons.</p>
+</div>
+</body>
+</html>
diff --git a/demos/checkboxradio/images/jquery-mobile.png b/demos/checkboxradio/images/jquery-mobile.png
new file mode 100644
index 000000000..fe2c36376
--- /dev/null
+++ b/demos/checkboxradio/images/jquery-mobile.png
Binary files differ
diff --git a/demos/checkboxradio/images/jquery-ui.png b/demos/checkboxradio/images/jquery-ui.png
new file mode 100644
index 000000000..651e2e115
--- /dev/null
+++ b/demos/checkboxradio/images/jquery-ui.png
Binary files differ
diff --git a/demos/checkboxradio/images/jquery.png b/demos/checkboxradio/images/jquery.png
new file mode 100644
index 000000000..ff3fdc21d
--- /dev/null
+++ b/demos/checkboxradio/images/jquery.png
Binary files differ
diff --git a/demos/checkboxradio/images/qunit.png b/demos/checkboxradio/images/qunit.png
new file mode 100644
index 000000000..048bcfddb
--- /dev/null
+++ b/demos/checkboxradio/images/qunit.png
Binary files differ
diff --git a/demos/checkboxradio/images/sizzle.png b/demos/checkboxradio/images/sizzle.png
new file mode 100644
index 000000000..6145cd8ec
--- /dev/null
+++ b/demos/checkboxradio/images/sizzle.png
Binary files differ
diff --git a/demos/checkboxradio/index.html b/demos/checkboxradio/index.html
new file mode 100644
index 000000000..08e598dbc
--- /dev/null
+++ b/demos/checkboxradio/index.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>jQuery UI Checkboxradio Demos</title>
+</head>
+<body>
+
+<ul>
+ <li><a href="default.html">Default functionality</a></li>
+ <li><a href="no-icons.html">No icons</a></li>
+ <li><a href="radiogroup.html">Radiogroup</a></li>
+ <li><a href="product-selector.html">Product Selector</a></li>
+</ul>
+
+</body>
+</html>
diff --git a/demos/checkboxradio/no-icons.html b/demos/checkboxradio/no-icons.html
new file mode 100644
index 000000000..bcff28dcd
--- /dev/null
+++ b/demos/checkboxradio/no-icons.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Checkboxradio - No Icons</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js">
+ $( "input" ).checkboxradio({
+ icon: false
+ });
+ </script>
+</head>
+<body>
+<div class="widget">
+ <h1>Checkbox and radio button widgets</h1>
+
+ <h2>Radio Group</h2>
+ <fieldset>
+ <legend>Select a Location: </legend>
+ <label for="radio-1">New York</label>
+ <input type="radio" name="radio-1" id="radio-1">
+ <label for="radio-2">Paris</label>
+ <input type="radio" name="radio-1" id="radio-2">
+ <label for="radio-3">London</label>
+ <input type="radio" name="radio-1" id="radio-3">
+ </fieldset>
+
+ <h2>Checkbox</h2>
+ <fieldset>
+ <legend>Hotel Ratings: </legend>
+ <label for="checkbox-1">2 Star</label>
+ <input type="checkbox" name="checkbox-1" id="checkbox-1">
+ <label for="checkbox-2">3 Star</label>
+ <input type="checkbox" name="checkbox-2" id="checkbox-2">
+ <label for="checkbox-3">4 Star</label>
+ <input type="checkbox" name="checkbox-3" id="checkbox-3">
+ <label for="checkbox-4">5 Star</label>
+ <input type="checkbox" name="checkbox-4" id="checkbox-4">
+ </fieldset>
+
+ <h2>Checkbox nested in label</h2>
+ <fieldset>
+ <legend>Bed Type: </legend>
+ <label for="checkbox-nested-1">2 Double
+ <input type="checkbox" name="checkbox-nested-1" id="checkbox-nested-1">
+ </label>
+ <label for="checkbox-nested-2">2 Queen
+ <input type="checkbox" name="checkbox-nested-2" id="checkbox-nested-2">
+ </label>
+ <label for="checkbox-nested-3">1 Queen
+ <input type="checkbox" name="checkbox-nested-3" id="checkbox-nested-3">
+ </label>
+ <label for="checkbox-nested-4">1 King
+ <input type="checkbox" name="checkbox-nested-4" id="checkbox-nested-4">
+ </label>
+ </fieldset>
+</div>
+
+<div class="demo-description">
+ <p>Examples of the markup that can be used with checkboxes and radio buttons, here showing both without icons.</p>
+</div>
+</body>
+</html>
diff --git a/demos/checkboxradio/product-selector.html b/demos/checkboxradio/product-selector.html
new file mode 100644
index 000000000..c78c51657
--- /dev/null
+++ b/demos/checkboxradio/product-selector.html
@@ -0,0 +1,138 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Checkboxradio - Product Selector</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js" data-modules="controlgroup">
+ function handleShape( e ) {
+ $( ".shape" )
+ .removeClass( "circle pill square rectangle" )
+ .addClass( $( e.target ).val() );
+ };
+ function handleToggle( e ) {
+ var target = $( e.target );
+
+ if ( target.is( ".brand-toggle" ) ) {
+ var checked = target.is( ":checked" ),
+ value = $( "[name='brand']" )
+ .filter( ":checked" )
+ .attr( "data-" + target[ 0 ].id )
+ $( ".shape" ).css( target[ 0 ].id, checked ? value : "" );
+ } else {
+ $( ".shape" ).toggleClass( target[ 0 ].id, target.is( ":checked") );
+ }
+ }
+ function updateBrand() {
+ handleShape( { target: $( "[name='shape']:checked" ) } );
+ $( ".toggle:checked" ).each( function() {
+ handleToggle( { target: $( this ) } );
+ } );
+ }
+
+ // Initalize widgets
+ $( "input" ).checkboxradio();
+ $( ".shape-bar, .brand" ).controlgroup();
+ $( ".toggles" ).controlgroup( {
+ direction: "vertical"
+ } );
+
+ // Bind event handlers
+ $( "[name='shape']").on( "change", handleShape );
+ $( ".toggle" ).on( "change", handleToggle );
+ $( "[name='brand']").on( "change", updateBrand );
+
+ // Set initial values
+ updateBrand();
+ </script>
+ <style>
+ .shape {
+ margin-left: 4em;
+ margin-top: 2.5em;
+ height: 8em;
+ width: 8em;
+ box-shadow: 4px 4px 8px;
+ color: #ccc;
+ background-repeat: no-repeat;
+ background-size: 90%;
+ background-position: 50%;
+ }
+ .circle, .pill {
+ border-radius: 8em;
+ }
+ .pill, .rectangle {
+ width: 16em;
+ }
+ .square, .circle {
+ margin-left: 9em;
+ }
+ .border {
+ border: 2px solid #333333;
+ }
+ .toggles {
+ width: 200px;
+ }
+ .toggle-wrap, .shape {
+ display: inline-block;
+ vertical-align: top;
+ }
+ .controls {
+ background: #ccc;
+ padding: 1em;
+ display: inline-block;
+ }
+ </style>
+</head>
+<body>
+<div class="controls">
+ <div class="brand-wrap">
+ <h3>1.) Select a brand</h3>
+ <div class="brand">
+ <label for="brand-jquery">jQuery</label>
+ <input type="radio" name="brand" id="brand-jquery" data-background-color="#0769AD" data-color="#7ACEF4" data-background-image="url(images/jquery.png)">
+ <label for="brand-jquery-ui">jQuery UI</label>
+ <input type="radio" name="brand" id="brand-jquery-ui" data-background-color="#B24926" data-color="#FAA523" data-background-image="url(images/jquery-ui.png)" checked>
+ <label for="brand-jquery-mobile">jQuery Mobile</label>
+ <input type="radio" name="brand" id="brand-jquery-mobile" data-background-color="#108040" data-color="#3EB249" data-background-image="url(images/jquery-mobile.png)">
+ <label for="brand-sizzle">Sizzle</label>
+ <input type="radio" name="brand" id="brand-sizzle" data-background-color="#9A1B1E" data-color="#FAA523" data-background-image="url(images/sizzle.png)">
+ <label for="brand-qunit">QUnit</label>
+ <input type="radio" name="brand" id="brand-qunit" data-background-color="#390F39" data-color="#9C3493" data-background-image="url(images/qunit.png)">
+ </div>
+ </div>
+ <div class="shape-wrap">
+ <h3>2.) Select a shape</h3>
+ <div class="shape-bar">
+ <label for="shape-circle">Circle</label>
+ <input type="radio" name="shape" id="shape-circle" value="circle" checked>
+ <label for="shape-square">Square</label>
+ <input type="radio" name="shape" id="shape-square" value="square">
+ <label for="shape-pill">Pill</label>
+ <input type="radio" name="shape" id="shape-pill" value="pill">
+ <label for="shape-rectangle">Rectangle</label>
+ <input type="radio" name="shape" id="shape-rectangle" value="rectangle">
+ </div>
+ </div>
+ <div class="toggle-wrap">
+ <h3>3.) Customize</h3>
+ <div class="toggles">
+ <label for="color">Shadow</label>
+ <input class="toggle brand-toggle" type="checkbox" name="color" id="color">
+ <label for="border">Border</label>
+ <input class="toggle" type="checkbox" name="border" id="border">
+ <label for="background-color">Background</label>
+ <input class="toggle brand-toggle" type="checkbox" name="background-color" id="background-color" checked>
+ <label for="background-image">Background Image</label>
+ <input class="toggle brand-toggle" type="checkbox" name="background-image" id="background-image" checked>
+ </div>
+ </div>
+ <div class="shape circle background jquery-ui"></div>
+</div>
+
+<div class="demo-description">
+<p>Using two sets of radio buttons, as horizontal controlgroups, and one group of checkboxes, as a vertical controlgroup, to implement a product selector.</p>
+</div>
+</body>
+</html>
diff --git a/demos/checkboxradio/radiogroup.html b/demos/checkboxradio/radiogroup.html
new file mode 100644
index 000000000..a8f808c11
--- /dev/null
+++ b/demos/checkboxradio/radiogroup.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Checkboxradio - Radio Group</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js" data-modules="controlgroup">
+ $( "input" ).checkboxradio();
+ $( "fieldset" ).controlgroup();
+ </script>
+</head>
+<body>
+<div class="widget">
+
+ <h2>Radio Group</h2>
+ <fieldset>
+ <legend>Select a Location: </legend>
+ <label for="radio-1">New York</label>
+ <input type="radio" name="radio-1" id="radio-1">
+ <label for="radio-2">Paris</label>
+ <input type="radio" name="radio-1" id="radio-2">
+ <label for="radio-3">London</label>
+ <input type="radio" name="radio-1" id="radio-3">
+ </fieldset>
+</div>
+
+<div class="demo-description">
+<p>Example markup using the controlgroup widget to create a radio group.</p>
+</div>
+</body>
+</html>
diff --git a/demos/controlgroup/default.html b/demos/controlgroup/default.html
new file mode 100644
index 000000000..0c26bd6cd
--- /dev/null
+++ b/demos/controlgroup/default.html
@@ -0,0 +1,86 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Controlgroup - Default Functionality</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <style>
+ .ui-controlgroup-vertical {
+ width: 150px;
+ }
+ .ui-controlgroup.ui-controlgroup-vertical > button.ui-button,
+ .ui-controlgroup.ui-controlgroup-vertical > .ui-controlgroup-label {
+ text-align: center;
+ }
+ #car-type-button {
+ width: 120px;
+ }
+ .ui-controlgroup-horizontal .ui-spinner-input {
+ width: 20px;
+ }
+ </style>
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js" data-modules="button checkboxradio selectmenu spinner">
+ $( ".controlgroup" ).controlgroup()
+ $( ".controlgroup-vertical" ).controlgroup({
+ "direction": "vertical"
+ });
+ </script>
+</head>
+<body>
+<div class="widget">
+ <h1>Controlgroup</h1>
+ <fieldset>
+ <legend>Rental Car</legend>
+ <div class="controlgroup">
+ <select id="car-type">
+ <option>Compact car</option>
+ <option>Midsize car</option>
+ <option>Full size car</option>
+ <option>SUV</option>
+ <option>Luxury</option>
+ <option>Truck</option>
+ <option>Van</option>
+ </select>
+ <label for="transmission-standard">Standard</label>
+ <input type="radio" name="transmission" id="transmission-standard">
+ <label for="transmission-automatic">Automatic</label>
+ <input type="radio" name="transmission" id="transmission-automatic">
+ <label for="insurance">Insurance</label>
+ <input type="checkbox" name="insurance" id="insurance">
+ <label for="horizontal-spinner" class="ui-controlgroup-label"># of cars</label>
+ <input id="horizontal-spinner" class="ui-spinner-input">
+ <button>Book Now!</button>
+ </div>
+ </fieldset>
+ <br/>
+ <fieldset>
+ <legend>Rental Car</legend>
+ <div class="controlgroup-vertical">
+ <select>
+ <option>Compact car</option>
+ <option>Midsize car</option>
+ <option>Full size car</option>
+ <option>SUV</option>
+ <option>Luxury</option>
+ <option>Truck</option>
+ <option>Van</option>
+ </select>
+ <label for="transmission-standard-v">Standard</label>
+ <input type="radio" name="transmission-v" id="transmission-standard-v">
+ <label for="transmission-automatic-v">Automatic</label>
+ <input type="radio" name="transmission-v" id="transmission-automatic-v">
+ <label for="insurance-v">Insurance</label>
+ <input type="checkbox" name="insurance" id="insurance-v">
+ <label for="vertical-spinner" class="ui-controlgroup-label"># of cars</label>
+ <input id="vertical-spinner" class="ui-spinner-input">
+ <button>Book Now!</button>
+ </div>
+ </fieldset>
+</div>
+<div class="demo-description">
+<p>A controlgroup featuring various form controls. The first features a horizontal toolbar like orientation, the second is in a space saving vertical orientation for usages like mobile devices and panels.</p>
+</div>
+</body>
+</html>
diff --git a/demos/controlgroup/index.html b/demos/controlgroup/index.html
new file mode 100644
index 000000000..5aa4f5fd6
--- /dev/null
+++ b/demos/controlgroup/index.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>jQuery UI Controlgroup Demos</title>
+</head>
+<body>
+
+<ul>
+ <li><a href="default.html">Default functionality</a></li>
+ <li><a href="splitbutton.html">Split Button</a></li>
+ <li><a href="toolbar.html">Toolbar</a></li>
+</ul>
+
+</body>
+</html>
diff --git a/demos/controlgroup/splitbutton.html b/demos/controlgroup/splitbutton.html
new file mode 100644
index 000000000..ec2b78876
--- /dev/null
+++ b/demos/controlgroup/splitbutton.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Controlgroup - Split Button</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <style>
+ .ui-button-icon-only.demo-splitbutton-select {
+ width: 1em;
+ }
+ </style>
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js" data-modules="button checkboxradio selectmenu">
+ $( "select" ).selectmenu({
+ classes: {
+ "ui-selectmenu-button": "ui-button-icon-only demo-splitbutton-select"
+ },
+ change: function(){
+ $( ".output" ).append( "<li>" + this.value + "</li>" );
+ }
+ });
+ $( ".controlgroup" ).controlgroup();
+ $( "button" ).click(function() {
+ $( ".output" ).append( "<li>Running Last Action...</li>" );
+ });
+ </script>
+</head>
+<body>
+<div class="widget">
+ <h1>Split button</h1>
+ <div class="controlgroup">
+ <button>Run last option</button>
+ <select>
+ <option>Open...</option>
+ <option>Save</option>
+ <option>Delete</option>
+ </select>
+ </div>
+ <br/>
+ <h3>Output:</h3>
+ <ul class="output"></ul>
+</div>
+<div class="demo-description">
+ <p>A controlgroup creating a split button, by combining a button and a selectmenu. We adjust the classes option on the selectmenu to show only the icon</p>
+</div>
+</body>
+</html>
diff --git a/demos/controlgroup/toolbar.html b/demos/controlgroup/toolbar.html
new file mode 100644
index 000000000..14f9842c8
--- /dev/null
+++ b/demos/controlgroup/toolbar.html
@@ -0,0 +1,277 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Controlgroup - Toolbar</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <style>
+ #zoom-button {
+ width: 55px;
+ }
+ #fontname-button,
+ #fontsize-button {
+ width: 45px;
+ }
+ #forecolor-button {
+ width: 50px;
+ }
+ #hilitecolor-button {
+ width: 70px;
+ }
+ #bold {
+ font-weight: bold;
+ }
+ #italic {
+ font-style: italic;
+ }
+ #underline {
+ text-decoration: underline;
+ }
+ .toolbar {
+ font-size: .75em;
+ }
+ #page {
+ width: 440px;
+ left: 50%;
+ position: relative;
+ margin-left: -226px;
+ height: 450px;
+ border: 1px solid #888;
+ box-shadow: 7px 7px 3px #ccc;
+ font-size: 11px;
+ font-family: "Lucida Grande";
+ zoom: 100%;
+ padding: 5px;
+ white-space: pre-line;
+ overflow: scroll;
+ }
+ .wrap {
+ width: 588px;
+ }
+ </style>
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js" data-modules="button checkboxradio selectmenu">
+ var page = $( "#page" );
+ var basicControls = [ "#print", "#bold", "#italic", "#undo", "#redo" ];
+ var valueControls = [ "#fontsize", "#forecolor", "#hilitecolor", "#backcolor", "fontname" ];
+
+ $( "#print" ).button({
+ "icon": "ui-icon-print",
+ "showLabel": false
+ });
+ $( "#redo" ).button({
+ "icon": "ui-icon-arrowreturnthick-1-e",
+ "showLabel": false
+ });
+ $( "#undo" ).button({
+ "icon": "ui-icon-arrowreturnthick-1-w",
+ "showLabel": false
+ });
+
+ $( ".toolbar" ).controlgroup();
+ $( "#zoom" ).on( "selectmenuchange", function() {
+ page.css({ "zoom": $( this ).val() });
+ })
+ $( basicControls.concat( valueControls ).join( ", " ) ).on( "click change selectmenuchange",
+ function() {
+ document.execCommand(
+ this.id,
+ false,
+ $( this ).val()
+ );
+ } );
+ $( "form" ).on( "submit", function( event ) {
+ event.preventDefault();
+ });
+ </script>
+</head>
+<body>
+<div class="wrap">
+ <div class="toolbar">
+ <button id="print">Print</button>
+ <button id="undo">Undo</button>
+ <button id="redo">Redo</button>
+ <select id="zoom">
+ <option selected disabled>Zoom</option>
+ <option>50%</option>
+ <option>75%</option>
+ <option>90%</option>
+ <option>100%</option>
+ <option>125%</option>
+ <option>150%</option>
+ <option>200%</option>
+ </select>
+ <select id="fontname">
+ <option selected disabled>Font</option>
+ <option>Arial</option>
+ <option>Comic Sans MS</option>
+ <option>Courier New</option>
+ <option>Georgia</option>
+ <option>Impact</option>
+ <option>Lucida Grande</option>
+ <option>Times New Roman</option>
+ <option>Verdana</option>
+ </select>
+ <select id="fontsize">
+ <option selected disabled>Size</option>
+ <option value="1">8px</option>
+ <option value="2">9px</option>
+ <option value="3">10px</option>
+ <option value="4">11px</option>
+ <option value="5">12px</option>
+ <option value="6">14px</option>
+ <option value="7">18px</option>
+ <option value="8">24px</option>
+ <option value="9">30px</option>
+ <option value="10">36px</option>
+ </select>
+ <select id="hilitecolor" title="Background color">
+ <option selected disabled>Highlight</option>
+ <option value="white">None</option>
+ <option value="red">Red</option>
+ <option value="yellow">Yellow</option>
+ <option value="green">Green</option>
+ <option value="blue">Blue</option>
+ <option value="grey">Grey</option>
+ <option value="purple">Purple</option>
+ <option value="orange">Orange</option>
+ </select>
+ <select id="forecolor" title="Color">
+ <option selected disabled>Color</option>
+ <option value="black">Black</option>
+ <option value="white">White</option>
+ <option value="red">Red</option>
+ <option value="yellow">Yellow</option>
+ <option value="green">Green</option>
+ <option value="blue">Blue</option>
+ <option value="#ccc">Grey</option>
+ <option value="purple">Purple</option>
+ <option value="orange">Orange</option>
+ </select>
+ <button id="bold">B</button>
+ <button id="italic">I</button>
+ <button id="underline">U</button>
+
+ </div>
+ <pre id="page" contenteditable='true'>
+ The Rime of the Ancient Mariner (text of 1834)
+ BY SAMUEL TAYLOR COLERIDGE
+ Argument
+
+ How a Ship having passed the Line was driven by storms to the cold Country towards the South Pole;
+ and how from thence she made her course to the tropical Latitude of the Great Pacific Ocean; and
+ of the strange things that befell; and in what manner the Ancyent Marinere came back to his own
+ Country.
+
+ PART I
+ It is an ancient Mariner,
+ And he stoppeth one of three.
+ 'By thy long grey beard and glittering eye,
+ Now wherefore stopp'st thou me?
+
+ The Bridegroom's doors are opened wide,
+ And I am next of kin;
+ The guests are met, the feast is set:
+ May'st hear the merry din.'
+
+ He holds him with his skinny hand,
+ 'There was a ship,' quoth he.
+ 'Hold off! unhand me, grey-beard loon!'
+ Eftsoons his hand dropt he.
+
+ He holds him with his glittering eye—
+ The Wedding-Guest stood still,
+ And listens like a three years' child:
+ The Mariner hath his will.
+
+ The Wedding-Guest sat on a stone:
+ He cannot choose but hear;
+ And thus spake on that ancient man,
+ The bright-eyed Mariner.
+
+ 'The ship was cheered, the harbour cleared,
+ Merrily did we drop
+ Below the kirk, below the hill,
+ Below the lighthouse top.
+
+ The Sun came up upon the left,
+ Out of the sea came he!
+ And he shone bright, and on the right
+ Went down into the sea.
+
+ Higher and higher every day,
+ Till over the mast at noon—'
+ The Wedding-Guest here beat his breast,
+ For he heard the loud bassoon.
+
+ The bride hath paced into the hall,
+ Red as a rose is she;
+ Nodding their heads before her goes
+ The merry minstrelsy.
+
+ The Wedding-Guest he beat his breast,
+ Yet he cannot choose but hear;
+ And thus spake on that ancient man,
+ The bright-eyed Mariner.
+
+ And now the STORM-BLAST came, and he
+ Was tyrannous and strong:
+ He struck with his o'ertaking wings,
+ And chased us south along.
+
+ With sloping masts and dipping prow,
+ As who pursued with yell and blow
+ Still treads the shadow of his foe,
+ And forward bends his head,
+ The ship drove fast, loud roared the blast,
+ And southward aye we fled.
+
+ And now there came both mist and snow,
+ And it grew wondrous cold:
+ And ice, mast-high, came floating by,
+ As green as emerald.
+
+ And through the drifts the snowy clifts
+ Did send a dismal sheen:
+ Nor shapes of men nor beasts we ken—
+ The ice was all between.
+
+ The ice was here, the ice was there,
+ The ice was all around:
+ It cracked and growled, and roared and howled,
+ Like noises in a swound!
+
+ At length did cross an Albatross,
+ Thorough the fog it came;
+ As if it had been a Christian soul,
+ We hailed it in God's name.
+
+ It ate the food it ne'er had eat,
+ And round and round it flew.
+ The ice did split with a thunder-fit;
+ The helmsman steered us through!
+
+ And a good south wind sprung up behind;
+ The Albatross did follow,
+ And every day, for food or play,
+ Came to the mariner's hollo!
+
+ In mist or cloud, on mast or shroud,
+ It perched for vespers nine;
+ Whiles all the night, through fog-smoke white,
+ Glimmered the white Moon-shine.'
+
+ 'God save thee, ancient Mariner!
+ From the fiends, that plague thee thus!—
+ Why look'st thou so?'—With my cross-bow
+ I shot the ALBATROSS.
+ </pre>
+</div>
+<div class="demo-description">
+ <p>A sample editor toolbar</p>
+ <p>Highlight text and edit it using the buttons and dropdowns in the toolbar.</p>
+ <p class="warning">Remember: This is only a demo and shouldn't be used for anything in production. Use a proper editor like <a href="http://prosemirror.net/">ProseMirror</a> instead.
+</div>
+</body>
+</html>
diff --git a/demos/draggable/constrain-movement.html b/demos/draggable/constrain-movement.html
index c6c7c6430..5b5c9cd9e 100644
--- a/demos/draggable/constrain-movement.html
+++ b/demos/draggable/constrain-movement.html
@@ -20,7 +20,7 @@
$( "#draggable2" ).draggable({ axis: "x" });
$( "#draggable3" ).draggable({ containment: "#containment-wrapper", scroll: false });
- $( "#draggable5" ).draggable({ containment: "parent" });
+ $( "#draggable4" ).draggable({ containment: "parent" });
</script>
</head>
<body>
@@ -42,7 +42,7 @@
</div>
<div class="draggable ui-widget-content">
- <p id="draggable5" class="ui-widget-header">I'm contained within my parent</p>
+ <p id="draggable4" class="ui-widget-header">I'm contained within my parent</p>
</div>
</div>
diff --git a/demos/index.html b/demos/index.html
index c4a0fdf95..b9d2f4e79 100644
--- a/demos/index.html
+++ b/demos/index.html
@@ -12,6 +12,8 @@
<li><a href="autocomplete/">autocomplete</a></li>
<li><a href="button/">button</a></li>
<li><a href="calendar/">calendar</a></li>
+ <li><a href="checkboxradio/">checkboxradio</a></li>
+ <li><a href="controlgroup/">controlgroup</a></li>
<li><a href="datepicker/">datepicker</a></li>
<li><a href="dialog/">dialog</a></li>
<li><a href="draggable/">draggable</a></li>
diff --git a/demos/tooltip/video-player.html b/demos/tooltip/video-player.html
index cbcce3db0..e1ebac24f 100644
--- a/demos/tooltip/video-player.html
+++ b/demos/tooltip/video-player.html
@@ -35,7 +35,7 @@
}
</style>
<script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js" data-modules="button menu effect effect-blind">
+ <script src="../bootstrap.js" data-modules="button controlgroup menu effect effect-blind">
function notify( input ) {
var msg = "Selected " + $.trim( input.data( "tooltip-title" ) || input.text() );
$( "<div>" )
@@ -70,8 +70,10 @@
notify( button );
});
});
- $( ".set" ).buttonset({
- items: "button"
+ $( ".set" ).controlgroup({
+ items: {
+ "button" : "button"
+ }
});
$( "button.menu" )
diff --git a/demos/widget/default.html b/demos/widget/default.html
index 59bc58d12..0f62bb968 100644
--- a/demos/widget/default.html
+++ b/demos/widget/default.html
@@ -166,6 +166,7 @@
<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>To learn more about the widget factory, <a href="http://learn.jquery.com/jquery-ui/widget-factory/">visit learn.jquery.com</a>.</p>
</div>
</body>
</html>
diff --git a/package.json b/package.json
index 1ea3d972b..7bd301b61 100644
--- a/package.json
+++ b/package.json
@@ -58,6 +58,7 @@
"grunt": "0.4.2",
"grunt-bowercopy": "1.1.0",
"grunt-compare-size": "0.4.0",
+ "grunt-contrib-concat": "0.5.1",
"grunt-contrib-csslint": "0.2.0",
"grunt-contrib-jshint": "0.7.1",
"grunt-contrib-qunit": "0.6.0",
diff --git a/tests/lib/bootstrap.js b/tests/lib/bootstrap.js
index 4cee83f93..96b707f96 100644
--- a/tests/lib/bootstrap.js
+++ b/tests/lib/bootstrap.js
@@ -102,7 +102,7 @@ function jqueryUrl() {
var version = parseUrl().jquery;
var url;
- if ( version === "git" || version === "compat-git" ) {
+ if ( version === "git" ) {
url = "http://code.jquery.com/jquery-" + version;
} else {
url = "../../../external/jquery-" + ( version || "1.11.3" ) + "/jquery";
diff --git a/tests/lib/common.js b/tests/lib/common.js
index c3e898535..d0d72ab8a 100644
--- a/tests/lib/common.js
+++ b/tests/lib/common.js
@@ -70,7 +70,9 @@ exports.testWidget = function( widget, settings ) {
exports.testJshint( "/widgets/" + widget );
testWidgetDefaults( widget, settings.defaults );
testWidgetOverrides( widget );
- testBasicUsage( widget );
+ if ( !settings.noDefaultElement ) {
+ testBasicUsage( widget );
+ }
test( "version", function() {
expect( 1 );
ok( "version" in $.ui[ widget ].prototype, "version property exists" );
diff --git a/tests/lib/qunit.js b/tests/lib/qunit.js
index b421341ea..e2a6e85c7 100644
--- a/tests/lib/qunit.js
+++ b/tests/lib/qunit.js
@@ -27,7 +27,7 @@ QUnit.config.urlConfig.push( {
"1.11.0", "1.11.1", "1.11.2", "1.11.3",
"2.0.0", "2.0.1", "2.0.2", "2.0.3",
"2.1.0", "2.1.1", "2.1.2", "2.1.3",
- "compat-git", "git", "custom"
+ "git", "custom"
],
tooltip: "Which jQuery Core version to test against"
} );
diff --git a/tests/unit/autocomplete/core.js b/tests/unit/autocomplete/core.js
index 41be5ae6a..e252970ee 100644
--- a/tests/unit/autocomplete/core.js
+++ b/tests/unit/autocomplete/core.js
@@ -398,4 +398,28 @@ asyncTest( "Search if the user retypes the same value (#7434)", function() {
} );
} );
+asyncTest( "Close on click outside when focus remains", function() {
+ expect( 2 );
+
+ var element = $( "#autocomplete" ).autocomplete( {
+ source: [ "java", "javascript" ],
+ delay: 0
+ } );
+ var menu = element.autocomplete( "widget" );
+
+ $( "body" ).on( "mousedown", function( event ) {
+ event.preventDefault();
+ } );
+
+ element.val( "j" ).autocomplete( "search", "j" );
+ setTimeout( function() {
+ ok( menu.is( ":visible" ), "menu displays initially" );
+ $( "body" ).simulate( "mousedown" );
+ setTimeout( function() {
+ ok( menu.is( ":hidden" ), "menu closes after clicking elsewhere" );
+ start();
+ } );
+ } );
+} );
+
} );
diff --git a/tests/unit/button/button.html b/tests/unit/button/button.html
index 7ba400645..6cf27fb33 100644
--- a/tests/unit/button/button.html
+++ b/tests/unit/button/button.html
@@ -6,54 +6,24 @@
<script src="../../../external/requirejs/require.js"></script>
<script src="../../lib/css.js" data-modules="core button"></script>
- <script src="../../lib/bootstrap.js" data-widget="button"></script>
+ <script src="../../lib/bootstrap.js" data-widget="button" data-no-back-compat="true"></script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture">
+<form id="form1">
+ <div><button id="button">Label</button></div>
+ <div><button id="button2">label <span>with span</span></button></div>
-<div><button id="button" class="foo">Label</button></div>
-
-<div id="radio0" style="margin-top: 2em;">
- <input type="radio" id="radio01" name="radio" checked="checked"><label for="radio01">Choice 1</label>
- <input type="radio" id="radio02" name="radio"><label for="radio02">Choice 2</label>
- <input type="radio" id="radio03" name="radio"><label for="radio03">Choice 3</label>
-</div>
-<div id="checkbox0">
- <input type="checkbox" id="checkbox01" name="checkbox"><label for="checkbox01">Choice 1</label>
- <input type="checkbox" id="checkbox02" name="checkbox"><label for="checkbox02">Choice 2</label>
- <input type="checkbox" id="checkbox03" name="checkbox"><label for="checkbox03">Choice 3</label>
-</div>
-<form>
- <div id="radio1" style="margin-top: 2em;">
- <input type="radio" id="radio11" name="radio"><label for="radio11">Choice 1</label>
- <input type="radio" id="radio12" name="radio" checked="checked"><label for="radio12">Choice 2</label>
- <input type="radio" id="radio13" name="radio"><label for="radio13">Choice 3</label>
- </div>
-</form>
-<form>
- <div id="radio2" style="margin-top: 2em;">
- <input type="radio" id="radio21" name="radio"><label for="radio21">Choice 1</label>
- <input type="radio" id="radio22" name="radio"><label for="radio22">Choice 2</label>
- <input type="radio" id="radio23" name="radio" checked="checked"><label for="radio23">Choice 3</label>
- </div>
+ <div><input id="submit" type="submit" value="Label"></div>
</form>
-<form>
- <div id="radio3">
- <input type="radio" id="radio31" name="data['Page']['parse']"><label for="radio31">Choice 1</label>
- <input type="radio" id="radio32" name="data['Page']['parse']" checked="checked"><label for="radio32">Choice 2</label>
- <input type="radio" id="radio33" name="data['Page']['parse']"><label for="radio33">Choice 3</label>
- </div>
-</form>
-
-<input type="checkbox" id="check"><label for="check">Toggle</label>
-<input type="checkbox" id="check2"><label for="check2">Checkbox</label>
-<div><input id="submit" type="submit" value="Label"></div>
-
-<button id="button1">Button</button>
+<form id="form2">
+ <button id="button-disabled" disabled>Button</button>
+ <a href="#" id="anchor-button">Anchor Button</a>
+</form>
</div>
</body>
</html>
diff --git a/tests/unit/button/common-deprecated.js b/tests/unit/button/common-deprecated.js
new file mode 100644
index 000000000..0f03bdba2
--- /dev/null
+++ b/tests/unit/button/common-deprecated.js
@@ -0,0 +1,27 @@
+define( [
+ "lib/common",
+ "ui/widgets/button"
+], function( common ) {
+
+common.testWidget( "button", {
+ defaults: {
+ classes: {
+ "ui-button": "ui-corner-all"
+ },
+ disabled: null,
+ icon: null,
+ iconPosition: "beginning",
+ icons: {
+ primary: null,
+ secondary: null
+ },
+ label: null,
+ showLabel: true,
+ text: true,
+
+ // Callbacks
+ create: null
+ }
+} );
+
+} );
diff --git a/tests/unit/button/common.js b/tests/unit/button/common.js
index 4ef136fac..91ce1cff9 100644
--- a/tests/unit/button/common.js
+++ b/tests/unit/button/common.js
@@ -5,14 +5,14 @@ define( [
common.testWidget( "button", {
defaults: {
- classes: {},
- disabled: null,
- icons: {
- primary: null,
- secondary: null
+ classes: {
+ "ui-button": "ui-corner-all"
},
+ disabled: null,
+ icon: null,
+ iconPosition: "beginning",
label: null,
- text: true,
+ showLabel: true,
// Callbacks
create: null
diff --git a/tests/unit/button/core.js b/tests/unit/button/core.js
index f4e5d35a7..de26b0312 100644
--- a/tests/unit/button/core.js
+++ b/tests/unit/button/core.js
@@ -1,229 +1,22 @@
define( [
"jquery",
+ "ui/safe-active-element",
"ui/widgets/button"
], function( $ ) {
-module( "button: core" );
+module( "Button: core" );
-test( "checkbox", function( assert ) {
- expect( 4 );
- var input = $( "#check" ),
- label = $( "label[for=check]" );
- ok( input.is( ":visible" ) );
- ok( label.is( ":not(.ui-button)" ) );
- input.button();
- assert.hasClasses( input, "ui-helper-hidden-accessible" );
- assert.hasClasses( label, "ui-button" );
-} );
-
-test( "radios", function( assert ) {
- expect( 8 );
- var inputs = $( "#radio0 input" ),
- labels = $( "#radio0 label" );
- ok( inputs.is( ":visible" ) );
- ok( labels.is( ":not(.ui-button)" ) );
- inputs.button();
- inputs.each( function() {
- assert.hasClasses( this, "ui-helper-hidden-accessible" );
- } );
- labels.each( function() {
- assert.hasClasses( this, "ui-button" );
- } );
-} );
-
-test( "radio groups", function( assert ) {
- expect( 12 );
-
- function assertClasses( noForm, form1, form2 ) {
- assert.hasClasses( $( "#radio0 .ui-button" + noForm ), "ui-state-active" );
- assert.hasClasses( $( "#radio1 .ui-button" + form1 ), "ui-state-active" );
- assert.hasClasses( $( "#radio2 .ui-button" + form2 ), "ui-state-active" );
- }
-
- $( "input[type=radio]" ).button();
- assertClasses( ":eq(0)", ":eq(1)", ":eq(2)" );
-
- // Click outside of forms
- $( "#radio0 .ui-button:eq(1)" ).trigger( "click" );
- assertClasses( ":eq(1)", ":eq(1)", ":eq(2)" );
-
- // Click in first form
- $( "#radio1 .ui-button:eq(0)" ).trigger( "click" );
- assertClasses( ":eq(1)", ":eq(0)", ":eq(2)" );
-
- // Click in second form
- $( "#radio2 .ui-button:eq(0)" ).trigger( "click" );
- assertClasses( ":eq(1)", ":eq(0)", ":eq(0)" );
-} );
-
-test( "radio groups - ignore elements with same name", function() {
- expect( 1 );
- var form = $( "form:first" ),
- radios = form.find( "[type=radio]" ).button(),
- checkbox = $( "<input>", {
- type: "checkbox",
- name: radios.attr( "name" )
- } );
-
- form.append( checkbox );
- radios.button( "refresh" );
- ok( true, "no exception from accessing button instance of checkbox" );
-} );
-
-test( "input type submit, don't create child elements", function() {
+asyncTest( "Disabled button loses focus", function() {
expect( 2 );
- var input = $( "#submit" );
- deepEqual( input.children().length, 0 );
- input.button();
- deepEqual( input.children().length, 0 );
-} );
-
-test( "buttonset", function( assert ) {
- expect( 6 );
- var set = $( "#radio1" ).buttonset();
- assert.hasClasses( set, "ui-buttonset" );
- deepEqual( set.children( ".ui-button" ).length, 3 );
- deepEqual( set.children( "input[type=radio].ui-helper-hidden-accessible" ).length, 3 );
- ok( set.children( "label:eq(0)" ).is( ".ui-button.ui-corner-left: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-right:not(.ui-corner-all)" ) );
-} );
-
-test( "buttonset (rtl)", function( assert ) {
- expect( 6 );
- var set,
- parent = $( "#radio1" ).parent();
-
- // Set to rtl
- parent.attr( "dir", "rtl" );
-
- set = $( "#radio1" ).buttonset();
- assert.hasClasses( set, "ui-buttonset" );
- deepEqual( set.children( ".ui-button" ).length, 3 );
- deepEqual( set.children( "input[type=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)" ) );
-} );
-
-// TODO: simulated click events don't behave like real click events in IE
-// remove this when simulate properly simulates this
-// see http://yuilibrary.com/projects/yui2/ticket/2528826 fore more info
-if ( !$.ui.ie || ( document.documentMode && document.documentMode > 8 ) ) {
- asyncTest( "ensure checked and aria after single click on checkbox label button, see #5518", function( assert ) {
- expect( 3 );
-
- $( "#check2" ).button().on( "change", function() {
- var lbl = $( this ).button( "widget" );
- ok( this.checked, "checked ok" );
- ok( lbl.attr( "aria-pressed" ) === "true", "aria ok" );
- assert.hasClasses( lbl, "ui-state-active" );
- } );
-
- // Support: Opera
- // Opera doesn't trigger a change event when this is done synchronously.
- // This seems to be a side effect of another test, but until that can be
- // tracked down, this delay will have to do.
- setTimeout( function() {
- $( "#check2" ).button( "widget" ).simulate( "click" );
- start();
- }, 1 );
- } );
-}
-
-test( "#7092 - button creation that requires a matching label does not find label in all cases", function( assert ) {
- expect( 5 );
- var group = $( "<span><label for='t7092a'></label><input type='checkbox' id='t7092a'></span>" );
- group.find( "input[type=checkbox]" ).button();
- assert.hasClasses( group.find( "label" ), "ui-button" );
-
- group = $( "<input type='checkbox' id='t7092b'><label for='t7092b'></label>" );
- group.filter( "input[type=checkbox]" ).button();
- assert.hasClasses( group.filter( "label" ), "ui-button" );
-
- group = $( "<span><input type='checkbox' id='t7092c'></span><label for='t7092c'></label>" );
- group.find( "input[type=checkbox]" ).button();
- assert.hasClasses( group.filter( "label" ), "ui-button" );
-
- group = $( "<span><input type='checkbox' id='t7092d'></span><span><label for='t7092d'></label></span>" );
- group.find( "input[type=checkbox]" ).button();
- assert.hasClasses( group.find( "label" ), "ui-button" );
-
- group = $( "<input type='checkbox' id='t7092e'><span><label for='t7092e'></label></span>" );
- group.filter( "input[type=checkbox]" ).button();
- assert.hasClasses( group.find( "label" ), "ui-button" );
-} );
-
-test( "#5946 - buttonset should ignore buttons that are not :visible", function( assert ) {
- expect( 2 );
- $( "#radio01" ).next().addBack().hide();
- var set = $( "#radio0" ).buttonset( { items: "input[type=radio]:visible" } );
- ok( set.find( "label:eq(0)" ).is( ":not(.ui-button):not(.ui-corner-left)" ) );
- assert.hasClasses( set.find( "label:eq(1)" ), "ui-button ui-corner-left" );
-} );
-
-test( "#6262 - buttonset not applying ui-corner to invisible elements", function( assert ) {
- expect( 3 );
- $( "#radio0" ).hide();
- var set = $( "#radio0" ).buttonset();
- assert.hasClasses( set.find( "label:eq(0)" ), "ui-button ui-corner-left" );
- assert.hasClasses( set.find( "label:eq(1)" ), "ui-button" );
- assert.hasClasses( set.find( "label:eq(2)" ), "ui-button ui-corner-right" );
-
-} );
-
-asyncTest( "Resetting a button's form should refresh the visual state of the button widget to match.", function( assert ) {
- expect( 2 );
- var form = $( "<form>" +
- "<button></button>" +
- "<label for='c1'></label><input id='c1' type='checkbox' checked>" +
- "</form>" ),
- button = form.find( "button" ).button(),
- checkbox = form.find( "input[type=checkbox]" ).button();
-
- checkbox.prop( "checked", false ).button( "refresh" );
- assert.lacksClasses( checkbox.button( "widget" ), "ui-state-active" );
-
- form.get( 0 ).reset();
-
- // If a button has been removed, refresh should not be called on it when
- // its corresponding form is reset.
- button.remove();
+ var element = $( "#button" ).button();
+ element.focus();
setTimeout( function() {
- assert.hasClasses( checkbox.button( "widget" ), "ui-state-active" );
- start();
- }, 1 );
-} );
-asyncTest( "#6711 Checkbox/Radiobutton do not Show Focused State when using Keyboard Navigation", function( assert ) {
- expect( 2 );
- var check = $( "#check" ).button(),
- label = $( "label[for='check']" );
- assert.lacksClasses( label, "ui-state-focus" );
- check.trigger( "focus" );
- setTimeout( function() {
- assert.hasClasses( label, "ui-state-focus" );
- start();
- } );
-} );
-
-test( "#7534 - Button label selector works for ids with \":\"", function( assert ) {
- expect( 1 );
- var group = $( "<span><input type='checkbox' id='check:7534'><label for='check:7534'>Label</label></span>" );
- group.find( "input" ).button();
- assert.hasClasses( group.find( "label" ), "ui-button", "Found an id with a :" );
-} );
+ equal( element[ 0 ], $.ui.safeActiveElement( document ), "Button is focused" );
-asyncTest( "#9169 - Disabled button maintains ui-state-focus", function( assert ) {
- expect( 2 );
- var element = $( "#button1" ).button();
- element[ 0 ].focus();
- setTimeout( function() {
- assert.hasClasses( element, "ui-state-focus" );
element.button( "disable" );
- assert.lacksClasses( element, "ui-state-focus",
- "button does not have ui-state-focus when disabled" );
+ notEqual( element[ 0 ], $.ui.safeActiveElement( document ), "Button has had focus removed" );
start();
} );
} );
diff --git a/tests/unit/button/deprecated.html b/tests/unit/button/deprecated.html
new file mode 100644
index 000000000..73f62921c
--- /dev/null
+++ b/tests/unit/button/deprecated.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Button Deprecated Test Suite</title>
+
+ <script src="../../../external/requirejs/require.js"></script>
+ <script src="../../lib/css.js" data-modules="core button"></script>
+ <script src="../../lib/bootstrap.js" data-widget="button" data-deprecated="true"></script>
+</head>
+<body>
+
+<div id="qunit"></div>
+<div id="qunit-fixture">
+
+<div class="buttonset"><button id="button">Label</button><button>button 2</button></div>
+<div><button id="button2">label <span>with span</span></button></div>
+
+<div id="radio0" style="margin-top: 2em;">
+ <input type="radio" id="radio01" name="radio" checked="checked"><label for="radio01">Choice 1</label>
+ <input type="radio" id="radio02" name="radio"><label for="radio02">Choice 2</label>
+ <input type="radio" id="radio03" name="radio"><label for="radio03">Choice 3</label>
+</div>
+<div id="checkbox0">
+ <input type="checkbox" id="checkbox01" name="checkbox"><label for="checkbox01">Choice 1</label>
+ <input type="checkbox" id="checkbox02" name="checkbox"><label for="checkbox02">Choice 2</label>
+ <input type="checkbox" id="checkbox03" name="checkbox"><label for="checkbox03">Choice 3</label>
+</div>
+<form>
+ <div id="radio1" style="margin-top: 2em;">
+ <input type="radio" id="radio11" name="radio"><label for="radio11">Choice 1</label>
+ <input type="radio" id="radio12" name="radio" checked="checked"><label for="radio12">Choice 2</label>
+ <input type="radio" id="radio13" name="radio"><label for="radio13">Choice 3</label>
+ </div>
+</form>
+<form>
+ <div id="radio2" style="margin-top: 2em;">
+ <input type="radio" id="radio21" name="radio"><label for="radio21">Choice 1</label>
+ <input type="radio" id="radio22" name="radio"><label for="radio22">Choice 2</label>
+ <input type="radio" id="radio23" name="radio" checked="checked"><label for="radio23">Choice 3</label>
+ </div>
+</form>
+<form>
+ <div id="radio3">
+ <input type="radio" id="radio31" name="data['Page']['parse']"><label for="radio31">Choice 1</label>
+ <input type="radio" id="radio32" name="data['Page']['parse']" checked="checked"><label for="radio32">Choice 2</label>
+ <input type="radio" id="radio33" name="data['Page']['parse']"><label for="radio33">Choice 3</label>
+ </div>
+</form>
+
+<input type="checkbox" id="check"><label for="check">Toggle</label>
+<input type="checkbox" id="check2"><label for="check2">Checkbox</label>
+
+<div><input id="submit" type="submit" value="Label"></div>
+<button id="button-disabled" disabled>Button</button>
+<button id="button1">Button</button>
+<a href="#" id="anchor-button">Anchor Button</a>
+
+</div>
+</body>
+</html>
diff --git a/tests/unit/button/deprecated.js b/tests/unit/button/deprecated.js
new file mode 100644
index 000000000..fac02e2a6
--- /dev/null
+++ b/tests/unit/button/deprecated.js
@@ -0,0 +1,196 @@
+define( [
+ "jquery",
+ "ui/widgets/button"
+], function( $ ) {
+
+module( "Button (deprecated): core" );
+
+test( "Calling button on a checkbox input calls checkboxradio widget", function() {
+ var checkbox = $( "#checkbox01" );
+
+ expect( 2 );
+ checkbox.button();
+
+ ok( !!checkbox.checkboxradio( "instance" ),
+ "Calling button on a checkbox creates checkboxradio instance" );
+ ok( !checkbox.checkboxradio( "option", "icon" ),
+ "Calling button on a checkbox sets the checkboxradio icon option to false" );
+} );
+
+test( "Calling buttonset calls controlgroup", function() {
+ var controlgroup = $( ".buttonset" );
+
+ expect( 1 );
+ controlgroup.buttonset();
+
+ ok( controlgroup.is( ":ui-controlgroup" ), "Calling buttonset creates controlgroup instance" );
+} );
+
+module( "Button (deprecated): methods" );
+
+test( "destroy", function( assert ) {
+ expect( 1 );
+ assert.domEqual( "#checkbox02", function() {
+ $( "#checkbox02" ).button().button( "destroy" );
+ } );
+} );
+
+test( "refresh: Ensure disabled state is preserved correctly.", function() {
+ expect( 5 );
+ var element = null;
+
+ element = $( "#checkbox02" );
+ element.button( { disabled: true } ).button( "refresh" );
+ ok( element.button( "option", "disabled" ), "Checkboxes should remain disabled after refresh" );
+ ok( element.prop( "disabled" ), "Input remains disabled after refresh" );
+
+ element = $( "#radio02" );
+ element.button( { disabled: true } ).button( "refresh" );
+ ok( element.button( "option", "disabled" ), "Radio buttons should remain disabled after refresh" );
+
+ element = $( "#checkbox02" );
+ element.button( { disabled: true } ).prop( "disabled", false ).button( "refresh" );
+ ok( !element.button( "option", "disabled" ), "Changing a checkbox's disabled property should update the state after refresh." );
+
+ element = $( "#radio02" );
+ element.button( { disabled: true } ).prop( "disabled", false ).button( "refresh" );
+ ok( !element.button( "option", "disabled" ), "Changing a radio button's disabled property should update the state after refresh." );
+
+} );
+
+module( "button (deprecated): options" );
+
+test( "Setting items option on buttonset sets the button properties on the items option", function() {
+ expect( 2 );
+
+ var controlgroup = $( ".buttonset" );
+
+ controlgroup.buttonset( { items: "bar" } );
+ equal( controlgroup.controlgroup( "option", "items.button" ), "bar",
+ "items.button set when setting items option on init on buttonset" );
+
+ controlgroup.buttonset( "option", "items", "foo" );
+ equal( controlgroup.controlgroup( "option", "items.button" ), "foo",
+ "items.button set when setting items option on buttonset" );
+} );
+
+test( "disabled, null", function() {
+ expect( 2 );
+
+ $( "#radio02" ).prop( "disabled", true ).button( { disabled: null } );
+ deepEqual( $( "#radio02" ).button( "option", "disabled" ), true,
+ "disabled option set to true" );
+ deepEqual( true, $( "#radio02" ).prop( "disabled" ), "element is not disabled" );
+} );
+
+test( "text / showLabel options proxied", function() {
+ expect( 8 );
+ var button = $( "#button" );
+ button.button( {
+ text: false,
+ icon: "ui-icon-gear"
+ } );
+ equal( button.button( "option", "showLabel" ), false,
+ "Setting the text option to false sets the showLabel option to false on init" );
+ button.button( "option", "showLabel", true );
+ equal( button.button( "option", "text" ), true,
+ "Setting showLabel true with option method sets text option to true" );
+ button.button( "option", "text", false );
+ equal( button.button( "option", "showLabel" ), false,
+ "Setting text false with option method sets showLabel option to false" );
+ button.button( "option", "text", true );
+ equal( button.button( "option", "showLabel" ), true,
+ "Setting text true with option method sets showLabel option to true" );
+ button.button( "option", "showLabel", false );
+ equal( button.button( "option", "text" ), false,
+ "Setting showLabel false with option method sets text option to false" );
+ button.button( "destroy" );
+ button.button( {
+ text: true,
+ icon: "ui-icon-gear"
+ } );
+ equal( button.button( "option", "showLabel" ), true,
+ "Setting the text option to true sets the showLabel option to true on init" );
+ button.button( "destroy" );
+ button.button( {
+ showLabel: true,
+ icon: "ui-icon-gear"
+ } );
+ equal( button.button( "option", "text" ), true,
+ "Setting the showLabel option to true sets the text option to true on init" );
+ button.button( "destroy" );
+ button.button( {
+ showLabel: false,
+ icon: "ui-icon-gear"
+ } );
+ equal( button.button( "option", "text" ), false,
+ "Setting the showLabel option to false sets the text option to false on init" );
+} );
+
+test( "icon / icons options properly proxied", function() {
+ expect( 10 );
+
+ var button = $( "#button" );
+
+ button.button( {
+ icon: "foo"
+ } );
+
+ equal( button.button( "option", "icons.primary" ), "foo",
+ "Icon option properly proxied on init" );
+
+ button.button( {
+ icon: "bar"
+ } );
+
+ equal( button.button( "option", "icons.primary" ), "bar",
+ "Icon option properly proxied with option method" );
+
+ button.button( {
+ icons: {
+ primary: "foo"
+ }
+ } );
+
+ equal( button.button( "option", "icon" ), "foo",
+ "Icons primary option properly proxied with option method" );
+ equal( button.button( "option", "iconPosition" ), "beginning",
+ "Icons primary option sets iconPosition option to beginning" );
+
+ button.button( {
+ icons: {
+ secondary: "bar"
+ }
+ } );
+
+ equal( button.button( "option", "icon" ), "bar",
+ "Icons secondary option properly proxied with option method" );
+ equal( button.button( "option", "iconPosition" ), "end",
+ "Icons secondary option sets iconPosition option to end" );
+
+ button.button( "destroy" );
+
+ button.button( {
+ icons: {
+ primary: "foo"
+ }
+ } );
+
+ equal( button.button( "option", "icon" ), "foo",
+ "Icons primary option properly proxied on init" );
+ equal( button.button( "option", "iconPosition" ), "beginning",
+ "Icons primary option sets iconPosition option to beginning on init" );
+
+ button.button( {
+ icons: {
+ secondary: "bar"
+ }
+ } );
+
+ equal( button.button( "option", "icon" ), "bar",
+ "Icons secondary option properly proxied on init" );
+ equal( button.button( "option", "iconPosition" ), "end",
+ "Icons secondary option sets iconPosition option to end on init" );
+} );
+
+} );
diff --git a/tests/unit/button/events.js b/tests/unit/button/events.js
index 15a285046..f780fb494 100644
--- a/tests/unit/button/events.js
+++ b/tests/unit/button/events.js
@@ -3,34 +3,19 @@ define( [
"ui/widgets/button"
], function( $ ) {
-module( "button: events" );
+module( "Button: events" );
-test( "buttonset works with single-quote named elements (#7505)", function() {
- expect( 1 );
- $( "#radio3" ).buttonset();
- $( "#radio33" ).on( "click", function() {
- ok( true, "button clicks work with single-quote named elements" );
- } ).trigger( "click" );
-} );
-
-asyncTest( "when button loses focus, ensure active state is removed (#8559)", function( assert ) {
+asyncTest( "Anchor recieves click event when spacebar is pressed", function() {
expect( 1 );
+ var element = $( "#anchor-button" ).button();
- var element = $( "#button" ).button();
-
- element.one( "keypress", function() {
- element.one( "blur", function() {
- assert.lacksClasses( element, "ui-state-active", "button loses active state appropriately" );
- start();
- } ).trigger( "blur" );
+ element.on( "click", function( event ) {
+ event.preventDefault();
+ ok( true, "click occcured as a result of spacebar" );
+ start();
} );
- element.trigger( "focus" );
- setTimeout( function() {
- element
- .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } )
- .simulate( "keypress", { keyCode: $.ui.keyCode.ENTER } );
- } );
+ element.trigger( $.Event( "keyup", { keyCode: $.ui.keyCode.SPACE } ) );
} );
} );
diff --git a/tests/unit/button/methods.js b/tests/unit/button/methods.js
index 0bafd90f9..09a91bbc0 100644
--- a/tests/unit/button/methods.js
+++ b/tests/unit/button/methods.js
@@ -3,7 +3,7 @@ define( [
"ui/widgets/button"
], function( $ ) {
-module( "button: methods" );
+module( "Button: methods" );
test( "destroy", function( assert ) {
expect( 1 );
@@ -13,61 +13,22 @@ test( "destroy", function( assert ) {
} );
test( "refresh: Ensure disabled state is preserved correctly.", function() {
- expect( 8 );
+ expect( 3 );
var element = $( "<a href='#'></a>" );
element.button( { disabled: true } ).button( "refresh" );
- ok( element.button( "option", "disabled" ), "Anchor button should remain disabled after refresh" ); //See #8237
-
- element = $( "<div></div>" );
- element.button( { disabled: true } ).button( "refresh" );
- ok( element.button( "option", "disabled" ), "<div> buttons should remain disabled after refresh" );
+ ok( element.button( "option", "disabled" ),
+ "Anchor button should remain disabled after refresh" );
element = $( "<button></button>" );
element.button( { disabled: true } ).button( "refresh" );
ok( element.button( "option", "disabled" ), "<button> should remain disabled after refresh" );
- element = $( "<input type='checkbox'>" );
- element.button( { disabled: true } ).button( "refresh" );
- ok( element.button( "option", "disabled" ), "Checkboxes should remain disabled after refresh" );
-
- element = $( "<input type='radio'>" );
- element.button( { disabled: true } ).button( "refresh" );
- ok( element.button( "option", "disabled" ), "Radio buttons should remain disabled after refresh" );
-
element = $( "<button></button>" );
element.button( { disabled: true } ).prop( "disabled", false ).button( "refresh" );
- ok( !element.button( "option", "disabled" ), "Changing a <button>'s disabled property should update the state after refresh." ); //See #8828
-
- element = $( "<input type='checkbox'>" );
- element.button( { disabled: true } ).prop( "disabled", false ).button( "refresh" );
- ok( !element.button( "option", "disabled" ), "Changing a checkbox's disabled property should update the state after refresh." );
-
- element = $( "<input type='radio'>" );
- element.button( { disabled: true } ).prop( "disabled", false ).button( "refresh" );
- ok( !element.button( "option", "disabled" ), "Changing a radio button's disabled property should update the state after refresh." );
-} );
-
-// #8975
-test( "refresh: buttonset should turn added elements into button widgets", function() {
- expect( 2 );
- var radioButtonset = $( "#radio0" ).buttonset(),
- checkboxButtonset = $( "#checkbox0" ).buttonset();
-
- radioButtonset.append(
- "<input type='radio' name='radio' id='radio04'>" +
- "<label for='radio04'>Choice 4</label>"
- );
- checkboxButtonset.append(
- "<input type='checkbox' name='checkbox' id='checkbox04'>" +
- "<label for='checkbox04'>Choice 4</label>"
- );
-
- radioButtonset.buttonset( "refresh" );
- checkboxButtonset.buttonset( "refresh" );
+ ok( !element.button( "option", "disabled" ),
+ "Changing a <button>'s disabled property should update the state after refresh." );
- equal( radioButtonset.find( ":ui-button" ).length, 4, "radio" );
- equal( checkboxButtonset.find( ":ui-button" ).length, 4, "checkbox" );
} );
} );
diff --git a/tests/unit/button/options.js b/tests/unit/button/options.js
index 31542427c..6ef166974 100644
--- a/tests/unit/button/options.js
+++ b/tests/unit/button/options.js
@@ -6,152 +6,179 @@ define( [
module( "button: options" );
test( "disabled, explicit value", function( assert ) {
- expect( 7 );
+ expect( 8 );
- var element = $( "#radio01" ).button( { disabled: false } );
- deepEqual( element.button( "option", "disabled" ), false, "disabled option set to false" );
- deepEqual( element.prop( "disabled" ), false, "element is disabled" );
+ var element = $( "#button" ).button( { disabled: false } );
+
+ strictEqual( element.button( "option", "disabled" ), false, "disabled option set to false" );
+ strictEqual( element.prop( "disabled" ), false, "Disabled property is false" );
assert.lacksClasses( element.button( "widget" ), "ui-state-disabled ui-button-disabled" );
- element = $( "#radio02" ).button( { disabled: true } );
+ element = $( "#button" ).button( { disabled: true } );
- ok( !element.button( "widget" ).attr( "aria-disabled" ), "element does not get aria-disabled" );
- assert.hasClasses( element.button( "widget" ), "ui-button-disabled ui-state-disabled" );
+ assert.hasClasses( element.button( "widget" ), "ui-state-disabled" );
+ strictEqual( element.button( "widget" ).attr( "aria-disabled" ), undefined,
+ "element does not get aria-disabled" );
+ assert.hasClasses( element.button( "widget" ), "ui-button-disabled" );
- deepEqual( element.button( "option", "disabled" ), true, "disabled option set to true" );
- deepEqual( element.prop( "disabled" ), true, "element is not disabled" );
+ strictEqual( element.button( "option", "disabled" ), true, "disabled option set to true" );
+ strictEqual( element.prop( "disabled" ), true, "Disabled property is set" );
} );
+// We are testing the default here because the default null is a special value which means to check
+// the DOM. We need to make sure this happens correctly. Checking the options should never return
+// null, it should always be true or false.
test( "disabled, null", function() {
expect( 4 );
- $( "#radio01" ).button( { disabled: null } );
- deepEqual( false, $( "#radio01" ).button( "option", "disabled" ),
- "disabled option set to false" );
- deepEqual( false, $( "#radio01" ).prop( "disabled" ), "element is disabled" );
+ var element = $( "#button" ),
+ elementDisabled = $( "#button-disabled" );
- $( "#radio02" ).prop( "disabled", true ).button( { disabled: null } );
- deepEqual( true, $( "#radio02" ).button( "option", "disabled" ),
+ element.add( elementDisabled ).button( { disabled: null } );
+ strictEqual( element.button( "option", "disabled" ), false, "disabled option set to false" );
+ strictEqual( element.prop( "disabled" ), false, "element is disabled" );
+ strictEqual( elementDisabled.button( "option", "disabled" ), true,
"disabled option set to true" );
- deepEqual( true, $( "#radio02" ).prop( "disabled" ), "element is not disabled" );
+ strictEqual( elementDisabled.prop( "disabled" ), true, "element is disabled" );
} );
-test( "disabled, ui-state-active is removed unless checkbox or radio", function( assert ) {
- expect( 12 );
- var elements = [
- $( "<input type='button'>" ),
- $( "<button></button>" ),
- $( "<a></a>" ),
- $( "<div></div>" ),
- $( "<input type='checkbox' id='checkbox' checked><label for='checkbox'></label>" ),
- $( "<input type='radio' id='radio' checked><label for='radio'></label>" )
- ];
-
- $.each( elements, function() {
- var element = $( this ).first().button(),
- buttonElement = element.button( "widget" ),
- elementType = element.prop( "nodeName" ).toLowerCase();
-
- if ( element.is( "input" ) ) {
- elementType += ":" + element.attr( "type" );
- }
-
- element.trigger( "mousedown" );
- assert.hasClasses( buttonElement, "ui-state-active",
- "[" + elementType + "] has ui-state-active class after mousedown." );
-
- element.button( "disable" );
- if ( element.is( "[type=checkbox], [type=radio]" ) ) {
- assert.hasClasses( buttonElement, "ui-state-active",
- "Disabled [" + elementType + "] has ui-state-active class." );
- } else {
- assert.lacksClasses( buttonElement, "ui-state-active",
- "Disabled [" + elementType + "] does not have ui-state-active class." );
- }
- } );
-} );
+test( "showLabel, false, without icon", function( assert ) {
+ expect( 4 );
-test( "text false without icon", function() {
- expect( 1 );
- $( "#button" ).button( {
- text: false
+ var button = $( "#button" ).button( {
+ showLabel: false
} );
- ok( $( "#button" ).is( ".ui-button-text-only:not(.ui-button-icon-only)" ) );
- $( "#button" ).button( "destroy" );
+ assert.lacksClasses( button, "ui-button-icon-only" );
+ strictEqual( button.button( "option", "showLabel" ), true,
+ "showLabel false only allowed if icon true" );
+
+ button.button( "option", "showLabel", false );
+ assert.lacksClasses( button, "ui-button-icon-only" );
+ strictEqual( button.button( "option", "showLabel" ), true,
+ "showLabel false only allowed if icon true" );
} );
-test( "text false with icon", function() {
+test( "showLabel, false, with icon", function( assert ) {
expect( 1 );
- $( "#button" ).button( {
- text: false,
- icons: {
- primary: "iconclass"
- }
+ var button = $( "#button" ).button( {
+ showLabel: false,
+ icon: "iconclass"
} );
- ok( $( "#button" ).is( ".ui-button-icon-only:not(.ui-button-text):has(span.ui-icon.iconclass)" ) );
-
- $( "#button" ).button( "destroy" );
+ assert.hasClasses( button, "ui-button ui-corner-all ui-widget ui-button-icon-only" );
} );
test( "label, default", function() {
expect( 2 );
- $( "#button" ).button();
- deepEqual( $( "#button" ).text(), "Label" );
- deepEqual( $( "#button" ).button( "option", "label" ), "Label" );
+ var button = $( "#button" ).button();
- $( "#button" ).button( "destroy" );
+ deepEqual( button.text(), "Label" );
+ deepEqual( button.button( "option", "label" ), "Label" );
} );
-test( "label", function() {
+test( "label, with html markup", function() {
+ expect( 3 );
+ var button = $( "#button2" ).button();
+
+ deepEqual( button.text(), "label with span" );
+ deepEqual( button.html().toLowerCase(), "label <span>with span</span>" );
+ deepEqual( button.button( "option", "label" ).toLowerCase(), "label <span>with span</span>" );
+} );
+
+test( "label, explicit value", function() {
expect( 2 );
- $( "#button" ).button( {
+ var button = $( "#button" ).button( {
label: "xxx"
} );
- deepEqual( $( "#button" ).text(), "xxx" );
- deepEqual( $( "#button" ).button( "option", "label" ), "xxx" );
- $( "#button" ).button( "destroy" );
+ deepEqual( button.text(), "xxx" );
+ deepEqual( button.button( "option", "label" ), "xxx" );
} );
-test( "label default with input type submit", function() {
+test( "label, default, with input type submit", function() {
expect( 2 );
- deepEqual( $( "#submit" ).button().val(), "Label" );
- deepEqual( $( "#submit" ).button( "option", "label" ), "Label" );
+ var button = $( "#submit" ).button();
+
+ deepEqual( button.val(), "Label" );
+ deepEqual( button.button( "option", "label" ), "Label" );
} );
-test( "label with input type submit", function() {
+test( "label, explicit value, with input type submit", function() {
expect( 2 );
- var label = $( "#submit" ).button( {
+ var button = $( "#submit" ).button( {
label: "xxx"
- } ).val();
- deepEqual( label, "xxx" );
- deepEqual( $( "#submit" ).button( "option", "label" ), "xxx" );
+ } );
+
+ deepEqual( button.val(), "xxx" );
+ deepEqual( button.button( "option", "label" ), "xxx" );
} );
-test( "icons", function() {
- expect( 1 );
- $( "#button" ).button( {
- text: false,
- icons: {
- primary: "iconclass",
- secondary: "iconclass2"
- }
- } );
- ok( $( "#button" ).is( ":has(span.ui-icon.ui-button-icon-primary.iconclass):has(span.ui-icon.ui-button-icon-secondary.iconclass2)" ) );
+test( "icon", function( assert ) {
+ expect( 4 );
+ var button = $( "#button" ).button( {
+ showLabel: false,
+ icon: "iconclass"
+ } ),
+ icon = button.find( ".ui-icon" );
+
+ assert.hasClasses( icon, "iconclass" );
+ equal( icon.length, 1, "button with icon option set has icon" );
+
+ button.button( "option", "icon", false );
+ equal( button.find( ".ui-icon" ).length, 0, "setting icon to false removes the icon" );
+
+ button.button( "option", "icon", "iconclass" );
+ ok( button.find( ".ui-icon" ).length, "setting icon to a value adds the icon" );
- $( "#button" ).button( "destroy" );
} );
-test( "#5295 - button does not remove hoverstate if disabled", function( assert ) {
- expect( 1 );
- var btn = $( "#button" ).button();
- btn.on( "hover", function() {
- btn.button( "disable" );
- } );
- btn.trigger( "mouseenter" );
- btn.trigger( "mouseleave" );
- assert.lacksClasses( btn, "ui-state-hover" );
+test( "icon position", function( assert ) {
+ expect( 22 );
+
+ var button = $( "#button" ).button( {
+ icon: "ui-icon-gear"
+ } ),
+ icon = button.find( ".ui-icon" ),
+ space = button.find( ".ui-button-icon-space" );
+
+ equal( icon.length, 1, "button with icon option set has icon" );
+ equal( button.button( "option", "iconPosition" ), "beginning",
+ "Button has iconPosition beginning by default" );
+ equal( button.contents()[ 0 ], icon[ 0 ], "icon is prepended when position is begining" );
+ equal( icon.next()[ 0 ], space[ 0 ], "icon is followed by a space when position is begining" );
+ equal( space.length, 1,
+ "ui-button-icon-space contains a breaking space iconPosition:beginning" );
+ assert.lacksClasses( icon, "ui-widget-icon-block" );
+
+ button.button( "option", "iconPosition", "end" );
+ icon = button.find( ".ui-icon" );
+ space = button.find( ".ui-button-icon-space" );
+ equal( icon.length, 1, "Changing position to end does not re-create or duplicate icon" );
+ equal( button.button( "option", "iconPosition" ), "end", "Button has iconPosition end" );
+ equal( button.contents().last()[ 0 ], icon[ 0 ], "icon is appended when position is end" );
+ equal( icon.prev()[ 0 ], space[ 0 ], "icon is preceeded by a space when position is end" );
+ equal( space.length, 1,
+ "ui-button-icon-space contains a breaking space iconPosition:beginning" );
+ assert.lacksClasses( icon, "ui-widget-icon-block" );
+
+ button.button( "option", "iconPosition", "top" );
+ icon = button.find( ".ui-icon" );
+ equal( icon.length, 1, "Changing position to top does not re-create or duplicate icon" );
+ equal( button.button( "option", "iconPosition" ), "top", "Button has iconPosition top" );
+ equal( button.contents()[ 0 ], icon[ 0 ], "icon is prepended when position is top" );
+ ok( !button.find( "ui-button-icon-space" ).length,
+ "Button should not have an iconSpace with position: top" );
+ assert.hasClasses( icon, "ui-widget-icon-block" );
+
+ button.button( "option", "iconPosition", "bottom" );
+ icon = button.find( ".ui-icon" );
+ equal( icon.length, 1, "Changing position to bottom does not re-create or duplicate icon" );
+ equal( button.button( "option", "iconPosition" ), "bottom", "Button has iconPosition top" );
+ equal( button.contents().last()[ 0 ], icon[ 0 ], "icon is prepended when position is bottom" );
+ ok( !button.find( "ui-button-icon-space" ).length,
+ "Button should not have an iconSpace with position: bottom" );
+ assert.hasClasses( icon, "ui-widget-icon-block" );
+
} );
} );
diff --git a/tests/unit/checkboxradio/all.html b/tests/unit/checkboxradio/all.html
new file mode 100644
index 000000000..71a65d9ee
--- /dev/null
+++ b/tests/unit/checkboxradio/all.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Checkboxradio Test Suite</title>
+
+ <script src="../../../external/jquery/jquery.js"></script>
+
+ <link rel="stylesheet" href="../../../external/qunit/qunit.css">
+ <link rel="stylesheet" href="../../../external/qunit-composite/qunit-composite.css">
+ <script src="../../../external/qunit/qunit.js"></script>
+ <script src="../../../external/qunit-composite/qunit-composite.js"></script>
+ <script src="../subsuite.js"></script>
+
+ <script>
+ testAllVersions( "checkboxradio" );
+ </script>
+</head>
+<body>
+
+<div id="qunit"></div>
+<div id="qunit-fixture">
+
+</div>
+</body>
+</html>
diff --git a/tests/unit/checkboxradio/checkboxradio.html b/tests/unit/checkboxradio/checkboxradio.html
new file mode 100644
index 000000000..9883e0834
--- /dev/null
+++ b/tests/unit/checkboxradio/checkboxradio.html
@@ -0,0 +1,76 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Checkboxradio Test Suite</title>
+
+ <script src="../../../external/requirejs/require.js"></script>
+ <script src="../../lib/css.js" data-modules="core button checkboxradio"></script>
+ <script src="../../lib/bootstrap.js" data-widget="button"></script>
+</head>
+<body>
+
+<div id="qunit"></div>
+<div id="qunit-fixture">
+
+<div id="radio0">
+ <input type="radio" id="radio01" name="radio" checked="checked"><label for="radio01">Choice 1</label>
+ <input type="radio" id="radio02" name="radio"><label for="radio02">Choice 2</label>
+ <input type="radio" id="radio03" name="radio"><label for="radio03">Choice 3</label>
+</div>
+<form id="form1">
+ <div id="radio1">
+ <input type="radio" id="radio11" name="radio"><label for="radio11">Choice 1</label>
+ <input type="radio" id="radio12" name="radio"><label for="radio12">Choice 2</label>
+ <input type="radio" id="radio13" name="radio" checked="checked"><label for="radio13">Choice 3</label>
+ </div>
+</form>
+<form id="form2">
+ <div id="radio2">
+ <input type="radio" id="radio21" name="radio"><label for="radio21">Choice 1</label>
+ <input type="radio" id="radio22" name="radio"><label for="radio22">Choice 2</label>
+ <input type="radio" id="radio23" name="radio" checked="checked"><label for="radio23">Choice 3</label>
+ </div>
+</form>
+<form>
+ <div id="radio3">
+ <input type="radio" id="radio31" name="data['Page']['parse']"><label for="radio31">Choice 1</label>
+ <input type="radio" id="radio32" name="data['Page']['parse']" checked="checked"><label for="radio32">Choice 2</label>
+ <input type="radio" id="radio33" name="data['Page']['parse']"><label for="radio33">Choice 3</label>
+ </div>
+</form>
+
+<input type="checkbox" id="check"><label for="check">Toggle</label>
+<input type="checkbox" id="check2"><label for="check2">Checkbox</label>
+<label for="checkbox-method-refresh" id="checkbox-method-refresh-label">checkbox refresh</label>
+<input type="checkbox" id="checkbox-method-refresh"/>
+<label for="checkbox-method-destroy" class="bar" id="checkbox-method-destroy-label">checkbox refresh</label>
+<input type="checkbox" class="foo" id="checkbox-method-destroy"/>
+<label for="checkbox-method-disable">checkbox refresh</label>
+<input type="checkbox" class="foo" id="checkbox-method-disable"/>
+
+<label for="radio-method-refresh" id="radio-method-refresh-label">radio refresh</label>
+<input type="radio" id="radio-method-refresh"/>
+<label for="radio-method-destroy" class="bar" id="radio-method-destroy-label">radio refresh</label>
+<input type="radio" class="foo" id="radio-method-destroy"/>
+<label for="radio-method-disable">radio refresh</label>
+<input type="radio" class="foo" id="radio-method-disable"/>
+
+<label for="checkbox-option-disabled">checkbox disabled</label>
+<input type="checkbox" class="foo" id="checkbox-option-disabled"/>
+<label for="checkbox-option-icon">checkbox icon</label>
+<input type="checkbox" class="foo" id="checkbox-option-icon"/>
+<label for="checkbox-option-label">checkbox label<input type="checkbox" class="foo" id="checkbox-option-label"/></label>
+<label>
+ <input type="checkbox" id="label-with-no-for"/>
+</label>
+
+<form id="form3"></form>
+<input type="radio" name="crazy-form" id="crazy-form-1" form="form3" checked="checked">
+<label for="crazy-form-1">Choice 1</label>
+<input type="radio" name="crazy-form" id="crazy-form-2" form="form3">
+<label for="crazy-form-2">Choice 2</label>
+
+</div>
+</body>
+</html>
diff --git a/tests/unit/checkboxradio/common.js b/tests/unit/checkboxradio/common.js
new file mode 100644
index 000000000..48c348a3e
--- /dev/null
+++ b/tests/unit/checkboxradio/common.js
@@ -0,0 +1,22 @@
+define( [
+ "lib/common",
+ "ui/widgets/checkboxradio"
+], function( common ) {
+
+common.testWidget( "checkboxradio", {
+ noDefaultElement: true,
+ defaults: {
+ classes: {
+ "ui-checkboxradio-label": "ui-corner-all",
+ "ui-checkboxradio-icon": "ui-corner-all"
+ },
+ disabled: null,
+ icon: true,
+ label: null,
+
+ // Callbacks
+ create: null
+ }
+} );
+
+} );
diff --git a/tests/unit/checkboxradio/core.js b/tests/unit/checkboxradio/core.js
new file mode 100644
index 000000000..2a9cf9822
--- /dev/null
+++ b/tests/unit/checkboxradio/core.js
@@ -0,0 +1,136 @@
+define( [
+ "jquery",
+ "ui/widgets/checkboxradio"
+], function( $ ) {
+
+module( "Checkboxradio: core" );
+
+test( "Checkbox - Initial class structure", function( assert ) {
+ expect( 2 );
+ var input = $( "#check" ),
+ label = $( "label[for=check]" );
+
+ input.checkboxradio();
+ assert.hasClasses( input, "ui-helper-hidden-accessible ui-checkboxradio" );
+ assert.hasClasses( label, "ui-button ui-widget ui-checkboxradio-label ui-corner-all" );
+} );
+
+test( "Radios - Initial class structure", function( assert ) {
+ expect( 6 );
+ var inputs = $( "#radio0 input" ),
+ labels = $( "#radio0 label" );
+
+ inputs.checkboxradio();
+ inputs.each( function() {
+ assert.hasClasses( this, "ui-helper-hidden-accessible" );
+ } );
+ labels.each( function() {
+ assert.hasClasses( this, "ui-button" );
+ } );
+} );
+
+asyncTest( "Ensure checked after single click on checkbox label button", function( assert ) {
+ expect( 2 );
+
+ $( "#check2" ).checkboxradio().change( function() {
+ var label = $( this ).checkboxradio( "widget" );
+ ok( this.checked, "checked ok" );
+
+ assert.hasClasses( label, "ui-state-active" );
+ } );
+
+ // Support: Opera
+ // Opera doesn't trigger a change event when this is done synchronously.
+ // This seems to be a side effect of another test, but until that can be
+ // tracked down, this delay will have to do.
+ setTimeout( function() {
+ $( "#check2" ).checkboxradio( "widget" ).simulate( "click" );
+ start();
+ } );
+} );
+
+test( "Handle form association via form attribute", function( assert ) {
+ expect( 4 );
+
+ var radio1 = $( "#crazy-form-1" ).checkboxradio();
+ var radio1Label = radio1.checkboxradio( "widget" );
+ var radio2 = $( "#crazy-form-2" ).checkboxradio();
+ var radio2Label = radio2.checkboxradio( "widget" );
+
+ radio2.change( function() {
+ ok( this.checked, "#2 checked" );
+ ok( !radio1[ 0 ].checked, "#1 not checked" );
+
+ assert.hasClasses( radio2Label, "ui-state-active" );
+ assert.lacksClasses( radio1Label, "ui-state-active" );
+ } );
+
+ radio2Label.simulate( "click" );
+} );
+
+test( "Checkbox creation requires a label, and finds it in all cases", function( assert ) {
+ expect( 7 );
+ var groups = [
+ "<span><label for='t7092a'></label><input type='checkbox' id='t7092a'></span>",
+ "<span><input type='checkbox' id='t7092b'><label for='t7092b'></label></span>",
+ "<span><span><input type='checkbox' id='t7092c'></span><label for='t7092c'></label></span>",
+ "<span><input type='checkbox' id='t7092d'></span><span><label for='t7092d'></label></span>",
+ "<span><input type='checkbox' id='t7092e'><span><label for='t7092e'></label></span></span>",
+ "<span><label><input type='checkbox' id='t7092f'></label></span>",
+ "<span><input type='checkbox' id='check:7534'><label for='check:7534'>Label</label></span>"
+ ];
+
+ $.each( groups, function( index, markup ) {
+ var group = $( markup );
+
+ group.find( "input[type=checkbox]" ).checkboxradio();
+ assert.hasClasses( group.find( "label" ), "ui-button" );
+ } );
+} );
+
+test( "Calling checkboxradio on an unsupported element throws an error", function( assert ) {
+ expect( 2 );
+
+ var errorMessage =
+ "Can't create checkboxradio on element.nodeName=div and element.type=undefined";
+ var error = new Error( errorMessage );
+ assert.raises(
+ function() {
+ $( "<div>" ).checkboxradio();
+ },
+
+ // Support: jQuery 1.7.0 only
+ $.fn.jquery === "1.7" ? errorMessage : error,
+ "Proper error thrown"
+ );
+
+ errorMessage = "Can't create checkboxradio on element.nodeName=input and element.type=button";
+ error = new Error( errorMessage );
+ assert.raises(
+ function() {
+ $( "<input type='button'>" ).checkboxradio();
+ },
+
+ // Support: jQuery 1.7.0 only
+ $.fn.jquery === "1.7" ? errorMessage : error,
+ "Proper error thrown"
+ );
+} );
+
+test( "Calling checkboxradio on an input with no label throws an error", function( assert ) {
+ expect( 1 );
+
+ var errorMessage = "No label found for checkboxradio widget";
+ var error = new Error( errorMessage );
+ assert.raises(
+ function() {
+ $( "<input type='checkbox'>" ).checkboxradio();
+ },
+
+ // Support: jQuery 1.7.0 only
+ $.fn.jquery === "1.7" ? errorMessage : error,
+ "Proper error thrown"
+ );
+} );
+
+} );
diff --git a/tests/unit/checkboxradio/events.js b/tests/unit/checkboxradio/events.js
new file mode 100644
index 000000000..838e0ca63
--- /dev/null
+++ b/tests/unit/checkboxradio/events.js
@@ -0,0 +1,42 @@
+define( [
+ "jquery",
+ "ui/widgets/checkboxradio"
+], function( $ ) {
+
+module( "Checkboxradio: events" );
+
+asyncTest(
+ "Resetting a checkbox's form should refresh the visual state of the checkbox",
+ function( assert ) {
+ expect( 2 );
+ var form = $( "<form>" +
+ "<label for='c1'></label><input id='c1' type='checkbox' checked>" +
+ "</form>" ),
+ checkbox = form.find( "input[type=checkbox]" ).checkboxradio(),
+ widget = checkbox.checkboxradio( "widget" );
+
+ checkbox.prop( "checked", false ).checkboxradio( "refresh" );
+ assert.lacksClasses( widget, "ui-state-active" );
+
+ form.get( 0 ).reset();
+
+ setTimeout( function() {
+ assert.hasClasses( widget, "ui-state-active" );
+ start();
+ }, 1 );
+ }
+);
+
+asyncTest( "Checkbox shows focus when using keyboard navigation", function( assert ) {
+ expect( 2 );
+ var check = $( "#check" ).checkboxradio(),
+ label = $( "label[for='check']" );
+ assert.lacksClasses( label, "ui-state-focus" );
+ check.focus();
+ setTimeout( function() {
+ assert.hasClasses( label, "ui-state-focus" );
+ start();
+ } );
+} );
+
+} );
diff --git a/tests/unit/checkboxradio/methods.js b/tests/unit/checkboxradio/methods.js
new file mode 100644
index 000000000..ec3a3f667
--- /dev/null
+++ b/tests/unit/checkboxradio/methods.js
@@ -0,0 +1,96 @@
+define( [
+ "jquery",
+ "ui/widgets/checkboxradio"
+], function( $ ) {
+
+module( "Checkboxradio: methods" );
+
+$.each( [ "checkbox", "radio" ], function( index, value ) {
+ test( value + ": refresh", function( assert ) {
+ var widget, icon,
+ checkbox = value === "checkbox",
+ input = $( "#" + value + "-method-refresh" );
+
+ expect( checkbox ? 11 : 8 );
+
+ input.checkboxradio();
+
+ widget = input.checkboxradio( "widget" );
+ icon = widget.find( ".ui-icon" );
+ strictEqual( icon.length, 1,
+ "There is initally one icon" );
+
+ icon.remove();
+ input.checkboxradio( "refresh" );
+ icon = widget.find( ".ui-icon" );
+ strictEqual( icon.length, 1,
+ "Icon is recreated on refresh if absent" );
+ assert.hasClasses( icon, "ui-icon-blank" );
+ if ( checkbox ) {
+ assert.lacksClasses( icon, "ui-icon-check" );
+ }
+ assert.lacksClasses( widget, "ui-checkboxradio-checked" );
+
+ input.prop( "checked", true );
+ input.checkboxradio( "refresh" );
+ if ( checkbox ) {
+ assert.hasClasses( icon, "ui-icon-check" );
+ }
+ assert[ !checkbox ? "hasClasses" : "lacksClasses" ]( icon, "ui-icon-blank" );
+ assert.hasClasses( widget, "ui-checkboxradio-checked" );
+
+ input.prop( "checked", false );
+ input.checkboxradio( "refresh" );
+ assert.hasClasses( icon, "ui-icon-blank" );
+ if ( checkbox ) {
+ assert.lacksClasses( icon, "ui-icon-check" );
+ }
+ assert.lacksClasses( widget, "ui-checkboxradio-checked" );
+ } );
+
+ test( value + ": destroy", function( assert ) {
+ expect( 1 );
+ assert.domEqual( "#" + value + "-method-destroy", function() {
+ $( "#" + value + "-method-destroy" ).checkboxradio().checkboxradio( "destroy" );
+ } );
+ } );
+
+ test( value + ": disable / enable", function( assert ) {
+ expect( 4 );
+ var input = $( "#" + value + "-method-disable" ),
+ widget = input.checkboxradio().checkboxradio( "widget" );
+
+ input.checkboxradio( "disable" );
+ assert.hasClasses( widget, "ui-state-disabled" );
+ strictEqual( input.is( ":disabled" ), true,
+ value + " is disabled when disable is called" );
+
+ input.checkboxradio( "enable" );
+ assert.lacksClasses( widget, "ui-state-disabled" );
+ strictEqual( input.is( ":disabled" ), false,
+ value + " has disabled prop removed when enable is called" );
+ } );
+
+ test( value + ": widget returns the label", function() {
+ expect( 1 );
+
+ var input = $( "#" + value + "-method-refresh" ),
+ label = $( "#" + value + "-method-refresh-label" );
+
+ input.checkboxradio();
+ strictEqual( input.checkboxradio( "widget" )[ 0 ], label[ 0 ],
+ "widget method returns label" );
+ } );
+} );
+
+test( "Input wrapped in a label preserved on refresh", function() {
+ var input = $( "#label-with-no-for" ).checkboxradio(),
+ element = input.checkboxradio( "widget" );
+
+ expect( 1 );
+
+ input.checkboxradio( "refresh" );
+ strictEqual( input.parent()[ 0 ], element[ 0 ], "Input preserved" );
+} );
+
+} );
diff --git a/tests/unit/checkboxradio/options.js b/tests/unit/checkboxradio/options.js
new file mode 100644
index 000000000..1f862c242
--- /dev/null
+++ b/tests/unit/checkboxradio/options.js
@@ -0,0 +1,205 @@
+define( [
+ "jquery",
+ "ui/widgets/checkboxradio"
+], function( $ ) {
+
+module( "Checkboxradio: options" );
+
+function assertDisabled( checkbox, assert ) {
+ assert.hasClasses( checkbox.checkboxradio( "widget" ), "ui-state-disabled",
+ "label gets ui-state-disabled" );
+ strictEqual( checkbox.is( ":disabled" ), true, "checkbox is disabled" );
+}
+
+function assertEnabled( checkbox, assert ) {
+ assert.lacksClasses( checkbox.checkboxradio( "widget" ), "ui-state-disabled",
+ "label has ui-state-disabled removed when disabled set to false" );
+ strictEqual( checkbox.is( ":disabled" ), false,
+ "checkbox has disabled prop removed when disabled set to false" );
+}
+
+test( "disabled", function( assert ) {
+ expect( 6 );
+
+ var checkbox = $( "#checkbox-option-disabled" );
+ checkbox.checkboxradio( {
+ disabled: true
+ } );
+
+ assertDisabled( checkbox, assert );
+
+ checkbox.checkboxradio( "option", "disabled", false );
+ assertEnabled( checkbox, assert );
+
+ checkbox.checkboxradio( "option", "disabled", true );
+ assertDisabled( checkbox, assert );
+} );
+
+test( "disabled - prop true on init", function( assert ) {
+ expect( 2 );
+ var checkbox = $( "#checkbox-option-disabled" );
+
+ checkbox.prop( "disabled", true );
+ checkbox.checkboxradio();
+
+ assertDisabled( checkbox, assert );
+} );
+
+test( "disabled - explicit null value, checks the DOM", function( assert ) {
+ expect( 2 );
+ var checkbox = $( "#checkbox-option-disabled" );
+
+ checkbox.prop( "disabled", true );
+ checkbox.checkboxradio( {
+ disabled: null
+ } );
+ assertDisabled( checkbox, assert );
+} );
+
+function assertNoIcon( checkbox ) {
+ strictEqual( checkbox.checkboxradio( "widget" ).find( "span.ui-icon" ).length, 0,
+ "Label does not contain an icon" );
+}
+
+function assertIcon( checkbox, icon, assert ) {
+ var iconElement = checkbox.checkboxradio( "widget" ).find( ".ui-icon" );
+
+ icon = icon || "blank";
+ strictEqual( iconElement.length, 1,
+ "Label contains icon" );
+ assert.hasClasses( iconElement, "ui-checkboxradio-icon ui-corner-all ui-icon " +
+ "ui-icon-background ui-icon-" + icon,
+ "Icon has proper classes" );
+ if ( icon === "blank" ) {
+ assert.lacksClasses( iconElement, "ui-icon-check ui-state-highlight" );
+ }
+}
+
+test( "icon - false on init", function() {
+ var checkbox = $( "#checkbox-option-icon" );
+
+ expect( 1 );
+
+ checkbox.checkboxradio( { icon: false } );
+ assertNoIcon( checkbox );
+} );
+
+test( "icon - default unchecked", function( assert ) {
+ var checkbox = $( "#checkbox-option-icon" );
+
+ expect( 3 );
+
+ checkbox.checkboxradio();
+ assertIcon( checkbox, false, assert );
+} );
+
+test( "icon - default checked", function( assert ) {
+ var checkbox = $( "#checkbox-option-icon" ).attr( "checked", true );
+
+ expect( 2 );
+
+ checkbox.checkboxradio();
+ assertIcon( checkbox, "check ui-state-highlight", assert );
+} );
+
+test( "icon", function( assert ) {
+ var checkbox = $( "#checkbox-option-icon" );
+
+ expect( 9 );
+
+ checkbox.prop( "checked", true );
+
+ checkbox.checkboxradio();
+ assertIcon( checkbox, "check ui-state-highlight", assert );
+
+ checkbox.checkboxradio( "option", "icon", false );
+ assertNoIcon( checkbox );
+
+ checkbox.checkboxradio( "option", "icon", true );
+ assertIcon( checkbox, "check ui-state-highlight", assert );
+
+ checkbox.checkboxradio( "option", "icon", false );
+ assertNoIcon( checkbox );
+
+ checkbox.checkboxradio( "option", "icon", true );
+ checkbox.prop( "checked", false ).checkboxradio( "refresh" );
+ assertIcon( checkbox, false, assert );
+} );
+
+test( "label - default", function() {
+ var checkbox = $( "#checkbox-option-label" ),
+ widget;
+
+ expect( 2 );
+
+ checkbox.checkboxradio();
+ widget = checkbox.checkboxradio( "widget" );
+ strictEqual( checkbox.checkboxradio( "option", "label" ),
+ "checkbox label", "When no value passed on create text from dom is used for option" );
+ strictEqual( $.trim( widget.text() ),
+ "checkbox label", "When no value passed on create text from dom is used in dom" );
+} );
+
+test( "label - explicit value", function() {
+ expect( 5 );
+ var checkbox = $( "#checkbox-option-label" ).checkboxradio( {
+ label: "foo"
+ } ),
+ widget = checkbox.checkboxradio( "widget" ),
+ icon = widget.find( ".ui-icon" ),
+ iconSpace = widget.find( ".ui-checkboxradio-icon-space" );
+
+ strictEqual( checkbox.checkboxradio( "option", "label" ),
+ "foo", "When value is passed on create value is used for option" );
+ strictEqual( $.trim( widget.text() ),
+ "foo", "When value is passed on create value is used in dom" );
+ strictEqual( icon.length, 1,
+ "Icon is preserved when label is set on init when wrapped in label" );
+ strictEqual( iconSpace.length, 1,
+ "Icon space is preserved when label is set on init when wrapped in label" );
+ strictEqual( $( "#checkbox-option-label" ).length, 1,
+ "Element is preserved when label is set on init when wrapped in label" );
+} );
+
+test( "label - explicit null value", function() {
+ var checkbox = $( "#checkbox-option-label" ),
+ widget;
+
+ expect( 2 );
+
+ // The default null is a special value which means to check the DOM.
+ // We need to make sure that the option never return null.
+ // It should always be true or false after initialization.
+ checkbox.checkboxradio( {
+ label: null
+ } );
+ widget = checkbox.checkboxradio( "widget" );
+ strictEqual( checkbox.checkboxradio( "option", "label" ),
+ "checkbox label", "When null is passed on create text from dom is used for option" );
+ strictEqual( $.trim( widget.text() ),
+ "checkbox label", "When null is passed on create text from dom is used in dom" );
+
+} );
+
+test( "label", function() {
+ expect( 4 );
+
+ var checkbox = $( "#checkbox-option-label" ),
+ widget;
+
+ checkbox.checkboxradio();
+ widget = checkbox.checkboxradio( "widget" );
+ checkbox.checkboxradio( "option", "label", "bar" );
+ strictEqual( checkbox.checkboxradio( "option", "label" ),
+ "bar", "When value is passed value is used for option" );
+ strictEqual( $.trim( widget.text() ),
+ "bar", "When value is passed value is used in dom" );
+
+ checkbox.checkboxradio( "option", "label", null );
+ strictEqual( checkbox.checkboxradio( "option", "label" ),
+ "bar", "When null is passed text from dom is used for option" );
+ strictEqual( $.trim( widget.text() ),
+ "bar", "When null is passed text from dom is used in dom" );
+} );
+
+} );
diff --git a/tests/unit/controlgroup/all.html b/tests/unit/controlgroup/all.html
new file mode 100644
index 000000000..737144acd
--- /dev/null
+++ b/tests/unit/controlgroup/all.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Countrolgroup Test Suite</title>
+
+ <script src="../../../external/jquery/jquery.js"></script>
+
+ <link rel="stylesheet" href="../../../external/qunit/qunit.css">
+ <link rel="stylesheet" href="../../../external/qunit-composite/qunit-composite.css">
+ <script src="../../../external/qunit/qunit.js"></script>
+ <script src="../../../external/qunit-composite/qunit-composite.js"></script>
+ <script src="../subsuite.js"></script>
+
+ <script>
+ testAllVersions( "controlgroup" );
+ </script>
+</head>
+<body>
+
+<div id="qunit"></div>
+<div id="qunit-fixture">
+
+</div>
+</body>
+</html>
diff --git a/tests/unit/controlgroup/common.js b/tests/unit/controlgroup/common.js
new file mode 100644
index 000000000..1a62d971b
--- /dev/null
+++ b/tests/unit/controlgroup/common.js
@@ -0,0 +1,28 @@
+define( [
+ "lib/common",
+ "ui/widgets/controlgroup",
+ "ui/widgets/checkboxradio",
+ "ui/widgets/selectmenu",
+ "ui/widgets/button"
+], function( common ) {
+
+common.testWidget( "controlgroup", {
+ defaults: {
+ classes: {},
+ direction: "horizontal",
+ disabled: null,
+ items: {
+ "button": "input[type=button], input[type=submit], input[type=reset], button, a",
+ "checkboxradio": "input[type='checkbox'], input[type='radio']",
+ "selectmenu": "select",
+ "spinner": ".ui-spinner-input",
+ "controlgroupLabel": ".ui-controlgroup-label"
+ },
+ onlyVisible: true,
+
+ // Callbacks
+ create: null
+ }
+} );
+
+} );
diff --git a/tests/unit/controlgroup/controlgroup.html b/tests/unit/controlgroup/controlgroup.html
new file mode 100644
index 000000000..9767381ac
--- /dev/null
+++ b/tests/unit/controlgroup/controlgroup.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Controlgroup Test Suite</title>
+
+ <script src="../../../external/requirejs/require.js"></script>
+ <script src="../../lib/css.js" data-modules="core button checkboxradio selectmenu spinner controlgroup"></script>
+ <script src="../../lib/bootstrap.js" data-modules="common core methods options"></script>
+</head>
+<body>
+
+<div id="qunit"></div>
+<div id="qunit-fixture">
+ <div class="controlgroup">
+ <button style="display:none">Button with icon only</button>
+ <select>
+ <option>Fast</option>
+ <option>Medium</option>
+ <option>Slow</option>
+ </select>
+ <label for="checkbox">Checkbox</label>
+ <input type="checkbox" value="checkbox" id="checkbox" />
+ <select>
+ <option>Fast</option>
+ <option>Medium</option>
+ <option>Slow</option>
+ </select>
+ <div class="test"></div>
+ <button>Button with icon on the bottom</button>
+ <label for="spinner" class="ui-controlgroup-label"># of cars</label>
+ <input id="spinner" class="ui-spinner-input">
+ <select>
+ <option>Fast</option>
+ <option>Medium</option>
+ <option>Slow</option>
+ </select>
+ </div>
+</div>
+</body>
+</html>
diff --git a/tests/unit/controlgroup/core.js b/tests/unit/controlgroup/core.js
new file mode 100644
index 000000000..775d22ade
--- /dev/null
+++ b/tests/unit/controlgroup/core.js
@@ -0,0 +1,76 @@
+define( [
+ "jquery",
+ "ui/widgets/controlgroup",
+ "ui/widgets/checkboxradio",
+ "ui/widgets/selectmenu",
+ "ui/widgets/button"
+], function( $ ) {
+
+module( "Controlgroup: Core" );
+
+test( "selectmenu: open/close corners", function( assert ) {
+ expect( 12 );
+ var element = $( ".controlgroup" ).controlgroup(),
+ selects = element.find( "select" ),
+ selectButton = selects.eq( 0 ).selectmenu( "widget" );
+
+ selects.eq( 0 ).selectmenu( "open" );
+ assert.hasClasses( selectButton, "ui-corner-tl",
+ "Horizontal: First selectmenu gets ui-corner-tl when opened" );
+
+ selects.eq( 0 ).selectmenu( "close" );
+ assert.hasClasses( selectButton, "ui-corner-left",
+ "Horizontal: First selectmenu gets ui-corner-left when closed" );
+
+ selectButton = selects.eq( 1 ).selectmenu( "widget" );
+ selects.eq( 1 ).selectmenu( "open" );
+ assert.lacksClassStart( selectButton, "ui-corner" );
+
+ selects.eq( 1 ).selectmenu( "close" );
+ assert.lacksClassStart( selectButton, "ui-corner" );
+
+ selectButton = selects.eq( 2 ).selectmenu( "widget" );
+ selects.eq( 2 ).selectmenu( "open" );
+ assert.hasClasses( selectButton, "ui-corner-tr",
+ "Horizontal: Last selectmenu gets ui-corner-tr when opened" );
+
+ selects.eq( 2 ).selectmenu( "close" );
+ assert.hasClasses( selectButton, "ui-corner-right",
+ "Horizontal: Last selectmenu gets ui-corner-right when closed" );
+
+ element.controlgroup( "option", "direction", "vertical" );
+ selectButton = selects.eq( 0 ).selectmenu( "widget" );
+ selects.eq( 0 ).selectmenu( "open" );
+ assert.hasClasses( selectButton, "ui-corner-top",
+ "vertical: First selectmenu gets ui-corner-top when opened" );
+
+ selects.eq( 0 ).selectmenu( "close" );
+ assert.hasClasses( selectButton, "ui-corner-top",
+ "vertical: First selectmenu gets ui-corner-top when closed" );
+
+ selectButton = selects.eq( 1 ).selectmenu( "widget" );
+ selects.eq( 1 ).selectmenu( "open" );
+ assert.lacksClassStart( selectButton, "ui-corner" );
+
+ selects.eq( 1 ).selectmenu( "close" );
+ assert.lacksClassStart( selectButton, "ui-corner" );
+
+ selectButton = selects.eq( 2 ).selectmenu( "widget" );
+ selects.eq( 2 ).selectmenu( "open" );
+ assert.lacksClassStart( selectButton, "ui-corner" );
+
+ selects.eq( 2 ).selectmenu( "close" );
+ assert.hasClasses( selectButton, "ui-corner-bottom",
+ "vertical: Last selectmenu gets ui-corner-bottom when closed" );
+} );
+
+test( "selectmenu: controlgroupLabel", function( assert ) {
+ expect( 2 );
+ var element = $( ".controlgroup" ).controlgroup();
+ var label = element.find( ".ui-controlgroup-label" );
+
+ assert.hasClasses( label, "ui-widget ui-widget-content ui-state-default ui-controlgroup-item" );
+ assert.hasClasses( label.find( "span" ), "ui-controlgroup-label-contents" );
+} );
+
+} );
diff --git a/tests/unit/controlgroup/methods.js b/tests/unit/controlgroup/methods.js
new file mode 100644
index 000000000..4bc384f5e
--- /dev/null
+++ b/tests/unit/controlgroup/methods.js
@@ -0,0 +1,150 @@
+define( [
+ "jquery",
+ "ui/widgets/controlgroup",
+ "ui/widgets/checkboxradio",
+ "ui/widgets/selectmenu",
+ "ui/widgets/button"
+], function( $ ) {
+
+module( "Controlgroup: methods" );
+
+test( "destroy", function( assert ) {
+ expect( 1 );
+ assert.domEqual( ".controlgroup", function() {
+ $( ".controlgroup" ).controlgroup().controlgroup( "destroy" );
+ } );
+} );
+
+test( "disable", function( assert ) {
+ expect( 2 );
+ var element = $( ".controlgroup" ).controlgroup().controlgroup( "disable" );
+ assert.lacksClasses( element, "ui-state-disabled",
+ "The widget does not get the disabled class, because we disable each child widget" );
+ strictEqual( element.find( ".ui-state-disabled" ).length, 6,
+ "Child widgets are disabled" );
+} );
+
+test( "enable", function( assert ) {
+ expect( 2 );
+ var element = $( ".controlgroup" ).controlgroup().controlgroup( "enable" );
+ assert.lacksClasses( element, "ui-state-disabled",
+ "ui-state-disabled is not present on widget after enabling" );
+ strictEqual( element.find( "ui-state-disabled" ).length, 0,
+ "Child widgets are disabled" );
+} );
+
+var tests = {
+ "checkboxradio": "<input type='checkbox'>",
+ "selectmenu": "<select><option>foo</option></select>",
+ "button": "<button>button text</button>"
+ },
+ orientations = {
+ "horizontal": [
+ "ui-corner-left",
+ false,
+ false,
+ "ui-corner-right"
+ ],
+ "vertical": [
+ "ui-corner-top",
+ false,
+ false,
+ "ui-corner-bottom"
+ ]
+ };
+
+// Iterate through supported element markup
+$.each( tests, function( widget, html ) {
+
+ // Check in both horizontal and vertical orientations
+ $.each( orientations, function( name, classes ) {
+
+ test( "refresh: " + widget + ": " + name, function( assert ) {
+ expect( 41 );
+
+ var i, control, currentClasses,
+ controls = [],
+ element = $( "<div>" ).controlgroup( {
+ direction: name
+ } ).appendTo( "body" );
+
+ // checks the elements with in the controlgroup against the expected class list
+ function checkCornerClasses( classList ) {
+ for ( var j = 0; j < 4; j++ ) {
+ if ( classList[ j ] ) {
+ assert.hasClasses( controls[ j ][ widget ]( "widget" ), classList[ j ] );
+ } else {
+ assert.lacksClassStart( controls[ j ][ widget ]( "widget" ), "ui-corner" );
+ }
+ }
+ }
+
+ function showElements( index, value ) {
+ $( value )[ widget ]( "widget" ).show();
+ }
+
+ // Hide each element and check the corner classes
+ function iterateHidden( onlyVisible ) {
+ for ( i = 0; i < 4; i++ ) {
+
+ $( controls ).each( showElements );
+
+ controls[ i ][ widget ]( "widget" ).hide();
+
+ currentClasses = classes.slice( 0 );
+ if ( onlyVisible ) {
+ if ( i === 0 ) {
+ currentClasses[ i + 1 ] = classes[ i ];
+ currentClasses[ i ] = false;
+ } else if ( i === 3 ) {
+ currentClasses[ i - 1 ] = classes[ i ];
+ currentClasses[ i ] = false;
+ }
+ }
+ element.controlgroup( "refresh" );
+ checkCornerClasses( currentClasses );
+ }
+ }
+
+ // Add a label for each element and then append the element to the control group
+ for ( i = 0; i < 4; i++ ) {
+ control = $( html ).attr( "id", "id" + i )
+ .add( $( "<label>label text</label>" ).clone().attr( "for", "id" + i ) );
+
+ controls.push( control );
+ element.append( control );
+ }
+
+ // Refresh the controlgroup now that its populated
+ element.controlgroup( "refresh" );
+ for ( i = 0; i < 4; i++ ) {
+ strictEqual( controls[ i ].is( ":ui-" + widget ), true,
+ name + ": " + widget + " " + i + ": is a " + widget + " widget" );
+ }
+
+ // Check that we have the right classes
+ checkCornerClasses( classes );
+
+ // hide each element and then check its classes
+ iterateHidden( true );
+
+ // Set the exclude option to false so we no longer care about hidden
+ element.controlgroup( "option", "onlyVisible", false );
+
+ // Iterate hiding the elements again and check their corner classes
+ iterateHidden();
+
+ // Disable the first control
+ controls[ 0 ].prop( "disabled", true );
+
+ element.controlgroup( "refresh" );
+
+ assert.hasClasses( controls[ 0 ][ widget ]( "widget" ), "ui-state-disabled" );
+
+ // remove the controlgroup before we start the next set
+ element.remove();
+ } );
+ } );
+} );
+
+} );
diff --git a/tests/unit/controlgroup/options.js b/tests/unit/controlgroup/options.js
new file mode 100644
index 000000000..565d4b893
--- /dev/null
+++ b/tests/unit/controlgroup/options.js
@@ -0,0 +1,109 @@
+define( [
+ "jquery",
+ "ui/widgets/controlgroup",
+ "ui/widgets/checkboxradio",
+ "ui/widgets/selectmenu",
+ "ui/widgets/button"
+], function( $ ) {
+
+module( "Controlgroup: options" );
+
+test( "disabled", function( assert ) {
+ expect( 4 );
+ var element = $( ".controlgroup" ).controlgroup().controlgroup( "option", "disabled", true );
+ assert.lacksClasses( element, "ui-state-disabled" );
+ equal( element.find( ".ui-state-disabled" ).length, 6, "Child widgets are disabled" );
+
+ element.controlgroup( "option", "disabled", false );
+ assert.lacksClasses( element, "ui-state-disabled" );
+ strictEqual( element.find( ".ui-state-disabled" ).length, 0, "Child widgets are not disabled" );
+
+} );
+
+test( "items - null", function() {
+ expect( 2 );
+ var element = $( ".controlgroup" ).controlgroup( {
+ items: {
+ "button": null,
+ "selectmenu": null,
+ "checkboxradio": null
+ }
+ } );
+
+ strictEqual( element.children( ".ui-button" ).length, 0,
+ "Child widgets are not called when selector is null" );
+
+ element.controlgroup( "option", "items", {
+ "button": "button"
+ } );
+ strictEqual( element.children( ".ui-button" ).length, 2,
+ "Correct child widgets are called when selector is updated" );
+} );
+
+test( "items: custom selector", function() {
+ expect( 1 );
+ var element = $( ".controlgroup" ).controlgroup( {
+ items: {
+ "button": ".button"
+ }
+ } );
+ strictEqual( element.children( ".ui-button" ).length, 4,
+ "Correct child widgets are called when custom selector used" );
+} );
+
+$.widget( "ui.test", {
+ _create: function() {
+ this.element.addClass( "ui-test ui-button" );
+ },
+
+ // Controlgroup requires a refresh method to exist
+ refresh: $.noop
+} );
+
+test( "items: custom widget", function() {
+ expect( 2 );
+ var element = $( ".controlgroup" ).controlgroup( {
+ items: {
+ "test": ".test"
+ }
+ } );
+
+ strictEqual( element.children( ".ui-button" ).length, 7,
+ "Correct child widgets are called when custom selector used" );
+ strictEqual( element.children( ".ui-test" ).length, 1,
+ "Custom widget called" );
+} );
+
+test( "onlyVisible", function( assert ) {
+ expect( 4 );
+ var element = $( ".controlgroup" ).controlgroup( {
+ onlyVisible: false
+ } ),
+ buttons = element.children( ".ui-button" );
+
+ assert.lacksClassStart( buttons.eq( 1 ), "ui-corner" );
+ assert.hasClasses( buttons.eq( 0 ), "ui-corner-left",
+ "onlyVisible: false: First button hidden second button doesn't get a corner class" );
+
+ element.controlgroup( "option", "onlyVisible", true );
+ assert.lacksClassStart( buttons.eq( 0 ), "ui-corner" );
+ assert.hasClasses( buttons.eq( 1 ), "ui-corner-left",
+ "onlyVisible: true: First button is hidden second button get corner class" );
+} );
+
+test( "direction", function( assert ) {
+ expect( 6 );
+ var element = $( ".controlgroup" ).controlgroup(),
+ buttons = element.children( ".ui-button" ).filter( ":visible" );
+
+ assert.hasClasses( element, "ui-controlgroup-horizontal" );
+ assert.hasClasses( buttons.first(), "ui-corner-left" );
+ assert.hasClasses( buttons.last(), "ui-corner-right" );
+
+ element.controlgroup( "option", "direction", "vertical" );
+ assert.hasClasses( element, "ui-controlgroup-vertical" );
+ assert.hasClasses( buttons.first(), "ui-corner-top" );
+ assert.hasClasses( buttons.last(), "ui-corner-bottom" );
+} );
+
+} );
diff --git a/tests/unit/date/core.js b/tests/unit/date/core.js
index b04531593..2c32c70d2 100644
--- a/tests/unit/date/core.js
+++ b/tests/unit/date/core.js
@@ -154,7 +154,7 @@ test( "Months", 5, function() {
ok( lastMonth.last );
ok( !lastMonth.first );
- ok( firstMonth.month() === lastMonth.month() - 1 );
+ equal( firstMonth.month(), lastMonth.month() - 1 );
} );
test( "Equal", 4, function() {
diff --git a/tests/unit/dialog/options.js b/tests/unit/dialog/options.js
index 7565799c4..ab9ace259 100644
--- a/tests/unit/dialog/options.js
+++ b/tests/unit/dialog/options.js
@@ -156,10 +156,8 @@ test( "buttons - advanced", function( assert ) {
click: function() {
equal( this, element[ 0 ], "correct context" );
},
- icons: {
- primary: "ui-icon-cancel"
- },
- showText: false
+ icon: "ui-icon-cancel",
+ showLabel: false
}
]
} );
@@ -167,10 +165,10 @@ test( "buttons - advanced", function( assert ) {
buttons = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" );
equal( buttons.length, 1, "correct number of buttons" );
equal( buttons.attr( "id" ), "my-button-id", "correct id" );
- equal( buttons.text(), "a button", "correct label" );
+ equal( $.trim( buttons.text() ), "a button", "correct label" );
assert.hasClasses( buttons, "additional-class" );
- deepEqual( buttons.button( "option", "icons" ), { primary: "ui-icon-cancel", secondary: null } );
- equal( buttons.button( "option", "text" ), false );
+ deepEqual( buttons.button( "option", "icon" ), "ui-icon-cancel" );
+ equal( buttons.button( "option", "showLabel" ), false );
buttons.trigger( "click" );
element.remove();
@@ -208,22 +206,27 @@ test( "closeOnEscape", function() {
} );
test( "closeText", function() {
- expect( 3 );
+ expect( 4 );
var element = $( "<div></div>" ).dialog();
- equal( element.dialog( "widget" ).find( ".ui-dialog-titlebar-close span" ).text(), "Close",
+ equal( $.trim( element.dialog( "widget" ).find( ".ui-dialog-titlebar-close" ).text() ), "Close",
"default close text" );
element.remove();
element = $( "<div></div>" ).dialog( { closeText: "foo" } );
- equal( element.dialog( "widget" ).find( ".ui-dialog-titlebar-close span" ).text(), "foo",
+ equal( $.trim( element.dialog( "widget" ).find( ".ui-dialog-titlebar-close" ).text() ), "foo",
"closeText on init" );
element.remove();
element = $( "<div></div>" ).dialog().dialog( "option", "closeText", "bar" );
- equal( element.dialog( "widget" ).find( ".ui-dialog-titlebar-close span" ).text(), "bar",
+ equal( $.trim( element.dialog( "widget" ).find( ".ui-dialog-titlebar-close" ).text() ), "bar",
"closeText via option method" );
element.remove();
+
+ element = $( "<div></div>" ).dialog( { closeText: "<span>foo</span>" } );
+ equal( $.trim( element.dialog( "widget" ).find( ".ui-dialog-titlebar-close" ).text() ), "<span>foo</span>",
+ "closeText is escaped" );
+ element.remove();
} );
test( "draggable", function() {
diff --git a/tests/unit/draggable/core.js b/tests/unit/draggable/core.js
index 8bc751e0e..61d8503ea 100644
--- a/tests/unit/draggable/core.js
+++ b/tests/unit/draggable/core.js
@@ -345,4 +345,27 @@ test( "ui-draggable-handle managed correctly in nested draggables", function( as
assert.hasClasses( child, "ui-draggable-handle", "child retains class name on destroy" );
} );
+// Support: IE 8 only
+// IE 8 implements DOM Level 2 Events which only has events bubble up to the document.
+// We skip this test since it would be impossible for it to pass in such an environment.
+QUnit[ document.documentMode === 8 ? "skip" : "test" ](
+ "does not stop propagation to window",
+ function( assert ) {
+ expect( 1 );
+ var element = $( "#draggable1" ).draggable();
+
+ var handler = function() {
+ assert.ok( true, "mouseup propagates to window" );
+ };
+ $( window ).on( "mouseup", handler );
+
+ element.simulate( "drag", {
+ dx: 10,
+ dy: 10
+ } );
+
+ $( window ).off( "mouseup", handler );
+ }
+);
+
} );
diff --git a/tests/unit/draggable/draggable.html b/tests/unit/draggable/draggable.html
index 0971b2325..53468a3a9 100644
--- a/tests/unit/draggable/draggable.html
+++ b/tests/unit/draggable/draggable.html
@@ -48,7 +48,7 @@
}
.sortable {
position: relative;
- top: 8000px;
+ top: 800px;
left: 10px;
width: 300px;
padding: 0;
@@ -81,17 +81,17 @@
<div style="width: 1px; height: 1000px;"></div>
<div style="position: absolute; width: 1px; height: 2000px;"></div>
<ul id="sortable" class="sortable">
- <li id="draggableSortable">Item 0</li>
- <li id="draggableSortable2">Item 1</li>
- <li>Item 2</li>
- <li>Item 3</li>
- </ul>
- <ul id="sortable2" class="sortable">
- <li id="draggableSortableClone" class="sortable2Item">Item 0</li>
- <li>Item 1</li>
- <li>Item 2</li>
- <li>Item 3</li>
- </ul>
+ <li id="draggableSortable">Item 0</li>
+ <li id="draggableSortable2">Item 1</li>
+ <li>Item 2</li>
+ <li>Item 3</li>
+ </ul>
+ <ul id="sortable2" class="sortable">
+ <li id="draggableSortableClone" class="sortable2Item">Item 0</li>
+ <li>Item 1</li>
+ <li>Item 2</li>
+ <li>Item 3</li>
+ </ul>
</div>
</body>
diff --git a/tests/unit/draggable/options.js b/tests/unit/draggable/options.js
index 2c8de5a0a..2aa5a1ae1 100644
--- a/tests/unit/draggable/options.js
+++ b/tests/unit/draggable/options.js
@@ -6,6 +6,8 @@ define( [
"ui/widgets/sortable"
], function( $, testHelper ) {
+module( "draggable: options" );
+
// TODO: This doesn't actually test whether append happened, possibly remove
test( "{ appendTo: 'parent' }, default, no clone", function() {
expect( 4 );
diff --git a/tests/unit/index.html b/tests/unit/index.html
index d6c214fa5..9f793141e 100644
--- a/tests/unit/index.html
+++ b/tests/unit/index.html
@@ -41,6 +41,8 @@
<li><a href="autocomplete/autocomplete.html">Autocomplete</a></li>
<li><a href="calendar/calendar.html">Calendar</a></li>
<li><a href="button/button.html">Button</a></li>
+ <li><a href="checkboxradio/checkboxradio.html">Checkboxradio</a></li>
+ <li><a href="controlgroup/controlgroup.html">Controlgroup</a></li>
<li><a href="datepicker/datepicker.html">Datepicker</a></li>
<li><a href="dialog/dialog.html">Dialog</a></li>
<li><a href="menu/menu.html">Menu</a></li>
diff --git a/tests/unit/selectmenu/core.js b/tests/unit/selectmenu/core.js
index 5431d689d..1c1a6b622 100644
--- a/tests/unit/selectmenu/core.js
+++ b/tests/unit/selectmenu/core.js
@@ -15,7 +15,7 @@ test( "markup structure", function( assert ) {
assert.hasClasses( button,
"ui-selectmenu-button ui-selectmenu-button-closed ui-widget" );
- assert.lacksClasses( button, "ui-selectmenu-button-open" );
+ assert.lacksClasses( button, "ui-selectmenu-button-open ui-selectmenu-open" );
assert.hasClasses( menuWrap, "ui-selectmenu-menu" );
assert.lacksClasses( menuWrap, "ui-selectmenu-menu-open" );
} );
@@ -89,8 +89,8 @@ test( "_renderButtonItem()", function() {
element.selectmenu( "refresh" );
option = element.find( "option:selected" );
equal(
+ $.trim( button.text() ),
option.text() + element[ 0 ].selectedIndex,
- button.text(),
"refresh: button item text"
);
@@ -98,8 +98,8 @@ test( "_renderButtonItem()", function() {
menu.find( "li" ).last().simulate( "mouseover" ).trigger( "click" );
option = element.find( "option" ).last();
equal(
+ $.trim( button.text() ),
option.text() + element[ 0 ].selectedIndex,
- button.text(),
"click: button item text"
);
} );
@@ -146,7 +146,7 @@ $.each( [
selected.val(),
"original select state"
);
- equal( button.text(), selected.text(), "button text" );
+ equal( $.trim( button.text() ), selected.text(), "button text" );
start();
} );
} );
@@ -181,7 +181,7 @@ $.each( [
selected.val(),
"original select state"
);
- equal( button.text(), selected.text(), "button text" );
+ equal( $.trim( button.text() ), selected.text(), "button text" );
start();
}, 1 );
} );
@@ -222,7 +222,7 @@ $.each( [
"button aria-activedescendant" );
equal( element.find( "option:selected" ).val(), options.eq( 1 ).val(),
"original select state" );
- equal( button.text(), options.eq( 1 ).text(), "button text" );
+ equal( $.trim( button.text() ), options.eq( 1 ).text(), "button text" );
start();
} );
} );
@@ -329,4 +329,22 @@ $.each( [
} );
} );
+ asyncTest( "Selectmenu should reset when its parent form resets", function() {
+ expect( 2 );
+
+ var element = $( "#speed" ).selectmenu(),
+ widget = element.selectmenu( "widget" ),
+ initialValue = element.val(),
+ form = element.closest( "form" );
+
+ element.val( "Slower" );
+ element.selectmenu( "refresh" );
+ equal( $.trim( widget.text() ), "Slower" );
+ form[ 0 ].reset();
+ setTimeout( function() {
+ equal( $.trim( widget.text() ), initialValue );
+ start();
+ } );
+ } );
+
} );
diff --git a/tests/unit/selectmenu/methods.js b/tests/unit/selectmenu/methods.js
index e49da50f5..e8f2d2d37 100644
--- a/tests/unit/selectmenu/methods.js
+++ b/tests/unit/selectmenu/methods.js
@@ -81,21 +81,21 @@ asyncTest( "refresh - change selected option", function() {
var element = $( "#speed" ).selectmenu(),
button = element.selectmenu( "widget" );
- equal( element.find( "option:selected" ).text(), button.text(), "button text after init" );
+ equal( $.trim( button.text() ), "Medium", "button text after init" );
button.simulate( "focus" );
+
setTimeout( function() {
- equal( element.find( "option:selected" ).text(), button.text(), "button text after focus" );
+ equal( $.trim( button.text() ), "Medium", "button text after focus" );
element[ 0 ].selectedIndex = 0;
element.selectmenu( "refresh" );
- equal( element.find( "option:selected" ).text(), button.text(),
- "button text after changing selected option" );
+ equal( $.trim( button.text() ), "Slower", "button text after changing selected option" );
element.find( "option" ).prop( "selected", false );
element.append( "<option selected value=\"selected_option\">Selected option</option>" );
element.selectmenu( "refresh" );
- equal( "Selected option", button.text(), "button text after adding selected option" );
+ equal( $.trim( button.text() ), "Selected option", "button text after adding selected option" );
start();
} );
@@ -180,7 +180,7 @@ test( "widget and menuWidget", function( assert ) {
menu = element.selectmenu( "menuWidget" );
equal( button.length, 1, "button: one element" );
- assert.hasClasses( button, "ui-selectmenu-button" );
+ assert.hasClasses( button, "ui-button" );
equal( menu.length, 1, "Menu Widget: one element" );
ok( menu.is( "ul.ui-menu" ), "Menu Widget: element and class" );
diff --git a/tests/unit/selectmenu/selectmenu.html b/tests/unit/selectmenu/selectmenu.html
index 16e0f15a7..be8b826c8 100644
--- a/tests/unit/selectmenu/selectmenu.html
+++ b/tests/unit/selectmenu/selectmenu.html
@@ -3,9 +3,8 @@
<head>
<meta charset="utf-8">
<title>jQuery UI Selectmenu Test Suite</title>
-
<script src="../../../external/requirejs/require.js"></script>
- <script src="../../lib/css.js" data-modules="core menu selectmenu"></script>
+ <script src="../../lib/css.js" data-modules="core menu selectmenu button"></script>
<script src="../../lib/bootstrap.js" data-widget="selectmenu"></script>
</head>
<body>
@@ -14,7 +13,7 @@
<div id="qunit-fixture">
<div id="selectmenu-wrap1" class="selectmenu-wrap"></div>
- <div id="selectmenu-wrap2" class="selectmenu-wrap">
+ <form id="selectmenu-wrap2" class="selectmenu-wrap">
<label for="speed">Select a speed:</label>
<select name="speed" id="speed">
<option value="Slower">Slower</option>
@@ -23,7 +22,7 @@
<option value="Fast">Fast</option>
<option value="Faster">Faster</option>
</select>
- </div>
+ </form>
<label for="number">Select a number:</label>
<select name="number" id="number">
diff --git a/tests/unit/slider/methods.js b/tests/unit/slider/methods.js
index 15b2e8726..5c0cbb7bd 100644
--- a/tests/unit/slider/methods.js
+++ b/tests/unit/slider/methods.js
@@ -111,8 +111,54 @@ test( "value", function() {
equal( element.slider( "value" ), 460, "value is restricted to maximum valid step" );
} );
-//test( "values", function() {
-// ok(false, "missing test - untested code is broken code." );
-//});
+test( "values, single step", function() {
+ expect( 8 );
+
+ var element = $( "<div></div>" ).slider( {
+ range: false,
+ min: 10,
+ max: 100,
+ step: 1,
+ values: [ 20 ]
+ } );
+
+ deepEqual( element.slider( "values" ), [ 20 ], "range: false, values - get value for handle" );
+ equal( element.slider( "values", 0 ), 20, "values (index) - get value of handle" );
+
+ element.slider( "values", 0, 5 );
+ equal( element.slider( "values", 0 ), 10, "values (index) - restrict against min" );
+
+ element.slider( "values", 0, 110 );
+ equal( element.slider( "values", 0 ), 100, "values (index) - restrict against max" );
+
+ element.slider( "option", "range", true );
+ element.slider( "values", [ 20, 90 ] );
+
+ deepEqual( element.slider( "values" ), [ 20, 90 ], "range: true, values - get value for all handles" );
+ equal( element.slider( "values", 0 ), 20, "values (index) - 1st handle" );
+ equal( element.slider( "values", 1 ), 90, "values (index) - 2nd handle" );
+
+ element.slider( "values", [ 5, 110 ] );
+ deepEqual( element.slider( "values" ), [ 10, 100 ], "values - restricted against min and max" );
+ element.slider( "destroy" );
+} );
+
+test( "values, multi step", function() {
+ expect( 2 );
+
+ var element = $( "<div></div>" ).slider( {
+ range: false,
+ min: 9,
+ max: 20,
+ step: 3,
+ values: [ 9, 12 ]
+ } );
+ deepEqual( element.slider( "values" ), [ 9, 12 ], "values - evenly divisible by step" );
+
+ element.slider( "values", [ 10, 20 ] );
+ deepEqual( element.slider( "values" ), [ 9, 18 ], "values - not evenly divisible by step" );
+
+ element.slider( "destroy" );
+} );
} );
diff --git a/tests/unit/sortable/options.js b/tests/unit/sortable/options.js
index cdb932af3..ba3a70d99 100644
--- a/tests/unit/sortable/options.js
+++ b/tests/unit/sortable/options.js
@@ -87,7 +87,6 @@ asyncTest( "#7415: Incorrect revert animation with axis: 'y'", function() {
element = $( "#sortable" ).sortable( {
axis: "y",
revert: true,
- stop: start,
sort: function() {
expectedLeft = item.css( "left" );
}
@@ -103,6 +102,7 @@ asyncTest( "#7415: Incorrect revert animation with axis: 'y'", function() {
var top = parseFloat( item.css( "top" ) );
equal( item.css( "left" ), expectedLeft, "left not animated" );
ok( top > 0 && top < 300, "top is animated" );
+ start();
}, 100 );
} );
diff --git a/tests/unit/subsuite.js b/tests/unit/subsuite.js
index 31a279c28..498f60a0b 100644
--- a/tests/unit/subsuite.js
+++ b/tests/unit/subsuite.js
@@ -6,7 +6,7 @@ var versions = [
"1.9.0", "1.9.1",
"1.10.0", "1.10.1", "1.10.2",
"1.11.0", "1.11.1", "1.11.2", "1.11.3",
- "compat-git"
+ "git"
],
additionalTests = {
diff --git a/tests/unit/tabs/helper.js b/tests/unit/tabs/helper.js
index 073895f5f..8c102ec60 100644
--- a/tests/unit/tabs/helper.js
+++ b/tests/unit/tabs/helper.js
@@ -47,7 +47,10 @@ return $.extend( helper, {
equalHeight: function( tabs, height ) {
tabs.find( ".ui-tabs-panel" ).each( function() {
- equal( $( this ).outerHeight(), height );
+
+ // Handle overly-precise values
+ var actualHeight = parseFloat( $( this ).outerHeight().toFixed( 1 ) );
+ equal( actualHeight, height );
} );
},
diff --git a/tests/visual/button/button.html b/tests/visual/button/button.html
deleted file mode 100644
index 1d82cf665..000000000
--- a/tests/visual/button/button.html
+++ /dev/null
@@ -1,89 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>Button Visual Test</title>
- <link rel="stylesheet" href="../../../themes/base/all.css">
- <script src="../../../external/requirejs/require.js"></script>
- <script src="../../../demos/bootstrap.js">
- $( ".buttons" ).each(function() {
- $( this ).children()
- .eq( 0 )
- .button({
- text: false,
- icons: {
- primary: "ui-icon-help"
- }
- })
- .end()
- .eq( 1 )
- .button({
- icons: {
- primary: "ui-icon-help"
- },
- disabled: true
- })
- .end()
- .eq( 2 )
- .button();
- });
- </script>
-</head>
-<body>
-
-<div class="buttons">
- <button>button</button>
- <button>button</button>
- <button>button</button>
-</div>
-
-<div class="buttons">
- <button type="button">button button</button>
- <button type="button">button button</button>
- <button type="button">button button</button>
-</div>
-
-<div class="buttons">
- <button type="submit">button submit</button>
- <button type="submit">button submit</button>
- <button type="submit">button submit</button>
-</div>
-
-<div class="buttons">
- <input type="button" value="input button">
- <input type="button" value="input button">
- <input type="button" value="input button">
-</div>
-
-<div class="buttons">
- <input type="submit" value="input submit">
- <input type="submit" value="input submit">
- <input type="submit" value="input submit">
-</div>
-
-<div class="buttons">
- <input type="checkbox" id="input-checkbox0">
- <input type="checkbox" id="input-checkbox1">
- <input type="checkbox" id="input-checkbox2">
- <label for="input-checkbox0">input checkbox</label>
- <label for="input-checkbox1">input checkbox</label>
- <label for="input-checkbox2">input checkbox</label>
-</div>
-
-<div class="buttons">
- <input type="radio" id="input-radio0" name="radio">
- <input type="radio" id="input-radio1" name="radio">
- <input type="radio" id="input-radio2" name="radio">
- <label for="input-radio0">input radio</label>
- <label for="input-radio1">input radio</label>
- <label for="input-radio2">input radio</label>
-</div>
-
-<div class="buttons">
- <a href="#">anchor</a>
- <a href="#">anchor</a>
- <a href="#">anchor</a>
-</div>
-
-</body>
-</html>
diff --git a/tests/visual/button/performance.html b/tests/visual/button/performance.html
deleted file mode 100644
index 0d807d167..000000000
--- a/tests/visual/button/performance.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>Button Visual Test: Initialization Performance</title>
- <link rel="stylesheet" href="../../../themes/base/all.css">
- <script src="../../../external/requirejs/require.js"></script>
- <script src="../../../demos/bootstrap.js">
- var start,
- html = new Array( 500 ).join( "<button>button</button>" );
- $( html ).appendTo( "body" );
-
- start = $.now();
- $( "button" ).button();
- $( "<p>" ).text( "Time to initialize: " + ($.now() - start) + "ms" ).prependTo( "body" );
- </script>
-</head>
-<body>
-
-</body>
-</html>
diff --git a/tests/visual/checkboxradio/checkboxradio.html b/tests/visual/checkboxradio/checkboxradio.html
new file mode 100644
index 000000000..a472c9df2
--- /dev/null
+++ b/tests/visual/checkboxradio/checkboxradio.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI - Checkboxes</title>
+ <link rel="stylesheet" href="../../../themes/base/all.css">
+ <script src="../../../external/jquery/jquery.js"></script>
+ <script src="../../../ui/core.js"></script>
+ <script src="../../../ui/widget.js"></script>
+ <script src="../../../ui/button.js"></script>
+ <script src="../../../ui/checkboxradio.js"></script>
+ <script>
+ $(function() {
+ var checkboxes = $( "form input" ).checkboxradio();
+
+ $( ".controls input, .controls select" ).on( "change keyup", function() {
+ var option = $( this ).attr( "name" ),
+ value = $( this ).val();
+
+ if ( $( this ).is( "[type=checkbox]" ) ) {
+ value = $( this ).is( ":checked" );
+ }
+ if ( option != "label" || value !== "" ) {
+ checkboxes.checkboxradio( "option", option, value );
+ }
+ });
+ $( ".controls > button" ).click( function() {
+ if ( this.id !== "create" ) {
+ checkboxes.checkboxradio( this.id );
+ } else {
+ checkboxes.checkboxradio();
+ }
+ });
+ });
+ </script>
+ <style>
+ #format { margin-top: 2em; }
+ </style>
+</head>
+<body>
+<h2>
+ Easy way to toggle through various combinations of options and states to make sure none lead to
+ a broken appearence.
+</h2>
+<div class="controls">
+ <button id="create">Create</button>
+ <button id="destroy">Destroy</button>
+ <button id="enable">Enable</button>
+ <button id="disable">Disable</button>
+ <button id="refresh">Refresh</button>
+ <input type="checkbox" id="icon" name="icon" checked><label for="icon">Icon</label>
+ <input type="checkbox" id="disabled" name="disabled"><label for="disabled">Disabled</label>
+ <label for="label">Label<input type="text" id="label" name="label"></label>
+</div>
+<form>
+ <input type="checkbox" id="checkbox-1">
+ <label for="checkbox-1">Checkbox widget sample</label>
+ <input type="checkbox" id="checkbox-2"><label for="checkbox-2">Checkbox widget sample</label>
+
+ <label for="radio-1">Radio widget sample <input type="radio" id="radio-1" name="radio" checked></label>
+ <input type="radio" id="radio-2" name="radio"><label for="radio-2"><span>boom</span>Radio widget sample 2</label>
+ <button type="reset">Reset</button>
+</form>
+</body>
+</html>
diff --git a/tests/visual/index.html b/tests/visual/index.html
index 98753c827..39168c9f4 100644
--- a/tests/visual/index.html
+++ b/tests/visual/index.html
@@ -31,6 +31,11 @@
<li><a href="button/performance.html">Performance</a></li>
</ul>
+ <h2>Checkboxradio</h2>
+ <ul>
+ <li><a href="checkboxradio/checkboxradio.html">General</a></li>
+ </ul>
+
<h2>Dialog</h2>
<ul>
<li><a href="dialog/animated.html">Animations</a></li>
diff --git a/themes/base/accordion.css b/themes/base/accordion.css
index edf368eca..baffce488 100644
--- a/themes/base/accordion.css
+++ b/themes/base/accordion.css
@@ -16,18 +16,6 @@
padding: .5em .5em .5em .7em;
font-size: 100%;
}
-.ui-accordion .ui-accordion-icons {
- padding-left: 2.2em;
-}
-.ui-accordion .ui-accordion-icons .ui-accordion-icons {
- padding-left: 2.2em;
-}
-.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
- position: absolute;
- left: .5em;
- top: 50%;
- margin-top: -8px;
-}
.ui-accordion .ui-accordion-content {
padding: 1em 2.2em;
border-top: 0;
diff --git a/themes/base/base.css b/themes/base/base.css
index aa8e6d157..4d7433491 100644
--- a/themes/base/base.css
+++ b/themes/base/base.css
@@ -14,6 +14,8 @@
@import url("autocomplete.css");
@import url("button.css");
@import url("calendar.css");
+@import url("checkboxradio.css");
+@import url("controlgroup.css");
@import url("datepicker.css");
@import url("dialog.css");
@import url("draggable.css");
diff --git a/themes/base/button.css b/themes/base/button.css
index 17dea198f..4a3a57d48 100644
--- a/themes/base/button.css
+++ b/themes/base/button.css
@@ -9,16 +9,23 @@
* http://api.jqueryui.com/button/#theming
*/
.ui-button {
+ padding: .4em 1em;
display: inline-block;
position: relative;
- padding: 0;
line-height: normal;
margin-right: .1em;
cursor: pointer;
vertical-align: middle;
text-align: center;
- overflow: visible; /* removes extra width in IE */
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+
+ /* Support: IE <= 11 */
+ overflow: visible;
}
+
.ui-button,
.ui-button:link,
.ui-button:visited,
@@ -26,87 +33,48 @@
.ui-button:active {
text-decoration: none;
}
+
/* to make room for the icon, a width needs to be set here */
.ui-button-icon-only {
- width: 2.2em;
-}
-/* button elements seem to need a little more width */
-button.ui-button-icon-only {
- width: 2.4em;
-}
-.ui-button-icons-only {
- width: 3.4em;
-}
-button.ui-button-icons-only {
- width: 3.7em;
+ width: 2em;
+ box-sizing: border-box;
+ text-indent: -9999px;
+ white-space: nowrap;
}
-/* button text element */
-.ui-button .ui-button-text {
- display: block;
- line-height: normal;
-}
-.ui-button-text-only .ui-button-text {
- padding: .4em 1em;
-}
-.ui-button-icon-only .ui-button-text,
-.ui-button-icons-only .ui-button-text {
- padding: 0;
- text-indent: -9999999px;
-}
-.ui-button-text-icon-primary .ui-button-text,
-.ui-button-text-icons .ui-button-text {
- padding: .4em 1em .4em 2.1em;
-}
-.ui-button-text-icon-secondary .ui-button-text,
-.ui-button-text-icons .ui-button-text {
- padding: .4em 2.1em .4em 1em;
-}
-.ui-button-text-icons .ui-button-text {
- padding-left: 2.1em;
- padding-right: 2.1em;
-}
-/* no icon support for input elements, provide padding by default */
-input.ui-button {
- padding: .4em 1em;
+/* no icon support for input elements */
+input.ui-button.ui-button-icon-only {
+ text-indent: 0;
}
/* button icon element(s) */
-.ui-button-icon-only .ui-icon,
-.ui-button-text-icon-primary .ui-icon,
-.ui-button-text-icon-secondary .ui-icon,
-.ui-button-text-icons .ui-icon,
-.ui-button-icons-only .ui-icon {
+.ui-button-icon-only .ui-icon {
position: absolute;
top: 50%;
- margin-top: -8px;
-}
-.ui-button-icon-only .ui-icon {
left: 50%;
+ margin-top: -8px;
margin-left: -8px;
}
-.ui-button-text-icon-primary .ui-button-icon-primary,
-.ui-button-text-icons .ui-button-icon-primary,
-.ui-button-icons-only .ui-button-icon-primary {
- left: .5em;
-}
-.ui-button-text-icon-secondary .ui-button-icon-secondary,
-.ui-button-text-icons .ui-button-icon-secondary,
-.ui-button-icons-only .ui-button-icon-secondary {
- right: .5em;
-}
-/* button sets */
-.ui-buttonset {
- margin-right: 7px;
+.ui-button.ui-icon-notext .ui-icon {
+ padding: 0;
+ width: 2.1em;
+ height: 2.1em;
+ text-indent: -9999px;
+ white-space: nowrap;
+
}
-.ui-buttonset .ui-button {
- margin-left: 0;
- margin-right: -.3em;
+
+input.ui-button.ui-icon-notext .ui-icon {
+ width: auto;
+ height: auto;
+ text-indent: 0;
+ white-space: normal;
+ padding: .4em 1em;
}
/* workarounds */
-/* reset extra padding in Firefox, see h5bp.com/l */
+/* Support: Firefox 5 - 40 */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
border: 0;
diff --git a/themes/base/checkboxradio.css b/themes/base/checkboxradio.css
new file mode 100644
index 000000000..a41125e23
--- /dev/null
+++ b/themes/base/checkboxradio.css
@@ -0,0 +1,34 @@
+/*!
+ * jQuery UI Checkboxradio @VERSION
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/checkboxradio/#theming
+ */
+
+.ui-checkboxradio-label .ui-icon-background {
+ box-shadow: inset 1px 1px 1px #ccc;
+ border-radius: .12em;
+ border: none;
+}
+.ui-checkboxradio-radio-label .ui-icon-background {
+ width: 16px;
+ height: 16px;
+ border-radius: 1em;
+ overflow: visible;
+ border: none;
+}
+.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,
+.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon {
+ background-image: none;
+ width: 8px;
+ height: 8px;
+ border-width: 4px;
+ border-style: solid;
+}
+.ui-checkboxradio-disabled {
+ pointer-events: none;
+}
diff --git a/themes/base/controlgroup.css b/themes/base/controlgroup.css
new file mode 100644
index 000000000..35e442e17
--- /dev/null
+++ b/themes/base/controlgroup.css
@@ -0,0 +1,65 @@
+/*!
+ * jQuery UI Controlgroup @VERSION
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/controlgroup/#theming
+ */
+
+.ui-controlgroup {
+ vertical-align: middle;
+ display: inline-block;
+}
+.ui-controlgroup > .ui-controlgroup-item {
+ float: left;
+ margin-left: 0;
+ margin-right: 0;
+}
+.ui-controlgroup > .ui-controlgroup-item:focus,
+.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus {
+ z-index: 9999;
+}
+.ui-controlgroup-vertical > .ui-controlgroup-item {
+ display: block;
+ float: none;
+ width: 100%;
+ margin-top: 0;
+ margin-bottom: 0;
+ text-align: left;
+}
+.ui-controlgroup-vertical .ui-controlgroup-item {
+ box-sizing: border-box;
+}
+.ui-controlgroup .ui-controlgroup-label {
+ padding: .4em 1em;
+}
+.ui-controlgroup .ui-controlgroup-label span {
+ font-size: 80%;
+}
+.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item {
+ border-left: none;
+}
+.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item {
+ border-top: none;
+}
+.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content {
+ border-right: none;
+}
+.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content {
+ border-bottom: none;
+}
+
+/* Spinner specific style fixes */
+.ui-controlgroup-vertical .ui-spinner-input {
+
+ /* Support: IE8 only, Android < 4.4 only */
+ width: 75%;
+ width: calc( 100% - 2.4em );
+}
+.ui-controlgroup-vertical .ui-spinner .ui-spinner-up {
+ border-top-style: solid;
+}
+
diff --git a/themes/base/core.css b/themes/base/core.css
index 4a39cd395..2ff5d2da4 100644
--- a/themes/base/core.css
+++ b/themes/base/core.css
@@ -68,15 +68,21 @@
/* Icons
----------------------------------*/
-
-/* states and images */
.ui-icon {
- display: block;
+ display: inline-block;
+ vertical-align: middle;
+ margin-top: -.25em;
+ position: relative;
text-indent: -99999px;
overflow: hidden;
background-repeat: no-repeat;
}
+.ui-widget-icon-block {
+ left: 50%;
+ margin-left: -8px;
+ display: block;
+}
/* Misc visuals
----------------------------------*/
diff --git a/themes/base/images/ui-icons_444444_256x240.png b/themes/base/images/ui-icons_444444_256x240.png
index a957b5e56..a957b5e56 100755..100644
--- a/themes/base/images/ui-icons_444444_256x240.png
+++ b/themes/base/images/ui-icons_444444_256x240.png
Binary files differ
diff --git a/themes/base/images/ui-icons_555555_256x240.png b/themes/base/images/ui-icons_555555_256x240.png
index 5dcdcb41d..5dcdcb41d 100755..100644
--- a/themes/base/images/ui-icons_555555_256x240.png
+++ b/themes/base/images/ui-icons_555555_256x240.png
Binary files differ
diff --git a/themes/base/images/ui-icons_777620_256x240.png b/themes/base/images/ui-icons_777620_256x240.png
index 41f75dd51..41f75dd51 100755..100644
--- a/themes/base/images/ui-icons_777620_256x240.png
+++ b/themes/base/images/ui-icons_777620_256x240.png
Binary files differ
diff --git a/themes/base/images/ui-icons_777777_256x240.png b/themes/base/images/ui-icons_777777_256x240.png
index 067a99208..067a99208 100755..100644
--- a/themes/base/images/ui-icons_777777_256x240.png
+++ b/themes/base/images/ui-icons_777777_256x240.png
Binary files differ
diff --git a/themes/base/images/ui-icons_cc0000_256x240.png b/themes/base/images/ui-icons_cc0000_256x240.png
index 1e18edbf0..1e18edbf0 100755..100644
--- a/themes/base/images/ui-icons_cc0000_256x240.png
+++ b/themes/base/images/ui-icons_cc0000_256x240.png
Binary files differ
diff --git a/themes/base/images/ui-icons_ffffff_256x240.png b/themes/base/images/ui-icons_ffffff_256x240.png
index 4f624bb2b..4f624bb2b 100755..100644
--- a/themes/base/images/ui-icons_ffffff_256x240.png
+++ b/themes/base/images/ui-icons_ffffff_256x240.png
Binary files differ
diff --git a/themes/base/selectmenu.css b/themes/base/selectmenu.css
index 178d7037f..3449c19b5 100644
--- a/themes/base/selectmenu.css
+++ b/themes/base/selectmenu.css
@@ -33,27 +33,10 @@
.ui-selectmenu-open {
display: block;
}
-.ui-selectmenu-button {
- display: inline-block;
- overflow: hidden;
- position: relative;
- text-decoration: none;
- cursor: pointer;
- width: 14em;
-}
-.ui-selectmenu-button span.ui-icon {
- right: 0.5em;
- left: auto;
- margin-top: -8px;
- position: absolute;
- top: 50%;
-}
-.ui-selectmenu-button span.ui-selectmenu-text {
+.ui-selectmenu-button.ui-button {
text-align: left;
- padding: 0.4em 2.1em 0.4em 1em;
- display: block;
- line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
+ width: 14em;
}
diff --git a/themes/base/spinner.css b/themes/base/spinner.css
index 19a0bb7b6..c3908106f 100644
--- a/themes/base/spinner.css
+++ b/themes/base/spinner.css
@@ -23,10 +23,10 @@
margin: .2em 0;
vertical-align: middle;
margin-left: .4em;
- margin-right: 22px;
+ margin-right: 2em;
}
.ui-spinner-button {
- width: 16px;
+ width: 1.6em;
height: 50%;
font-size: .5em;
padding: 0;
@@ -40,16 +40,9 @@
}
/* more specificity required here to override default borders */
.ui-spinner a.ui-spinner-button {
- border-top: none;
- border-bottom: none;
- border-right: none;
-}
-/* vertically center icon */
-.ui-spinner .ui-icon {
- position: absolute;
- margin-top: -8px;
- top: 50%;
- left: 0;
+ border-top-style: none;
+ border-bottom-style: none;
+ border-right-style: none;
}
.ui-spinner-up {
top: 0;
@@ -57,9 +50,3 @@
.ui-spinner-down {
bottom: 0;
}
-
-/* TR overrides */
-.ui-spinner .ui-icon-triangle-1-s {
- /* need to fix icons sprite */
- background-position: -65px -16px;
-}
diff --git a/themes/base/theme.css b/themes/base/theme.css
index 0e0561dc1..acac7cc04 100644
--- a/themes/base/theme.css
+++ b/themes/base/theme.css
@@ -53,7 +53,13 @@
----------------------------------*/
.ui-state-default,
.ui-widget-content .ui-state-default,
-.ui-widget-header .ui-state-default {
+.ui-widget-header .ui-state-default,
+.ui-button,
+
+/* We use html here because we need a greater specificity to make sure disabled
+works properly when clicked or hovered */
+html .ui-button.ui-state-disabled:hover,
+html .ui-button.ui-state-disabled:active {
border: 1px solid #c5c5c5/*{borderColorDefault}*/;
background: #f6f6f6/*{bgColorDefault}*/ /*{bgImgUrlDefault}*/ /*{bgDefaultXPos}*/ /*{bgDefaultYPos}*/ /*{bgDefaultRepeat}*/;
font-weight: normal/*{fwDefault}*/;
@@ -61,7 +67,11 @@
}
.ui-state-default a,
.ui-state-default a:link,
-.ui-state-default a:visited {
+.ui-state-default a:visited,
+a.ui-button,
+a:link.ui-button,
+a:visited.ui-button,
+.ui-button {
color: #454545/*{fcDefault}*/;
text-decoration: none;
}
@@ -70,7 +80,9 @@
.ui-widget-header .ui-state-hover,
.ui-state-focus,
.ui-widget-content .ui-state-focus,
-.ui-widget-header .ui-state-focus {
+.ui-widget-header .ui-state-focus,
+.ui-button:hover,
+.ui-button:focus {
border: 1px solid #cccccc/*{borderColorHover}*/;
background: #ededed/*{bgColorHover}*/ /*{bgImgUrlHover}*/ /*{bgHoverXPos}*/ /*{bgHoverYPos}*/ /*{bgHoverRepeat}*/;
font-weight: normal/*{fwDefault}*/;
@@ -83,18 +95,32 @@
.ui-state-focus a,
.ui-state-focus a:hover,
.ui-state-focus a:link,
-.ui-state-focus a:visited {
+.ui-state-focus a:visited,
+a.ui-button:hover,
+a.ui-button:focus {
color: #2b2b2b/*{fcHover}*/;
text-decoration: none;
}
+
+.ui-visual-focus {
+ box-shadow: 0 0 3px 1px rgb(94, 158, 214);
+}
.ui-state-active,
.ui-widget-content .ui-state-active,
-.ui-widget-header .ui-state-active {
+.ui-widget-header .ui-state-active,
+a.ui-button:active,
+.ui-button:active,
+.ui-button.ui-state-active:hover {
border: 1px solid #003eff/*{borderColorActive}*/;
background: #007fff/*{bgColorActive}*/ /*{bgImgUrlActive}*/ /*{bgActiveXPos}*/ /*{bgActiveYPos}*/ /*{bgActiveRepeat}*/;
font-weight: normal/*{fwDefault}*/;
color: #ffffff/*{fcActive}*/;
}
+.ui-icon-background,
+.ui-state-active .ui-icon-background {
+ border: #003eff/*{borderColorActive}*/;
+ background-color: #ffffff/*{fcActive}*/;
+}
.ui-state-active a,
.ui-state-active a:link,
.ui-state-active a:visited {
@@ -171,17 +197,22 @@
.ui-widget-header .ui-icon {
background-image: url("images/ui-icons_444444_256x240.png")/*{iconsHeader}*/;
}
-.ui-state-default .ui-icon {
+.ui-button .ui-icon {
background-image: url("images/ui-icons_777777_256x240.png")/*{iconsDefault}*/;
}
.ui-state-hover .ui-icon,
-.ui-state-focus .ui-icon {
+.ui-state-focus .ui-icon,
+.ui-button:hover .ui-icon,
+.ui-button:focus .ui-icon,
+.ui-state-default .ui-icon {
background-image: url("images/ui-icons_555555_256x240.png")/*{iconsHover}*/;
}
-.ui-state-active .ui-icon {
+.ui-state-active .ui-icon,
+.ui-button:active .ui-icon {
background-image: url("images/ui-icons_ffffff_256x240.png")/*{iconsActive}*/;
}
-.ui-state-highlight .ui-icon {
+.ui-state-highlight .ui-icon,
+.ui-button .ui-state-highlight.ui-icon {
background-image: url("images/ui-icons_777620_256x240.png")/*{iconsHighlight}*/;
}
.ui-state-error .ui-icon,
@@ -195,7 +226,7 @@
.ui-icon-caret-1-ne { background-position: -16px 0; }
.ui-icon-caret-1-e { background-position: -32px 0; }
.ui-icon-caret-1-se { background-position: -48px 0; }
-.ui-icon-caret-1-s { background-position: -64px 0; }
+.ui-icon-caret-1-s { background-position: -65px 0; }
.ui-icon-caret-1-sw { background-position: -80px 0; }
.ui-icon-caret-1-w { background-position: -96px 0; }
.ui-icon-caret-1-nw { background-position: -112px 0; }
@@ -205,7 +236,7 @@
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
-.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-s { background-position: -65px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
@@ -215,7 +246,7 @@
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
-.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-s { background-position: -65px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
@@ -227,7 +258,7 @@
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
-.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-n { background-position: 1px -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
diff --git a/ui/core.js b/ui/core.js
index 8737993d9..2cccd0bd8 100644
--- a/ui/core.js
+++ b/ui/core.js
@@ -1,18 +1,3 @@
-/*!
- * jQuery UI Core @VERSION
- * http://jqueryui.com
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- *
- */
-
-//>>label: Core
-//>>group: UI Core
-//>>description: The core of jQuery UI, required for all interactions and widgets.
-//>>docs: http://api.jqueryui.com/category/ui-core/
-
// This file is deprecated in 1.12.0 to be removed in 1.13
( function() {
define( [
diff --git a/ui/effects/effect-transfer.js b/ui/effects/effect-transfer.js
index 38f815875..0029de7a5 100644
--- a/ui/effects/effect-transfer.js
+++ b/ui/effects/effect-transfer.js
@@ -29,10 +29,12 @@
}
}( function( $ ) {
+var effect;
if ( $.uiBackCompat !== false ) {
- return $.effects.define( "transfer", function( options, done ) {
+ effect = $.effects.define( "transfer", function( options, done ) {
$( this ).transfer( options, done );
} );
}
+return effect;
} ) );
diff --git a/ui/form-reset-mixin.js b/ui/form-reset-mixin.js
index 21704708e..a14c82ee6 100644
--- a/ui/form-reset-mixin.js
+++ b/ui/form-reset-mixin.js
@@ -1,3 +1,17 @@
+/*!
+ * jQuery UI Form Reset Mixin @VERSION
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Form Reset Mixin
+//>>group: Core
+//>>description: Refresh input widgets when their form is reset
+//>>docs: http://api.jqueryui.com/form-reset-mixin/
+
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
diff --git a/ui/jquery-1-7.js b/ui/jquery-1-7.js
index 8d25f8807..bd40e332f 100644
--- a/ui/jquery-1-7.js
+++ b/ui/jquery-1-7.js
@@ -9,7 +9,7 @@
*/
//>>label: jQuery 1.7 Support
-//>>group: UI Core
+//>>group: Core
//>>description: Support version 1.7.x of jQuery core
( function( factory ) {
diff --git a/ui/position.js b/ui/position.js
index 64f86173e..f8fa1b5db 100644
--- a/ui/position.js
+++ b/ui/position.js
@@ -10,7 +10,7 @@
*/
//>>label: Position
-//>>group: UI Core
+//>>group: Core
//>>description: Positions elements relative to other elements.
//>>docs: http://api.jqueryui.com/position/
//>>demos: http://jqueryui.com/position/
diff --git a/ui/widget.js b/ui/widget.js
index 1542cc88b..e38c0c871 100644
--- a/ui/widget.js
+++ b/ui/widget.js
@@ -8,7 +8,7 @@
*/
//>>label: Widget
-//>>group: UI Core
+//>>group: Core
//>>description: Provides a factory for creating stateful widgets with a common API.
//>>docs: http://api.jqueryui.com/jQuery.widget/
//>>demos: http://jqueryui.com/widget/
diff --git a/ui/widgets/accordion.js b/ui/widgets/accordion.js
index 360ac1700..14b3f7303 100644
--- a/ui/widgets/accordion.js
+++ b/ui/widgets/accordion.js
@@ -12,9 +12,9 @@
//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
//>>docs: http://api.jqueryui.com/accordion/
//>>demos: http://jqueryui.com/accordion/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/accordion.css
-//>>css.theme: ../themes/base/theme.css
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/accordion.css
+//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
diff --git a/ui/widgets/autocomplete.js b/ui/widgets/autocomplete.js
index 4067f871f..060d8e94f 100644
--- a/ui/widgets/autocomplete.js
+++ b/ui/widgets/autocomplete.js
@@ -12,9 +12,9 @@
//>>description: Lists suggested words as the user is typing.
//>>docs: http://api.jqueryui.com/autocomplete/
//>>demos: http://jqueryui.com/autocomplete/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/autocomplete.css
-//>>css.theme: ../themes/base/theme.css
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/autocomplete.css
+//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
@@ -245,24 +245,6 @@ $.widget( "ui.autocomplete", {
this.element.trigger( "focus" );
}
} );
-
- // Clicking on the scrollbar causes focus to shift to the body
- // but we can't detect a mouseup or a click immediately afterward
- // so we have to track the next mousedown and close the menu if
- // the user clicks somewhere outside of the autocomplete
- var menuElement = this.menu.element[ 0 ];
- if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
- this._delay( function() {
- var that = this;
- this.document.one( "mousedown", function( event ) {
- if ( event.target !== that.element[ 0 ] &&
- event.target !== menuElement &&
- !$.contains( menuElement, event.target ) ) {
- that.close();
- }
- } );
- } );
- }
},
menufocus: function( event, ui ) {
var label, item;
@@ -368,6 +350,20 @@ $.widget( "ui.autocomplete", {
}
},
+ _isEventTargetInWidget: function( event ) {
+ var menuElement = this.menu.element[ 0 ];
+
+ return event.target === this.element[ 0 ] ||
+ event.target === menuElement ||
+ $.contains( menuElement, event.target );
+ },
+
+ _closeOnClickOutside: function( event ) {
+ if ( !this._isEventTargetInWidget( event ) ) {
+ this.close();
+ }
+ },
+
_appendTo: function() {
var element = this.options.appendTo;
@@ -496,6 +492,10 @@ $.widget( "ui.autocomplete", {
},
_close: function( event ) {
+
+ // Remove the handler that closes the menu on outside clicks
+ this._off( this.document, "mousedown" );
+
if ( this.menu.element.is( ":visible" ) ) {
this.menu.element.hide();
this.menu.blur();
@@ -546,6 +546,11 @@ $.widget( "ui.autocomplete", {
if ( this.options.autoFocus ) {
this.menu.next();
}
+
+ // Listen for interactions outside of the widget (#6642)
+ this._on( this.document, {
+ mousedown: "_closeOnClickOutside"
+ } );
},
_resizeMenu: function() {
diff --git a/ui/widgets/button.js b/ui/widgets/button.js
index 94fc75331..50da9f9e2 100644
--- a/ui/widgets/button.js
+++ b/ui/widgets/button.js
@@ -12,9 +12,9 @@
//>>description: Enhances a form with themeable buttons.
//>>docs: http://api.jqueryui.com/button/
//>>demos: http://jqueryui.com/button/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/button.css
-//>>css.theme: ../themes/base/theme.css
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/button.css
+//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
@@ -22,10 +22,13 @@
// AMD. Register as an anonymous module.
define( [
"jquery",
- "../data",
+
+ // These are only for backcompat
+ // TODO: Remove after 1.12
+ "./controlgroup",
+ "./checkboxradio",
+
"../keycode",
- "../labels",
- "../version",
"../widget"
], factory );
} else {
@@ -35,391 +38,349 @@
}
}( function( $ ) {
-var lastActive,
- baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
- 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() {
- var form = $( this );
- setTimeout( function() {
- form.find( ":ui-button" ).button( "refresh" );
- }, 1 );
- },
- radioGroup = function( radio ) {
- var name = radio.name,
- form = radio.form,
- radios = $( [] );
- if ( name ) {
- name = name.replace( /'/g, "\\'" );
- if ( form ) {
- radios = $( form ).find( "[name='" + name + "'][type=radio]" );
- } else {
- radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
- .filter( function() {
- return !this.form;
- } );
- }
- }
- return radios;
- };
-
$.widget( "ui.button", {
version: "@VERSION",
defaultElement: "<button>",
options: {
+ classes: {
+ "ui-button": "ui-corner-all"
+ },
disabled: null,
- text: true,
+ icon: null,
+ iconPosition: "beginning",
label: null,
- icons: {
- primary: null,
- secondary: null
- }
+ showLabel: true
},
- _create: function() {
- this.element.closest( "form" )
- .off( "reset" + this.eventNamespace )
- .on( "reset" + this.eventNamespace, formResetHandler );
- if ( typeof this.options.disabled !== "boolean" ) {
- this.options.disabled = !!this.element.prop( "disabled" );
- } else {
- this.element.prop( "disabled", this.options.disabled );
- }
+ _getCreateOptions: function() {
+ var disabled,
- this._determineButtonType();
- this.hasTitle = !!this.buttonElement.attr( "title" );
+ // This is to support cases like in jQuery Mobile where the base widget does have
+ // an implementation of _getCreateOptions
+ options = this._super() || {};
- var that = this,
- options = this.options,
- toggleButton = this.type === "checkbox" || this.type === "radio",
- activeClass = !toggleButton ? "ui-state-active" : "";
+ this.isInput = this.element.is( "input" );
- if ( options.label === null ) {
- options.label = ( this.type === "input" ? this.buttonElement.val() : this.buttonElement.html() );
+ disabled = this.element[ 0 ].disabled;
+ if ( disabled != null ) {
+ options.disabled = disabled;
}
- this._hoverable( this.buttonElement );
+ this.originalLabel = this.isInput ? this.element.val() : this.element.html();
+ if ( this.originalLabel ) {
+ options.label = this.originalLabel;
+ }
- this.buttonElement
- .addClass( baseClasses )
- .attr( "role", "button" )
- .on( "mouseenter" + this.eventNamespace, function() {
- if ( options.disabled ) {
- return;
- }
- if ( this === lastActive ) {
- $( this ).addClass( "ui-state-active" );
- }
- } )
- .on( "mouseleave" + this.eventNamespace, function() {
- if ( options.disabled ) {
- return;
- }
- $( this ).removeClass( activeClass );
- } )
- .on( "click" + this.eventNamespace, function( event ) {
- if ( options.disabled ) {
- event.preventDefault();
- event.stopImmediatePropagation();
- }
- } );
+ return options;
+ },
- // Can't use _focusable() because the element that receives focus
- // and the element that gets the ui-state-focus class are different
- this._on( {
- focus: function() {
- this.buttonElement.addClass( "ui-state-focus" );
- },
- blur: function() {
- this.buttonElement.removeClass( "ui-state-focus" );
- }
- } );
+ _create: function() {
+ if ( !this.option.showLabel & !this.options.icon ) {
+ this.options.showLabel = true;
+ }
- if ( toggleButton ) {
- this.element.on( "change" + this.eventNamespace, function() {
- that.refresh();
- } );
+ // We have to check the option again here even though we did in _getCreateOptions,
+ // because null may have been passed on init which would override what was set in
+ // _getCreateOptions
+ if ( this.options.disabled == null ) {
+ this.options.disabled = this.element[ 0 ].disabled || false;
}
- if ( this.type === "checkbox" ) {
- this.buttonElement.on( "click" + this.eventNamespace, function() {
- if ( options.disabled ) {
- return false;
- }
- } );
- } else if ( this.type === "radio" ) {
- this.buttonElement.on( "click" + this.eventNamespace, function() {
- if ( options.disabled ) {
- return false;
- }
- $( this ).addClass( "ui-state-active" );
- that.buttonElement.attr( "aria-pressed", "true" );
-
- var radio = that.element[ 0 ];
- radioGroup( radio )
- .not( radio )
- .map( function() {
- return $( this ).button( "widget" )[ 0 ];
- } )
- .removeClass( "ui-state-active" )
- .attr( "aria-pressed", "false" );
- } );
- } else {
- this.buttonElement
- .on( "mousedown" + this.eventNamespace, function() {
- if ( options.disabled ) {
- return false;
- }
- $( this ).addClass( "ui-state-active" );
- lastActive = this;
- that.document.one( "mouseup", function() {
- lastActive = null;
- } );
- } )
- .on( "mouseup" + this.eventNamespace, function() {
- if ( options.disabled ) {
- return false;
- }
- $( this ).removeClass( "ui-state-active" );
- } )
- .on( "keydown" + this.eventNamespace, function( event ) {
- if ( options.disabled ) {
- return false;
- }
- if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
- $( this ).addClass( "ui-state-active" );
- }
- } )
+ this.hasTitle = !!this.element.attr( "title" );
- // see #8559, we bind to blur here in case the button element loses
- // focus between keydown and keyup, it would be left in an "active" state
- .on( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
- $( this ).removeClass( "ui-state-active" );
- } );
+ // Check to see if the label needs to be set or if its already correct
+ if ( this.options.label && this.options.label !== this.originalLabel ) {
+ if ( this.isInput ) {
+ this.element.val( this.options.label );
+ } else {
+ this.element.html( this.options.label );
+ }
+ }
+ this._addClass( "ui-button", "ui-widget" );
+ this._setOption( "disabled", this.options.disabled );
+ this._enhance();
- if ( this.buttonElement.is( "a" ) ) {
- this.buttonElement.on( "keyup", function( event ) {
+ if ( this.element.is( "a" ) ) {
+ this._on( {
+ "keyup": function( event ) {
if ( event.keyCode === $.ui.keyCode.SPACE ) {
-
- // TODO pass through original event correctly (just as 2nd argument doesn't work)
- $( this ).trigger( "click" );
+ event.preventDefault();
+
+ // Support: PhantomJS <= 1.9, IE 8 Only
+ // If a native click is available use it so we actually cause navigation
+ // otherwise just trigger a click event
+ if ( this.element[ 0 ].click ) {
+ this.element[ 0 ].click();
+ } else {
+ this.element.trigger( "click" );
+ }
}
- } );
- }
+ }
+ } );
+ }
+ },
+
+ _enhance: function() {
+ if ( !this.element.is( "button" ) ) {
+ this.element.attr( "role", "button" );
}
- this._setOption( "disabled", options.disabled );
- this._resetButton();
+ if ( this.options.icon ) {
+ this._updateIcon( "icon", this.options.icon );
+ this._updateTooltip();
+ }
},
- _determineButtonType: function() {
- var ancestor, labelSelector, checked;
+ _updateTooltip: function() {
+ this.title = this.element.attr( "title" );
- if ( this.element.is( "[type=checkbox]" ) ) {
- this.type = "checkbox";
- } else if ( this.element.is( "[type=radio]" ) ) {
- this.type = "radio";
- } else if ( this.element.is( "input" ) ) {
- this.type = "input";
- } else {
- this.type = "button";
+ if ( !this.options.showLabel && !this.title ) {
+ this.element.attr( "title", this.options.label );
}
+ },
- if ( this.type === "checkbox" || this.type === "radio" ) {
-
- // we don't search against the document in case the element
- // is disconnected from the DOM
- ancestor = this.element.parents().last();
- labelSelector = "label[for='" + this.element.attr( "id" ) + "']";
- this.buttonElement = ancestor.find( labelSelector );
- if ( !this.buttonElement.length ) {
- ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
- this.buttonElement = ancestor.filter( labelSelector );
- if ( !this.buttonElement.length ) {
- this.buttonElement = ancestor.find( labelSelector );
- }
+ _updateIcon: function( option, value ) {
+ var icon = option !== "iconPosition",
+ position = icon ? this.options.iconPosition : value,
+ displayBlock = position === "top" || position === "bottom";
+
+ // Create icon
+ if ( !this.icon ) {
+ this.icon = $( "<span>" );
+
+ this._addClass( this.icon, "ui-button-icon", "ui-icon" );
+
+ if ( !this.options.showLabel ) {
+ this._addClass( "ui-button-icon-only" );
}
- this.element.addClass( "ui-helper-hidden-accessible" );
+ } else if ( icon ) {
- checked = this.element.is( ":checked" );
- if ( checked ) {
- this.buttonElement.addClass( "ui-state-active" );
+ // If we are updating the icon remove the old icon class
+ this._removeClass( this.icon, null, this.options.icon );
+ }
+
+ // If we are updating the icon add the new icon class
+ if ( icon ) {
+ this._addClass( this.icon, null, value );
+ }
+
+ this._attachIcon( position );
+
+ // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
+ // the iconSpace if there is one.
+ if ( displayBlock ) {
+ this._addClass( this.icon, null, "ui-widget-icon-block" );
+ if ( this.iconSpace ) {
+ this.iconSpace.remove();
}
- this.buttonElement.prop( "aria-pressed", checked );
} else {
- this.buttonElement = this.element;
- }
- },
- widget: function() {
- return this.buttonElement;
+ // Position is beginning or end so remove the ui-widget-icon-block class and add the
+ // space if it does not exist
+ if ( !this.iconSpace ) {
+ this.iconSpace = $( "<span> </span>" );
+ this._addClass( this.iconSpace, "ui-button-icon-space" );
+ }
+ this._removeClass( this.icon, null, "ui-wiget-icon-block" );
+ this._attachIconSpace( position );
+ }
},
_destroy: function() {
- this.element
- .removeClass( "ui-helper-hidden-accessible" );
- this.buttonElement
- .removeClass( baseClasses + " ui-state-active " + typeClasses )
- .removeAttr( "role aria-pressed" )
- .html( this.buttonElement.find( ".ui-button-text" ).html() );
+ this.element.removeAttr( "role" );
+ if ( this.icon ) {
+ this.icon.remove();
+ }
+ if ( this.iconSpace ) {
+ this.iconSpace.remove();
+ }
if ( !this.hasTitle ) {
- this.buttonElement.removeAttr( "title" );
+ this.element.removeAttr( "title" );
}
},
- _setOption: function( key, value ) {
- this._super( key, value );
- if ( key === "disabled" ) {
- this.widget().toggleClass( "ui-state-disabled", !!value );
- this.element.prop( "disabled", !!value );
- if ( value ) {
- if ( this.type === "checkbox" || this.type === "radio" ) {
- this.buttonElement.removeClass( "ui-state-focus" );
- } else {
- this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
- }
- }
- return;
- }
- this._resetButton();
+ _attachIconSpace: function( iconPosition ) {
+ this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
},
- refresh: function() {
+ _attachIcon: function( iconPosition ) {
+ this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
+ },
- //See #8237 & #8828
- var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
+ _setOptions: function( options ) {
+ var newShowLabel = options.showLabel === undefined ?
+ this.options.showLabel :
+ options.showLabel,
+ newIcon = options.icon === undefined ? this.options.icon : options.icon;
- if ( isDisabled !== this.options.disabled ) {
- this._setOption( "disabled", isDisabled );
- }
- if ( this.type === "radio" ) {
- radioGroup( this.element[ 0 ] ).each( function() {
- if ( $( this ).is( ":checked" ) ) {
- $( this ).button( "widget" )
- .addClass( "ui-state-active" )
- .attr( "aria-pressed", "true" );
- } else {
- $( this ).button( "widget" )
- .removeClass( "ui-state-active" )
- .attr( "aria-pressed", "false" );
- }
- } );
- } else if ( this.type === "checkbox" ) {
- if ( this.element.is( ":checked" ) ) {
- this.buttonElement
- .addClass( "ui-state-active" )
- .attr( "aria-pressed", "true" );
- } else {
- this.buttonElement
- .removeClass( "ui-state-active" )
- .attr( "aria-pressed", "false" );
- }
+ if ( !newShowLabel && !newIcon ) {
+ options.showLabel = true;
}
+ this._super( options );
},
- _resetButton: function() {
- if ( this.type === "input" ) {
- if ( this.options.label ) {
- this.element.val( this.options.label );
+ _setOption: function( key, value ) {
+ if ( key === "icon" ) {
+ if ( value ) {
+ this._updateIcon( key, value );
+ } else if ( this.icon ) {
+ this.icon.remove();
+ if ( this.iconSpace ) {
+ this.iconSpace.remove();
+ }
}
- return;
}
- var buttonElement = this.buttonElement.removeClass( typeClasses ),
- buttonText = $( "<span></span>", this.document[ 0 ] )
- .addClass( "ui-button-text" )
- .html( this.options.label )
- .appendTo( buttonElement.empty() )
- .text(),
- icons = this.options.icons,
- multipleIcons = icons.primary && icons.secondary,
- buttonClasses = [];
-
- if ( icons.primary || icons.secondary ) {
- if ( this.options.text ) {
- buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
- }
- if ( icons.primary ) {
- buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
- }
+ if ( key === "iconPosition" ) {
+ this._updateIcon( key, value );
+ }
- if ( icons.secondary ) {
- buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
- }
+ // Make sure we can't end up with a button that has neither text nor icon
+ if ( key === "showLabel" ) {
+ this._toggleClass( "ui-button-icon-only", null, !value );
+ this._updateTooltip();
+ }
- if ( !this.options.text ) {
- buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
+ if ( key === "label" ) {
+ if ( this.isInput ) {
+ this.element.val( value );
+ } else {
- if ( !this.hasTitle ) {
- buttonElement.attr( "title", $.trim( buttonText ) );
+ // If there is an icon, append it, else nothing then append the value
+ // this avoids removal of the icon when setting label text
+ this.element.html( value );
+ if ( this.icon ) {
+ this._attachIcon( this.options.iconPosition );
+ this._attachIconSpace( this.options.iconPosition );
}
}
- } else {
- buttonClasses.push( "ui-button-text-only" );
}
- buttonElement.addClass( buttonClasses.join( " " ) );
- }
-} );
-
-$.widget( "ui.buttonset", {
- version: "@VERSION",
- options: {
- items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
- },
- _create: function() {
- this.element.addClass( "ui-buttonset" );
- },
-
- _init: function() {
- this.refresh();
- },
+ this._super( key, value );
- _setOption: function( key, value ) {
if ( key === "disabled" ) {
- this.buttons.button( "option", key, value );
+ this._toggleClass( null, "ui-state-disabled", value );
+ this.element[ 0 ].disabled = value;
+ if ( value ) {
+ this.element.blur();
+ }
}
-
- this._super( key, value );
},
refresh: function() {
- var rtl = this.element.css( "direction" ) === "rtl",
- allButtons = this.element.find( this.options.items ),
- existingButtons = allButtons.filter( ":ui-button" );
-
- // Initialize new buttons
- allButtons.not( ":ui-button" ).button();
-
- // Refresh existing buttons
- existingButtons.button( "refresh" );
-
- this.buttons = allButtons
- .map( function() {
- return $( this ).button( "widget" )[ 0 ];
- } )
- .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
- .filter( ":first" )
- .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
- .end()
- .filter( ":last" )
- .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
- .end()
- .end();
- },
- _destroy: function() {
- this.element.removeClass( "ui-buttonset" );
- this.buttons
- .map( function() {
- return $( this ).button( "widget" )[ 0 ];
- } )
- .removeClass( "ui-corner-left ui-corner-right" )
- .end()
- .button( "destroy" );
+ // Make sure to only check disabled if its an element that supports this otherwise
+ // check for the disabled class to determine state
+ var isDisabled = this.element.is( "input, button" ) ?
+ this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
+
+ if ( isDisabled !== this.options.disabled ) {
+ this._setOptions( { disabled: isDisabled } );
+ }
+
+ this._updateTooltip();
}
} );
+// DEPRECATED
+if ( $.uiBackCompat !== false ) {
+
+ // Text and Icons options
+ $.widget( "ui.button", $.ui.button, {
+ options: {
+ text: true,
+ icons: {
+ primary: null,
+ secondary: null
+ }
+ },
+
+ _create: function() {
+ if ( this.options.showLabel && !this.options.text ) {
+ this.options.showLabel = this.options.text;
+ }
+ if ( !this.options.showLabel && this.options.text ) {
+ this.options.text = this.options.showLabel;
+ }
+ if ( !this.options.icon && ( this.options.icons.primary ||
+ this.options.icons.secondary ) ) {
+ if ( this.options.icons.primary ) {
+ this.options.icon = this.options.icons.primary;
+ } else {
+ this.options.icon = this.options.icons.secondary;
+ this.options.iconPosition = "end";
+ }
+ } else if ( this.options.icon ) {
+ this.options.icons.primary = this.options.icon;
+ }
+ this._super();
+ },
+
+ _setOption: function( key, value ) {
+ if ( key === "text" ) {
+ this._super( "showLabel", value );
+ return;
+ }
+ if ( key === "showLabel" ) {
+ this.options.text = value;
+ }
+ if ( key === "icon" ) {
+ this.options.icons.primary = value;
+ }
+ if ( key === "icons" ) {
+ if ( value.primary ) {
+ this._super( "icon", value.primary );
+ this._super( "iconPosition", "beginning" );
+ } else if ( value.secondary ) {
+ this._super( "icon", value.secondary );
+ this._super( "iconPosition", "end" );
+ }
+ }
+ this._superApply( arguments );
+ }
+ } );
+
+ $.fn.button = ( function( orig ) {
+ return function() {
+ if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
+ ( this.length && this[ 0 ].tagName === "INPUT" && (
+ this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
+ ) ) ) {
+ return orig.apply( this, arguments );
+ }
+ if ( !$.ui.checkboxradio ) {
+ $.error( "Checkboxradio widget missing" );
+ }
+ if ( arguments.length === 0 ) {
+ return this.checkboxradio( {
+ "icon": false
+ } );
+ }
+ return this.checkboxradio.apply( this, arguments );
+ };
+ } )( $.fn.button );
+
+ $.fn.buttonset = function() {
+ if ( !$.ui.controlgroup ) {
+ $.error( "Controlgroup widget missing" );
+ }
+ if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
+ return this.controlgroup.apply( this,
+ [ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
+ }
+ if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
+ return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
+ }
+ if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
+ arguments[ 0 ].items = {
+ button: arguments[ 0 ].items
+ };
+ }
+ return this.controlgroup.apply( this, arguments );
+ };
+}
+
return $.ui.button;
} ) );
diff --git a/ui/widgets/checkboxradio.js b/ui/widgets/checkboxradio.js
new file mode 100644
index 000000000..107749201
--- /dev/null
+++ b/ui/widgets/checkboxradio.js
@@ -0,0 +1,277 @@
+/*!
+ * jQuery UI Checkboxradio @VERSION
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Checkboxradio
+//>>group: Widgets
+//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
+//>>docs: http://api.jqueryui.com/checkboxradio/
+//>>demos: http://jqueryui.com/checkboxradio/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/button.css
+//>>css.structure: ../../themes/base/checkboxradio.css
+//>>css.theme: ../../themes/base/theme.css
+
+( function( factory ) {
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD. Register as an anonymous module.
+ define( [
+ "jquery",
+ "../escape-selector",
+ "../form-reset-mixin",
+ "../labels",
+ "../widget"
+ ], factory );
+ } else {
+
+ // Browser globals
+ factory( jQuery );
+ }
+}( function( $ ) {
+
+$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
+ version: "@VERSION",
+ options: {
+ disabled: null,
+ label: null,
+ icon: true,
+ classes: {
+ "ui-checkboxradio-label": "ui-corner-all",
+ "ui-checkboxradio-icon": "ui-corner-all"
+ }
+ },
+
+ _getCreateOptions: function() {
+ var disabled, labels;
+ var that = this;
+ var options = this._super() || {};
+
+ // We read the type here, because it makes more sense to throw a element type error first,
+ // rather then the error for lack of a label. Often if its the wrong type, it
+ // won't have a label (e.g. calling on a div, btn, etc)
+ this._readType();
+
+ labels = this.element.labels();
+
+ // If there are multiple labels, use the last one
+ this.label = $( labels[ labels.length - 1 ] );
+ if ( !this.label.length ) {
+ $.error( "No label found for checkboxradio widget" );
+ }
+
+ this.originalLabel = "";
+
+ // We need to get the label text but this may also need to make sure it does not contain the
+ // input itself.
+ this.label.contents().not( this.element ).each( function() {
+
+ // The label contents could be text, html, or a mix. We concat each element to get a string
+ // representation of the label, without the input as part of it.
+ that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
+ } );
+
+ // Set the label option if we found label text
+ if ( this.originalLabel ) {
+ options.label = this.originalLabel;
+ }
+
+ disabled = this.element[ 0 ].disabled;
+ if ( disabled != null ) {
+ options.disabled = disabled;
+ }
+ return options;
+ },
+
+ _create: function() {
+ var checked = this.element[ 0 ].checked;
+
+ this._bindFormResetHandler();
+
+ if ( this.options.disabled == null ) {
+ this.options.disabled = this.element[ 0 ].disabled;
+ }
+
+ this._setOption( "disabled", this.options.disabled );
+ this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
+ this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
+
+ if ( this.type === "radio" ) {
+ this._addClass( this.label, "ui-checkboxradio-radio-label" );
+ }
+
+ if ( this.options.label && this.options.label !== this.originalLabel ) {
+ this._updateLabel();
+ } else if ( this.originalLabel ) {
+ this.options.label = this.originalLabel;
+ }
+
+ this._enhance();
+
+ if ( checked ) {
+ this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
+ this._addClass( this.icon, null, "ui-state-hover" );
+ }
+
+ this._on( {
+ change: "_toggleClasses",
+ focus: function() {
+ this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
+ },
+ blur: function() {
+ this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
+ }
+ } );
+ },
+
+ _readType: function() {
+ var nodeName = this.element[ 0 ].nodeName.toLowerCase();
+ this.type = this.element[ 0 ].type;
+ if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
+ $.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
+ " and element.type=" + this.type );
+ }
+ },
+
+ // Support jQuery Mobile enhanced option
+ _enhance: function() {
+ this._updateIcon( this.element[ 0 ].checked );
+ },
+
+ widget: function() {
+ return this.label;
+ },
+
+ _getRadioGroup: function() {
+ var group;
+ var name = this.element[ 0 ].name;
+ var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
+
+ if ( !name ) {
+ return $( [] );
+ }
+
+ if ( this.form.length ) {
+ group = $( this.form[ 0 ].elements ).filter( nameSelector );
+ } else {
+
+ // Not inside a form, check all inputs that also are not inside a form
+ group = $( nameSelector ).filter( function() {
+ return $( this ).form().length === 0;
+ } );
+ }
+
+ return group.not( this.element );
+ },
+
+ _toggleClasses: function() {
+ var checked = this.element[ 0 ].checked;
+ this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
+
+ if ( this.options.icon && this.type === "checkbox" ) {
+
+ // We add ui-state-highlight to change the icon color
+ this._toggleClass( this.icon, null, "ui-icon-check ui-state-highlight", checked )
+ ._toggleClass( this.icon, null, "ui-icon-blank", !checked );
+ }
+ if ( this.type === "radio" ) {
+ this._getRadioGroup()
+ .each( function() {
+ var instance = $( this ).checkboxradio( "instance" );
+
+ if ( instance ) {
+ instance._removeClass( instance.label,
+ "ui-checkboxradio-checked", "ui-state-active" );
+ }
+ } );
+ }
+ },
+
+ _destroy: function() {
+ this._unbindFormResetHandler();
+
+ if ( this.icon ) {
+ this.icon.remove();
+ this.iconSpace.remove();
+ }
+ },
+
+ _setOption: function( key, value ) {
+
+ // We don't allow the value to be set to nothing
+ if ( key === "label" && !value ) {
+ return;
+ }
+
+ this._super( key, value );
+
+ if ( key === "disabled" ) {
+ this._toggleClass( this.label, null, "ui-state-disabled", value );
+ this.element[ 0 ].disabled = value;
+
+ // Don't refresh when setting disabled
+ return;
+ }
+ this.refresh();
+ },
+
+ _updateIcon: function( checked ) {
+ var toAdd = "ui-icon ui-icon-background ";
+
+ if ( this.options.icon ) {
+ if ( !this.icon ) {
+ this.icon = $( "<span>" );
+ this.iconSpace = $( "<span> </span>" );
+ this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
+ }
+
+ if ( this.type === "checkbox" ) {
+ toAdd += checked ? "ui-icon-check ui-state-highlight" : "ui-icon-blank";
+ this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
+ } else {
+ toAdd += "ui-icon-blank";
+ }
+ this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
+ if ( !checked ) {
+ this._removeClass( this.icon, null, "ui-icon-check ui-state-highlight" );
+ }
+ this.icon.prependTo( this.label ).after( this.iconSpace );
+ } else if ( this.icon !== undefined ) {
+ this.icon.remove();
+ this.iconSpace.remove();
+ delete this.icon;
+ }
+ },
+
+ _updateLabel: function() {
+
+ // Remove the contents of the label ( minus the icon, icon space, and input )
+ this.label.contents().not( this.element.add( this.icon ).add( this.iconSpace ) ).remove();
+ this.label.append( this.options.label );
+ },
+
+ refresh: function() {
+ var checked = this.element[ 0 ].checked,
+ isDisabled = this.element[ 0 ].disabled;
+
+ this._updateIcon( checked );
+ this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
+ if ( this.options.label !== null ) {
+ this._updateLabel();
+ }
+
+ if ( isDisabled !== this.options.disabled ) {
+ this._setOptions( { "disabled": isDisabled } );
+ }
+ }
+
+} ] );
+
+return $.ui.checkboxradio;
+
+} ) );
diff --git a/ui/widgets/controlgroup.js b/ui/widgets/controlgroup.js
new file mode 100644
index 000000000..ceb78c7c3
--- /dev/null
+++ b/ui/widgets/controlgroup.js
@@ -0,0 +1,251 @@
+/*!
+ * jQuery UI Controlgroup @VERSION
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Controlgroup
+//>>group: Widgets
+//>>description: Visually groups form control widgets
+//>>docs: http://api.jqueryui.com/controlgroup/
+//>>demos: http://jqueryui.com/controlgroup/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/controlgroup.css
+//>>css.theme: ../../themes/base/theme.css
+
+( function( factory ) {
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD. Register as an anonymous module.
+ define( [
+ "jquery",
+ "../widget"
+ ], factory );
+ } else {
+
+ // Browser globals
+ factory( jQuery );
+ }
+}( function( $ ) {
+
+return $.widget( "ui.controlgroup", {
+ version: "@VERSION",
+ defaultElement: "<div>",
+ options: {
+ direction: "horizontal",
+ disabled: null,
+ onlyVisible: true,
+ items: {
+ "button": "input[type=button], input[type=submit], input[type=reset], button, a",
+ "controlgroupLabel": ".ui-controlgroup-label",
+ "checkboxradio": "input[type='checkbox'], input[type='radio']",
+ "selectmenu": "select",
+ "spinner": ".ui-spinner-input"
+ }
+ },
+
+ _create: function() {
+ this._enhance();
+ },
+
+ // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
+ _enhance: function() {
+ this.element.attr( "role", "toolbar" );
+ this.refresh();
+ },
+
+ _destroy: function() {
+ this._callChildMethod( "destroy" );
+ this.childWidgets.removeData( "ui-controlgroup-data" );
+ this.element.removeAttr( "role" );
+ if ( this.options.items.controlgroupLabel ) {
+ this.element
+ .find( this.options.items.controlgroupLabel )
+ .find( ".ui-controlgroup-label-contents" )
+ .contents().unwrap();
+ }
+ },
+
+ _initWidgets: function() {
+ var that = this,
+ childWidgets = [];
+
+ // First we iterate over each of the items options
+ $.each( this.options.items, function( widget, selector ) {
+ var labels;
+ var options = {};
+
+ // Make sure the widget has a selector set
+ if ( !selector ) {
+ return;
+ }
+
+ if ( widget === "controlgroupLabel" ) {
+ labels = that.element.find( selector );
+ labels.each( function() {
+ $( this ).contents().wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
+ } );
+ that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
+ childWidgets = childWidgets.concat( labels.get() );
+ return;
+ }
+
+ // Make sure the widget actually exists
+ if ( !$.fn[ widget ] ) {
+ return;
+ }
+
+ // We assume everything is in the middle to start because we can't determine
+ // first / last elements until all enhancments are done.
+ if ( that[ "_" + widget + "Options" ] ) {
+ options = that[ "_" + widget + "Options" ]( "middle" );
+ }
+
+ // Find instances of this widget inside controlgroup and init them
+ that.element
+ .find( selector )[ widget ]( options )
+ .each( function() {
+ var element = $( this );
+
+ // Store an instance of the controlgroup to be able to reference
+ // from the outermost element for changing options and refresh
+ var widgetElement = element[ widget ]( "widget" );
+ $.data( widgetElement[ 0 ], "ui-controlgroup-data",
+ element[ widget ]( "instance" ) );
+
+ childWidgets.push( widgetElement[ 0 ] );
+ } );
+ } );
+
+ this.childWidgets = $( $.unique( childWidgets ) );
+ this._addClass( this.childWidgets, "ui-controlgroup-item" );
+ },
+
+ _callChildMethod: function( method ) {
+ this.childWidgets.each( function() {
+ var element = $( this ),
+ data = element.data( "ui-controlgroup-data" );
+ if ( data && data[ method ] ) {
+ data[ method ]();
+ }
+ } );
+ },
+
+ _updateCornerClass: function( element, position ) {
+ var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right";
+ var add = this._buildSimpleOptions( position, "label" ).classes.label;
+
+ this._removeClass( element, null, remove );
+ this._addClass( element, null, add );
+ },
+
+ _buildSimpleOptions: function( position, key ) {
+ var direction = this.options.direction === "vertical";
+ var result = {
+ classes: {}
+ };
+ result.classes[ key ] = {
+ "middle": null,
+ "first": "ui-corner-" + ( direction ? "top" : "left" ),
+ "last": "ui-corner-" + ( direction ? "bottom" : "right" )
+ }[ position ];
+
+ return result;
+ },
+
+ _spinnerOptions: function( position ) {
+ var options = this._buildSimpleOptions( position, "ui-spinner" );
+
+ options.classes[ "ui-spinner-up" ] = "";
+ options.classes[ "ui-spinner-down" ] = "";
+
+ return options;
+ },
+
+ _buttonOptions: function( position ) {
+ return this._buildSimpleOptions( position, "ui-button" );
+ },
+
+ _checkboxradioOptions: function( position ) {
+ return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
+ },
+
+ _selectmenuOptions: function( position ) {
+ var direction = this.options.direction === "vertical";
+ return {
+ width: direction ? "auto" : false,
+ classes: {
+ middle: {
+ "ui-selectmenu-button-open": null,
+ "ui-selectmenu-button-closed": null
+ },
+ first: {
+ "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
+ "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
+ },
+ last: {
+ "ui-selectmenu-button-open": direction ? null : "ui-corner-tr",
+ "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
+ }
+
+ }[ position ]
+ };
+ },
+
+ _setOption: function( key, value ) {
+ if ( key === "direction" ) {
+ this._removeClass( "ui-controlgroup-" + this.options.direction );
+ }
+
+ this._super( key, value );
+ if ( key === "disabled" ) {
+ this._callChildMethod( value ? "disable" : "enable" );
+ return;
+ }
+
+ this.refresh();
+ },
+
+ refresh: function() {
+ var children,
+ that = this;
+
+ this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
+
+ if ( this.options.direction === "horizontal" ) {
+ this._addClass( null, "ui-helper-clearfix" );
+ }
+ this._initWidgets();
+
+ children = this.childWidgets;
+
+ // We filter here because we need to track all childWidgets not just the visible ones
+ if ( this.options.onlyVisible ) {
+ children = children.filter( ":visible" );
+ }
+
+ if ( children.length ) {
+
+ // We do this last because we need to make sure all enhancment is done
+ // before determining first and last
+ $.each( [ "first", "last" ], function( index, value ) {
+ var instance = children[ value ]().data( "ui-controlgroup-data" );
+
+ if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
+ instance.element[ instance.widgetName ](
+ that[ "_" + instance.widgetName + "Options" ]( value )
+ );
+ } else {
+ that._updateCornerClass( children[ value ](), value );
+ }
+ } );
+
+ // Finally call the refresh method on each of the child widgets.
+ this._callChildMethod( "refresh" );
+ }
+ }
+} );
+} ) );
diff --git a/ui/widgets/dialog.js b/ui/widgets/dialog.js
index 6070014c9..c3ca95ed3 100644
--- a/ui/widgets/dialog.js
+++ b/ui/widgets/dialog.js
@@ -12,9 +12,9 @@
//>>description: Displays customizable dialog windows.
//>>docs: http://api.jqueryui.com/dialog/
//>>demos: http://jqueryui.com/dialog/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/dialog.css
-//>>css.theme: ../themes/base/theme.css
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/dialog.css
+//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
@@ -426,11 +426,9 @@ $.widget( "ui.dialog", {
// dialog in IE (#9312)
this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
.button( {
- label: this.options.closeText,
- icons: {
- primary: "ui-icon-closethick"
- },
- text: false
+ label: $( "<a>" ).text( this.options.closeText ).html(),
+ icon: "ui-icon-closethick",
+ showLabel: false
} )
.appendTo( this.uiDialogTitlebar );
@@ -498,12 +496,15 @@ $.widget( "ui.dialog", {
// Change the context for the click callback to be the main element
click = props.click;
buttonOptions = {
- icons: props.icons,
- text: props.showText
+ icon: props.icon,
+ iconPosition: props.iconPosition,
+ showLabel: props.showLabel
};
- delete props.icons;
- delete props.showText;
+
delete props.click;
+ delete props.icon;
+ delete props.iconPosition;
+ delete props.showLabel;
$( "<button></button>", props )
.button( buttonOptions )
@@ -714,7 +715,7 @@ $.widget( "ui.dialog", {
this.uiDialogTitlebarClose.button( {
// Ensure that we always pass a string
- label: "" + value
+ label: $( "<a>" ).text( "" + this.options.closeText ).html()
} );
}
diff --git a/ui/widgets/draggable.js b/ui/widgets/draggable.js
index f61c38ce0..7da09b7ec 100644
--- a/ui/widgets/draggable.js
+++ b/ui/widgets/draggable.js
@@ -12,7 +12,7 @@
//>>description: Enables dragging functionality for any element.
//>>docs: http://api.jqueryui.com/draggable/
//>>demos: http://jqueryui.com/draggable/
-//>>css.structure: ../themes/base/draggable.css
+//>>css.structure: ../../themes/base/draggable.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
@@ -255,7 +255,7 @@ $.widget( "ui.draggable", $.ui.mouse, {
if ( !noPropagation ) {
var ui = this._uiHash();
if ( this._trigger( "drag", event, ui ) === false ) {
- this._mouseUp( {} );
+ this._mouseUp( new $.Event( "mouseup", event ) );
return false;
}
this.position = ui.position;
@@ -322,7 +322,7 @@ $.widget( "ui.draggable", $.ui.mouse, {
cancel: function() {
if ( this.helper.is( ".ui-draggable-dragging" ) ) {
- this._mouseUp( {} );
+ this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
} else {
this._clear();
}
diff --git a/ui/widgets/menu.js b/ui/widgets/menu.js
index d42d65bac..e7b13e7c9 100644
--- a/ui/widgets/menu.js
+++ b/ui/widgets/menu.js
@@ -12,9 +12,9 @@
//>>description: Creates nestable menus.
//>>docs: http://api.jqueryui.com/menu/
//>>demos: http://jqueryui.com/menu/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/menu.css
-//>>css.theme: ../themes/base/theme.css
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/menu.css
+//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
diff --git a/ui/widgets/mouse.js b/ui/widgets/mouse.js
index 938d0f4b7..c14aebe53 100644
--- a/ui/widgets/mouse.js
+++ b/ui/widgets/mouse.js
@@ -8,7 +8,7 @@
*/
//>>label: Mouse
-//>>group: UI Core
+//>>group: Widgets
//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
//>>docs: http://api.jqueryui.com/mouse/
@@ -146,7 +146,16 @@ return $.widget( "ui.mouse", {
// Iframe mouseup check - mouseup occurred in another document
} else if ( !event.which ) {
- return this._mouseUp( event );
+
+ // Support: Safari <=8 - 9
+ // Safari sets which to 0 if you press any of the following keys
+ // during a drag (#14461)
+ if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
+ event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
+ this.ignoreMissingWhich = true;
+ } else if ( !this.ignoreMissingWhich ) {
+ return this._mouseUp( event );
+ }
}
}
@@ -188,8 +197,9 @@ return $.widget( "ui.mouse", {
delete this._mouseDelayTimer;
}
+ this.ignoreMissingWhich = false;
mouseHandled = false;
- return false;
+ event.preventDefault();
},
_mouseDistanceMet: function( event ) {
diff --git a/ui/widgets/progressbar.js b/ui/widgets/progressbar.js
index 7e2695994..6afba892e 100644
--- a/ui/widgets/progressbar.js
+++ b/ui/widgets/progressbar.js
@@ -12,9 +12,9 @@
//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
//>>docs: http://api.jqueryui.com/progressbar/
//>>demos: http://jqueryui.com/progressbar/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/progressbar.css
-//>>css.theme: ../themes/base/theme.css
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/progressbar.css
+//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
diff --git a/ui/widgets/resizable.js b/ui/widgets/resizable.js
index 74e664c43..88ad41180 100644
--- a/ui/widgets/resizable.js
+++ b/ui/widgets/resizable.js
@@ -12,9 +12,9 @@
//>>description: Enables resize functionality for any element.
//>>docs: http://api.jqueryui.com/resizable/
//>>demos: http://jqueryui.com/resizable/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/resizable.css
-//>>css.theme: ../themes/base/theme.css
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/resizable.css
+//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
@@ -99,7 +99,7 @@ $.widget( "ui.resizable", $.ui.mouse, {
_create: function() {
- var n, i, handle, axis, hname,
+ var n, i, handle, axis, hname, margins,
that = this,
o = this.options;
this._addClass( "ui-resizable" );
@@ -131,18 +131,15 @@ $.widget( "ui.resizable", $.ui.mouse, {
this.elementIsWrapper = true;
- this.element.css( {
- marginLeft: this.originalElement.css( "marginLeft" ),
+ margins = {
marginTop: this.originalElement.css( "marginTop" ),
marginRight: this.originalElement.css( "marginRight" ),
- marginBottom: this.originalElement.css( "marginBottom" )
- } );
- this.originalElement.css( {
- marginLeft: 0,
- marginTop: 0,
- marginRight: 0,
- marginBottom: 0
- } );
+ marginBottom: this.originalElement.css( "marginBottom" ),
+ marginLeft: this.originalElement.css( "marginLeft" )
+ };
+
+ this.element.css( margins );
+ this.originalElement.css( "margin", 0 );
// support: Safari
// Prevent Safari textarea resize
@@ -157,7 +154,7 @@ $.widget( "ui.resizable", $.ui.mouse, {
// Support: IE9
// avoid IE jump (hard set the margin)
- this.originalElement.css( { margin: this.originalElement.css( "margin" ) } );
+ this.originalElement.css( margins );
this._proportionallyResize();
}
@@ -690,8 +687,8 @@ $.widget( "ui.resizable", $.ui.mouse, {
this._addClass( this.helper, this._helper );
this.helper.css( {
- width: this.element.outerWidth() - 1,
- height: this.element.outerHeight() - 1,
+ width: this.element.outerWidth(),
+ height: this.element.outerHeight(),
position: "absolute",
left: this.elementOffset.left + "px",
top: this.elementOffset.top + "px",
@@ -1035,7 +1032,7 @@ $.ui.plugin.add( "resizable", "alsoResize", {
},
stop: function() {
- $( this ).removeData( "resizable-alsoresize" );
+ $( this ).removeData( "ui-resizable-alsoresize" );
}
} );
diff --git a/ui/widgets/selectable.js b/ui/widgets/selectable.js
index 152729d7c..f3f144a81 100644
--- a/ui/widgets/selectable.js
+++ b/ui/widgets/selectable.js
@@ -12,7 +12,7 @@
//>>description: Allows groups of elements to be selected with the mouse.
//>>docs: http://api.jqueryui.com/selectable/
//>>demos: http://jqueryui.com/selectable/
-//>>css.structure: ../themes/base/selectable.css
+//>>css.structure: ../../themes/base/selectable.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
diff --git a/ui/widgets/selectmenu.js b/ui/widgets/selectmenu.js
index 30d8c71af..b251f04f1 100644
--- a/ui/widgets/selectmenu.js
+++ b/ui/widgets/selectmenu.js
@@ -12,9 +12,9 @@
//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
//>>docs: http://api.jqueryui.com/selectmenu/
//>>demos: http://jqueryui.com/selectmenu/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/selectmenu.css
-//>>css.theme: ../themes/base/theme.css
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
+//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
@@ -24,6 +24,7 @@
"jquery",
"./menu",
"../escape-selector",
+ "../form-reset-mixin",
"../keycode",
"../labels",
"../position",
@@ -38,7 +39,7 @@
}
}( function( $ ) {
-return $.widget( "ui.selectmenu", {
+return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
version: "@VERSION",
defaultElement: "<select>",
options: {
@@ -76,13 +77,14 @@ return $.widget( "ui.selectmenu", {
this._drawButton();
this._drawMenu();
+ this._bindFormResetHandler();
this._rendered = false;
this.menuItems = $();
},
_drawButton: function() {
- var icon,
+ var icon, space,
that = this,
item = this._parseOption(
this.element.find( "option:selected" ),
@@ -115,10 +117,13 @@ return $.widget( "ui.selectmenu", {
.insertAfter( this.element );
this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
- "ui-widget ui-state-default" );
+ "ui-button ui-widget" );
icon = $( "<span>" ).prependTo( this.button );
+ space = $( "<span> </span>" );
+ this._addClass( space, "ui-selectmenu-icon-space" );
this._addClass( icon, null, "ui-icon " + this.options.icons.button );
+ icon.after( space );
this.buttonItem = this._renderButtonItem( item )
.appendTo( this.button );
@@ -136,8 +141,6 @@ return $.widget( "ui.selectmenu", {
that._refreshMenu();
}
} );
- this._hoverable( this.button );
- this._focusable( this.button );
},
_drawMenu: function() {
@@ -606,7 +609,7 @@ return $.widget( "ui.selectmenu", {
// we always remove classes first and add them second, otherwise if both classes have the
// same theme class, it will be removed after we add it.
this._removeClass( this.button, "ui-selectmenu-button-" +
- ( this.isOpen ? "closed" : "open" ) )
+ ( this.isOpen ? "closed" : "open" ) )
._addClass( this.button, "ui-selectmenu-button-" +
( this.isOpen ? "open" : "closed" ) )
._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
@@ -674,12 +677,13 @@ return $.widget( "ui.selectmenu", {
},
_destroy: function() {
+ this._unbindFormResetHandler();
this.menuWrap.remove();
this.button.remove();
this.element.show();
this.element.removeUniqueId();
this.labels.attr( "for", this.ids.element );
}
-} );
+} ] );
} ) );
diff --git a/ui/widgets/slider.js b/ui/widgets/slider.js
index 8b8a7292a..a2da892c4 100644
--- a/ui/widgets/slider.js
+++ b/ui/widgets/slider.js
@@ -12,9 +12,9 @@
//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
//>>docs: http://api.jqueryui.com/slider/
//>>demos: http://jqueryui.com/slider/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/slider.css
-//>>css.theme: ../themes/base/theme.css
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/slider.css
+//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
diff --git a/ui/widgets/sortable.js b/ui/widgets/sortable.js
index 423bb81f8..8920ed967 100644
--- a/ui/widgets/sortable.js
+++ b/ui/widgets/sortable.js
@@ -12,7 +12,7 @@
//>>description: Enables items in a list to be sorted using the mouse.
//>>docs: http://api.jqueryui.com/sortable/
//>>demos: http://jqueryui.com/sortable/
-//>>css.structure: ../themes/base/sortable.css
+//>>css.structure: ../../themes/base/sortable.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
diff --git a/ui/widgets/spinner.js b/ui/widgets/spinner.js
index f79b2baed..e875f10ad 100644
--- a/ui/widgets/spinner.js
+++ b/ui/widgets/spinner.js
@@ -12,9 +12,9 @@
//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
//>>docs: http://api.jqueryui.com/spinner/
//>>demos: http://jqueryui.com/spinner/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/spinner.css
-//>>css.theme: ../themes/base/theme.css
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/spinner.css
+//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
@@ -230,12 +230,7 @@ $.widget( "ui.spinner", {
// Add buttons
.append(
- "<a>" +
- "<span>&#9650;</span>" +
- "</a>" +
- "<a>" +
- "<span>&#9660;</span>" +
- "</a>"
+ "<a></a><a></a>"
);
},
@@ -250,17 +245,26 @@ $.widget( "ui.spinner", {
// Button bindings
this.buttons = this.uiSpinner.children( "a" )
.attr( "tabIndex", -1 )
- .button();
+ .attr( "aria-hidden", true )
+ .button( {
+ classes: {
+ "ui-button": ""
+ }
+ } );
// TODO: Right now button does not support classes this is already updated in button PR
this._removeClass( this.buttons, "ui-corner-all" );
this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
- this._addClass( this.buttons.first().find( ".ui-button-text span" ), null,
- "ui-icon " + this.options.icons.up );
- this._addClass( this.buttons.last().find( ".ui-button-text span" ), null,
- "ui-icon " + this.options.icons.down );
+ this.buttons.first().button( {
+ "icon": this.options.icons.up,
+ "showLabel": false
+ } );
+ this.buttons.last().button( {
+ "icon": this.options.icons.down,
+ "showLabel": false
+ } );
// IE 6 doesn't understand height: 50% for the buttons
// unless the wrapper has an explicit height
@@ -559,13 +563,7 @@ if ( $.uiBackCompat !== false ) {
},
_buttonHtml: function() {
- return "" +
- "<a>" +
- "<span>&#9650;</span>" +
- "</a>" +
- "<a>" +
- "<span>&#9660;</span>" +
- "</a>";
+ return "<a></a><a></a>";
}
} );
}
diff --git a/ui/widgets/tabs.js b/ui/widgets/tabs.js
index baece431d..a35386541 100644
--- a/ui/widgets/tabs.js
+++ b/ui/widgets/tabs.js
@@ -12,9 +12,9 @@
//>>description: Transforms a set of container elements into a tab structure.
//>>docs: http://api.jqueryui.com/tabs/
//>>demos: http://jqueryui.com/tabs/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/tabs.css
-//>>css.theme: ../themes/base/theme.css
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/tabs.css
+//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
diff --git a/ui/widgets/tooltip.js b/ui/widgets/tooltip.js
index daf783a98..94021092a 100644
--- a/ui/widgets/tooltip.js
+++ b/ui/widgets/tooltip.js
@@ -12,9 +12,9 @@
//>>description: Shows additional information for any element on hover or focus.
//>>docs: http://api.jqueryui.com/tooltip/
//>>demos: http://jqueryui.com/tooltip/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/tooltip.css
-//>>css.theme: ../themes/base/theme.css
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/tooltip.css
+//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
@@ -318,7 +318,8 @@ $.widget( "ui.tooltip", {
// Handle tracking tooltips that are shown with a delay (#8644). As soon
// as the tooltip is visible, position the tooltip using the most recent
// event.
- if ( this.options.show && this.options.show.delay ) {
+ // Adds the check to add the timers only when both delay and track options are set (#14682)
+ if ( this.options.track && this.options.show && this.options.show.delay ) {
delayedShow = this.delayedShow = setInterval( function() {
if ( tooltip.is( ":visible" ) ) {
position( positionOption.of );