diff --git a/Gruntfile.js b/Gruntfile.js index 8c0a940bc..c6fcd3095 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -173,34 +173,19 @@ grunt.initConfig({ files: expandFiles( "tests/unit/**/*.html" ).filter(function( file ) { // disabling everything that doesn't (quite) work with PhantomJS for now // TODO except for all|index|test, try to include more as we go - return !( /(all|index|test|dialog|tooltip)\.html$/ ).test( file ); + return !( /(all|index|test|dialog|tooltip|draggable)\.html$/ ).test( file ); }) }, jshint: { - ui: { - options: { - jshintrc: "ui/.jshintrc" - }, - files: { - src: "ui/*.js" - } + options: { + jshintrc: true }, - grunt: { - options: { - jshintrc: ".jshintrc" - }, - files: { - src: [ "Gruntfile.js", "build/**/*.js" ] - } - }, - tests: { - options: { - jshintrc: "tests/.jshintrc" - }, - files: { - src: "tests/unit/**/*.js" - } - } + all: [ + "ui/*.js", + "Gruntfile.js", + "build/**/*.js", + "tests/unit/**/*.js" + ] }, csslint: { base_theme: { diff --git a/README.md b/README.md index d02a93936..9731e95d3 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -[jQuery UI](http://jqueryui.com/) - Interactions and Widgets for the web -================================ +# [jQuery UI](http://jqueryui.com/) - Interactions and Widgets for the web jQuery UI is a curated set of user interface interactions, effects, widgets, and themes built on top of jQuery. Whether you're building highly interactive web applications, or you just need to add a date picker to a form control, jQuery UI is the perfect choice. If you want to use jQuery UI, go to [jqueryui.com](http://jqueryui.com) to get started, [jqueryui.com/demos/](http://jqueryui.com/demos/) for demos, [api.jqueryui.com](http://api.jqueryui.com/) for API documentation, or the [Using jQuery UI Forum](http://forum.jquery.com/using-jquery-ui) for discussions and questions. +If you want to report a bug/issue, please visit [bugs.jqueryui.com](http://bugs.jqueryui.com). + If you are interested in helping develop jQuery UI, you are in the right place. To discuss development with team members and the community, visit the [Developing jQuery UI Forum](http://forum.jquery.com/developing-jquery-ui) or [#jqueryui-dev on irc.freenode.net](http://irc.jquery.org/). -For contributors ---- +## For contributors If you want to help and provide a patch for a bugfix or new feature, please take a few minutes and look at [our Getting Involved guide](http://wiki.jqueryui.com/w/page/35263114/Getting-Involved). @@ -22,8 +22,7 @@ pull request for that branch. Don't mix unrelated changes. You can use the commi message as the description for the pull request. -Running the Unit Tests ---- +## Running the Unit Tests Run the unit tests with a local server that supports PHP. No database is required. Pre-configured php local servers are available for Windows and Mac. Here are some options: @@ -33,8 +32,7 @@ Run the unit tests with a local server that supports PHP. No database is require - [Mongoose (most platforms)](http://code.google.com/p/mongoose/) -Building jQuery UI ---- +## Building jQuery UI jQuery UI uses the [Grunt](http://github.com/gruntjs/grunt) build system. @@ -61,8 +59,7 @@ grunt --help ``` -For committers ---- +## For committers When looking at pull requests, first check for [proper commit messages](http://wiki.jqueryui.com/w/page/12137724/Bug-Fixing-Guide). diff --git a/build/widget.json b/build/widget.json index 6adddb121..4a0f128a3 100644 --- a/build/widget.json +++ b/build/widget.json @@ -21,7 +21,7 @@ }, "button": { "dependencies": [], - "description": "Enhances a form with themable buttons.", + "description": "Enhances a form with themeable buttons.", "keywords": [ "form", "radio", diff --git a/demos/autocomplete/categories.html b/demos/autocomplete/categories.html index 6601ebc1c..e3c59ba13 100644 --- a/demos/autocomplete/categories.html +++ b/demos/autocomplete/categories.html @@ -21,6 +21,10 @@ @@ -46,10 +76,14 @@

    -
    -
    Relative
    -
    Absolute
    -
    Absolute
    +
    +
    +
    Relative
    +
    Absolute
    +
    Absolute
    +
    +
    +
    diff --git a/tests/unit/draggable/draggable_options.js b/tests/unit/draggable/draggable_options.js index 8a7a28735..ea52eb299 100644 --- a/tests/unit/draggable/draggable_options.js +++ b/tests/unit/draggable/draggable_options.js @@ -158,7 +158,7 @@ test( "axis, default, switching after initialization", function() { test( "{ cancel: 'input,textarea,button,select,option' }, default", function() { expect( 2 ); - $( "
    " ).appendTo( "#main" ); + $( "
    " ).appendTo( "#qunit-fixture" ); var element = $( "#draggable-option-cancel-default" ).draggable({ cancel: "input,textarea,button,select,option" }); TestHelpers.draggable.shouldMove( element, "cancel: default, element dragged" ); @@ -230,7 +230,7 @@ test( "{ cancel: Selectors }, matching parent selector", function() { test( "cancelement, default, switching after initialization", function() { expect( 2 ); - $( "
    " ).appendTo( "#main" ); + $( "
    " ).appendTo( "#qunit-fixture" ); var input = $( "#draggable-option-cancel-default input" ), element = $( "#draggable-option-cancel-default" ).draggable(); @@ -346,7 +346,7 @@ test( "{ containment: 'parent' }, absolute", function() { test( "containment, account for border", function() { expect( 2 ); - var el = $("#draggable1").appendTo("#main"), + var el = $( "#draggable1" ).appendTo( "#scrollParent" ), parent = el.parent().css({ height: "100px", width: "100px", @@ -368,9 +368,9 @@ test( "containment, account for border", function() { dy: 100 }); - equal( el.offset().top, parentBottom - parentBorderBottom - el.height(), + closeEnough( el.offset().top, parentBottom - parentBorderBottom - el.height(), 1, "The draggable should be on top of its parent's bottom border" ); - equal( el.offset().left, parentRight - parentBorderRight - el.width(), + closeEnough( el.offset().left, parentRight - parentBorderRight - el.width(), 1, "The draggable should be to the right of its parent's right border" ); }); @@ -381,13 +381,7 @@ test( "containment, default, switching after initialization", function() { TestHelpers.draggable.testDrag( element, element, -100, -100, -100, -100, "containment: default" ); - element.draggable( "option", "containment", "parent" ) - .css({ - top: 0, - left: 0 - }) - .appendTo( $( "#main" ) ); - + element.draggable( "option", "containment", "parent" ).css({ top: 0, left: 0 }); TestHelpers.draggable.testDrag( element, element, -100, -100, 0, 0, "containment: parent as option" ); element.draggable( "option", "containment", false ); @@ -666,332 +660,66 @@ test( "helper, default, switching after initialization", function() { TestHelpers.draggable.shouldMove( element, "helper: default" ); element.draggable( "option", "helper", "clone" ); - TestHelpers.draggable.shouldMovePositionButNotOffset( element, "helper: clone" ); + TestHelpers.draggable.shouldMove( element, "helper: clone" ); element.draggable( "option", "helper", "original" ); TestHelpers.draggable.shouldMove( element, "helper: original" ); }); -test( "{ helper: 'clone' }, relative", function() { - expect( 2 ); +/* jshint loopfunc: true */ +(function(){ + var k, l, m, + scrollElements = { + "no elements": [], + "parent": [ "#main" ], + "root": [ document ], + "parent and root": [ "#main", document ], + "grandparent": [ "#scrollParent" ] + }, + positions = [ "absolute", "fixed", "relative", "static" ], + helpers = [ "original", "clone" ], + scrollPositions = [ "relative", "static", "absolute", "fixed" ]; - var element = $( "#draggable1" ).draggable({ helper: "clone" }); - TestHelpers.draggable.shouldMovePositionButNotOffset( element, "helper: clone relative" ); -}); + for ( m = 0 ; m < helpers.length; m++ ) { + for ( l = 0; l < positions.length; l++ ) { + for ( k in scrollElements ) { + (function( position, helper, scrollElements, scrollElementsTitle ){ + test( "{ helper: '" + helper + "' }, " + position + ", with scroll offset on " + scrollElementsTitle, function() { + expect( 8 ); + var i, j, + element = $( "#draggable1" ).css({ position: position, top: 0, left: 0 }).draggable({ + helper: helper, + scroll: false + }); -test( "{ helper: 'clone' }, absolute", function() { - expect( 2 ); + if ( scrollElements.length === 1 && scrollElements[ 1 ] === "#scrollParent" ) { + TestHelpers.draggable.setScrollable( "#main", false ); + TestHelpers.draggable.setScrollable( "#scrollParent", true ); + } - var element = $( "#draggable2" ).draggable({ helper: "clone" }); - TestHelpers.draggable.shouldMovePositionButNotOffset( element, "helper: clone absolute" ); -}); + for ( j = 0; j < scrollPositions.length; j++ ) { + for ( i = 0; i < scrollElements.length; i++ ) { + TestHelpers.draggable.setScroll( scrollElements[ i ] ); + } -test( "{ helper: 'original' }, relative, with scroll offset on parent", function() { - expect( 6 ); + TestHelpers.draggable.testScroll( element, scrollPositions[ j ] ); - var element = $( "#draggable1" ).draggable({ helper: "original" }); + for ( i = 0; i < scrollElements.length; i++ ) { + TestHelpers.draggable.restoreScroll( scrollElements[ i ] ); + } + } - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.testScroll( element, "relative" ); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.testScroll( element, "static" ); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.testScroll( element, "absolute" ); - - TestHelpers.draggable.restoreScroll( "#main" ); -}); - -test( "{ helper: 'original' }, relative, with scroll offset on root", function() { - expect( 6 ); - - var element = $( "#draggable1" ).draggable({ helper: "original" }); - - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "relative" ); - - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "static" ); - - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "absolute" ); - - TestHelpers.draggable.restoreScroll( document ); -}); - -test( "{ helper: 'original' }, relative, with scroll offset on root and parent", function() { - expect( 6 ); - - var element = $( "#draggable1" ).draggable({ helper: "original" }); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "relative" ); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "static" ); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "absolute" ); - - TestHelpers.draggable.restoreScroll( "#main" ); - TestHelpers.draggable.restoreScroll( document ); -}); - -test( "{ helper: 'original' }, absolute, with scroll offset on parent", function() { - expect( 6 ); - - var element = $( "#draggable1" ).css({ position: "absolute", top: 0, left: 0 }).draggable({ helper: "original" }); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.testScroll( element, "relative" ); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.testScroll( element, "static" ); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.testScroll( element, "absolute" ); - - TestHelpers.draggable.restoreScroll( "#main" ); -}); - -test( "{ helper: 'original' }, absolute, with scroll offset on root", function() { - expect( 6 ); - - var element = $( "#draggable1" ).css({ position: "absolute", top: 0, left: 0 }).draggable({ helper: "original" }); - - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "relative" ); - - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "static" ); - - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "absolute" ); - - TestHelpers.draggable.restoreScroll( document ); -}); - -test( "{ helper: 'original' }, absolute, with scroll offset on root and parent", function() { - expect( 6 ); - - var element = $( "#draggable1" ).css({ position: "absolute", top: 0, left: 0 }).draggable({ helper: "original" }); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "relative" ); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "static" ); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "absolute" ); - - TestHelpers.draggable.restoreScroll( "#main" ); - TestHelpers.draggable.restoreScroll( document ); -}); - -test( "{ helper: 'original' }, fixed, with scroll offset on parent", function() { - expect( 4 ); - - var element = $( "#draggable1" ).css({ position: "fixed", top: 0, left: 0 }).draggable({ helper: "original" }); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.testScroll( element, "relative" ); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.testScroll( element, "static" ); - - TestHelpers.draggable.setScroll( "#main" ); - // TODO: investigate these failure in PhantomJS - //TestHelpers.draggable.testScroll( element, "absolute" ); - - TestHelpers.draggable.restoreScroll( "#main" ); -}); - -test( "{ helper: 'original' }, fixed, with scroll offset on root", function() { - expect( 4 ); - - var element = $( "#draggable1" ).css({ position: "fixed", top: 0, left: 0 }).draggable({ helper: "original" }); - - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "relative" ); - - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "static" ); - - TestHelpers.draggable.setScroll( document ); - // TODO: investigate these failure in PhantomJS - //TestHelpers.draggable.testScroll( element, "absolute" ); - - TestHelpers.draggable.restoreScroll( document ); -}); - -test( "{ helper: 'original' }, fixed, with scroll offset on root and parent", function() { - expect( 4 ); - - var element = $( "#draggable1" ).css({ position: "fixed", top: 0, left: 0 }).draggable({ helper: "original" }); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "relative" ); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.testScroll( element, "static" ); - - TestHelpers.draggable.setScroll( "#main" ); - TestHelpers.draggable.setScroll( document ); - // TODO: investigate these failure in PhantomJS - //TestHelpers.draggable.testScroll( element, "absolute" ); - - TestHelpers.draggable.restoreScroll( "#main" ); - TestHelpers.draggable.restoreScroll( document ); -}); - -test( "{ helper: 'clone' }, absolute", function() { - expect( 1 ); - - var helperOffset = null, - origOffset = $( "#draggable1" ).offset(), - element = $( "#draggable1" ).draggable({ helper: "clone", drag: function( event, ui) { - helperOffset = ui.helper.offset(); - } }); - - element.simulate( "drag", { - dx: 1, - dy: 1 - }); - deepEqual({ top: helperOffset.top - 1, left: helperOffset.left - 1 }, origOffset, "dragged[1, 1]" ); -}); - -test( "{ helper: 'clone' }, absolute with scroll offset on parent", function() { - expect( 3 ); - - TestHelpers.draggable.setScroll( "#main" ); - var helperOffset = null, - origOffset = null, - element = $( "#draggable1" ).draggable({ - helper: "clone", - drag: function( event, ui) { - helperOffset = ui.helper.offset(); + if ( scrollElements.length === 1 && scrollElements[ 1 ] === "#scrollParent" ) { + TestHelpers.draggable.setScrollable( "#main", true ); + TestHelpers.draggable.setScrollable( "#scrollParent", false ); + } + }); + })( positions[ l ], helpers[ m ], scrollElements[ k ], k ); } - }); - - $( "#main" ).css( "position", "relative" ); - origOffset = $( "#draggable1" ).offset(); - element.simulate( "drag", { - dx: 1, - dy: 1 - }); - deepEqual({ top: helperOffset.top - 1, left: helperOffset.left - 1 }, origOffset, "dragged[1, 1]" ); - - $( "#main" ).css( "position", "static" ); - origOffset = $( "#draggable1" ).offset(); - element.simulate( "drag", { - dx: 1, - dy: 1 - }); - deepEqual({ top: helperOffset.top - 1, left: helperOffset.left - 1 }, origOffset, "dragged[1, 1]" ); - - $( "#main" ).css( "position", "absolute" ); - origOffset = $( "#draggable1" ).offset(); - element.simulate( "drag", { - dx: 1, - dy: 1 - }); - deepEqual({ top: helperOffset.top - 1, left: helperOffset.left - 1 }, origOffset, "dragged[1, 1]" ); - - TestHelpers.draggable.restoreScroll( "#main" ); -}); - -test( "{ helper: 'clone' }, absolute with scroll offset on root", function() { - expect( 3 ); - - TestHelpers.draggable.setScroll( document ); - var helperOffset = null, - origOffset = null, - element = $( "#draggable1" ).draggable({ - helper: "clone", - drag: function( event, ui) { - helperOffset = ui.helper.offset(); - } - }); - - $( "#main" ).css( "position", "relative" ); - origOffset = $( "#draggable1" ).offset(); - element.simulate( "drag", { - dx: 1, - dy: 1 - }); - deepEqual({ top: helperOffset.top - 1, left: helperOffset.left - 1 }, origOffset, "dragged[1, 1]" ); - - $( "#main" ).css( "position", "static" ); - origOffset = $( "#draggable1" ).offset(); - element.simulate( "drag", { - dx: 1, - dy: 1 - }); - deepEqual({ top: helperOffset.top - 1, left: helperOffset.left - 1 }, origOffset, "dragged[1, 1]" ); - - $( "#main" ).css( "position", "absolute" ); - origOffset = $( "#draggable1" ).offset(); - element.simulate( "drag", { - dx: 1, - dy: 1 - }); - deepEqual({ top: helperOffset.top - 1, left: helperOffset.left - 1 }, origOffset, "dragged[1, 1]" ); - - TestHelpers.draggable.restoreScroll( document ); -}); - -test( "{ helper: 'clone' }, absolute with scroll offset on root and parent", function() { - expect( 3 ); - - TestHelpers.draggable.setScroll( document ); - TestHelpers.draggable.setScroll( "#main" ); - - var helperOffset = null, - origOffset = null, - element = $( "#draggable1" ).draggable({ - helper: "clone", - drag: function( event, ui) { - helperOffset = ui.helper.offset(); - } - }); - - $( "#main" ).css( "position", "relative" ); - origOffset = $( "#draggable1" ).offset(); - element.simulate( "drag", { - dx: 1, - dy: 1 - }); - deepEqual({ top: helperOffset.top - 1, left: helperOffset.left - 1 }, origOffset, "dragged[1, 1]" ); - - $( "#main" ).css( "position", "static" ); - origOffset = $( "#draggable1" ).offset(); - element.simulate( "drag", { - dx: 1, - dy: 1 - }); - deepEqual({ top: helperOffset.top - 1, left: helperOffset.left - 1 }, origOffset, "dragged[1, 1]" ); - - $( "#main" ).css( "position", "absolute" ); - origOffset = $( "#draggable1" ).offset(); - element.simulate( "drag", { - dx: 1, - dy: 1 - }); - deepEqual({ top: helperOffset.top - 1, left: helperOffset.left - 1 }, origOffset, "dragged[1, 1]" ); - - TestHelpers.draggable.restoreScroll( document ); - TestHelpers.draggable.restoreScroll( "#main" ); -}); + } + } +})(); +/* jshint loopfunc: false */ test( "{ opacity: 0.5 }", function() { expect( 1 ); @@ -1098,8 +826,10 @@ test( "scope", function() { test( "scroll, scrollSensitivity, and scrollSpeed", function() { expect( 2 ); + TestHelpers.draggable.setScrollable( "#main", false ); + var viewportHeight = $( window ).height(), - element = $( "#draggable1" ).draggable({ scroll: true }), + element = $( "#draggable1" ).draggable({ scroll: true }).appendTo( "#qunit-fixture" ), scrollSensitivity = element.draggable( "option", "scrollSensitivity" ), scrollSpeed = element.draggable( "option", "scrollSpeed" ); diff --git a/tests/unit/draggable/draggable_test_helpers.js b/tests/unit/draggable/draggable_test_helpers.js index 2edf7452f..0b533a4e1 100644 --- a/tests/unit/draggable/draggable_test_helpers.js +++ b/tests/unit/draggable/draggable_test_helpers.js @@ -20,8 +20,8 @@ TestHelpers.draggable = { var offsetBefore = el.offset(), offsetExpected = { left: offsetBefore.left + expectedDX, top: offsetBefore.top + expectedDY }; - $( el ).one( "dragstop", function() { - deepEqual( el.offset(), offsetExpected, "offset dragged[" + dx + ", " + dy + "] " + msg ); + $( el ).one( "dragstop", function( event, ui ) { + deepEqual( ui.helper.offset(), offsetExpected, "offset dragged[" + dx + ", " + dy + "] " + msg ); } ); }, testDrag: function( el, handle, dx, dy, expectedDX, expectedDY, msg ) { @@ -30,10 +30,7 @@ TestHelpers.draggable = { $( handle ).simulate( "drag", { dx: dx, - dy: dy, - // moves is 1 here because simulate currently fire events synchronously - // so we can't faithfully test things that rely on a scroll event (which is async) - moves: 1 + dy: dy }); }, shouldMovePositionButNotOffset: function( el, msg, handle ) { @@ -43,10 +40,7 @@ TestHelpers.draggable = { $( handle ).simulate( "drag", { dx: 100, - dy: 100, - // moves is 1 here because simulate currently fire events synchronously - // so we can't faithfully test things that rely on a scroll event (which is async) - moves: 1 + dy: 100 }); }, shouldMove: function( el, msg, handle ) { @@ -68,9 +62,13 @@ TestHelpers.draggable = { }); $( el ).unbind( "dragstop" ); }, + setScrollable: function ( what, isScrollable ) { + var overflow = isScrollable ? "scroll" : "hidden"; + $( what ).css({ overflow: overflow, overflowX: overflow, overflowY: overflow }); + }, testScroll: function( el, position ) { var oldPosition = $( "#main" ).css( "position" ); - $( "#main" ).css( "position", position); + $( "#main" ).css({ position: position, top: "0px", left: "0px" }); TestHelpers.draggable.shouldMove( el, position + " parent" ); $( "#main" ).css( "position", oldPosition ); }, diff --git a/tests/unit/droppable/droppable_options.js b/tests/unit/droppable/droppable_options.js index c2ecdcfda..1d8f95da9 100644 --- a/tests/unit/droppable/droppable_options.js +++ b/tests/unit/droppable/droppable_options.js @@ -35,6 +35,48 @@ test("{ addClasses: false }", function() { ok(!el.is(".ui-droppable"), "'ui-droppable' class not added"); el.droppable("destroy"); }); + +test( "scope", function() { + expect( 4 ); + var droppableOffset, draggableOffset, oldDraggableOffset, dx, dy, + draggable1 = $("
    ").appendTo( "#qunit-fixture" ).draggable({ revert: "invalid" }), + draggable2 = $("
    ").appendTo( "#qunit-fixture" ).droppable(), + droppable = $("
    ").appendTo( "#qunit-fixture" ).droppable(), + newScope = "test"; + + draggable1.draggable( "option", "scope", newScope ); + droppable.droppable( "option", "scope", newScope ); + + // Test that droppable accepts draggable with new scope. + droppableOffset = droppable.offset(); + draggableOffset = draggable1.offset(); + dx = droppableOffset.left - draggableOffset.left; + dy = droppableOffset.top - draggableOffset.top; + + draggable1.simulate( "drag", { + dx: dx, + dy: dy + }); + + draggableOffset = draggable1.offset(); + equal( draggableOffset.left, droppableOffset.left ); + equal( draggableOffset.top, droppableOffset.top ); + + // Test that droppable doesn't accept draggable with old scope. + draggableOffset = draggable2.offset(); + dx = droppableOffset.left - draggableOffset.left; + dy = droppableOffset.top - draggableOffset.top; + oldDraggableOffset = draggableOffset; + + draggable2.simulate( "drag", { + dx: dx, + dy: dy + }); + + draggableOffset = draggable2.offset(); + equal( draggableOffset.left, oldDraggableOffset.left ); + equal( draggableOffset.top, oldDraggableOffset.top ); +}); /* test("greedy", function() { ok(false, 'missing test - untested code is broken code'); @@ -44,10 +86,6 @@ test("hoverClass", function() { ok(false, 'missing test - untested code is broken code'); }); -test("scope", function() { - ok(false, 'missing test - untested code is broken code'); -}); - test("tolerance, fit", function() { ok(false, 'missing test - untested code is broken code'); }); diff --git a/tests/unit/sortable/sortable.html b/tests/unit/sortable/sortable.html index 8e0bac501..b03c786e1 100644 --- a/tests/unit/sortable/sortable.html +++ b/tests/unit/sortable/sortable.html @@ -38,7 +38,7 @@ margin: 1px; border-width: 0; } - #sortable li{ + #sortable li, #sortable2 li{ padding: 0; margin: 0; border-width: 0; @@ -58,7 +58,15 @@
      -
        +
          +
        • Item 1
        • +
        • Item 2
        • +
        • Item 3
        • +
        • Item 4
        • +
        • Item 5
        • +
        + +
        • Item 1
        • Item 2
        • Item 3
        • diff --git a/tests/unit/sortable/sortable_core.js b/tests/unit/sortable/sortable_core.js index 211f8ac95..18e7dae08 100644 --- a/tests/unit/sortable/sortable_core.js +++ b/tests/unit/sortable/sortable_core.js @@ -1,3 +1,19 @@ /* * sortable_core.js - */ \ No newline at end of file + */ + +(function( $ ) { + +module( "sortable: core" ); + +test( "#9314: Sortable: Items cannot be dragged directly into bottom position", function() { + expect( 1 ); + + var el = $( ".connectWith" ).sortable({ + connectWith: ".connectWith" + }); + + TestHelpers.sortable.sort( $( "li", el[ 1 ] )[ 0 ], 0, -12, 5, "Dragging the sortable into connected sortable" ); +}); + +})( jQuery ); diff --git a/tests/unit/tabs/tabs_core.js b/tests/unit/tabs/tabs_core.js index cc4f0460c..945dfb1e4 100644 --- a/tests/unit/tabs/tabs_core.js +++ b/tests/unit/tabs/tabs_core.js @@ -67,7 +67,7 @@ test( "aria-controls", function() { tabs = element.find( ".ui-tabs-nav li" ); equal( tabs.eq( 0 ).attr( "aria-controls" ), "colon:test" ); equal( tabs.eq( 1 ).attr( "aria-controls" ), "inline-style" ); - ok( /^ui-tabs-\d+$/.test( tabs.eq( 2 ).attr( "aria-controls" ) ), "generated id" ); + ok( /^ui-id-\d+$/.test( tabs.eq( 2 ).attr( "aria-controls" ) ), "generated id" ); equal( tabs.eq( 3 ).attr( "aria-controls" ), "custom-id" ); }); diff --git a/themes/base/jquery.ui.menu.css b/themes/base/jquery.ui.menu.css index cc390cec4..7970422c7 100644 --- a/themes/base/jquery.ui.menu.css +++ b/themes/base/jquery.ui.menu.css @@ -10,27 +10,25 @@ */ .ui-menu { list-style: none; - padding: 2px; + padding: 0; margin: 0; display: block; outline: none; } .ui-menu .ui-menu { - margin-top: -3px; position: absolute; } .ui-menu .ui-menu-item { margin: 0; display: block; - padding: 2px .4em; - line-height: 1.5; + padding: 3px .4em; + cursor: pointer; min-height: 0; /* support: IE7 */ - font-weight: normal; /* support: IE10, see #8844 */ list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); } .ui-menu .ui-menu-divider { - margin: 5px -2px 5px -2px; + margin: 5px 0; height: 0; font-size: 0; line-height: 0; @@ -38,19 +36,9 @@ } .ui-menu .ui-state-focus, .ui-menu .ui-state-active { - font-weight: normal; margin: -1px; } -.ui-menu .ui-state-disabled { - font-weight: normal; - margin: .4em 0 .2em; - line-height: 1.5; -} -.ui-menu .ui-state-disabled a { - cursor: default; -} - /* icon support */ .ui-menu-icons { position: relative; @@ -69,6 +57,7 @@ /* right-aligned */ .ui-menu .ui-menu-icon { - position: static; + position: relative; + top: -.2em; float: right; } diff --git a/ui/i18n/jquery.ui.datepicker-lv.js b/ui/i18n/jquery.ui.datepicker-lv.js index 28cc102fc..3fdf8565b 100644 --- a/ui/i18n/jquery.ui.datepicker-lv.js +++ b/ui/i18n/jquery.ui.datepicker-lv.js @@ -3,8 +3,8 @@ jQuery(function($){ $.datepicker.regional['lv'] = { closeText: 'Aizvērt', - prevText: 'Iepr', - nextText: 'Nāka', + prevText: 'Iepr.', + nextText: 'Nāk.', currentText: 'Šodien', monthNames: ['Janvāris','Februāris','Marts','Aprīlis','Maijs','Jūnijs', 'Jūlijs','Augusts','Septembris','Oktobris','Novembris','Decembris'], @@ -13,8 +13,8 @@ jQuery(function($){ dayNames: ['svētdiena','pirmdiena','otrdiena','trešdiena','ceturtdiena','piektdiena','sestdiena'], dayNamesShort: ['svt','prm','otr','tre','ctr','pkt','sst'], dayNamesMin: ['Sv','Pr','Ot','Tr','Ct','Pk','Ss'], - weekHeader: 'Nav', - dateFormat: 'dd-mm-yy', + weekHeader: 'Ned.', + dateFormat: 'dd.mm.yy', firstDay: 1, isRTL: false, showMonthAfterYear: false, diff --git a/ui/jquery.ui.accordion.js b/ui/jquery.ui.accordion.js index 26a9ce94f..131d12c32 100644 --- a/ui/jquery.ui.accordion.js +++ b/ui/jquery.ui.accordion.js @@ -14,15 +14,6 @@ */ (function( $, undefined ) { -var uid = 0, - hideProps = {}, - showProps = {}; - -hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = - hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; -showProps.height = showProps.paddingTop = showProps.paddingBottom = - showProps.borderTopWidth = showProps.borderBottomWidth = "show"; - $.widget( "ui.accordion", { version: "@VERSION", options: { @@ -42,6 +33,22 @@ $.widget( "ui.accordion", { beforeActivate: null }, + hideProps: { + borderTopWidth: "hide", + borderBottomWidth: "hide", + paddingTop: "hide", + paddingBottom: "hide", + height: "hide" + }, + + showProps: { + borderTopWidth: "show", + borderBottomWidth: "show", + paddingTop: "show", + paddingBottom: "show", + height: "show" + }, + _create: function() { var options = this.options; this.prevShow = this.prevHide = $(); @@ -99,31 +106,27 @@ $.widget( "ui.accordion", { // clean up headers this.headers - .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) + .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " + + "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) .removeAttr( "role" ) + .removeAttr( "aria-expanded" ) .removeAttr( "aria-selected" ) .removeAttr( "aria-controls" ) .removeAttr( "tabIndex" ) - .each(function() { - if ( /^ui-accordion/.test( this.id ) ) { - this.removeAttribute( "id" ); - } - }); + .removeUniqueId(); + this._destroyIcons(); // clean up content panels contents = this.headers.next() + .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " + + "ui-accordion-content ui-accordion-content-active ui-state-disabled" ) .css( "display", "" ) .removeAttr( "role" ) - .removeAttr( "aria-expanded" ) .removeAttr( "aria-hidden" ) .removeAttr( "aria-labelledby" ) - .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) - .each(function() { - if ( /^ui-accordion/.test( this.id ) ) { - this.removeAttribute( "id" ); - } - }); + .removeUniqueId(); + if ( this.options.heightStyle !== "content" ) { contents.css( "height", "" ); } @@ -259,9 +262,7 @@ $.widget( "ui.accordion", { var maxHeight, options = this.options, heightStyle = options.heightStyle, - parent = this.element.parent(), - accordionId = this.accordionId = "ui-accordion-" + - (this.element.attr( "id" ) || ++uid); + parent = this.element.parent(); this.active = this._findActive( options.active ) .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) @@ -272,19 +273,11 @@ $.widget( "ui.accordion", { this.headers .attr( "role", "tab" ) - .each(function( i ) { + .each(function() { var header = $( this ), - headerId = header.attr( "id" ), + headerId = header.uniqueId().attr( "id" ), panel = header.next(), - panelId = panel.attr( "id" ); - if ( !headerId ) { - headerId = accordionId + "-header-" + i; - header.attr( "id", headerId ); - } - if ( !panelId ) { - panelId = accordionId + "-panel-" + i; - panel.attr( "id", panelId ); - } + panelId = panel.uniqueId().attr( "id" ); header.attr( "aria-controls", panelId ); panel.attr( "aria-labelledby", headerId ); }) @@ -295,11 +288,11 @@ $.widget( "ui.accordion", { .not( this.active ) .attr({ "aria-selected": "false", + "aria-expanded": "false", tabIndex: -1 }) .next() .attr({ - "aria-expanded": "false", "aria-hidden": "true" }) .hide(); @@ -310,11 +303,11 @@ $.widget( "ui.accordion", { } else { this.active.attr({ "aria-selected": "true", + "aria-expanded": "true", tabIndex: 0 }) .next() .attr({ - "aria-expanded": "true", "aria-hidden": "false" }); } @@ -469,7 +462,6 @@ $.widget( "ui.accordion", { } toHide.attr({ - "aria-expanded": "false", "aria-hidden": "true" }); toHide.prev().attr( "aria-selected", "false" ); @@ -477,7 +469,10 @@ $.widget( "ui.accordion", { // if we're opening from collapsed state, remove the previous header from the tab order // if we're collapsing, then keep the collapsing header in the tab order if ( toShow.length && toHide.length ) { - toHide.prev().attr( "tabIndex", -1 ); + toHide.prev().attr({ + "tabIndex": -1, + "aria-expanded": "false" + }); } else if ( toShow.length ) { this.headers.filter(function() { return $( this ).attr( "tabIndex" ) === 0; @@ -486,14 +481,12 @@ $.widget( "ui.accordion", { } toShow - .attr({ - "aria-expanded": "true", - "aria-hidden": "false" - }) + .attr( "aria-hidden", "false" ) .prev() .attr({ "aria-selected": "true", - tabIndex: 0 + tabIndex: 0, + "aria-expanded": "true" }); }, @@ -520,14 +513,14 @@ $.widget( "ui.accordion", { duration = duration || options.duration || animate.duration; if ( !toHide.length ) { - return toShow.animate( showProps, duration, easing, complete ); + return toShow.animate( this.showProps, duration, easing, complete ); } if ( !toShow.length ) { - return toHide.animate( hideProps, duration, easing, complete ); + return toHide.animate( this.hideProps, duration, easing, complete ); } total = toShow.show().outerHeight(); - toHide.animate( hideProps, { + toHide.animate( this.hideProps, { duration: duration, easing: easing, step: function( now, fx ) { @@ -536,7 +529,7 @@ $.widget( "ui.accordion", { }); toShow .hide() - .animate( showProps, { + .animate( this.showProps, { duration: duration, easing: easing, complete: complete, @@ -565,7 +558,6 @@ $.widget( "ui.accordion", { if ( toHide.length ) { toHide.parent()[0].className = toHide.parent()[0].className; } - this._trigger( "activate", null, data ); } }); diff --git a/ui/jquery.ui.button.js b/ui/jquery.ui.button.js index ae3b86ae9..6bde7863f 100644 --- a/ui/jquery.ui.button.js +++ b/ui/jquery.ui.button.js @@ -14,7 +14,7 @@ */ (function( $, undefined ) { -var lastActive, startXPos, startYPos, clickDragged, +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() { @@ -115,42 +115,19 @@ $.widget( "ui.button", { if ( toggleButton ) { this.element.bind( "change" + this.eventNamespace, function() { - if ( clickDragged ) { - return; - } that.refresh(); }); - // if mouse moves between mousedown and mouseup (drag) set clickDragged flag - // prevents issue where button state changes but checkbox/radio checked state - // does not in Firefox (see ticket #6970) - this.buttonElement - .bind( "mousedown" + this.eventNamespace, function( event ) { - if ( options.disabled ) { - return; - } - clickDragged = false; - startXPos = event.pageX; - startYPos = event.pageY; - }) - .bind( "mouseup" + this.eventNamespace, function( event ) { - if ( options.disabled ) { - return; - } - if ( startXPos !== event.pageX || startYPos !== event.pageY ) { - clickDragged = true; - } - }); } if ( this.type === "checkbox" ) { this.buttonElement.bind( "click" + this.eventNamespace, function() { - if ( options.disabled || clickDragged ) { + if ( options.disabled ) { return false; } }); } else if ( this.type === "radio" ) { this.buttonElement.bind( "click" + this.eventNamespace, function() { - if ( options.disabled || clickDragged ) { + if ( options.disabled ) { return false; } $( this ).addClass( "ui-state-active" ); diff --git a/ui/jquery.ui.core.js b/ui/jquery.ui.core.js index 9145d5d45..7faae0760 100644 --- a/ui/jquery.ui.core.js +++ b/ui/jquery.ui.core.js @@ -10,9 +10,6 @@ */ (function( $, undefined ) { -var uuid = 0, - runiqueId = /^ui-id-\d+$/; - // $.ui might exist from components with no dependencies, e.g., $.ui.position $.ui = $.ui || {}; @@ -72,17 +69,21 @@ $.fn.extend({ return ( /fixed/ ).test( this.css( "position") ) || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent; }, - uniqueId: function() { - return this.each(function() { - if ( !this.id ) { - this.id = "ui-id-" + (++uuid); - } - }); - }, + uniqueId: (function() { + var uuid = 0; + + return function() { + return this.each(function() { + if ( !this.id ) { + this.id = "ui-id-" + ( ++uuid ); + } + }); + }; + })(), removeUniqueId: function() { return this.each(function() { - if ( runiqueId.test( this.id ) ) { + if ( /^ui-id-\d+$/.test( this.id ) ) { $( this ).removeAttr( "id" ); } }); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 0f0ee7fe2..e4961a1df 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -15,10 +15,9 @@ $.extend($.ui, { datepicker: { version: "@VERSION" } }); -var PROP_NAME = "datepicker", - instActive; +var datepicker_instActive; -function getZindex( elem ) { +function datepicker_getZindex( elem ) { var position, value; while ( elem.length && elem[ 0 ] !== document ) { // Ignore z-index if position is set to a value where z-index is ignored by the browser @@ -130,7 +129,7 @@ function Datepicker() { disabled: false // The initial disabled state }; $.extend(this._defaults, this.regional[""]); - this.dpDiv = bindHover($("
          ")); + this.dpDiv = datepicker_bindHover($("
          ")); } $.extend(Datepicker.prototype, { @@ -150,7 +149,7 @@ $.extend(Datepicker.prototype, { * @return the manager object */ setDefaults: function(settings) { - extendRemove(this._defaults, settings || {}); + datepicker_extendRemove(this._defaults, settings || {}); return this; }, @@ -183,7 +182,7 @@ $.extend(Datepicker.prototype, { drawMonth: 0, drawYear: 0, // month being drawn inline: inline, // is datepicker inline or not dpDiv: (!inline ? this.dpDiv : // presentation div - bindHover($("
          ")))}; + datepicker_bindHover($("
          ")))}; }, /* Attach the date picker to an input field. */ @@ -198,7 +197,7 @@ $.extend(Datepicker.prototype, { input.addClass(this.markerClassName).keydown(this._doKeyDown). keypress(this._doKeyPress).keyup(this._doKeyUp); this._autoSize(inst); - $.data(target, PROP_NAME, inst); + $.data(target, "datepicker", inst); //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) if( inst.settings.disabled ) { this._disableDatepicker( target ); @@ -288,7 +287,7 @@ $.extend(Datepicker.prototype, { return; } divSpan.addClass(this.markerClassName).append(inst.dpDiv); - $.data(target, PROP_NAME, inst); + $.data(target, "datepicker", inst); this._setDate(inst, this._getDefaultDate(inst), true); this._updateDatepicker(inst); this._updateAlternate(inst); @@ -324,9 +323,9 @@ $.extend(Datepicker.prototype, { $("body").append(this._dialogInput); inst = this._dialogInst = this._newInst(this._dialogInput, false); inst.settings = {}; - $.data(this._dialogInput[0], PROP_NAME, inst); + $.data(this._dialogInput[0], "datepicker", inst); } - extendRemove(inst.settings, settings || {}); + datepicker_extendRemove(inst.settings, settings || {}); date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); this._dialogInput.val(date); @@ -349,7 +348,7 @@ $.extend(Datepicker.prototype, { if ($.blockUI) { $.blockUI(this.dpDiv); } - $.data(this._dialogInput[0], PROP_NAME, inst); + $.data(this._dialogInput[0], "datepicker", inst); return this; }, @@ -359,14 +358,14 @@ $.extend(Datepicker.prototype, { _destroyDatepicker: function(target) { var nodeName, $target = $(target), - inst = $.data(target, PROP_NAME); + inst = $.data(target, "datepicker"); if (!$target.hasClass(this.markerClassName)) { return; } nodeName = target.nodeName.toLowerCase(); - $.removeData(target, PROP_NAME); + $.removeData(target, "datepicker"); if (nodeName === "input") { inst.append.remove(); inst.trigger.remove(); @@ -386,7 +385,7 @@ $.extend(Datepicker.prototype, { _enableDatepicker: function(target) { var nodeName, inline, $target = $(target), - inst = $.data(target, PROP_NAME); + inst = $.data(target, "datepicker"); if (!$target.hasClass(this.markerClassName)) { return; @@ -414,7 +413,7 @@ $.extend(Datepicker.prototype, { _disableDatepicker: function(target) { var nodeName, inline, $target = $(target), - inst = $.data(target, PROP_NAME); + inst = $.data(target, "datepicker"); if (!$target.hasClass(this.markerClassName)) { return; @@ -460,7 +459,7 @@ $.extend(Datepicker.prototype, { */ _getInst: function(target) { try { - return $.data(target, PROP_NAME); + return $.data(target, "datepicker"); } catch (err) { throw "Missing instance data for this datepicker"; @@ -500,7 +499,7 @@ $.extend(Datepicker.prototype, { date = this._getDateDatepicker(target, true); minDate = this._getMinMaxDate(inst, "min"); maxDate = this._getMinMaxDate(inst, "max"); - extendRemove(inst.settings, settings); + datepicker_extendRemove(inst.settings, settings); // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { inst.settings.minDate = this._formatDate(inst, minDate); @@ -728,7 +727,7 @@ $.extend(Datepicker.prototype, { if(beforeShowSettings === false){ return; } - extendRemove(inst.settings, beforeShowSettings); + datepicker_extendRemove(inst.settings, beforeShowSettings); inst.lastVal = null; $.datepicker._lastInput = input; @@ -765,7 +764,7 @@ $.extend(Datepicker.prototype, { if (!inst.inline) { showAnim = $.datepicker._get(inst, "showAnim"); duration = $.datepicker._get(inst, "duration"); - inst.dpDiv.css( "z-index", getZindex( $( input ) ) + 1 ); + inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); $.datepicker._datepickerShowing = true; if ( $.effects && $.effects.effect[ showAnim ] ) { @@ -785,7 +784,7 @@ $.extend(Datepicker.prototype, { /* Generate the date picker content. */ _updateDatepicker: function(inst) { this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) - instActive = inst; // for delegate hover events + datepicker_instActive = inst; // for delegate hover events inst.dpDiv.empty().append(this._generateHTML(inst)); this._attachHandlers(inst); inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); @@ -871,7 +870,7 @@ $.extend(Datepicker.prototype, { var showAnim, duration, postProcess, onClose, inst = this._curInst; - if (!inst || (input && inst !== $.data(input, PROP_NAME))) { + if (!inst || (input && inst !== $.data(input, "datepicker"))) { return; } @@ -1975,9 +1974,9 @@ $.extend(Datepicker.prototype, { /* * Bind hover events for datepicker elements. * Done via delegate so the binding only occurs once in the lifetime of the parent div. - * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. + * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. */ -function bindHover(dpDiv) { +function datepicker_bindHover(dpDiv) { var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; return dpDiv.delegate(selector, "mouseout", function() { $(this).removeClass("ui-state-hover"); @@ -1989,7 +1988,7 @@ function bindHover(dpDiv) { } }) .delegate(selector, "mouseover", function(){ - if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { + if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? dpDiv.parent()[0] : datepicker_instActive.input[0])) { $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); $(this).addClass("ui-state-hover"); if (this.className.indexOf("ui-datepicker-prev") !== -1) { @@ -2003,7 +2002,7 @@ function bindHover(dpDiv) { } /* jQuery extend now ignores nulls! */ -function extendRemove(target, props) { +function datepicker_extendRemove(target, props) { $.extend(target, props); for (var name in props) { if (props[name] == null) { diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js index cbae739bf..c5bd42ab5 100644 --- a/ui/jquery.ui.dialog.js +++ b/ui/jquery.ui.dialog.js @@ -19,22 +19,6 @@ */ (function( $, undefined ) { -var sizeRelatedOptions = { - buttons: true, - height: true, - maxHeight: true, - maxWidth: true, - minHeight: true, - minWidth: true, - width: true - }, - resizableRelatedOptions = { - maxHeight: true, - maxWidth: true, - minHeight: true, - minWidth: true - }; - $.widget( "ui.dialog", { version: "@VERSION", options: { @@ -83,6 +67,23 @@ $.widget( "ui.dialog", { resizeStop: null }, + sizeRelatedOptions: { + buttons: true, + height: true, + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true, + width: true + }, + + resizableRelatedOptions: { + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true + }, + _create: function() { this.originalCss = { display: this.element[0].style.display, @@ -579,10 +580,10 @@ $.widget( "ui.dialog", { $.each( options, function( key, value ) { that._setOption( key, value ); - if ( key in sizeRelatedOptions ) { + if ( key in that.sizeRelatedOptions ) { resize = true; } - if ( key in resizableRelatedOptions ) { + if ( key in that.resizableRelatedOptions ) { resizableOptions[ key ] = value; } }); diff --git a/ui/jquery.ui.droppable.js b/ui/jquery.ui.droppable.js index a51c3a335..0e4b65cc4 100644 --- a/ui/jquery.ui.droppable.js +++ b/ui/jquery.ui.droppable.js @@ -16,10 +16,6 @@ */ (function( $, undefined ) { -function isOverAxis( x, reference, size ) { - return ( x >= reference ) && ( x < ( reference + size ) ); -} - $.widget( "ui.droppable", { version: "@VERSION", widgetEventPrefix: "drop", @@ -67,23 +63,31 @@ $.widget( "ui.droppable", { } }; - // Add the reference and positions to the manager - $.ui.ddmanager.droppables[ o.scope ] = $.ui.ddmanager.droppables[ o.scope ] || []; - $.ui.ddmanager.droppables[ o.scope ].push( this ); + this._addToManager( o.scope ); o.addClasses && this.element.addClass( "ui-droppable" ); }, - _destroy: function() { - var i = 0, - drop = $.ui.ddmanager.droppables[ this.options.scope ]; + _addToManager: function( scope ) { + // Add the reference and positions to the manager + $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; + $.ui.ddmanager.droppables[ scope ].push( this ); + }, + _splice: function( drop ) { + var i = 0; for ( ; i < drop.length; i++ ) { if ( drop[ i ] === this ) { drop.splice( i, 1 ); } } + }, + + _destroy: function() { + var drop = $.ui.ddmanager.droppables[ this.options.scope ]; + + this._splice( drop ); this.element.removeClass( "ui-droppable ui-droppable-disabled" ); }, @@ -94,7 +98,13 @@ $.widget( "ui.droppable", { this.accept = $.isFunction( value ) ? value : function( d ) { return d.is( value ); }; + } else if ( key === "scope" ) { + var drop = $.ui.ddmanager.droppables[ this.options.scope ]; + + this._splice( drop ); + this._addToManager( value ); } + this._super( key, value ); }, @@ -204,23 +214,28 @@ $.widget( "ui.droppable", { }); -$.ui.intersect = function( draggable, droppable, toleranceMode ) { - - if ( !droppable.offset ) { - return false; +$.ui.intersect = (function() { + function isOverAxis( x, reference, size ) { + return ( x >= reference ) && ( x < ( reference + size ) ); } - var draggableLeft, draggableTop, - x1 = ( draggable.positionAbs || draggable.position.absolute ).left, - y1 = ( draggable.positionAbs || draggable.position.absolute ).top, - x2 = x1 + draggable.helperProportions.width, - y2 = y1 + draggable.helperProportions.height, - l = droppable.offset.left, - t = droppable.offset.top, - r = l + droppable.proportions().width, - b = t + droppable.proportions().height; + return function( draggable, droppable, toleranceMode ) { - switch ( toleranceMode ) { + if ( !droppable.offset ) { + return false; + } + + var draggableLeft, draggableTop, + x1 = ( draggable.positionAbs || draggable.position.absolute ).left, + y1 = ( draggable.positionAbs || draggable.position.absolute ).top, + x2 = x1 + draggable.helperProportions.width, + y2 = y1 + draggable.helperProportions.height, + l = droppable.offset.left, + t = droppable.offset.top, + r = l + droppable.proportions().width, + b = t + droppable.proportions().height; + + switch ( toleranceMode ) { case "fit": return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); case "intersect": @@ -245,8 +260,8 @@ $.ui.intersect = function( draggable, droppable, toleranceMode ) { default: return false; } - -}; + }; +})(); /* This manager tracks offsets of draggables and droppables diff --git a/ui/jquery.ui.effect-blind.js b/ui/jquery.ui.effect-blind.js index f97de7413..e6f4b8a4c 100644 --- a/ui/jquery.ui.effect-blind.js +++ b/ui/jquery.ui.effect-blind.js @@ -13,12 +13,11 @@ */ (function( $, undefined ) { -var rvertical = /up|down|vertical/, - rpositivemotion = /up|left|vertical|horizontal/; - $.effects.effect.blind = function( o, done ) { // Create element var el = $( this ), + rvertical = /up|down|vertical/, + rpositivemotion = /up|left|vertical|horizontal/, props = [ "position", "top", "bottom", "left", "right", "height", "width" ], mode = $.effects.setMode( el, o.mode || "hide" ), direction = o.direction || "up", @@ -76,7 +75,6 @@ $.effects.effect.blind = function( o, done ) { done(); } }); - }; })(jQuery); diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index b0ff38894..c5d2bc777 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -26,7 +26,7 @@ $.widget( "ui.menu", { items: "> *", menus: "ul", position: { - my: "left top", + my: "left-1 top", at: "right top" }, role: "menu", @@ -44,7 +44,7 @@ $.widget( "ui.menu", { this.mouseHandled = false; this.element .uniqueId() - .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) + .addClass( "ui-menu ui-widget ui-widget-content" ) .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) .attr({ role: this.options.role, @@ -147,7 +147,7 @@ $.widget( "ui.menu", { this.element .removeAttr( "aria-activedescendant" ) .find( ".ui-menu" ).addBack() - .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) + .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons" ) .removeAttr( "role" ) .removeAttr( "tabIndex" ) .removeAttr( "aria-labelledby" ) @@ -163,7 +163,7 @@ $.widget( "ui.menu", { .removeAttr( "role" ) .removeAttr( "aria-disabled" ) .removeUniqueId() - .removeClass( "ui-corner-all ui-state-hover" ) + .removeClass( "ui-state-hover" ) .removeAttr( "tabIndex" ) .removeAttr( "role" ) .removeAttr( "aria-haspopup" ) @@ -292,7 +292,7 @@ $.widget( "ui.menu", { // Initialize nested menus submenus.filter( ":not(.ui-menu)" ) - .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) + .addClass( "ui-menu ui-widget ui-widget-content" ) .hide() .attr({ role: this.options.role, @@ -328,7 +328,6 @@ $.widget( "ui.menu", { items.not( ".ui-menu-item, .ui-menu-divider" ) .addClass( "ui-menu-item" ) .uniqueId() - .addClass( "ui-corner-all" ) .attr({ tabIndex: -1, role: this._itemRole() diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 21c3cef1b..15f168927 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -9,6 +9,7 @@ * http://api.jqueryui.com/position/ */ (function( $, undefined ) { +(function() { $.ui = $.ui || {}; @@ -494,4 +495,5 @@ $.ui.position = { testElementParent.removeChild( testElement ); })(); +})(); }( jQuery ) ); diff --git a/ui/jquery.ui.resizable.js b/ui/jquery.ui.resizable.js index f683e6b65..040f029f9 100644 --- a/ui/jquery.ui.resizable.js +++ b/ui/jquery.ui.resizable.js @@ -15,37 +15,6 @@ */ (function( $, undefined ) { -function num(v) { - return parseInt(v, 10) || 0; -} - -function isNumber(value) { - return !isNaN(parseInt(value, 10)); -} - -function hasScroll( el, a ) { - - //If overflow is hidden, the element might have extra content, but the user wants to hide it - if ( $( el ).css( "overflow" ) === "hidden") { - return false; - } - - var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", - has = false; - - if ( el[ scroll ] > 0 ) { - return true; - } - - // TODO: determine which cases actually cause this to happen - // if the element doesn't have the scroll set, see if it's possible to - // set the scroll - el[ scroll ] = 1; - has = ( el[ scroll ] > 0 ); - el[ scroll ] = 0; - return has; -} - $.widget("ui.resizable", $.ui.mouse, { version: "@VERSION", widgetEventPrefix: "resize", @@ -73,6 +42,38 @@ $.widget("ui.resizable", $.ui.mouse, { start: null, stop: null }, + + _num: function( value ) { + return parseInt( value, 10 ) || 0; + }, + + _isNumber: function( value ) { + return !isNaN( parseInt( value , 10 ) ); + }, + + _hasScroll: function( el, a ) { + + //If overflow is hidden, the element might have extra content, but the user wants to hide it + if ( $( el ).css( "overflow" ) === "hidden") { + return false; + } + + var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", + has = false; + + if ( el[ scroll ] > 0 ) { + return true; + } + + // TODO: determine which cases actually cause this to happen + // if the element doesn't have the scroll set, see if it's possible to + // set the scroll + el[ scroll ] = 1; + has = ( el[ scroll ] > 0 ); + el[ scroll ] = 0; + return has; + }, + _create: function() { var n, i, handle, axis, hname, @@ -305,8 +306,8 @@ $.widget("ui.resizable", $.ui.mouse, { this._renderProxy(); - curleft = num(this.helper.css("left")); - curtop = num(this.helper.css("top")); + curleft = this._num(this.helper.css("left")); + curtop = this._num(this.helper.css("top")); if (o.containment) { curleft += $(o.containment).scrollLeft() || 0; @@ -404,7 +405,7 @@ $.widget("ui.resizable", $.ui.mouse, { pr = this._proportionallyResizeElements; ista = pr.length && (/textarea/i).test(pr[0].nodeName); - soffseth = ista && hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; + soffseth = ista && this._hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; soffsetw = ista ? 0 : that.sizeDiff.width; s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; @@ -442,10 +443,10 @@ $.widget("ui.resizable", $.ui.mouse, { o = this.options; b = { - minWidth: isNumber(o.minWidth) ? o.minWidth : 0, - maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, - minHeight: isNumber(o.minHeight) ? o.minHeight : 0, - maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity + minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0, + maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity, + minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0, + maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity }; if(this._aspectRatio || forceAspectRatio) { @@ -474,16 +475,16 @@ $.widget("ui.resizable", $.ui.mouse, { _updateCache: function(data) { this.offset = this.helper.offset(); - if (isNumber(data.left)) { + if (this._isNumber(data.left)) { this.position.left = data.left; } - if (isNumber(data.top)) { + if (this._isNumber(data.top)) { this.position.top = data.top; } - if (isNumber(data.height)) { + if (this._isNumber(data.height)) { this.size.height = data.height; } - if (isNumber(data.width)) { + if (this._isNumber(data.width)) { this.size.width = data.width; } }, @@ -494,9 +495,9 @@ $.widget("ui.resizable", $.ui.mouse, { csize = this.size, a = this.axis; - if (isNumber(data.height)) { + if (this._isNumber(data.height)) { data.width = (data.height * this.aspectRatio); - } else if (isNumber(data.width)) { + } else if (this._isNumber(data.width)) { data.height = (data.width / this.aspectRatio); } @@ -516,8 +517,8 @@ $.widget("ui.resizable", $.ui.mouse, { var o = this._vBoundaries, a = this.axis, - ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), - isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), + ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), + isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height), dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height, cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); @@ -678,7 +679,7 @@ $.ui.plugin.add("resizable", "animate", { o = that.options, pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), - soffseth = ista && hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, + soffseth = ista && that._hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, soffsetw = ista ? 0 : that.sizeDiff.width, style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, @@ -742,7 +743,7 @@ $.ui.plugin.add("resizable", "containment", { else { element = $(ce); p = []; - $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); + $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = that._num(element.css("padding" + name)); }); that.containerOffset = element.offset(); that.containerPosition = element.position(); @@ -751,8 +752,8 @@ $.ui.plugin.add("resizable", "containment", { co = that.containerOffset; ch = that.containerSize.height; cw = that.containerSize.width; - width = (hasScroll(ce, "left") ? ce.scrollWidth : cw ); - height = (hasScroll(ce) ? ce.scrollHeight : ch); + width = (that._hasScroll(ce, "left") ? ce.scrollWidth : cw ); + height = (that._hasScroll(ce) ? ce.scrollHeight : ch); that.parentData = { element: ce, left: co.left, top: co.top, width: width, height: height diff --git a/ui/jquery.ui.slider.js b/ui/jquery.ui.slider.js index df71f363f..10efc4bf8 100644 --- a/ui/jquery.ui.slider.js +++ b/ui/jquery.ui.slider.js @@ -15,10 +15,6 @@ */ (function( $, undefined ) { -// number of pages in a slider -// (how many times can you page up/down to go through the whole range) -var numPages = 5; - $.widget( "ui.slider", $.ui.mouse, { version: "@VERSION", widgetEventPrefix: "slide", @@ -41,6 +37,10 @@ $.widget( "ui.slider", $.ui.mouse, { stop: null }, + // number of pages in a slider + // (how many times can you page up/down to go through the whole range) + numPages: 5, + _create: function() { this._keySliding = false; this._mouseSliding = false; @@ -637,10 +637,13 @@ $.widget( "ui.slider", $.ui.mouse, { newVal = this._valueMax(); break; case $.ui.keyCode.PAGE_UP: - newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); + newVal = this._trimAlignValue( + curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) + ); break; case $.ui.keyCode.PAGE_DOWN: - newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); + newVal = this._trimAlignValue( + curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) ); break; case $.ui.keyCode.UP: case $.ui.keyCode.RIGHT: @@ -674,7 +677,6 @@ $.widget( "ui.slider", $.ui.mouse, { } } } - }); }(jQuery)); diff --git a/ui/jquery.ui.sortable.js b/ui/jquery.ui.sortable.js index c76a02397..4ba2576c1 100644 --- a/ui/jquery.ui.sortable.js +++ b/ui/jquery.ui.sortable.js @@ -15,14 +15,6 @@ */ (function( $, undefined ) { -function isOverAxis( x, reference, size ) { - return ( x >= reference ) && ( x < ( reference + size ) ); -} - -function isFloating(item) { - return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); -} - $.widget("ui.sortable", $.ui.mouse, { version: "@VERSION", widgetEventPrefix: "sort", @@ -65,6 +57,15 @@ $.widget("ui.sortable", $.ui.mouse, { stop: null, update: null }, + + _isOverAxis: function( x, reference, size ) { + return ( x >= reference ) && ( x < ( reference + size ) ); + }, + + _isFloating: function( item ) { + return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); + }, + _create: function() { var o = this.options; @@ -75,7 +76,7 @@ $.widget("ui.sortable", $.ui.mouse, { this.refresh(); //Let's determine if the items are being displayed horizontally - this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; + this.floating = this.items.length ? o.axis === "x" || this._isFloating(this.items[0].item) : false; //Let's determine the parent's offset this.offset = this.element.offset(); @@ -554,8 +555,8 @@ $.widget("ui.sortable", $.ui.mouse, { _intersectsWithPointer: function(item) { - var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), - isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), + var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), + isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), isOverElement = isOverElementHeight && isOverElementWidth, verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); @@ -572,8 +573,8 @@ $.widget("ui.sortable", $.ui.mouse, { _intersectsWithSides: function(item) { - var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), - isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), + var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), + isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); @@ -798,7 +799,7 @@ $.widget("ui.sortable", $.ui.mouse, { }, _contactContainers: function(event) { - var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, + var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis, innermostContainer = null, innermostIndex = null; @@ -846,10 +847,11 @@ $.widget("ui.sortable", $.ui.mouse, { //When entering a new container, we will find the item with the least distance and append our item near it dist = 10000; itemWithLeastDistance = null; - floating = innermostContainer.floating || isFloating(this.currentItem); + floating = innermostContainer.floating || this._isFloating(this.currentItem); posProperty = floating ? "left" : "top"; sizeProperty = floating ? "width" : "height"; - base = this.positionAbs[posProperty] + this.offset.click[posProperty]; + axis = floating ? "clientX" : "clientY"; + for (j = this.items.length - 1; j >= 0; j--) { if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { continue; @@ -857,18 +859,16 @@ $.widget("ui.sortable", $.ui.mouse, { if(this.items[j].item[0] === this.currentItem[0]) { continue; } - if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { - continue; - } + cur = this.items[j].item.offset()[posProperty]; nearBottom = false; - if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ + if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { nearBottom = true; - cur += this.items[j][sizeProperty]; } - if(Math.abs(cur - base) < dist) { - dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; + if ( Math.abs( event[ axis ] - cur ) < dist ) { + dist = Math.abs( event[ axis ] - cur ); + itemWithLeastDistance = this.items[ j ]; this.direction = nearBottom ? "up": "down"; } } diff --git a/ui/jquery.ui.spinner.js b/ui/jquery.ui.spinner.js index 3bbd35f88..870b3328a 100644 --- a/ui/jquery.ui.spinner.js +++ b/ui/jquery.ui.spinner.js @@ -15,7 +15,7 @@ */ (function( $ ) { -function modifier( fn ) { +function spinner_modifier( fn ) { return function() { var previous = this.element.val(); fn.apply( this, arguments ); @@ -391,7 +391,7 @@ $.widget( "ui.spinner", { } }, - _setOptions: modifier(function( options ) { + _setOptions: spinner_modifier(function( options ) { this._super( options ); this._value( this.element.val() ); }), @@ -462,7 +462,7 @@ $.widget( "ui.spinner", { this.uiSpinner.replaceWith( this.element ); }, - stepUp: modifier(function( steps ) { + stepUp: spinner_modifier(function( steps ) { this._stepUp( steps ); }), _stepUp: function( steps ) { @@ -472,7 +472,7 @@ $.widget( "ui.spinner", { } }, - stepDown: modifier(function( steps ) { + stepDown: spinner_modifier(function( steps ) { this._stepDown( steps ); }), _stepDown: function( steps ) { @@ -482,11 +482,11 @@ $.widget( "ui.spinner", { } }, - pageUp: modifier(function( pages ) { + pageUp: spinner_modifier(function( pages ) { this._stepUp( (pages || 1) * this.options.page ); }), - pageDown: modifier(function( pages ) { + pageDown: spinner_modifier(function( pages ) { this._stepDown( (pages || 1) * this.options.page ); }), @@ -494,7 +494,7 @@ $.widget( "ui.spinner", { if ( !arguments.length ) { return this._parse( this.element.val() ); } - modifier( this._value ).call( this, newVal ); + spinner_modifier( this._value ).call( this, newVal ); }, widget: function() { diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index 4077c9ac5..25395b8fc 100644 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -14,23 +14,6 @@ */ (function( $, undefined ) { -var tabId = 0, - rhash = /#.*$/; - -function getNextTabId() { - return ++tabId; -} - -function isLocal( anchor ) { - // support: IE7 - // IE7 doesn't normalize the href property when set via script (#9317) - anchor = anchor.cloneNode( false ); - - return anchor.hash.length > 1 && - decodeURIComponent( anchor.href.replace( rhash, "" ) ) === - decodeURIComponent( location.href.replace( rhash, "" ) ); -} - $.widget( "ui.tabs", { version: "@VERSION", delay: 300, @@ -49,6 +32,31 @@ $.widget( "ui.tabs", { load: null }, + _isLocal: (function() { + var rhash = /#.*$/; + + return function( anchor ) { + var anchorUrl, locationUrl; + + // support: IE7 + // IE7 doesn't normalize the href property when set via script (#9317) + anchor = anchor.cloneNode( false ); + + anchorUrl = anchor.href.replace( rhash, "" ); + locationUrl = location.href.replace( rhash, "" ); + + // decoding may throw an error if the URL isn't UTF-8 (#9518) + try { + anchorUrl = decodeURIComponent( anchorUrl ); + } catch ( error ) {} + try { + locationUrl = decodeURIComponent( locationUrl ); + } catch ( error ) {} + + return anchor.hash.length > 1 && anchorUrl === locationUrl; + }; + })(), + _create: function() { var that = this, options = this.options; @@ -296,10 +304,6 @@ $.widget( "ui.tabs", { } }, - _tabId: function( tab ) { - return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); - }, - _sanitizeSelector: function( hash ) { return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; }, @@ -406,12 +410,15 @@ $.widget( "ui.tabs", { originalAriaControls = tab.attr( "aria-controls" ); // inline tab - if ( isLocal( anchor ) ) { + if ( that._isLocal( anchor ) ) { selector = anchor.hash; + panelId = selector.substring( 1 ); panel = that.element.find( that._sanitizeSelector( selector ) ); // remote tab } else { - panelId = that._tabId( tab ); + // If the tab doesn't already have aria-controls, + // generate an id by using a throw-away element + panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; selector = "#" + panelId; panel = that.element.find( selector ); if ( !panel.length ) { @@ -428,7 +435,7 @@ $.widget( "ui.tabs", { tab.data( "ui-tabs-aria-controls", originalAriaControls ); } tab.attr({ - "aria-controls": selector.substring( 1 ), + "aria-controls": panelId, "aria-labelledby": anchorId }); panel.attr( "aria-labelledby", anchorId ); @@ -790,7 +797,7 @@ $.widget( "ui.tabs", { }; // not remote - if ( isLocal( anchor[ 0 ] ) ) { + if ( this._isLocal( anchor[ 0 ] ) ) { return; } diff --git a/ui/jquery.ui.tooltip.js b/ui/jquery.ui.tooltip.js index 5df93a002..9fde036a8 100644 --- a/ui/jquery.ui.tooltip.js +++ b/ui/jquery.ui.tooltip.js @@ -15,33 +15,6 @@ */ (function( $ ) { -var increments = 0; - -function addDescribedBy( elem, id ) { - var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); - describedby.push( id ); - elem - .data( "ui-tooltip-id", id ) - .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); -} - -function removeDescribedBy( elem ) { - var id = elem.data( "ui-tooltip-id" ), - describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), - index = $.inArray( id, describedby ); - if ( index !== -1 ) { - describedby.splice( index, 1 ); - } - - elem.removeData( "ui-tooltip-id" ); - describedby = $.trim( describedby.join( " " ) ); - if ( describedby ) { - elem.attr( "aria-describedby", describedby ); - } else { - elem.removeAttr( "aria-describedby" ); - } -} - $.widget( "ui.tooltip", { version: "@VERSION", options: { @@ -69,6 +42,32 @@ $.widget( "ui.tooltip", { open: null }, + _addDescribedBy: function( elem, id ) { + var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); + describedby.push( id ); + elem + .data( "ui-tooltip-id", id ) + .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); + }, + + _removeDescribedBy: function( elem ) { + var id = elem.data( "ui-tooltip-id" ), + describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), + index = $.inArray( id, describedby ); + + if ( index !== -1 ) { + describedby.splice( index, 1 ); + } + + elem.removeData( "ui-tooltip-id" ); + describedby = $.trim( describedby.join( " " ) ); + if ( describedby ) { + elem.attr( "aria-describedby", describedby ); + } else { + elem.removeAttr( "aria-describedby" ); + } + }, + _create: function() { this._on({ mouseover: "open", @@ -243,7 +242,7 @@ $.widget( "ui.tooltip", { } tooltip = this._tooltip( target ); - addDescribedBy( target, tooltip.attr( "id" ) ); + this._addDescribedBy( target, tooltip.attr( "id" ) ); tooltip.find( ".ui-tooltip-content" ).html( content ); function position( event ) { @@ -322,7 +321,7 @@ $.widget( "ui.tooltip", { target.attr( "title", target.data( "ui-tooltip-title" ) ); } - removeDescribedBy( target ); + this._removeDescribedBy( target ); tooltip.stop( true ); this._hide( tooltip, this.options.hide, function() { @@ -350,17 +349,16 @@ $.widget( "ui.tooltip", { }, _tooltip: function( element ) { - var id = "ui-tooltip-" + increments++, - tooltip = $( "
          " ) - .attr({ - id: id, - role: "tooltip" - }) + var tooltip = $( "
          " ) + .attr( "role", "tooltip" ) .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + - ( this.options.tooltipClass || "" ) ); + ( this.options.tooltipClass || "" ) ), + id = tooltip.uniqueId().attr( "id" ); + $( "
          " ) .addClass( "ui-tooltip-content" ) .appendTo( tooltip ); + tooltip.appendTo( this.document[0].body ); this.tooltips[ id ] = element; return tooltip; diff --git a/ui/jquery.ui.widget.js b/ui/jquery.ui.widget.js index cc01f784f..97f5fd7e0 100644 --- a/ui/jquery.ui.widget.js +++ b/ui/jquery.ui.widget.js @@ -10,18 +10,20 @@ */ (function( $, undefined ) { -var uuid = 0, - slice = Array.prototype.slice, - _cleanData = $.cleanData; -$.cleanData = function( elems ) { - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { - try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} - } - _cleanData( elems ); -}; +var widget_uuid = 0, + widget_slice = Array.prototype.slice; + +$.cleanData = (function( orig ) { + return function( elems ) { + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + try { + $( elem ).triggerHandler( "remove" ); + // http://bugs.jquery.com/ticket/8235 + } catch( e ) {} + } + orig( elems ); + }; +})( $.cleanData ); $.widget = function( name, base, prototype ) { var fullName, existingConstructor, constructor, basePrototype, @@ -139,7 +141,7 @@ $.widget = function( name, base, prototype ) { }; $.widget.extend = function( target ) { - var input = slice.call( arguments, 1 ), + var input = widget_slice.call( arguments, 1 ), inputIndex = 0, inputLength = input.length, key, @@ -168,7 +170,7 @@ $.widget.bridge = function( name, object ) { var fullName = object.prototype.widgetFullName || name; $.fn[ name ] = function( options ) { var isMethodCall = typeof options === "string", - args = slice.call( arguments, 1 ), + args = widget_slice.call( arguments, 1 ), returnValue = this; // allow multiple hashes to be passed on init @@ -233,7 +235,7 @@ $.Widget.prototype = { _createWidget: function( options, element ) { element = $( element || this.defaultElement || this )[ 0 ]; this.element = $( element ); - this.uuid = uuid++; + this.uuid = widget_uuid++; this.eventNamespace = "." + this.widgetName + this.uuid; this.options = $.widget.extend( {}, this.options,