diff --git a/AUTHORS.txt b/AUTHORS.txt index bc7c89d79..2a7a396c8 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -231,3 +231,8 @@ Pavel Selitskas Bjørn Johansen Matthieu Penant Dominic Barnes +David Sullivan +Thomas Jaggi +Vahid Sohrabloo +Travis Carden +Bruno M. Custódio diff --git a/build/tasks/build.js b/build/tasks/build.js index 75cbca4a0..a8f25f98f 100644 --- a/build/tasks/build.js +++ b/build/tasks/build.js @@ -159,7 +159,7 @@ grunt.registerMultiTask( "zip", "Create a zip file for release", function() { grunt.registerMultiTask( "md5", "Create list of md5 hashes for CDN uploads", function() { // remove dest file before creating it, to make sure itself is not included - if ( path.existsSync( this.file.dest ) ) { + if ( fs.existsSync( this.file.dest ) ) { fs.unlinkSync( this.file.dest ); } var crypto = require( "crypto" ), @@ -175,67 +175,43 @@ grunt.registerMultiTask( "md5", "Create list of md5 hashes for CDN uploads", fun }); grunt.registerTask( "generate_themes", function() { - var download, files, done, configContent, - target = "dist/" + grunt.template.process( grunt.config( "files.themes" ), grunt.config() ) + "/", + var download, done, distFolder = "dist/" + grunt.template.process( grunt.config( "files.dist" ), grunt.config() ), - configFile = "node_modules/download.jqueryui.com/config.json"; + target = "dist/" + grunt.template.process( grunt.config( "files.themes" ), grunt.config() ) + "/"; + try { require.resolve( "download.jqueryui.com" ); } catch( error ) { throw new Error( "You need to manually install download.jqueryui.com for this task to work" ); } - // copy release files into download builder to avoid cloning again - grunt.file.expandFiles( distFolder + "/**" ).forEach(function( file ) { - grunt.file.copy( file, "node_modules/download.jqueryui.com/release/" + file.replace(/^dist\/jquery-ui-/, "") ); - }); - // make it look for the right version - configContent = grunt.file.readJSON( configFile ); - configContent.jqueryUi.stable.version = grunt.config( "pkg.version" ); - grunt.file.write( configFile, JSON.stringify( configContent, null, "\t" ) + "\n" ); - - download = new ( require( "download.jqueryui.com" ) )(); - - files = grunt.file.expandFiles( distFolder + "/themes/base/**/*" ); - files.forEach(function( fileName ) { - grunt.file.copy( fileName, target + fileName.replace( distFolder, "" ) ); + download = require( "download.jqueryui.com" )({ + config: { + "jqueryUi": { + "stable": { "path": path.resolve( __dirname + "/../../" + distFolder ) } + }, + "jquery": "skip" + } }); done = this.async(); - grunt.utils.async.forEach( download.themeroller.gallery(), function( theme, done ) { - var folderName = theme.folderName(), - concatTarget = "css-" + folderName, - cssContent = theme.css(), - cssFolderName = target + "themes/" + folderName + "/", - cssFileName = cssFolderName + "jquery.ui.theme.css", - cssFiles = grunt.config.get( "concat.css.src" )[ 1 ].slice(); - - grunt.file.write( cssFileName, cssContent ); - - // get css components, replace the last file with the current theme - cssFiles.splice(-1); - cssFiles.push( "" ); - grunt.config.get( "concat" )[ concatTarget ] = { - src: [ "", cssFiles ], - dest: cssFolderName + "jquery-ui.css" - }; - grunt.task.run( "concat:" + concatTarget ); - - theme.fetchImages(function( err, files ) { - if ( err ) { - done( err ); - return; - } - files.forEach(function( file ) { - grunt.file.write( cssFolderName + "images/" + file.path, file.data ); - }); - done(); - }); - }, function( err ) { - if ( err ) { - grunt.log.error( err ); + download.buildThemesBundle(function( error, files ) { + if ( error ) { + grunt.log.error( error ); + return done( false ); } - done( !err ); + + done( + files.every(function( file ) { + try { + grunt.file.write( target + file.path, file.data ); + } catch( err ) { + grunt.log.error( err ); + return false; + } + return true; + }) && grunt.log.writeln( "Generated at " + target ) + ); }); }); diff --git a/demos/accordion/hoverintent.html b/demos/accordion/hoverintent.html index 023682d4b..0ff63a321 100644 --- a/demos/accordion/hoverintent.html +++ b/demos/accordion/hoverintent.html @@ -16,11 +16,11 @@ }); }); - var cfg = ($.hoverintent = { - sensitivity: 7, - interval: 100 - }); - + /* + * hoverIntent | Copyright 2011 Brian Cherne + * http://cherne.net/brian/resources/jquery.hoverIntent.html + * modified by the jQuery UI team + */ $.event.special.hoverintent = { setup: function() { $( this ).bind( "mouseover", jQuery.event.special.hoverintent.handler ); @@ -29,41 +29,56 @@ $( this ).unbind( "mouseover", jQuery.event.special.hoverintent.handler ); }, handler: function( event ) { - var that = this, + var currentX, currentY, timeout, args = arguments, target = $( event.target ), - cX, cY, pX, pY; + previousX = event.pageX, + previousY = event.pageY; function track( event ) { - cX = event.pageX; - cY = event.pageY; + currentX = event.pageX; + currentY = event.pageY; }; - pX = event.pageX; - pY = event.pageY; + function clear() { target .unbind( "mousemove", track ) - .unbind( "mouseout", arguments.callee ); + .unbind( "mouseout", clear ); clearTimeout( timeout ); } + function handler() { - if ( ( Math.abs( pX - cX ) + Math.abs( pY - cY ) ) < cfg.sensitivity ) { + var prop, + orig = event; + + if ( ( Math.abs( previousX - currentX ) + + Math.abs( previousY - currentY ) ) < 7 ) { clear(); - event.type = "hoverintent"; - // prevent accessing the original event since the new event + + event = $.Event( "hoverintent" ); + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + // Prevent accessing the original event since the new event // is fired asynchronously and the old event is no longer // usable (#6028) - event.originalEvent = {}; - jQuery.event.handle.apply( that, args ); + delete event.originalEvent; + + target.trigger( event ); } else { - pX = cX; - pY = cY; - timeout = setTimeout( handler, cfg.interval ); + previousX = currentX; + previousY = currentY; + timeout = setTimeout( handler, 100 ); } } - var timeout = setTimeout( handler, cfg.interval ); - target.mousemove( track ).mouseout( clear ); - return true; + + timeout = setTimeout( handler, 100 ); + target.bind({ + mousemove: track, + mouseout: clear + }); } }; diff --git a/demos/autocomplete/combobox.html b/demos/autocomplete/combobox.html index 0d59db670..f89f260eb 100644 --- a/demos/autocomplete/combobox.html +++ b/demos/autocomplete/combobox.html @@ -37,91 +37,52 @@ (function( $ ) { $.widget( "ui.combobox", { _create: function() { - var input, - that = this, - wasOpen = false, - select = this.element.hide(), - selected = select.children( ":selected" ), - value = selected.val() ? selected.text() : "", - wrapper = this.wrapper = $( "" ) - .addClass( "ui-combobox" ) - .insertAfter( select ); + this.wrapper = $( "" ) + .addClass( "ui-combobox" ) + .insertAfter( this.element ); - function removeIfInvalid( element ) { - var value = $( element ).val(), - matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( value ) + "$", "i" ), - valid = false; - select.children( "option" ).each(function() { - if ( $( this ).text().match( matcher ) ) { - this.selected = valid = true; - return false; - } - }); + this._createAutocomplete(); + this._createShowAllButton(); + }, - if ( !valid ) { - // remove invalid value, as it didn't match anything - $( element ) - .val( "" ) - .attr( "title", value + " didn't match any item" ) - .tooltip( "open" ); - select.val( "" ); - setTimeout(function() { - input.tooltip( "close" ).attr( "title", "" ); - }, 2500 ); - input.data( "ui-autocomplete" ).term = ""; - } - } + _createAutocomplete: function() { + var selected = this.element.children( ":selected" ), + value = selected.val() ? selected.text() : ""; - input = $( "" ) - .appendTo( wrapper ) + this.input = $( "" ) + .appendTo( this.wrapper ) .val( value ) .attr( "title", "" ) - .addClass( "ui-state-default ui-combobox-input" ) + .addClass( "ui-state-default ui-combobox-input ui-widget ui-widget-content ui-corner-left" ) .autocomplete({ delay: 0, minLength: 0, - source: function( request, response ) { - var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" ); - response( select.children( "option" ).map(function() { - var text = $( this ).text(); - if ( this.value && ( !request.term || matcher.test(text) ) ) - return { - label: text.replace( - new RegExp( - "(?![^&;]+;)(?!<[^<>]*)(" + - $.ui.autocomplete.escapeRegex(request.term) + - ")(?![^<>]*>)(?![^&;]+;)", "gi" - ), "$1" ), - value: text, - option: this - }; - }) ); - }, - select: function( event, ui ) { - ui.item.option.selected = true; - that._trigger( "selected", event, { - item: ui.item.option - }); - }, - change: function( event, ui ) { - if ( !ui.item ) { - removeIfInvalid( this ); - } - } + source: $.proxy( this, "_source" ) }) - .addClass( "ui-widget ui-widget-content ui-corner-left" ); + .tooltip({ + tooltipClass: "ui-state-highlight" + }); - input.data( "ui-autocomplete" )._renderItem = function( ul, item ) { - return $( "
  • " ) - .append( "" + item.label + "" ) - .appendTo( ul ); - }; + this._on( this.input, { + autocompleteselect: function( event, ui ) { + ui.item.option.selected = true; + this._trigger( "select", event, { + item: ui.item.option + }); + }, + + autocompletechange: "_removeIfInvalid" + }); + }, + + _createShowAllButton: function() { + var wasOpen = false; $( "" ) .attr( "tabIndex", -1 ) .attr( "title", "Show All Items" ) .tooltip() - .appendTo( wrapper ) + .appendTo( this.wrapper ) .button({ icons: { primary: "ui-icon-triangle-1-s" @@ -136,18 +97,62 @@ .click(function() { input.focus(); - // close if already visible + // Close if already visible if ( wasOpen ) { return; } - // pass empty string as value to search for, displaying all results + // Pass empty string as value to search for, displaying all results input.autocomplete( "search", "" ); }); + }, - input.tooltip({ - tooltipClass: "ui-state-highlight" + _source: function( request, response ) { + var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" ); + response( this.element.children( "option" ).map(function() { + var text = $( this ).text(); + if ( this.value && ( !request.term || matcher.test(text) ) ) + return { + label: text, + value: text, + option: this + }; + }) ); + }, + + _removeIfInvalid: function( event, ui ) { + + // Selected an item, nothing to do + if ( ui.item ) { + return; + } + + // Search for a match (case-insensitive) + var value = this.input.val(), + valueLowerCase = value.toLowerCase(), + valid = false; + this.element.children( "option" ).each(function() { + if ( $( this ).text().toLowerCase() === valueLowerCase ) { + this.selected = valid = true; + return false; + } }); + + // Found a match, nothing to do + if ( valid ) { + return; + } + + // Remove invalid value + this.input + .val( "" ) + .attr( "title", value + " didn't match any item" ) + .tooltip( "open" ); + this.element.val( "" ); + this._delay(function() { + this.input.tooltip( "close" ).attr( "title", "" ); + }, 2500 ); + this.input.data( "ui-autocomplete" ).term = ""; }, _destroy: function() { diff --git a/demos/sortable/portlets.html b/demos/sortable/portlets.html index 24582f502..5a3f2b662 100644 --- a/demos/sortable/portlets.html +++ b/demos/sortable/portlets.html @@ -11,6 +11,7 @@ + @@ -39,13 +45,14 @@

      -
      Relative
      Absolute
      +
      +
      diff --git a/tests/unit/draggable/draggable_options.js b/tests/unit/draggable/draggable_options.js index a3f7169f2..8496d6182 100644 --- a/tests/unit/draggable/draggable_options.js +++ b/tests/unit/draggable/draggable_options.js @@ -723,4 +723,39 @@ test("{ zIndex: 10 }", function() { }); +test( "{ stack }", function() { + expect( 4 ); + + var draggable1 = $( "#draggable1" ), + draggable2 = $( "#draggable2" ), + draggable3 = $( "#draggable3" ), + draggable4 = $( "#draggable4" ); + + // Set z-index as an inline style. + $( "#draggable1, #draggable2" ) + .css( "zIndex", 100 ) + .draggable({ + stack: "#draggable1, #draggable2" + }); + // Have z-index applied via CSS, see #9077 + $( "#draggable3, #draggable4" ) + .draggable({ + stack: "#draggable3, #draggable4" + }); + + draggable1.simulate( "drag", { + dx: 1, + dy: 1 + }); + draggable3.simulate( "drag", { + dx: 1, + dy: 1 + }); + + equal( draggable1.css( "zIndex" ), 102); + equal( draggable2.css( "zIndex" ), 101); + equal( draggable3.css( "zIndex" ), 102); + equal( draggable4.css( "zIndex" ), 101); +}); + })(jQuery); diff --git a/tests/unit/droppable/droppable.html b/tests/unit/droppable/droppable.html index 7cd5eb0f5..d084464c2 100644 --- a/tests/unit/droppable/droppable.html +++ b/tests/unit/droppable/droppable.html @@ -42,6 +42,7 @@
      Draggable
      Droppable
      +
      Droppable
       
      diff --git a/tests/unit/droppable/droppable_events.js b/tests/unit/droppable/droppable_events.js index 8f842e942..4b8fe5acd 100644 --- a/tests/unit/droppable/droppable_events.js +++ b/tests/unit/droppable/droppable_events.js @@ -1,13 +1,41 @@ -/* - * droppable_events.js - */ -(function($) { +(function( $ ) { + +module( "droppable: events" ); + +test( "droppable destruction/recreation on drop event", function() { + expect( 1 ); + + var config = { + activeClass: "active", + drop: function() { + var element = $( this ), + newDroppable = $( "
      " ) + .css({ width: 100, height: 100 }) + .text( "Droppable" ); + element.after( newDroppable ); + element.remove(); + newDroppable.droppable( config ); + } + }, + + draggable = $( "#draggable1" ).draggable(), + droppable1 = $( "#droppable1" ).droppable( config ), + droppable2 = $( "#droppable2" ).droppable( config ), + + droppableOffset = droppable1.offset(), + draggableOffset = draggable.offset(), + dx = droppableOffset.left - draggableOffset.left, + dy = droppableOffset.top - draggableOffset.top; + + draggable.simulate( "drag", { + dx: dx, + dy: dy + }); + + ok( !droppable2.hasClass( "active" ), "subsequent droppable no longer active" ); +}); -module("droppable: events"); -// this is here to make JSHint pass "unused", and we don't want to -// remove the parameter for when we finally implement -$.noop(); // todo: comment the following in when ready to actually test /* @@ -32,4 +60,4 @@ test("drop", function() { }); */ -})(jQuery); +})( jQuery ); diff --git a/tests/unit/effects/effects.html b/tests/unit/effects/effects.html index c283eabff..4538ecb03 100644 --- a/tests/unit/effects/effects.html +++ b/tests/unit/effects/effects.html @@ -96,7 +96,11 @@

        - +
        +
        +

        Child Element Test

        diff --git a/tests/unit/effects/effects_core.js b/tests/unit/effects/effects_core.js index c9b1e1b4a..11e9d0b45 100644 --- a/tests/unit/effects/effects_core.js +++ b/tests/unit/effects/effects_core.js @@ -16,6 +16,24 @@ var minDuration = 15, module( "effects.core" ); +// TODO: test all signatures of .show(), .hide(), .toggle(). +// Look at core's signatures and UI's signatures. +asyncTest( ".hide() with step", function() { + expect( 1 ); + var element = $( "#elem" ), + step = function() { + ok( true, "step callback invoked" ); + step = $.noop; + }; + + element.hide({ + step: function() { + step(); + }, + complete: start + }); +}); + test( "Immediate Return Conditions", function() { var hidden = $( "div.hidden" ), count = 0; @@ -28,6 +46,14 @@ test( "Immediate Return Conditions", function() { equal( ++count, 3, "Both Functions worked properly" ); }); +test( ".hide() with hidden parent", function() { + expect( 1 ); + var element = $( "div.hidden" ).children(); + element.hide( "blind", function() { + equal( element.css( "display" ), "none", "display: none" ); + }); +}); + asyncTest( "Parse of null for options", function() { var hidden = $( "div.hidden" ), count = 0; diff --git a/tests/unit/position/position_core.js b/tests/unit/position/position_core.js index 7b51223ac..cefd7929c 100644 --- a/tests/unit/position/position_core.js +++ b/tests/unit/position/position_core.js @@ -221,7 +221,7 @@ test( "of", function() { }); test( "offsets", function() { - expect( 4 ); + expect( 7 ); $( "#elx" ).position({ my: "left top", @@ -254,6 +254,30 @@ test( "offsets", function() { collision: "none" }); deepEqual( $( "#elx" ).offset(), { top: 65, left: 37 }, "percentage offsets in my" ); + + $( "#elx" ).position({ + my: "left-30.001% top+50.0%", + at: "left bottom", + of: "#parentx", + collision: "none" + }); + deepEqual( $( "#elx" ).offset(), { top: 65, left: 37 }, "decimal percentage offsets in my" ); + + $( "#elx" ).position({ + my: "left+10.4 top-10.6", + at: "left bottom", + of: "#parentx", + collision: "none" + }); + deepEqual( $( "#elx" ).offset(), { top: 49, left: 50 }, "decimal offsets in my" ); + + $( "#elx" ).position({ + my: "left+right top-left", + at: "left-top bottom-bottom", + of: "#parentx", + collision: "none" + }); + deepEqual( $( "#elx" ).offset(), { top: 60, left: 40 }, "invalid offsets" ); }); test( "using", function() { diff --git a/tests/unit/slider/slider_options.js b/tests/unit/slider/slider_options.js index dfa94696a..f46dbde99 100644 --- a/tests/unit/slider/slider_options.js +++ b/tests/unit/slider/slider_options.js @@ -16,7 +16,7 @@ test( "disabled", function(){ var count = 0; element = $( "#slider1" ).slider(); - element.on( "slidestart", function() { + element.bind( "slidestart", function() { count++; }); @@ -180,13 +180,13 @@ test( "values", function() { document.createElement( "div" ), document.createElement( "div" ) ]).slider({ - range: true, + range: true, values: [ 25, 75 ] }); notStrictEqual( - ranges.eq( 0 ).data( "uiSlider" ).options.values, - ranges.eq( 1 ).data( "uiSlider" ).options.values, + ranges.eq( 0 ).data( "ui-slider" ).options.values, + ranges.eq( 1 ).data( "ui-slider" ).options.values, "multiple range sliders should not have a reference to the same options.values array" ); diff --git a/tests/unit/sortable/sortable.html b/tests/unit/sortable/sortable.html index c23a15854..6e326a865 100644 --- a/tests/unit/sortable/sortable.html +++ b/tests/unit/sortable/sortable.html @@ -63,6 +63,27 @@
      1. Item 5
      2. + + + + + + + + + + + + + + + + + + + +
        12
        34
        56
        78
        + diff --git a/tests/unit/sortable/sortable_options.js b/tests/unit/sortable/sortable_options.js index cf35aedb1..fe50be002 100644 --- a/tests/unit/sortable/sortable_options.js +++ b/tests/unit/sortable/sortable_options.js @@ -185,11 +185,41 @@ test("{ opacity: 1 }", function() { test("{ placeholder: false }, default", function() { ok(false, "missing test - untested code is broken code."); }); +*/ +test( "{ placeholder: String }", function() { + expect( 1 ); -test("{ placeholder: String }", function() { - ok(false, "missing test - untested code is broken code."); + var element = $( "#sortable" ).sortable({ + placeholder: "test", + start: function( event, ui ) { + ok( ui.placeholder.hasClass( "test" ), "placeholder has class" ); + } + }); + + element.find( "li" ).eq( 0 ).simulate( "drag", { + dy: 1 + }); }); +test( "{ placholder: String } tr", function() { + expect( 3 ); + + var element = $( "#sortable-table tbody" ).sortable({ + placeholder: "test", + start: function( event, ui ) { + ok( ui.placeholder.hasClass( "test" ), "placeholder has class" ); + equal( ui.placeholder.children().length, 1, "placeholder tr contains a td" ); + equal( ui.placeholder.children().html(), $( " " ).html(), + "placeholder td has content for forced dimensions" ); + } + }); + + element.find( "tr" ).eq( 0 ).simulate( "drag", { + dy: 1 + }); +}); + +/* test("{ revert: false }, default", function() { ok(false, "missing test - untested code is broken code."); }); diff --git a/tests/unit/spinner/spinner_core.js b/tests/unit/spinner/spinner_core.js index a1179bb35..bea5f9122 100644 --- a/tests/unit/spinner/spinner_core.js +++ b/tests/unit/spinner/spinner_core.js @@ -80,6 +80,33 @@ test( "keydown PAGE_DOWN on input, decreases value not less than min", function( equal( element.val(), 20 ); }); +asyncTest( "blur input while spinning with UP", function() { + expect( 3 ); + var value, + element = $( "#spin" ).val( 10 ).spinner(); + + function step1() { + element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); + equal( element.val(), 11 ); + setTimeout( step2, 750 ); + } + + function step2() { + value = element.val(); + ok( value > 11, "repeating while key is down" ); + element[0].blur(); + setTimeout( step3, 250 ); + } + + function step3() { + equal( element.val(), value, "stopped repeating on blur" ); + start(); + } + + element[ 0 ].focus(); + setTimeout( step1 ); +}); + test( "mouse click on up button, increases value not greater than max", function() { expect( 3 ); var element = $( "#spin" ).val( 18 ).spinner({ diff --git a/themes/base/jquery.ui.core.css b/themes/base/jquery.ui.core.css index dc1216f70..c644bb30f 100644 --- a/themes/base/jquery.ui.core.css +++ b/themes/base/jquery.ui.core.css @@ -38,6 +38,7 @@ .ui-helper-clearfix:after { content: ""; display: table; + border-collapse: collapse; } .ui-helper-clearfix:after { clear: both; diff --git a/themes/base/jquery.ui.tabs.css b/themes/base/jquery.ui.tabs.css index 6c35e193e..b8f77b040 100644 --- a/themes/base/jquery.ui.tabs.css +++ b/themes/base/jquery.ui.tabs.css @@ -22,7 +22,7 @@ position: relative; top: 0; margin: 1px .2em 0 0; - border-bottom: 0; + border-bottom-width: 0; padding: 0; white-space: nowrap; } diff --git a/ui/i18n/jquery.ui.datepicker-de.js b/ui/i18n/jquery.ui.datepicker-de.js index cfe91759b..abe75c4e4 100644 --- a/ui/i18n/jquery.ui.datepicker-de.js +++ b/ui/i18n/jquery.ui.datepicker-de.js @@ -2,10 +2,10 @@ /* Written by Milian Wolff (mail@milianw.de). */ jQuery(function($){ $.datepicker.regional['de'] = { - closeText: 'schließen', - prevText: '<zurück', + closeText: 'Schließen', + prevText: '<Zurück', nextText: 'Vor>', - currentText: 'heute', + currentText: 'Heute', monthNames: ['Januar','Februar','März','April','Mai','Juni', 'Juli','August','September','Oktober','November','Dezember'], monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun', diff --git a/ui/i18n/jquery.ui.datepicker-sk.js b/ui/i18n/jquery.ui.datepicker-sk.js index 83ae8e811..0cb76c4e8 100644 --- a/ui/i18n/jquery.ui.datepicker-sk.js +++ b/ui/i18n/jquery.ui.datepicker-sk.js @@ -6,11 +6,11 @@ jQuery(function($){ prevText: '<Predchádzajúci', nextText: 'Nasledujúci>', currentText: 'Dnes', - monthNames: ['Január','Február','Marec','Apríl','Máj','Jún', - 'Júl','August','September','Október','November','December'], + monthNames: ['január','február','marec','apríl','máj','jún', + 'júl','august','september','október','november','december'], monthNamesShort: ['Jan','Feb','Mar','Apr','Máj','Jún', 'Júl','Aug','Sep','Okt','Nov','Dec'], - dayNames: ['Nedeľa','Pondelok','Utorok','Streda','Štvrtok','Piatok','Sobota'], + dayNames: ['nedeľa','pondelok','utorok','streda','štvrtok','piatok','sobota'], dayNamesShort: ['Ned','Pon','Uto','Str','Štv','Pia','Sob'], dayNamesMin: ['Ne','Po','Ut','St','Št','Pia','So'], weekHeader: 'Ty', diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js index 1b0f2138f..b3a05da0b 100644 --- a/ui/jquery.ui.autocomplete.js +++ b/ui/jquery.ui.autocomplete.js @@ -234,7 +234,8 @@ $.widget( "ui.autocomplete", { } }, menufocus: function( event, ui ) { - // #7024 - Prevent accidental activation of menu items in Firefox + // support: Firefox + // Prevent accidental activation of menu items in Firefox (#7024 #9118) if ( this.isNewMenu ) { this.isNewMenu = false; if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { @@ -490,6 +491,7 @@ $.widget( "ui.autocomplete", { _suggest: function( items ) { var ul = this.menu.element.empty(); this._renderMenu( ul, items ); + this.isNewMenu = true; this.menu.refresh(); // size and position menu diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js index 85dbddda2..b35c0ffcf 100644 --- a/ui/jquery.ui.dialog.js +++ b/ui/jquery.ui.dialog.js @@ -692,11 +692,23 @@ $.widget( "ui.dialog", { } }, + _allowInteraction: function( event ) { + if ( $( event.target ).closest(".ui-dialog").length ) { + return true; + } + + // TODO: Remove hack when datepicker implements + // the .ui-front logic (#8989) + return !!$( event.target ).closest(".ui-datepicker").length; + }, + _createOverlay: function() { if ( !this.options.modal ) { return; } + var that = this, + widgetFullName = this.widgetFullName; if ( !$.ui.dialog.overlayInstances ) { // Prevent use of anchors and inputs. // We use a delay in case the overlay is created from an @@ -705,13 +717,10 @@ $.widget( "ui.dialog", { // Handle .dialog().dialog("close") (#4065) if ( $.ui.dialog.overlayInstances ) { this.document.bind( "focusin.dialog", function( event ) { - if ( !$( event.target ).closest(".ui-dialog").length && - // TODO: Remove hack when datepicker implements - // the .ui-front logic (#8989) - !$( event.target ).closest(".ui-datepicker").length ) { + if ( !that._allowInteraction( event ) ) { event.preventDefault(); $(".ui-dialog:visible:last .ui-dialog-content") - .data("ui-dialog")._focusTabbable(); + .data( widgetFullName )._focusTabbable(); } }); } diff --git a/ui/jquery.ui.draggable.js b/ui/jquery.ui.draggable.js index 9a31add7c..27b6b4ef0 100644 --- a/ui/jquery.ui.draggable.js +++ b/ui/jquery.ui.draggable.js @@ -600,7 +600,7 @@ $.ui.plugin.add("draggable", "connectToSortable", { //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" if(this.shouldRevert) { - this.instance.options.revert = true; + this.instance.options.revert = this.shouldRevert; } //Trigger the stop of the sortable @@ -908,22 +908,19 @@ $.ui.plugin.add("draggable", "snap", { $.ui.plugin.add("draggable", "stack", { start: function() { - var min, - o = $(this).data("ui-draggable").options, + o = this.data("ui-draggable").options, group = $.makeArray($(o.stack)).sort(function(a,b) { return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); }); if (!group.length) { return; } - min = parseInt(group[0].style.zIndex, 10) || 0; + min = parseInt($(group[0]).css("zIndex"), 10) || 0; $(group).each(function(i) { - this.style.zIndex = min + i; + $(this).css("zIndex", min + i); }); - - this[0].style.zIndex = min + group.length; - + this.css("zIndex", (min + group.length)); } }); diff --git a/ui/jquery.ui.droppable.js b/ui/jquery.ui.droppable.js index 4fbfcde06..552b24a58 100644 --- a/ui/jquery.ui.droppable.js +++ b/ui/jquery.ui.droppable.js @@ -278,7 +278,8 @@ $.ui.ddmanager = { drop: function(draggable, event) { var dropped = false; - $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { + // Create a copy of the droppables in case the list changes during the drop (#9116) + $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() { if(!this.options) { return; diff --git a/ui/jquery.ui.effect.js b/ui/jquery.ui.effect.js index 97f006ee0..f3d9929b0 100644 --- a/ui/jquery.ui.effect.js +++ b/ui/jquery.ui.effect.js @@ -1106,14 +1106,29 @@ function _normalizeArguments( effect, options, speed, callback ) { return effect; } -function standardSpeed( speed ) { - // valid standard speeds - if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { +function standardAnimationOption( option ) { + // Valid standard speeds (nothing, number, named speed) + if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { return true; } - // invalid strings - treat as "normal" speed - return typeof speed === "string" && !$.effects.effect[ speed ]; + // Invalid strings - treat as "normal" speed + if ( typeof option === "string" && !$.effects.effect[ option ] ) { + return true; + } + + // Complete callback + if ( $.isFunction( option ) ) { + return true; + } + + // Options hash (but not naming an effect) + if ( typeof option === "object" && !option.effect ) { + return true; + } + + // Didn't match any standard API + return false; } $.fn.extend({ @@ -1150,9 +1165,10 @@ $.fn.extend({ } } - // if the element is hiddden and mode is hide, - // or element is visible and mode is show + // If the element already has the correct final state, delegate to + // the core methods so the internal tracking of "olddisplay" works. if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { + elem[ mode ](); done(); } else { effectMethod.call( elem[0], args, done ); @@ -1162,39 +1178,41 @@ $.fn.extend({ return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); }, - _show: $.fn.show, - show: function( speed ) { - if ( standardSpeed( speed ) ) { - return this._show.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "show"; - return this.effect.call( this, args ); - } - }, + show: (function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "show"; + return this.effect.call( this, args ); + } + }; + })( $.fn.show ), - _hide: $.fn.hide, - hide: function( speed ) { - if ( standardSpeed( speed ) ) { - return this._hide.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "hide"; - return this.effect.call( this, args ); - } - }, + hide: (function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "hide"; + return this.effect.call( this, args ); + } + }; + })( $.fn.hide ), - // jQuery core overloads toggle and creates _toggle - __toggle: $.fn.toggle, - toggle: function( speed ) { - if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) { - return this.__toggle.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "toggle"; - return this.effect.call( this, args ); - } - }, + toggle: (function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) || typeof option === "boolean" ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "toggle"; + return this.effect.call( this, args ); + } + }; + })( $.fn.toggle ), // helper functions cssUnit: function(key) { diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 0209b442c..2d3451c06 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -18,15 +18,15 @@ var cachedScrollbarWidth, round = Math.round, rhorizontal = /left|center|right/, rvertical = /top|center|bottom/, - roffset = /[\+\-]\d+%?/, + roffset = /[\+\-]\d+(\.[\d]+)?%?/, rposition = /^\w+/, rpercent = /%$/, _position = $.fn.position; function getOffsets( offsets, width, height ) { return [ - parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), - parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) + parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), + parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) ]; } @@ -95,8 +95,8 @@ $.position = { hasOverflowY = overflowY === "scroll" || ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); return { - width: hasOverflowX ? $.position.scrollbarWidth() : 0, - height: hasOverflowY ? $.position.scrollbarWidth() : 0 + width: hasOverflowY ? $.position.scrollbarWidth() : 0, + height: hasOverflowX ? $.position.scrollbarWidth() : 0 }; }, getWithinInfo: function( element ) { diff --git a/ui/jquery.ui.sortable.js b/ui/jquery.ui.sortable.js index 211ff272e..f095ce9c5 100644 --- a/ui/jquery.ui.sortable.js +++ b/ui/jquery.ui.sortable.js @@ -158,7 +158,7 @@ $.widget("ui.sortable", $.ui.mouse, { _mouseStart: function(event, overrideHandle, noActivation) { - var i, + var i, body, o = this.options; this.currentContainer = this; @@ -228,11 +228,14 @@ $.widget("ui.sortable", $.ui.mouse, { this._setContainment(); } - if(o.cursor) { // cursor option - if ($("body").css("cursor")) { - this._storedCursor = $("body").css("cursor"); - } - $("body").css("cursor", o.cursor); + if( o.cursor && o.cursor !== "auto" ) { // cursor option + body = this.document.find( "body" ); + + // support: IE + this.storedCursor = body.css( "cursor" ); + body.css( "cursor", o.cursor ); + + this.storedStylesheet = $( "" ).appendTo( body ); } if(o.opacity) { // opacity option @@ -749,15 +752,23 @@ $.widget("ui.sortable", $.ui.mouse, { o.placeholder = { element: function() { - var el = $(document.createElement(that.currentItem[0].nodeName)) - .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") - .removeClass("ui-sortable-helper")[0]; + var nodeName = that.currentItem[0].nodeName.toLowerCase(), + element = $( that.document[0].createElement( nodeName ) ) + .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") + .removeClass("ui-sortable-helper"); - if(!className) { - el.style.visibility = "hidden"; + if ( nodeName === "tr" ) { + // Use a high colspan to force the td to expand the full + // width of the table (browsers are smart enough to + // handle this properly) + element.append( " " ); } - return el; + if ( !className ) { + element.css( "visibility", "hidden" ); + } + + return element; }, update: function(container, p) { @@ -1178,8 +1189,9 @@ $.widget("ui.sortable", $.ui.mouse, { } //Do what was originally in plugins - if(this._storedCursor) { - $("body").css("cursor", this._storedCursor); + if ( this.storedCursor ) { + this.document.find( "body" ).css( "cursor", this.storedCursor ); + this.storedStylesheet.remove(); } if(this._storedOpacity) { this.helper.css("opacity", this._storedOpacity); diff --git a/ui/jquery.ui.spinner.js b/ui/jquery.ui.spinner.js index c14ef9370..644b65239 100644 --- a/ui/jquery.ui.spinner.js +++ b/ui/jquery.ui.spinner.js @@ -102,6 +102,7 @@ $.widget( "ui.spinner", { return; } + this._stop(); this._refresh(); if ( this.previous !== this.element.val() ) { this._trigger( "change", event );