aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Nagel <info@felixnagel.com>2012-11-10 01:40:05 +0100
committerFelix Nagel <info@felixnagel.com>2012-11-10 01:40:05 +0100
commit7ce8e0515ea7cc513c3c065946c85cf2d1aa5652 (patch)
treea0337f9f7d8d0d27a7cdb78a63ee152d8357b32f
parent94b3a65c66e338fc6f697d13fc77d7f19b8666ae (diff)
parentd6c6b7dc3381432f50212b4f458931b2521ecb56 (diff)
downloadjquery-ui-7ce8e0515ea7cc513c3c065946c85cf2d1aa5652.tar.gz
jquery-ui-7ce8e0515ea7cc513c3c065946c85cf2d1aa5652.zip
Merge branch 'master' into selectmenu
-rw-r--r--.editorconfig5
-rw-r--r--.jshintrc6
-rw-r--r--build/.jshintrc13
-rw-r--r--build/release/changelog-shell32
-rw-r--r--build/release/release.js37
-rw-r--r--build/tasks/build.js7
-rw-r--r--build/tasks/testswarm.js26
-rw-r--r--demos/autocomplete/combobox.html1
-rw-r--r--demos/autocomplete/custom-data.html1
-rw-r--r--demos/button/icons.html2
-rw-r--r--demos/datepicker/localization.html2
-rw-r--r--demos/dialog/animated.html14
-rw-r--r--demos/dialog/default.html1
-rw-r--r--demos/dialog/modal-confirmation.html1
-rw-r--r--demos/dialog/modal-form.html1
-rw-r--r--demos/dialog/modal-message.html1
-rw-r--r--demos/dialog/modal.html1
-rw-r--r--demos/droppable/photo-manager.html4
-rw-r--r--demos/droppable/shopping-cart.html2
-rw-r--r--demos/menu/default.html57
-rw-r--r--demos/menu/icons.html44
-rw-r--r--demos/menu/index.html3
-rw-r--r--demos/menu/navigationmenu.html74
-rw-r--r--demos/menu/topalignmenu.html87
-rw-r--r--demos/position/cycler.html6
-rw-r--r--demos/position/default.html5
-rw-r--r--demos/slider/hotelrooms.html2
-rw-r--r--demos/slider/side-scroll.html1
-rw-r--r--demos/tooltip/custom-content.html3
-rw-r--r--demos/tooltip/forms.html2
-rw-r--r--external/jquery.bgiframe-2.1.2.js39
-rw-r--r--external/jquery.cookie.js89
-rw-r--r--external/jquery.metadata.js122
-rw-r--r--external/jshint.js2785
-rw-r--r--grunt.js18
-rw-r--r--jquery-1.8.2.js3328
-rw-r--r--package.json9
-rw-r--r--tests/.jshintrc29
-rw-r--r--tests/jquery-1.6.1.js106
-rw-r--r--tests/jquery-1.6.2.js110
-rw-r--r--tests/jquery-1.6.3.js108
-rw-r--r--tests/jquery-1.6.4.js108
-rw-r--r--tests/jquery-1.6.js130
-rw-r--r--tests/jquery-1.7.1.js82
-rw-r--r--tests/jquery-1.7.2.js2
-rw-r--r--tests/jquery-1.7.js82
-rw-r--r--tests/jquery-1.8.0.js2922
-rw-r--r--tests/jquery-1.8.1.js3058
-rw-r--r--tests/jquery-1.8.2.js3328
-rw-r--r--tests/jquery.simulate.js4
-rw-r--r--tests/unit/accordion/accordion.html3
-rw-r--r--tests/unit/accordion/accordion_common_deprecated.js29
-rw-r--r--tests/unit/accordion/accordion_deprecated.html140
-rw-r--r--tests/unit/accordion/accordion_deprecated.js342
-rw-r--r--tests/unit/accordion/accordion_options.js49
-rw-r--r--tests/unit/all-active.html72
-rw-r--r--tests/unit/all.html13
-rw-r--r--tests/unit/autocomplete/autocomplete_core.js7
-rw-r--r--tests/unit/autocomplete/autocomplete_events.js6
-rw-r--r--tests/unit/autocomplete/autocomplete_options.js2
-rw-r--r--tests/unit/button/button_events.js2
-rw-r--r--tests/unit/button/button_tickets.js8
-rw-r--r--tests/unit/core/core.html5
-rw-r--r--tests/unit/core/selector.js12
-rw-r--r--tests/unit/datepicker/datepicker.html12
-rw-r--r--tests/unit/datepicker/datepicker_core.js159
-rw-r--r--tests/unit/datepicker/datepicker_defaults.js4
-rw-r--r--tests/unit/datepicker/datepicker_events.js29
-rw-r--r--tests/unit/datepicker/datepicker_methods.js38
-rw-r--r--tests/unit/datepicker/datepicker_options.js310
-rw-r--r--tests/unit/datepicker/datepicker_test_helpers.js22
-rw-r--r--tests/unit/datepicker/datepicker_tickets.js88
-rw-r--r--tests/unit/dialog/dialog.html15
-rw-r--r--tests/unit/dialog/dialog_common.js2
-rw-r--r--tests/unit/dialog/dialog_core.js99
-rw-r--r--tests/unit/dialog/dialog_events.js253
-rw-r--r--tests/unit/dialog/dialog_methods.js72
-rw-r--r--tests/unit/dialog/dialog_options.js284
-rw-r--r--tests/unit/dialog/dialog_test_helpers.js45
-rw-r--r--tests/unit/dialog/dialog_tickets.js114
-rw-r--r--tests/unit/draggable/draggable.html14
-rw-r--r--tests/unit/draggable/draggable_common.js1
-rw-r--r--tests/unit/draggable/draggable_core.js58
-rw-r--r--tests/unit/draggable/draggable_events.js54
-rw-r--r--tests/unit/draggable/draggable_methods.js53
-rw-r--r--tests/unit/draggable/draggable_options.js674
-rw-r--r--tests/unit/draggable/draggable_test_helpers.js57
-rw-r--r--tests/unit/droppable/droppable.html11
-rw-r--r--tests/unit/droppable/droppable_common.js1
-rw-r--r--tests/unit/droppable/droppable_core.js21
-rw-r--r--tests/unit/droppable/droppable_events.js7
-rw-r--r--tests/unit/droppable/droppable_methods.js40
-rw-r--r--tests/unit/droppable/droppable_options.js13
-rw-r--r--tests/unit/droppable/droppable_test_helpers.js10
-rw-r--r--tests/unit/effects/effects.html3
-rw-r--r--tests/unit/effects/effects_core.js25
-rw-r--r--tests/unit/menu/menu_events.js30
-rw-r--r--tests/unit/menu/menu_methods.js11
-rw-r--r--tests/unit/menu/menu_options.js4
-rw-r--r--tests/unit/position/position.html3
-rw-r--r--tests/unit/position/position_core.js3
-rw-r--r--tests/unit/position/position_deprecated.html56
-rw-r--r--tests/unit/position/position_deprecated.js33
-rw-r--r--tests/unit/progressbar/progressbar_options.js18
-rw-r--r--tests/unit/resizable/resizable.html11
-rw-r--r--tests/unit/resizable/resizable_core.js68
-rw-r--r--tests/unit/resizable/resizable_events.js4
-rw-r--r--tests/unit/resizable/resizable_methods.js3
-rw-r--r--tests/unit/resizable/resizable_options.js66
-rw-r--r--tests/unit/resizable/resizable_test_helpers.js15
-rw-r--r--tests/unit/selectable/selectable.html11
-rw-r--r--tests/unit/selectable/selectable_common.js1
-rw-r--r--tests/unit/selectable/selectable_core.js15
-rw-r--r--tests/unit/selectable/selectable_events.js8
-rw-r--r--tests/unit/selectable/selectable_methods.js22
-rw-r--r--tests/unit/selectable/selectable_options.js25
-rw-r--r--tests/unit/selectable/selectable_test_helpers.js8
-rw-r--r--tests/unit/slider/slider.html10
-rw-r--r--tests/unit/slider/slider_events.js24
-rw-r--r--tests/unit/slider/slider_methods.js4
-rw-r--r--tests/unit/sortable/sortable.html27
-rw-r--r--tests/unit/sortable/sortable_common.js1
-rw-r--r--tests/unit/sortable/sortable_core.js8
-rw-r--r--tests/unit/sortable/sortable_events.js28
-rw-r--r--tests/unit/sortable/sortable_methods.js52
-rw-r--r--tests/unit/sortable/sortable_options.js7
-rw-r--r--tests/unit/sortable/sortable_test_helpers.js9
-rw-r--r--tests/unit/sortable/sortable_tickets.js46
-rw-r--r--tests/unit/spinner/spinner_options.js6
-rw-r--r--tests/unit/subsuite.js4
-rw-r--r--tests/unit/swarminject.js5
-rw-r--r--tests/unit/tabs/tabs.html3
-rw-r--r--tests/unit/tabs/tabs_common_deprecated.js32
-rw-r--r--tests/unit/tabs/tabs_core.js11
-rw-r--r--tests/unit/tabs/tabs_deprecated.html157
-rw-r--r--tests/unit/tabs/tabs_deprecated.js599
-rw-r--r--tests/unit/tabs/tabs_events.js96
-rw-r--r--tests/unit/tabs/tabs_methods.js12
-rw-r--r--tests/unit/tabs/tabs_options.js46
-rw-r--r--tests/unit/testsuite.js48
-rw-r--r--tests/unit/tooltip/tooltip.html5
-rw-r--r--tests/unit/tooltip/tooltip_common.js8
-rw-r--r--tests/unit/tooltip/tooltip_core.js63
-rw-r--r--tests/unit/tooltip/tooltip_events.js38
-rw-r--r--tests/unit/tooltip/tooltip_options.js53
-rw-r--r--tests/unit/widget/widget_core.js179
-rw-r--r--tests/unit/widget/widget_extend.js15
-rw-r--r--tests/visual/dialog/animated.html52
-rw-r--r--tests/visual/dialog/complex-dialogs.html94
-rw-r--r--tests/visual/dialog/form.html69
-rw-r--r--tests/visual/dialog/performance.html1
-rw-r--r--tests/visual/position/position_feedback.html29
-rw-r--r--tests/visual/tooltip/tooltip.html26
-rw-r--r--themes/base/jquery.ui.autocomplete.css6
-rw-r--r--themes/base/jquery.ui.core.css6
-rw-r--r--themes/base/jquery.ui.datepicker.css11
-rw-r--r--themes/base/jquery.ui.dialog.css2
-rw-r--r--themes/base/jquery.ui.spinner.css3
-rw-r--r--themes/base/jquery.ui.theme.css5
-rw-r--r--themes/base/jquery.ui.tooltip.css15
-rw-r--r--ui/.jshintrc2
-rw-r--r--ui/i18n/jquery.ui.datepicker-ar.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-az.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-bs.js10
-rw-r--r--ui/i18n/jquery.ui.datepicker-cy-GB.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-el.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-es.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-et.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-eu.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-fa.js6
-rw-r--r--ui/i18n/jquery.ui.datepicker-fr-CH.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-gl.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-hr.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-hy.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-id.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-is.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-ja.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-ko.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-ky.js24
-rw-r--r--ui/i18n/jquery.ui.datepicker-lt.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-lv.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-ml.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-ms.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-nl.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-pt-BR.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-pt.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-ru.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-th.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-tj.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-tr.js2
-rw-r--r--ui/i18n/jquery.ui.datepicker-uk.js2
-rw-r--r--ui/jquery.ui.accordion.js213
-rw-r--r--ui/jquery.ui.autocomplete.js21
-rw-r--r--ui/jquery.ui.button.js4
-rw-r--r--ui/jquery.ui.core.js142
-rw-r--r--ui/jquery.ui.datepicker.js274
-rw-r--r--ui/jquery.ui.dialog.js349
-rw-r--r--ui/jquery.ui.draggable.js111
-rw-r--r--ui/jquery.ui.droppable.js54
-rw-r--r--ui/jquery.ui.effect-highlight.js2
-rw-r--r--ui/jquery.ui.effect-scale.js30
-rw-r--r--ui/jquery.ui.effect.js78
-rw-r--r--ui/jquery.ui.menu.js47
-rw-r--r--ui/jquery.ui.mouse.js16
-rw-r--r--ui/jquery.ui.position.js40
-rw-r--r--ui/jquery.ui.progressbar.js83
-rw-r--r--ui/jquery.ui.resizable.js182
-rw-r--r--ui/jquery.ui.selectable.js54
-rw-r--r--ui/jquery.ui.slider.js15
-rw-r--r--ui/jquery.ui.sortable.js63
-rw-r--r--ui/jquery.ui.spinner.js5
-rw-r--r--ui/jquery.ui.tabs.js540
-rw-r--r--ui/jquery.ui.tooltip.js118
-rw-r--r--ui/jquery.ui.widget.js66
214 files changed, 11700 insertions, 13411 deletions
diff --git a/.editorconfig b/.editorconfig
index c94db9a8e..1ba4f5faa 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -9,3 +9,8 @@ end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
+
+[external/**]
+trim_trailing_whitespace = false
+insert_final_newline = varies
+end_of_line = varies
diff --git a/.jshintrc b/.jshintrc
index 99161bd4e..d6966c51d 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -3,10 +3,10 @@
"eqnull": true,
"eqeqeq": true,
"expr": true,
- "latedef": true,
"noarg": true,
+ "node": true,
"onevar": true,
- "smarttabs": true,
"trailing": true,
- "undef": true
+ "undef": true,
+ "unused": true
}
diff --git a/build/.jshintrc b/build/.jshintrc
deleted file mode 100644
index 9e6abf31d..000000000
--- a/build/.jshintrc
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "curly": true,
- "eqnull": true,
- "eqeqeq": true,
- "expr": true,
- "noarg": true,
- "node": true,
- "onevar": true,
- "smarttabs": true,
- "strict": false,
- "trailing": true,
- "undef": true
-}
diff --git a/build/release/changelog-shell b/build/release/changelog-shell
index 9c9df9350..9f0f9b436 100644
--- a/build/release/changelog-shell
+++ b/build/release/changelog-shell
@@ -24,54 +24,86 @@ DELETE EVERYTHING ABOVE THE FOLLOWING LINE
## Build
+
## Core &amp; Utilities
### UI Core
+
### Mouse
+
### Widget Factory
+
### Position
+
## Interactions
### Draggable
+
### Droppable
+
### Resizable
+
### Selectable
+
### Sortable
+
## Widgets
### Accordion
+
### Autocomplete
+
### Button
+
### Datepicker
+
### Dialog
+
+### Menu
+
+
### Progressbar
+
### Slider
+
+### Spinner
+
+
### Tabs
+
+### Tooltip
+
+
## Effects
+
### Individual effects
+
## CSS Framework
+
## Demos
+
## Website
+
### Download Builder
diff --git a/build/release/release.js b/build/release/release.js
index 77430d8d1..0e41702e9 100644
--- a/build/release/release.js
+++ b/build/release/release.js
@@ -1,5 +1,7 @@
#!/usr/bin/env node
-/*global cat:true cd:true cp:true echo:true exec:true exit:true ls:true*/
+/*global cat:true cd:true echo:true exec:true exit:true*/
+
+"use strict";
var baseDir, repoDir, prevVersion, newVersion, nextVersion, tagTime,
fs = require( "fs" ),
@@ -41,9 +43,6 @@ walk([
section( "gathering contributors" ),
gatherContributors,
- section( "generating quick download" ),
- generateQuickDownload,
-
section( "updating trac" ),
updateTrac,
confirm
@@ -261,34 +260,6 @@ function gatherContributors() {
echo( "Stored contributors in " + contributorsPath.cyan + "." );
}
-function generateQuickDownload() {
- var config,
- downloadDir = repoDir + "/node_modules/download.jqueryui.com",
- filename = "jquery-ui-" + newVersion + ".custom.zip",
- destination = baseDir + "/" + filename;
-
- cd( downloadDir );
-
- // Update jQuery UI version for download builder
- config = JSON.parse( cat( "config.json" ) );
- config.jqueryUi = newVersion;
- JSON.stringify( config ).to( "config.json" );
-
- // Generate quick download
- // TODO: Find a way to avoid having to clone jquery-ui inside download builder
- if ( exec( "grunt prepare build" ).code !== 0 ) {
- abort( "Error generating quick download." );
- }
- cp( downloadDir + "/release/" + filename, destination );
- // cp() doesn't have error handling, so check for the file
- if ( ls( destination ).length !== 1 ) {
- abort( "Error copying quick download." );
- }
-
- // Go back to repo directory for consistency
- cd( repoDir );
-}
-
function updateTrac() {
echo( newVersion.cyan + " was tagged at " + tagTime.cyan + "." );
echo( "Close the " + newVersion.cyan + " Milestone with the above date and time." );
@@ -423,7 +394,7 @@ function abort( msg ) {
function walk( methods ) {
var method = methods.shift();
- function next( error ) {
+ function next() {
if ( methods.length ) {
walk( methods );
}
diff --git a/build/tasks/build.js b/build/tasks/build.js
index 3f3dd31c5..18e427a56 100644
--- a/build/tasks/build.js
+++ b/build/tasks/build.js
@@ -1,6 +1,9 @@
module.exports = function( grunt ) {
-var path = require( "path" );
+"use strict";
+
+var path = require( "path" ),
+ fs = require( "fs" );
grunt.registerTask( "manifest", "Generate jquery.json manifest files", function() {
var pkg = grunt.config( "pkg" ),
@@ -143,7 +146,7 @@ grunt.registerMultiTask( "zip", "Create a zip file for release", function() {
opts: {
cwd: 'dist'
}
- }, function( err, result ) {
+ }, function( err ) {
if ( err ) {
grunt.log.error( err );
done();
diff --git a/build/tasks/testswarm.js b/build/tasks/testswarm.js
index 34c17d4f6..f76c5570d 100644
--- a/build/tasks/testswarm.js
+++ b/build/tasks/testswarm.js
@@ -1,6 +1,7 @@
-/*jshint node: true */
module.exports = function( grunt ) {
+"use strict";
+
var versions = {
"git": "git",
"1.8": "1.8.0 1.8.1 1.8.2",
@@ -9,26 +10,23 @@ var versions = {
},
tests = {
"Accordion": "accordion/accordion.html",
- "Accordion_deprecated": "accordion/accordion_deprecated.html",
"Autocomplete": "autocomplete/autocomplete.html",
"Button": "button/button.html",
"Core": "core/core.html",
- //"datepicker/datepicker.html",
- //"dialog/dialog.html",
- //"draggable/draggable.html",
- //"droppable/droppable.html",
+ "Datepicker": "datepicker/datepicker.html",
+ "Dialog": "dialog/dialog.html",
+ "Draggable": "draggable/draggable.html",
+ "Droppable": "droppable/droppable.html",
"Effects": "effects/effects.html",
"Menu": "menu/menu.html",
"Position": "position/position.html",
- "Position_deprecated": "position/position_deprecated.html",
"Progressbar": "progressbar/progressbar.html",
- //"resizable/resizable.html",
- //"selectable/selectable.html",
- //"slider/slider.html",
- //"sortable/sortable.html",
+ "Resizable": "resizable/resizable.html",
+ "Selectable": "selectable/selectable.html",
+ "Slider": "slider/slider.html",
+ "Sortable": "sortable/sortable.html",
"Spinner": "spinner/spinner.html",
"Tabs": "tabs/tabs.html",
- "Tabs_deprecated": "tabs/tabs_deprecated.html",
"Tooltip": "tooltip/tooltip.html",
"Widget": "widget/widget.html"
};
@@ -53,9 +51,9 @@ function submit( commit, tests, configFile, version, done ) {
authToken: config.authToken,
jobName: 'jQuery UI ' + version + '#<a href="https://github.com/jquery/jquery-ui/commit/' + commit + '">' + commit.substr( 0, 10 ) + '</a>',
runMax: config.runMax,
- "runNames[]": Object.keys(tests),
+ "runNames[]": Object.keys( tests ),
"runUrls[]": testUrls,
- "browserSets[]": ["popular"]
+ "browserSets[]": [ "popular-no-ie6" ]
});
}
diff --git a/demos/autocomplete/combobox.html b/demos/autocomplete/combobox.html
index cc43f4527..c8270c2d8 100644
--- a/demos/autocomplete/combobox.html
+++ b/demos/autocomplete/combobox.html
@@ -111,7 +111,6 @@
input.data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li>" )
- .data( "item.autocomplete", item )
.append( "<a>" + item.label + "</a>" )
.appendTo( ul );
};
diff --git a/demos/autocomplete/custom-data.html b/demos/autocomplete/custom-data.html
index 1e64df047..df191b899 100644
--- a/demos/autocomplete/custom-data.html
+++ b/demos/autocomplete/custom-data.html
@@ -68,7 +68,6 @@
})
.data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li>" )
- .data( "item.autocomplete", item )
.append( "<a>" + item.label + "<br>" + item.desc + "</a>" )
.appendTo( ul );
};
diff --git a/demos/button/icons.html b/demos/button/icons.html
index 8c4bf5a30..78f01d707 100644
--- a/demos/button/icons.html
+++ b/demos/button/icons.html
@@ -43,7 +43,7 @@
<button>Button with two icons and no text</button>
<div class="demo-description">
-<p>Some buttons with various combinations of text and icons, here specified via metadata.</p>
+<p>Some buttons with various combinations of text and icons.</p>
</div>
</body>
</html>
diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html
index 4fd7a1c46..f6d00631a 100644
--- a/demos/datepicker/localization.html
+++ b/demos/datepicker/localization.html
@@ -46,6 +46,7 @@
<script src="../../ui/i18n/jquery.ui.datepicker-kk.js"></script>
<script src="../../ui/i18n/jquery.ui.datepicker-km.js"></script>
<script src="../../ui/i18n/jquery.ui.datepicker-ko.js"></script>
+ <script src="../../ui/i18n/jquery.ui.datepicker-ky.js"></script>
<script src="../../ui/i18n/jquery.ui.datepicker-lb.js"></script>
<script src="../../ui/i18n/jquery.ui.datepicker-lt.js"></script>
<script src="../../ui/i18n/jquery.ui.datepicker-lv.js"></script>
@@ -134,6 +135,7 @@
<option value="kk">Kazakhstan (Kazakh)</option>
<option value="km">Khmer</option>
<option value="ko">Korean (&#54620;&#44397;&#50612;)</option>
+ <option value="ky">Kyrgyzstan (Kyrgyz)</option>
<option value="lv">Latvian (Latvie&ouml;u Valoda)</option>
<option value="lt">Lithuanian (lietuviu kalba)</option>
<option value="lb">Luxembourgish</option>
diff --git a/demos/dialog/animated.html b/demos/dialog/animated.html
index 8a27150de..92d7b642d 100644
--- a/demos/dialog/animated.html
+++ b/demos/dialog/animated.html
@@ -5,7 +5,6 @@
<title>jQuery UI Dialog - Animation</title>
<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
<script src="../../jquery-1.8.2.js"></script>
- <script src="../../external/jquery.bgiframe-2.1.2.js"></script>
<script src="../../ui/jquery.ui.core.js"></script>
<script src="../../ui/jquery.ui.widget.js"></script>
<script src="../../ui/jquery.ui.mouse.js"></script>
@@ -18,18 +17,21 @@
<script src="../../ui/jquery.ui.effect-explode.js"></script>
<link rel="stylesheet" href="../demos.css">
<script>
- // increase the default animation speed to exaggerate the effect
- $.fx.speeds._default = 1000;
$(function() {
$( "#dialog" ).dialog({
autoOpen: false,
- show: "blind",
- hide: "explode"
+ show: {
+ effect: "blind",
+ duration: 1000
+ },
+ hide: {
+ effect: "explode",
+ duration: 1000
+ }
});
$( "#opener" ).click(function() {
$( "#dialog" ).dialog( "open" );
- return false;
});
});
</script>
diff --git a/demos/dialog/default.html b/demos/dialog/default.html
index 5dcb1a05c..19cf912e2 100644
--- a/demos/dialog/default.html
+++ b/demos/dialog/default.html
@@ -5,7 +5,6 @@
<title>jQuery UI Dialog - Default functionality</title>
<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
<script src="../../jquery-1.8.2.js"></script>
- <script src="../../external/jquery.bgiframe-2.1.2.js"></script>
<script src="../../ui/jquery.ui.core.js"></script>
<script src="../../ui/jquery.ui.widget.js"></script>
<script src="../../ui/jquery.ui.mouse.js"></script>
diff --git a/demos/dialog/modal-confirmation.html b/demos/dialog/modal-confirmation.html
index cca3b296d..b9bf6396f 100644
--- a/demos/dialog/modal-confirmation.html
+++ b/demos/dialog/modal-confirmation.html
@@ -5,7 +5,6 @@
<title>jQuery UI Dialog - Modal confirmation</title>
<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
<script src="../../jquery-1.8.2.js"></script>
- <script src="../../external/jquery.bgiframe-2.1.2.js"></script>
<script src="../../ui/jquery.ui.core.js"></script>
<script src="../../ui/jquery.ui.widget.js"></script>
<script src="../../ui/jquery.ui.mouse.js"></script>
diff --git a/demos/dialog/modal-form.html b/demos/dialog/modal-form.html
index 48452f862..1c0cd6fc3 100644
--- a/demos/dialog/modal-form.html
+++ b/demos/dialog/modal-form.html
@@ -5,7 +5,6 @@
<title>jQuery UI Dialog - Modal form</title>
<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
<script src="../../jquery-1.8.2.js"></script>
- <script src="../../external/jquery.bgiframe-2.1.2.js"></script>
<script src="../../ui/jquery.ui.core.js"></script>
<script src="../../ui/jquery.ui.widget.js"></script>
<script src="../../ui/jquery.ui.mouse.js"></script>
diff --git a/demos/dialog/modal-message.html b/demos/dialog/modal-message.html
index d44331017..3c877b26e 100644
--- a/demos/dialog/modal-message.html
+++ b/demos/dialog/modal-message.html
@@ -5,7 +5,6 @@
<title>jQuery UI Dialog - Modal message</title>
<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
<script src="../../jquery-1.8.2.js"></script>
- <script src="../../external/jquery.bgiframe-2.1.2.js"></script>
<script src="../../ui/jquery.ui.core.js"></script>
<script src="../../ui/jquery.ui.widget.js"></script>
<script src="../../ui/jquery.ui.mouse.js"></script>
diff --git a/demos/dialog/modal.html b/demos/dialog/modal.html
index 2b1ac2574..9bb6d95b2 100644
--- a/demos/dialog/modal.html
+++ b/demos/dialog/modal.html
@@ -5,7 +5,6 @@
<title>jQuery UI Dialog - Basic modal</title>
<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
<script src="../../jquery-1.8.2.js"></script>
- <script src="../../external/jquery.bgiframe-2.1.2.js"></script>
<script src="../../ui/jquery.ui.core.js"></script>
<script src="../../ui/jquery.ui.widget.js"></script>
<script src="../../ui/jquery.ui.mouse.js"></script>
diff --git a/demos/droppable/photo-manager.html b/demos/droppable/photo-manager.html
index 315473761..7da5f5370 100644
--- a/demos/droppable/photo-manager.html
+++ b/demos/droppable/photo-manager.html
@@ -15,7 +15,7 @@
<script src="../../ui/jquery.ui.dialog.js"></script>
<link rel="stylesheet" href="../demos.css">
<style>
- #gallery { float: left; width: 65%; min-height: 12em; } * html #gallery { height: 12em; } /* IE6 */
+ #gallery { float: left; width: 65%; min-height: 12em; }
.gallery.custom-state-active { background: #eee; }
.gallery li { float: left; width: 96px; padding: 0.4em; margin: 0 0.4em 0.4em 0; text-align: center; }
.gallery li h5 { margin: 0 0 0.4em; cursor: move; }
@@ -23,7 +23,7 @@
.gallery li a.ui-icon-zoomin { float: left; }
.gallery li img { width: 100%; cursor: move; }
- #trash { float: right; width: 32%; min-height: 18em; padding: 1%;} * html #trash { height: 18em; } /* IE6 */
+ #trash { float: right; width: 32%; min-height: 18em; padding: 1%; }
#trash h4 { line-height: 16px; margin: 0 0 0.4em; }
#trash h4 .ui-icon { float: left; }
#trash .gallery h5 { display: none; }
diff --git a/demos/droppable/shopping-cart.html b/demos/droppable/shopping-cart.html
index 60468aab7..7c33a3d4b 100644
--- a/demos/droppable/shopping-cart.html
+++ b/demos/droppable/shopping-cart.html
@@ -88,7 +88,7 @@
</div>
<div class="demo-description">
-<p>Demonstrate how to use an accordion to structure products into a catalog and make use drag and drop for adding them to a shopping cart, where they are sortable.</p>
+<p>Demonstrate how to use an accordion to structure products into a catalog and make use of drag and drop for adding them to a shopping cart, where they are sortable.</p>
</div>
</body>
</html>
diff --git a/demos/menu/default.html b/demos/menu/default.html
index 27b1f249c..5b535856b 100644
--- a/demos/menu/default.html
+++ b/demos/menu/default.html
@@ -7,6 +7,7 @@
<script src="../../jquery-1.8.2.js"></script>
<script src="../../ui/jquery.ui.core.js"></script>
<script src="../../ui/jquery.ui.widget.js"></script>
+ <script src="../../ui/jquery.ui.position.js"></script>
<script src="../../ui/jquery.ui.menu.js"></script>
<link rel="stylesheet" href="../demos.css">
<script>
@@ -14,29 +15,53 @@
$( "#menu" ).menu();
});
</script>
+ <style>
+ .ui-menu { width: 150px; }
+ </style>
</head>
<body>
<ul id="menu">
- <li><a href="#Aberdeen">Aberdeen</a></li>
- <li><a href="#Ada">Ada</a></li>
- <li><a href="#Adamsville">Adamsville</a></li>
- <li><a href="#Addyston">Addyston</a></li>
- <li><a href="#Adelphi">Adelphi</a></li>
- <li><a href="#Adena">Adena</a></li>
- <li><a href="#Adrian">Adrian</a></li>
- <li><a href="#Akron">Akron</a></li>
- <li><a href="#Albany">Albany</a></li>
- <li><a href="#Alexandria">Alexandria</a></li>
- <li><a href="#Alger">Alger</a></li>
- <li><a href="#Alledonia">Alledonia</a></li>
- <li><a href="#Alliance">Alliance</a></li>
- <li><a href="#Alpha">Alpha</a></li>
- <li><a href="#Alvada">Alvada</a></li>
+ <li class="ui-state-disabled"><a href="#">Aberdeen</a></li>
+ <li><a href="#">Ada</a></li>
+ <li><a href="#">Adamsville</a></li>
+ <li><a href="#">Addyston</a></li>
+ <li>
+ <a href="#">Delphi</a>
+ <ul>
+ <li class="ui-state-disabled"><a href="#">Ada</a></li>
+ <li><a href="#">Saarland</a></li>
+ <li><a href="#">Salzburg</a></li>
+ </ul>
+ </li>
+ <li><a href="#">Saarland</a></li>
+ <li>
+ <a href="#">Salzburg</a>
+ <ul>
+ <li>
+ <a href="#">Delphi</a>
+ <ul>
+ <li><a href="#">Ada</a></li>
+ <li><a href="#">Saarland</a></li>
+ <li><a href="#">Salzburg</a></li>
+ </ul>
+ </li>
+ <li>
+ <a href="#">Delphi</a>
+ <ul>
+ <li><a href="#">Ada</a></li>
+ <li><a href="#">Saarland</a></li>
+ <li><a href="#">Salzburg</a></li>
+ </ul>
+ </li>
+ <li><a href="#">Perch</a></li>
+ </ul>
+ </li>
+ <li class="ui-state-disabled"><a href="#">Amesville</a></li>
</ul>
<div class="demo-description">
-<p>A menu with the default configuration. A list is transformed, adding theming, mouse and keyboard navigation support. Try to tab to the menu then use the cursor keys to navigate.</p>
+<p>A menu with the default configuration, disabled items and nested menus. A list is transformed, adding theming, mouse and keyboard navigation support. Try to tab to the menu then use the cursor keys to navigate.</p>
</div>
</body>
</html>
diff --git a/demos/menu/icons.html b/demos/menu/icons.html
new file mode 100644
index 000000000..56cf242f3
--- /dev/null
+++ b/demos/menu/icons.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Menu - Icons</title>
+ <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
+ <script src="../../jquery-1.8.2.js"></script>
+ <script src="../../ui/jquery.ui.core.js"></script>
+ <script src="../../ui/jquery.ui.widget.js"></script>
+ <script src="../../ui/jquery.ui.position.js"></script>
+ <script src="../../ui/jquery.ui.menu.js"></script>
+ <link rel="stylesheet" href="../demos.css">
+ <script>
+ $(function() {
+ $( "#menu" ).menu();
+ });
+ </script>
+ <style>
+ .ui-menu { width: 150px; }
+ </style>
+</head>
+<body>
+
+<ul id="menu">
+ <li><a href="#"><span class="ui-icon ui-icon-disk"></span>Save</a></li>
+ <li><a href="#"><span class="ui-icon ui-icon-zoomin"></span>Zoom In</a></li>
+ <li><a href="#"><span class="ui-icon ui-icon-zoomout"></span>Zoom Out</a></li>
+ <li class="ui-state-disabled"><a href="#"><span class="ui-icon ui-icon-print"></span>Print...</a></li>
+ <li>
+ <a href="#">Playback</a>
+ <ul>
+ <li><a href="#"><span class="ui-icon ui-icon-seek-start"></span>Prev</a></li>
+ <li><a href="#"><span class="ui-icon ui-icon-stop"></span>Stop</a></li>
+ <li><a href="#"><span class="ui-icon ui-icon-play"></span>Play</a></li>
+ <li><a href="#"><span class="ui-icon ui-icon-seek-end"></span>Next</a></li>
+ </ul>
+ </li>
+</ul>
+
+<div class="demo-description">
+<p>A menu with the default configuration, showing how to use a menu with icons.</p>
+</div>
+</body>
+</html>
diff --git a/demos/menu/index.html b/demos/menu/index.html
index 07556c6ec..40e9e0b54 100644
--- a/demos/menu/index.html
+++ b/demos/menu/index.html
@@ -8,8 +8,7 @@
<ul>
<li><a href="default.html">Default functionality</a></li>
- <li><a href="topalignmenu.html">Top-aligned sub menus</a></li>
- <li><a href="navigationmenu.html">Navigation menu</a></li>
+ <li><a href="icons.html">Icons</a></li>
</ul>
</body>
diff --git a/demos/menu/navigationmenu.html b/demos/menu/navigationmenu.html
deleted file mode 100644
index c2bb307ba..000000000
--- a/demos/menu/navigationmenu.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>jQuery UI Menu - Navigation Menu</title>
- <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
- <script src="../../jquery-1.8.2.js"></script>
- <script src="../../ui/jquery.ui.core.js"></script>
- <script src="../../ui/jquery.ui.widget.js"></script>
- <script src="../../ui/jquery.ui.position.js"></script>
- <script src="../../ui/jquery.ui.menu.js"></script>
- <link rel="stylesheet" href="../demos.css">
- <script>
- $(function() {
- $( "#menu" ).menu({
- select: function( event, ui ) {
- var link = ui.item.children( "a:first" );
- if ( link.attr( "target" ) || event.metaKey || event.shiftKey || event.ctrlKey ) {
- return;
- }
- location.href = link.attr( "href" );
- }
- });
- });
- </script>
- <style>
- .ui-menu { width: 200px; margin-bottom: 2em; }
- </style>
-</head>
-<body>
-
-<ul id="menu">
- <li><a href="?Aberdeen">Aberdeen</a></li>
- <li><a href="?Ada">Ada</a></li>
- <li><a href="?Adamsville">Adamsville</a></li>
- <li><a href="?Addyston">Addyston</a></li>
- <li>
- <a href="?Delphi">Delphi</a>
- <ul>
- <li><a href="?Ada">Ada</a></li>
- <li><a href="?Saarland">Saarland</a></li>
- <li><a href="?Salzburg">Salzburg</a></li>
- </ul>
- </li>
- <li><a href="?Saarland">Saarland</a></li>
- <li>
- <a href="?Salzburg">Salzburg</a>
- <ul>
- <li>
- <a href="?Delphi">Delphi</a>
- <ul>
- <li><a href="?Ada">Ada</a></li>
- <li><a href="?Saarland">Saarland</a></li>
- <li><a href="?Salzburg">Salzburg</a></li>
- </ul>
- </li>
- <li>
- <a href="?Delphi">Delphi</a>
- <ul>
- <li><a href="?Ada">Ada</a></li>
- <li><a href="?Saarland">Saarland</a></li>
- <li><a href="?Salzburg">Salzburg</a></li>
- </ul>
- </li>
- <li><a href="?Perch">Perch</a></li>
- </ul>
- </li>
-</ul>
-
-<div class="demo-description">
-<p>A navigation menu. A list is transformed, adding theming, mouse and keyboard navigation support. Try to tab to the menu then use the cursor keys to navigate.</p>
-</div>
-</body>
-</html>
diff --git a/demos/menu/topalignmenu.html b/demos/menu/topalignmenu.html
deleted file mode 100644
index 4f34b98c2..000000000
--- a/demos/menu/topalignmenu.html
+++ /dev/null
@@ -1,87 +0,0 @@
-<!doctype html>
-<html>
-<head>
- <meta charset="utf-8">
- <title>Menu Demo: Top-aligned Menu</title>
- <link rel="stylesheet" href="../demos.css">
- <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
- <script src="../../jquery-1.8.2.js"></script>
- <script src="../../ui/jquery.ui.core.js"></script>
- <script src="../../ui/jquery.ui.widget.js"></script>
- <script src="../../ui/jquery.ui.position.js"></script>
- <script src="../../ui/jquery.ui.menu.js"></script>
- <script>
- $(function() {
- $( "#menu" ).menu({
- position: { of: "ul:has(a.ui-state-focus):last" },
- icons: {
- submenu: "ui-icon-carat-1-e"
- }
- });
- });
- </script>
- <style>
- .ui-menu { width: 200px; margin-bottom: 2em; }
- </style>
-</head>
-<body>
-
-<ul id="menu">
- <li><a href="#">Aberdeen</a></li>
- <li><a href="#">Ada</a></li>
- <li><a href="#">Adamsville</a></li>
- <li><a href="#">Addyston</a></li>
- <li>
- <a href="#">Delphi</a>
- <ul>
- <li><a href="#">Ada</a></li>
- <li><a href="#">Saarland</a></li>
- <li><a href="#">Salzburg</a></li>
- </ul>
- </li>
- <li><a href="#">Saarland</a></li>
- <li>
- <a href="#">Salzburg</a>
- <ul>
- <li>
- <a href="#">Delphi</a>
- <ul>
- <li><a href="#">Ada</a></li>
- <li><a href="#">Saarland</a></li>
- <li><a href="#">Salzburg</a></li>
- </ul>
- </li>
- <li>
- <a href="#">Adamsville</a>
- <ul>
- <li><a href="#">Aberdeen</a></li>
- <li><a href="#">Ada</a></li>
- <li><a href="#">Adamsville</a></li>
- <li><a href="#">Addyston</a></li>
- <li>
- <a href="#">Delphi</a>
- <ul>
- <li><a href="#">Ada</a></li>
- <li><a href="#">Saarland</a></li>
- <li><a href="#">Salzburg</a></li>
- </ul>
- </li>
- <li><a href="#">Saarland</a></li>
- </ul>
- </li>
- <li><a href="#">Perch</a>
- <ul>
- <li><a href="#">Addyston</a></li>
- <li><a href="#">Delphi</a></li>
- <li><a href="#">Perch</a></li>
- </ul>
- </li>
- </ul>
- </li>
-</ul>
-
-<div class="demo-description">
-<p>Menus can use custom positioning. There is a delay before activing an item on hover and a delay before closing a menu on mouse out to allow for moving to a submenu that is not touching its parent item.</p>
-</div>
-</body>
-</html>
diff --git a/demos/position/cycler.html b/demos/position/cycler.html
index 2c421211f..dc9c8a0bd 100644
--- a/demos/position/cycler.html
+++ b/demos/position/cycler.html
@@ -10,6 +10,9 @@
<script src="../../ui/jquery.ui.position.js"></script>
<link rel="stylesheet" href="../demos.css">
<style>
+ body {
+ margin: 0;
+ }
#container {
overflow: hidden;
position: relative;
@@ -96,10 +99,9 @@
</div>
<div class="demo-description">
-<p>A prototype for the <a href="http://wiki.jqueryui.com/Photoviewer">Photoviewer</a> using Position to place images at the center, left and right and cycle them.
+<p>A photoviewer prototype using Position to place images at the center, left and right and cycle them.
<br>Use the links at the top to cycle, or click on the images on the left and right.
<br>Note how the images are repositioned when resizing the window.
-<br>Warning: Doesn't currently work inside the demo viewer; open in a new window instead!</p>
</div>
</body>
</html>
diff --git a/demos/position/default.html b/demos/position/default.html
index 223788b1f..48fd07e35 100644
--- a/demos/position/default.html
+++ b/demos/position/default.html
@@ -48,7 +48,6 @@
of: $( "#parent" ),
my: $( "#my_horizontal" ).val() + " " + $( "#my_vertical" ).val(),
at: $( "#at_horizontal" ).val() + " " + $( "#at_vertical" ).val(),
- offset: $( "#offset" ).val(),
collision: $( "#collision_horizontal" ).val() + " " + $( "#collision_vertical" ).val()
});
}
@@ -114,10 +113,6 @@
</select>
</div>
<div style="padding-bottom: 20px;">
- <b>offset:</b>
- <input id="offset">
- </div>
- <div style="padding-bottom: 20px;">
<b>collision:</b>
<select id="collision_horizontal">
<option value="flip">flip</option>
diff --git a/demos/slider/hotelrooms.html b/demos/slider/hotelrooms.html
index d866261b5..05675e1fa 100644
--- a/demos/slider/hotelrooms.html
+++ b/demos/slider/hotelrooms.html
@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
- <title>jQuery UI Slider - Range with fixed minimum</title>
+ <title>jQuery UI Slider - Slider bound to select</title>
<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
<script src="../../jquery-1.8.2.js"></script>
<script src="../../ui/jquery.ui.core.js"></script>
diff --git a/demos/slider/side-scroll.html b/demos/slider/side-scroll.html
index 4ca49b9c2..58188d8f3 100644
--- a/demos/slider/side-scroll.html
+++ b/demos/slider/side-scroll.html
@@ -14,7 +14,6 @@
.scroll-pane { overflow: auto; width: 99%; float:left; }
.scroll-content { width: 2440px; float: left; }
.scroll-content-item { width: 100px; height: 100px; float: left; margin: 10px; font-size: 3em; line-height: 96px; text-align: center; }
- * html .scroll-content-item { display: inline; } /* IE6 float double margin bug */
.scroll-bar-wrap { clear: left; padding: 0 4px 0 2px; margin: 0 -1px -1px -1px; }
.scroll-bar-wrap .ui-slider { background: none; border:0; height: 2em; margin: 0 auto; }
.scroll-bar-wrap .ui-handle-helper-parent { position: relative; width: 100%; height: 100%; margin: 0 auto; }
diff --git a/demos/tooltip/custom-content.html b/demos/tooltip/custom-content.html
index 93172524a..20039e2b8 100644
--- a/demos/tooltip/custom-content.html
+++ b/demos/tooltip/custom-content.html
@@ -22,6 +22,9 @@
width: 350px;
height: 350px;
}
+ .ui-tooltip {
+ max-width: 350px;
+ }
</style>
<script>
$(function() {
diff --git a/demos/tooltip/forms.html b/demos/tooltip/forms.html
index da3affa2d..0aef106c9 100644
--- a/demos/tooltip/forms.html
+++ b/demos/tooltip/forms.html
@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
- <title>jQuery UI Tooltip - Default demo</title>
+ <title>jQuery UI Tooltip - Forms</title>
<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
<script src="../../jquery-1.8.2.js"></script>
<script src="../../ui/jquery.ui.core.js"></script>
diff --git a/external/jquery.bgiframe-2.1.2.js b/external/jquery.bgiframe-2.1.2.js
deleted file mode 100644
index 5cd38bb1d..000000000
--- a/external/jquery.bgiframe-2.1.2.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
- * Licensed under the MIT License (LICENSE.txt).
- *
- * Version 2.1.2
- */
-
-(function($){
-
-$.fn.bgiframe = ($.browser.msie && /msie 6\.0/i.test(navigator.userAgent) ? function(s) {
- s = $.extend({
- top : 'auto', // auto == .currentStyle.borderTopWidth
- left : 'auto', // auto == .currentStyle.borderLeftWidth
- width : 'auto', // auto == offsetWidth
- height : 'auto', // auto == offsetHeight
- opacity : true,
- src : 'javascript:false;'
- }, s);
- var html = '<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+
- 'style="display:block;position:absolute;z-index:-1;'+
- (s.opacity !== false?'filter:Alpha(Opacity=\'0\');':'')+
- 'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+
- 'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+
- 'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+
- 'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+
- '"/>';
- return this.each(function() {
- if ( $(this).children('iframe.bgiframe').length === 0 )
- this.insertBefore( document.createElement(html), this.firstChild );
- });
-} : function() { return this; });
-
-// old alias
-$.fn.bgIframe = $.fn.bgiframe;
-
-function prop(n) {
- return n && n.constructor === Number ? n + 'px' : n;
-}
-
-})(jQuery); \ No newline at end of file
diff --git a/external/jquery.cookie.js b/external/jquery.cookie.js
deleted file mode 100644
index 7b3e70125..000000000
--- a/external/jquery.cookie.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/*jslint browser: true */ /*global jQuery: true */
-
-/**
- * jQuery Cookie plugin
- *
- * Copyright (c) 2010 Klaus Hartl (stilbuero.de)
- * Dual licensed under the MIT and GPL licenses:
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- *
- */
-
-// TODO JsDoc
-
-/**
- * Create a cookie with the given key and value and other optional parameters.
- *
- * @example $.cookie('the_cookie', 'the_value');
- * @desc Set the value of a cookie.
- * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
- * @desc Create a cookie with all available options.
- * @example $.cookie('the_cookie', 'the_value');
- * @desc Create a session cookie.
- * @example $.cookie('the_cookie', null);
- * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
- * used when the cookie was set.
- *
- * @param String key The key of the cookie.
- * @param String value The value of the cookie.
- * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
- * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
- * If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
- * If set to null or omitted, the cookie will be a session cookie and will not be retained
- * when the the browser exits.
- * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
- * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
- * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
- * require a secure protocol (like HTTPS).
- * @type undefined
- *
- * @name $.cookie
- * @cat Plugins/Cookie
- * @author Klaus Hartl/klaus.hartl@stilbuero.de
- */
-
-/**
- * Get the value of a cookie with the given key.
- *
- * @example $.cookie('the_cookie');
- * @desc Get the value of a cookie.
- *
- * @param String key The key of the cookie.
- * @return The value of the cookie.
- * @type String
- *
- * @name $.cookie
- * @cat Plugins/Cookie
- * @author Klaus Hartl/klaus.hartl@stilbuero.de
- */
-jQuery.cookie = function (key, value, options) {
-
- // key and value given, set cookie...
- if (arguments.length > 1 && (value === null || typeof value !== "object")) {
- options = jQuery.extend({}, options);
-
- if (value === null) {
- options.expires = -1;
- }
-
- if (typeof options.expires === 'number') {
- var days = options.expires, t = options.expires = new Date();
- t.setDate(t.getDate() + days);
- }
-
- return (document.cookie = [
- encodeURIComponent(key), '=',
- options.raw ? String(value) : encodeURIComponent(String(value)),
- options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
- options.path ? '; path=' + options.path : '',
- options.domain ? '; domain=' + options.domain : '',
- options.secure ? '; secure' : ''
- ].join(''));
- }
-
- // key and possibly options given, get cookie...
- options = value || {};
- var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
- return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
-};
diff --git a/external/jquery.metadata.js b/external/jquery.metadata.js
deleted file mode 100644
index ad8bfba40..000000000
--- a/external/jquery.metadata.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Metadata - jQuery plugin for parsing metadata from elements
- *
- * Copyright (c) 2006 John Resig, Yehuda Katz, J�örn Zaefferer, Paul McLanahan
- *
- * Dual licensed under the MIT and GPL licenses:
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- *
- * Revision: $Id: jquery.metadata.js 4187 2007-12-16 17:15:27Z joern.zaefferer $
- *
- */
-
-/**
- * Sets the type of metadata to use. Metadata is encoded in JSON, and each property
- * in the JSON will become a property of the element itself.
- *
- * There are three supported types of metadata storage:
- *
- * attr: Inside an attribute. The name parameter indicates *which* attribute.
- *
- * class: Inside the class attribute, wrapped in curly braces: { }
- *
- * elem: Inside a child element (e.g. a script tag). The
- * name parameter indicates *which* element.
- *
- * The metadata for an element is loaded the first time the element is accessed via jQuery.
- *
- * As a result, you can define the metadata type, use $(expr) to load the metadata into the elements
- * matched by expr, then redefine the metadata type and run another $(expr) for other elements.
- *
- * @name $.metadata.setType
- *
- * @example <p id="one" class="some_class {item_id: 1, item_label: 'Label'}">This is a p</p>
- * @before $.metadata.setType("class")
- * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
- * @desc Reads metadata from the class attribute
- *
- * @example <p id="one" class="some_class" data="{item_id: 1, item_label: 'Label'}">This is a p</p>
- * @before $.metadata.setType("attr", "data")
- * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
- * @desc Reads metadata from a "data" attribute
- *
- * @example <p id="one" class="some_class"><script>{item_id: 1, item_label: 'Label'}</script>This is a p</p>
- * @before $.metadata.setType("elem", "script")
- * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
- * @desc Reads metadata from a nested script element
- *
- * @param String type The encoding type
- * @param String name The name of the attribute to be used to get metadata (optional)
- * @cat Plugins/Metadata
- * @descr Sets the type of encoding to be used when loading metadata for the first time
- * @type undefined
- * @see metadata()
- */
-
-(function($) {
-
-$.extend({
- metadata : {
- defaults : {
- type: 'class',
- name: 'metadata',
- cre: /({.*})/,
- single: 'metadata'
- },
- setType: function( type, name ){
- this.defaults.type = type;
- this.defaults.name = name;
- },
- get: function( elem, opts ){
- var settings = $.extend({},this.defaults,opts);
- // check for empty string in single property
- if ( !settings.single.length ) settings.single = 'metadata';
-
- var data = $.data(elem, settings.single);
- // returned cached data if it already exists
- if ( data ) return data;
-
- data = "{}";
-
- if ( settings.type == "class" ) {
- var m = settings.cre.exec( elem.className );
- if ( m )
- data = m[1];
- } else if ( settings.type == "elem" ) {
- if( !elem.getElementsByTagName )
- return undefined;
- var e = elem.getElementsByTagName(settings.name);
- if ( e.length )
- data = $.trim(e[0].innerHTML);
- } else if ( elem.getAttribute != undefined ) {
- var attr = elem.getAttribute( settings.name );
- if ( attr )
- data = attr;
- }
-
- if ( data.indexOf( '{' ) <0 )
- data = "{" + data + "}";
-
- data = eval("(" + data + ")");
-
- $.data( elem, settings.single, data );
- return data;
- }
- }
-});
-
-/**
- * Returns the metadata object for the first member of the jQuery object.
- *
- * @name metadata
- * @descr Returns element's metadata object
- * @param Object opts An object contianing settings to override the defaults
- * @type jQuery
- * @cat Plugins/Metadata
- */
-$.fn.metadata = function( opts ){
- return $.metadata.get( this[0], opts );
-};
-
-})(jQuery); \ No newline at end of file
diff --git a/external/jshint.js b/external/jshint.js
index 5bf937c4b..8f06d9be0 100644
--- a/external/jshint.js
+++ b/external/jshint.js
@@ -1,8 +1,8 @@
/*!
* JSHint, by JSHint Community.
*
- * Licensed under the same slightly modified MIT license that JSLint is.
- * It stops evil-doers everywhere.
+ * This file (and this file only) is licensed under the same slightly modified
+ * MIT license that JSLint is. It stops evil-doers everywhere.
*
* JSHint is a derivative work of JSLint:
*
@@ -28,8 +28,6 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
- * JSHint was forked from 2010-12-16 edition of JSLint.
- *
*/
/*
@@ -55,8 +53,8 @@
JSHINT.errors is an array of objects containing these members:
{
- line : The line (relative to 0) at which the lint was found
- character : The character (relative to 0) at which the lint was found
+ line : The line (relative to 1) at which the lint was found
+ character : The character (relative to 1) at which the lint was found
reason : The problem
evidence : The text line in which the problem occurred
raw : The raw message before the details were inserted
@@ -69,15 +67,6 @@
If a fatal error was found, a null will be the last element of the
JSHINT.errors array.
- You can request a Function Report, which shows all of the functions
- and the parameters and vars that they use. This can be used to find
- implied global variables and other problems. The report is in HTML and
- can be inserted in an HTML <body>.
-
- var myReport = JSHINT.report(limited);
-
- If limited is true, then the report will be limited to only errors.
-
You can request a data structure which contains JSHint's results.
var myData = JSHINT.data();
@@ -96,7 +85,9 @@
functions: [
name: STRING,
line: NUMBER,
+ character: NUMBER,
last: NUMBER,
+ lastcharacter: NUMBER,
param: [
STRING
],
@@ -152,19 +143,20 @@
/*jshint
evil: true, nomen: false, onevar: false, regexp: false, strict: true, boss: true,
- undef: true, maxlen: 100, indent:4
+ undef: true, maxlen: 100, indent: 4, quotmark: double, unused: true
*/
/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", "(begin)",
- "(breakage)", "(context)", "(error)", "(global)", "(identifier)", "(last)",
- "(line)", "(loopage)", "(name)", "(onevar)", "(params)", "(scope)",
- "(statement)", "(verb)", "*", "+", "++", "-", "--", "\/", "<", "<=", "==",
+ "(breakage)", "(character)", "(context)", "(error)", "(explicitNewcap)", "(global)",
+ "(identifier)", "(last)", "(lastcharacter)", "(line)", "(loopage)", "(metrics)",
+ "(name)", "(onevar)", "(params)", "(scope)", "(statement)", "(verb)", "(tokens)", "(catch)",
+ "*", "+", "++", "-", "--", "\/", "<", "<=", "==",
"===", ">", ">=", $, $$, $A, $F, $H, $R, $break, $continue, $w, Abstract, Ajax,
__filename, __dirname, ActiveXObject, Array, ArrayBuffer, ArrayBufferView, Audio,
- Autocompleter, Assets, Boolean, Builder, Buffer, Browser, COM, CScript, Canvas,
- CustomAnimation, Class, Control, Chain, Color, Cookie, Core, DataView, Date,
- Debug, Draggable, Draggables, Droppables, Document, DomReady, DOMReady, Drag,
- E, Enumerator, Enumerable, Element, Elements, Error, Effect, EvalError, Event,
+ Autocompleter, Asset, Boolean, Builder, Buffer, Browser, Blob, COM, CScript, Canvas,
+ CustomAnimation, Class, Control, ComplexityCount, Chain, Color, Cookie, Core, DataView, Date,
+ Debug, Draggable, Draggables, Droppables, Document, DomReady, DOMEvent, DOMReady, DOMParser,
+ Drag, E, Enumerator, Enumerable, Element, Elements, Error, Effect, EvalError, Event,
Events, FadeAnimation, Field, Flash, Float32Array, Float64Array, Form,
FormField, Frame, FormData, Function, Fx, GetObject, Group, Hash, HotKey,
HTMLElement, HTMLAnchorElement, HTMLBaseElement, HTMLBlockquoteElement,
@@ -181,49 +173,53 @@
HtmlTable, HTMLTableCaptionElement, HTMLTableCellElement, HTMLTableColElement,
HTMLTableElement, HTMLTableRowElement, HTMLTableSectionElement,
HTMLTextAreaElement, HTMLTitleElement, HTMLUListElement, HTMLVideoElement,
- Iframe, IframeShim, Image, Int16Array, Int32Array, Int8Array,
+ Iframe, IframeShim, Image, importScripts, Int16Array, Int32Array, Int8Array,
Insertion, InputValidator, JSON, Keyboard, Locale, LN10, LN2, LOG10E, LOG2E,
- MAX_VALUE, MIN_VALUE, Mask, Math, MenuItem, MoveAnimation, MooTools, Native,
- NEGATIVE_INFINITY, Number, Object, ObjectRange, Option, Options, OverText, PI,
- POSITIVE_INFINITY, PeriodicalExecuter, Point, Position, Prototype, RangeError,
- Rectangle, ReferenceError, RegExp, ResizeAnimation, Request, RotateAnimation,
+ MAX_VALUE, MIN_VALUE, Map, Mask, Math, MenuItem, MessageChannel, MessageEvent, MessagePort,
+ MoveAnimation, MooTools, MutationObserver, NaN, Native, NEGATIVE_INFINITY, Node, NodeFilter,
+ Number, Object, ObjectRange,
+ Option, Options, OverText, PI, POSITIVE_INFINITY, PeriodicalExecuter, Point, Position, Prototype,
+ RangeError, Rectangle, ReferenceError, RegExp, ResizeAnimation, Request, RotateAnimation, Set,
SQRT1_2, SQRT2, ScrollBar, ScriptEngine, ScriptEngineBuildVersion,
ScriptEngineMajorVersion, ScriptEngineMinorVersion, Scriptaculous, Scroller,
Slick, Slider, Selector, SharedWorker, String, Style, SyntaxError, Sortable, Sortables,
SortableObserver, Sound, Spinner, System, Swiff, Text, TextArea, Template,
Timer, Tips, Type, TypeError, Toggle, Try, "use strict", unescape, URI, URIError, URL,
- VBArray, WSH, WScript, XDomainRequest, Web, Window, XMLDOM, XMLHttpRequest, XPathEvaluator,
- XPathException, XPathExpression, XPathNamespace, XPathNSResolver, XPathResult, "\\", a,
- addEventListener, address, alert, apply, applicationCache, arguments, arity,
- asi, b, basic, basicToken, bitwise, block, blur, boolOptions, boss, browser, c, call, callee,
- caller, cases, charAt, charCodeAt, character, clearInterval, clearTimeout,
- close, closed, closure, comment, condition, confirm, console, constructor,
- content, couch, create, css, curly, d, data, datalist, dd, debug, decodeURI,
- decodeURIComponent, defaultStatus, defineClass, deserialize, devel, document,
- dojo, dijit, dojox, define, else, emit, encodeURI, encodeURIComponent,
- entityify, eqeqeq, eqnull, errors, es5, escape, esnext, eval, event, evidence, evil,
- ex, exception, exec, exps, expr, exports, FileReader, first, floor, focus,
+ VBArray, WeakMap, WSH, WScript, XDomainRequest, Web, Window, XMLDOM, XMLHttpRequest, XMLSerializer,
+ XPathEvaluator, XPathException, XPathExpression, XPathNamespace, XPathNSResolver, XPathResult,
+ "\\", a, abs, addEventListener, address, alert, apply, applicationCache, arguments, arity,
+ asi, atob, b, basic, basicToken, bitwise, blacklist, block, blur, boolOptions, boss,
+ browser, btoa, c, call, callee, caller, camelcase, cases, charAt, charCodeAt, character,
+ clearInterval, clearTimeout, close, closed, closure, comment, complexityCount, condition,
+ confirm, console, constructor, content, couch, create, css, curly, d, data, datalist, dd, debug,
+ decodeURI, decodeURIComponent, defaultStatus, defineClass, deserialize, devel, document,
+ dojo, dijit, dojox, define, else, emit, encodeURI, encodeURIComponent, elem,
+ eqeq, eqeqeq, eqnull, errors, es5, escape, esnext, eval, event, evidence, evil,
+ ex, exception, exec, exps, expr, exports, FileReader, first, floor, focus, forEach,
forin, fragment, frames, from, fromCharCode, fud, funcscope, funct, function, functions,
g, gc, getComputedStyle, getRow, getter, getterToken, GLOBAL, global, globals, globalstrict,
hasOwnProperty, help, history, i, id, identifier, immed, implieds, importPackage, include,
- indent, indexOf, init, ins, instanceOf, isAlpha, isApplicationRunning, isArray,
+ indent, indexOf, init, ins, internals, instanceOf, isAlpha, isApplicationRunning, isArray,
isDigit, isFinite, isNaN, iterator, java, join, jshint,
- JSHINT, json, jquery, jQuery, keys, label, labelled, last, lastsemic, laxbreak, laxcomma,
- latedef, lbp, led, left, length, line, load, loadClass, localStorage, location,
- log, loopfunc, m, match, maxerr, maxlen, member,message, meta, module, moveBy,
- moveTo, mootools, multistr, name, navigator, new, newcap, noarg, node, noempty, nomen,
- nonew, nonstandard, nud, onbeforeunload, onblur, onerror, onevar, onecase, onfocus,
- onload, onresize, onunload, open, openDatabase, openURL, opener, opera, options, outer, param,
- parent, parseFloat, parseInt, passfail, plusplus, predef, print, process, prompt,
- proto, prototype, prototypejs, provides, push, quit, range, raw, reach, reason, regexp,
- readFile, readUrl, regexdash, removeEventListener, replace, report, require,
- reserved, resizeBy, resizeTo, resolvePath, resumeUpdates, respond, rhino, right,
- runCommand, scroll, screen, scripturl, scrollBy, scrollTo, scrollbar, search, seal,
- send, serialize, sessionStorage, setInterval, setTimeout, setter, setterToken, shift, slice,
- smarttabs, sort, spawn, split, stack, status, start, strict, sub, substr, supernew, shadow,
- supplant, sum, sync, test, toLowerCase, toString, toUpperCase, toint32, token, top, trailing,
- type, typeOf, Uint16Array, Uint32Array, Uint8Array, undef, undefs, unused, urls, validthis,
- value, valueOf, var, version, WebSocket, white, window, Worker, wsh*/
+ JSHINT, json, jquery, jQuery, keys, label, labelled, last, lastcharacter, lastsemic, laxbreak,
+ laxcomma, latedef, lbp, led, left, length, line, load, loadClass, localStorage, location,
+ log, loopfunc, m, match, max, maxcomplexity, maxdepth, maxerr, maxlen, maxstatements, maxparams,
+ member, message, meta, module, moveBy, moveTo, mootools, multistr, name, navigator, new, newcap,
+ nestedBlockDepth, noarg, node, noempty, nomen, nonew, nonstandard, nud, onbeforeunload, onblur,
+ onerror, onevar, onecase, onfocus, onload, onresize, onunload, open, openDatabase, openURL,
+ opener, opera, options, outer, param, parent, parseFloat, parseInt, passfail, plusplus,
+ postMessage, pop, predef, print, process, prompt, proto, prototype, prototypejs, provides, push,
+ quit, quotmark, range, raw, reach, reason, regexp, readFile, readUrl, regexdash,
+ removeEventListener, replace, report, require, reserved, resizeBy, resizeTo, resolvePath,
+ resumeUpdates, respond, rhino, right, runCommand, scroll, scope, screen, scripturl, scrollBy,
+ scrollTo, scrollbar, search, seal, self, send, serialize, sessionStorage, setInterval, setTimeout,
+ setter, setterToken, shift, slice, smarttabs, sort, spawn, split, statement, statementCount, stack,
+ status, start, strict, sub, substr, supernew, shadow, supplant, sum, sync, test, toLowerCase,
+ toString, toUpperCase, toint32, token, tokens, top, trailing, type, typeOf, Uint16Array,
+ Uint32Array, Uint8Array, undef, undefs, unused, urls, validthis, value, valueOf, var, vars,
+ version, verifyMaxParametersPerFunction, verifyMaxStatementsPerFunction,
+ verifyMaxComplexityPerFunction, verifyMaxNestedBlockDepthPerFunction, WebSocket, withstmt, white,
+ window, windows, Worker, worker, wsh, yui, YUI, Y, YUI_config*/
/*global exports: false */
@@ -239,19 +235,19 @@ var JSHINT = (function () {
// These are operators that should not be used with the ! operator.
bang = {
- '<' : true,
- '<=' : true,
- '==' : true,
- '===': true,
- '!==': true,
- '!=' : true,
- '>' : true,
- '>=' : true,
- '+' : true,
- '-' : true,
- '*' : true,
- '/' : true,
- '%' : true
+ "<" : true,
+ "<=" : true,
+ "==" : true,
+ "===": true,
+ "!==": true,
+ "!=" : true,
+ ">" : true,
+ ">=" : true,
+ "+" : true,
+ "-" : true,
+ "*" : true,
+ "/" : true,
+ "%" : true
},
// These are the JSHint boolean options.
@@ -260,6 +256,7 @@ var JSHINT = (function () {
bitwise : true, // if bitwise operators should not be allowed
boss : true, // if advanced usage of assignments should be allowed
browser : true, // if the standard browser globals should be predefined
+ camelcase : true, // if identifiers should be required in camel case
couch : true, // if CouchDB globals should be predefined
curly : true, // if curly braces around all blocks should be required
debug : true, // if debugger statements should be allowed
@@ -311,6 +308,7 @@ var JSHINT = (function () {
regexp : true, // if the . should not be allowed in regexp literals
rhino : true, // if the Rhino environment globals should be predefined
undef : true, // if variables should be declared before used
+ unused : true, // if variables should be always used
scripturl : true, // if script-targeted URLs should be tolerated
shadow : true, // if variable shadowing should be tolerated
smarttabs : true, // if smarttabs should be tolerated
@@ -322,25 +320,73 @@ var JSHINT = (function () {
trailing : true, // if trailing whitespace rules apply
validthis : true, // if 'this' inside a non-constructor function is valid.
// This is a function scoped option only.
+ withstmt : true, // if with statements should be allowed
white : true, // if strict whitespace rules apply
- wsh : true // if the Windows Scripting Host environment globals
+ worker : true, // if Web Worker script symbols should be allowed
+ wsh : true, // if the Windows Scripting Host environment globals
// should be predefined
+ yui : true // YUI variables should be predefined
},
+ // These are the JSHint options that can take any value
+ // (we use this object to detect invalid options)
+ valOptions = {
+ maxlen : false,
+ indent : false,
+ maxerr : false,
+ predef : false,
+ quotmark : false, //'single'|'double'|true
+ scope : false,
+ maxstatements: false, // {int} max statements per function
+ maxdepth : false, // {int} max nested block depth per function
+ maxparams : false, // {int} max params per function
+ maxcomplexity: false // {int} max cyclomatic complexity per function
+ },
+
+ // These are JSHint boolean options which are shared with JSLint
+ // where the definition in JSHint is opposite JSLint
+ invertedOptions = {
+ bitwise : true,
+ forin : true,
+ newcap : true,
+ nomen : true,
+ plusplus : true,
+ regexp : true,
+ undef : true,
+ white : true,
+
+ // Inverted and renamed, use JSHint name here
+ eqeqeq : true,
+ onevar : true
+ },
+
+ // These are JSHint boolean options which are shared with JSLint
+ // where the name has been changed but the effect is unchanged
+ renamedOptions = {
+ eqeq : "eqeqeq",
+ vars : "onevar",
+ windows : "wsh"
+ },
+
+
// browser contains a set of global names which are commonly provided by a
// web browser environment.
browser = {
ArrayBuffer : false,
ArrayBufferView : false,
Audio : false,
+ Blob : false,
addEventListener : false,
applicationCache : false,
+ atob : false,
blur : false,
+ btoa : false,
clearInterval : false,
clearTimeout : false,
close : false,
closed : false,
DataView : false,
+ DOMParser : false,
defaultStatus : false,
document : false,
event : false,
@@ -413,9 +459,15 @@ var JSHINT = (function () {
length : false,
localStorage : false,
location : false,
+ MessageChannel : false,
+ MessageEvent : false,
+ MessagePort : false,
moveBy : false,
moveTo : false,
+ MutationObserver : false,
name : false,
+ Node : false,
+ NodeFilter : false,
navigator : false,
onbeforeunload : true,
onblur : true,
@@ -450,6 +502,7 @@ var JSHINT = (function () {
window : false,
Worker : false,
XMLHttpRequest : false,
+ XMLSerializer : false,
XPathEvaluator : false,
XPathException : false,
XPathExpression : false,
@@ -472,6 +525,8 @@ var JSHINT = (function () {
provides : false
},
+ declared, // Globals that were declared using /*global ... */ syntax.
+
devel = {
alert : false,
confirm : false,
@@ -489,22 +544,11 @@ var JSHINT = (function () {
"require" : false
},
- escapes = {
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '/' : '\\/',
- '\\': '\\\\'
- },
-
funct, // The current function
functionicity = [
- 'closure', 'exception', 'global', 'label',
- 'outer', 'unused', 'var'
+ "closure", "exception", "global", "label",
+ "outer", "unused", "var"
],
functions, // All of the functions
@@ -516,7 +560,7 @@ var JSHINT = (function () {
jsonmode,
jquery = {
- '$' : false,
+ "$" : false,
jQuery : false
},
@@ -526,9 +570,9 @@ var JSHINT = (function () {
membersOnly,
mootools = {
- '$' : false,
- '$$' : false,
- Assets : false,
+ "$" : false,
+ "$$" : false,
+ Asset : false,
Browser : false,
Chain : false,
Class : false,
@@ -537,6 +581,7 @@ var JSHINT = (function () {
Core : false,
Document : false,
DomReady : false,
+ DOMEvent : false,
DOMReady : false,
Drag : false,
Element : false,
@@ -579,7 +624,7 @@ var JSHINT = (function () {
__dirname : false,
Buffer : false,
console : false,
- exports : false,
+ exports : true, // In Node it is ok to exports = module.exports = foo();
GLOBAL : false,
global : false,
module : false,
@@ -598,15 +643,15 @@ var JSHINT = (function () {
prevtoken,
prototypejs = {
- '$' : false,
- '$$' : false,
- '$A' : false,
- '$F' : false,
- '$H' : false,
- '$R' : false,
- '$break' : false,
- '$continue' : false,
- '$w' : false,
+ "$" : false,
+ "$$" : false,
+ "$A" : false,
+ "$F" : false,
+ "$H" : false,
+ "$R" : false,
+ "$break" : false,
+ "$continue" : false,
+ "$w" : false,
Abstract : false,
Ajax : false,
Class : false,
@@ -638,6 +683,8 @@ var JSHINT = (function () {
Scriptaculous : false
},
+ quotmark,
+
rhino = {
defineClass : false,
deserialize : false,
@@ -674,14 +721,16 @@ var JSHINT = (function () {
encodeURI : false,
encodeURIComponent : false,
Error : false,
- 'eval' : false,
+ "eval" : false,
EvalError : false,
Function : false,
hasOwnProperty : false,
isFinite : false,
isNaN : false,
JSON : false,
+ Map : false,
Math : false,
+ NaN : false,
Number : false,
Object : false,
parseInt : false,
@@ -689,10 +738,12 @@ var JSHINT = (function () {
RangeError : false,
ReferenceError : false,
RegExp : false,
+ Set : false,
String : false,
SyntaxError : false,
TypeError : false,
- URIError : false
+ URIError : false,
+ WeakMap : false
},
// widely adopted global names that are not part of ECMAScript standard
@@ -701,29 +752,21 @@ var JSHINT = (function () {
unescape : false
},
- standard_member = {
- E : true,
- LN2 : true,
- LN10 : true,
- LOG2E : true,
- LOG10E : true,
- MAX_VALUE : true,
- MIN_VALUE : true,
- NEGATIVE_INFINITY : true,
- PI : true,
- POSITIVE_INFINITY : true,
- SQRT1_2 : true,
- SQRT2 : true
- },
-
directive,
syntax = {},
tab,
token,
+ unuseds,
urls,
useESNextSyntax,
warnings,
+ worker = {
+ importScripts : true,
+ postMessage : true,
+ self : true
+ },
+
wsh = {
ActiveXObject : true,
Enumerator : true,
@@ -736,8 +779,13 @@ var JSHINT = (function () {
WSH : true,
WScript : true,
XDomainRequest : true
- };
+ },
+ yui = {
+ YUI : false,
+ Y : false,
+ YUI_config : false
+ };
// Regular expressions. Some of these are stupidly long.
var ax, cx, tx, nx, nxg, lx, ix, jx, ft;
(function () {
@@ -750,14 +798,14 @@ var JSHINT = (function () {
cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
// token
- tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jshint|jslint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/;
+ tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/=(?!(\S*\/[gim]?))|\/(\*(jshint|jslint|members?|global)?|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/;
// characters in strings that need escapement
nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
// star slash
- lx = /\*\/|\/\*/;
+ lx = /\*\//;
// identifier
ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/;
@@ -772,29 +820,85 @@ var JSHINT = (function () {
function F() {} // Used by Object.create
function is_own(object, name) {
+ // The object.hasOwnProperty method fails when the property under consideration
+ // is named 'hasOwnProperty'. So we have to use this more convoluted form.
+ return Object.prototype.hasOwnProperty.call(object, name);
+ }
-// The object.hasOwnProperty method fails when the property under consideration
-// is named 'hasOwnProperty'. So we have to use this more convoluted form.
+ function checkOption(name, t) {
+ if (valOptions[name] === undefined && boolOptions[name] === undefined) {
+ warning("Bad option: '" + name + "'.", t);
+ }
+ }
- return Object.prototype.hasOwnProperty.call(object, name);
+ function isString(obj) {
+ return Object.prototype.toString.call(obj) === "[object String]";
}
-// Provide critical ES5 functions to ES3.
+ // Provide critical ES5 functions to ES3.
- if (typeof Array.isArray !== 'function') {
+ if (typeof Array.isArray !== "function") {
Array.isArray = function (o) {
- return Object.prototype.toString.apply(o) === '[object Array]';
+ return Object.prototype.toString.apply(o) === "[object Array]";
+ };
+ }
+
+ if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function (fn, scope) {
+ var len = this.length;
+
+ for (var i = 0; i < len; i++) {
+ fn.call(scope || this, this[i], i, this);
+ }
};
}
- if (typeof Object.create !== 'function') {
+ if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
+ if (this === null || this === undefined) {
+ throw new TypeError();
+ }
+
+ var t = new Object(this);
+ var len = t.length >>> 0;
+
+ if (len === 0) {
+ return -1;
+ }
+
+ var n = 0;
+ if (arguments.length > 0) {
+ n = Number(arguments[1]);
+ if (n != n) { // shortcut for verifying if it's NaN
+ n = 0;
+ } else if (n !== 0 && n != Infinity && n != -Infinity) {
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
+ }
+ }
+
+ if (n >= len) {
+ return -1;
+ }
+
+ var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
+ for (; k < len; k++) {
+ if (k in t && t[k] === searchElement) {
+ return k;
+ }
+ }
+
+ return -1;
+ };
+ }
+
+ if (typeof Object.create !== "function") {
Object.create = function (o) {
F.prototype = o;
return new F();
};
}
- if (typeof Object.keys !== 'function') {
+ if (typeof Object.keys !== "function") {
Object.keys = function (o) {
var a = [], k;
for (k in o) {
@@ -806,74 +910,49 @@ var JSHINT = (function () {
};
}
-// Non standard methods
+ // Non standard methods
- if (typeof String.prototype.entityify !== 'function') {
- String.prototype.entityify = function () {
- return this
- .replace(/&/g, '&amp;')
- .replace(/</g, '&lt;')
- .replace(/>/g, '&gt;');
- };
+ function isAlpha(str) {
+ return (str >= "a" && str <= "z\uffff") ||
+ (str >= "A" && str <= "Z\uffff");
}
- if (typeof String.prototype.isAlpha !== 'function') {
- String.prototype.isAlpha = function () {
- return (this >= 'a' && this <= 'z\uffff') ||
- (this >= 'A' && this <= 'Z\uffff');
- };
+ function isDigit(str) {
+ return (str >= "0" && str <= "9");
}
- if (typeof String.prototype.isDigit !== 'function') {
- String.prototype.isDigit = function () {
- return (this >= '0' && this <= '9');
- };
- }
-
- if (typeof String.prototype.supplant !== 'function') {
- String.prototype.supplant = function (o) {
- return this.replace(/\{([^{}]*)\}/g, function (a, b) {
- var r = o[b];
- return typeof r === 'string' || typeof r === 'number' ? r : a;
- });
- };
- }
-
- if (typeof String.prototype.name !== 'function') {
- String.prototype.name = function () {
+ function isIdentifier(token, value) {
+ if (!token)
+ return false;
-// If the string looks like an identifier, then we can return it as is.
-// If the string contains no control characters, no quote characters, and no
-// backslash characters, then we can simply slap some quotes around it.
-// Otherwise we must also replace the offending characters with safe
-// sequences.
+ if (!token.identifier || token.value !== value)
+ return false;
- if (ix.test(this)) {
- return this;
- }
- if (nx.test(this)) {
- return '"' + this.replace(nxg, function (a) {
- var c = escapes[a];
- if (c) {
- return c;
- }
- return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4);
- }) + '"';
- }
- return '"' + this + '"';
- };
+ return true;
}
+ function supplant(str, data) {
+ return str.replace(/\{([^{}]*)\}/g, function (a, b) {
+ var r = data[b];
+ return typeof r === "string" || typeof r === "number" ? r : a;
+ });
+ }
function combine(t, o) {
var n;
for (n in o) {
- if (is_own(o, n)) {
+ if (is_own(o, n) && !is_own(JSHINT.blacklist, n)) {
t[n] = o[n];
}
}
}
+ function updatePredefined() {
+ Object.keys(JSHINT.blacklist).forEach(function (key) {
+ delete predefined[key];
+ });
+ }
+
function assume() {
if (option.couch) {
combine(predefined, couch);
@@ -889,6 +968,7 @@ var JSHINT = (function () {
if (option.node) {
combine(predefined, node);
+ option.globalstrict = true;
}
if (option.devel) {
@@ -915,6 +995,10 @@ var JSHINT = (function () {
combine(predefined, mootools);
}
+ if (option.worker) {
+ combine(predefined, worker);
+ }
+
if (option.wsh) {
combine(predefined, wsh);
}
@@ -926,6 +1010,10 @@ var JSHINT = (function () {
if (option.globalstrict && option.strict !== false) {
option.strict = true;
}
+
+ if (option.yui) {
+ combine(predefined, yui);
+ }
}
@@ -934,7 +1022,7 @@ var JSHINT = (function () {
var percentage = Math.floor((line / lines.length) * 100);
throw {
- name: 'JSHintError',
+ name: "JSHintError",
line: line,
character: chr,
message: message + " (" + percentage + "% scanned).",
@@ -949,26 +1037,27 @@ var JSHINT = (function () {
function warning(m, t, a, b, c, d) {
var ch, l, w;
t = t || nexttoken;
- if (t.id === '(end)') { // `~
+ if (t.id === "(end)") { // `~
t = token;
}
l = t.line || 0;
ch = t.from || 0;
w = {
- id: '(error)',
+ id: "(error)",
raw: m,
- evidence: lines[l - 1] || '',
+ evidence: lines[l - 1] || "",
line: l,
character: ch,
+ scope: JSHINT.scope,
a: a,
b: b,
c: c,
d: d
};
- w.reason = m.supplant(w);
+ w.reason = supplant(m, w);
JSHINT.errors.push(w);
if (option.passfail) {
- quit('Stopping. ', l, ch);
+ quit("Stopping. ", l, ch);
}
warnings += 1;
if (warnings >= option.maxerr) {
@@ -985,7 +1074,7 @@ var JSHINT = (function () {
}
function error(m, t, a, b, c, d) {
- var w = warning(m, t, a, b, c, d);
+ warning(m, t, a, b, c, d);
}
function errorAt(m, l, ch, a, b, c, d) {
@@ -995,6 +1084,17 @@ var JSHINT = (function () {
}, a, b, c, d);
}
+ // Tracking of "internal" scripts, like eval containing a static string
+ function addInternalSrc(elem, src) {
+ var i;
+ i = {
+ id: "(internal)",
+ elem: elem,
+ value: src
+ };
+ JSHINT.internals.push(i);
+ return i;
+ }
// lexical analysis and token construction
@@ -1006,6 +1106,7 @@ var JSHINT = (function () {
function nextLine() {
var at,
+ match,
tw; // trailing whitespace check
if (line >= lines.length)
@@ -1017,10 +1118,14 @@ var JSHINT = (function () {
// If smarttabs option is used check for spaces followed by tabs only.
// Otherwise check for any occurence of mixed tabs and spaces.
- if (option.smarttabs)
- at = s.search(/ \t/);
- else
- at = s.search(/ \t|\t /);
+ // Tabs and one space followed by block comment is allowed.
+ if (option.smarttabs) {
+ // negative look-behind for "//"
+ match = s.match(/(\/\/)? \t/);
+ at = match && !match[1] ? 0 : -1;
+ } else {
+ at = s.search(/ \t|\t [^\*]/);
+ }
if (at >= 0)
warningAt("Mixed spaces and tabs.", line, at + 1);
@@ -1035,9 +1140,9 @@ var JSHINT = (function () {
warningAt("Line too long.", line, s.length);
// Check for trailing whitespaces
- tw = /\s+$/.test(s);
- if (option.trailing && tw && !/^\s+$/.test(s)) {
- warningAt("Trailing whitespace.", line, tw);
+ tw = option.trailing && s.match(/^(.*?)\s+$/);
+ if (tw && !/^\s+$/.test(s)) {
+ warningAt("Trailing whitespace.", line, tw[1].length + 1);
}
return true;
}
@@ -1046,46 +1151,74 @@ var JSHINT = (function () {
function it(type, value) {
var i, t;
- if (type === '(color)' || type === '(range)') {
+
+ function checkName(name) {
+ if (!option.proto && name === "__proto__") {
+ warningAt("The '{a}' property is deprecated.", line, from, name);
+ return;
+ }
+
+ if (!option.iterator && name === "__iterator__") {
+ warningAt("'{a}' is only available in JavaScript 1.7.", line, from, name);
+ return;
+ }
+
+ // Check for dangling underscores unless we're in Node
+ // environment and this identifier represents built-in
+ // Node globals with underscores.
+
+ var hasDangling = /^(_+.*|.*_+)$/.test(name);
+
+ if (option.nomen && hasDangling && name !== "_") {
+ if (option.node && token.id !== "." && /^(__dirname|__filename)$/.test(name))
+ return;
+
+ warningAt("Unexpected {a} in '{b}'.", line, from, "dangling '_'", name);
+ return;
+ }
+
+ // Check for non-camelcase names. Names like MY_VAR and
+ // _myVar are okay though.
+
+ if (option.camelcase) {
+ if (name.replace(/^_+/, "").indexOf("_") > -1 && !name.match(/^[A-Z0-9_]*$/)) {
+ warningAt("Identifier '{a}' is not in camel case.", line, from, value);
+ }
+ }
+ }
+
+ if (type === "(color)" || type === "(range)") {
t = {type: type};
- } else if (type === '(punctuator)' ||
- (type === '(identifier)' && is_own(syntax, value))) {
- t = syntax[value] || syntax['(error)'];
+ } else if (type === "(punctuator)" ||
+ (type === "(identifier)" && is_own(syntax, value))) {
+ t = syntax[value] || syntax["(error)"];
} else {
t = syntax[type];
}
+
t = Object.create(t);
- if (type === '(string)' || type === '(range)') {
+
+ if (type === "(string)" || type === "(range)") {
if (!option.scripturl && jx.test(value)) {
warningAt("Script URL.", line, from);
}
}
- if (type === '(identifier)') {
+
+ if (type === "(identifier)") {
t.identifier = true;
- if (value === '__proto__' && !option.proto) {
- warningAt("The '{a}' property is deprecated.",
- line, from, value);
- } else if (value === '__iterator__' && !option.iterator) {
- warningAt("'{a}' is only available in JavaScript 1.7.",
- line, from, value);
- } else if (option.nomen && (value.charAt(0) === '_' ||
- value.charAt(value.length - 1) === '_')) {
- if (!option.node || token.id === '.' ||
- (value !== '__dirname' && value !== '__filename')) {
- warningAt("Unexpected {a} in '{b}'.", line, from, "dangling '_'", value);
- }
- }
+ checkName(value);
}
+
t.value = value;
t.line = line;
t.character = character;
t.from = from;
i = t.id;
- if (i !== '(endline)') {
+ if (i !== "(endline)") {
prereg = i &&
- (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
- i === 'return' ||
- i === 'case');
+ (("(,=:[!&|?{};".indexOf(i.charAt(i.length - 1)) >= 0) ||
+ i === "return" ||
+ i === "case");
}
return t;
}
@@ -1093,19 +1226,19 @@ var JSHINT = (function () {
// Public lex methods
return {
init: function (source) {
- if (typeof source === 'string') {
+ if (typeof source === "string") {
lines = source
- .replace(/\r\n/g, '\n')
- .replace(/\r/g, '\n')
- .split('\n');
+ .replace(/\r\n/g, "\n")
+ .replace(/\r/g, "\n")
+ .split("\n");
} else {
lines = source;
}
// If the first line is a shebang (#!), make it a blank and move on.
// Shebangs are used by Node scripts.
- if (lines[0] && lines[0].substr(0, 2) === '#!')
- lines[0] = '';
+ if (lines[0] && lines[0].substr(0, 2) === "#!")
+ lines[0] = "";
line = 0;
nextLine();
@@ -1113,7 +1246,7 @@ var JSHINT = (function () {
},
range: function (begin, end) {
- var c, value = '';
+ var c, value = "";
from = character;
if (s.charAt(0) !== begin) {
errorAt("Expected '{a}' and instead saw '{b}'.",
@@ -1124,14 +1257,14 @@ var JSHINT = (function () {
character += 1;
c = s.charAt(0);
switch (c) {
- case '':
+ case "":
errorAt("Missing '{a}'.", line, character, c);
break;
case end:
s = s.slice(1);
character += 1;
- return it('(range)', value);
- case '\\':
+ return it("(range)", value);
+ case "\\":
warningAt("Unexpected '{a}'.", line, character, c);
}
value += c;
@@ -1142,10 +1275,11 @@ var JSHINT = (function () {
// token -- this is called by advance to get the next token
token: function () {
- var b, c, captures, d, depth, high, i, l, low, q, t, isLiteral, isInRange;
+ var b, c, captures, d, depth, high, i, l, low, q, t, isLiteral, isInRange, n;
function match(x) {
var r = x.exec(s), r1;
+
if (r) {
l = r[0].length;
r1 = r[1];
@@ -1158,13 +1292,29 @@ var JSHINT = (function () {
}
function string(x) {
- var c, j, r = '', allowNewLine = false;
+ var c, j, r = "", allowNewLine = false;
- if (jsonmode && x !== '"') {
+ if (jsonmode && x !== "\"") {
warningAt("Strings must use doublequote.",
line, character);
}
+ if (option.quotmark) {
+ if (option.quotmark === "single" && x !== "'") {
+ warningAt("Strings must use singlequote.",
+ line, character);
+ } else if (option.quotmark === "double" && x !== "\"") {
+ warningAt("Strings must use doublequote.",
+ line, character);
+ } else if (option.quotmark === true) {
+ quotmark = quotmark || x;
+ if (quotmark !== x) {
+ warningAt("Mixed double and single quotes.",
+ line, character);
+ }
+ }
+ }
+
function esc(n) {
var i = parseInt(s.substr(j + 1, n), 16);
j += n;
@@ -1175,8 +1325,11 @@ var JSHINT = (function () {
character += n;
c = String.fromCharCode(i);
}
+
j = 0;
-unclosedString: for (;;) {
+
+unclosedString:
+ for (;;) {
while (j >= s.length) {
j = 0;
@@ -1192,63 +1345,77 @@ unclosedString: for (;;) {
warningAt("Unclosed string.", cl, cf);
}
}
+
c = s.charAt(j);
if (c === x) {
character += 1;
s = s.substr(j + 1);
- return it('(string)', r, x);
+ return it("(string)", r, x);
}
- if (c < ' ') {
- if (c === '\n' || c === '\r') {
+
+ if (c < " ") {
+ if (c === "\n" || c === "\r") {
break;
}
warningAt("Control character in string: {a}.",
line, character + j, s.slice(0, j));
- } else if (c === '\\') {
+ } else if (c === "\\") {
j += 1;
character += 1;
c = s.charAt(j);
+ n = s.charAt(j + 1);
switch (c) {
- case '\\':
- case '"':
- case '/':
+ case "\\":
+ case "\"":
+ case "/":
break;
- case '\'':
+ case "\'":
if (jsonmode) {
warningAt("Avoid \\'.", line, character);
}
break;
- case 'b':
- c = '\b';
+ case "b":
+ c = "\b";
+ break;
+ case "f":
+ c = "\f";
break;
- case 'f':
- c = '\f';
+ case "n":
+ c = "\n";
break;
- case 'n':
- c = '\n';
+ case "r":
+ c = "\r";
break;
- case 'r':
- c = '\r';
+ case "t":
+ c = "\t";
break;
- case 't':
- c = '\t';
+ case "0":
+ c = "\0";
+ // Octal literals fail in strict mode
+ // check if the number is between 00 and 07
+ // where 'n' is the token next to 'c'
+ if (n >= 0 && n <= 7 && directive["use strict"]) {
+ warningAt(
+ "Octal literals are not allowed in strict mode.",
+ line, character);
+ }
break;
- case 'u':
+ case "u":
esc(4);
break;
- case 'v':
+ case "v":
if (jsonmode) {
warningAt("Avoid \\v.", line, character);
}
- c = '\v';
+ c = "\v";
break;
- case 'x':
+ case "x":
if (jsonmode) {
warningAt("Avoid \\x-.", line, character);
}
esc(2);
break;
- case '':
+ case "":
// last character is escape character
// always allow new line if escaped, but show
// warning if option is not set
@@ -1257,13 +1424,17 @@ unclosedString: for (;;) {
if (jsonmode) {
warningAt("Avoid EOL escapement.", line, character);
}
- c = '';
+ c = "";
character -= 1;
break;
}
warningAt("Bad escapement of EOL. Use option multistr if needed.",
line, character);
break;
+ case "!":
+ if (s.charAt(j - 2) === "<")
+ break;
+ /*falls through*/
default:
warningAt("Bad escapement.", line, character);
}
@@ -1276,74 +1447,76 @@ unclosedString: for (;;) {
for (;;) {
if (!s) {
- return it(nextLine() ? '(endline)' : '(end)', '');
+ return it(nextLine() ? "(endline)" : "(end)", "");
}
+
t = match(tx);
+
if (!t) {
- t = '';
- c = '';
- while (s && s < '!') {
+ t = "";
+ c = "";
+ while (s && s < "!") {
s = s.substr(1);
}
if (s) {
errorAt("Unexpected '{a}'.", line, character, s.substr(0, 1));
- s = '';
+ s = "";
}
} else {
// identifier
- if (c.isAlpha() || c === '_' || c === '$') {
- return it('(identifier)', t);
+ if (isAlpha(c) || c === "_" || c === "$") {
+ return it("(identifier)", t);
}
// number
- if (c.isDigit()) {
+ if (isDigit(c)) {
if (!isFinite(Number(t))) {
warningAt("Bad number '{a}'.",
line, character, t);
}
- if (s.substr(0, 1).isAlpha()) {
+ if (isAlpha(s.substr(0, 1))) {
warningAt("Missing space after '{a}'.",
line, character, t);
}
- if (c === '0') {
+ if (c === "0") {
d = t.substr(1, 1);
- if (d.isDigit()) {
- if (token.id !== '.') {
+ if (isDigit(d)) {
+ if (token.id !== ".") {
warningAt("Don't use extra leading zeros '{a}'.",
line, character, t);
}
- } else if (jsonmode && (d === 'x' || d === 'X')) {
+ } else if (jsonmode && (d === "x" || d === "X")) {
warningAt("Avoid 0x-. '{a}'.",
line, character, t);
}
}
- if (t.substr(t.length - 1) === '.') {
+ if (t.substr(t.length - 1) === ".") {
warningAt(
"A trailing decimal point can be confused with a dot '{a}'.", line, character, t);
}
- return it('(number)', t);
+ return it("(number)", t);
}
switch (t) {
// string
- case '"':
+ case "\"":
case "'":
return string(t);
// // comment
- case '//':
- s = '';
+ case "//":
+ s = "";
token.comment = true;
break;
// /* comment
- case '/*':
+ case "/*":
for (;;) {
i = s.search(lx);
if (i >= 0) {
@@ -1353,38 +1526,35 @@ unclosedString: for (;;) {
errorAt("Unclosed comment.", line, character);
}
}
- character += i + 2;
- if (s.substr(i, 1) === '/') {
- errorAt("Nested comment.", line, character);
- }
s = s.substr(i + 2);
token.comment = true;
break;
// /*members /*jshint /*global
- case '/*members':
- case '/*member':
- case '/*jshint':
- case '/*jslint':
- case '/*global':
- case '*/':
+ case "/*members":
+ case "/*member":
+ case "/*jshint":
+ case "/*jslint":
+ case "/*global":
+ case "*/":
return {
value: t,
- type: 'special',
+ type: "special",
line: line,
character: character,
from: from
};
- case '':
+ case "":
break;
// /
- case '/':
- if (token.id === '/=') {
+ case "/":
+ if (s.charAt(0) === "=") {
errorAt("A regular expression literal can be confused with '/='.",
line, from);
}
+
if (prereg) {
depth = 0;
captures = 0;
@@ -1394,10 +1564,10 @@ unclosedString: for (;;) {
c = s.charAt(l);
l += 1;
switch (c) {
- case '':
+ case "":
errorAt("Unclosed regular expression.", line, from);
- return quit('Stopping.', line, from);
- case '/':
+ return quit("Stopping.", line, from);
+ case "/":
if (depth > 0) {
warningAt("{a} unterminated regular expression " +
"group(s).", line, from + l, depth);
@@ -1415,55 +1585,55 @@ unclosedString: for (;;) {
character += l;
s = s.substr(l);
q = s.charAt(0);
- if (q === '/' || q === '*') {
+ if (q === "/" || q === "*") {
errorAt("Confusing regular expression.",
line, from);
}
- return it('(regexp)', c);
- case '\\':
+ return it("(regexp)", c);
+ case "\\":
c = s.charAt(l);
- if (c < ' ') {
+ if (c < " ") {
warningAt(
"Unexpected control character in regular expression.", line, from + l);
- } else if (c === '<') {
+ } else if (c === "<") {
warningAt(
"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
}
l += 1;
break;
- case '(':
+ case "(":
depth += 1;
b = false;
- if (s.charAt(l) === '?') {
+ if (s.charAt(l) === "?") {
l += 1;
switch (s.charAt(l)) {
- case ':':
- case '=':
- case '!':
+ case ":":
+ case "=":
+ case "!":
l += 1;
break;
default:
warningAt(
-"Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l));
+"Expected '{a}' and instead saw '{b}'.", line, from + l, ":", s.charAt(l));
}
} else {
captures += 1;
}
break;
- case '|':
+ case "|":
b = false;
break;
- case ')':
+ case ")":
if (depth === 0) {
warningAt("Unescaped '{a}'.",
- line, from + l, ')');
+ line, from + l, ")");
} else {
depth -= 1;
}
break;
- case ' ':
+ case " ":
q = 1;
- while (s.charAt(l) === ' ') {
+ while (s.charAt(l) === " ") {
l += 1;
q += 1;
}
@@ -1472,30 +1642,28 @@ unclosedString: for (;;) {
"Spaces are hard to count. Use {{a}}.", line, from + l, q);
}
break;
- case '[':
+ case "[":
c = s.charAt(l);
- if (c === '^') {
+ if (c === "^") {
l += 1;
- if (option.regexp) {
- warningAt("Insecure '{a}'.",
- line, from + l, c);
- } else if (s.charAt(l) === ']') {
+ if (s.charAt(l) === "]") {
errorAt("Unescaped '{a}'.",
- line, from + l, '^');
+ line, from + l, "^");
}
}
- if (c === ']') {
+ if (c === "]") {
warningAt("Empty class.", line,
from + l - 1);
}
isLiteral = false;
isInRange = false;
-klass: do {
+klass:
+ do {
c = s.charAt(l);
l += 1;
switch (c) {
- case '[':
- case '^':
+ case "[":
+ case "^":
warningAt("Unescaped '{a}'.",
line, from + l, c);
if (isInRange) {
@@ -1504,35 +1672,35 @@ klass: do {
isLiteral = true;
}
break;
- case '-':
+ case "-":
if (isLiteral && !isInRange) {
isLiteral = false;
isInRange = true;
} else if (isInRange) {
isInRange = false;
- } else if (s.charAt(l) === ']') {
+ } else if (s.charAt(l) === "]") {
isInRange = true;
} else {
if (option.regexdash !== (l === 2 || (l === 3 &&
- s.charAt(1) === '^'))) {
+ s.charAt(1) === "^"))) {
warningAt("Unescaped '{a}'.",
- line, from + l - 1, '-');
+ line, from + l - 1, "-");
}
isLiteral = true;
}
break;
- case ']':
+ case "]":
if (isInRange && !option.regexdash) {
warningAt("Unescaped '{a}'.",
- line, from + l - 1, '-');
+ line, from + l - 1, "-");
}
break klass;
- case '\\':
+ case "\\":
c = s.charAt(l);
- if (c < ' ') {
+ if (c < " ") {
warningAt(
"Unexpected control character in regular expression.", line, from + l);
- } else if (c === '<') {
+ } else if (c === "<") {
warningAt(
"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
}
@@ -1542,7 +1710,7 @@ klass: do {
if (/[wsd]/i.test(c)) {
if (isInRange) {
warningAt("Unescaped '{a}'.",
- line, from + l, '-');
+ line, from + l, "-");
isInRange = false;
}
isLiteral = false;
@@ -1552,9 +1720,9 @@ klass: do {
isLiteral = true;
}
break;
- case '/':
+ case "/":
warningAt("Unescaped '{a}'.",
- line, from + l - 1, '/');
+ line, from + l - 1, "/");
if (isInRange) {
isInRange = false;
@@ -1562,7 +1730,7 @@ klass: do {
isLiteral = true;
}
break;
- case '<':
+ case "<":
if (isInRange) {
isInRange = false;
} else {
@@ -1578,59 +1746,60 @@ klass: do {
}
} while (c);
break;
- case '.':
+ case ".":
if (option.regexp) {
warningAt("Insecure '{a}'.", line,
from + l, c);
}
break;
- case ']':
- case '?':
- case '{':
- case '}':
- case '+':
- case '*':
+ case "]":
+ case "?":
+ case "{":
+ case "}":
+ case "+":
+ case "*":
warningAt("Unescaped '{a}'.", line,
from + l, c);
}
if (b) {
switch (s.charAt(l)) {
- case '?':
- case '+':
- case '*':
+ case "?":
+ case "+":
+ case "*":
l += 1;
- if (s.charAt(l) === '?') {
+ if (s.charAt(l) === "?") {
l += 1;
}
break;
- case '{':
+ case "{":
l += 1;
c = s.charAt(l);
- if (c < '0' || c > '9') {
+ if (c < "0" || c > "9") {
warningAt(
"Expected a number and instead saw '{a}'.", line, from + l, c);
+ break; // No reason to continue checking numbers.
}
l += 1;
low = +c;
for (;;) {
c = s.charAt(l);
- if (c < '0' || c > '9') {
+ if (c < "0" || c > "9") {
break;
}
l += 1;
low = +c + (low * 10);
}
high = low;
- if (c === ',') {
+ if (c === ",") {
l += 1;
high = Infinity;
c = s.charAt(l);
- if (c >= '0' && c <= '9') {
+ if (c >= "0" && c <= "9") {
l += 1;
high = +c;
for (;;) {
c = s.charAt(l);
- if (c < '0' || c > '9') {
+ if (c < "0" || c > "9") {
break;
}
l += 1;
@@ -1638,13 +1807,13 @@ klass: do {
}
}
}
- if (s.charAt(l) !== '}') {
+ if (s.charAt(l) !== "}") {
warningAt(
-"Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c);
+"Expected '{a}' and instead saw '{b}'.", line, from + l, "}", c);
} else {
l += 1;
}
- if (s.charAt(l) === '?') {
+ if (s.charAt(l) === "?") {
l += 1;
}
if (low > high) {
@@ -1657,16 +1826,16 @@ klass: do {
c = s.substr(0, l - 1);
character += l;
s = s.substr(l);
- return it('(regexp)', c);
+ return it("(regexp)", c);
}
- return it('(punctuator)', t);
+ return it("(punctuator)", t);
// punctuator
- case '#':
- return it('(punctuator)', t);
+ case "#":
+ return it("(punctuator)", t);
default:
- return it('(punctuator)', t);
+ return it("(punctuator)", t);
}
}
}
@@ -1675,25 +1844,38 @@ klass: do {
}());
- function addlabel(t, type) {
-
- if (t === 'hasOwnProperty') {
+ function addlabel(t, type, token) {
+ if (t === "hasOwnProperty") {
warning("'hasOwnProperty' is a really bad name.");
}
-// Define t in the current function in the current scope.
- if (is_own(funct, t) && !funct['(global)']) {
+ // Define t in the current function in the current scope.
+ if (type === "exception") {
+ if (is_own(funct["(context)"], t)) {
+ if (funct[t] !== true && !option.node) {
+ warning("Value of '{a}' may be overwritten in IE.", nexttoken, t);
+ }
+ }
+ }
+
+ if (is_own(funct, t) && !funct["(global)"]) {
if (funct[t] === true) {
if (option.latedef)
warning("'{a}' was used before it was defined.", nexttoken, t);
} else {
- if (!option.shadow && type !== "exception")
+ if (!option.shadow && type !== "exception") {
warning("'{a}' is already defined.", nexttoken, t);
+ }
}
}
funct[t] = type;
- if (funct['(global)']) {
+
+ if (token) {
+ funct["(tokens)"][t] = token;
+ }
+
+ if (funct["(global)"]) {
global[t] = funct;
if (is_own(implied, t)) {
if (option.latedef)
@@ -1707,102 +1889,163 @@ klass: do {
function doOption() {
- var b, obj, filter, o = nexttoken.value, t, v;
+ var nt = nexttoken;
+ var o = nt.value;
+ var quotmarkValue = option.quotmark;
+ var predef = {};
+ var b, obj, filter, t, tn, v, minus;
+
switch (o) {
- case '*/':
+ case "*/":
error("Unbegun comment.");
break;
- case '/*members':
- case '/*member':
- o = '/*members';
+ case "/*members":
+ case "/*member":
+ o = "/*members";
if (!membersOnly) {
membersOnly = {};
}
obj = membersOnly;
+ option.quotmark = false;
break;
- case '/*jshint':
- case '/*jslint':
+ case "/*jshint":
+ case "/*jslint":
obj = option;
filter = boolOptions;
break;
- case '/*global':
- obj = predefined;
+ case "/*global":
+ obj = predef;
break;
default:
error("What?");
}
+
t = lex.token();
-loop: for (;;) {
+
+loop:
+ for (;;) {
+ minus = false;
for (;;) {
- if (t.type === 'special' && t.value === '*/') {
+ if (t.type === "special" && t.value === "*/") {
break loop;
}
- if (t.id !== '(endline)' && t.id !== ',') {
+ if (t.id !== "(endline)" && t.id !== ",") {
break;
}
t = lex.token();
}
- if (t.type !== '(string)' && t.type !== '(identifier)' &&
- o !== '/*members') {
+
+ if (o === "/*global" && t.value === "-") {
+ minus = true;
+ t = lex.token();
+ }
+
+ if (t.type !== "(string)" && t.type !== "(identifier)" && o !== "/*members") {
error("Bad option.", t);
}
+
v = lex.token();
- if (v.id === ':') {
+ if (v.id === ":") {
v = lex.token();
+
if (obj === membersOnly) {
- error("Expected '{a}' and instead saw '{b}'.",
- t, '*/', ':');
+ error("Expected '{a}' and instead saw '{b}'.", t, "*/", ":");
}
- if (t.value === 'indent' && (o === '/*jshint' || o === '/*jslint')) {
- b = +v.value;
- if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
- Math.floor(b) !== b) {
- error("Expected a small integer and instead saw '{a}'.",
- v, v.value);
- }
- obj.white = true;
- obj.indent = b;
- } else if (t.value === 'maxerr' && (o === '/*jshint' || o === '/*jslint')) {
- b = +v.value;
- if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
- Math.floor(b) !== b) {
- error("Expected a small integer and instead saw '{a}'.",
- v, v.value);
- }
- obj.maxerr = b;
- } else if (t.value === 'maxlen' && (o === '/*jshint' || o === '/*jslint')) {
+
+ if (o === "/*jshint") {
+ checkOption(t.value, t);
+ }
+
+ var numericVals = [
+ "maxstatements",
+ "maxparams",
+ "maxdepth",
+ "maxcomplexity",
+ "maxerr",
+ "maxlen",
+ "indent"
+ ];
+
+ if (numericVals.indexOf(t.value) > -1 && (o === "/*jshint" || o === "/*jslint")) {
b = +v.value;
- if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
- Math.floor(b) !== b) {
- error("Expected a small integer and instead saw '{a}'.",
- v, v.value);
+
+ if (typeof b !== "number" || !isFinite(b) || b <= 0 || Math.floor(b) !== b) {
+ error("Expected a small integer and instead saw '{a}'.", v, v.value);
}
- obj.maxlen = b;
- } else if (t.value === 'validthis') {
- if (funct['(global)']) {
+
+ if (t.value === "indent")
+ obj.white = true;
+
+ obj[t.value] = b;
+ } else if (t.value === "validthis") {
+ if (funct["(global)"]) {
error("Option 'validthis' can't be used in a global scope.");
} else {
- if (v.value === 'true' || v.value === 'false')
- obj[t.value] = v.value === 'true';
+ if (v.value === "true" || v.value === "false")
+ obj[t.value] = v.value === "true";
else
error("Bad option value.", v);
}
- } else if (v.value === 'true') {
- obj[t.value] = true;
- } else if (v.value === 'false') {
- obj[t.value] = false;
+ } else if (t.value === "quotmark" && (o === "/*jshint")) {
+ switch (v.value) {
+ case "true":
+ obj.quotmark = true;
+ break;
+ case "false":
+ obj.quotmark = false;
+ break;
+ case "double":
+ case "single":
+ obj.quotmark = v.value;
+ break;
+ default:
+ error("Bad option value.", v);
+ }
+ } else if (v.value === "true" || v.value === "false") {
+ if (o === "/*jslint") {
+ tn = renamedOptions[t.value] || t.value;
+ obj[tn] = v.value === "true";
+ if (invertedOptions[tn] !== undefined) {
+ obj[tn] = !obj[tn];
+ }
+ } else {
+ obj[t.value] = v.value === "true";
+ }
+
+ if (t.value === "newcap")
+ obj["(explicitNewcap)"] = true;
} else {
error("Bad option value.", v);
}
t = lex.token();
} else {
- if (o === '/*jshint' || o === '/*jslint') {
+ if (o === "/*jshint" || o === "/*jslint") {
error("Missing option value.", t);
}
+
obj[t.value] = false;
+
+ if (o === "/*global" && minus === true) {
+ JSHINT.blacklist[t.value] = t.value;
+ updatePredefined();
+ }
+
t = v;
}
}
+
+ if (o === "/*members") {
+ option.quotmark = quotmarkValue;
+ }
+
+ combine(predefined, predef);
+
+ for (var key in predef) {
+ if (is_own(predef, key)) {
+ declared[key] = nt;
+ }
+ }
+
if (filter) {
assume();
}
@@ -1834,36 +2077,36 @@ loop: for (;;) {
function advance(id, t) {
switch (token.id) {
- case '(number)':
- if (nexttoken.id === '.') {
+ case "(number)":
+ if (nexttoken.id === ".") {
warning("A dot following a number can be confused with a decimal point.", token);
}
break;
- case '-':
- if (nexttoken.id === '-' || nexttoken.id === '--') {
+ case "-":
+ if (nexttoken.id === "-" || nexttoken.id === "--") {
warning("Confusing minusses.");
}
break;
- case '+':
- if (nexttoken.id === '+' || nexttoken.id === '++') {
+ case "+":
+ if (nexttoken.id === "+" || nexttoken.id === "++") {
warning("Confusing plusses.");
}
break;
}
- if (token.type === '(string)' || token.identifier) {
+ if (token.type === "(string)" || token.identifier) {
anonname = token.value;
}
if (id && nexttoken.id !== id) {
if (t) {
- if (nexttoken.id === '(end)') {
+ if (nexttoken.id === "(end)") {
warning("Unmatched '{a}'.", t, t.id);
} else {
warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
nexttoken, id, t.id, t.line, nexttoken.value);
}
- } else if (nexttoken.type !== '(identifier)' ||
+ } else if (nexttoken.type !== "(identifier)" ||
nexttoken.value !== id) {
warning("Expected '{a}' and instead saw '{b}'.",
nexttoken, id, nexttoken.value);
@@ -1874,13 +2117,13 @@ loop: for (;;) {
token = nexttoken;
for (;;) {
nexttoken = lookahead.shift() || lex.token();
- if (nexttoken.id === '(end)' || nexttoken.id === '(error)') {
+ if (nexttoken.id === "(end)" || nexttoken.id === "(error)") {
return;
}
- if (nexttoken.type === 'special') {
+ if (nexttoken.type === "special") {
doOption();
} else {
- if (nexttoken.id !== '(endline)') {
+ if (nexttoken.id !== "(endline)") {
break;
}
}
@@ -1903,15 +2146,15 @@ loop: for (;;) {
// They are elements of the parsing method called Top Down Operator Precedence.
function expression(rbp, initial) {
- var left, isArray = false;
+ var left, isArray = false, isObject = false;
- if (nexttoken.id === '(end)')
+ if (nexttoken.id === "(end)")
error("Unexpected early end of program.", token);
advance();
if (initial) {
- anonname = 'anonymous';
- funct['(verb)'] = token.value;
+ anonname = "anonymous";
+ funct["(verb)"] = token.value;
}
if (initial === true && token.fud) {
left = token.fud();
@@ -1919,7 +2162,7 @@ loop: for (;;) {
if (token.nud) {
left = token.nud();
} else {
- if (nexttoken.type === '(number)' && token.id === '.') {
+ if (nexttoken.type === "(number)" && token.id === ".") {
warning("A leading decimal point can be confused with a dot: '.{a}'.",
token, nexttoken.value);
advance();
@@ -1930,10 +2173,32 @@ loop: for (;;) {
}
}
while (rbp < nexttoken.lbp) {
- isArray = token.value === 'Array';
+ isArray = token.value === "Array";
+ isObject = token.value === "Object";
+
+ // #527, new Foo.Array(), Foo.Array(), new Foo.Object(), Foo.Object()
+ // Line breaks in IfStatement heads exist to satisfy the checkJSHint
+ // "Line too long." error.
+ if (left && (left.value || (left.first && left.first.value))) {
+ // If the left.value is not "new", or the left.first.value is a "."
+ // then safely assume that this is not "new Array()" and possibly
+ // not "new Object()"...
+ if (left.value !== "new" ||
+ (left.first && left.first.value && left.first.value === ".")) {
+ isArray = false;
+ // ...In the case of Object, if the left.value and token.value
+ // are not equal, then safely assume that this not "new Object()"
+ if (left.value !== token.value) {
+ isObject = false;
+ }
+ }
+ }
+
advance();
- if (isArray && token.id === '(' && nexttoken.id === ')')
+ if (isArray && token.id === "(" && nexttoken.id === ")")
warning("Use the array literal notation [].", token);
+ if (isObject && token.id === "(" && nexttoken.id === ")")
+ warning("Use the object literal notation {}.", token);
if (token.led) {
left = token.led(left);
} else {
@@ -1981,6 +2246,9 @@ loop: for (;;) {
if (option.white) {
left = left || token;
right = right || nexttoken;
+ if (left.value === ";" && right.value === ";") {
+ return;
+ }
if (left.line === right.line && left.character === right.from) {
left.from += (left.character - left.from);
warning("Missing space after '{a}'.",
@@ -2007,7 +2275,7 @@ loop: for (;;) {
function indentation(bias) {
var i;
- if (option.white && nexttoken.id !== '(end)') {
+ if (option.white && nexttoken.id !== "(end)") {
i = indent + (bias || 0);
if (nexttoken.from !== i) {
warning(
@@ -2038,19 +2306,17 @@ loop: for (;;) {
token.from += (token.character - token.from);
warning("Unexpected space after '{a}'.", token, token.value);
}
- advance(',');
+ advance(",");
nonadjacent(token, nexttoken);
}
- comma.first = true;
-
// Functional constructors for making the symbols that will be inherited by
// tokens.
function symbol(s, p) {
var x = syntax[s];
- if (!x || typeof x !== 'object') {
+ if (!x || typeof x !== "object") {
syntax[s] = x = {
id: s,
lbp: p,
@@ -2083,7 +2349,7 @@ loop: for (;;) {
function reserveName(x) {
var c = x.id.charAt(0);
- if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+ if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) {
x.identifier = x.reserved = true;
}
return x;
@@ -2093,14 +2359,14 @@ loop: for (;;) {
function prefix(s, f) {
var x = symbol(s, 150);
reserveName(x);
- x.nud = (typeof f === 'function') ? f : function () {
+ x.nud = (typeof f === "function") ? f : function () {
this.right = expression(150);
- this.arity = 'unary';
- if (this.id === '++' || this.id === '--') {
+ this.arity = "unary";
+ if (this.id === "++" || this.id === "--") {
if (option.plusplus) {
warning("Unexpected use of '{a}'.", this, this.id);
} else if ((!this.right.identifier || this.right.reserved) &&
- this.right.id !== '.' && this.right.id !== '[') {
+ this.right.id !== "." && this.right.id !== "[") {
warning("Bad operand.", this);
}
}
@@ -2127,7 +2393,7 @@ loop: for (;;) {
function reservevar(s, v) {
return reserve(s, function () {
- if (typeof v === 'function') {
+ if (typeof v === "function") {
v(this);
}
return this;
@@ -2144,9 +2410,9 @@ loop: for (;;) {
nonadjacent(token, nexttoken);
}
if (s === "in" && left.id === "!") {
- warning("Confusing use of '{a}'.", left, '!');
+ warning("Confusing use of '{a}'.", left, "!");
}
- if (typeof f === 'function') {
+ if (typeof f === "function") {
return f(left, this);
} else {
this.left = left;
@@ -2164,16 +2430,17 @@ loop: for (;;) {
nobreaknonadjacent(prevtoken, token);
nonadjacent(token, nexttoken);
var right = expression(100);
- if ((left && left.id === 'NaN') || (right && right.id === 'NaN')) {
+
+ if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) {
warning("Use the isNaN function to compare with NaN.", this);
} else if (f) {
f.apply(this, [left, right]);
}
- if (left.id === '!') {
- warning("Confusing use of '{a}'.", left, '!');
+ if (left.id === "!") {
+ warning("Confusing use of '{a}'.", left, "!");
}
- if (right.id === '!') {
- warning("Confusing use of '{a}'.", right, '!');
+ if (right.id === "!") {
+ warning("Confusing use of '{a}'.", right, "!");
}
this.left = left;
this.right = right;
@@ -2185,49 +2452,54 @@ loop: for (;;) {
function isPoorRelation(node) {
return node &&
- ((node.type === '(number)' && +node.value === 0) ||
- (node.type === '(string)' && node.value === '') ||
- (node.type === 'null' && !option.eqnull) ||
- node.type === 'true' ||
- node.type === 'false' ||
- node.type === 'undefined');
+ ((node.type === "(number)" && +node.value === 0) ||
+ (node.type === "(string)" && node.value === "") ||
+ (node.type === "null" && !option.eqnull) ||
+ node.type === "true" ||
+ node.type === "false" ||
+ node.type === "undefined");
}
- function assignop(s, f) {
+ function assignop(s) {
symbol(s, 20).exps = true;
+
return infix(s, function (left, that) {
- var l;
that.left = left;
+
if (predefined[left.value] === false &&
- scope[left.value]['(global)'] === true) {
+ scope[left.value]["(global)"] === true) {
warning("Read only.", left);
- } else if (left['function']) {
+ } else if (left["function"]) {
warning("'{a}' is a function.", left, left.value);
}
+
if (left) {
- if (option.esnext && funct[left.value] === 'const') {
+ if (option.esnext && funct[left.value] === "const") {
warning("Attempting to override '{a}' which is a constant", left, left.value);
}
- if (left.id === '.' || left.id === '[') {
- if (!left.left || left.left.value === 'arguments') {
- warning('Bad assignment.', that);
+
+ if (left.id === "." || left.id === "[") {
+ if (!left.left || left.left.value === "arguments") {
+ warning("Bad assignment.", that);
}
that.right = expression(19);
return that;
} else if (left.identifier && !left.reserved) {
- if (funct[left.value] === 'exception') {
+ if (funct[left.value] === "exception") {
warning("Do not assign to the exception parameter.", left);
}
that.right = expression(19);
return that;
}
- if (left === syntax['function']) {
+
+ if (left === syntax["function"]) {
warning(
"Expected an identifier in an assignment and instead saw a function invocation.",
token);
}
}
+
error("Bad assignment.", that);
}, 20);
}
@@ -2236,7 +2508,7 @@ loop: for (;;) {
function bitwise(s, f, p) {
var x = symbol(s, p);
reserveName(x);
- x.led = (typeof f === 'function') ? f : function (left) {
+ x.led = (typeof f === "function") ? f : function (left) {
if (option.bitwise) {
warning("Unexpected use of '{a}'.", this, this.id);
}
@@ -2257,12 +2529,12 @@ loop: for (;;) {
nonadjacent(prevtoken, token);
nonadjacent(token, nexttoken);
if (left) {
- if (left.id === '.' || left.id === '[' ||
+ if (left.id === "." || left.id === "[" ||
(left.identifier && !left.reserved)) {
expression(19);
return that;
}
- if (left === syntax['function']) {
+ if (left === syntax["function"]) {
warning(
"Expected an identifier in an assignment, and instead saw a function invocation.",
token);
@@ -2274,13 +2546,13 @@ loop: for (;;) {
}
- function suffix(s, f) {
+ function suffix(s) {
var x = symbol(s, 150);
x.led = function (left) {
if (option.plusplus) {
warning("Unexpected use of '{a}'.", this, this.id);
} else if ((!left.identifier || left.reserved) &&
- left.id !== '.' && left.id !== '[') {
+ left.id !== "." && left.id !== "[") {
warning("Bad operand.", this);
}
this.left = left;
@@ -2299,7 +2571,7 @@ loop: for (;;) {
// `undefined` as a function param is a common pattern to protect
// against the case when somebody does `undefined = true` and
// help with minification. More info: https://gist.github.com/315916
- if (!fnparam || token.value !== 'undefined') {
+ if (!fnparam || token.value !== "undefined") {
warning("Expected an identifier and instead saw '{a}' (a reserved word).",
token, token.id);
}
@@ -2315,7 +2587,7 @@ loop: for (;;) {
if (i) {
return i;
}
- if (token.id === 'function' && nexttoken.id === '(') {
+ if (token.id === "function" && nexttoken.id === "(") {
warning("Missing name in function declaration.");
} else {
error("Expected an identifier and instead saw '{a}'.",
@@ -2326,7 +2598,7 @@ loop: for (;;) {
function reachable(s) {
var i = 0, t;
- if (nexttoken.id !== ';' || noreach) {
+ if (nexttoken.id !== ";" || noreach) {
return;
}
for (;;) {
@@ -2334,8 +2606,8 @@ loop: for (;;) {
if (t.reach) {
return;
}
- if (t.id !== '(endline)') {
- if (t.id === 'function') {
+ if (t.id !== "(endline)") {
+ if (t.id === "function") {
if (!option.latedef) {
break;
}
@@ -2359,26 +2631,34 @@ loop: for (;;) {
return;
}
-// Is this a labelled statement?
+ // Is this a labelled statement?
- if (t.identifier && !t.reserved && peek().id === ':') {
+ if (t.identifier && !t.reserved && peek().id === ":") {
advance();
- advance(':');
+ advance(":");
scope = Object.create(s);
- addlabel(t.value, 'label');
- if (!nexttoken.labelled) {
- warning("Label '{a}' on {b} statement.",
- nexttoken, t.value, nexttoken.value);
+ addlabel(t.value, "label");
+
+ if (!nexttoken.labelled && nexttoken.value !== "{") {
+ warning("Label '{a}' on {b} statement.", nexttoken, t.value, nexttoken.value);
}
- if (jx.test(t.value + ':')) {
- warning("Label '{a}' looks like a javascript url.",
- t, t.value);
+
+ if (jx.test(t.value + ":")) {
+ warning("Label '{a}' looks like a javascript url.", t, t.value);
}
+
nexttoken.label = t.value;
t = nexttoken;
}
-// Parse the statement.
+ // Is it a lonely block?
+
+ if (t.id === "{") {
+ block(true, true);
+ return;
+ }
+
+ // Parse the statement.
if (!noindent) {
indentation();
@@ -2386,27 +2666,32 @@ loop: for (;;) {
r = expression(0, true);
// Look for the final semicolon.
+
if (!t.block) {
if (!option.expr && (!r || !r.exps)) {
warning("Expected an assignment or function call and instead saw an expression.",
token);
- } else if (option.nonew && r.id === '(' && r.left.id === 'new') {
- warning("Do not use 'new' for side effects.");
+ } else if (option.nonew && r.id === "(" && r.left.id === "new") {
+ warning("Do not use 'new' for side effects.", t);
}
- if (nexttoken.id !== ';') {
+ if (nexttoken.id === ",") {
+ return comma();
+ }
+
+ if (nexttoken.id !== ";") {
if (!option.asi) {
// If this is the last statement in a block that ends on
// the same line *and* option lastsemic is on, ignore the warning.
// Otherwise, complain about missing semicolon.
- if (!option.lastsemic || nexttoken.id !== '}' ||
+ if (!option.lastsemic || nexttoken.id !== "}" ||
nexttoken.line !== token.line) {
warningAt("Missing semicolon.", token.line, token.character);
}
}
} else {
adjacent(token, nexttoken);
- advance(';');
+ advance(";");
nonadjacent(token, nexttoken);
}
}
@@ -2420,15 +2705,15 @@ loop: for (;;) {
function statements(startLine) {
- var a = [], f, p;
+ var a = [], p;
- while (!nexttoken.reach && nexttoken.id !== '(end)') {
- if (nexttoken.id === ';') {
+ while (!nexttoken.reach && nexttoken.id !== "(end)") {
+ if (nexttoken.id === ";") {
p = peek();
if (!p || p.id !== "(") {
warning("Unnecessary semicolon.");
}
- advance(';');
+ advance(";");
} else {
a.push(statement(startLine === nexttoken.line));
}
@@ -2479,7 +2764,8 @@ loop: for (;;) {
}
if (token.value === "use strict") {
- option.newcap = true;
+ if (!option["(explicitNewcap)"])
+ option.newcap = true;
option.undef = true;
}
@@ -2515,14 +2801,21 @@ loop: for (;;) {
d;
inblock = ordinary;
- if (!ordinary || !option.funcscope) scope = Object.create(scope);
+
+ if (!ordinary || !option.funcscope)
+ scope = Object.create(scope);
+
nonadjacent(token, nexttoken);
t = nexttoken;
- if (nexttoken.id === '{') {
- advance('{');
+ var metrics = funct["(metrics)"];
+ metrics.nestedBlockDepth += 1;
+ metrics.verifyMaxNestedBlockDepthPerFunction();
+
+ if (nexttoken.id === "{") {
+ advance("{");
line = token.line;
- if (nexttoken.id !== '}') {
+ if (nexttoken.id !== "}") {
indent += option.indent;
while (!ordinary && nexttoken.from > indent) {
indent += option.indent;
@@ -2537,7 +2830,7 @@ loop: for (;;) {
}
directives();
- if (option.strict && funct['(context)']['(global)']) {
+ if (option.strict && funct["(context)"]["(global)"]) {
if (!m["use strict"] && !directive["use strict"]) {
warning("Missing \"use strict\" statement.");
}
@@ -2546,6 +2839,8 @@ loop: for (;;) {
a = statements(line);
+ metrics.statementCount += a.length;
+
if (isfunc) {
directive = m;
}
@@ -2557,15 +2852,15 @@ loop: for (;;) {
} else if (line !== nexttoken.line) {
indentation();
}
- advance('}', t);
+ advance("}", t);
indent = old_indent;
} else if (!ordinary) {
error("Expected '{a}' and instead saw '{b}'.",
- nexttoken, '{', nexttoken.value);
+ nexttoken, "{", nexttoken.value);
} else {
if (!stmt || option.curly)
warning("Expected '{a}' and instead saw '{b}'.",
- nexttoken, '{', nexttoken.value);
+ nexttoken, "{", nexttoken.value);
noreach = true;
indent += option.indent;
@@ -2574,21 +2869,22 @@ loop: for (;;) {
indent -= option.indent;
noreach = false;
}
- funct['(verb)'] = null;
+ funct["(verb)"] = null;
if (!ordinary || !option.funcscope) scope = s;
inblock = b;
if (ordinary && option.noempty && (!a || a.length === 0)) {
warning("Empty block.");
}
+ metrics.nestedBlockDepth -= 1;
return a;
}
function countMember(m) {
- if (membersOnly && typeof membersOnly[m] !== 'boolean') {
+ if (membersOnly && typeof membersOnly[m] !== "boolean") {
warning("Unexpected /*member '{a}'.", token, m);
}
- if (typeof member[m] === 'number') {
+ if (typeof member[m] === "number") {
member[m] += 1;
} else {
member[m] = 1;
@@ -2598,7 +2894,7 @@ loop: for (;;) {
function note_implied(token) {
var name = token.value, line = token.line, a = implied[name];
- if (typeof a === 'function') {
+ if (typeof a === "function") {
a = false;
}
@@ -2613,16 +2909,16 @@ loop: for (;;) {
// Build the syntax table by declaring the syntactic elements of the language.
- type('(number)', function () {
+ type("(number)", function () {
return this;
});
- type('(string)', function () {
+ type("(string)", function () {
return this;
});
- syntax['(identifier)'] = {
- type: '(identifier)',
+ syntax["(identifier)"] = {
+ type: "(identifier)",
lbp: 0,
identifier: true,
nud: function () {
@@ -2630,13 +2926,13 @@ loop: for (;;) {
s = scope[v],
f;
- if (typeof s === 'function') {
+ if (typeof s === "function") {
// Protection against accidental inheritance.
s = undefined;
- } else if (typeof s === 'boolean') {
+ } else if (typeof s === "boolean") {
f = funct;
funct = functions[0];
- addlabel(v, 'var');
+ addlabel(v, "var");
s = funct;
funct = f;
}
@@ -2645,21 +2941,21 @@ loop: for (;;) {
if (funct === s) {
// Change 'unused' to 'var', and reject labels.
switch (funct[v]) {
- case 'unused':
- funct[v] = 'var';
+ case "unused":
+ funct[v] = "var";
break;
- case 'unction':
- funct[v] = 'function';
- this['function'] = true;
+ case "unction":
+ funct[v] = "function";
+ this["function"] = true;
break;
- case 'function':
- this['function'] = true;
+ case "function":
+ this["function"] = true;
break;
- case 'label':
+ case "label":
warning("'{a}' is a statement label.", token, v);
break;
}
- } else if (funct['(global)']) {
+ } else if (funct["(global)"]) {
// The name is not defined in the function. If we are in the global
// scope, then we have an undefined variable.
//
@@ -2667,32 +2963,33 @@ loop: for (;;) {
// the base object of a reference is null so no need to display warning
// if we're inside of typeof or delete.
- if (option.undef && typeof predefined[v] !== 'boolean') {
+ if (option.undef && typeof predefined[v] !== "boolean") {
// Attempting to subscript a null reference will throw an
// error, even within the typeof and delete operators
- if (!(anonname === 'typeof' || anonname === 'delete') ||
- (nexttoken && (nexttoken.value === '.' || nexttoken.value === '['))) {
+ if (!(anonname === "typeof" || anonname === "delete") ||
+ (nexttoken && (nexttoken.value === "." || nexttoken.value === "["))) {
isundef(funct, "'{a}' is not defined.", token, v);
}
}
+
note_implied(token);
} else {
// If the name is already defined in the current
// function, but not as outer, then there is a scope error.
switch (funct[v]) {
- case 'closure':
- case 'function':
- case 'var':
- case 'unused':
+ case "closure":
+ case "function":
+ case "var":
+ case "unused":
warning("'{a}' used out of scope.", token, v);
break;
- case 'label':
+ case "label":
warning("'{a}' is a statement label.", token, v);
break;
- case 'outer':
- case 'global':
+ case "outer":
+ case "global":
break;
default:
// If the name is defined in an outer function, make an outer entry,
@@ -2702,16 +2999,16 @@ loop: for (;;) {
} else if (s === null) {
warning("'{a}' is not allowed.", token, v);
note_implied(token);
- } else if (typeof s !== 'object') {
+ } else if (typeof s !== "object") {
// Operators typeof and delete do not raise runtime errors even
// if the base object of a reference is null so no need to
// display warning if we're inside of typeof or delete.
if (option.undef) {
// Attempting to subscript a null reference will throw an
// error, even within the typeof and delete operators
- if (!(anonname === 'typeof' || anonname === 'delete') ||
+ if (!(anonname === "typeof" || anonname === "delete") ||
(nexttoken &&
- (nexttoken.value === '.' || nexttoken.value === '['))) {
+ (nexttoken.value === "." || nexttoken.value === "["))) {
isundef(funct, "'{a}' is not defined.", token, v);
}
@@ -2720,22 +3017,21 @@ loop: for (;;) {
note_implied(token);
} else {
switch (s[v]) {
- case 'function':
- case 'unction':
- this['function'] = true;
- s[v] = 'closure';
- funct[v] = s['(global)'] ? 'global' : 'outer';
+ case "function":
+ case "unction":
+ this["function"] = true;
+ s[v] = "closure";
+ funct[v] = s["(global)"] ? "global" : "outer";
break;
- case 'var':
- case 'unused':
- s[v] = 'closure';
- funct[v] = s['(global)'] ? 'global' : 'outer';
+ case "var":
+ case "unused":
+ s[v] = "closure";
+ funct[v] = s["(global)"] ? "global" : "outer";
break;
- case 'closure':
- case 'parameter':
- funct[v] = s['(global)'] ? 'global' : 'outer';
+ case "closure":
+ funct[v] = s["(global)"] ? "global" : "outer";
break;
- case 'label':
+ case "label":
warning("'{a}' is a statement label.", token, v);
}
}
@@ -2749,123 +3045,122 @@ loop: for (;;) {
}
};
- type('(regexp)', function () {
+ type("(regexp)", function () {
return this;
});
// ECMAScript parser
- delim('(endline)');
- delim('(begin)');
- delim('(end)').reach = true;
- delim('</').reach = true;
- delim('<!');
- delim('<!--');
- delim('-->');
- delim('(error)').reach = true;
- delim('}').reach = true;
- delim(')');
- delim(']');
- delim('"').reach = true;
+ delim("(endline)");
+ delim("(begin)");
+ delim("(end)").reach = true;
+ delim("</").reach = true;
+ delim("<!");
+ delim("<!--");
+ delim("-->");
+ delim("(error)").reach = true;
+ delim("}").reach = true;
+ delim(")");
+ delim("]");
+ delim("\"").reach = true;
delim("'").reach = true;
- delim(';');
- delim(':').reach = true;
- delim(',');
- delim('#');
- delim('@');
- reserve('else');
- reserve('case').reach = true;
- reserve('catch');
- reserve('default').reach = true;
- reserve('finally');
- reservevar('arguments', function (x) {
- if (directive['use strict'] && funct['(global)']) {
+ delim(";");
+ delim(":").reach = true;
+ delim(",");
+ delim("#");
+ delim("@");
+ reserve("else");
+ reserve("case").reach = true;
+ reserve("catch");
+ reserve("default").reach = true;
+ reserve("finally");
+ reservevar("arguments", function (x) {
+ if (directive["use strict"] && funct["(global)"]) {
warning("Strict violation.", x);
}
});
- reservevar('eval');
- reservevar('false');
- reservevar('Infinity');
- reservevar('NaN');
- reservevar('null');
- reservevar('this', function (x) {
- if (directive['use strict'] && !option.validthis && ((funct['(statement)'] &&
- funct['(name)'].charAt(0) > 'Z') || funct['(global)'])) {
+ reservevar("eval");
+ reservevar("false");
+ reservevar("Infinity");
+ reservevar("null");
+ reservevar("this", function (x) {
+ if (directive["use strict"] && !option.validthis && ((funct["(statement)"] &&
+ funct["(name)"].charAt(0) > "Z") || funct["(global)"])) {
warning("Possible strict violation.", x);
}
});
- reservevar('true');
- reservevar('undefined');
- assignop('=', 'assign', 20);
- assignop('+=', 'assignadd', 20);
- assignop('-=', 'assignsub', 20);
- assignop('*=', 'assignmult', 20);
- assignop('/=', 'assigndiv', 20).nud = function () {
+ reservevar("true");
+ reservevar("undefined");
+ assignop("=", "assign", 20);
+ assignop("+=", "assignadd", 20);
+ assignop("-=", "assignsub", 20);
+ assignop("*=", "assignmult", 20);
+ assignop("/=", "assigndiv", 20).nud = function () {
error("A regular expression literal can be confused with '/='.");
};
- assignop('%=', 'assignmod', 20);
- bitwiseassignop('&=', 'assignbitand', 20);
- bitwiseassignop('|=', 'assignbitor', 20);
- bitwiseassignop('^=', 'assignbitxor', 20);
- bitwiseassignop('<<=', 'assignshiftleft', 20);
- bitwiseassignop('>>=', 'assignshiftright', 20);
- bitwiseassignop('>>>=', 'assignshiftrightunsigned', 20);
- infix('?', function (left, that) {
+ assignop("%=", "assignmod", 20);
+ bitwiseassignop("&=", "assignbitand", 20);
+ bitwiseassignop("|=", "assignbitor", 20);
+ bitwiseassignop("^=", "assignbitxor", 20);
+ bitwiseassignop("<<=", "assignshiftleft", 20);
+ bitwiseassignop(">>=", "assignshiftright", 20);
+ bitwiseassignop(">>>=", "assignshiftrightunsigned", 20);
+ infix("?", function (left, that) {
that.left = left;
that.right = expression(10);
- advance(':');
- that['else'] = expression(10);
+ advance(":");
+ that["else"] = expression(10);
return that;
}, 30);
- infix('||', 'or', 40);
- infix('&&', 'and', 50);
- bitwise('|', 'bitor', 70);
- bitwise('^', 'bitxor', 80);
- bitwise('&', 'bitand', 90);
- relation('==', function (left, right) {
- var eqnull = option.eqnull && (left.value === 'null' || right.value === 'null');
+ infix("||", "or", 40);
+ infix("&&", "and", 50);
+ bitwise("|", "bitor", 70);
+ bitwise("^", "bitxor", 80);
+ bitwise("&", "bitand", 90);
+ relation("==", function (left, right) {
+ var eqnull = option.eqnull && (left.value === "null" || right.value === "null");
if (!eqnull && option.eqeqeq)
- warning("Expected '{a}' and instead saw '{b}'.", this, '===', '==');
+ warning("Expected '{a}' and instead saw '{b}'.", this, "===", "==");
else if (isPoorRelation(left))
- warning("Use '{a}' to compare with '{b}'.", this, '===', left.value);
+ warning("Use '{a}' to compare with '{b}'.", this, "===", left.value);
else if (isPoorRelation(right))
- warning("Use '{a}' to compare with '{b}'.", this, '===', right.value);
+ warning("Use '{a}' to compare with '{b}'.", this, "===", right.value);
return this;
});
- relation('===');
- relation('!=', function (left, right) {
+ relation("===");
+ relation("!=", function (left, right) {
var eqnull = option.eqnull &&
- (left.value === 'null' || right.value === 'null');
+ (left.value === "null" || right.value === "null");
if (!eqnull && option.eqeqeq) {
warning("Expected '{a}' and instead saw '{b}'.",
- this, '!==', '!=');
+ this, "!==", "!=");
} else if (isPoorRelation(left)) {
warning("Use '{a}' to compare with '{b}'.",
- this, '!==', left.value);
+ this, "!==", left.value);
} else if (isPoorRelation(right)) {
warning("Use '{a}' to compare with '{b}'.",
- this, '!==', right.value);
+ this, "!==", right.value);
}
return this;
});
- relation('!==');
- relation('<');
- relation('>');
- relation('<=');
- relation('>=');
- bitwise('<<', 'shiftleft', 120);
- bitwise('>>', 'shiftright', 120);
- bitwise('>>>', 'shiftrightunsigned', 120);
- infix('in', 'in', 120);
- infix('instanceof', 'instanceof', 120);
- infix('+', function (left, that) {
+ relation("!==");
+ relation("<");
+ relation(">");
+ relation("<=");
+ relation(">=");
+ bitwise("<<", "shiftleft", 120);
+ bitwise(">>", "shiftright", 120);
+ bitwise(">>>", "shiftrightunsigned", 120);
+ infix("in", "in", 120);
+ infix("instanceof", "instanceof", 120);
+ infix("+", function (left, that) {
var right = expression(130);
- if (left && right && left.id === '(string)' && right.id === '(string)') {
+ if (left && right && left.id === "(string)" && right.id === "(string)") {
left.value += right.value;
left.character = right.character;
if (!option.scripturl && jx.test(left.value)) {
@@ -2877,105 +3172,102 @@ loop: for (;;) {
that.right = right;
return that;
}, 130);
- prefix('+', 'num');
- prefix('+++', function () {
+ prefix("+", "num");
+ prefix("+++", function () {
warning("Confusing pluses.");
this.right = expression(150);
- this.arity = 'unary';
+ this.arity = "unary";
return this;
});
- infix('+++', function (left) {
+ infix("+++", function (left) {
warning("Confusing pluses.");
this.left = left;
this.right = expression(130);
return this;
}, 130);
- infix('-', 'sub', 130);
- prefix('-', 'neg');
- prefix('---', function () {
+ infix("-", "sub", 130);
+ prefix("-", "neg");
+ prefix("---", function () {
warning("Confusing minuses.");
this.right = expression(150);
- this.arity = 'unary';
+ this.arity = "unary";
return this;
});
- infix('---', function (left) {
+ infix("---", function (left) {
warning("Confusing minuses.");
this.left = left;
this.right = expression(130);
return this;
}, 130);
- infix('*', 'mult', 140);
- infix('/', 'div', 140);
- infix('%', 'mod', 140);
-
- suffix('++', 'postinc');
- prefix('++', 'preinc');
- syntax['++'].exps = true;
-
- suffix('--', 'postdec');
- prefix('--', 'predec');
- syntax['--'].exps = true;
- prefix('delete', function () {
+ infix("*", "mult", 140);
+ infix("/", "div", 140);
+ infix("%", "mod", 140);
+
+ suffix("++", "postinc");
+ prefix("++", "preinc");
+ syntax["++"].exps = true;
+
+ suffix("--", "postdec");
+ prefix("--", "predec");
+ syntax["--"].exps = true;
+ prefix("delete", function () {
var p = expression(0);
- if (!p || (p.id !== '.' && p.id !== '[')) {
+ if (!p || (p.id !== "." && p.id !== "[")) {
warning("Variables should not be deleted.");
}
this.first = p;
return this;
}).exps = true;
- prefix('~', function () {
+ prefix("~", function () {
if (option.bitwise) {
- warning("Unexpected '{a}'.", this, '~');
+ warning("Unexpected '{a}'.", this, "~");
}
expression(150);
return this;
});
- prefix('!', function () {
+ prefix("!", function () {
this.right = expression(150);
- this.arity = 'unary';
+ this.arity = "unary";
if (bang[this.right.id] === true) {
- warning("Confusing use of '{a}'.", this, '!');
+ warning("Confusing use of '{a}'.", this, "!");
}
return this;
});
- prefix('typeof', 'typeof');
- prefix('new', function () {
+ prefix("typeof", "typeof");
+ prefix("new", function () {
var c = expression(155), i;
- if (c && c.id !== 'function') {
+ if (c && c.id !== "function") {
if (c.identifier) {
- c['new'] = true;
+ c["new"] = true;
switch (c.value) {
- case 'Object':
- warning("Use the object literal notation {}.", token);
- break;
- case 'Number':
- case 'String':
- case 'Boolean':
- case 'Math':
- case 'JSON':
- warning("Do not use {a} as a constructor.", token, c.value);
+ case "Number":
+ case "String":
+ case "Boolean":
+ case "Math":
+ case "JSON":
+ warning("Do not use {a} as a constructor.", prevtoken, c.value);
break;
- case 'Function':
+ case "Function":
if (!option.evil) {
warning("The Function constructor is eval.");
}
break;
- case 'Date':
- case 'RegExp':
+ case "Date":
+ case "RegExp":
break;
default:
- if (c.id !== 'function') {
+ if (c.id !== "function") {
i = c.value.substr(0, 1);
- if (option.newcap && (i < 'A' || i > 'Z')) {
+ if (option.newcap && (i < "A" || i > "Z") && !is_own(global, c.value)) {
warning("A constructor name should start with an uppercase letter.",
token);
}
}
}
} else {
- if (c.id !== '.' && c.id !== '[' && c.id !== '(') {
+ if (c.id !== "." && c.id !== "[" && c.id !== "(") {
warning("Bad constructor.", token);
}
}
@@ -2984,46 +3276,47 @@ loop: for (;;) {
warning("Weird construction. Delete 'new'.", this);
}
adjacent(token, nexttoken);
- if (nexttoken.id !== '(' && !option.supernew) {
- warning("Missing '()' invoking a constructor.");
+ if (nexttoken.id !== "(" && !option.supernew) {
+ warning("Missing '()' invoking a constructor.",
+ token, token.value);
}
this.first = c;
return this;
});
- syntax['new'].exps = true;
+ syntax["new"].exps = true;
- prefix('void').exps = true;
+ prefix("void").exps = true;
- infix('.', function (left, that) {
+ infix(".", function (left, that) {
adjacent(prevtoken, token);
nobreak();
var m = identifier();
- if (typeof m === 'string') {
+ if (typeof m === "string") {
countMember(m);
}
that.left = left;
that.right = m;
- if (left && left.value === 'arguments' && (m === 'callee' || m === 'caller')) {
+ if (left && left.value === "arguments" && (m === "callee" || m === "caller")) {
if (option.noarg)
warning("Avoid arguments.{a}.", left, m);
- else if (directive['use strict'])
- error('Strict violation.');
- } else if (!option.evil && left && left.value === 'document' &&
- (m === 'write' || m === 'writeln')) {
+ else if (directive["use strict"])
+ error("Strict violation.");
+ } else if (!option.evil && left && left.value === "document" &&
+ (m === "write" || m === "writeln")) {
warning("document.write can be a form of eval.", left);
}
- if (!option.evil && (m === 'eval' || m === 'execScript')) {
- warning('eval is evil.');
+ if (!option.evil && (m === "eval" || m === "execScript")) {
+ warning("eval is evil.");
}
return that;
}, 160, true);
- infix('(', function (left, that) {
- if (prevtoken.id !== '}' && prevtoken.id !== ')') {
+ infix("(", function (left, that) {
+ if (prevtoken.id !== "}" && prevtoken.id !== ")") {
nobreak(prevtoken, token);
}
nospace();
- if (option.immed && !left.immed && left.id === 'function') {
+ if (option.immed && !left.immed && left.id === "function") {
warning("Wrap an immediate function invocation in parentheses " +
"to assist the reader in understanding that the expression " +
"is the result of a function, and not the function itself.");
@@ -3031,51 +3324,63 @@ loop: for (;;) {
var n = 0,
p = [];
if (left) {
- if (left.type === '(identifier)') {
+ if (left.type === "(identifier)") {
if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
- if (left.value !== 'Number' && left.value !== 'String' &&
- left.value !== 'Boolean' &&
- left.value !== 'Date') {
- if (left.value === 'Math') {
+ if ("Number String Boolean Date Object".indexOf(left.value) === -1) {
+ if (left.value === "Math") {
warning("Math is not a function.", left);
} else if (option.newcap) {
- warning(
-"Missing 'new' prefix when invoking a constructor.", left);
+ warning("Missing 'new' prefix when invoking a constructor.", left);
}
}
}
}
}
- if (nexttoken.id !== ')') {
+ if (nexttoken.id !== ")") {
for (;;) {
p[p.length] = expression(10);
n += 1;
- if (nexttoken.id !== ',') {
+ if (nexttoken.id !== ",") {
break;
}
comma();
}
}
- advance(')');
+ advance(")");
nospace(prevtoken, token);
- if (typeof left === 'object') {
- if (left.value === 'parseInt' && n === 1) {
- warning("Missing radix parameter.", left);
+ if (typeof left === "object") {
+ if (left.value === "parseInt" && n === 1) {
+ warning("Missing radix parameter.", token);
}
if (!option.evil) {
- if (left.value === 'eval' || left.value === 'Function' ||
- left.value === 'execScript') {
+ if (left.value === "eval" || left.value === "Function" ||
+ left.value === "execScript") {
warning("eval is evil.", left);
- } else if (p[0] && p[0].id === '(string)' &&
- (left.value === 'setTimeout' ||
- left.value === 'setInterval')) {
+
+ if (p[0] && [0].id === "(string)") {
+ addInternalSrc(left, p[0].value);
+ }
+ } else if (p[0] && p[0].id === "(string)" &&
+ (left.value === "setTimeout" ||
+ left.value === "setInterval")) {
+ warning(
+ "Implied eval is evil. Pass a function instead of a string.", left);
+ addInternalSrc(left, p[0].value);
+
+ // window.setTimeout/setInterval
+ } else if (p[0] && p[0].id === "(string)" &&
+ left.value === "." &&
+ left.left.value === "window" &&
+ (left.right === "setTimeout" ||
+ left.right === "setInterval")) {
warning(
"Implied eval is evil. Pass a function instead of a string.", left);
+ addInternalSrc(left, p[0].value);
}
}
- if (!left.identifier && left.id !== '.' && left.id !== '[' &&
- left.id !== '(' && left.id !== '&&' && left.id !== '||' &&
- left.id !== '?') {
+ if (!left.identifier && left.id !== "." && left.id !== "[" &&
+ left.id !== "(" && left.id !== "&&" && left.id !== "||" &&
+ left.id !== "?") {
warning("Bad invocation.", left);
}
}
@@ -3083,34 +3388,32 @@ loop: for (;;) {
return that;
}, 155, true).exps = true;
- prefix('(', function () {
+ prefix("(", function () {
nospace();
- if (nexttoken.id === 'function') {
+ if (nexttoken.id === "function") {
nexttoken.immed = true;
}
var v = expression(0);
- advance(')', this);
+ advance(")", this);
nospace(prevtoken, token);
- if (option.immed && v.id === 'function') {
- if (nexttoken.id === '(' ||
- (nexttoken.id === '.' && (peek().value === 'call' || peek().value === 'apply'))) {
- warning(
-"Move the invocation into the parens that contain the function.", nexttoken);
- } else {
+ if (option.immed && v.id === "function") {
+ if (nexttoken.id !== "(" &&
+ (nexttoken.id !== "." || (peek().value !== "call" && peek().value !== "apply"))) {
warning(
"Do not wrap function literals in parens unless they are to be immediately invoked.",
this);
}
}
+
return v;
});
- infix('[', function (left, that) {
+ infix("[", function (left, that) {
nobreak(prevtoken, token);
nospace();
var e = expression(0), s;
- if (e && e.type === '(string)') {
- if (!option.evil && (e.value === 'eval' || e.value === 'execScript')) {
+ if (e && e.type === "(string)") {
+ if (!option.evil && (e.value === "eval" || e.value === "execScript")) {
warning("eval is evil.", that);
}
countMember(e.value);
@@ -3118,18 +3421,18 @@ loop: for (;;) {
s = syntax[e.value];
if (!s || !s.reserved) {
warning("['{a}'] is better written in dot notation.",
- e, e.value);
+ prevtoken, e.value);
}
}
}
- advance(']', that);
+ advance("]", that);
nospace(prevtoken, token);
that.left = left;
that.right = e;
return that;
}, 160, true);
- prefix('[', function () {
+ prefix("[", function () {
var b = token.line !== nexttoken.line;
this.first = [];
if (b) {
@@ -3138,21 +3441,22 @@ loop: for (;;) {
indent += option.indent;
}
}
- while (nexttoken.id !== '(end)') {
- while (nexttoken.id === ',') {
- warning("Extra comma.");
- advance(',');
+ while (nexttoken.id !== "(end)") {
+ while (nexttoken.id === ",") {
+ if (!option.es5)
+ warning("Extra comma.");
+ advance(",");
}
- if (nexttoken.id === ']') {
+ if (nexttoken.id === "]") {
break;
}
if (b && token.line !== nexttoken.line) {
indentation();
}
this.first.push(expression(10));
- if (nexttoken.id === ',') {
+ if (nexttoken.id === ",") {
comma();
- if (nexttoken.id === ']' && !option.es5) {
+ if (nexttoken.id === "]" && !option.es5) {
warning("Extra comma.", token);
break;
}
@@ -3164,7 +3468,7 @@ loop: for (;;) {
indent -= option.indent;
indentation();
}
- advance(']', this);
+ advance("]", this);
return this;
}, 160);
@@ -3172,10 +3476,10 @@ loop: for (;;) {
function property_name() {
var id = optionalidentifier(true);
if (!id) {
- if (nexttoken.id === '(string)') {
+ if (nexttoken.id === "(string)") {
id = nexttoken.value;
advance();
- } else if (nexttoken.id === '(number)') {
+ } else if (nexttoken.id === "(number)") {
id = nexttoken.value.toString();
advance();
}
@@ -3185,65 +3489,130 @@ loop: for (;;) {
function functionparams() {
- var i, t = nexttoken, p = [];
- advance('(');
+ var next = nexttoken;
+ var params = [];
+ var ident;
+
+ advance("(");
nospace();
- if (nexttoken.id === ')') {
- advance(')');
+
+ if (nexttoken.id === ")") {
+ advance(")");
return;
}
+
for (;;) {
- i = identifier(true);
- p.push(i);
- addlabel(i, 'parameter');
- if (nexttoken.id === ',') {
+ ident = identifier(true);
+ params.push(ident);
+ addlabel(ident, "unused", token);
+ if (nexttoken.id === ",") {
comma();
} else {
- advance(')', t);
+ advance(")", next);
nospace(prevtoken, token);
- return p;
+ return params;
}
}
}
- function doFunction(i, statement) {
- var f,
- oldOption = option,
- oldScope = scope;
+ function doFunction(name, statement) {
+ var f;
+ var oldOption = option;
+ var oldScope = scope;
option = Object.create(option);
- scope = Object.create(scope);
+ scope = Object.create(scope);
funct = {
- '(name)' : i || '"' + anonname + '"',
- '(line)' : nexttoken.line,
- '(context)' : funct,
- '(breakage)' : 0,
- '(loopage)' : 0,
- '(scope)' : scope,
- '(statement)': statement
+ "(name)" : name || "\"" + anonname + "\"",
+ "(line)" : nexttoken.line,
+ "(character)": nexttoken.character,
+ "(context)" : funct,
+ "(breakage)" : 0,
+ "(loopage)" : 0,
+ "(metrics)" : createMetrics(nexttoken),
+ "(scope)" : scope,
+ "(statement)": statement,
+ "(tokens)" : {}
};
+
f = funct;
token.funct = funct;
+
functions.push(funct);
- if (i) {
- addlabel(i, 'function');
+
+ if (name) {
+ addlabel(name, "function");
}
- funct['(params)'] = functionparams();
+
+ funct["(params)"] = functionparams();
+ funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]);
block(false, false, true);
+
+ funct["(metrics)"].verifyMaxStatementsPerFunction();
+ funct["(metrics)"].verifyMaxComplexityPerFunction();
+
scope = oldScope;
option = oldOption;
- funct['(last)'] = token.line;
- funct = funct['(context)'];
+ funct["(last)"] = token.line;
+ funct["(lastcharacter)"] = token.character;
+ funct = funct["(context)"];
+
return f;
}
+ function createMetrics(functionStartToken) {
+ return {
+ statementCount: 0,
+ nestedBlockDepth: -1,
+ ComplexityCount: 1,
+ verifyMaxStatementsPerFunction: function () {
+ if (option.maxstatements &&
+ this.statementCount > option.maxstatements) {
+ var message = "Too many statements per function (" + this.statementCount + ").";
+ warning(message, functionStartToken);
+ }
+ },
+
+ verifyMaxParametersPerFunction: function (params) {
+ params = params || [];
+
+ if (option.maxparams && params.length > option.maxparams) {
+ var message = "Too many parameters per function (" + params.length + ").";
+ warning(message, functionStartToken);
+ }
+ },
+
+ verifyMaxNestedBlockDepthPerFunction: function () {
+ if (option.maxdepth &&
+ this.nestedBlockDepth > 0 &&
+ this.nestedBlockDepth === option.maxdepth + 1) {
+ var message = "Blocks are nested too deeply (" + this.nestedBlockDepth + ").";
+ warning(message);
+ }
+ },
+
+ verifyMaxComplexityPerFunction: function () {
+ var max = option.maxcomplexity;
+ var cc = this.ComplexityCount;
+ if (max && cc > max) {
+ var message = "Cyclomatic complexity is too high per function (" + cc + ").";
+ warning(message, functionStartToken);
+ }
+ }
+ };
+ }
+
+ function increaseComplexityCount() {
+ funct["(metrics)"].ComplexityCount += 1;
+ }
+
(function (x) {
x.nud = function () {
- var b, f, i, j, p, t;
+ var b, f, i, p, t;
var props = {}; // All properties, including accessors
function saveProperty(name, token) {
@@ -3288,14 +3657,14 @@ loop: for (;;) {
}
}
for (;;) {
- if (nexttoken.id === '}') {
+ if (nexttoken.id === "}") {
break;
}
if (b) {
indentation();
}
- if (nexttoken.value === 'get' && peek().id !== ':') {
- advance('get');
+ if (nexttoken.value === "get" && peek().id !== ":") {
+ advance("get");
if (!option.es5) {
error("get/set are ES5 features.");
}
@@ -3307,13 +3676,13 @@ loop: for (;;) {
t = nexttoken;
adjacent(token, nexttoken);
f = doFunction();
- p = f['(params)'];
+ p = f["(params)"];
if (p) {
warning("Unexpected parameter '{a}' in get {b} function.", t, p[0], i);
}
adjacent(token, nexttoken);
- } else if (nexttoken.value === 'set' && peek().id !== ':') {
- advance('set');
+ } else if (nexttoken.value === "set" && peek().id !== ":") {
+ advance("set");
if (!option.es5) {
error("get/set are ES5 features.");
}
@@ -3325,27 +3694,27 @@ loop: for (;;) {
t = nexttoken;
adjacent(token, nexttoken);
f = doFunction();
- p = f['(params)'];
+ p = f["(params)"];
if (!p || p.length !== 1) {
warning("Expected a single parameter in set {a} function.", t, i);
}
} else {
i = property_name();
saveProperty(i, nexttoken);
- if (typeof i !== 'string') {
+ if (typeof i !== "string") {
break;
}
- advance(':');
+ advance(":");
nonadjacent(token, nexttoken);
expression(10);
}
countMember(i);
- if (nexttoken.id === ',') {
+ if (nexttoken.id === ",") {
comma();
- if (nexttoken.id === ',') {
+ if (nexttoken.id === ",") {
warning("Extra comma.", token);
- } else if (nexttoken.id === '}' && !option.es5) {
+ } else if (nexttoken.id === "}" && !option.es5) {
warning("Extra comma.", token);
}
} else {
@@ -3356,7 +3725,7 @@ loop: for (;;) {
indent -= option.indent;
indentation();
}
- advance('}', this);
+ advance("}", this);
// Check for lonely setters if in the ES5 mode.
if (option.es5) {
@@ -3371,13 +3740,13 @@ loop: for (;;) {
x.fud = function () {
error("Expected to see a statement and instead saw a block.", token);
};
- }(delim('{')));
+ }(delim("{")));
// This Function is called when esnext option is set to true
// it adds the `const` statement to JSHINT
useESNextSyntax = function () {
- var conststatement = stmt('const', function (prefix) {
+ var conststatement = stmt("const", function (prefix) {
var id, name, value;
this.first = [];
@@ -3387,10 +3756,10 @@ loop: for (;;) {
if (funct[id] === "const") {
warning("const '" + id + "' has already been declared");
}
- if (funct['(global)'] && predefined[id] === false) {
+ if (funct["(global)"] && predefined[id] === false) {
warning("Redefinition of '{a}'.", token, id);
}
- addlabel(id, 'const');
+ addlabel(id, "const");
if (prefix) {
break;
}
@@ -3402,15 +3771,15 @@ loop: for (;;) {
"'{a}' is initialized to 'undefined'.", token, id);
}
- if (nexttoken.id === '=') {
+ if (nexttoken.id === "=") {
nonadjacent(token, nexttoken);
- advance('=');
+ advance("=");
nonadjacent(token, nexttoken);
- if (nexttoken.id === 'undefined') {
+ if (nexttoken.id === "undefined") {
warning("It is not necessary to initialize " +
"'{a}' to 'undefined'.", token, id);
}
- if (peek(0).id === '=' && nexttoken.identifier) {
+ if (peek(0).id === "=" && nexttoken.identifier) {
error("Constant {a} was not declared correctly.",
nexttoken, nexttoken.value);
}
@@ -3418,7 +3787,7 @@ loop: for (;;) {
name.first = value;
}
- if (nexttoken.id !== ',') {
+ if (nexttoken.id !== ",") {
break;
}
comma();
@@ -3428,47 +3797,55 @@ loop: for (;;) {
conststatement.exps = true;
};
- var varstatement = stmt('var', function (prefix) {
+ var varstatement = stmt("var", function (prefix) {
// JavaScript does not have block scope. It only has function scope. So,
// declaring a variable in a block can have unexpected consequences.
var id, name, value;
- if (funct['(onevar)'] && option.onevar) {
+ if (funct["(onevar)"] && option.onevar) {
warning("Too many var statements.");
- } else if (!funct['(global)']) {
- funct['(onevar)'] = true;
+ } else if (!funct["(global)"]) {
+ funct["(onevar)"] = true;
}
+
this.first = [];
+
for (;;) {
nonadjacent(token, nexttoken);
id = identifier();
+
if (option.esnext && funct[id] === "const") {
warning("const '" + id + "' has already been declared");
}
- if (funct['(global)'] && predefined[id] === false) {
+
+ if (funct["(global)"] && predefined[id] === false) {
warning("Redefinition of '{a}'.", token, id);
}
- addlabel(id, 'unused');
+
+ addlabel(id, "unused", token);
+
if (prefix) {
break;
}
+
name = token;
this.first.push(token);
- if (nexttoken.id === '=') {
+
+ if (nexttoken.id === "=") {
nonadjacent(token, nexttoken);
- advance('=');
+ advance("=");
nonadjacent(token, nexttoken);
- if (nexttoken.id === 'undefined') {
+ if (nexttoken.id === "undefined") {
warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id);
}
- if (peek(0).id === '=' && nexttoken.identifier) {
+ if (peek(0).id === "=" && nexttoken.identifier) {
error("Variable {a} was not declared correctly.",
nexttoken, nexttoken.value);
}
value = expression(0);
name.first = value;
}
- if (nexttoken.id !== ',') {
+ if (nexttoken.id !== ",") {
break;
}
comma();
@@ -3477,7 +3854,7 @@ loop: for (;;) {
});
varstatement.exps = true;
- blockstmt('function', function () {
+ blockstmt("function", function () {
if (inblock) {
warning("Function declarations should not be placed in blocks. " +
"Use a function expression or move the statement to the top of " +
@@ -3489,16 +3866,17 @@ loop: for (;;) {
warning("const '" + i + "' has already been declared");
}
adjacent(token, nexttoken);
- addlabel(i, 'unction');
- doFunction(i, true);
- if (nexttoken.id === '(' && nexttoken.line === token.line) {
+ addlabel(i, "unction", token);
+
+ doFunction(i, { statement: true });
+ if (nexttoken.id === "(" && nexttoken.line === token.line) {
error(
"Function declarations are not invocable. Wrap the whole function invocation in parens.");
}
return this;
});
- prefix('function', function () {
+ prefix("function", function () {
var i = optionalidentifier();
if (i) {
adjacent(token, nexttoken);
@@ -3506,31 +3884,32 @@ loop: for (;;) {
nonadjacent(token, nexttoken);
}
doFunction(i);
- if (!option.loopfunc && funct['(loopage)']) {
+ if (!option.loopfunc && funct["(loopage)"]) {
warning("Don't make functions within a loop.");
}
return this;
});
- blockstmt('if', function () {
+ blockstmt("if", function () {
var t = nexttoken;
- advance('(');
+ increaseComplexityCount();
+ advance("(");
nonadjacent(this, t);
nospace();
expression(20);
- if (nexttoken.id === '=') {
+ if (nexttoken.id === "=") {
if (!option.boss)
warning("Expected a conditional expression and instead saw an assignment.");
- advance('=');
+ advance("=");
expression(20);
}
- advance(')', t);
+ advance(")", t);
nospace(prevtoken, token);
block(true, true);
- if (nexttoken.id === 'else') {
+ if (nexttoken.id === "else") {
nonadjacent(token, nexttoken);
- advance('else');
- if (nexttoken.id === 'if' || nexttoken.id === 'switch') {
+ advance("else");
+ if (nexttoken.id === "if" || nexttoken.id === "switch") {
statement(true);
} else {
block(true, true);
@@ -3539,90 +3918,146 @@ loop: for (;;) {
return this;
});
- blockstmt('try', function () {
- var b, e, s;
+ blockstmt("try", function () {
+ var b;
- block(false);
- if (nexttoken.id === 'catch') {
- advance('catch');
+ function doCatch() {
+ var oldScope = scope;
+ var e;
+
+ advance("catch");
nonadjacent(token, nexttoken);
- advance('(');
- s = scope;
- scope = Object.create(s);
+ advance("(");
+
+ scope = Object.create(oldScope);
+
e = nexttoken.value;
- if (nexttoken.type !== '(identifier)') {
- warning("Expected an identifier and instead saw '{a}'.",
- nexttoken, e);
- } else {
- addlabel(e, 'exception');
+ if (nexttoken.type !== "(identifier)") {
+ e = null;
+ warning("Expected an identifier and instead saw '{a}'.", nexttoken, e);
}
+
advance();
- advance(')');
+ advance(")");
+
+ funct = {
+ "(name)" : "(catch)",
+ "(line)" : nexttoken.line,
+ "(character)": nexttoken.character,
+ "(context)" : funct,
+ "(breakage)" : funct["(breakage)"],
+ "(loopage)" : funct["(loopage)"],
+ "(scope)" : scope,
+ "(statement)": false,
+ "(metrics)" : createMetrics(nexttoken),
+ "(catch)" : true,
+ "(tokens)" : {}
+ };
+
+ if (e) {
+ addlabel(e, "exception");
+ }
+
+ token.funct = funct;
+ functions.push(funct);
+
block(false);
+
+ scope = oldScope;
+
+ funct["(last)"] = token.line;
+ funct["(lastcharacter)"] = token.character;
+ funct = funct["(context)"];
+ }
+
+ block(false);
+
+ if (nexttoken.id === "catch") {
+ increaseComplexityCount();
+ doCatch();
b = true;
- scope = s;
}
- if (nexttoken.id === 'finally') {
- advance('finally');
+
+ if (nexttoken.id === "finally") {
+ advance("finally");
block(false);
return;
} else if (!b) {
error("Expected '{a}' and instead saw '{b}'.",
- nexttoken, 'catch', nexttoken.value);
+ nexttoken, "catch", nexttoken.value);
}
+
return this;
});
- blockstmt('while', function () {
+ blockstmt("while", function () {
var t = nexttoken;
- funct['(breakage)'] += 1;
- funct['(loopage)'] += 1;
- advance('(');
+ funct["(breakage)"] += 1;
+ funct["(loopage)"] += 1;
+ increaseComplexityCount();
+ advance("(");
nonadjacent(this, t);
nospace();
expression(20);
- if (nexttoken.id === '=') {
+ if (nexttoken.id === "=") {
if (!option.boss)
warning("Expected a conditional expression and instead saw an assignment.");
- advance('=');
+ advance("=");
expression(20);
}
- advance(')', t);
+ advance(")", t);
nospace(prevtoken, token);
block(true, true);
- funct['(breakage)'] -= 1;
- funct['(loopage)'] -= 1;
+ funct["(breakage)"] -= 1;
+ funct["(loopage)"] -= 1;
return this;
}).labelled = true;
- reserve('with');
+ blockstmt("with", function () {
+ var t = nexttoken;
+ if (directive["use strict"]) {
+ error("'with' is not allowed in strict mode.", token);
+ } else if (!option.withstmt) {
+ warning("Don't use 'with'.", token);
+ }
- blockstmt('switch', function () {
+ advance("(");
+ nonadjacent(this, t);
+ nospace();
+ expression(0);
+ advance(")", t);
+ nospace(prevtoken, token);
+ block(true, true);
+
+ return this;
+ });
+
+ blockstmt("switch", function () {
var t = nexttoken,
g = false;
- funct['(breakage)'] += 1;
- advance('(');
+ funct["(breakage)"] += 1;
+ advance("(");
nonadjacent(this, t);
nospace();
this.condition = expression(20);
- advance(')', t);
+ advance(")", t);
nospace(prevtoken, token);
nonadjacent(token, nexttoken);
t = nexttoken;
- advance('{');
+ advance("{");
nonadjacent(token, nexttoken);
indent += option.indent;
this.cases = [];
for (;;) {
switch (nexttoken.id) {
- case 'case':
- switch (funct['(verb)']) {
- case 'break':
- case 'case':
- case 'continue':
- case 'return':
- case 'switch':
- case 'throw':
+ case "case":
+ switch (funct["(verb)"]) {
+ case "break":
+ case "case":
+ case "continue":
+ case "return":
+ case "switch":
+ case "throw":
break;
default:
// You can tell JSHint that you don't use break intentionally by
@@ -3635,18 +4070,19 @@ loop: for (;;) {
}
}
indentation(-option.indent);
- advance('case');
+ advance("case");
this.cases.push(expression(20));
+ increaseComplexityCount();
g = true;
- advance(':');
- funct['(verb)'] = 'case';
+ advance(":");
+ funct["(verb)"] = "case";
break;
- case 'default':
- switch (funct['(verb)']) {
- case 'break':
- case 'continue':
- case 'return':
- case 'throw':
+ case "default":
+ switch (funct["(verb)"]) {
+ case "break":
+ case "continue":
+ case "return":
+ case "throw":
break;
default:
if (!ft.test(lines[nexttoken.line - 2])) {
@@ -3656,32 +4092,32 @@ loop: for (;;) {
}
}
indentation(-option.indent);
- advance('default');
+ advance("default");
g = true;
- advance(':');
+ advance(":");
break;
- case '}':
+ case "}":
indent -= option.indent;
indentation();
- advance('}', t);
- if (this.cases.length === 1 || this.condition.id === 'true' ||
- this.condition.id === 'false') {
+ advance("}", t);
+ if (this.cases.length === 1 || this.condition.id === "true" ||
+ this.condition.id === "false") {
if (!option.onecase)
warning("This 'switch' should be an 'if'.", this);
}
- funct['(breakage)'] -= 1;
- funct['(verb)'] = undefined;
+ funct["(breakage)"] -= 1;
+ funct["(verb)"] = undefined;
return;
- case '(end)':
- error("Missing '{a}'.", nexttoken, '}');
+ case "(end)":
+ error("Missing '{a}'.", nexttoken, "}");
return;
default:
if (g) {
switch (token.id) {
- case ',':
+ case ",":
error("Each value should have its own case label.");
return;
- case ':':
+ case ":":
g = false;
statements();
break;
@@ -3690,13 +4126,13 @@ loop: for (;;) {
return;
}
} else {
- if (token.id === ':') {
- advance(':');
- error("Unexpected '{a}'.", token, ':');
+ if (token.id === ":") {
+ advance(":");
+ error("Unexpected '{a}'.", token, ":");
statements();
} else {
error("Expected '{a}' and instead saw '{b}'.",
- nexttoken, 'case', nexttoken.value);
+ nexttoken, "case", nexttoken.value);
return;
}
}
@@ -3704,7 +4140,7 @@ loop: for (;;) {
}
}).labelled = true;
- stmt('debugger', function () {
+ stmt("debugger", function () {
if (!option.debug) {
warning("All 'debugger' statements should be removed.");
}
@@ -3712,49 +4148,52 @@ loop: for (;;) {
}).exps = true;
(function () {
- var x = stmt('do', function () {
- funct['(breakage)'] += 1;
- funct['(loopage)'] += 1;
+ var x = stmt("do", function () {
+ funct["(breakage)"] += 1;
+ funct["(loopage)"] += 1;
+ increaseComplexityCount();
+
this.first = block(true);
- advance('while');
+ advance("while");
var t = nexttoken;
nonadjacent(token, t);
- advance('(');
+ advance("(");
nospace();
expression(20);
- if (nexttoken.id === '=') {
+ if (nexttoken.id === "=") {
if (!option.boss)
warning("Expected a conditional expression and instead saw an assignment.");
- advance('=');
+ advance("=");
expression(20);
}
- advance(')', t);
+ advance(")", t);
nospace(prevtoken, token);
- funct['(breakage)'] -= 1;
- funct['(loopage)'] -= 1;
+ funct["(breakage)"] -= 1;
+ funct["(loopage)"] -= 1;
return this;
});
x.labelled = true;
x.exps = true;
}());
- blockstmt('for', function () {
+ blockstmt("for", function () {
var s, t = nexttoken;
- funct['(breakage)'] += 1;
- funct['(loopage)'] += 1;
- advance('(');
+ funct["(breakage)"] += 1;
+ funct["(loopage)"] += 1;
+ increaseComplexityCount();
+ advance("(");
nonadjacent(this, t);
nospace();
- if (peek(nexttoken.id === 'var' ? 1 : 0).id === 'in') {
- if (nexttoken.id === 'var') {
- advance('var');
+ if (peek(nexttoken.id === "var" ? 1 : 0).id === "in") {
+ if (nexttoken.id === "var") {
+ advance("var");
varstatement.fud.call(varstatement, true);
} else {
switch (funct[nexttoken.value]) {
- case 'unused':
- funct[nexttoken.value] = 'var';
+ case "unused":
+ funct[nexttoken.value] = "var";
break;
- case 'var':
+ case "var":
break;
default:
warning("Bad for in variable '{a}'.",
@@ -3762,27 +4201,27 @@ loop: for (;;) {
}
advance();
}
- advance('in');
+ advance("in");
expression(20);
- advance(')', t);
+ advance(")", t);
s = block(true, true);
- if (option.forin && s && (s.length > 1 || typeof s[0] !== 'object' ||
- s[0].value !== 'if')) {
+ if (option.forin && s && (s.length > 1 || typeof s[0] !== "object" ||
+ s[0].value !== "if")) {
warning("The body of a for in should be wrapped in an if statement to filter " +
"unwanted properties from the prototype.", this);
}
- funct['(breakage)'] -= 1;
- funct['(loopage)'] -= 1;
+ funct["(breakage)"] -= 1;
+ funct["(loopage)"] -= 1;
return this;
} else {
- if (nexttoken.id !== ';') {
- if (nexttoken.id === 'var') {
- advance('var');
+ if (nexttoken.id !== ";") {
+ if (nexttoken.id === "var") {
+ advance("var");
varstatement.fud.call(varstatement);
} else {
for (;;) {
- expression(0, 'for');
- if (nexttoken.id !== ',') {
+ expression(0, "for");
+ if (nexttoken.id !== ",") {
break;
}
comma();
@@ -3790,53 +4229,53 @@ loop: for (;;) {
}
}
nolinebreak(token);
- advance(';');
- if (nexttoken.id !== ';') {
+ advance(";");
+ if (nexttoken.id !== ";") {
expression(20);
- if (nexttoken.id === '=') {
+ if (nexttoken.id === "=") {
if (!option.boss)
warning("Expected a conditional expression and instead saw an assignment.");
- advance('=');
+ advance("=");
expression(20);
}
}
nolinebreak(token);
- advance(';');
- if (nexttoken.id === ';') {
+ advance(";");
+ if (nexttoken.id === ";") {
error("Expected '{a}' and instead saw '{b}'.",
- nexttoken, ')', ';');
+ nexttoken, ")", ";");
}
- if (nexttoken.id !== ')') {
+ if (nexttoken.id !== ")") {
for (;;) {
- expression(0, 'for');
- if (nexttoken.id !== ',') {
+ expression(0, "for");
+ if (nexttoken.id !== ",") {
break;
}
comma();
}
}
- advance(')', t);
+ advance(")", t);
nospace(prevtoken, token);
block(true, true);
- funct['(breakage)'] -= 1;
- funct['(loopage)'] -= 1;
+ funct["(breakage)"] -= 1;
+ funct["(loopage)"] -= 1;
return this;
}
}).labelled = true;
- stmt('break', function () {
+ stmt("break", function () {
var v = nexttoken.value;
- if (funct['(breakage)'] === 0)
+ if (funct["(breakage)"] === 0)
warning("Unexpected '{a}'.", nexttoken, this.value);
if (!option.asi)
nolinebreak(this);
- if (nexttoken.id !== ';') {
+ if (nexttoken.id !== ";") {
if (token.line === nexttoken.line) {
- if (funct[v] !== 'label') {
+ if (funct[v] !== "label") {
warning("'{a}' is not a statement label.", nexttoken, v);
} else if (scope[v] !== funct) {
warning("'{a}' is out of scope.", nexttoken, v);
@@ -3845,23 +4284,23 @@ loop: for (;;) {
advance();
}
}
- reachable('break');
+ reachable("break");
return this;
}).exps = true;
- stmt('continue', function () {
+ stmt("continue", function () {
var v = nexttoken.value;
- if (funct['(breakage)'] === 0)
+ if (funct["(breakage)"] === 0)
warning("Unexpected '{a}'.", nexttoken, this.value);
if (!option.asi)
nolinebreak(this);
- if (nexttoken.id !== ';') {
+ if (nexttoken.id !== ";") {
if (token.line === nexttoken.line) {
- if (funct[v] !== 'label') {
+ if (funct[v] !== "label") {
warning("'{a}' is not a statement label.", nexttoken, v);
} else if (scope[v] !== funct) {
warning("'{a}' is out of scope.", nexttoken, v);
@@ -3869,20 +4308,20 @@ loop: for (;;) {
this.first = nexttoken;
advance();
}
- } else if (!funct['(loopage)']) {
+ } else if (!funct["(loopage)"]) {
warning("Unexpected '{a}'.", nexttoken, this.value);
}
- reachable('continue');
+ reachable("continue");
return this;
}).exps = true;
- stmt('return', function () {
+ stmt("return", function () {
if (this.line === nexttoken.line) {
- if (nexttoken.id === '(regexp)')
+ if (nexttoken.id === "(regexp)")
warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator.");
- if (nexttoken.id !== ';' && !nexttoken.reach) {
+ if (nexttoken.id !== ";" && !nexttoken.reach) {
nonadjacent(token, nexttoken);
if (peek().value === "=" && !option.boss) {
warningAt("Did you mean to return a conditional instead of an assignment?",
@@ -3893,38 +4332,38 @@ loop: for (;;) {
} else if (!option.asi) {
nolinebreak(this); // always warn (Line breaking error)
}
- reachable('return');
+ reachable("return");
return this;
}).exps = true;
- stmt('throw', function () {
+ stmt("throw", function () {
nolinebreak(this);
nonadjacent(token, nexttoken);
this.first = expression(20);
- reachable('throw');
+ reachable("throw");
return this;
}).exps = true;
// Superfluous reserved words
- reserve('class');
- reserve('const');
- reserve('enum');
- reserve('export');
- reserve('extends');
- reserve('import');
- reserve('super');
-
- reserve('let');
- reserve('yield');
- reserve('implements');
- reserve('interface');
- reserve('package');
- reserve('private');
- reserve('protected');
- reserve('public');
- reserve('static');
+ reserve("class");
+ reserve("const");
+ reserve("enum");
+ reserve("export");
+ reserve("extends");
+ reserve("import");
+ reserve("super");
+
+ reserve("let");
+ reserve("yield");
+ reserve("implements");
+ reserve("interface");
+ reserve("package");
+ reserve("private");
+ reserve("protected");
+ reserve("public");
+ reserve("static");
// Parse JSON
@@ -3933,26 +4372,26 @@ loop: for (;;) {
function jsonObject() {
var o = {}, t = nexttoken;
- advance('{');
- if (nexttoken.id !== '}') {
+ advance("{");
+ if (nexttoken.id !== "}") {
for (;;) {
- if (nexttoken.id === '(end)') {
+ if (nexttoken.id === "(end)") {
error("Missing '}' to match '{' from line {a}.",
nexttoken, t.line);
- } else if (nexttoken.id === '}') {
+ } else if (nexttoken.id === "}") {
warning("Unexpected comma.", token);
break;
- } else if (nexttoken.id === ',') {
+ } else if (nexttoken.id === ",") {
error("Unexpected comma.", nexttoken);
- } else if (nexttoken.id !== '(string)') {
+ } else if (nexttoken.id !== "(string)") {
warning("Expected a string and instead saw {a}.",
nexttoken, nexttoken.value);
}
if (o[nexttoken.value] === true) {
warning("Duplicate key '{a}'.",
nexttoken, nexttoken.value);
- } else if ((nexttoken.value === '__proto__' &&
- !option.proto) || (nexttoken.value === '__iterator__' &&
+ } else if ((nexttoken.value === "__proto__" &&
+ !option.proto) || (nexttoken.value === "__iterator__" &&
!option.iterator)) {
warning("The '{a}' key may produce unexpected results.",
nexttoken, nexttoken.value);
@@ -3960,62 +4399,62 @@ loop: for (;;) {
o[nexttoken.value] = true;
}
advance();
- advance(':');
+ advance(":");
jsonValue();
- if (nexttoken.id !== ',') {
+ if (nexttoken.id !== ",") {
break;
}
- advance(',');
+ advance(",");
}
}
- advance('}');
+ advance("}");
}
function jsonArray() {
var t = nexttoken;
- advance('[');
- if (nexttoken.id !== ']') {
+ advance("[");
+ if (nexttoken.id !== "]") {
for (;;) {
- if (nexttoken.id === '(end)') {
+ if (nexttoken.id === "(end)") {
error("Missing ']' to match '[' from line {a}.",
nexttoken, t.line);
- } else if (nexttoken.id === ']') {
+ } else if (nexttoken.id === "]") {
warning("Unexpected comma.", token);
break;
- } else if (nexttoken.id === ',') {
+ } else if (nexttoken.id === ",") {
error("Unexpected comma.", nexttoken);
}
jsonValue();
- if (nexttoken.id !== ',') {
+ if (nexttoken.id !== ",") {
break;
}
- advance(',');
+ advance(",");
}
}
- advance(']');
+ advance("]");
}
switch (nexttoken.id) {
- case '{':
+ case "{":
jsonObject();
break;
- case '[':
+ case "[":
jsonArray();
break;
- case 'true':
- case 'false':
- case 'null':
- case '(number)':
- case '(string)':
+ case "true":
+ case "false":
+ case "null":
+ case "(number)":
+ case "(string)":
advance();
break;
- case '-':
- advance('-');
+ case "-":
+ advance("-");
if (token.character !== nexttoken.from) {
warning("Unexpected space after '-'.", token);
}
adjacent(token, nexttoken);
- advance('(number)');
+ advance("(number)");
break;
default:
error("Expected a JSON value.", nexttoken);
@@ -4023,48 +4462,75 @@ loop: for (;;) {
}
-// The actual JSHINT function itself.
-
+ // The actual JSHINT function itself.
var itself = function (s, o, g) {
- var a, i, k;
- JSHINT.errors = [];
- JSHINT.undefs = [];
+ var a, i, k, x;
+ var optionKeys;
+ var newOptionObj = {};
+
+ if (o && o.scope) {
+ JSHINT.scope = o.scope;
+ } else {
+ JSHINT.errors = [];
+ JSHINT.undefs = [];
+ JSHINT.internals = [];
+ JSHINT.blacklist = {};
+ JSHINT.scope = "(main)";
+ }
+
predefined = Object.create(standard);
+ declared = Object.create(null);
combine(predefined, g || {});
+
if (o) {
a = o.predef;
if (a) {
- if (Array.isArray(a)) {
- for (i = 0; i < a.length; i += 1) {
- predefined[a[i]] = true;
- }
- } else if (typeof a === 'object') {
- k = Object.keys(a);
- for (i = 0; i < k.length; i += 1) {
- predefined[k[i]] = !!a[k[i]];
- }
+ if (!Array.isArray(a) && typeof a === "object") {
+ a = Object.keys(a);
}
+ a.forEach(function (item) {
+ var slice;
+ if (item[0] === "-") {
+ slice = item.slice(1);
+ JSHINT.blacklist[slice] = slice;
+ } else {
+ predefined[item] = true;
+ }
+ });
+ }
+
+ optionKeys = Object.keys(o);
+ for (x = 0; x < optionKeys.length; x++) {
+ newOptionObj[optionKeys[x]] = o[optionKeys[x]];
+
+ if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false)
+ newOptionObj["(explicitNewcap)"] = true;
+
+ if (optionKeys[x] === "indent")
+ newOptionObj.white = true;
}
- option = o;
- } else {
- option = {};
}
+
+ option = newOptionObj;
+
option.indent = option.indent || 4;
option.maxerr = option.maxerr || 50;
- tab = '';
+ tab = "";
for (i = 0; i < option.indent; i += 1) {
- tab += ' ';
+ tab += " ";
}
indent = 1;
global = Object.create(predefined);
scope = global;
funct = {
- '(global)': true,
- '(name)': '(global)',
- '(scope)': scope,
- '(breakage)': 0,
- '(loopage)': 0
+ "(global)": true,
+ "(name)": "(global)",
+ "(scope)": scope,
+ "(breakage)": 0,
+ "(loopage)": 0,
+ "(tokens)": {},
+ "(metrics)": createMetrics(nexttoken)
};
functions = [funct];
urls = [];
@@ -4076,21 +4542,52 @@ loop: for (;;) {
lookahead = [];
jsonmode = false;
warnings = 0;
+ lines = [];
+ unuseds = [];
+
+ if (!isString(s) && !Array.isArray(s)) {
+ errorAt("Input is neither a string nor an array of strings.", 0);
+ return false;
+ }
+
+ if (isString(s) && /^\s*$/g.test(s)) {
+ errorAt("Input is an empty string.", 0);
+ return false;
+ }
+
+ if (s.length === 0) {
+ errorAt("Input is an empty array.", 0);
+ return false;
+ }
+
lex.init(s);
+
prereg = true;
directive = {};
- prevtoken = token = nexttoken = syntax['(begin)'];
+ prevtoken = token = nexttoken = syntax["(begin)"];
+
+ // Check options
+ for (var name in o) {
+ if (is_own(o, name)) {
+ checkOption(name, token);
+ }
+ }
+
assume();
// combine the passed globals after we've assumed all our options
combine(predefined, g || {});
+ //reset values
+ comma.first = true;
+ quotmark = undefined;
+
try {
advance();
switch (nexttoken.id) {
- case '{':
- case '[':
+ case "{":
+ case "[":
option.laxbreak = true;
jsonmode = true;
jsonValue();
@@ -4103,26 +4600,26 @@ loop: for (;;) {
statements();
}
- advance('(end)');
+ advance((nexttoken && nexttoken.value !== ".") ? "(end)" : undefined);
var markDefined = function (name, context) {
do {
- if (typeof context[name] === 'string') {
+ if (typeof context[name] === "string") {
// JSHINT marks unused variables as 'unused' and
// unused function declaration as 'unction'. This
// code changes such instances back 'var' and
// 'closure' so that the code in JSHINT.data()
// doesn't think they're unused.
- if (context[name] === 'unused')
- context[name] = 'var';
- else if (context[name] === 'unction')
- context[name] = 'closure';
+ if (context[name] === "unused")
+ context[name] = "var";
+ else if (context[name] === "unction")
+ context[name] = "closure";
return true;
}
- context = context['(context)'];
+ context = context["(context)"];
} while (context);
return false;
@@ -4144,6 +4641,37 @@ loop: for (;;) {
implied[name] = newImplied;
};
+ var warnUnused = function (name, token) {
+ var line = token.line;
+ var chr = token.character;
+
+ if (option.unused)
+ warningAt("'{a}' is defined but never used.", line, chr, name);
+
+ unuseds.push({
+ name: name,
+ line: line,
+ character: chr
+ });
+ };
+
+ var checkUnused = function (func, key) {
+ var type = func[key];
+ var token = func["(tokens)"][key];
+
+ if (key.charAt(0) === "(")
+ return;
+
+ if (type !== "unused" && type !== "unction")
+ return;
+
+ // Params are checked separately from other variables.
+ if (func["(params)"] && func["(params)"].indexOf(key) !== -1)
+ return;
+
+ warnUnused(key, token);
+ };
+
// Check queued 'x is not defined' instances to see if they're still undefined.
for (i = 0; i < JSHINT.undefs.length; i += 1) {
k = JSHINT.undefs[i].slice(0);
@@ -4154,6 +4682,43 @@ loop: for (;;) {
warning.apply(warning, k.slice(1));
}
}
+
+ functions.forEach(function (func) {
+ for (var key in func) {
+ if (is_own(func, key)) {
+ checkUnused(func, key);
+ }
+ }
+
+ if (!func["(params)"])
+ return;
+
+ var params = func["(params)"].slice();
+ var param = params.pop();
+ var type;
+
+ while (param) {
+ type = func[param];
+
+ // 'undefined' is a special case for (function (window, undefined) { ... })();
+ // patterns.
+
+ if (param === "undefined")
+ return;
+
+ if (type !== "unused" && type !== "unction")
+ return;
+
+ warnUnused(param, func["(tokens)"][param]);
+ param = params.pop();
+ }
+ });
+
+ for (var key in declared) {
+ if (is_own(declared, key) && !is_own(global, key)) {
+ warnUnused(key, declared[key]);
+ }
+ }
} catch (e) {
if (e) {
var nt = nexttoken || {};
@@ -4166,14 +4731,31 @@ loop: for (;;) {
}
}
+ // Loop over the listed "internals", and check them as well.
+
+ if (JSHINT.scope === "(main)") {
+ o = o || {};
+
+ for (i = 0; i < JSHINT.internals.length; i += 1) {
+ k = JSHINT.internals[i];
+ o.scope = k.elem;
+ itself(k.value, o, g);
+ }
+ }
+
return JSHINT.errors.length === 0;
};
// Data summary.
itself.data = function () {
+ var data = {
+ functions: [],
+ options: option
+ };
+ var implieds = [];
+ var members = [];
+ var fu, f, i, j, n, globals;
- var data = { functions: [], options: option }, fu, globals, implieds = [], f, i, j,
- members = [], n, unused = [], v;
if (itself.errors.length) {
data.errors = itself.errors;
}
@@ -4190,6 +4772,7 @@ loop: for (;;) {
});
}
}
+
if (implieds.length > 0) {
data.implieds = implieds;
}
@@ -4202,49 +4785,37 @@ loop: for (;;) {
if (globals.length > 0) {
data.globals = globals;
}
+
for (i = 1; i < functions.length; i += 1) {
f = functions[i];
fu = {};
+
for (j = 0; j < functionicity.length; j += 1) {
fu[functionicity[j]] = [];
}
- for (n in f) {
- if (is_own(f, n) && n.charAt(0) !== '(') {
- v = f[n];
- if (v === 'unction') {
- v = 'unused';
- }
- if (Array.isArray(fu[v])) {
- fu[v].push(n);
- if (v === 'unused') {
- unused.push({
- name: n,
- line: f['(line)'],
- 'function': f['(name)']
- });
- }
- }
- }
- }
+
for (j = 0; j < functionicity.length; j += 1) {
if (fu[functionicity[j]].length === 0) {
delete fu[functionicity[j]];
}
}
- fu.name = f['(name)'];
- fu.param = f['(params)'];
- fu.line = f['(line)'];
- fu.last = f['(last)'];
+
+ fu.name = f["(name)"];
+ fu.param = f["(params)"];
+ fu.line = f["(line)"];
+ fu.character = f["(character)"];
+ fu.last = f["(last)"];
+ fu.lastcharacter = f["(lastcharacter)"];
data.functions.push(fu);
}
- if (unused.length > 0) {
- data.unused = unused;
+ if (unuseds.length > 0) {
+ data.unused = unuseds;
}
members = [];
for (n in member) {
- if (typeof member[n] === 'number') {
+ if (typeof member[n] === "number") {
data.member = member;
break;
}
@@ -4253,138 +4824,12 @@ loop: for (;;) {
return data;
};
- itself.report = function (option) {
- var data = itself.data();
-
- var a = [], c, e, err, f, i, k, l, m = '', n, o = [], s;
-
- function detail(h, array) {
- var b, i, singularity;
- if (array) {
- o.push('<div><i>' + h + '</i> ');
- array = array.sort();
- for (i = 0; i < array.length; i += 1) {
- if (array[i] !== singularity) {
- singularity = array[i];
- o.push((b ? ', ' : '') + singularity);
- b = true;
- }
- }
- o.push('</div>');
- }
- }
-
-
- if (data.errors || data.implieds || data.unused) {
- err = true;
- o.push('<div id=errors><i>Error:</i>');
- if (data.errors) {
- for (i = 0; i < data.errors.length; i += 1) {
- c = data.errors[i];
- if (c) {
- e = c.evidence || '';
- o.push('<p>Problem' + (isFinite(c.line) ? ' at line ' +
- c.line + ' character ' + c.character : '') +
- ': ' + c.reason.entityify() +
- '</p><p class=evidence>' +
- (e && (e.length > 80 ? e.slice(0, 77) + '...' :
- e).entityify()) + '</p>');
- }
- }
- }
-
- if (data.implieds) {
- s = [];
- for (i = 0; i < data.implieds.length; i += 1) {
- s[i] = '<code>' + data.implieds[i].name + '</code>&nbsp;<i>' +
- data.implieds[i].line + '</i>';
- }
- o.push('<p><i>Implied global:</i> ' + s.join(', ') + '</p>');
- }
-
- if (data.unused) {
- s = [];
- for (i = 0; i < data.unused.length; i += 1) {
- s[i] = '<code><u>' + data.unused[i].name + '</u></code>&nbsp;<i>' +
- data.unused[i].line + '</i> <code>' +
- data.unused[i]['function'] + '</code>';
- }
- o.push('<p><i>Unused variable:</i> ' + s.join(', ') + '</p>');
- }
- if (data.json) {
- o.push('<p>JSON: bad.</p>');
- }
- o.push('</div>');
- }
-
- if (!option) {
-
- o.push('<br><div id=functions>');
-
- if (data.urls) {
- detail("URLs<br>", data.urls, '<br>');
- }
-
- if (data.json && !err) {
- o.push('<p>JSON: good.</p>');
- } else if (data.globals) {
- o.push('<div><i>Global</i> ' +
- data.globals.sort().join(', ') + '</div>');
- } else {
- o.push('<div><i>No new global variables introduced.</i></div>');
- }
-
- for (i = 0; i < data.functions.length; i += 1) {
- f = data.functions[i];
-
- o.push('<br><div class=function><i>' + f.line + '-' +
- f.last + '</i> ' + (f.name || '') + '(' +
- (f.param ? f.param.join(', ') : '') + ')</div>');
- detail('<big><b>Unused</b></big>', f.unused);
- detail('Closure', f.closure);
- detail('Variable', f['var']);
- detail('Exception', f.exception);
- detail('Outer', f.outer);
- detail('Global', f.global);
- detail('Label', f.label);
- }
-
- if (data.member) {
- a = Object.keys(data.member);
- if (a.length) {
- a = a.sort();
- m = '<br><pre id=members>/*members ';
- l = 10;
- for (i = 0; i < a.length; i += 1) {
- k = a[i];
- n = k.name();
- if (l + n.length > 72) {
- o.push(m + '<br>');
- m = ' ';
- l = 1;
- }
- l += n.length + 2;
- if (data.member[k] === 1) {
- n = '<i>' + n + '</i>';
- }
- if (i < a.length - 1) {
- n += ', ';
- }
- m += n;
- }
- o.push(m + '<br>*/</pre>');
- }
- o.push('</div>');
- }
- }
- return o.join('');
- };
-
itself.jshint = itself;
return itself;
}());
// Make JSHINT a Node module, if possible.
-if (typeof exports === 'object' && exports)
+if (typeof exports === "object" && exports) {
exports.JSHINT = JSHINT;
+} \ No newline at end of file
diff --git a/grunt.js b/grunt.js
index 08647a7a1..524421be7 100644
--- a/grunt.js
+++ b/grunt.js
@@ -1,6 +1,7 @@
-/*jshint node: true */
module.exports = function( grunt ) {
+"use strict";
+
var
// files
coreFiles = [
@@ -161,6 +162,7 @@ grunt.initConfig({
"package.json",
"*.jquery.json",
"ui/**/*",
+ "ui/.jshintrc",
"demos/**/*",
"themes/**/*",
"external/**/*",
@@ -279,14 +281,11 @@ grunt.initConfig({
files: grunt.file.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|all-active|index|test|draggable|droppable|selectable|resizable|sortable|dialog|slider|datepicker|tabs|tabs_deprecated)\.html$/ ).test( file );
+ return !( /(all|index|test|dialog|tabs|tooltip)\.html$/ ).test( file );
})
},
lint: {
- ui: grunt.file.expandFiles( "ui/*.js" ).filter(function( file ) {
- // TODO remove items from this list once rewritten
- return !( /(mouse|datepicker|draggable|droppable|resizable|selectable|sortable)\.js$/ ).test( file );
- }),
+ ui: "ui/*.js",
grunt: [ "grunt.js", "build/**/*.js" ],
tests: "tests/unit/**/*.js"
},
@@ -304,7 +303,8 @@ grunt.initConfig({
"important": false,
"outline-none": false,
// especially this one
- "overqualified-elements": false
+ "overqualified-elements": false,
+ "compatible-vendor-prefixes": false
}
}
},
@@ -325,9 +325,7 @@ grunt.initConfig({
}
return {
- // TODO: use "faux strict mode" https://github.com/jshint/jshint/issues/504
- // TODO: limit `smarttabs` to multi-line comments https://github.com/jshint/jshint/issues/503
- options: parserc(),
+ grunt: parserc(),
ui: parserc( "ui/" ),
// TODO: `evil: true` is only for document.write() https://github.com/jshint/jshint/issues/519
// TODO: don't create so many globals in tests
diff --git a/jquery-1.8.2.js b/jquery-1.8.2.js
index d4f3bb38c..12c7797fd 100644
--- a/jquery-1.8.2.js
+++ b/jquery-1.8.2.js
@@ -3665,1667 +3665,1667 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
}
});
-/*!
- * Sizzle CSS Selector Engine
- * Copyright 2012 jQuery Foundation and other contributors
- * Released under the MIT license
- * http://sizzlejs.com/
- */
-(function( window, undefined ) {
-
-var cachedruns,
- assertGetIdNotName,
- Expr,
- getText,
- isXML,
- contains,
- compile,
- sortOrder,
- hasDuplicate,
- outermostContext,
-
- baseHasDuplicate = true,
- strundefined = "undefined",
-
- expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
-
- Token = String,
- document = window.document,
- docElem = document.documentElement,
- dirruns = 0,
- done = 0,
- pop = [].pop,
- push = [].push,
- slice = [].slice,
- // Use a stripped-down indexOf if a native one is unavailable
- indexOf = [].indexOf || function( elem ) {
- var i = 0,
- len = this.length;
- for ( ; i < len; i++ ) {
- if ( this[i] === elem ) {
- return i;
- }
- }
- return -1;
- },
-
- // Augment a function for special use by Sizzle
- markFunction = function( fn, value ) {
- fn[ expando ] = value == null || value;
- return fn;
- },
-
- createCache = function() {
- var cache = {},
- keys = [];
-
- return markFunction(function( key, value ) {
- // Only keep the most recent entries
- if ( keys.push( key ) > Expr.cacheLength ) {
- delete cache[ keys.shift() ];
- }
-
- return (cache[ key ] = value);
- }, cache );
- },
-
- classCache = createCache(),
- tokenCache = createCache(),
- compilerCache = createCache(),
-
- // Regex
-
- // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
- whitespace = "[\\x20\\t\\r\\n\\f]",
- // http://www.w3.org/TR/css3-syntax/#characters
- characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
-
- // Loosely modeled on CSS identifier characters
- // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)
- // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
- identifier = characterEncoding.replace( "w", "w#" ),
-
- // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
- operators = "([*^$|!~]?=)",
- attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
- "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
-
- // Prefer arguments not in parens/brackets,
- // then attribute selectors and non-pseudos (denoted by :),
- // then anything else
- // These preferences are here to reduce the number of selectors
- // needing tokenize in the PSEUDO preFilter
- pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",
-
- // For matchExpr.POS and matchExpr.needsContext
- pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
- "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)",
-
- // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
- rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
-
- rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
- rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
- rpseudo = new RegExp( pseudos ),
-
- // Easily-parseable/retrievable ID or TAG or CLASS selectors
- rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
-
- rnot = /^:not/,
- rsibling = /[\x20\t\r\n\f]*[+~]/,
- rendsWithNot = /:not\($/,
-
- rheader = /h\d/i,
- rinputs = /input|select|textarea|button/i,
-
- rbackslash = /\\(?!\\)/g,
-
- matchExpr = {
- "ID": new RegExp( "^#(" + characterEncoding + ")" ),
- "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
- "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
- "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
- "ATTR": new RegExp( "^" + attributes ),
- "PSEUDO": new RegExp( "^" + pseudos ),
- "POS": new RegExp( pos, "i" ),
- "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace +
- "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
- "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
- // For use in libraries implementing .is()
- "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
- },
-
- // Support
-
- // Used for testing something on an element
- assert = function( fn ) {
- var div = document.createElement("div");
-
- try {
- return fn( div );
- } catch (e) {
- return false;
- } finally {
- // release memory in IE
- div = null;
- }
- },
-
- // Check if getElementsByTagName("*") returns only elements
- assertTagNameNoComments = assert(function( div ) {
- div.appendChild( document.createComment("") );
- return !div.getElementsByTagName("*").length;
- }),
-
- // Check if getAttribute returns normalized href attributes
- assertHrefNotNormalized = assert(function( div ) {
- div.innerHTML = "<a href='#'></a>";
- return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
- div.firstChild.getAttribute("href") === "#";
- }),
-
- // Check if attributes should be retrieved by attribute nodes
- assertAttributes = assert(function( div ) {
- div.innerHTML = "<select></select>";
- var type = typeof div.lastChild.getAttribute("multiple");
- // IE8 returns a string for some attributes even when not present
- return type !== "boolean" && type !== "string";
- }),
-
- // Check if getElementsByClassName can be trusted
- assertUsableClassName = assert(function( div ) {
- // Opera can't find a second classname (in 9.6)
- div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
- if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
- return false;
- }
-
- // Safari 3.2 caches class attributes and doesn't catch changes
- div.lastChild.className = "e";
- return div.getElementsByClassName("e").length === 2;
- }),
-
- // Check if getElementById returns elements by name
- // Check if getElementsByName privileges form controls or returns elements by ID
- assertUsableName = assert(function( div ) {
- // Inject content
- div.id = expando + 0;
- div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
- docElem.insertBefore( div, docElem.firstChild );
-
- // Test
- var pass = document.getElementsByName &&
- // buggy browsers will return fewer than the correct 2
- document.getElementsByName( expando ).length === 2 +
- // buggy browsers will return more than the correct 0
- document.getElementsByName( expando + 0 ).length;
- assertGetIdNotName = !document.getElementById( expando );
-
- // Cleanup
- docElem.removeChild( div );
-
- return pass;
- });
-
-// If slice is not available, provide a backup
-try {
- slice.call( docElem.childNodes, 0 )[0].nodeType;
-} catch ( e ) {
- slice = function( i ) {
- var elem,
- results = [];
- for ( ; (elem = this[i]); i++ ) {
- results.push( elem );
- }
- return results;
- };
-}
-
-function Sizzle( selector, context, results, seed ) {
- results = results || [];
- context = context || document;
- var match, elem, xml, m,
- nodeType = context.nodeType;
-
- if ( !selector || typeof selector !== "string" ) {
- return results;
- }
-
- if ( nodeType !== 1 && nodeType !== 9 ) {
- return [];
- }
-
- xml = isXML( context );
-
- if ( !xml && !seed ) {
- if ( (match = rquickExpr.exec( selector )) ) {
- // Speed-up: Sizzle("#ID")
- if ( (m = match[1]) ) {
- if ( nodeType === 9 ) {
- elem = context.getElementById( m );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- if ( elem && elem.parentNode ) {
- // Handle the case where IE, Opera, and Webkit return items
- // by name instead of ID
- if ( elem.id === m ) {
- results.push( elem );
- return results;
- }
- } else {
- return results;
- }
- } else {
- // Context is not a document
- if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
- contains( context, elem ) && elem.id === m ) {
- results.push( elem );
- return results;
- }
- }
-
- // Speed-up: Sizzle("TAG")
- } else if ( match[2] ) {
- push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
- return results;
-
- // Speed-up: Sizzle(".CLASS")
- } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
- push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
- return results;
- }
- }
- }
-
- // All others
- return select( selector.replace( rtrim, "$1" ), context, results, seed, xml );
-}
-
-Sizzle.matches = function( expr, elements ) {
- return Sizzle( expr, null, null, elements );
-};
-
-Sizzle.matchesSelector = function( elem, expr ) {
- return Sizzle( expr, null, null, [ elem ] ).length > 0;
-};
-
-// Returns a function to use in pseudos for input types
-function createInputPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === type;
- };
-}
-
-// Returns a function to use in pseudos for buttons
-function createButtonPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return (name === "input" || name === "button") && elem.type === type;
- };
-}
-
-// Returns a function to use in pseudos for positionals
-function createPositionalPseudo( fn ) {
- return markFunction(function( argument ) {
- argument = +argument;
- return markFunction(function( seed, matches ) {
- var j,
- matchIndexes = fn( [], seed.length, argument ),
- i = matchIndexes.length;
-
- // Match elements found at the specified indexes
- while ( i-- ) {
- if ( seed[ (j = matchIndexes[i]) ] ) {
- seed[j] = !(matches[j] = seed[j]);
- }
- }
- });
- });
-}
-
-/**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-getText = Sizzle.getText = function( elem ) {
- var node,
- ret = "",
- i = 0,
- nodeType = elem.nodeType;
-
- if ( nodeType ) {
- if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
- // Use textContent for elements
- // innerText usage removed for consistency of new lines (see #11153)
- if ( typeof elem.textContent === "string" ) {
- return elem.textContent;
- } else {
- // Traverse its children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
- ret += getText( elem );
- }
- }
- } else if ( nodeType === 3 || nodeType === 4 ) {
- return elem.nodeValue;
- }
- // Do not include comment or processing instruction nodes
- } else {
-
- // If no nodeType, this is expected to be an array
- for ( ; (node = elem[i]); i++ ) {
- // Do not traverse comment nodes
- ret += getText( node );
- }
- }
- return ret;
-};
-
-isXML = Sizzle.isXML = function( elem ) {
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = elem && (elem.ownerDocument || elem).documentElement;
- return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-// Element contains another
-contains = Sizzle.contains = docElem.contains ?
- function( a, b ) {
- var adown = a.nodeType === 9 ? a.documentElement : a,
- bup = b && b.parentNode;
- return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
- } :
- docElem.compareDocumentPosition ?
- function( a, b ) {
- return b && !!( a.compareDocumentPosition( b ) & 16 );
- } :
- function( a, b ) {
- while ( (b = b.parentNode) ) {
- if ( b === a ) {
- return true;
- }
- }
- return false;
- };
-
-Sizzle.attr = function( elem, name ) {
- var val,
- xml = isXML( elem );
-
- if ( !xml ) {
- name = name.toLowerCase();
- }
- if ( (val = Expr.attrHandle[ name ]) ) {
- return val( elem );
- }
- if ( xml || assertAttributes ) {
- return elem.getAttribute( name );
- }
- val = elem.getAttributeNode( name );
- return val ?
- typeof elem[ name ] === "boolean" ?
- elem[ name ] ? name : null :
- val.specified ? val.value : null :
- null;
-};
-
-Expr = Sizzle.selectors = {
-
- // Can be adjusted by the user
- cacheLength: 50,
-
- createPseudo: markFunction,
-
- match: matchExpr,
-
- // IE6/7 return a modified href
- attrHandle: assertHrefNotNormalized ?
- {} :
- {
- "href": function( elem ) {
- return elem.getAttribute( "href", 2 );
- },
- "type": function( elem ) {
- return elem.getAttribute("type");
- }
- },
-
- find: {
- "ID": assertGetIdNotName ?
- function( id, context, xml ) {
- if ( typeof context.getElementById !== strundefined && !xml ) {
- var m = context.getElementById( id );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- return m && m.parentNode ? [m] : [];
- }
- } :
- function( id, context, xml ) {
- if ( typeof context.getElementById !== strundefined && !xml ) {
- var m = context.getElementById( id );
-
- return m ?
- m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
- [m] :
- undefined :
- [];
- }
- },
-
- "TAG": assertTagNameNoComments ?
- function( tag, context ) {
- if ( typeof context.getElementsByTagName !== strundefined ) {
- return context.getElementsByTagName( tag );
- }
- } :
- function( tag, context ) {
- var results = context.getElementsByTagName( tag );
-
- // Filter out possible comments
- if ( tag === "*" ) {
- var elem,
- tmp = [],
- i = 0;
-
- for ( ; (elem = results[i]); i++ ) {
- if ( elem.nodeType === 1 ) {
- tmp.push( elem );
- }
- }
-
- return tmp;
- }
- return results;
- },
-
- "NAME": assertUsableName && function( tag, context ) {
- if ( typeof context.getElementsByName !== strundefined ) {
- return context.getElementsByName( name );
- }
- },
-
- "CLASS": assertUsableClassName && function( className, context, xml ) {
- if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
- return context.getElementsByClassName( className );
- }
- }
- },
-
- relative: {
- ">": { dir: "parentNode", first: true },
- " ": { dir: "parentNode" },
- "+": { dir: "previousSibling", first: true },
- "~": { dir: "previousSibling" }
- },
-
- preFilter: {
- "ATTR": function( match ) {
- match[1] = match[1].replace( rbackslash, "" );
-
- // Move the given value to match[3] whether quoted or unquoted
- match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
-
- if ( match[2] === "~=" ) {
- match[3] = " " + match[3] + " ";
- }
-
- return match.slice( 0, 4 );
- },
-
- "CHILD": function( match ) {
- /* matches from matchExpr["CHILD"]
- 1 type (only|nth|...)
- 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
- 3 xn-component of xn+y argument ([+-]?\d*n|)
- 4 sign of xn-component
- 5 x of xn-component
- 6 sign of y-component
- 7 y of y-component
- */
- match[1] = match[1].toLowerCase();
-
- if ( match[1] === "nth" ) {
- // nth-child requires argument
- if ( !match[2] ) {
- Sizzle.error( match[0] );
- }
-
- // numeric x and y parameters for Expr.filter.CHILD
- // remember that false/true cast respectively to 0/1
- match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
- match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
-
- // other types prohibit arguments
- } else if ( match[2] ) {
- Sizzle.error( match[0] );
- }
-
- return match;
- },
-
- "PSEUDO": function( match ) {
- var unquoted, excess;
- if ( matchExpr["CHILD"].test( match[0] ) ) {
- return null;
- }
-
- if ( match[3] ) {
- match[2] = match[3];
- } else if ( (unquoted = match[4]) ) {
- // Only check arguments that contain a pseudo
- if ( rpseudo.test(unquoted) &&
- // Get excess from tokenize (recursively)
- (excess = tokenize( unquoted, true )) &&
- // advance to the next closing parenthesis
- (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
-
- // excess is a negative index
- unquoted = unquoted.slice( 0, excess );
- match[0] = match[0].slice( 0, excess );
- }
- match[2] = unquoted;
- }
-
- // Return only captures needed by the pseudo filter method (type and argument)
- return match.slice( 0, 3 );
- }
- },
-
- filter: {
- "ID": assertGetIdNotName ?
- function( id ) {
- id = id.replace( rbackslash, "" );
- return function( elem ) {
- return elem.getAttribute("id") === id;
- };
- } :
- function( id ) {
- id = id.replace( rbackslash, "" );
- return function( elem ) {
- var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
- return node && node.value === id;
- };
- },
-
- "TAG": function( nodeName ) {
- if ( nodeName === "*" ) {
- return function() { return true; };
- }
- nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
-
- return function( elem ) {
- return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
- };
- },
-
- "CLASS": function( className ) {
- var pattern = classCache[ expando ][ className ];
- if ( !pattern ) {
- pattern = classCache( className, new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)") );
- }
- return function( elem ) {
- return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
- };
- },
-
- "ATTR": function( name, operator, check ) {
- return function( elem, context ) {
- var result = Sizzle.attr( elem, name );
-
- if ( result == null ) {
- return operator === "!=";
- }
- if ( !operator ) {
- return true;
- }
-
- result += "";
-
- return operator === "=" ? result === check :
- operator === "!=" ? result !== check :
- operator === "^=" ? check && result.indexOf( check ) === 0 :
- operator === "*=" ? check && result.indexOf( check ) > -1 :
- operator === "$=" ? check && result.substr( result.length - check.length ) === check :
- operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
- operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" :
- false;
- };
- },
-
- "CHILD": function( type, argument, first, last ) {
-
- if ( type === "nth" ) {
- return function( elem ) {
- var node, diff,
- parent = elem.parentNode;
-
- if ( first === 1 && last === 0 ) {
- return true;
- }
-
- if ( parent ) {
- diff = 0;
- for ( node = parent.firstChild; node; node = node.nextSibling ) {
- if ( node.nodeType === 1 ) {
- diff++;
- if ( elem === node ) {
- break;
- }
- }
- }
- }
-
- // Incorporate the offset (or cast to NaN), then check against cycle size
- diff -= last;
- return diff === first || ( diff % first === 0 && diff / first >= 0 );
- };
- }
-
- return function( elem ) {
- var node = elem;
-
- switch ( type ) {
- case "only":
- case "first":
- while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
-
- if ( type === "first" ) {
- return true;
- }
-
- node = elem;
-
- /* falls through */
- case "last":
- while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
-
- return true;
- }
- };
- },
-
- "PSEUDO": function( pseudo, argument ) {
- // pseudo-class names are case-insensitive
- // http://www.w3.org/TR/selectors/#pseudo-classes
- // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
- // Remember that setFilters inherits from pseudos
- var args,
- fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
- Sizzle.error( "unsupported pseudo: " + pseudo );
-
- // The user may use createPseudo to indicate that
- // arguments are needed to create the filter function
- // just as Sizzle does
- if ( fn[ expando ] ) {
- return fn( argument );
- }
-
- // But maintain support for old signatures
- if ( fn.length > 1 ) {
- args = [ pseudo, pseudo, "", argument ];
- return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
- markFunction(function( seed, matches ) {
- var idx,
- matched = fn( seed, argument ),
- i = matched.length;
- while ( i-- ) {
- idx = indexOf.call( seed, matched[i] );
- seed[ idx ] = !( matches[ idx ] = matched[i] );
- }
- }) :
- function( elem ) {
- return fn( elem, 0, args );
- };
- }
-
- return fn;
- }
- },
-
- pseudos: {
- "not": markFunction(function( selector ) {
- // Trim the selector passed to compile
- // to avoid treating leading and trailing
- // spaces as combinators
- var input = [],
- results = [],
- matcher = compile( selector.replace( rtrim, "$1" ) );
-
- return matcher[ expando ] ?
- markFunction(function( seed, matches, context, xml ) {
- var elem,
- unmatched = matcher( seed, null, xml, [] ),
- i = seed.length;
-
- // Match elements unmatched by `matcher`
- while ( i-- ) {
- if ( (elem = unmatched[i]) ) {
- seed[i] = !(matches[i] = elem);
- }
- }
- }) :
- function( elem, context, xml ) {
- input[0] = elem;
- matcher( input, null, xml, results );
- return !results.pop();
- };
- }),
-
- "has": markFunction(function( selector ) {
- return function( elem ) {
- return Sizzle( selector, elem ).length > 0;
- };
- }),
-
- "contains": markFunction(function( text ) {
- return function( elem ) {
- return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
- };
- }),
-
- "enabled": function( elem ) {
- return elem.disabled === false;
- },
-
- "disabled": function( elem ) {
- return elem.disabled === true;
- },
-
- "checked": function( elem ) {
- // In CSS3, :checked should return both checked and selected elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- var nodeName = elem.nodeName.toLowerCase();
- return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
- },
-
- "selected": function( elem ) {
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- if ( elem.parentNode ) {
- elem.parentNode.selectedIndex;
- }
-
- return elem.selected === true;
- },
-
- "parent": function( elem ) {
- return !Expr.pseudos["empty"]( elem );
- },
-
- "empty": function( elem ) {
- // http://www.w3.org/TR/selectors/#empty-pseudo
- // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
- // not comment, processing instructions, or others
- // Thanks to Diego Perini for the nodeName shortcut
- // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
- var nodeType;
- elem = elem.firstChild;
- while ( elem ) {
- if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
- return false;
- }
- elem = elem.nextSibling;
- }
- return true;
- },
-
- "header": function( elem ) {
- return rheader.test( elem.nodeName );
- },
-
- "text": function( elem ) {
- var type, attr;
- // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
- // use getAttribute instead to test this case
- return elem.nodeName.toLowerCase() === "input" &&
- (type = elem.type) === "text" &&
- ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
- },
-
- // Input types
- "radio": createInputPseudo("radio"),
- "checkbox": createInputPseudo("checkbox"),
- "file": createInputPseudo("file"),
- "password": createInputPseudo("password"),
- "image": createInputPseudo("image"),
-
- "submit": createButtonPseudo("submit"),
- "reset": createButtonPseudo("reset"),
-
- "button": function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === "button" || name === "button";
- },
-
- "input": function( elem ) {
- return rinputs.test( elem.nodeName );
- },
-
- "focus": function( elem ) {
- var doc = elem.ownerDocument;
- return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href);
- },
-
- "active": function( elem ) {
- return elem === elem.ownerDocument.activeElement;
- },
-
- // Positional types
- "first": createPositionalPseudo(function( matchIndexes, length, argument ) {
- return [ 0 ];
- }),
-
- "last": createPositionalPseudo(function( matchIndexes, length, argument ) {
- return [ length - 1 ];
- }),
-
- "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
- return [ argument < 0 ? argument + length : argument ];
- }),
-
- "even": createPositionalPseudo(function( matchIndexes, length, argument ) {
- for ( var i = 0; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "odd": createPositionalPseudo(function( matchIndexes, length, argument ) {
- for ( var i = 1; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
- for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
- for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- })
- }
-};
-
-function siblingCheck( a, b, ret ) {
- if ( a === b ) {
- return ret;
- }
-
- var cur = a.nextSibling;
-
- while ( cur ) {
- if ( cur === b ) {
- return -1;
- }
-
- cur = cur.nextSibling;
- }
-
- return 1;
-}
-
-sortOrder = docElem.compareDocumentPosition ?
- function( a, b ) {
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
- a.compareDocumentPosition :
- a.compareDocumentPosition(b) & 4
- ) ? -1 : 1;
- } :
- function( a, b ) {
- // The nodes are identical, we can exit early
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
-
- // Fallback to using sourceIndex (in IE) if it's available on both nodes
- } else if ( a.sourceIndex && b.sourceIndex ) {
- return a.sourceIndex - b.sourceIndex;
- }
-
- var al, bl,
- ap = [],
- bp = [],
- aup = a.parentNode,
- bup = b.parentNode,
- cur = aup;
-
- // If the nodes are siblings (or identical) we can do a quick check
- if ( aup === bup ) {
- return siblingCheck( a, b );
-
- // If no parents were found then the nodes are disconnected
- } else if ( !aup ) {
- return -1;
-
- } else if ( !bup ) {
- return 1;
- }
-
- // Otherwise they're somewhere else in the tree so we need
- // to build up a full list of the parentNodes for comparison
- while ( cur ) {
- ap.unshift( cur );
- cur = cur.parentNode;
- }
-
- cur = bup;
-
- while ( cur ) {
- bp.unshift( cur );
- cur = cur.parentNode;
- }
-
- al = ap.length;
- bl = bp.length;
-
- // Start walking down the tree looking for a discrepancy
- for ( var i = 0; i < al && i < bl; i++ ) {
- if ( ap[i] !== bp[i] ) {
- return siblingCheck( ap[i], bp[i] );
- }
- }
-
- // We ended someplace up the tree so do a sibling check
- return i === al ?
- siblingCheck( a, bp[i], -1 ) :
- siblingCheck( ap[i], b, 1 );
- };
-
-// Always assume the presence of duplicates if sort doesn't
-// pass them to our comparison function (as in Google Chrome).
-[0, 0].sort( sortOrder );
-baseHasDuplicate = !hasDuplicate;
-
-// Document sorting and removing duplicates
-Sizzle.uniqueSort = function( results ) {
- var elem,
- i = 1;
-
- hasDuplicate = baseHasDuplicate;
- results.sort( sortOrder );
-
- if ( hasDuplicate ) {
- for ( ; (elem = results[i]); i++ ) {
- if ( elem === results[ i - 1 ] ) {
- results.splice( i--, 1 );
- }
- }
- }
-
- return results;
-};
-
-Sizzle.error = function( msg ) {
- throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
-
-function tokenize( selector, parseOnly ) {
- var matched, match, tokens, type, soFar, groups, preFilters,
- cached = tokenCache[ expando ][ selector ];
-
- if ( cached ) {
- return parseOnly ? 0 : cached.slice( 0 );
- }
-
- soFar = selector;
- groups = [];
- preFilters = Expr.preFilter;
-
- while ( soFar ) {
-
- // Comma and first run
- if ( !matched || (match = rcomma.exec( soFar )) ) {
- if ( match ) {
- soFar = soFar.slice( match[0].length );
- }
- groups.push( tokens = [] );
- }
-
- matched = false;
-
- // Combinators
- if ( (match = rcombinators.exec( soFar )) ) {
- tokens.push( matched = new Token( match.shift() ) );
- soFar = soFar.slice( matched.length );
-
- // Cast descendant combinators to space
- matched.type = match[0].replace( rtrim, " " );
- }
-
- // Filters
- for ( type in Expr.filter ) {
- if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
- // The last two arguments here are (context, xml) for backCompat
- (match = preFilters[ type ]( match, document, true ))) ) {
-
- tokens.push( matched = new Token( match.shift() ) );
- soFar = soFar.slice( matched.length );
- matched.type = type;
- matched.matches = match;
- }
- }
-
- if ( !matched ) {
- break;
- }
- }
-
- // Return the length of the invalid excess
- // if we're just parsing
- // Otherwise, throw an error or return tokens
- return parseOnly ?
- soFar.length :
- soFar ?
- Sizzle.error( selector ) :
- // Cache the tokens
- tokenCache( selector, groups ).slice( 0 );
-}
-
-function addCombinator( matcher, combinator, base ) {
- var dir = combinator.dir,
- checkNonElements = base && combinator.dir === "parentNode",
- doneName = done++;
-
- return combinator.first ?
- // Check against closest ancestor/preceding element
- function( elem, context, xml ) {
- while ( (elem = elem[ dir ]) ) {
- if ( checkNonElements || elem.nodeType === 1 ) {
- return matcher( elem, context, xml );
- }
- }
- } :
-
- // Check against all ancestor/preceding elements
- function( elem, context, xml ) {
- // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
- if ( !xml ) {
- var cache,
- dirkey = dirruns + " " + doneName + " ",
- cachedkey = dirkey + cachedruns;
- while ( (elem = elem[ dir ]) ) {
- if ( checkNonElements || elem.nodeType === 1 ) {
- if ( (cache = elem[ expando ]) === cachedkey ) {
- return elem.sizset;
- } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
- if ( elem.sizset ) {
- return elem;
- }
- } else {
- elem[ expando ] = cachedkey;
- if ( matcher( elem, context, xml ) ) {
- elem.sizset = true;
- return elem;
- }
- elem.sizset = false;
- }
- }
- }
- } else {
- while ( (elem = elem[ dir ]) ) {
- if ( checkNonElements || elem.nodeType === 1 ) {
- if ( matcher( elem, context, xml ) ) {
- return elem;
- }
- }
- }
- }
- };
-}
-
-function elementMatcher( matchers ) {
- return matchers.length > 1 ?
- function( elem, context, xml ) {
- var i = matchers.length;
- while ( i-- ) {
- if ( !matchers[i]( elem, context, xml ) ) {
- return false;
- }
- }
- return true;
- } :
- matchers[0];
-}
-
-function condense( unmatched, map, filter, context, xml ) {
- var elem,
- newUnmatched = [],
- i = 0,
- len = unmatched.length,
- mapped = map != null;
-
- for ( ; i < len; i++ ) {
- if ( (elem = unmatched[i]) ) {
- if ( !filter || filter( elem, context, xml ) ) {
- newUnmatched.push( elem );
- if ( mapped ) {
- map.push( i );
- }
- }
- }
- }
-
- return newUnmatched;
-}
-
-function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
- if ( postFilter && !postFilter[ expando ] ) {
- postFilter = setMatcher( postFilter );
- }
- if ( postFinder && !postFinder[ expando ] ) {
- postFinder = setMatcher( postFinder, postSelector );
- }
- return markFunction(function( seed, results, context, xml ) {
- // Positional selectors apply to seed elements, so it is invalid to follow them with relative ones
- if ( seed && postFinder ) {
- return;
- }
-
- var i, elem, postFilterIn,
- preMap = [],
- postMap = [],
- preexisting = results.length,
-
- // Get initial elements from seed or context
- elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [], seed ),
-
- // Prefilter to get matcher input, preserving a map for seed-results synchronization
- matcherIn = preFilter && ( seed || !selector ) ?
- condense( elems, preMap, preFilter, context, xml ) :
- elems,
-
- matcherOut = matcher ?
- // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
- postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
-
- // ...intermediate processing is necessary
- [] :
-
- // ...otherwise use results directly
- results :
- matcherIn;
-
- // Find primary matches
- if ( matcher ) {
- matcher( matcherIn, matcherOut, context, xml );
- }
-
- // Apply postFilter
- if ( postFilter ) {
- postFilterIn = condense( matcherOut, postMap );
- postFilter( postFilterIn, [], context, xml );
-
- // Un-match failing elements by moving them back to matcherIn
- i = postFilterIn.length;
- while ( i-- ) {
- if ( (elem = postFilterIn[i]) ) {
- matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
- }
- }
- }
-
- // Keep seed and results synchronized
- if ( seed ) {
- // Ignore postFinder because it can't coexist with seed
- i = preFilter && matcherOut.length;
- while ( i-- ) {
- if ( (elem = matcherOut[i]) ) {
- seed[ preMap[i] ] = !(results[ preMap[i] ] = elem);
- }
- }
- } else {
- matcherOut = condense(
- matcherOut === results ?
- matcherOut.splice( preexisting, matcherOut.length ) :
- matcherOut
- );
- if ( postFinder ) {
- postFinder( null, results, matcherOut, xml );
- } else {
- push.apply( results, matcherOut );
- }
- }
- });
-}
-
-function matcherFromTokens( tokens ) {
- var checkContext, matcher, j,
- len = tokens.length,
- leadingRelative = Expr.relative[ tokens[0].type ],
- implicitRelative = leadingRelative || Expr.relative[" "],
- i = leadingRelative ? 1 : 0,
-
- // The foundational matcher ensures that elements are reachable from top-level context(s)
- matchContext = addCombinator( function( elem ) {
- return elem === checkContext;
- }, implicitRelative, true ),
- matchAnyContext = addCombinator( function( elem ) {
- return indexOf.call( checkContext, elem ) > -1;
- }, implicitRelative, true ),
- matchers = [ function( elem, context, xml ) {
- return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
- (checkContext = context).nodeType ?
- matchContext( elem, context, xml ) :
- matchAnyContext( elem, context, xml ) );
- } ];
-
- for ( ; i < len; i++ ) {
- if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
- matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
- } else {
- // The concatenated values are (context, xml) for backCompat
- matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
-
- // Return special upon seeing a positional matcher
- if ( matcher[ expando ] ) {
- // Find the next relative operator (if any) for proper handling
- j = ++i;
- for ( ; j < len; j++ ) {
- if ( Expr.relative[ tokens[j].type ] ) {
- break;
- }
- }
- return setMatcher(
- i > 1 && elementMatcher( matchers ),
- i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ),
- matcher,
- i < j && matcherFromTokens( tokens.slice( i, j ) ),
- j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
- j < len && tokens.join("")
- );
- }
- matchers.push( matcher );
- }
- }
-
- return elementMatcher( matchers );
-}
-
-function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
- var bySet = setMatchers.length > 0,
- byElement = elementMatchers.length > 0,
- superMatcher = function( seed, context, xml, results, expandContext ) {
- var elem, j, matcher,
- setMatched = [],
- matchedCount = 0,
- i = "0",
- unmatched = seed && [],
- outermost = expandContext != null,
- contextBackup = outermostContext,
- // We must always have either seed elements or context
- elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
- // Nested matchers should use non-integer dirruns
- dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);
-
- if ( outermost ) {
- outermostContext = context !== document && context;
- cachedruns = superMatcher.el;
- }
-
- // Add elements passing elementMatchers directly to results
- for ( ; (elem = elems[i]) != null; i++ ) {
- if ( byElement && elem ) {
- for ( j = 0; (matcher = elementMatchers[j]); j++ ) {
- if ( matcher( elem, context, xml ) ) {
- results.push( elem );
- break;
- }
- }
- if ( outermost ) {
- dirruns = dirrunsUnique;
- cachedruns = ++superMatcher.el;
- }
- }
-
- // Track unmatched elements for set filters
- if ( bySet ) {
- // They will have gone through all possible matchers
- if ( (elem = !matcher && elem) ) {
- matchedCount--;
- }
-
- // Lengthen the array for every element, matched or not
- if ( seed ) {
- unmatched.push( elem );
- }
- }
- }
-
- // Apply set filters to unmatched elements
- matchedCount += i;
- if ( bySet && i !== matchedCount ) {
- for ( j = 0; (matcher = setMatchers[j]); j++ ) {
- matcher( unmatched, setMatched, context, xml );
- }
-
- if ( seed ) {
- // Reintegrate element matches to eliminate the need for sorting
- if ( matchedCount > 0 ) {
- while ( i-- ) {
- if ( !(unmatched[i] || setMatched[i]) ) {
- setMatched[i] = pop.call( results );
- }
- }
- }
-
- // Discard index placeholder values to get only actual matches
- setMatched = condense( setMatched );
- }
-
- // Add matches to results
- push.apply( results, setMatched );
-
- // Seedless set matches succeeding multiple successful matchers stipulate sorting
- if ( outermost && !seed && setMatched.length > 0 &&
- ( matchedCount + setMatchers.length ) > 1 ) {
-
- Sizzle.uniqueSort( results );
- }
- }
-
- // Override manipulation of globals by nested matchers
- if ( outermost ) {
- dirruns = dirrunsUnique;
- outermostContext = contextBackup;
- }
-
- return unmatched;
- };
-
- superMatcher.el = 0;
- return bySet ?
- markFunction( superMatcher ) :
- superMatcher;
-}
-
-compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
- var i,
- setMatchers = [],
- elementMatchers = [],
- cached = compilerCache[ expando ][ selector ];
-
- if ( !cached ) {
- // Generate a function of recursive functions that can be used to check each element
- if ( !group ) {
- group = tokenize( selector );
- }
- i = group.length;
- while ( i-- ) {
- cached = matcherFromTokens( group[i] );
- if ( cached[ expando ] ) {
- setMatchers.push( cached );
- } else {
- elementMatchers.push( cached );
- }
- }
-
- // Cache the compiled function
- cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
- }
- return cached;
-};
-
-function multipleContexts( selector, contexts, results, seed ) {
- var i = 0,
- len = contexts.length;
- for ( ; i < len; i++ ) {
- Sizzle( selector, contexts[i], results, seed );
- }
- return results;
-}
-
-function select( selector, context, results, seed, xml ) {
- var i, tokens, token, type, find,
- match = tokenize( selector ),
- j = match.length;
-
- if ( !seed ) {
- // Try to minimize operations if there is only one group
- if ( match.length === 1 ) {
-
- // Take a shortcut and set the context if the root selector is an ID
- tokens = match[0] = match[0].slice( 0 );
- if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
- context.nodeType === 9 && !xml &&
- Expr.relative[ tokens[1].type ] ) {
-
- context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0];
- if ( !context ) {
- return results;
- }
-
- selector = selector.slice( tokens.shift().length );
- }
-
- // Fetch a seed set for right-to-left matching
- for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {
- token = tokens[i];
-
- // Abort if we hit a combinator
- if ( Expr.relative[ (type = token.type) ] ) {
- break;
- }
- if ( (find = Expr.find[ type ]) ) {
- // Search, expanding context for leading sibling combinators
- if ( (seed = find(
- token.matches[0].replace( rbackslash, "" ),
- rsibling.test( tokens[0].type ) && context.parentNode || context,
- xml
- )) ) {
-
- // If seed is empty or no tokens remain, we can return early
- tokens.splice( i, 1 );
- selector = seed.length && tokens.join("");
- if ( !selector ) {
- push.apply( results, slice.call( seed, 0 ) );
- return results;
- }
-
- break;
- }
- }
- }
- }
- }
-
- // Compile and execute a filtering function
- // Provide `match` to avoid retokenization if we modified the selector above
- compile( selector, match )(
- seed,
- context,
- xml,
- results,
- rsibling.test( selector )
- );
- return results;
-}
-
-if ( document.querySelectorAll ) {
- (function() {
- var disconnectedMatch,
- oldSelect = select,
- rescape = /'|\\/g,
- rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
-
- // qSa(:focus) reports false when true (Chrome 21),
- // A support test would require too much code (would include document ready)
- rbuggyQSA = [":focus"],
-
- // matchesSelector(:focus) reports false when true (Chrome 21),
- // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
- // A support test would require too much code (would include document ready)
- // just skip matchesSelector for :active
- rbuggyMatches = [ ":active", ":focus" ],
- matches = docElem.matchesSelector ||
- docElem.mozMatchesSelector ||
- docElem.webkitMatchesSelector ||
- docElem.oMatchesSelector ||
- docElem.msMatchesSelector;
-
- // Build QSA regex
- // Regex strategy adopted from Diego Perini
- assert(function( div ) {
- // Select is set to empty string on purpose
- // This is to test IE's treatment of not explictly
- // setting a boolean content attribute,
- // since its presence should be enough
- // http://bugs.jquery.com/ticket/12359
- div.innerHTML = "<select><option selected=''></option></select>";
-
- // IE8 - Some boolean attributes are not treated correctly
- if ( !div.querySelectorAll("[selected]").length ) {
- rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
- }
-
- // Webkit/Opera - :checked should return selected option elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- // IE8 throws error here (do not put tests after this one)
- if ( !div.querySelectorAll(":checked").length ) {
- rbuggyQSA.push(":checked");
- }
- });
-
- assert(function( div ) {
-
- // Opera 10-12/IE9 - ^= $= *= and empty values
- // Should not select anything
- div.innerHTML = "<p test=''></p>";
- if ( div.querySelectorAll("[test^='']").length ) {
- rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
- }
-
- // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
- // IE8 throws error here (do not put tests after this one)
- div.innerHTML = "<input type='hidden'/>";
- if ( !div.querySelectorAll(":enabled").length ) {
- rbuggyQSA.push(":enabled", ":disabled");
- }
- });
-
- // rbuggyQSA always contains :focus, so no need for a length check
- rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") );
-
- select = function( selector, context, results, seed, xml ) {
- // Only use querySelectorAll when not filtering,
- // when this is not xml,
- // and when no QSA bugs apply
- if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
- var groups, i,
- old = true,
- nid = expando,
- newContext = context,
- newSelector = context.nodeType === 9 && selector;
-
- // qSA works strangely on Element-rooted queries
- // We can work around this by specifying an extra ID on the root
- // and working up from there (Thanks to Andrew Dupont for the technique)
- // IE 8 doesn't work on object elements
- if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
- groups = tokenize( selector );
-
- if ( (old = context.getAttribute("id")) ) {
- nid = old.replace( rescape, "\\$&" );
- } else {
- context.setAttribute( "id", nid );
- }
- nid = "[id='" + nid + "'] ";
-
- i = groups.length;
- while ( i-- ) {
- groups[i] = nid + groups[i].join("");
- }
- newContext = rsibling.test( selector ) && context.parentNode || context;
- newSelector = groups.join(",");
- }
-
- if ( newSelector ) {
- try {
- push.apply( results, slice.call( newContext.querySelectorAll(
- newSelector
- ), 0 ) );
- return results;
- } catch(qsaError) {
- } finally {
- if ( !old ) {
- context.removeAttribute("id");
- }
- }
- }
- }
-
- return oldSelect( selector, context, results, seed, xml );
- };
-
- if ( matches ) {
- assert(function( div ) {
- // Check to see if it's possible to do matchesSelector
- // on a disconnected node (IE 9)
- disconnectedMatch = matches.call( div, "div" );
-
- // This should fail with an exception
- // Gecko does not error, returns false instead
- try {
- matches.call( div, "[test!='']:sizzle" );
- rbuggyMatches.push( "!=", pseudos );
- } catch ( e ) {}
- });
-
- // rbuggyMatches always contains :active and :focus, so no need for a length check
- rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
-
- Sizzle.matchesSelector = function( elem, expr ) {
- // Make sure that attribute selectors are quoted
- expr = expr.replace( rattributeQuotes, "='$1']" );
-
- // rbuggyMatches always contains :active, so no need for an existence check
- if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) {
- try {
- var ret = matches.call( elem, expr );
-
- // IE 9's matchesSelector returns false on disconnected nodes
- if ( ret || disconnectedMatch ||
- // As well, disconnected nodes are said to be in a document
- // fragment in IE 9
- elem.document && elem.document.nodeType !== 11 ) {
- return ret;
- }
- } catch(e) {}
- }
-
- return Sizzle( expr, null, null, [ elem ] ).length > 0;
- };
- }
- })();
-}
-
-// Deprecated
-Expr.pseudos["nth"] = Expr.pseudos["eq"];
-
-// Back-compat
-function setFilters() {}
-Expr.filters = setFilters.prototype = Expr.pseudos;
-Expr.setFilters = new setFilters();
-
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://sizzlejs.com/
+ */
+(function( window, undefined ) {
+
+var cachedruns,
+ assertGetIdNotName,
+ Expr,
+ getText,
+ isXML,
+ contains,
+ compile,
+ sortOrder,
+ hasDuplicate,
+ outermostContext,
+
+ baseHasDuplicate = true,
+ strundefined = "undefined",
+
+ expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
+
+ Token = String,
+ document = window.document,
+ docElem = document.documentElement,
+ dirruns = 0,
+ done = 0,
+ pop = [].pop,
+ push = [].push,
+ slice = [].slice,
+ // Use a stripped-down indexOf if a native one is unavailable
+ indexOf = [].indexOf || function( elem ) {
+ var i = 0,
+ len = this.length;
+ for ( ; i < len; i++ ) {
+ if ( this[i] === elem ) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ // Augment a function for special use by Sizzle
+ markFunction = function( fn, value ) {
+ fn[ expando ] = value == null || value;
+ return fn;
+ },
+
+ createCache = function() {
+ var cache = {},
+ keys = [];
+
+ return markFunction(function( key, value ) {
+ // Only keep the most recent entries
+ if ( keys.push( key ) > Expr.cacheLength ) {
+ delete cache[ keys.shift() ];
+ }
+
+ return (cache[ key ] = value);
+ }, cache );
+ },
+
+ classCache = createCache(),
+ tokenCache = createCache(),
+ compilerCache = createCache(),
+
+ // Regex
+
+ // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+ whitespace = "[\\x20\\t\\r\\n\\f]",
+ // http://www.w3.org/TR/css3-syntax/#characters
+ characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
+
+ // Loosely modeled on CSS identifier characters
+ // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)
+ // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+ identifier = characterEncoding.replace( "w", "w#" ),
+
+ // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
+ operators = "([*^$|!~]?=)",
+ attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
+ "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
+
+ // Prefer arguments not in parens/brackets,
+ // then attribute selectors and non-pseudos (denoted by :),
+ // then anything else
+ // These preferences are here to reduce the number of selectors
+ // needing tokenize in the PSEUDO preFilter
+ pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",
+
+ // For matchExpr.POS and matchExpr.needsContext
+ pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
+ "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)",
+
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+ rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
+ rpseudo = new RegExp( pseudos ),
+
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
+ rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
+
+ rnot = /^:not/,
+ rsibling = /[\x20\t\r\n\f]*[+~]/,
+ rendsWithNot = /:not\($/,
+
+ rheader = /h\d/i,
+ rinputs = /input|select|textarea|button/i,
+
+ rbackslash = /\\(?!\\)/g,
+
+ matchExpr = {
+ "ID": new RegExp( "^#(" + characterEncoding + ")" ),
+ "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+ "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
+ "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
+ "ATTR": new RegExp( "^" + attributes ),
+ "PSEUDO": new RegExp( "^" + pseudos ),
+ "POS": new RegExp( pos, "i" ),
+ "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace +
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+ // For use in libraries implementing .is()
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
+ },
+
+ // Support
+
+ // Used for testing something on an element
+ assert = function( fn ) {
+ var div = document.createElement("div");
+
+ try {
+ return fn( div );
+ } catch (e) {
+ return false;
+ } finally {
+ // release memory in IE
+ div = null;
+ }
+ },
+
+ // Check if getElementsByTagName("*") returns only elements
+ assertTagNameNoComments = assert(function( div ) {
+ div.appendChild( document.createComment("") );
+ return !div.getElementsByTagName("*").length;
+ }),
+
+ // Check if getAttribute returns normalized href attributes
+ assertHrefNotNormalized = assert(function( div ) {
+ div.innerHTML = "<a href='#'></a>";
+ return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
+ div.firstChild.getAttribute("href") === "#";
+ }),
+
+ // Check if attributes should be retrieved by attribute nodes
+ assertAttributes = assert(function( div ) {
+ div.innerHTML = "<select></select>";
+ var type = typeof div.lastChild.getAttribute("multiple");
+ // IE8 returns a string for some attributes even when not present
+ return type !== "boolean" && type !== "string";
+ }),
+
+ // Check if getElementsByClassName can be trusted
+ assertUsableClassName = assert(function( div ) {
+ // Opera can't find a second classname (in 9.6)
+ div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
+ if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
+ return false;
+ }
+
+ // Safari 3.2 caches class attributes and doesn't catch changes
+ div.lastChild.className = "e";
+ return div.getElementsByClassName("e").length === 2;
+ }),
+
+ // Check if getElementById returns elements by name
+ // Check if getElementsByName privileges form controls or returns elements by ID
+ assertUsableName = assert(function( div ) {
+ // Inject content
+ div.id = expando + 0;
+ div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
+ docElem.insertBefore( div, docElem.firstChild );
+
+ // Test
+ var pass = document.getElementsByName &&
+ // buggy browsers will return fewer than the correct 2
+ document.getElementsByName( expando ).length === 2 +
+ // buggy browsers will return more than the correct 0
+ document.getElementsByName( expando + 0 ).length;
+ assertGetIdNotName = !document.getElementById( expando );
+
+ // Cleanup
+ docElem.removeChild( div );
+
+ return pass;
+ });
+
+// If slice is not available, provide a backup
+try {
+ slice.call( docElem.childNodes, 0 )[0].nodeType;
+} catch ( e ) {
+ slice = function( i ) {
+ var elem,
+ results = [];
+ for ( ; (elem = this[i]); i++ ) {
+ results.push( elem );
+ }
+ return results;
+ };
+}
+
+function Sizzle( selector, context, results, seed ) {
+ results = results || [];
+ context = context || document;
+ var match, elem, xml, m,
+ nodeType = context.nodeType;
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ if ( nodeType !== 1 && nodeType !== 9 ) {
+ return [];
+ }
+
+ xml = isXML( context );
+
+ if ( !xml && !seed ) {
+ if ( (match = rquickExpr.exec( selector )) ) {
+ // Speed-up: Sizzle("#ID")
+ if ( (m = match[1]) ) {
+ if ( nodeType === 9 ) {
+ elem = context.getElementById( m );
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE, Opera, and Webkit return items
+ // by name instead of ID
+ if ( elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ } else {
+ return results;
+ }
+ } else {
+ // Context is not a document
+ if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
+ contains( context, elem ) && elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ }
+
+ // Speed-up: Sizzle("TAG")
+ } else if ( match[2] ) {
+ push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
+ return results;
+
+ // Speed-up: Sizzle(".CLASS")
+ } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
+ push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
+ return results;
+ }
+ }
+ }
+
+ // All others
+ return select( selector.replace( rtrim, "$1" ), context, results, seed, xml );
+}
+
+Sizzle.matches = function( expr, elements ) {
+ return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+ return Sizzle( expr, null, null, [ elem ] ).length > 0;
+};
+
+// Returns a function to use in pseudos for input types
+function createInputPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === type;
+ };
+}
+
+// Returns a function to use in pseudos for buttons
+function createButtonPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && elem.type === type;
+ };
+}
+
+// Returns a function to use in pseudos for positionals
+function createPositionalPseudo( fn ) {
+ return markFunction(function( argument ) {
+ argument = +argument;
+ return markFunction(function( seed, matches ) {
+ var j,
+ matchIndexes = fn( [], seed.length, argument ),
+ i = matchIndexes.length;
+
+ // Match elements found at the specified indexes
+ while ( i-- ) {
+ if ( seed[ (j = matchIndexes[i]) ] ) {
+ seed[j] = !(matches[j] = seed[j]);
+ }
+ }
+ });
+ });
+}
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+ var node,
+ ret = "",
+ i = 0,
+ nodeType = elem.nodeType;
+
+ if ( nodeType ) {
+ if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+ // Use textContent for elements
+ // innerText usage removed for consistency of new lines (see #11153)
+ if ( typeof elem.textContent === "string" ) {
+ return elem.textContent;
+ } else {
+ // Traverse its children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ ret += getText( elem );
+ }
+ }
+ } else if ( nodeType === 3 || nodeType === 4 ) {
+ return elem.nodeValue;
+ }
+ // Do not include comment or processing instruction nodes
+ } else {
+
+ // If no nodeType, this is expected to be an array
+ for ( ; (node = elem[i]); i++ ) {
+ // Do not traverse comment nodes
+ ret += getText( node );
+ }
+ }
+ return ret;
+};
+
+isXML = Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+// Element contains another
+contains = Sizzle.contains = docElem.contains ?
+ function( a, b ) {
+ var adown = a.nodeType === 9 ? a.documentElement : a,
+ bup = b && b.parentNode;
+ return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
+ } :
+ docElem.compareDocumentPosition ?
+ function( a, b ) {
+ return b && !!( a.compareDocumentPosition( b ) & 16 );
+ } :
+ function( a, b ) {
+ while ( (b = b.parentNode) ) {
+ if ( b === a ) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+Sizzle.attr = function( elem, name ) {
+ var val,
+ xml = isXML( elem );
+
+ if ( !xml ) {
+ name = name.toLowerCase();
+ }
+ if ( (val = Expr.attrHandle[ name ]) ) {
+ return val( elem );
+ }
+ if ( xml || assertAttributes ) {
+ return elem.getAttribute( name );
+ }
+ val = elem.getAttributeNode( name );
+ return val ?
+ typeof elem[ name ] === "boolean" ?
+ elem[ name ] ? name : null :
+ val.specified ? val.value : null :
+ null;
+};
+
+Expr = Sizzle.selectors = {
+
+ // Can be adjusted by the user
+ cacheLength: 50,
+
+ createPseudo: markFunction,
+
+ match: matchExpr,
+
+ // IE6/7 return a modified href
+ attrHandle: assertHrefNotNormalized ?
+ {} :
+ {
+ "href": function( elem ) {
+ return elem.getAttribute( "href", 2 );
+ },
+ "type": function( elem ) {
+ return elem.getAttribute("type");
+ }
+ },
+
+ find: {
+ "ID": assertGetIdNotName ?
+ function( id, context, xml ) {
+ if ( typeof context.getElementById !== strundefined && !xml ) {
+ var m = context.getElementById( id );
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ return m && m.parentNode ? [m] : [];
+ }
+ } :
+ function( id, context, xml ) {
+ if ( typeof context.getElementById !== strundefined && !xml ) {
+ var m = context.getElementById( id );
+
+ return m ?
+ m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
+ [m] :
+ undefined :
+ [];
+ }
+ },
+
+ "TAG": assertTagNameNoComments ?
+ function( tag, context ) {
+ if ( typeof context.getElementsByTagName !== strundefined ) {
+ return context.getElementsByTagName( tag );
+ }
+ } :
+ function( tag, context ) {
+ var results = context.getElementsByTagName( tag );
+
+ // Filter out possible comments
+ if ( tag === "*" ) {
+ var elem,
+ tmp = [],
+ i = 0;
+
+ for ( ; (elem = results[i]); i++ ) {
+ if ( elem.nodeType === 1 ) {
+ tmp.push( elem );
+ }
+ }
+
+ return tmp;
+ }
+ return results;
+ },
+
+ "NAME": assertUsableName && function( tag, context ) {
+ if ( typeof context.getElementsByName !== strundefined ) {
+ return context.getElementsByName( name );
+ }
+ },
+
+ "CLASS": assertUsableClassName && function( className, context, xml ) {
+ if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
+ return context.getElementsByClassName( className );
+ }
+ }
+ },
+
+ relative: {
+ ">": { dir: "parentNode", first: true },
+ " ": { dir: "parentNode" },
+ "+": { dir: "previousSibling", first: true },
+ "~": { dir: "previousSibling" }
+ },
+
+ preFilter: {
+ "ATTR": function( match ) {
+ match[1] = match[1].replace( rbackslash, "" );
+
+ // Move the given value to match[3] whether quoted or unquoted
+ match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
+
+ if ( match[2] === "~=" ) {
+ match[3] = " " + match[3] + " ";
+ }
+
+ return match.slice( 0, 4 );
+ },
+
+ "CHILD": function( match ) {
+ /* matches from matchExpr["CHILD"]
+ 1 type (only|nth|...)
+ 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+ 3 xn-component of xn+y argument ([+-]?\d*n|)
+ 4 sign of xn-component
+ 5 x of xn-component
+ 6 sign of y-component
+ 7 y of y-component
+ */
+ match[1] = match[1].toLowerCase();
+
+ if ( match[1] === "nth" ) {
+ // nth-child requires argument
+ if ( !match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // numeric x and y parameters for Expr.filter.CHILD
+ // remember that false/true cast respectively to 0/1
+ match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
+ match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
+
+ // other types prohibit arguments
+ } else if ( match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ return match;
+ },
+
+ "PSEUDO": function( match ) {
+ var unquoted, excess;
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
+ return null;
+ }
+
+ if ( match[3] ) {
+ match[2] = match[3];
+ } else if ( (unquoted = match[4]) ) {
+ // Only check arguments that contain a pseudo
+ if ( rpseudo.test(unquoted) &&
+ // Get excess from tokenize (recursively)
+ (excess = tokenize( unquoted, true )) &&
+ // advance to the next closing parenthesis
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+ // excess is a negative index
+ unquoted = unquoted.slice( 0, excess );
+ match[0] = match[0].slice( 0, excess );
+ }
+ match[2] = unquoted;
+ }
+
+ // Return only captures needed by the pseudo filter method (type and argument)
+ return match.slice( 0, 3 );
+ }
+ },
+
+ filter: {
+ "ID": assertGetIdNotName ?
+ function( id ) {
+ id = id.replace( rbackslash, "" );
+ return function( elem ) {
+ return elem.getAttribute("id") === id;
+ };
+ } :
+ function( id ) {
+ id = id.replace( rbackslash, "" );
+ return function( elem ) {
+ var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+ return node && node.value === id;
+ };
+ },
+
+ "TAG": function( nodeName ) {
+ if ( nodeName === "*" ) {
+ return function() { return true; };
+ }
+ nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
+
+ return function( elem ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+ };
+ },
+
+ "CLASS": function( className ) {
+ var pattern = classCache[ expando ][ className ];
+ if ( !pattern ) {
+ pattern = classCache( className, new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)") );
+ }
+ return function( elem ) {
+ return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
+ };
+ },
+
+ "ATTR": function( name, operator, check ) {
+ return function( elem, context ) {
+ var result = Sizzle.attr( elem, name );
+
+ if ( result == null ) {
+ return operator === "!=";
+ }
+ if ( !operator ) {
+ return true;
+ }
+
+ result += "";
+
+ return operator === "=" ? result === check :
+ operator === "!=" ? result !== check :
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
+ operator === "$=" ? check && result.substr( result.length - check.length ) === check :
+ operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
+ operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" :
+ false;
+ };
+ },
+
+ "CHILD": function( type, argument, first, last ) {
+
+ if ( type === "nth" ) {
+ return function( elem ) {
+ var node, diff,
+ parent = elem.parentNode;
+
+ if ( first === 1 && last === 0 ) {
+ return true;
+ }
+
+ if ( parent ) {
+ diff = 0;
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ diff++;
+ if ( elem === node ) {
+ break;
+ }
+ }
+ }
+ }
+
+ // Incorporate the offset (or cast to NaN), then check against cycle size
+ diff -= last;
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
+ };
+ }
+
+ return function( elem ) {
+ var node = elem;
+
+ switch ( type ) {
+ case "only":
+ case "first":
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ if ( type === "first" ) {
+ return true;
+ }
+
+ node = elem;
+
+ /* falls through */
+ case "last":
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ };
+ },
+
+ "PSEUDO": function( pseudo, argument ) {
+ // pseudo-class names are case-insensitive
+ // http://www.w3.org/TR/selectors/#pseudo-classes
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+ // Remember that setFilters inherits from pseudos
+ var args,
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+ Sizzle.error( "unsupported pseudo: " + pseudo );
+
+ // The user may use createPseudo to indicate that
+ // arguments are needed to create the filter function
+ // just as Sizzle does
+ if ( fn[ expando ] ) {
+ return fn( argument );
+ }
+
+ // But maintain support for old signatures
+ if ( fn.length > 1 ) {
+ args = [ pseudo, pseudo, "", argument ];
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+ markFunction(function( seed, matches ) {
+ var idx,
+ matched = fn( seed, argument ),
+ i = matched.length;
+ while ( i-- ) {
+ idx = indexOf.call( seed, matched[i] );
+ seed[ idx ] = !( matches[ idx ] = matched[i] );
+ }
+ }) :
+ function( elem ) {
+ return fn( elem, 0, args );
+ };
+ }
+
+ return fn;
+ }
+ },
+
+ pseudos: {
+ "not": markFunction(function( selector ) {
+ // Trim the selector passed to compile
+ // to avoid treating leading and trailing
+ // spaces as combinators
+ var input = [],
+ results = [],
+ matcher = compile( selector.replace( rtrim, "$1" ) );
+
+ return matcher[ expando ] ?
+ markFunction(function( seed, matches, context, xml ) {
+ var elem,
+ unmatched = matcher( seed, null, xml, [] ),
+ i = seed.length;
+
+ // Match elements unmatched by `matcher`
+ while ( i-- ) {
+ if ( (elem = unmatched[i]) ) {
+ seed[i] = !(matches[i] = elem);
+ }
+ }
+ }) :
+ function( elem, context, xml ) {
+ input[0] = elem;
+ matcher( input, null, xml, results );
+ return !results.pop();
+ };
+ }),
+
+ "has": markFunction(function( selector ) {
+ return function( elem ) {
+ return Sizzle( selector, elem ).length > 0;
+ };
+ }),
+
+ "contains": markFunction(function( text ) {
+ return function( elem ) {
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+ };
+ }),
+
+ "enabled": function( elem ) {
+ return elem.disabled === false;
+ },
+
+ "disabled": function( elem ) {
+ return elem.disabled === true;
+ },
+
+ "checked": function( elem ) {
+ // In CSS3, :checked should return both checked and selected elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ var nodeName = elem.nodeName.toLowerCase();
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+ },
+
+ "selected": function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ "parent": function( elem ) {
+ return !Expr.pseudos["empty"]( elem );
+ },
+
+ "empty": function( elem ) {
+ // http://www.w3.org/TR/selectors/#empty-pseudo
+ // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
+ // not comment, processing instructions, or others
+ // Thanks to Diego Perini for the nodeName shortcut
+ // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
+ var nodeType;
+ elem = elem.firstChild;
+ while ( elem ) {
+ if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
+ return false;
+ }
+ elem = elem.nextSibling;
+ }
+ return true;
+ },
+
+ "header": function( elem ) {
+ return rheader.test( elem.nodeName );
+ },
+
+ "text": function( elem ) {
+ var type, attr;
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // use getAttribute instead to test this case
+ return elem.nodeName.toLowerCase() === "input" &&
+ (type = elem.type) === "text" &&
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
+ },
+
+ // Input types
+ "radio": createInputPseudo("radio"),
+ "checkbox": createInputPseudo("checkbox"),
+ "file": createInputPseudo("file"),
+ "password": createInputPseudo("password"),
+ "image": createInputPseudo("image"),
+
+ "submit": createButtonPseudo("submit"),
+ "reset": createButtonPseudo("reset"),
+
+ "button": function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === "button" || name === "button";
+ },
+
+ "input": function( elem ) {
+ return rinputs.test( elem.nodeName );
+ },
+
+ "focus": function( elem ) {
+ var doc = elem.ownerDocument;
+ return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href);
+ },
+
+ "active": function( elem ) {
+ return elem === elem.ownerDocument.activeElement;
+ },
+
+ // Positional types
+ "first": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ return [ 0 ];
+ }),
+
+ "last": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ return [ length - 1 ];
+ }),
+
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ return [ argument < 0 ? argument + length : argument ];
+ }),
+
+ "even": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ for ( var i = 0; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "odd": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ for ( var i = 1; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ })
+ }
+};
+
+function siblingCheck( a, b, ret ) {
+ if ( a === b ) {
+ return ret;
+ }
+
+ var cur = a.nextSibling;
+
+ while ( cur ) {
+ if ( cur === b ) {
+ return -1;
+ }
+
+ cur = cur.nextSibling;
+ }
+
+ return 1;
+}
+
+sortOrder = docElem.compareDocumentPosition ?
+ function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
+ a.compareDocumentPosition :
+ a.compareDocumentPosition(b) & 4
+ ) ? -1 : 1;
+ } :
+ function( a, b ) {
+ // The nodes are identical, we can exit early
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+
+ // Fallback to using sourceIndex (in IE) if it's available on both nodes
+ } else if ( a.sourceIndex && b.sourceIndex ) {
+ return a.sourceIndex - b.sourceIndex;
+ }
+
+ var al, bl,
+ ap = [],
+ bp = [],
+ aup = a.parentNode,
+ bup = b.parentNode,
+ cur = aup;
+
+ // If the nodes are siblings (or identical) we can do a quick check
+ if ( aup === bup ) {
+ return siblingCheck( a, b );
+
+ // If no parents were found then the nodes are disconnected
+ } else if ( !aup ) {
+ return -1;
+
+ } else if ( !bup ) {
+ return 1;
+ }
+
+ // Otherwise they're somewhere else in the tree so we need
+ // to build up a full list of the parentNodes for comparison
+ while ( cur ) {
+ ap.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ cur = bup;
+
+ while ( cur ) {
+ bp.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ al = ap.length;
+ bl = bp.length;
+
+ // Start walking down the tree looking for a discrepancy
+ for ( var i = 0; i < al && i < bl; i++ ) {
+ if ( ap[i] !== bp[i] ) {
+ return siblingCheck( ap[i], bp[i] );
+ }
+ }
+
+ // We ended someplace up the tree so do a sibling check
+ return i === al ?
+ siblingCheck( a, bp[i], -1 ) :
+ siblingCheck( ap[i], b, 1 );
+ };
+
+// Always assume the presence of duplicates if sort doesn't
+// pass them to our comparison function (as in Google Chrome).
+[0, 0].sort( sortOrder );
+baseHasDuplicate = !hasDuplicate;
+
+// Document sorting and removing duplicates
+Sizzle.uniqueSort = function( results ) {
+ var elem,
+ i = 1;
+
+ hasDuplicate = baseHasDuplicate;
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ for ( ; (elem = results[i]); i++ ) {
+ if ( elem === results[ i - 1 ] ) {
+ results.splice( i--, 1 );
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.error = function( msg ) {
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+function tokenize( selector, parseOnly ) {
+ var matched, match, tokens, type, soFar, groups, preFilters,
+ cached = tokenCache[ expando ][ selector ];
+
+ if ( cached ) {
+ return parseOnly ? 0 : cached.slice( 0 );
+ }
+
+ soFar = selector;
+ groups = [];
+ preFilters = Expr.preFilter;
+
+ while ( soFar ) {
+
+ // Comma and first run
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
+ if ( match ) {
+ soFar = soFar.slice( match[0].length );
+ }
+ groups.push( tokens = [] );
+ }
+
+ matched = false;
+
+ // Combinators
+ if ( (match = rcombinators.exec( soFar )) ) {
+ tokens.push( matched = new Token( match.shift() ) );
+ soFar = soFar.slice( matched.length );
+
+ // Cast descendant combinators to space
+ matched.type = match[0].replace( rtrim, " " );
+ }
+
+ // Filters
+ for ( type in Expr.filter ) {
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+ // The last two arguments here are (context, xml) for backCompat
+ (match = preFilters[ type ]( match, document, true ))) ) {
+
+ tokens.push( matched = new Token( match.shift() ) );
+ soFar = soFar.slice( matched.length );
+ matched.type = type;
+ matched.matches = match;
+ }
+ }
+
+ if ( !matched ) {
+ break;
+ }
+ }
+
+ // Return the length of the invalid excess
+ // if we're just parsing
+ // Otherwise, throw an error or return tokens
+ return parseOnly ?
+ soFar.length :
+ soFar ?
+ Sizzle.error( selector ) :
+ // Cache the tokens
+ tokenCache( selector, groups ).slice( 0 );
+}
+
+function addCombinator( matcher, combinator, base ) {
+ var dir = combinator.dir,
+ checkNonElements = base && combinator.dir === "parentNode",
+ doneName = done++;
+
+ return combinator.first ?
+ // Check against closest ancestor/preceding element
+ function( elem, context, xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( checkNonElements || elem.nodeType === 1 ) {
+ return matcher( elem, context, xml );
+ }
+ }
+ } :
+
+ // Check against all ancestor/preceding elements
+ function( elem, context, xml ) {
+ // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+ if ( !xml ) {
+ var cache,
+ dirkey = dirruns + " " + doneName + " ",
+ cachedkey = dirkey + cachedruns;
+ while ( (elem = elem[ dir ]) ) {
+ if ( checkNonElements || elem.nodeType === 1 ) {
+ if ( (cache = elem[ expando ]) === cachedkey ) {
+ return elem.sizset;
+ } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
+ if ( elem.sizset ) {
+ return elem;
+ }
+ } else {
+ elem[ expando ] = cachedkey;
+ if ( matcher( elem, context, xml ) ) {
+ elem.sizset = true;
+ return elem;
+ }
+ elem.sizset = false;
+ }
+ }
+ }
+ } else {
+ while ( (elem = elem[ dir ]) ) {
+ if ( checkNonElements || elem.nodeType === 1 ) {
+ if ( matcher( elem, context, xml ) ) {
+ return elem;
+ }
+ }
+ }
+ }
+ };
+}
+
+function elementMatcher( matchers ) {
+ return matchers.length > 1 ?
+ function( elem, context, xml ) {
+ var i = matchers.length;
+ while ( i-- ) {
+ if ( !matchers[i]( elem, context, xml ) ) {
+ return false;
+ }
+ }
+ return true;
+ } :
+ matchers[0];
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+ var elem,
+ newUnmatched = [],
+ i = 0,
+ len = unmatched.length,
+ mapped = map != null;
+
+ for ( ; i < len; i++ ) {
+ if ( (elem = unmatched[i]) ) {
+ if ( !filter || filter( elem, context, xml ) ) {
+ newUnmatched.push( elem );
+ if ( mapped ) {
+ map.push( i );
+ }
+ }
+ }
+ }
+
+ return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+ if ( postFilter && !postFilter[ expando ] ) {
+ postFilter = setMatcher( postFilter );
+ }
+ if ( postFinder && !postFinder[ expando ] ) {
+ postFinder = setMatcher( postFinder, postSelector );
+ }
+ return markFunction(function( seed, results, context, xml ) {
+ // Positional selectors apply to seed elements, so it is invalid to follow them with relative ones
+ if ( seed && postFinder ) {
+ return;
+ }
+
+ var i, elem, postFilterIn,
+ preMap = [],
+ postMap = [],
+ preexisting = results.length,
+
+ // Get initial elements from seed or context
+ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [], seed ),
+
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
+ matcherIn = preFilter && ( seed || !selector ) ?
+ condense( elems, preMap, preFilter, context, xml ) :
+ elems,
+
+ matcherOut = matcher ?
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+ // ...intermediate processing is necessary
+ [] :
+
+ // ...otherwise use results directly
+ results :
+ matcherIn;
+
+ // Find primary matches
+ if ( matcher ) {
+ matcher( matcherIn, matcherOut, context, xml );
+ }
+
+ // Apply postFilter
+ if ( postFilter ) {
+ postFilterIn = condense( matcherOut, postMap );
+ postFilter( postFilterIn, [], context, xml );
+
+ // Un-match failing elements by moving them back to matcherIn
+ i = postFilterIn.length;
+ while ( i-- ) {
+ if ( (elem = postFilterIn[i]) ) {
+ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+ }
+ }
+ }
+
+ // Keep seed and results synchronized
+ if ( seed ) {
+ // Ignore postFinder because it can't coexist with seed
+ i = preFilter && matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) ) {
+ seed[ preMap[i] ] = !(results[ preMap[i] ] = elem);
+ }
+ }
+ } else {
+ matcherOut = condense(
+ matcherOut === results ?
+ matcherOut.splice( preexisting, matcherOut.length ) :
+ matcherOut
+ );
+ if ( postFinder ) {
+ postFinder( null, results, matcherOut, xml );
+ } else {
+ push.apply( results, matcherOut );
+ }
+ }
+ });
+}
+
+function matcherFromTokens( tokens ) {
+ var checkContext, matcher, j,
+ len = tokens.length,
+ leadingRelative = Expr.relative[ tokens[0].type ],
+ implicitRelative = leadingRelative || Expr.relative[" "],
+ i = leadingRelative ? 1 : 0,
+
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
+ matchContext = addCombinator( function( elem ) {
+ return elem === checkContext;
+ }, implicitRelative, true ),
+ matchAnyContext = addCombinator( function( elem ) {
+ return indexOf.call( checkContext, elem ) > -1;
+ }, implicitRelative, true ),
+ matchers = [ function( elem, context, xml ) {
+ return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+ (checkContext = context).nodeType ?
+ matchContext( elem, context, xml ) :
+ matchAnyContext( elem, context, xml ) );
+ } ];
+
+ for ( ; i < len; i++ ) {
+ if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+ matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
+ } else {
+ // The concatenated values are (context, xml) for backCompat
+ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+ // Return special upon seeing a positional matcher
+ if ( matcher[ expando ] ) {
+ // Find the next relative operator (if any) for proper handling
+ j = ++i;
+ for ( ; j < len; j++ ) {
+ if ( Expr.relative[ tokens[j].type ] ) {
+ break;
+ }
+ }
+ return setMatcher(
+ i > 1 && elementMatcher( matchers ),
+ i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ),
+ matcher,
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
+ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+ j < len && tokens.join("")
+ );
+ }
+ matchers.push( matcher );
+ }
+ }
+
+ return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+ var bySet = setMatchers.length > 0,
+ byElement = elementMatchers.length > 0,
+ superMatcher = function( seed, context, xml, results, expandContext ) {
+ var elem, j, matcher,
+ setMatched = [],
+ matchedCount = 0,
+ i = "0",
+ unmatched = seed && [],
+ outermost = expandContext != null,
+ contextBackup = outermostContext,
+ // We must always have either seed elements or context
+ elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
+ // Nested matchers should use non-integer dirruns
+ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);
+
+ if ( outermost ) {
+ outermostContext = context !== document && context;
+ cachedruns = superMatcher.el;
+ }
+
+ // Add elements passing elementMatchers directly to results
+ for ( ; (elem = elems[i]) != null; i++ ) {
+ if ( byElement && elem ) {
+ for ( j = 0; (matcher = elementMatchers[j]); j++ ) {
+ if ( matcher( elem, context, xml ) ) {
+ results.push( elem );
+ break;
+ }
+ }
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ cachedruns = ++superMatcher.el;
+ }
+ }
+
+ // Track unmatched elements for set filters
+ if ( bySet ) {
+ // They will have gone through all possible matchers
+ if ( (elem = !matcher && elem) ) {
+ matchedCount--;
+ }
+
+ // Lengthen the array for every element, matched or not
+ if ( seed ) {
+ unmatched.push( elem );
+ }
+ }
+ }
+
+ // Apply set filters to unmatched elements
+ matchedCount += i;
+ if ( bySet && i !== matchedCount ) {
+ for ( j = 0; (matcher = setMatchers[j]); j++ ) {
+ matcher( unmatched, setMatched, context, xml );
+ }
+
+ if ( seed ) {
+ // Reintegrate element matches to eliminate the need for sorting
+ if ( matchedCount > 0 ) {
+ while ( i-- ) {
+ if ( !(unmatched[i] || setMatched[i]) ) {
+ setMatched[i] = pop.call( results );
+ }
+ }
+ }
+
+ // Discard index placeholder values to get only actual matches
+ setMatched = condense( setMatched );
+ }
+
+ // Add matches to results
+ push.apply( results, setMatched );
+
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
+ if ( outermost && !seed && setMatched.length > 0 &&
+ ( matchedCount + setMatchers.length ) > 1 ) {
+
+ Sizzle.uniqueSort( results );
+ }
+ }
+
+ // Override manipulation of globals by nested matchers
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ outermostContext = contextBackup;
+ }
+
+ return unmatched;
+ };
+
+ superMatcher.el = 0;
+ return bySet ?
+ markFunction( superMatcher ) :
+ superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
+ var i,
+ setMatchers = [],
+ elementMatchers = [],
+ cached = compilerCache[ expando ][ selector ];
+
+ if ( !cached ) {
+ // Generate a function of recursive functions that can be used to check each element
+ if ( !group ) {
+ group = tokenize( selector );
+ }
+ i = group.length;
+ while ( i-- ) {
+ cached = matcherFromTokens( group[i] );
+ if ( cached[ expando ] ) {
+ setMatchers.push( cached );
+ } else {
+ elementMatchers.push( cached );
+ }
+ }
+
+ // Cache the compiled function
+ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+ }
+ return cached;
+};
+
+function multipleContexts( selector, contexts, results, seed ) {
+ var i = 0,
+ len = contexts.length;
+ for ( ; i < len; i++ ) {
+ Sizzle( selector, contexts[i], results, seed );
+ }
+ return results;
+}
+
+function select( selector, context, results, seed, xml ) {
+ var i, tokens, token, type, find,
+ match = tokenize( selector ),
+ j = match.length;
+
+ if ( !seed ) {
+ // Try to minimize operations if there is only one group
+ if ( match.length === 1 ) {
+
+ // Take a shortcut and set the context if the root selector is an ID
+ tokens = match[0] = match[0].slice( 0 );
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+ context.nodeType === 9 && !xml &&
+ Expr.relative[ tokens[1].type ] ) {
+
+ context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0];
+ if ( !context ) {
+ return results;
+ }
+
+ selector = selector.slice( tokens.shift().length );
+ }
+
+ // Fetch a seed set for right-to-left matching
+ for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {
+ token = tokens[i];
+
+ // Abort if we hit a combinator
+ if ( Expr.relative[ (type = token.type) ] ) {
+ break;
+ }
+ if ( (find = Expr.find[ type ]) ) {
+ // Search, expanding context for leading sibling combinators
+ if ( (seed = find(
+ token.matches[0].replace( rbackslash, "" ),
+ rsibling.test( tokens[0].type ) && context.parentNode || context,
+ xml
+ )) ) {
+
+ // If seed is empty or no tokens remain, we can return early
+ tokens.splice( i, 1 );
+ selector = seed.length && tokens.join("");
+ if ( !selector ) {
+ push.apply( results, slice.call( seed, 0 ) );
+ return results;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Compile and execute a filtering function
+ // Provide `match` to avoid retokenization if we modified the selector above
+ compile( selector, match )(
+ seed,
+ context,
+ xml,
+ results,
+ rsibling.test( selector )
+ );
+ return results;
+}
+
+if ( document.querySelectorAll ) {
+ (function() {
+ var disconnectedMatch,
+ oldSelect = select,
+ rescape = /'|\\/g,
+ rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
+
+ // qSa(:focus) reports false when true (Chrome 21),
+ // A support test would require too much code (would include document ready)
+ rbuggyQSA = [":focus"],
+
+ // matchesSelector(:focus) reports false when true (Chrome 21),
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+ // A support test would require too much code (would include document ready)
+ // just skip matchesSelector for :active
+ rbuggyMatches = [ ":active", ":focus" ],
+ matches = docElem.matchesSelector ||
+ docElem.mozMatchesSelector ||
+ docElem.webkitMatchesSelector ||
+ docElem.oMatchesSelector ||
+ docElem.msMatchesSelector;
+
+ // Build QSA regex
+ // Regex strategy adopted from Diego Perini
+ assert(function( div ) {
+ // Select is set to empty string on purpose
+ // This is to test IE's treatment of not explictly
+ // setting a boolean content attribute,
+ // since its presence should be enough
+ // http://bugs.jquery.com/ticket/12359
+ div.innerHTML = "<select><option selected=''></option></select>";
+
+ // IE8 - Some boolean attributes are not treated correctly
+ if ( !div.querySelectorAll("[selected]").length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
+ }
+
+ // Webkit/Opera - :checked should return selected option elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ // IE8 throws error here (do not put tests after this one)
+ if ( !div.querySelectorAll(":checked").length ) {
+ rbuggyQSA.push(":checked");
+ }
+ });
+
+ assert(function( div ) {
+
+ // Opera 10-12/IE9 - ^= $= *= and empty values
+ // Should not select anything
+ div.innerHTML = "<p test=''></p>";
+ if ( div.querySelectorAll("[test^='']").length ) {
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
+ }
+
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+ // IE8 throws error here (do not put tests after this one)
+ div.innerHTML = "<input type='hidden'/>";
+ if ( !div.querySelectorAll(":enabled").length ) {
+ rbuggyQSA.push(":enabled", ":disabled");
+ }
+ });
+
+ // rbuggyQSA always contains :focus, so no need for a length check
+ rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") );
+
+ select = function( selector, context, results, seed, xml ) {
+ // Only use querySelectorAll when not filtering,
+ // when this is not xml,
+ // and when no QSA bugs apply
+ if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+ var groups, i,
+ old = true,
+ nid = expando,
+ newContext = context,
+ newSelector = context.nodeType === 9 && selector;
+
+ // qSA works strangely on Element-rooted queries
+ // We can work around this by specifying an extra ID on the root
+ // and working up from there (Thanks to Andrew Dupont for the technique)
+ // IE 8 doesn't work on object elements
+ if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+ groups = tokenize( selector );
+
+ if ( (old = context.getAttribute("id")) ) {
+ nid = old.replace( rescape, "\\$&" );
+ } else {
+ context.setAttribute( "id", nid );
+ }
+ nid = "[id='" + nid + "'] ";
+
+ i = groups.length;
+ while ( i-- ) {
+ groups[i] = nid + groups[i].join("");
+ }
+ newContext = rsibling.test( selector ) && context.parentNode || context;
+ newSelector = groups.join(",");
+ }
+
+ if ( newSelector ) {
+ try {
+ push.apply( results, slice.call( newContext.querySelectorAll(
+ newSelector
+ ), 0 ) );
+ return results;
+ } catch(qsaError) {
+ } finally {
+ if ( !old ) {
+ context.removeAttribute("id");
+ }
+ }
+ }
+ }
+
+ return oldSelect( selector, context, results, seed, xml );
+ };
+
+ if ( matches ) {
+ assert(function( div ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9)
+ disconnectedMatch = matches.call( div, "div" );
+
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ try {
+ matches.call( div, "[test!='']:sizzle" );
+ rbuggyMatches.push( "!=", pseudos );
+ } catch ( e ) {}
+ });
+
+ // rbuggyMatches always contains :active and :focus, so no need for a length check
+ rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
+
+ Sizzle.matchesSelector = function( elem, expr ) {
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace( rattributeQuotes, "='$1']" );
+
+ // rbuggyMatches always contains :active, so no need for an existence check
+ if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) {
+ try {
+ var ret = matches.call( elem, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9
+ elem.document && elem.document.nodeType !== 11 ) {
+ return ret;
+ }
+ } catch(e) {}
+ }
+
+ return Sizzle( expr, null, null, [ elem ] ).length > 0;
+ };
+ }
+ })();
+}
+
+// Deprecated
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Back-compat
+function setFilters() {}
+Expr.filters = setFilters.prototype = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
// Override sizzle attribute retrieval
Sizzle.attr = jQuery.attr;
jQuery.find = Sizzle;
@@ -5335,9 +5335,9 @@ jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;
-
-
-})( window );
+
+
+})( window );
var runtil = /Until$/,
rparentsprev = /^(?:parents|prev(?:Until|All))/,
isSimple = /^.[^:#\[\.,]*$/,
diff --git a/package.json b/package.json
index 3625c1f44..6c3e73531 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "jquery-ui",
"title": "jQuery UI",
"description": "A curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library.",
- "version": "1.9.1pre",
+ "version": "1.10.0pre",
"homepage": "http://jqueryui.com",
"author": {
"name": "jQuery Foundation and other contributors",
@@ -20,11 +20,6 @@
"url": "http://bassistance.de"
},
{
- "name": "Richard D. Worth",
- "email": "rdworth@gmail.com",
- "url": "http://rdworth.org"
- },
- {
"name": "Kris Borchers",
"email": "kris.borchers@gmail.com",
"url": "http://krisborchers.com"
@@ -48,7 +43,7 @@
],
"dependencies": {},
"devDependencies": {
- "grunt": "~0.3.9",
+ "grunt": "~0.3.17",
"grunt-css": "0.2.0",
"grunt-compare-size": "0.1.4",
"grunt-html": "0.1.1",
diff --git a/tests/.jshintrc b/tests/.jshintrc
index 783237218..59ae11530 100644
--- a/tests/.jshintrc
+++ b/tests/.jshintrc
@@ -9,51 +9,26 @@
"latedef": true,
"noarg": true,
"onevar": true,
- "smarttabs": true,
"trailing": true,
"undef": true,
+ "unused": true,
"predef": [
- "addMonths",
"asyncTest",
- "container",
+ "closeEnough",
"deepEqual",
- "d1",
- "d2",
- "dlg",
"domEqual",
- "drag",
- "dragged",
- "el",
"equal",
- "equalsDate",
"expect",
"Globalize",
- "heightAfter",
- "init",
- "isNotOpen",
- "isOpen",
- "modal",
"module",
- "moved",
"notEqual",
- "offsetAfter",
- "offsetBefore",
"ok",
- "PROP_NAME",
"QUnit",
- "restoreScroll",
- "shouldBeDroppable",
- "shouldmove",
- "shouldNotBeDroppable",
- "shouldnotmove",
- "shouldnotresize",
- "shouldresize",
"start",
"strictEqual",
"stop",
"test",
"TestHelpers",
- "widthAfter",
"JSHINT"
]
} \ No newline at end of file
diff --git a/tests/jquery-1.6.1.js b/tests/jquery-1.6.1.js
index 5d5a1d58e..33e87732d 100644
--- a/tests/jquery-1.6.1.js
+++ b/tests/jquery-1.6.1.js
@@ -1895,11 +1895,11 @@ jQuery.fn.extend({
jQuery.removeAttr( this, name );
});
},
-
+
prop: function( name, value ) {
return jQuery.access( this, name, value, true, jQuery.prop );
},
-
+
removeProp: function( name ) {
name = jQuery.propFix[ name ] || name;
return this.each(function() {
@@ -2031,7 +2031,7 @@ jQuery.fn.extend({
val: function( value ) {
var hooks, ret,
elem = this[0];
-
+
if ( !arguments.length ) {
if ( elem ) {
hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
@@ -2159,15 +2159,15 @@ jQuery.extend({
height: true,
offset: true
},
-
+
attrFix: {
// Always normalize to ensure hook usage
tabindex: "tabIndex"
},
-
+
attr: function( elem, name, value, pass ) {
var nType = elem.nodeType;
-
+
// don't get/set attributes on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return undefined;
@@ -2235,7 +2235,7 @@ jQuery.extend({
var propName;
if ( elem.nodeType === 1 ) {
name = jQuery.attrFix[ name ] || name;
-
+
if ( jQuery.support.getSetAttribute ) {
// Use removeAttribute in browsers that support it
elem.removeAttribute( name );
@@ -2299,7 +2299,7 @@ jQuery.extend({
frameborder: "frameBorder",
contenteditable: "contentEditable"
},
-
+
prop: function( elem, name, value ) {
var nType = elem.nodeType;
@@ -2313,7 +2313,7 @@ jQuery.extend({
// Try to normalize/fix the name
name = notxml && jQuery.propFix[ name ] || name;
-
+
hooks = jQuery.propHooks[ name ];
if ( value !== undefined ) {
@@ -2333,7 +2333,7 @@ jQuery.extend({
}
}
},
-
+
propHooks: {}
});
@@ -2388,7 +2388,7 @@ if ( !jQuery.support.getSetAttribute ) {
// propFix is more comprehensive and contains all fixes
jQuery.attrFix = jQuery.propFix;
-
+
// Use this for any attribute on a form in IE6/7
formHook = jQuery.attrHooks.name = jQuery.valHooks.button = {
get: function( elem, name ) {
@@ -2759,7 +2759,7 @@ jQuery.event = {
}
}
},
-
+
// Events that are safe to short-circuit if no handlers are attached.
// Native DOM events should not be added, they may have inline handlers.
customEvent: {
@@ -2805,7 +2805,7 @@ jQuery.event = {
event.exclusive = exclusive;
event.namespace = namespaces.join(".");
event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
-
+
// triggerHandler() and global events don't bubble or run the default action
if ( onlyHandlers || !elem ) {
event.preventDefault();
@@ -2896,7 +2896,7 @@ jQuery.event = {
jQuery.event.triggered = undefined;
}
}
-
+
return event.result;
},
@@ -3731,7 +3731,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
return [];
}
-
+
if ( !selector || typeof selector !== "string" ) {
return results;
}
@@ -3741,7 +3741,7 @@ var Sizzle = function( selector, context, results, seed ) {
contextXML = Sizzle.isXML( context ),
parts = [],
soFar = selector;
-
+
// Reset the position of the chunker regexp (start from head)
do {
chunker.exec( "" );
@@ -3749,9 +3749,9 @@ var Sizzle = function( selector, context, results, seed ) {
if ( m ) {
soFar = m[3];
-
+
parts.push( m[1] );
-
+
if ( m[2] ) {
extra = m[3];
break;
@@ -3775,7 +3775,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( Expr.relative[ selector ] ) {
selector += parts.shift();
}
-
+
set = posProcess( selector, set );
}
}
@@ -3904,7 +3904,7 @@ Sizzle.find = function( expr, context, isXML ) {
for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
var match,
type = Expr.order[i];
-
+
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
var left = match[1];
match.splice( 1, 1 );
@@ -4236,7 +4236,7 @@ var Expr = Sizzle.selectors = {
ATTR: function( match, curLoop, inplace, result, not, isXML ) {
var name = match[1] = match[1].replace( rBackslash, "" );
-
+
if ( !isXML && Expr.attrMap[name] ) {
match[1] = Expr.attrMap[name];
}
@@ -4270,7 +4270,7 @@ var Expr = Sizzle.selectors = {
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
return true;
}
-
+
return match;
},
@@ -4280,7 +4280,7 @@ var Expr = Sizzle.selectors = {
return match;
}
},
-
+
filters: {
enabled: function( elem ) {
return elem.disabled === false && elem.type !== "hidden";
@@ -4293,14 +4293,14 @@ var Expr = Sizzle.selectors = {
checked: function( elem ) {
return elem.checked === true;
},
-
+
selected: function( elem ) {
// Accessing this property makes selected-by-default
// options in Safari work properly
if ( elem.parentNode ) {
elem.parentNode.selectedIndex;
}
-
+
return elem.selected === true;
},
@@ -4322,7 +4322,7 @@ var Expr = Sizzle.selectors = {
text: function( elem ) {
var attr = elem.getAttribute( "type" ), type = elem.type;
- // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
// use getAttribute instead to test this case
return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
},
@@ -4438,21 +4438,21 @@ var Expr = Sizzle.selectors = {
case "only":
case "first":
while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
- if ( type === "first" ) {
- return true;
+ if ( type === "first" ) {
+ return true;
}
node = elem;
case "last":
while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
@@ -4465,22 +4465,22 @@ var Expr = Sizzle.selectors = {
if ( first === 1 && last === 0 ) {
return true;
}
-
+
var doneName = match[0],
parent = elem.parentNode;
-
+
if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
var count = 0;
-
+
for ( node = parent.firstChild; node; node = node.nextSibling ) {
if ( node.nodeType === 1 ) {
node.nodeIndex = ++count;
}
- }
+ }
parent.sizcache = doneName;
}
-
+
var diff = elem.nodeIndex - last;
if ( first === 0 ) {
@@ -4499,7 +4499,7 @@ var Expr = Sizzle.selectors = {
TAG: function( elem, match ) {
return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
},
-
+
CLASS: function( elem, match ) {
return (" " + (elem.className || elem.getAttribute("class")) + " ")
.indexOf( match ) > -1;
@@ -4565,7 +4565,7 @@ var makeArray = function( array, results ) {
results.push.apply( results, array );
return results;
}
-
+
return array;
};
@@ -4817,7 +4817,7 @@ if ( document.querySelectorAll ) {
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
return;
}
-
+
Sizzle = function( query, context, extra, seed ) {
context = context || document;
@@ -4826,24 +4826,24 @@ if ( document.querySelectorAll ) {
if ( !seed && !Sizzle.isXML(context) ) {
// See if we find a selector to speed up
var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
-
+
if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
// Speed-up: Sizzle("TAG")
if ( match[1] ) {
return makeArray( context.getElementsByTagName( query ), extra );
-
+
// Speed-up: Sizzle(".CLASS")
} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
return makeArray( context.getElementsByClassName( match[2] ), extra );
}
}
-
+
if ( context.nodeType === 9 ) {
// Speed-up: Sizzle("body")
// The body element only exists once, optimize finding it
if ( query === "body" && context.body ) {
return makeArray( [ context.body ], extra );
-
+
// Speed-up: Sizzle("#ID")
} else if ( match && match[3] ) {
var elem = context.getElementById( match[3] );
@@ -4856,12 +4856,12 @@ if ( document.querySelectorAll ) {
if ( elem.id === match[3] ) {
return makeArray( [ elem ], extra );
}
-
+
} else {
return makeArray( [], extra );
}
}
-
+
try {
return makeArray( context.querySelectorAll(query), extra );
} catch(qsaError) {}
@@ -4899,7 +4899,7 @@ if ( document.querySelectorAll ) {
}
}
}
-
+
return oldSizzle(query, context, extra, seed);
};
@@ -4926,7 +4926,7 @@ if ( document.querySelectorAll ) {
// This should fail with an exception
// Gecko does not error, returns false instead
matches.call( document.documentElement, "[test!='']:sizzle" );
-
+
} catch( pseudoError ) {
pseudoWorks = true;
}
@@ -4936,7 +4936,7 @@ if ( document.querySelectorAll ) {
expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
if ( !Sizzle.isXML( node ) ) {
- try {
+ try {
if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
var ret = matches.call( node, expr );
@@ -4973,7 +4973,7 @@ if ( document.querySelectorAll ) {
if ( div.getElementsByClassName("e").length === 1 ) {
return;
}
-
+
Expr.order.splice(1, 0, "CLASS");
Expr.find.CLASS = function( match, context, isXML ) {
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
@@ -5024,7 +5024,7 @@ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
if ( elem ) {
var match = false;
-
+
elem = elem[dir];
while ( elem ) {
@@ -5077,7 +5077,7 @@ if ( document.documentElement.contains ) {
Sizzle.isXML = function( elem ) {
// documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
+ // (such as loading iframes in IE - #4833)
var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
return documentElement ? documentElement.nodeName !== "HTML" : false;
@@ -5198,7 +5198,7 @@ jQuery.fn.extend({
closest: function( selectors, context ) {
var ret = [], i, l, cur = this[0];
-
+
// Array
if ( jQuery.isArray( selectors ) ) {
var match, selector,
diff --git a/tests/jquery-1.6.2.js b/tests/jquery-1.6.2.js
index f3201aacb..fc5a1d74d 100644
--- a/tests/jquery-1.6.2.js
+++ b/tests/jquery-1.6.2.js
@@ -1511,7 +1511,7 @@ jQuery.extend({
return thisCache[ internalKey ] && thisCache[ internalKey ].events;
}
- return getByName ?
+ return getByName ?
// Check for both converted-to-camel and non-converted data property names
thisCache[ jQuery.camelCase( name ) ] || thisCache[ name ] :
thisCache;
@@ -1923,11 +1923,11 @@ jQuery.fn.extend({
jQuery.removeAttr( this, name );
});
},
-
+
prop: function( name, value ) {
return jQuery.access( this, name, value, true, jQuery.prop );
},
-
+
removeProp: function( name ) {
name = jQuery.propFix[ name ] || name;
return this.each(function() {
@@ -2060,7 +2060,7 @@ jQuery.fn.extend({
val: function( value ) {
var hooks, ret,
elem = this[0];
-
+
if ( !arguments.length ) {
if ( elem ) {
hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
@@ -2071,9 +2071,9 @@ jQuery.fn.extend({
ret = elem.value;
- return typeof ret === "string" ?
+ return typeof ret === "string" ?
// handle most common string cases
- ret.replace(rreturn, "") :
+ ret.replace(rreturn, "") :
// handle cases where value is null/undef or number
ret == null ? "" : ret;
}
@@ -2194,15 +2194,15 @@ jQuery.extend({
height: true,
offset: true
},
-
+
attrFix: {
// Always normalize to ensure hook usage
tabindex: "tabIndex"
},
-
+
attr: function( elem, name, value, pass ) {
var nType = elem.nodeType;
-
+
// don't get/set attributes on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return undefined;
@@ -2273,7 +2273,7 @@ jQuery.extend({
var propName;
if ( elem.nodeType === 1 ) {
name = jQuery.attrFix[ name ] || name;
-
+
if ( jQuery.support.getSetAttribute ) {
// Use removeAttribute in browsers that support it
elem.removeAttribute( name );
@@ -2356,7 +2356,7 @@ jQuery.extend({
frameborder: "frameBorder",
contenteditable: "contentEditable"
},
-
+
prop: function( elem, name, value ) {
var nType = elem.nodeType;
@@ -2391,7 +2391,7 @@ jQuery.extend({
}
}
},
-
+
propHooks: {}
});
@@ -2428,7 +2428,7 @@ if ( !jQuery.support.getSetAttribute ) {
// propFix is more comprehensive and contains all fixes
jQuery.attrFix = jQuery.propFix;
-
+
// Use this for any attribute on a form in IE6/7
formHook = jQuery.attrHooks.name = jQuery.attrHooks.title = jQuery.valHooks.button = {
get: function( elem, name ) {
@@ -2798,7 +2798,7 @@ jQuery.event = {
}
}
},
-
+
// Events that are safe to short-circuit if no handlers are attached.
// Native DOM events should not be added, they may have inline handlers.
customEvent: {
@@ -2844,7 +2844,7 @@ jQuery.event = {
event.exclusive = exclusive;
event.namespace = namespaces.join(".");
event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
-
+
// triggerHandler() and global events don't bubble or run the default action
if ( onlyHandlers || !elem ) {
event.preventDefault();
@@ -2935,7 +2935,7 @@ jQuery.event = {
jQuery.event.triggered = undefined;
}
}
-
+
return event.result;
},
@@ -3763,7 +3763,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
return [];
}
-
+
if ( !selector || typeof selector !== "string" ) {
return results;
}
@@ -3773,7 +3773,7 @@ var Sizzle = function( selector, context, results, seed ) {
contextXML = Sizzle.isXML( context ),
parts = [],
soFar = selector;
-
+
// Reset the position of the chunker regexp (start from head)
do {
chunker.exec( "" );
@@ -3781,9 +3781,9 @@ var Sizzle = function( selector, context, results, seed ) {
if ( m ) {
soFar = m[3];
-
+
parts.push( m[1] );
-
+
if ( m[2] ) {
extra = m[3];
break;
@@ -3807,7 +3807,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( Expr.relative[ selector ] ) {
selector += parts.shift();
}
-
+
set = posProcess( selector, set );
}
}
@@ -3936,7 +3936,7 @@ Sizzle.find = function( expr, context, isXML ) {
for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
var match,
type = Expr.order[i];
-
+
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
var left = match[1];
match.splice( 1, 1 );
@@ -4268,7 +4268,7 @@ var Expr = Sizzle.selectors = {
ATTR: function( match, curLoop, inplace, result, not, isXML ) {
var name = match[1] = match[1].replace( rBackslash, "" );
-
+
if ( !isXML && Expr.attrMap[name] ) {
match[1] = Expr.attrMap[name];
}
@@ -4302,7 +4302,7 @@ var Expr = Sizzle.selectors = {
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
return true;
}
-
+
return match;
},
@@ -4312,7 +4312,7 @@ var Expr = Sizzle.selectors = {
return match;
}
},
-
+
filters: {
enabled: function( elem ) {
return elem.disabled === false && elem.type !== "hidden";
@@ -4325,14 +4325,14 @@ var Expr = Sizzle.selectors = {
checked: function( elem ) {
return elem.checked === true;
},
-
+
selected: function( elem ) {
// Accessing this property makes selected-by-default
// options in Safari work properly
if ( elem.parentNode ) {
elem.parentNode.selectedIndex;
}
-
+
return elem.selected === true;
},
@@ -4354,7 +4354,7 @@ var Expr = Sizzle.selectors = {
text: function( elem ) {
var attr = elem.getAttribute( "type" ), type = elem.type;
- // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
// use getAttribute instead to test this case
return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
},
@@ -4470,21 +4470,21 @@ var Expr = Sizzle.selectors = {
case "only":
case "first":
while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
- if ( type === "first" ) {
- return true;
+ if ( type === "first" ) {
+ return true;
}
node = elem;
case "last":
while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
@@ -4497,22 +4497,22 @@ var Expr = Sizzle.selectors = {
if ( first === 1 && last === 0 ) {
return true;
}
-
+
var doneName = match[0],
parent = elem.parentNode;
-
+
if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
var count = 0;
-
+
for ( node = parent.firstChild; node; node = node.nextSibling ) {
if ( node.nodeType === 1 ) {
node.nodeIndex = ++count;
}
- }
+ }
parent.sizcache = doneName;
}
-
+
var diff = elem.nodeIndex - last;
if ( first === 0 ) {
@@ -4531,7 +4531,7 @@ var Expr = Sizzle.selectors = {
TAG: function( elem, match ) {
return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
},
-
+
CLASS: function( elem, match ) {
return (" " + (elem.className || elem.getAttribute("class")) + " ")
.indexOf( match ) > -1;
@@ -4597,7 +4597,7 @@ var makeArray = function( array, results ) {
results.push.apply( results, array );
return results;
}
-
+
return array;
};
@@ -4849,7 +4849,7 @@ if ( document.querySelectorAll ) {
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
return;
}
-
+
Sizzle = function( query, context, extra, seed ) {
context = context || document;
@@ -4858,24 +4858,24 @@ if ( document.querySelectorAll ) {
if ( !seed && !Sizzle.isXML(context) ) {
// See if we find a selector to speed up
var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
-
+
if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
// Speed-up: Sizzle("TAG")
if ( match[1] ) {
return makeArray( context.getElementsByTagName( query ), extra );
-
+
// Speed-up: Sizzle(".CLASS")
} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
return makeArray( context.getElementsByClassName( match[2] ), extra );
}
}
-
+
if ( context.nodeType === 9 ) {
// Speed-up: Sizzle("body")
// The body element only exists once, optimize finding it
if ( query === "body" && context.body ) {
return makeArray( [ context.body ], extra );
-
+
// Speed-up: Sizzle("#ID")
} else if ( match && match[3] ) {
var elem = context.getElementById( match[3] );
@@ -4888,12 +4888,12 @@ if ( document.querySelectorAll ) {
if ( elem.id === match[3] ) {
return makeArray( [ elem ], extra );
}
-
+
} else {
return makeArray( [], extra );
}
}
-
+
try {
return makeArray( context.querySelectorAll(query), extra );
} catch(qsaError) {}
@@ -4931,7 +4931,7 @@ if ( document.querySelectorAll ) {
}
}
}
-
+
return oldSizzle(query, context, extra, seed);
};
@@ -4958,7 +4958,7 @@ if ( document.querySelectorAll ) {
// This should fail with an exception
// Gecko does not error, returns false instead
matches.call( document.documentElement, "[test!='']:sizzle" );
-
+
} catch( pseudoError ) {
pseudoWorks = true;
}
@@ -4968,7 +4968,7 @@ if ( document.querySelectorAll ) {
expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
if ( !Sizzle.isXML( node ) ) {
- try {
+ try {
if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
var ret = matches.call( node, expr );
@@ -5005,7 +5005,7 @@ if ( document.querySelectorAll ) {
if ( div.getElementsByClassName("e").length === 1 ) {
return;
}
-
+
Expr.order.splice(1, 0, "CLASS");
Expr.find.CLASS = function( match, context, isXML ) {
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
@@ -5056,7 +5056,7 @@ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
if ( elem ) {
var match = false;
-
+
elem = elem[dir];
while ( elem ) {
@@ -5109,7 +5109,7 @@ if ( document.documentElement.contains ) {
Sizzle.isXML = function( elem ) {
// documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
+ // (such as loading iframes in IE - #4833)
var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
return documentElement ? documentElement.nodeName !== "HTML" : false;
@@ -5230,7 +5230,7 @@ jQuery.fn.extend({
closest: function( selectors, context ) {
var ret = [], i, l, cur = this[0];
-
+
// Array
if ( jQuery.isArray( selectors ) ) {
var match, selector,
diff --git a/tests/jquery-1.6.3.js b/tests/jquery-1.6.3.js
index 792e62f49..f69fd06b0 100644
--- a/tests/jquery-1.6.3.js
+++ b/tests/jquery-1.6.3.js
@@ -1961,11 +1961,11 @@ jQuery.fn.extend({
jQuery.removeAttr( this, name );
});
},
-
+
prop: function( name, value ) {
return jQuery.access( this, name, value, true, jQuery.prop );
},
-
+
removeProp: function( name ) {
name = jQuery.propFix[ name ] || name;
return this.each(function() {
@@ -2098,7 +2098,7 @@ jQuery.fn.extend({
val: function( value ) {
var hooks, ret,
elem = this[0];
-
+
if ( !arguments.length ) {
if ( elem ) {
hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
@@ -2109,9 +2109,9 @@ jQuery.fn.extend({
ret = elem.value;
- return typeof ret === "string" ?
+ return typeof ret === "string" ?
// handle most common string cases
- ret.replace(rreturn, "") :
+ ret.replace(rreturn, "") :
// handle cases where value is null/undef or number
ret == null ? "" : ret;
}
@@ -2232,15 +2232,15 @@ jQuery.extend({
height: true,
offset: true
},
-
+
attrFix: {
// Always normalize to ensure hook usage
tabindex: "tabIndex"
},
-
+
attr: function( elem, name, value, pass ) {
var nType = elem.nodeType;
-
+
// don't get/set attributes on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return undefined;
@@ -2373,7 +2373,7 @@ jQuery.extend({
frameborder: "frameBorder",
contenteditable: "contentEditable"
},
-
+
prop: function( elem, name, value ) {
var nType = elem.nodeType;
@@ -2408,7 +2408,7 @@ jQuery.extend({
}
}
},
-
+
propHooks: {
tabIndex: {
get: function( elem ) {
@@ -2461,7 +2461,7 @@ boolHook = {
// IE6/7 do not support getting/setting some attributes with get/setAttribute
if ( !jQuery.support.getSetAttribute ) {
-
+
// Use this for any attribute in IE6/7
// This fixes almost every IE6/7 issue
nodeHook = jQuery.valHooks.button = {
@@ -2833,7 +2833,7 @@ jQuery.event = {
}
}
},
-
+
// Events that are safe to short-circuit if no handlers are attached.
// Native DOM events should not be added, they may have inline handlers.
customEvent: {
@@ -2879,7 +2879,7 @@ jQuery.event = {
event.exclusive = exclusive;
event.namespace = namespaces.join(".");
event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
-
+
// triggerHandler() and global events don't bubble or run the default action
if ( onlyHandlers || !elem ) {
event.preventDefault();
@@ -2970,7 +2970,7 @@ jQuery.event = {
jQuery.event.triggered = undefined;
}
}
-
+
return event.result;
},
@@ -3799,7 +3799,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
return [];
}
-
+
if ( !selector || typeof selector !== "string" ) {
return results;
}
@@ -3809,7 +3809,7 @@ var Sizzle = function( selector, context, results, seed ) {
contextXML = Sizzle.isXML( context ),
parts = [],
soFar = selector;
-
+
// Reset the position of the chunker regexp (start from head)
do {
chunker.exec( "" );
@@ -3817,9 +3817,9 @@ var Sizzle = function( selector, context, results, seed ) {
if ( m ) {
soFar = m[3];
-
+
parts.push( m[1] );
-
+
if ( m[2] ) {
extra = m[3];
break;
@@ -3843,7 +3843,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( Expr.relative[ selector ] ) {
selector += parts.shift();
}
-
+
set = posProcess( selector, set );
}
}
@@ -3972,7 +3972,7 @@ Sizzle.find = function( expr, context, isXML ) {
for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
var match,
type = Expr.order[i];
-
+
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
var left = match[1];
match.splice( 1, 1 );
@@ -4304,7 +4304,7 @@ var Expr = Sizzle.selectors = {
ATTR: function( match, curLoop, inplace, result, not, isXML ) {
var name = match[1] = match[1].replace( rBackslash, "" );
-
+
if ( !isXML && Expr.attrMap[name] ) {
match[1] = Expr.attrMap[name];
}
@@ -4338,7 +4338,7 @@ var Expr = Sizzle.selectors = {
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
return true;
}
-
+
return match;
},
@@ -4348,7 +4348,7 @@ var Expr = Sizzle.selectors = {
return match;
}
},
-
+
filters: {
enabled: function( elem ) {
return elem.disabled === false && elem.type !== "hidden";
@@ -4361,14 +4361,14 @@ var Expr = Sizzle.selectors = {
checked: function( elem ) {
return elem.checked === true;
},
-
+
selected: function( elem ) {
// Accessing this property makes selected-by-default
// options in Safari work properly
if ( elem.parentNode ) {
elem.parentNode.selectedIndex;
}
-
+
return elem.selected === true;
},
@@ -4390,7 +4390,7 @@ var Expr = Sizzle.selectors = {
text: function( elem ) {
var attr = elem.getAttribute( "type" ), type = elem.type;
- // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
// use getAttribute instead to test this case
return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
},
@@ -4506,21 +4506,21 @@ var Expr = Sizzle.selectors = {
case "only":
case "first":
while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
- if ( type === "first" ) {
- return true;
+ if ( type === "first" ) {
+ return true;
}
node = elem;
case "last":
while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
@@ -4533,22 +4533,22 @@ var Expr = Sizzle.selectors = {
if ( first === 1 && last === 0 ) {
return true;
}
-
+
var doneName = match[0],
parent = elem.parentNode;
-
+
if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
var count = 0;
-
+
for ( node = parent.firstChild; node; node = node.nextSibling ) {
if ( node.nodeType === 1 ) {
node.nodeIndex = ++count;
}
- }
+ }
parent.sizcache = doneName;
}
-
+
var diff = elem.nodeIndex - last;
if ( first === 0 ) {
@@ -4567,7 +4567,7 @@ var Expr = Sizzle.selectors = {
TAG: function( elem, match ) {
return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
},
-
+
CLASS: function( elem, match ) {
return (" " + (elem.className || elem.getAttribute("class")) + " ")
.indexOf( match ) > -1;
@@ -4633,7 +4633,7 @@ var makeArray = function( array, results ) {
results.push.apply( results, array );
return results;
}
-
+
return array;
};
@@ -4885,7 +4885,7 @@ if ( document.querySelectorAll ) {
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
return;
}
-
+
Sizzle = function( query, context, extra, seed ) {
context = context || document;
@@ -4894,24 +4894,24 @@ if ( document.querySelectorAll ) {
if ( !seed && !Sizzle.isXML(context) ) {
// See if we find a selector to speed up
var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
-
+
if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
// Speed-up: Sizzle("TAG")
if ( match[1] ) {
return makeArray( context.getElementsByTagName( query ), extra );
-
+
// Speed-up: Sizzle(".CLASS")
} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
return makeArray( context.getElementsByClassName( match[2] ), extra );
}
}
-
+
if ( context.nodeType === 9 ) {
// Speed-up: Sizzle("body")
// The body element only exists once, optimize finding it
if ( query === "body" && context.body ) {
return makeArray( [ context.body ], extra );
-
+
// Speed-up: Sizzle("#ID")
} else if ( match && match[3] ) {
var elem = context.getElementById( match[3] );
@@ -4924,12 +4924,12 @@ if ( document.querySelectorAll ) {
if ( elem.id === match[3] ) {
return makeArray( [ elem ], extra );
}
-
+
} else {
return makeArray( [], extra );
}
}
-
+
try {
return makeArray( context.querySelectorAll(query), extra );
} catch(qsaError) {}
@@ -4967,7 +4967,7 @@ if ( document.querySelectorAll ) {
}
}
}
-
+
return oldSizzle(query, context, extra, seed);
};
@@ -4994,7 +4994,7 @@ if ( document.querySelectorAll ) {
// This should fail with an exception
// Gecko does not error, returns false instead
matches.call( document.documentElement, "[test!='']:sizzle" );
-
+
} catch( pseudoError ) {
pseudoWorks = true;
}
@@ -5004,7 +5004,7 @@ if ( document.querySelectorAll ) {
expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
if ( !Sizzle.isXML( node ) ) {
- try {
+ try {
if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
var ret = matches.call( node, expr );
@@ -5041,7 +5041,7 @@ if ( document.querySelectorAll ) {
if ( div.getElementsByClassName("e").length === 1 ) {
return;
}
-
+
Expr.order.splice(1, 0, "CLASS");
Expr.find.CLASS = function( match, context, isXML ) {
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
@@ -5092,7 +5092,7 @@ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
if ( elem ) {
var match = false;
-
+
elem = elem[dir];
while ( elem ) {
@@ -5145,7 +5145,7 @@ if ( document.documentElement.contains ) {
Sizzle.isXML = function( elem ) {
// documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
+ // (such as loading iframes in IE - #4833)
var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
return documentElement ? documentElement.nodeName !== "HTML" : false;
@@ -5266,7 +5266,7 @@ jQuery.fn.extend({
closest: function( selectors, context ) {
var ret = [], i, l, cur = this[0];
-
+
// Array
if ( jQuery.isArray( selectors ) ) {
var match, selector,
@@ -6718,7 +6718,7 @@ var r20 = /%20/g,
// Document location segments
ajaxLocParts,
-
+
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
allTypes = ["*/"] + ["*"];
diff --git a/tests/jquery-1.6.4.js b/tests/jquery-1.6.4.js
index 11e6d0679..5ccaf5b8e 100644
--- a/tests/jquery-1.6.4.js
+++ b/tests/jquery-1.6.4.js
@@ -1962,11 +1962,11 @@ jQuery.fn.extend({
jQuery.removeAttr( this, name );
});
},
-
+
prop: function( name, value ) {
return jQuery.access( this, name, value, true, jQuery.prop );
},
-
+
removeProp: function( name ) {
name = jQuery.propFix[ name ] || name;
return this.each(function() {
@@ -2099,7 +2099,7 @@ jQuery.fn.extend({
val: function( value ) {
var hooks, ret,
elem = this[0];
-
+
if ( !arguments.length ) {
if ( elem ) {
hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
@@ -2110,9 +2110,9 @@ jQuery.fn.extend({
ret = elem.value;
- return typeof ret === "string" ?
+ return typeof ret === "string" ?
// handle most common string cases
- ret.replace(rreturn, "") :
+ ret.replace(rreturn, "") :
// handle cases where value is null/undef or number
ret == null ? "" : ret;
}
@@ -2233,15 +2233,15 @@ jQuery.extend({
height: true,
offset: true
},
-
+
attrFix: {
// Always normalize to ensure hook usage
tabindex: "tabIndex"
},
-
+
attr: function( elem, name, value, pass ) {
var nType = elem.nodeType;
-
+
// don't get/set attributes on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return undefined;
@@ -2374,7 +2374,7 @@ jQuery.extend({
frameborder: "frameBorder",
contenteditable: "contentEditable"
},
-
+
prop: function( elem, name, value ) {
var nType = elem.nodeType;
@@ -2409,7 +2409,7 @@ jQuery.extend({
}
}
},
-
+
propHooks: {
tabIndex: {
get: function( elem ) {
@@ -2462,7 +2462,7 @@ boolHook = {
// IE6/7 do not support getting/setting some attributes with get/setAttribute
if ( !jQuery.support.getSetAttribute ) {
-
+
// Use this for any attribute in IE6/7
// This fixes almost every IE6/7 issue
nodeHook = jQuery.valHooks.button = {
@@ -2834,7 +2834,7 @@ jQuery.event = {
}
}
},
-
+
// Events that are safe to short-circuit if no handlers are attached.
// Native DOM events should not be added, they may have inline handlers.
customEvent: {
@@ -2880,7 +2880,7 @@ jQuery.event = {
event.exclusive = exclusive;
event.namespace = namespaces.join(".");
event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
-
+
// triggerHandler() and global events don't bubble or run the default action
if ( onlyHandlers || !elem ) {
event.preventDefault();
@@ -2971,7 +2971,7 @@ jQuery.event = {
jQuery.event.triggered = undefined;
}
}
-
+
return event.result;
},
@@ -3801,7 +3801,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
return [];
}
-
+
if ( !selector || typeof selector !== "string" ) {
return results;
}
@@ -3811,7 +3811,7 @@ var Sizzle = function( selector, context, results, seed ) {
contextXML = Sizzle.isXML( context ),
parts = [],
soFar = selector;
-
+
// Reset the position of the chunker regexp (start from head)
do {
chunker.exec( "" );
@@ -3819,9 +3819,9 @@ var Sizzle = function( selector, context, results, seed ) {
if ( m ) {
soFar = m[3];
-
+
parts.push( m[1] );
-
+
if ( m[2] ) {
extra = m[3];
break;
@@ -3845,7 +3845,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( Expr.relative[ selector ] ) {
selector += parts.shift();
}
-
+
set = posProcess( selector, set );
}
}
@@ -3974,7 +3974,7 @@ Sizzle.find = function( expr, context, isXML ) {
for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
var match,
type = Expr.order[i];
-
+
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
var left = match[1];
match.splice( 1, 1 );
@@ -4306,7 +4306,7 @@ var Expr = Sizzle.selectors = {
ATTR: function( match, curLoop, inplace, result, not, isXML ) {
var name = match[1] = match[1].replace( rBackslash, "" );
-
+
if ( !isXML && Expr.attrMap[name] ) {
match[1] = Expr.attrMap[name];
}
@@ -4340,7 +4340,7 @@ var Expr = Sizzle.selectors = {
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
return true;
}
-
+
return match;
},
@@ -4350,7 +4350,7 @@ var Expr = Sizzle.selectors = {
return match;
}
},
-
+
filters: {
enabled: function( elem ) {
return elem.disabled === false && elem.type !== "hidden";
@@ -4363,14 +4363,14 @@ var Expr = Sizzle.selectors = {
checked: function( elem ) {
return elem.checked === true;
},
-
+
selected: function( elem ) {
// Accessing this property makes selected-by-default
// options in Safari work properly
if ( elem.parentNode ) {
elem.parentNode.selectedIndex;
}
-
+
return elem.selected === true;
},
@@ -4392,7 +4392,7 @@ var Expr = Sizzle.selectors = {
text: function( elem ) {
var attr = elem.getAttribute( "type" ), type = elem.type;
- // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
// use getAttribute instead to test this case
return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
},
@@ -4508,21 +4508,21 @@ var Expr = Sizzle.selectors = {
case "only":
case "first":
while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
- if ( type === "first" ) {
- return true;
+ if ( type === "first" ) {
+ return true;
}
node = elem;
case "last":
while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
@@ -4535,22 +4535,22 @@ var Expr = Sizzle.selectors = {
if ( first === 1 && last === 0 ) {
return true;
}
-
+
var doneName = match[0],
parent = elem.parentNode;
-
+
if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
var count = 0;
-
+
for ( node = parent.firstChild; node; node = node.nextSibling ) {
if ( node.nodeType === 1 ) {
node.nodeIndex = ++count;
}
- }
+ }
parent.sizcache = doneName;
}
-
+
var diff = elem.nodeIndex - last;
if ( first === 0 ) {
@@ -4569,7 +4569,7 @@ var Expr = Sizzle.selectors = {
TAG: function( elem, match ) {
return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
},
-
+
CLASS: function( elem, match ) {
return (" " + (elem.className || elem.getAttribute("class")) + " ")
.indexOf( match ) > -1;
@@ -4635,7 +4635,7 @@ var makeArray = function( array, results ) {
results.push.apply( results, array );
return results;
}
-
+
return array;
};
@@ -4887,7 +4887,7 @@ if ( document.querySelectorAll ) {
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
return;
}
-
+
Sizzle = function( query, context, extra, seed ) {
context = context || document;
@@ -4896,24 +4896,24 @@ if ( document.querySelectorAll ) {
if ( !seed && !Sizzle.isXML(context) ) {
// See if we find a selector to speed up
var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
-
+
if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
// Speed-up: Sizzle("TAG")
if ( match[1] ) {
return makeArray( context.getElementsByTagName( query ), extra );
-
+
// Speed-up: Sizzle(".CLASS")
} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
return makeArray( context.getElementsByClassName( match[2] ), extra );
}
}
-
+
if ( context.nodeType === 9 ) {
// Speed-up: Sizzle("body")
// The body element only exists once, optimize finding it
if ( query === "body" && context.body ) {
return makeArray( [ context.body ], extra );
-
+
// Speed-up: Sizzle("#ID")
} else if ( match && match[3] ) {
var elem = context.getElementById( match[3] );
@@ -4926,12 +4926,12 @@ if ( document.querySelectorAll ) {
if ( elem.id === match[3] ) {
return makeArray( [ elem ], extra );
}
-
+
} else {
return makeArray( [], extra );
}
}
-
+
try {
return makeArray( context.querySelectorAll(query), extra );
} catch(qsaError) {}
@@ -4969,7 +4969,7 @@ if ( document.querySelectorAll ) {
}
}
}
-
+
return oldSizzle(query, context, extra, seed);
};
@@ -4996,7 +4996,7 @@ if ( document.querySelectorAll ) {
// This should fail with an exception
// Gecko does not error, returns false instead
matches.call( document.documentElement, "[test!='']:sizzle" );
-
+
} catch( pseudoError ) {
pseudoWorks = true;
}
@@ -5006,7 +5006,7 @@ if ( document.querySelectorAll ) {
expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
if ( !Sizzle.isXML( node ) ) {
- try {
+ try {
if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
var ret = matches.call( node, expr );
@@ -5043,7 +5043,7 @@ if ( document.querySelectorAll ) {
if ( div.getElementsByClassName("e").length === 1 ) {
return;
}
-
+
Expr.order.splice(1, 0, "CLASS");
Expr.find.CLASS = function( match, context, isXML ) {
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
@@ -5094,7 +5094,7 @@ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
if ( elem ) {
var match = false;
-
+
elem = elem[dir];
while ( elem ) {
@@ -5147,7 +5147,7 @@ if ( document.documentElement.contains ) {
Sizzle.isXML = function( elem ) {
// documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
+ // (such as loading iframes in IE - #4833)
var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
return documentElement ? documentElement.nodeName !== "HTML" : false;
@@ -5268,7 +5268,7 @@ jQuery.fn.extend({
closest: function( selectors, context ) {
var ret = [], i, l, cur = this[0];
-
+
// Array
if ( jQuery.isArray( selectors ) ) {
var match, selector,
@@ -6720,7 +6720,7 @@ var r20 = /%20/g,
// Document location segments
ajaxLocParts,
-
+
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
allTypes = ["*/"] + ["*"];
diff --git a/tests/jquery-1.6.js b/tests/jquery-1.6.js
index 9a13ab960..61091a7e7 100644
--- a/tests/jquery-1.6.js
+++ b/tests/jquery-1.6.js
@@ -1893,11 +1893,11 @@ jQuery.fn.extend({
jQuery.removeAttr( this, name );
});
},
-
+
prop: function( name, value ) {
return jQuery.access( this, name, value, true, jQuery.prop );
},
-
+
removeProp: function( name ) {
return this.each(function() {
// try/catch handles cases where IE balks (such as removing a property on window)
@@ -2028,7 +2028,7 @@ jQuery.fn.extend({
val: function( value ) {
var hooks, ret,
elem = this[0];
-
+
if ( !arguments.length ) {
if ( elem ) {
hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
@@ -2155,16 +2155,16 @@ jQuery.extend({
height: true,
offset: true
},
-
+
attrFix: {
// Always normalize to ensure hook usage
tabindex: "tabIndex",
readonly: "readOnly"
},
-
+
attr: function( elem, name, value, pass ) {
var nType = elem.nodeType;
-
+
// don't get/set attributes on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return undefined;
@@ -2173,10 +2173,10 @@ jQuery.extend({
if ( pass && name in jQuery.attrFn ) {
return jQuery( elem )[ name ]( value );
}
-
+
var ret, hooks,
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
-
+
// Normalize the name if needed
name = notxml && jQuery.attrFix[ name ] || name;
@@ -2223,11 +2223,11 @@ jQuery.extend({
}
}
},
-
+
removeAttr: function( elem, name ) {
if ( elem.nodeType === 1 ) {
name = jQuery.attrFix[ name ] || name;
-
+
if ( jQuery.support.getSetAttribute ) {
// Use removeAttribute in browsers that support it
elem.removeAttribute( name );
@@ -2271,43 +2271,43 @@ jQuery.extend({
}
}
},
-
+
propFix: {},
-
+
prop: function( elem, name, value ) {
var nType = elem.nodeType;
-
+
// don't get/set properties on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return undefined;
}
-
+
var ret, hooks,
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
-
+
// Try to normalize/fix the name
name = notxml && jQuery.propFix[ name ] || name;
-
+
hooks = jQuery.propHooks[ name ];
-
+
if ( value !== undefined ) {
if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
return ret;
-
+
} else {
return (elem[ name ] = value);
}
-
+
} else {
if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
return ret;
-
+
} else {
return elem[ name ];
}
}
},
-
+
propHooks: {}
});
@@ -2324,7 +2324,7 @@ if ( !jQuery.support.getSetAttribute ) {
usemap: "useMap",
frameborder: "frameBorder"
});
-
+
// Use this for any attribute on a form in IE6/7
formHook = jQuery.attrHooks.name = jQuery.attrHooks.value = jQuery.valHooks.button = {
get: function( elem, name ) {
@@ -2698,7 +2698,7 @@ jQuery.event = {
}
}
},
-
+
// Events that are safe to short-circuit if no handlers are attached.
// Native DOM events should not be added, they may have inline handlers.
customEvent: {
@@ -2744,7 +2744,7 @@ jQuery.event = {
event.exclusive = exclusive;
event.namespace = namespaces.join(".");
event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
-
+
// triggerHandler() and global events don't bubble or run the default action
if ( onlyHandlers || !elem ) {
event.preventDefault();
@@ -2835,7 +2835,7 @@ jQuery.event = {
jQuery.event.triggered = undefined;
}
}
-
+
return event.result;
},
@@ -3669,7 +3669,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
return [];
}
-
+
if ( !selector || typeof selector !== "string" ) {
return results;
}
@@ -3679,7 +3679,7 @@ var Sizzle = function( selector, context, results, seed ) {
contextXML = Sizzle.isXML( context ),
parts = [],
soFar = selector;
-
+
// Reset the position of the chunker regexp (start from head)
do {
chunker.exec( "" );
@@ -3687,9 +3687,9 @@ var Sizzle = function( selector, context, results, seed ) {
if ( m ) {
soFar = m[3];
-
+
parts.push( m[1] );
-
+
if ( m[2] ) {
extra = m[3];
break;
@@ -3713,7 +3713,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( Expr.relative[ selector ] ) {
selector += parts.shift();
}
-
+
set = posProcess( selector, set );
}
}
@@ -3842,7 +3842,7 @@ Sizzle.find = function( expr, context, isXML ) {
for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
var match,
type = Expr.order[i];
-
+
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
var left = match[1];
match.splice( 1, 1 );
@@ -4174,7 +4174,7 @@ var Expr = Sizzle.selectors = {
ATTR: function( match, curLoop, inplace, result, not, isXML ) {
var name = match[1] = match[1].replace( rBackslash, "" );
-
+
if ( !isXML && Expr.attrMap[name] ) {
match[1] = Expr.attrMap[name];
}
@@ -4208,7 +4208,7 @@ var Expr = Sizzle.selectors = {
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
return true;
}
-
+
return match;
},
@@ -4218,7 +4218,7 @@ var Expr = Sizzle.selectors = {
return match;
}
},
-
+
filters: {
enabled: function( elem ) {
return elem.disabled === false && elem.type !== "hidden";
@@ -4231,14 +4231,14 @@ var Expr = Sizzle.selectors = {
checked: function( elem ) {
return elem.checked === true;
},
-
+
selected: function( elem ) {
// Accessing this property makes selected-by-default
// options in Safari work properly
if ( elem.parentNode ) {
elem.parentNode.selectedIndex;
}
-
+
return elem.selected === true;
},
@@ -4260,7 +4260,7 @@ var Expr = Sizzle.selectors = {
text: function( elem ) {
var attr = elem.getAttribute( "type" ), type = elem.type;
- // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
// use getAttribute instead to test this case
return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
},
@@ -4375,21 +4375,21 @@ var Expr = Sizzle.selectors = {
case "only":
case "first":
while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
- if ( type === "first" ) {
- return true;
+ if ( type === "first" ) {
+ return true;
}
node = elem;
case "last":
while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
@@ -4402,22 +4402,22 @@ var Expr = Sizzle.selectors = {
if ( first === 1 && last === 0 ) {
return true;
}
-
+
var doneName = match[0],
parent = elem.parentNode;
-
+
if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
var count = 0;
-
+
for ( node = parent.firstChild; node; node = node.nextSibling ) {
if ( node.nodeType === 1 ) {
node.nodeIndex = ++count;
}
- }
+ }
parent.sizcache = doneName;
}
-
+
var diff = elem.nodeIndex - last;
if ( first === 0 ) {
@@ -4436,7 +4436,7 @@ var Expr = Sizzle.selectors = {
TAG: function( elem, match ) {
return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
},
-
+
CLASS: function( elem, match ) {
return (" " + (elem.className || elem.getAttribute("class")) + " ")
.indexOf( match ) > -1;
@@ -4502,7 +4502,7 @@ var makeArray = function( array, results ) {
results.push.apply( results, array );
return results;
}
-
+
return array;
};
@@ -4749,7 +4749,7 @@ if ( document.querySelectorAll ) {
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
return;
}
-
+
Sizzle = function( query, context, extra, seed ) {
context = context || document;
@@ -4758,24 +4758,24 @@ if ( document.querySelectorAll ) {
if ( !seed && !Sizzle.isXML(context) ) {
// See if we find a selector to speed up
var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
-
+
if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
// Speed-up: Sizzle("TAG")
if ( match[1] ) {
return makeArray( context.getElementsByTagName( query ), extra );
-
+
// Speed-up: Sizzle(".CLASS")
} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
return makeArray( context.getElementsByClassName( match[2] ), extra );
}
}
-
+
if ( context.nodeType === 9 ) {
// Speed-up: Sizzle("body")
// The body element only exists once, optimize finding it
if ( query === "body" && context.body ) {
return makeArray( [ context.body ], extra );
-
+
// Speed-up: Sizzle("#ID")
} else if ( match && match[3] ) {
var elem = context.getElementById( match[3] );
@@ -4788,12 +4788,12 @@ if ( document.querySelectorAll ) {
if ( elem.id === match[3] ) {
return makeArray( [ elem ], extra );
}
-
+
} else {
return makeArray( [], extra );
}
}
-
+
try {
return makeArray( context.querySelectorAll(query), extra );
} catch(qsaError) {}
@@ -4831,7 +4831,7 @@ if ( document.querySelectorAll ) {
}
}
}
-
+
return oldSizzle(query, context, extra, seed);
};
@@ -4858,7 +4858,7 @@ if ( document.querySelectorAll ) {
// This should fail with an exception
// Gecko does not error, returns false instead
matches.call( document.documentElement, "[test!='']:sizzle" );
-
+
} catch( pseudoError ) {
pseudoWorks = true;
}
@@ -4868,7 +4868,7 @@ if ( document.querySelectorAll ) {
expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
if ( !Sizzle.isXML( node ) ) {
- try {
+ try {
if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
var ret = matches.call( node, expr );
@@ -4905,7 +4905,7 @@ if ( document.querySelectorAll ) {
if ( div.getElementsByClassName("e").length === 1 ) {
return;
}
-
+
Expr.order.splice(1, 0, "CLASS");
Expr.find.CLASS = function( match, context, isXML ) {
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
@@ -4956,7 +4956,7 @@ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
if ( elem ) {
var match = false;
-
+
elem = elem[dir];
while ( elem ) {
@@ -5009,7 +5009,7 @@ if ( document.documentElement.contains ) {
Sizzle.isXML = function( elem ) {
// documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
+ // (such as loading iframes in IE - #4833)
var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
return documentElement ? documentElement.nodeName !== "HTML" : false;
@@ -5130,7 +5130,7 @@ jQuery.fn.extend({
closest: function( selectors, context ) {
var ret = [], i, l, cur = this[0];
-
+
// Array
if ( jQuery.isArray( selectors ) ) {
var match, selector,
@@ -5884,7 +5884,7 @@ jQuery.each({
function getAll( elem ) {
if ( "getElementsByTagName" in elem ) {
return elem.getElementsByTagName( "*" );
-
+
} else if ( "querySelectorAll" in elem ) {
return elem.querySelectorAll( "*" );
diff --git a/tests/jquery-1.7.1.js b/tests/jquery-1.7.1.js
index 8ccd0ea78..c8e7d7a01 100644
--- a/tests/jquery-1.7.1.js
+++ b/tests/jquery-1.7.1.js
@@ -3885,7 +3885,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
return [];
}
-
+
if ( !selector || typeof selector !== "string" ) {
return results;
}
@@ -3895,7 +3895,7 @@ var Sizzle = function( selector, context, results, seed ) {
contextXML = Sizzle.isXML( context ),
parts = [],
soFar = selector;
-
+
// Reset the position of the chunker regexp (start from head)
do {
chunker.exec( "" );
@@ -3903,9 +3903,9 @@ var Sizzle = function( selector, context, results, seed ) {
if ( m ) {
soFar = m[3];
-
+
parts.push( m[1] );
-
+
if ( m[2] ) {
extra = m[3];
break;
@@ -3929,7 +3929,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( Expr.relative[ selector ] ) {
selector += parts.shift();
}
-
+
set = posProcess( selector, set, seed );
}
}
@@ -4057,7 +4057,7 @@ Sizzle.find = function( expr, context, isXML ) {
for ( i = 0, len = Expr.order.length; i < len; i++ ) {
type = Expr.order[i];
-
+
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
left = match[1];
match.splice( 1, 1 );
@@ -4429,7 +4429,7 @@ var Expr = Sizzle.selectors = {
ATTR: function( match, curLoop, inplace, result, not, isXML ) {
var name = match[1] = match[1].replace( rBackslash, "" );
-
+
if ( !isXML && Expr.attrMap[name] ) {
match[1] = Expr.attrMap[name];
}
@@ -4463,7 +4463,7 @@ var Expr = Sizzle.selectors = {
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
return true;
}
-
+
return match;
},
@@ -4473,7 +4473,7 @@ var Expr = Sizzle.selectors = {
return match;
}
},
-
+
filters: {
enabled: function( elem ) {
return elem.disabled === false && elem.type !== "hidden";
@@ -4486,14 +4486,14 @@ var Expr = Sizzle.selectors = {
checked: function( elem ) {
return elem.checked === true;
},
-
+
selected: function( elem ) {
// Accessing this property makes selected-by-default
// options in Safari work properly
if ( elem.parentNode ) {
elem.parentNode.selectedIndex;
}
-
+
return elem.selected === true;
},
@@ -4515,7 +4515,7 @@ var Expr = Sizzle.selectors = {
text: function( elem ) {
var attr = elem.getAttribute( "type" ), type = elem.type;
- // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
// use getAttribute instead to test this case
return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
},
@@ -4634,21 +4634,21 @@ var Expr = Sizzle.selectors = {
case "only":
case "first":
while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
- if ( type === "first" ) {
- return true;
+ if ( type === "first" ) {
+ return true;
}
node = elem;
case "last":
while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
@@ -4661,22 +4661,22 @@ var Expr = Sizzle.selectors = {
if ( first === 1 && last === 0 ) {
return true;
}
-
+
doneName = match[0];
parent = elem.parentNode;
-
+
if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {
count = 0;
-
+
for ( node = parent.firstChild; node; node = node.nextSibling ) {
if ( node.nodeType === 1 ) {
node.nodeIndex = ++count;
}
- }
+ }
parent[ expando ] = doneName;
}
-
+
diff = elem.nodeIndex - last;
if ( first === 0 ) {
@@ -4695,7 +4695,7 @@ var Expr = Sizzle.selectors = {
TAG: function( elem, match ) {
return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;
},
-
+
CLASS: function( elem, match ) {
return (" " + (elem.className || elem.getAttribute("class")) + " ")
.indexOf( match ) > -1;
@@ -4765,7 +4765,7 @@ var makeArray = function( array, results ) {
results.push.apply( results, array );
return results;
}
-
+
return array;
};
@@ -4997,7 +4997,7 @@ if ( document.querySelectorAll ) {
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
return;
}
-
+
Sizzle = function( query, context, extra, seed ) {
context = context || document;
@@ -5006,24 +5006,24 @@ if ( document.querySelectorAll ) {
if ( !seed && !Sizzle.isXML(context) ) {
// See if we find a selector to speed up
var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
-
+
if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
// Speed-up: Sizzle("TAG")
if ( match[1] ) {
return makeArray( context.getElementsByTagName( query ), extra );
-
+
// Speed-up: Sizzle(".CLASS")
} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
return makeArray( context.getElementsByClassName( match[2] ), extra );
}
}
-
+
if ( context.nodeType === 9 ) {
// Speed-up: Sizzle("body")
// The body element only exists once, optimize finding it
if ( query === "body" && context.body ) {
return makeArray( [ context.body ], extra );
-
+
// Speed-up: Sizzle("#ID")
} else if ( match && match[3] ) {
var elem = context.getElementById( match[3] );
@@ -5036,12 +5036,12 @@ if ( document.querySelectorAll ) {
if ( elem.id === match[3] ) {
return makeArray( [ elem ], extra );
}
-
+
} else {
return makeArray( [], extra );
}
}
-
+
try {
return makeArray( context.querySelectorAll(query), extra );
} catch(qsaError) {}
@@ -5079,7 +5079,7 @@ if ( document.querySelectorAll ) {
}
}
}
-
+
return oldSizzle(query, context, extra, seed);
};
@@ -5106,7 +5106,7 @@ if ( document.querySelectorAll ) {
// This should fail with an exception
// Gecko does not error, returns false instead
matches.call( document.documentElement, "[test!='']:sizzle" );
-
+
} catch( pseudoError ) {
pseudoWorks = true;
}
@@ -5116,7 +5116,7 @@ if ( document.querySelectorAll ) {
expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
if ( !Sizzle.isXML( node ) ) {
- try {
+ try {
if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
var ret = matches.call( node, expr );
@@ -5153,7 +5153,7 @@ if ( document.querySelectorAll ) {
if ( div.getElementsByClassName("e").length === 1 ) {
return;
}
-
+
Expr.order.splice(1, 0, "CLASS");
Expr.find.CLASS = function( match, context, isXML ) {
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
@@ -5204,7 +5204,7 @@ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
if ( elem ) {
var match = false;
-
+
elem = elem[dir];
while ( elem ) {
@@ -5257,7 +5257,7 @@ if ( document.documentElement.contains ) {
Sizzle.isXML = function( elem ) {
// documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
+ // (such as loading iframes in IE - #4833)
var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
return documentElement ? documentElement.nodeName !== "HTML" : false;
@@ -5374,11 +5374,11 @@ jQuery.fn.extend({
},
is: function( selector ) {
- return !!selector && (
+ return !!selector && (
typeof selector === "string" ?
// If this is a positional selector, check membership in the returned set
// so $("p:first").is("p:last") won't return true for a doc with two "p".
- POS.test( selector ) ?
+ POS.test( selector ) ?
jQuery( selector, this.context ).index( this[0] ) >= 0 :
jQuery.filter( selector, this ).length > 0 :
this.filter( selector ).length > 0 );
@@ -5386,7 +5386,7 @@ jQuery.fn.extend({
closest: function( selectors, context ) {
var ret = [], i, l, cur = this[0];
-
+
// Array (deprecated as of jQuery 1.7)
if ( jQuery.isArray( selectors ) ) {
var level = 1;
diff --git a/tests/jquery-1.7.2.js b/tests/jquery-1.7.2.js
index 3774ff986..ceb681ff9 100644
--- a/tests/jquery-1.7.2.js
+++ b/tests/jquery-1.7.2.js
@@ -3645,7 +3645,7 @@ if ( !jQuery.support.submitBubbles ) {
});
// return undefined since we don't need an event listener
},
-
+
postDispatch: function( event ) {
// If form was submitted by the user, bubble the event up the tree
if ( event._submit_bubble ) {
diff --git a/tests/jquery-1.7.js b/tests/jquery-1.7.js
index eda55db35..3c9ea9e56 100644
--- a/tests/jquery-1.7.js
+++ b/tests/jquery-1.7.js
@@ -3947,7 +3947,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
return [];
}
-
+
if ( !selector || typeof selector !== "string" ) {
return results;
}
@@ -3957,7 +3957,7 @@ var Sizzle = function( selector, context, results, seed ) {
contextXML = Sizzle.isXML( context ),
parts = [],
soFar = selector;
-
+
// Reset the position of the chunker regexp (start from head)
do {
chunker.exec( "" );
@@ -3965,9 +3965,9 @@ var Sizzle = function( selector, context, results, seed ) {
if ( m ) {
soFar = m[3];
-
+
parts.push( m[1] );
-
+
if ( m[2] ) {
extra = m[3];
break;
@@ -3991,7 +3991,7 @@ var Sizzle = function( selector, context, results, seed ) {
if ( Expr.relative[ selector ] ) {
selector += parts.shift();
}
-
+
set = posProcess( selector, set, seed );
}
}
@@ -4119,7 +4119,7 @@ Sizzle.find = function( expr, context, isXML ) {
for ( i = 0, len = Expr.order.length; i < len; i++ ) {
type = Expr.order[i];
-
+
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
left = match[1];
match.splice( 1, 1 );
@@ -4491,7 +4491,7 @@ var Expr = Sizzle.selectors = {
ATTR: function( match, curLoop, inplace, result, not, isXML ) {
var name = match[1] = match[1].replace( rBackslash, "" );
-
+
if ( !isXML && Expr.attrMap[name] ) {
match[1] = Expr.attrMap[name];
}
@@ -4525,7 +4525,7 @@ var Expr = Sizzle.selectors = {
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
return true;
}
-
+
return match;
},
@@ -4535,7 +4535,7 @@ var Expr = Sizzle.selectors = {
return match;
}
},
-
+
filters: {
enabled: function( elem ) {
return elem.disabled === false && elem.type !== "hidden";
@@ -4548,14 +4548,14 @@ var Expr = Sizzle.selectors = {
checked: function( elem ) {
return elem.checked === true;
},
-
+
selected: function( elem ) {
// Accessing this property makes selected-by-default
// options in Safari work properly
if ( elem.parentNode ) {
elem.parentNode.selectedIndex;
}
-
+
return elem.selected === true;
},
@@ -4577,7 +4577,7 @@ var Expr = Sizzle.selectors = {
text: function( elem ) {
var attr = elem.getAttribute( "type" ), type = elem.type;
- // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
// use getAttribute instead to test this case
return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
},
@@ -4696,21 +4696,21 @@ var Expr = Sizzle.selectors = {
case "only":
case "first":
while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
- if ( type === "first" ) {
- return true;
+ if ( type === "first" ) {
+ return true;
}
node = elem;
case "last":
while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
+ if ( node.nodeType === 1 ) {
+ return false;
}
}
@@ -4723,22 +4723,22 @@ var Expr = Sizzle.selectors = {
if ( first === 1 && last === 0 ) {
return true;
}
-
+
doneName = match[0];
parent = elem.parentNode;
-
+
if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {
count = 0;
-
+
for ( node = parent.firstChild; node; node = node.nextSibling ) {
if ( node.nodeType === 1 ) {
node.nodeIndex = ++count;
}
- }
+ }
parent[ expando ] = doneName;
}
-
+
diff = elem.nodeIndex - last;
if ( first === 0 ) {
@@ -4757,7 +4757,7 @@ var Expr = Sizzle.selectors = {
TAG: function( elem, match ) {
return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;
},
-
+
CLASS: function( elem, match ) {
return (" " + (elem.className || elem.getAttribute("class")) + " ")
.indexOf( match ) > -1;
@@ -4827,7 +4827,7 @@ var makeArray = function( array, results ) {
results.push.apply( results, array );
return results;
}
-
+
return array;
};
@@ -5059,7 +5059,7 @@ if ( document.querySelectorAll ) {
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
return;
}
-
+
Sizzle = function( query, context, extra, seed ) {
context = context || document;
@@ -5068,24 +5068,24 @@ if ( document.querySelectorAll ) {
if ( !seed && !Sizzle.isXML(context) ) {
// See if we find a selector to speed up
var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
-
+
if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
// Speed-up: Sizzle("TAG")
if ( match[1] ) {
return makeArray( context.getElementsByTagName( query ), extra );
-
+
// Speed-up: Sizzle(".CLASS")
} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
return makeArray( context.getElementsByClassName( match[2] ), extra );
}
}
-
+
if ( context.nodeType === 9 ) {
// Speed-up: Sizzle("body")
// The body element only exists once, optimize finding it
if ( query === "body" && context.body ) {
return makeArray( [ context.body ], extra );
-
+
// Speed-up: Sizzle("#ID")
} else if ( match && match[3] ) {
var elem = context.getElementById( match[3] );
@@ -5098,12 +5098,12 @@ if ( document.querySelectorAll ) {
if ( elem.id === match[3] ) {
return makeArray( [ elem ], extra );
}
-
+
} else {
return makeArray( [], extra );
}
}
-
+
try {
return makeArray( context.querySelectorAll(query), extra );
} catch(qsaError) {}
@@ -5141,7 +5141,7 @@ if ( document.querySelectorAll ) {
}
}
}
-
+
return oldSizzle(query, context, extra, seed);
};
@@ -5168,7 +5168,7 @@ if ( document.querySelectorAll ) {
// This should fail with an exception
// Gecko does not error, returns false instead
matches.call( document.documentElement, "[test!='']:sizzle" );
-
+
} catch( pseudoError ) {
pseudoWorks = true;
}
@@ -5178,7 +5178,7 @@ if ( document.querySelectorAll ) {
expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
if ( !Sizzle.isXML( node ) ) {
- try {
+ try {
if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
var ret = matches.call( node, expr );
@@ -5215,7 +5215,7 @@ if ( document.querySelectorAll ) {
if ( div.getElementsByClassName("e").length === 1 ) {
return;
}
-
+
Expr.order.splice(1, 0, "CLASS");
Expr.find.CLASS = function( match, context, isXML ) {
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
@@ -5266,7 +5266,7 @@ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
if ( elem ) {
var match = false;
-
+
elem = elem[dir];
while ( elem ) {
@@ -5319,7 +5319,7 @@ if ( document.documentElement.contains ) {
Sizzle.isXML = function( elem ) {
// documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
+ // (such as loading iframes in IE - #4833)
var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
return documentElement ? documentElement.nodeName !== "HTML" : false;
@@ -5436,11 +5436,11 @@ jQuery.fn.extend({
},
is: function( selector ) {
- return !!selector && (
+ return !!selector && (
typeof selector === "string" ?
// If this is a positional selector, check membership in the returned set
// so $("p:first").is("p:last") won't return true for a doc with two "p".
- POS.test( selector ) ?
+ POS.test( selector ) ?
jQuery( selector, this.context ).index( this[0] ) >= 0 :
jQuery.filter( selector, this ).length > 0 :
this.filter( selector ).length > 0 );
@@ -5448,7 +5448,7 @@ jQuery.fn.extend({
closest: function( selectors, context ) {
var ret = [], i, l, cur = this[0];
-
+
// Array (deprecated as of jQuery 1.7)
if ( jQuery.isArray( selectors ) ) {
var level = 1;
diff --git a/tests/jquery-1.8.0.js b/tests/jquery-1.8.0.js
index 077068294..f81bd3d46 100644
--- a/tests/jquery-1.8.0.js
+++ b/tests/jquery-1.8.0.js
@@ -3668,1463 +3668,1463 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
}
});
-/*!
- * Sizzle CSS Selector Engine
- * Copyright 2012 jQuery Foundation and other contributors
- * Released under the MIT license
- * http://sizzlejs.com/
- */
-(function( window, undefined ) {
-
-var cachedruns,
- dirruns,
- sortOrder,
- siblingCheck,
- assertGetIdNotName,
-
- document = window.document,
- docElem = document.documentElement,
-
- strundefined = "undefined",
- hasDuplicate = false,
- baseHasDuplicate = true,
- done = 0,
- slice = [].slice,
- push = [].push,
-
- expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
-
- // Regex
-
- // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
- whitespace = "[\\x20\\t\\r\\n\\f]",
- // http://www.w3.org/TR/css3-syntax/#characters
- characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
-
- // Loosely modeled on CSS identifier characters
- // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)
- // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
- identifier = characterEncoding.replace( "w", "w#" ),
-
- // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
- operators = "([*^$|!~]?=)",
- attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
- "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
- pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",
- pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",
- combinators = whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*",
- groups = "(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|" + attributes + "|" + pseudos.replace( 2, 7 ) + "|[^\\\\(),])+",
-
- // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
- rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
-
- rcombinators = new RegExp( "^" + combinators ),
-
- // All simple (non-comma) selectors, excluding insignifant trailing whitespace
- rgroups = new RegExp( groups + "?(?=" + whitespace + "*,|$)", "g" ),
-
- // A selector, or everything after leading whitespace
- // Optionally followed in either case by a ")" for terminating sub-selectors
- rselector = new RegExp( "^(?:(?!,)(?:(?:^|,)" + whitespace + "*" + groups + ")*?|" + whitespace + "*(.*?))(\\)|$)" ),
-
- // All combinators and selector components (attribute test, tag, pseudo, etc.), the latter appearing together when consecutive
- rtokens = new RegExp( groups.slice( 19, -6 ) + "\\x20\\t\\r\\n\\f>+~])+|" + combinators, "g" ),
-
- // Easily-parseable/retrievable ID or TAG or CLASS selectors
- rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
-
- rsibling = /[\x20\t\r\n\f]*[+~]/,
- rendsWithNot = /:not\($/,
-
- rheader = /h\d/i,
- rinputs = /input|select|textarea|button/i,
-
- rbackslash = /\\(?!\\)/g,
-
- matchExpr = {
- "ID": new RegExp( "^#(" + characterEncoding + ")" ),
- "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
- "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
- "TAG": new RegExp( "^(" + characterEncoding.replace( "[-", "[-\\*" ) + ")" ),
- "ATTR": new RegExp( "^" + attributes ),
- "PSEUDO": new RegExp( "^" + pseudos ),
- "CHILD": new RegExp( "^:(only|nth|last|first)-child(?:\\(" + whitespace +
- "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
- "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
- "POS": new RegExp( pos, "ig" ),
- // For use in libraries implementing .is()
- "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
- },
-
- classCache = {},
- cachedClasses = [],
- compilerCache = {},
- cachedSelectors = [],
-
- // Mark a function for use in filtering
- markFunction = function( fn ) {
- fn.sizzleFilter = true;
- return fn;
- },
-
- // Returns a function to use in pseudos for input types
- createInputFunction = function( type ) {
- return function( elem ) {
- // Check the input's nodeName and type
- return elem.nodeName.toLowerCase() === "input" && elem.type === type;
- };
- },
-
- // Returns a function to use in pseudos for buttons
- createButtonFunction = function( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return (name === "input" || name === "button") && elem.type === type;
- };
- },
-
- // Used for testing something on an element
- assert = function( fn ) {
- var pass = false,
- div = document.createElement("div");
- try {
- pass = fn( div );
- } catch (e) {}
- // release memory in IE
- div = null;
- return pass;
- },
-
- // Check if attributes should be retrieved by attribute nodes
- assertAttributes = assert(function( div ) {
- div.innerHTML = "<select></select>";
- var type = typeof div.lastChild.getAttribute("multiple");
- // IE8 returns a string for some attributes even when not present
- return type !== "boolean" && type !== "string";
- }),
-
- // Check if getElementById returns elements by name
- // Check if getElementsByName privileges form controls or returns elements by ID
- assertUsableName = assert(function( div ) {
- // Inject content
- div.id = expando + 0;
- div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
- docElem.insertBefore( div, docElem.firstChild );
-
- // Test
- var pass = document.getElementsByName &&
- // buggy browsers will return fewer than the correct 2
- document.getElementsByName( expando ).length ===
- // buggy browsers will return more than the correct 0
- 2 + document.getElementsByName( expando + 0 ).length;
- assertGetIdNotName = !document.getElementById( expando );
-
- // Cleanup
- docElem.removeChild( div );
-
- return pass;
- }),
-
- // Check if the browser returns only elements
- // when doing getElementsByTagName("*")
- assertTagNameNoComments = assert(function( div ) {
- div.appendChild( document.createComment("") );
- return div.getElementsByTagName("*").length === 0;
- }),
-
- // Check if getAttribute returns normalized href attributes
- assertHrefNotNormalized = assert(function( div ) {
- div.innerHTML = "<a href='#'></a>";
- return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
- div.firstChild.getAttribute("href") === "#";
- }),
-
- // Check if getElementsByClassName can be trusted
- assertUsableClassName = assert(function( div ) {
- // Opera can't find a second classname (in 9.6)
- div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
- if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
- return false;
- }
-
- // Safari caches class attributes, doesn't catch changes (in 3.2)
- div.lastChild.className = "e";
- return div.getElementsByClassName("e").length !== 1;
- });
-
-var Sizzle = function( selector, context, results, seed ) {
- results = results || [];
- context = context || document;
- var match, elem, xml, m,
- nodeType = context.nodeType;
-
- if ( nodeType !== 1 && nodeType !== 9 ) {
- return [];
- }
-
- if ( !selector || typeof selector !== "string" ) {
- return results;
- }
-
- xml = isXML( context );
-
- if ( !xml && !seed ) {
- if ( (match = rquickExpr.exec( selector )) ) {
- // Speed-up: Sizzle("#ID")
- if ( (m = match[1]) ) {
- if ( nodeType === 9 ) {
- elem = context.getElementById( m );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- if ( elem && elem.parentNode ) {
- // Handle the case where IE, Opera, and Webkit return items
- // by name instead of ID
- if ( elem.id === m ) {
- results.push( elem );
- return results;
- }
- } else {
- return results;
- }
- } else {
- // Context is not a document
- if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
- contains( context, elem ) && elem.id === m ) {
- results.push( elem );
- return results;
- }
- }
-
- // Speed-up: Sizzle("TAG")
- } else if ( match[2] ) {
- push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
- return results;
-
- // Speed-up: Sizzle(".CLASS")
- } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
- push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
- return results;
- }
- }
- }
-
- // All others
- return select( selector, context, results, seed, xml );
-};
-
-var Expr = Sizzle.selectors = {
-
- // Can be adjusted by the user
- cacheLength: 50,
-
- match: matchExpr,
-
- order: [ "ID", "TAG" ],
-
- attrHandle: {},
-
- createPseudo: markFunction,
-
- find: {
- "ID": assertGetIdNotName ?
- function( id, context, xml ) {
- if ( typeof context.getElementById !== strundefined && !xml ) {
- var m = context.getElementById( id );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- return m && m.parentNode ? [m] : [];
- }
- } :
- function( id, context, xml ) {
- if ( typeof context.getElementById !== strundefined && !xml ) {
- var m = context.getElementById( id );
-
- return m ?
- m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
- [m] :
- undefined :
- [];
- }
- },
-
- "TAG": assertTagNameNoComments ?
- function( tag, context ) {
- if ( typeof context.getElementsByTagName !== strundefined ) {
- return context.getElementsByTagName( tag );
- }
- } :
- function( tag, context ) {
- var results = context.getElementsByTagName( tag );
-
- // Filter out possible comments
- if ( tag === "*" ) {
- var elem,
- tmp = [],
- i = 0;
-
- for ( ; (elem = results[i]); i++ ) {
- if ( elem.nodeType === 1 ) {
- tmp.push( elem );
- }
- }
-
- return tmp;
- }
- return results;
- }
- },
-
- relative: {
- ">": { dir: "parentNode", first: true },
- " ": { dir: "parentNode" },
- "+": { dir: "previousSibling", first: true },
- "~": { dir: "previousSibling" }
- },
-
- preFilter: {
- "ATTR": function( match ) {
- match[1] = match[1].replace( rbackslash, "" );
-
- // Move the given value to match[3] whether quoted or unquoted
- match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
-
- if ( match[2] === "~=" ) {
- match[3] = " " + match[3] + " ";
- }
-
- return match.slice( 0, 4 );
- },
-
- "CHILD": function( match ) {
- /* matches from matchExpr.CHILD
- 1 type (only|nth|...)
- 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
- 3 xn-component of xn+y argument ([+-]?\d*n|)
- 4 sign of xn-component
- 5 x of xn-component
- 6 sign of y-component
- 7 y of y-component
- */
- match[1] = match[1].toLowerCase();
-
- if ( match[1] === "nth" ) {
- // nth-child requires argument
- if ( !match[2] ) {
- Sizzle.error( match[0] );
- }
-
- // numeric x and y parameters for Expr.filter.CHILD
- // remember that false/true cast respectively to 0/1
- match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
- match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
-
- // other types prohibit arguments
- } else if ( match[2] ) {
- Sizzle.error( match[0] );
- }
-
- return match;
- },
-
- "PSEUDO": function( match ) {
- var argument,
- unquoted = match[4];
-
- if ( matchExpr["CHILD"].test( match[0] ) ) {
- return null;
- }
-
- // Relinquish our claim on characters in `unquoted` from a closing parenthesis on
- if ( unquoted && (argument = rselector.exec( unquoted )) && argument.pop() ) {
-
- match[0] = match[0].slice( 0, argument[0].length - unquoted.length - 1 );
- unquoted = argument[0].slice( 0, -1 );
- }
-
- // Quoted or unquoted, we have the full argument
- // Return only captures needed by the pseudo filter method (type and argument)
- match.splice( 2, 3, unquoted || match[3] );
- return match;
- }
- },
-
- filter: {
- "ID": assertGetIdNotName ?
- function( id ) {
- id = id.replace( rbackslash, "" );
- return function( elem ) {
- return elem.getAttribute("id") === id;
- };
- } :
- function( id ) {
- id = id.replace( rbackslash, "" );
- return function( elem ) {
- var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
- return node && node.value === id;
- };
- },
-
- "TAG": function( nodeName ) {
- if ( nodeName === "*" ) {
- return function() { return true; };
- }
- nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
-
- return function( elem ) {
- return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
- };
- },
-
- "CLASS": function( className ) {
- var pattern = classCache[ className ];
- if ( !pattern ) {
- pattern = classCache[ className ] = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" );
- cachedClasses.push( className );
- // Avoid too large of a cache
- if ( cachedClasses.length > Expr.cacheLength ) {
- delete classCache[ cachedClasses.shift() ];
- }
- }
- return function( elem ) {
- return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
- };
- },
-
- "ATTR": function( name, operator, check ) {
- if ( !operator ) {
- return function( elem ) {
- return Sizzle.attr( elem, name ) != null;
- };
- }
-
- return function( elem ) {
- var result = Sizzle.attr( elem, name ),
- value = result + "";
-
- if ( result == null ) {
- return operator === "!=";
- }
-
- switch ( operator ) {
- case "=":
- return value === check;
- case "!=":
- return value !== check;
- case "^=":
- return check && value.indexOf( check ) === 0;
- case "*=":
- return check && value.indexOf( check ) > -1;
- case "$=":
- return check && value.substr( value.length - check.length ) === check;
- case "~=":
- return ( " " + value + " " ).indexOf( check ) > -1;
- case "|=":
- return value === check || value.substr( 0, check.length + 1 ) === check + "-";
- }
- };
- },
-
- "CHILD": function( type, argument, first, last ) {
-
- if ( type === "nth" ) {
- var doneName = done++;
-
- return function( elem ) {
- var parent, diff,
- count = 0,
- node = elem;
-
- if ( first === 1 && last === 0 ) {
- return true;
- }
-
- parent = elem.parentNode;
-
- if ( parent && (parent[ expando ] !== doneName || !elem.sizset) ) {
- for ( node = parent.firstChild; node; node = node.nextSibling ) {
- if ( node.nodeType === 1 ) {
- node.sizset = ++count;
- if ( node === elem ) {
- break;
- }
- }
- }
-
- parent[ expando ] = doneName;
- }
-
- diff = elem.sizset - last;
-
- if ( first === 0 ) {
- return diff === 0;
-
- } else {
- return ( diff % first === 0 && diff / first >= 0 );
- }
- };
- }
-
- return function( elem ) {
- var node = elem;
-
- switch ( type ) {
- case "only":
- case "first":
- while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
-
- if ( type === "first" ) {
- return true;
- }
-
- node = elem;
-
- /* falls through */
- case "last":
- while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
-
- return true;
- }
- };
- },
-
- "PSEUDO": function( pseudo, argument, context, xml ) {
- // pseudo-class names are case-insensitive
- // http://www.w3.org/TR/selectors/#pseudo-classes
- // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
- var fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ];
-
- if ( !fn ) {
- Sizzle.error( "unsupported pseudo: " + pseudo );
- }
-
- // The user may set fn.sizzleFilter to indicate
- // that arguments are needed to create the filter function
- // just as Sizzle does
- if ( !fn.sizzleFilter ) {
- return fn;
- }
-
- return fn( argument, context, xml );
- }
- },
-
- pseudos: {
- "not": markFunction(function( selector, context, xml ) {
- // Trim the selector passed to compile
- // to avoid treating leading and trailing
- // spaces as combinators
- var matcher = compile( selector.replace( rtrim, "$1" ), context, xml );
- return function( elem ) {
- return !matcher( elem );
- };
- }),
-
- "enabled": function( elem ) {
- return elem.disabled === false;
- },
-
- "disabled": function( elem ) {
- return elem.disabled === true;
- },
-
- "checked": function( elem ) {
- // In CSS3, :checked should return both checked and selected elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- var nodeName = elem.nodeName.toLowerCase();
- return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
- },
-
- "selected": function( elem ) {
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- if ( elem.parentNode ) {
- elem.parentNode.selectedIndex;
- }
-
- return elem.selected === true;
- },
-
- "parent": function( elem ) {
- return !Expr.pseudos["empty"]( elem );
- },
-
- "empty": function( elem ) {
- // http://www.w3.org/TR/selectors/#empty-pseudo
- // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
- // not comment, processing instructions, or others
- // Thanks to Diego Perini for the nodeName shortcut
- // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
- var nodeType;
- elem = elem.firstChild;
- while ( elem ) {
- if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
- return false;
- }
- elem = elem.nextSibling;
- }
- return true;
- },
-
- "contains": markFunction(function( text ) {
- return function( elem ) {
- return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
- };
- }),
-
- "has": markFunction(function( selector ) {
- return function( elem ) {
- return Sizzle( selector, elem ).length > 0;
- };
- }),
-
- "header": function( elem ) {
- return rheader.test( elem.nodeName );
- },
-
- "text": function( elem ) {
- var type, attr;
- // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
- // use getAttribute instead to test this case
- return elem.nodeName.toLowerCase() === "input" &&
- (type = elem.type) === "text" &&
- ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
- },
-
- // Input types
- "radio": createInputFunction("radio"),
- "checkbox": createInputFunction("checkbox"),
- "file": createInputFunction("file"),
- "password": createInputFunction("password"),
- "image": createInputFunction("image"),
-
- "submit": createButtonFunction("submit"),
- "reset": createButtonFunction("reset"),
-
- "button": function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === "button" || name === "button";
- },
-
- "input": function( elem ) {
- return rinputs.test( elem.nodeName );
- },
-
- "focus": function( elem ) {
- var doc = elem.ownerDocument;
- return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href);
- },
-
- "active": function( elem ) {
- return elem === elem.ownerDocument.activeElement;
- }
- },
-
- setFilters: {
- "first": function( elements, argument, not ) {
- return not ? elements.slice( 1 ) : [ elements[0] ];
- },
-
- "last": function( elements, argument, not ) {
- var elem = elements.pop();
- return not ? elements : [ elem ];
- },
-
- "even": function( elements, argument, not ) {
- var results = [],
- i = not ? 1 : 0,
- len = elements.length;
- for ( ; i < len; i = i + 2 ) {
- results.push( elements[i] );
- }
- return results;
- },
-
- "odd": function( elements, argument, not ) {
- var results = [],
- i = not ? 0 : 1,
- len = elements.length;
- for ( ; i < len; i = i + 2 ) {
- results.push( elements[i] );
- }
- return results;
- },
-
- "lt": function( elements, argument, not ) {
- return not ? elements.slice( +argument ) : elements.slice( 0, +argument );
- },
-
- "gt": function( elements, argument, not ) {
- return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 );
- },
-
- "eq": function( elements, argument, not ) {
- var elem = elements.splice( +argument, 1 );
- return not ? elements : elem;
- }
- }
-};
-
-// Deprecated
-Expr.setFilters["nth"] = Expr.setFilters["eq"];
-
-// Back-compat
-Expr.filters = Expr.pseudos;
-
-// IE6/7 return a modified href
-if ( !assertHrefNotNormalized ) {
- Expr.attrHandle = {
- "href": function( elem ) {
- return elem.getAttribute( "href", 2 );
- },
- "type": function( elem ) {
- return elem.getAttribute("type");
- }
- };
-}
-
-// Add getElementsByName if usable
-if ( assertUsableName ) {
- Expr.order.push("NAME");
- Expr.find["NAME"] = function( name, context ) {
- if ( typeof context.getElementsByName !== strundefined ) {
- return context.getElementsByName( name );
- }
- };
-}
-
-// Add getElementsByClassName if usable
-if ( assertUsableClassName ) {
- Expr.order.splice( 1, 0, "CLASS" );
- Expr.find["CLASS"] = function( className, context, xml ) {
- if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
- return context.getElementsByClassName( className );
- }
- };
-}
-
-// If slice is not available, provide a backup
-try {
- slice.call( docElem.childNodes, 0 )[0].nodeType;
-} catch ( e ) {
- slice = function( i ) {
- var elem, results = [];
- for ( ; (elem = this[i]); i++ ) {
- results.push( elem );
- }
- return results;
- };
-}
-
-var isXML = Sizzle.isXML = function( elem ) {
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = elem && (elem.ownerDocument || elem).documentElement;
- return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-// Element contains another
-var contains = Sizzle.contains = docElem.compareDocumentPosition ?
- function( a, b ) {
- return !!( a.compareDocumentPosition( b ) & 16 );
- } :
- docElem.contains ?
- function( a, b ) {
- var adown = a.nodeType === 9 ? a.documentElement : a,
- bup = b.parentNode;
- return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
- } :
- function( a, b ) {
- while ( (b = b.parentNode) ) {
- if ( b === a ) {
- return true;
- }
- }
- return false;
- };
-
-/**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-var getText = Sizzle.getText = function( elem ) {
- var node,
- ret = "",
- i = 0,
- nodeType = elem.nodeType;
-
- if ( nodeType ) {
- if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
- // Use textContent for elements
- // innerText usage removed for consistency of new lines (see #11153)
- if ( typeof elem.textContent === "string" ) {
- return elem.textContent;
- } else {
- // Traverse its children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
- ret += getText( elem );
- }
- }
- } else if ( nodeType === 3 || nodeType === 4 ) {
- return elem.nodeValue;
- }
- // Do not include comment or processing instruction nodes
- } else {
-
- // If no nodeType, this is expected to be an array
- for ( ; (node = elem[i]); i++ ) {
- // Do not traverse comment nodes
- ret += getText( node );
- }
- }
- return ret;
-};
-
-Sizzle.attr = function( elem, name ) {
- var attr,
- xml = isXML( elem );
-
- if ( !xml ) {
- name = name.toLowerCase();
- }
- if ( Expr.attrHandle[ name ] ) {
- return Expr.attrHandle[ name ]( elem );
- }
- if ( assertAttributes || xml ) {
- return elem.getAttribute( name );
- }
- attr = elem.getAttributeNode( name );
- return attr ?
- typeof elem[ name ] === "boolean" ?
- elem[ name ] ? name : null :
- attr.specified ? attr.value : null :
- null;
-};
-
-Sizzle.error = function( msg ) {
- throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
-
-// Check if the JavaScript engine is using some sort of
-// optimization where it does not always call our comparision
-// function. If that is the case, discard the hasDuplicate value.
-// Thus far that includes Google Chrome.
-[0, 0].sort(function() {
- return (baseHasDuplicate = 0);
-});
-
-
-if ( docElem.compareDocumentPosition ) {
- sortOrder = function( a, b ) {
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
- a.compareDocumentPosition :
- a.compareDocumentPosition(b) & 4
- ) ? -1 : 1;
- };
-
-} else {
- sortOrder = function( a, b ) {
- // The nodes are identical, we can exit early
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
-
- // Fallback to using sourceIndex (in IE) if it's available on both nodes
- } else if ( a.sourceIndex && b.sourceIndex ) {
- return a.sourceIndex - b.sourceIndex;
- }
-
- var al, bl,
- ap = [],
- bp = [],
- aup = a.parentNode,
- bup = b.parentNode,
- cur = aup;
-
- // If the nodes are siblings (or identical) we can do a quick check
- if ( aup === bup ) {
- return siblingCheck( a, b );
-
- // If no parents were found then the nodes are disconnected
- } else if ( !aup ) {
- return -1;
-
- } else if ( !bup ) {
- return 1;
- }
-
- // Otherwise they're somewhere else in the tree so we need
- // to build up a full list of the parentNodes for comparison
- while ( cur ) {
- ap.unshift( cur );
- cur = cur.parentNode;
- }
-
- cur = bup;
-
- while ( cur ) {
- bp.unshift( cur );
- cur = cur.parentNode;
- }
-
- al = ap.length;
- bl = bp.length;
-
- // Start walking down the tree looking for a discrepancy
- for ( var i = 0; i < al && i < bl; i++ ) {
- if ( ap[i] !== bp[i] ) {
- return siblingCheck( ap[i], bp[i] );
- }
- }
-
- // We ended someplace up the tree so do a sibling check
- return i === al ?
- siblingCheck( a, bp[i], -1 ) :
- siblingCheck( ap[i], b, 1 );
- };
-
- siblingCheck = function( a, b, ret ) {
- if ( a === b ) {
- return ret;
- }
-
- var cur = a.nextSibling;
-
- while ( cur ) {
- if ( cur === b ) {
- return -1;
- }
-
- cur = cur.nextSibling;
- }
-
- return 1;
- };
-}
-
-// Document sorting and removing duplicates
-Sizzle.uniqueSort = function( results ) {
- var elem,
- i = 1;
-
- if ( sortOrder ) {
- hasDuplicate = baseHasDuplicate;
- results.sort( sortOrder );
-
- if ( hasDuplicate ) {
- for ( ; (elem = results[i]); i++ ) {
- if ( elem === results[ i - 1 ] ) {
- results.splice( i--, 1 );
- }
- }
- }
- }
-
- return results;
-};
-
-function multipleContexts( selector, contexts, results, seed ) {
- var i = 0,
- len = contexts.length;
- for ( ; i < len; i++ ) {
- Sizzle( selector, contexts[i], results, seed );
- }
-}
-
-function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) {
- var results,
- fn = Expr.setFilters[ posfilter.toLowerCase() ];
-
- if ( !fn ) {
- Sizzle.error( posfilter );
- }
-
- if ( selector || !(results = seed) ) {
- multipleContexts( selector || "*", contexts, (results = []), seed );
- }
-
- return results.length > 0 ? fn( results, argument, not ) : [];
-}
-
-function handlePOS( selector, context, results, seed, groups ) {
- var match, not, anchor, ret, elements, currentContexts, part, lastIndex,
- i = 0,
- len = groups.length,
- rpos = matchExpr["POS"],
- // This is generated here in case matchExpr["POS"] is extended
- rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ),
- // This is for making sure non-participating
- // matching groups are represented cross-browser (IE6-8)
- setUndefined = function() {
- var i = 1,
- len = arguments.length - 2;
- for ( ; i < len; i++ ) {
- if ( arguments[i] === undefined ) {
- match[i] = undefined;
- }
- }
- };
-
- for ( ; i < len; i++ ) {
- // Reset regex index to 0
- rpos.exec("");
- selector = groups[i];
- ret = [];
- anchor = 0;
- elements = seed;
- while ( (match = rpos.exec( selector )) ) {
- lastIndex = rpos.lastIndex = match.index + match[0].length;
- if ( lastIndex > anchor ) {
- part = selector.slice( anchor, match.index );
- anchor = lastIndex;
- currentContexts = [ context ];
-
- if ( rcombinators.test(part) ) {
- if ( elements ) {
- currentContexts = elements;
- }
- elements = seed;
- }
-
- if ( (not = rendsWithNot.test( part )) ) {
- part = part.slice( 0, -5 ).replace( rcombinators, "$&*" );
- }
-
- if ( match.length > 1 ) {
- match[0].replace( rposgroups, setUndefined );
- }
- elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not );
- }
- }
-
- if ( elements ) {
- ret = ret.concat( elements );
-
- if ( (part = selector.slice( anchor )) && part !== ")" ) {
- if ( rcombinators.test(part) ) {
- multipleContexts( part, ret, results, seed );
- } else {
- Sizzle( part, context, results, seed ? seed.concat(elements) : elements );
- }
- } else {
- push.apply( results, ret );
- }
- } else {
- Sizzle( selector, context, results, seed );
- }
- }
-
- // Do not sort if this is a single filter
- return len === 1 ? results : Sizzle.uniqueSort( results );
-}
-
-function tokenize( selector, context, xml ) {
- var tokens, soFar, type,
- groups = [],
- i = 0,
-
- // Catch obvious selector issues: terminal ")"; nonempty fallback match
- // rselector never fails to match *something*
- match = rselector.exec( selector ),
- matched = !match.pop() && !match.pop(),
- selectorGroups = matched && selector.match( rgroups ) || [""],
-
- preFilters = Expr.preFilter,
- filters = Expr.filter,
- checkContext = !xml && context !== document;
-
- for ( ; (soFar = selectorGroups[i]) != null && matched; i++ ) {
- groups.push( tokens = [] );
-
- // Need to make sure we're within a narrower context if necessary
- // Adding a descendant combinator will generate what is needed
- if ( checkContext ) {
- soFar = " " + soFar;
- }
-
- while ( soFar ) {
- matched = false;
-
- // Combinators
- if ( (match = rcombinators.exec( soFar )) ) {
- soFar = soFar.slice( match[0].length );
-
- // Cast descendant combinators to space
- matched = tokens.push({ part: match.pop().replace( rtrim, " " ), captures: match });
- }
-
- // Filters
- for ( type in filters ) {
- if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
- (match = preFilters[ type ]( match, context, xml )) ) ) {
-
- soFar = soFar.slice( match.shift().length );
- matched = tokens.push({ part: type, captures: match });
- }
- }
-
- if ( !matched ) {
- break;
- }
- }
- }
-
- if ( !matched ) {
- Sizzle.error( selector );
- }
-
- return groups;
-}
-
-function addCombinator( matcher, combinator, context ) {
- var dir = combinator.dir,
- doneName = done++;
-
- if ( !matcher ) {
- // If there is no matcher to check, check against the context
- matcher = function( elem ) {
- return elem === context;
- };
- }
- return combinator.first ?
- function( elem, context ) {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 ) {
- return matcher( elem, context ) && elem;
- }
- }
- } :
- function( elem, context ) {
- var cache,
- dirkey = doneName + "." + dirruns,
- cachedkey = dirkey + "." + cachedruns;
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 ) {
- if ( (cache = elem[ expando ]) === cachedkey ) {
- return elem.sizset;
- } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
- if ( elem.sizset ) {
- return elem;
- }
- } else {
- elem[ expando ] = cachedkey;
- if ( matcher( elem, context ) ) {
- elem.sizset = true;
- return elem;
- }
- elem.sizset = false;
- }
- }
- }
- };
-}
-
-function addMatcher( higher, deeper ) {
- return higher ?
- function( elem, context ) {
- var result = deeper( elem, context );
- return result && higher( result === true ? elem : result, context );
- } :
- deeper;
-}
-
-// ["TAG", ">", "ID", " ", "CLASS"]
-function matcherFromTokens( tokens, context, xml ) {
- var token, matcher,
- i = 0;
-
- for ( ; (token = tokens[i]); i++ ) {
- if ( Expr.relative[ token.part ] ) {
- matcher = addCombinator( matcher, Expr.relative[ token.part ], context );
- } else {
- token.captures.push( context, xml );
- matcher = addMatcher( matcher, Expr.filter[ token.part ].apply( null, token.captures ) );
- }
- }
-
- return matcher;
-}
-
-function matcherFromGroupMatchers( matchers ) {
- return function( elem, context ) {
- var matcher,
- j = 0;
- for ( ; (matcher = matchers[j]); j++ ) {
- if ( matcher(elem, context) ) {
- return true;
- }
- }
- return false;
- };
-}
-
-var compile = Sizzle.compile = function( selector, context, xml ) {
- var tokens, group, i,
- cached = compilerCache[ selector ];
-
- // Return a cached group function if already generated (context dependent)
- if ( cached && cached.context === context ) {
- return cached;
- }
-
- // Generate a function of recursive functions that can be used to check each element
- group = tokenize( selector, context, xml );
- for ( i = 0; (tokens = group[i]); i++ ) {
- group[i] = matcherFromTokens( tokens, context, xml );
- }
-
- // Cache the compiled function
- cached = compilerCache[ selector ] = matcherFromGroupMatchers( group );
- cached.context = context;
- cached.runs = cached.dirruns = 0;
- cachedSelectors.push( selector );
- // Ensure only the most recent are cached
- if ( cachedSelectors.length > Expr.cacheLength ) {
- delete compilerCache[ cachedSelectors.shift() ];
- }
- return cached;
-};
-
-Sizzle.matches = function( expr, elements ) {
- return Sizzle( expr, null, null, elements );
-};
-
-Sizzle.matchesSelector = function( elem, expr ) {
- return Sizzle( expr, null, null, [ elem ] ).length > 0;
-};
-
-var select = function( selector, context, results, seed, xml ) {
- // Remove excessive whitespace
- selector = selector.replace( rtrim, "$1" );
- var elements, matcher, i, len, elem, token,
- type, findContext, notTokens,
- match = selector.match( rgroups ),
- tokens = selector.match( rtokens ),
- contextNodeType = context.nodeType;
-
- // POS handling
- if ( matchExpr["POS"].test(selector) ) {
- return handlePOS( selector, context, results, seed, match );
- }
-
- if ( seed ) {
- elements = slice.call( seed, 0 );
-
- // To maintain document order, only narrow the
- // set if there is one group
- } else if ( match && match.length === 1 ) {
-
- // Take a shortcut and set the context if the root selector is an ID
- if ( tokens.length > 1 && contextNodeType === 9 && !xml &&
- (match = matchExpr["ID"].exec( tokens[0] )) ) {
-
- context = Expr.find["ID"]( match[1], context, xml )[0];
- if ( !context ) {
- return results;
- }
-
- selector = selector.slice( tokens.shift().length );
- }
-
- findContext = ( (match = rsibling.exec( tokens[0] )) && !match.index && context.parentNode ) || context;
-
- // Get the last token, excluding :not
- notTokens = tokens.pop();
- token = notTokens.split(":not")[0];
-
- for ( i = 0, len = Expr.order.length; i < len; i++ ) {
- type = Expr.order[i];
-
- if ( (match = matchExpr[ type ].exec( token )) ) {
- elements = Expr.find[ type ]( (match[1] || "").replace( rbackslash, "" ), findContext, xml );
-
- if ( elements == null ) {
- continue;
- }
-
- if ( token === notTokens ) {
- selector = selector.slice( 0, selector.length - notTokens.length ) +
- token.replace( matchExpr[ type ], "" );
-
- if ( !selector ) {
- push.apply( results, slice.call(elements, 0) );
- }
- }
- break;
- }
- }
- }
-
- // Only loop over the given elements once
- // If selector is empty, we're already done
- if ( selector ) {
- matcher = compile( selector, context, xml );
- dirruns = matcher.dirruns++;
-
- if ( elements == null ) {
- elements = Expr.find["TAG"]( "*", (rsibling.test( selector ) && context.parentNode) || context );
- }
- for ( i = 0; (elem = elements[i]); i++ ) {
- cachedruns = matcher.runs++;
- if ( matcher(elem, context) ) {
- results.push( elem );
- }
- }
- }
-
- return results;
-};
-
-if ( document.querySelectorAll ) {
- (function() {
- var disconnectedMatch,
- oldSelect = select,
- rescape = /'|\\/g,
- rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
- rbuggyQSA = [],
- // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
- // A support test would require too much code (would include document ready)
- // just skip matchesSelector for :active
- rbuggyMatches = [":active"],
- matches = docElem.matchesSelector ||
- docElem.mozMatchesSelector ||
- docElem.webkitMatchesSelector ||
- docElem.oMatchesSelector ||
- docElem.msMatchesSelector;
-
- // Build QSA regex
- // Regex strategy adopted from Diego Perini
- assert(function( div ) {
- div.innerHTML = "<select><option selected></option></select>";
-
- // IE8 - Some boolean attributes are not treated correctly
- if ( !div.querySelectorAll("[selected]").length ) {
- rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
- }
-
- // Webkit/Opera - :checked should return selected option elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- // IE8 throws error here (do not put tests after this one)
- if ( !div.querySelectorAll(":checked").length ) {
- rbuggyQSA.push(":checked");
- }
- });
-
- assert(function( div ) {
-
- // Opera 10-12/IE9 - ^= $= *= and empty values
- // Should not select anything
- div.innerHTML = "<p test=''></p>";
- if ( div.querySelectorAll("[test^='']").length ) {
- rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
- }
-
- // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
- // IE8 throws error here (do not put tests after this one)
- div.innerHTML = "<input type='hidden'>";
- if ( !div.querySelectorAll(":enabled").length ) {
- rbuggyQSA.push(":enabled", ":disabled");
- }
- });
-
- rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
-
- select = function( selector, context, results, seed, xml ) {
- // Only use querySelectorAll when not filtering,
- // when this is not xml,
- // and when no QSA bugs apply
- if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
- if ( context.nodeType === 9 ) {
- try {
- push.apply( results, slice.call(context.querySelectorAll( selector ), 0) );
- return results;
- } catch(qsaError) {}
- // qSA works strangely on Element-rooted queries
- // We can work around this by specifying an extra ID on the root
- // and working up from there (Thanks to Andrew Dupont for the technique)
- // IE 8 doesn't work on object elements
- } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
- var old = context.getAttribute("id"),
- nid = old || expando,
- newContext = rsibling.test( selector ) && context.parentNode || context;
-
- if ( old ) {
- nid = nid.replace( rescape, "\\$&" );
- } else {
- context.setAttribute( "id", nid );
- }
-
- try {
- push.apply( results, slice.call( newContext.querySelectorAll(
- selector.replace( rgroups, "[id='" + nid + "'] $&" )
- ), 0 ) );
- return results;
- } catch(qsaError) {
- } finally {
- if ( !old ) {
- context.removeAttribute("id");
- }
- }
- }
- }
-
- return oldSelect( selector, context, results, seed, xml );
- };
-
- if ( matches ) {
- assert(function( div ) {
- // Check to see if it's possible to do matchesSelector
- // on a disconnected node (IE 9)
- disconnectedMatch = matches.call( div, "div" );
-
- // This should fail with an exception
- // Gecko does not error, returns false instead
- try {
- matches.call( div, "[test!='']:sizzle" );
- rbuggyMatches.push( Expr.match.PSEUDO );
- } catch ( e ) {}
- });
-
- // rbuggyMatches always contains :active, so no need for a length check
- rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
-
- Sizzle.matchesSelector = function( elem, expr ) {
- // Make sure that attribute selectors are quoted
- expr = expr.replace( rattributeQuotes, "='$1']" );
-
- // rbuggyMatches always contains :active, so no need for an existence check
- if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) {
- try {
- var ret = matches.call( elem, expr );
-
- // IE 9's matchesSelector returns false on disconnected nodes
- if ( ret || disconnectedMatch ||
- // As well, disconnected nodes are said to be in a document
- // fragment in IE 9
- elem.document && elem.document.nodeType !== 11 ) {
- return ret;
- }
- } catch(e) {}
- }
-
- return Sizzle( expr, null, null, [ elem ] ).length > 0;
- };
- }
- })();
-}
-
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://sizzlejs.com/
+ */
+(function( window, undefined ) {
+
+var cachedruns,
+ dirruns,
+ sortOrder,
+ siblingCheck,
+ assertGetIdNotName,
+
+ document = window.document,
+ docElem = document.documentElement,
+
+ strundefined = "undefined",
+ hasDuplicate = false,
+ baseHasDuplicate = true,
+ done = 0,
+ slice = [].slice,
+ push = [].push,
+
+ expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
+
+ // Regex
+
+ // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+ whitespace = "[\\x20\\t\\r\\n\\f]",
+ // http://www.w3.org/TR/css3-syntax/#characters
+ characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
+
+ // Loosely modeled on CSS identifier characters
+ // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)
+ // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+ identifier = characterEncoding.replace( "w", "w#" ),
+
+ // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
+ operators = "([*^$|!~]?=)",
+ attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
+ "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
+ pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",
+ pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",
+ combinators = whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*",
+ groups = "(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|" + attributes + "|" + pseudos.replace( 2, 7 ) + "|[^\\\\(),])+",
+
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+ rcombinators = new RegExp( "^" + combinators ),
+
+ // All simple (non-comma) selectors, excluding insignifant trailing whitespace
+ rgroups = new RegExp( groups + "?(?=" + whitespace + "*,|$)", "g" ),
+
+ // A selector, or everything after leading whitespace
+ // Optionally followed in either case by a ")" for terminating sub-selectors
+ rselector = new RegExp( "^(?:(?!,)(?:(?:^|,)" + whitespace + "*" + groups + ")*?|" + whitespace + "*(.*?))(\\)|$)" ),
+
+ // All combinators and selector components (attribute test, tag, pseudo, etc.), the latter appearing together when consecutive
+ rtokens = new RegExp( groups.slice( 19, -6 ) + "\\x20\\t\\r\\n\\f>+~])+|" + combinators, "g" ),
+
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
+ rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
+
+ rsibling = /[\x20\t\r\n\f]*[+~]/,
+ rendsWithNot = /:not\($/,
+
+ rheader = /h\d/i,
+ rinputs = /input|select|textarea|button/i,
+
+ rbackslash = /\\(?!\\)/g,
+
+ matchExpr = {
+ "ID": new RegExp( "^#(" + characterEncoding + ")" ),
+ "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+ "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
+ "TAG": new RegExp( "^(" + characterEncoding.replace( "[-", "[-\\*" ) + ")" ),
+ "ATTR": new RegExp( "^" + attributes ),
+ "PSEUDO": new RegExp( "^" + pseudos ),
+ "CHILD": new RegExp( "^:(only|nth|last|first)-child(?:\\(" + whitespace +
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+ "POS": new RegExp( pos, "ig" ),
+ // For use in libraries implementing .is()
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
+ },
+
+ classCache = {},
+ cachedClasses = [],
+ compilerCache = {},
+ cachedSelectors = [],
+
+ // Mark a function for use in filtering
+ markFunction = function( fn ) {
+ fn.sizzleFilter = true;
+ return fn;
+ },
+
+ // Returns a function to use in pseudos for input types
+ createInputFunction = function( type ) {
+ return function( elem ) {
+ // Check the input's nodeName and type
+ return elem.nodeName.toLowerCase() === "input" && elem.type === type;
+ };
+ },
+
+ // Returns a function to use in pseudos for buttons
+ createButtonFunction = function( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && elem.type === type;
+ };
+ },
+
+ // Used for testing something on an element
+ assert = function( fn ) {
+ var pass = false,
+ div = document.createElement("div");
+ try {
+ pass = fn( div );
+ } catch (e) {}
+ // release memory in IE
+ div = null;
+ return pass;
+ },
+
+ // Check if attributes should be retrieved by attribute nodes
+ assertAttributes = assert(function( div ) {
+ div.innerHTML = "<select></select>";
+ var type = typeof div.lastChild.getAttribute("multiple");
+ // IE8 returns a string for some attributes even when not present
+ return type !== "boolean" && type !== "string";
+ }),
+
+ // Check if getElementById returns elements by name
+ // Check if getElementsByName privileges form controls or returns elements by ID
+ assertUsableName = assert(function( div ) {
+ // Inject content
+ div.id = expando + 0;
+ div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
+ docElem.insertBefore( div, docElem.firstChild );
+
+ // Test
+ var pass = document.getElementsByName &&
+ // buggy browsers will return fewer than the correct 2
+ document.getElementsByName( expando ).length ===
+ // buggy browsers will return more than the correct 0
+ 2 + document.getElementsByName( expando + 0 ).length;
+ assertGetIdNotName = !document.getElementById( expando );
+
+ // Cleanup
+ docElem.removeChild( div );
+
+ return pass;
+ }),
+
+ // Check if the browser returns only elements
+ // when doing getElementsByTagName("*")
+ assertTagNameNoComments = assert(function( div ) {
+ div.appendChild( document.createComment("") );
+ return div.getElementsByTagName("*").length === 0;
+ }),
+
+ // Check if getAttribute returns normalized href attributes
+ assertHrefNotNormalized = assert(function( div ) {
+ div.innerHTML = "<a href='#'></a>";
+ return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
+ div.firstChild.getAttribute("href") === "#";
+ }),
+
+ // Check if getElementsByClassName can be trusted
+ assertUsableClassName = assert(function( div ) {
+ // Opera can't find a second classname (in 9.6)
+ div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
+ if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+ return false;
+ }
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+ return div.getElementsByClassName("e").length !== 1;
+ });
+
+var Sizzle = function( selector, context, results, seed ) {
+ results = results || [];
+ context = context || document;
+ var match, elem, xml, m,
+ nodeType = context.nodeType;
+
+ if ( nodeType !== 1 && nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ xml = isXML( context );
+
+ if ( !xml && !seed ) {
+ if ( (match = rquickExpr.exec( selector )) ) {
+ // Speed-up: Sizzle("#ID")
+ if ( (m = match[1]) ) {
+ if ( nodeType === 9 ) {
+ elem = context.getElementById( m );
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE, Opera, and Webkit return items
+ // by name instead of ID
+ if ( elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ } else {
+ return results;
+ }
+ } else {
+ // Context is not a document
+ if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
+ contains( context, elem ) && elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ }
+
+ // Speed-up: Sizzle("TAG")
+ } else if ( match[2] ) {
+ push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
+ return results;
+
+ // Speed-up: Sizzle(".CLASS")
+ } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
+ push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
+ return results;
+ }
+ }
+ }
+
+ // All others
+ return select( selector, context, results, seed, xml );
+};
+
+var Expr = Sizzle.selectors = {
+
+ // Can be adjusted by the user
+ cacheLength: 50,
+
+ match: matchExpr,
+
+ order: [ "ID", "TAG" ],
+
+ attrHandle: {},
+
+ createPseudo: markFunction,
+
+ find: {
+ "ID": assertGetIdNotName ?
+ function( id, context, xml ) {
+ if ( typeof context.getElementById !== strundefined && !xml ) {
+ var m = context.getElementById( id );
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ return m && m.parentNode ? [m] : [];
+ }
+ } :
+ function( id, context, xml ) {
+ if ( typeof context.getElementById !== strundefined && !xml ) {
+ var m = context.getElementById( id );
+
+ return m ?
+ m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
+ [m] :
+ undefined :
+ [];
+ }
+ },
+
+ "TAG": assertTagNameNoComments ?
+ function( tag, context ) {
+ if ( typeof context.getElementsByTagName !== strundefined ) {
+ return context.getElementsByTagName( tag );
+ }
+ } :
+ function( tag, context ) {
+ var results = context.getElementsByTagName( tag );
+
+ // Filter out possible comments
+ if ( tag === "*" ) {
+ var elem,
+ tmp = [],
+ i = 0;
+
+ for ( ; (elem = results[i]); i++ ) {
+ if ( elem.nodeType === 1 ) {
+ tmp.push( elem );
+ }
+ }
+
+ return tmp;
+ }
+ return results;
+ }
+ },
+
+ relative: {
+ ">": { dir: "parentNode", first: true },
+ " ": { dir: "parentNode" },
+ "+": { dir: "previousSibling", first: true },
+ "~": { dir: "previousSibling" }
+ },
+
+ preFilter: {
+ "ATTR": function( match ) {
+ match[1] = match[1].replace( rbackslash, "" );
+
+ // Move the given value to match[3] whether quoted or unquoted
+ match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
+
+ if ( match[2] === "~=" ) {
+ match[3] = " " + match[3] + " ";
+ }
+
+ return match.slice( 0, 4 );
+ },
+
+ "CHILD": function( match ) {
+ /* matches from matchExpr.CHILD
+ 1 type (only|nth|...)
+ 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+ 3 xn-component of xn+y argument ([+-]?\d*n|)
+ 4 sign of xn-component
+ 5 x of xn-component
+ 6 sign of y-component
+ 7 y of y-component
+ */
+ match[1] = match[1].toLowerCase();
+
+ if ( match[1] === "nth" ) {
+ // nth-child requires argument
+ if ( !match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // numeric x and y parameters for Expr.filter.CHILD
+ // remember that false/true cast respectively to 0/1
+ match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
+ match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
+
+ // other types prohibit arguments
+ } else if ( match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ return match;
+ },
+
+ "PSEUDO": function( match ) {
+ var argument,
+ unquoted = match[4];
+
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
+ return null;
+ }
+
+ // Relinquish our claim on characters in `unquoted` from a closing parenthesis on
+ if ( unquoted && (argument = rselector.exec( unquoted )) && argument.pop() ) {
+
+ match[0] = match[0].slice( 0, argument[0].length - unquoted.length - 1 );
+ unquoted = argument[0].slice( 0, -1 );
+ }
+
+ // Quoted or unquoted, we have the full argument
+ // Return only captures needed by the pseudo filter method (type and argument)
+ match.splice( 2, 3, unquoted || match[3] );
+ return match;
+ }
+ },
+
+ filter: {
+ "ID": assertGetIdNotName ?
+ function( id ) {
+ id = id.replace( rbackslash, "" );
+ return function( elem ) {
+ return elem.getAttribute("id") === id;
+ };
+ } :
+ function( id ) {
+ id = id.replace( rbackslash, "" );
+ return function( elem ) {
+ var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+ return node && node.value === id;
+ };
+ },
+
+ "TAG": function( nodeName ) {
+ if ( nodeName === "*" ) {
+ return function() { return true; };
+ }
+ nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
+
+ return function( elem ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+ };
+ },
+
+ "CLASS": function( className ) {
+ var pattern = classCache[ className ];
+ if ( !pattern ) {
+ pattern = classCache[ className ] = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" );
+ cachedClasses.push( className );
+ // Avoid too large of a cache
+ if ( cachedClasses.length > Expr.cacheLength ) {
+ delete classCache[ cachedClasses.shift() ];
+ }
+ }
+ return function( elem ) {
+ return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
+ };
+ },
+
+ "ATTR": function( name, operator, check ) {
+ if ( !operator ) {
+ return function( elem ) {
+ return Sizzle.attr( elem, name ) != null;
+ };
+ }
+
+ return function( elem ) {
+ var result = Sizzle.attr( elem, name ),
+ value = result + "";
+
+ if ( result == null ) {
+ return operator === "!=";
+ }
+
+ switch ( operator ) {
+ case "=":
+ return value === check;
+ case "!=":
+ return value !== check;
+ case "^=":
+ return check && value.indexOf( check ) === 0;
+ case "*=":
+ return check && value.indexOf( check ) > -1;
+ case "$=":
+ return check && value.substr( value.length - check.length ) === check;
+ case "~=":
+ return ( " " + value + " " ).indexOf( check ) > -1;
+ case "|=":
+ return value === check || value.substr( 0, check.length + 1 ) === check + "-";
+ }
+ };
+ },
+
+ "CHILD": function( type, argument, first, last ) {
+
+ if ( type === "nth" ) {
+ var doneName = done++;
+
+ return function( elem ) {
+ var parent, diff,
+ count = 0,
+ node = elem;
+
+ if ( first === 1 && last === 0 ) {
+ return true;
+ }
+
+ parent = elem.parentNode;
+
+ if ( parent && (parent[ expando ] !== doneName || !elem.sizset) ) {
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.sizset = ++count;
+ if ( node === elem ) {
+ break;
+ }
+ }
+ }
+
+ parent[ expando ] = doneName;
+ }
+
+ diff = elem.sizset - last;
+
+ if ( first === 0 ) {
+ return diff === 0;
+
+ } else {
+ return ( diff % first === 0 && diff / first >= 0 );
+ }
+ };
+ }
+
+ return function( elem ) {
+ var node = elem;
+
+ switch ( type ) {
+ case "only":
+ case "first":
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ if ( type === "first" ) {
+ return true;
+ }
+
+ node = elem;
+
+ /* falls through */
+ case "last":
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ };
+ },
+
+ "PSEUDO": function( pseudo, argument, context, xml ) {
+ // pseudo-class names are case-insensitive
+ // http://www.w3.org/TR/selectors/#pseudo-classes
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+ var fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ];
+
+ if ( !fn ) {
+ Sizzle.error( "unsupported pseudo: " + pseudo );
+ }
+
+ // The user may set fn.sizzleFilter to indicate
+ // that arguments are needed to create the filter function
+ // just as Sizzle does
+ if ( !fn.sizzleFilter ) {
+ return fn;
+ }
+
+ return fn( argument, context, xml );
+ }
+ },
+
+ pseudos: {
+ "not": markFunction(function( selector, context, xml ) {
+ // Trim the selector passed to compile
+ // to avoid treating leading and trailing
+ // spaces as combinators
+ var matcher = compile( selector.replace( rtrim, "$1" ), context, xml );
+ return function( elem ) {
+ return !matcher( elem );
+ };
+ }),
+
+ "enabled": function( elem ) {
+ return elem.disabled === false;
+ },
+
+ "disabled": function( elem ) {
+ return elem.disabled === true;
+ },
+
+ "checked": function( elem ) {
+ // In CSS3, :checked should return both checked and selected elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ var nodeName = elem.nodeName.toLowerCase();
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+ },
+
+ "selected": function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ "parent": function( elem ) {
+ return !Expr.pseudos["empty"]( elem );
+ },
+
+ "empty": function( elem ) {
+ // http://www.w3.org/TR/selectors/#empty-pseudo
+ // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
+ // not comment, processing instructions, or others
+ // Thanks to Diego Perini for the nodeName shortcut
+ // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
+ var nodeType;
+ elem = elem.firstChild;
+ while ( elem ) {
+ if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
+ return false;
+ }
+ elem = elem.nextSibling;
+ }
+ return true;
+ },
+
+ "contains": markFunction(function( text ) {
+ return function( elem ) {
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+ };
+ }),
+
+ "has": markFunction(function( selector ) {
+ return function( elem ) {
+ return Sizzle( selector, elem ).length > 0;
+ };
+ }),
+
+ "header": function( elem ) {
+ return rheader.test( elem.nodeName );
+ },
+
+ "text": function( elem ) {
+ var type, attr;
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // use getAttribute instead to test this case
+ return elem.nodeName.toLowerCase() === "input" &&
+ (type = elem.type) === "text" &&
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
+ },
+
+ // Input types
+ "radio": createInputFunction("radio"),
+ "checkbox": createInputFunction("checkbox"),
+ "file": createInputFunction("file"),
+ "password": createInputFunction("password"),
+ "image": createInputFunction("image"),
+
+ "submit": createButtonFunction("submit"),
+ "reset": createButtonFunction("reset"),
+
+ "button": function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === "button" || name === "button";
+ },
+
+ "input": function( elem ) {
+ return rinputs.test( elem.nodeName );
+ },
+
+ "focus": function( elem ) {
+ var doc = elem.ownerDocument;
+ return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href);
+ },
+
+ "active": function( elem ) {
+ return elem === elem.ownerDocument.activeElement;
+ }
+ },
+
+ setFilters: {
+ "first": function( elements, argument, not ) {
+ return not ? elements.slice( 1 ) : [ elements[0] ];
+ },
+
+ "last": function( elements, argument, not ) {
+ var elem = elements.pop();
+ return not ? elements : [ elem ];
+ },
+
+ "even": function( elements, argument, not ) {
+ var results = [],
+ i = not ? 1 : 0,
+ len = elements.length;
+ for ( ; i < len; i = i + 2 ) {
+ results.push( elements[i] );
+ }
+ return results;
+ },
+
+ "odd": function( elements, argument, not ) {
+ var results = [],
+ i = not ? 0 : 1,
+ len = elements.length;
+ for ( ; i < len; i = i + 2 ) {
+ results.push( elements[i] );
+ }
+ return results;
+ },
+
+ "lt": function( elements, argument, not ) {
+ return not ? elements.slice( +argument ) : elements.slice( 0, +argument );
+ },
+
+ "gt": function( elements, argument, not ) {
+ return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 );
+ },
+
+ "eq": function( elements, argument, not ) {
+ var elem = elements.splice( +argument, 1 );
+ return not ? elements : elem;
+ }
+ }
+};
+
+// Deprecated
+Expr.setFilters["nth"] = Expr.setFilters["eq"];
+
+// Back-compat
+Expr.filters = Expr.pseudos;
+
+// IE6/7 return a modified href
+if ( !assertHrefNotNormalized ) {
+ Expr.attrHandle = {
+ "href": function( elem ) {
+ return elem.getAttribute( "href", 2 );
+ },
+ "type": function( elem ) {
+ return elem.getAttribute("type");
+ }
+ };
+}
+
+// Add getElementsByName if usable
+if ( assertUsableName ) {
+ Expr.order.push("NAME");
+ Expr.find["NAME"] = function( name, context ) {
+ if ( typeof context.getElementsByName !== strundefined ) {
+ return context.getElementsByName( name );
+ }
+ };
+}
+
+// Add getElementsByClassName if usable
+if ( assertUsableClassName ) {
+ Expr.order.splice( 1, 0, "CLASS" );
+ Expr.find["CLASS"] = function( className, context, xml ) {
+ if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
+ return context.getElementsByClassName( className );
+ }
+ };
+}
+
+// If slice is not available, provide a backup
+try {
+ slice.call( docElem.childNodes, 0 )[0].nodeType;
+} catch ( e ) {
+ slice = function( i ) {
+ var elem, results = [];
+ for ( ; (elem = this[i]); i++ ) {
+ results.push( elem );
+ }
+ return results;
+ };
+}
+
+var isXML = Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+// Element contains another
+var contains = Sizzle.contains = docElem.compareDocumentPosition ?
+ function( a, b ) {
+ return !!( a.compareDocumentPosition( b ) & 16 );
+ } :
+ docElem.contains ?
+ function( a, b ) {
+ var adown = a.nodeType === 9 ? a.documentElement : a,
+ bup = b.parentNode;
+ return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
+ } :
+ function( a, b ) {
+ while ( (b = b.parentNode) ) {
+ if ( b === a ) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+var getText = Sizzle.getText = function( elem ) {
+ var node,
+ ret = "",
+ i = 0,
+ nodeType = elem.nodeType;
+
+ if ( nodeType ) {
+ if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+ // Use textContent for elements
+ // innerText usage removed for consistency of new lines (see #11153)
+ if ( typeof elem.textContent === "string" ) {
+ return elem.textContent;
+ } else {
+ // Traverse its children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ ret += getText( elem );
+ }
+ }
+ } else if ( nodeType === 3 || nodeType === 4 ) {
+ return elem.nodeValue;
+ }
+ // Do not include comment or processing instruction nodes
+ } else {
+
+ // If no nodeType, this is expected to be an array
+ for ( ; (node = elem[i]); i++ ) {
+ // Do not traverse comment nodes
+ ret += getText( node );
+ }
+ }
+ return ret;
+};
+
+Sizzle.attr = function( elem, name ) {
+ var attr,
+ xml = isXML( elem );
+
+ if ( !xml ) {
+ name = name.toLowerCase();
+ }
+ if ( Expr.attrHandle[ name ] ) {
+ return Expr.attrHandle[ name ]( elem );
+ }
+ if ( assertAttributes || xml ) {
+ return elem.getAttribute( name );
+ }
+ attr = elem.getAttributeNode( name );
+ return attr ?
+ typeof elem[ name ] === "boolean" ?
+ elem[ name ] ? name : null :
+ attr.specified ? attr.value : null :
+ null;
+};
+
+Sizzle.error = function( msg ) {
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+// Check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+// Thus far that includes Google Chrome.
+[0, 0].sort(function() {
+ return (baseHasDuplicate = 0);
+});
+
+
+if ( docElem.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
+ a.compareDocumentPosition :
+ a.compareDocumentPosition(b) & 4
+ ) ? -1 : 1;
+ };
+
+} else {
+ sortOrder = function( a, b ) {
+ // The nodes are identical, we can exit early
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+
+ // Fallback to using sourceIndex (in IE) if it's available on both nodes
+ } else if ( a.sourceIndex && b.sourceIndex ) {
+ return a.sourceIndex - b.sourceIndex;
+ }
+
+ var al, bl,
+ ap = [],
+ bp = [],
+ aup = a.parentNode,
+ bup = b.parentNode,
+ cur = aup;
+
+ // If the nodes are siblings (or identical) we can do a quick check
+ if ( aup === bup ) {
+ return siblingCheck( a, b );
+
+ // If no parents were found then the nodes are disconnected
+ } else if ( !aup ) {
+ return -1;
+
+ } else if ( !bup ) {
+ return 1;
+ }
+
+ // Otherwise they're somewhere else in the tree so we need
+ // to build up a full list of the parentNodes for comparison
+ while ( cur ) {
+ ap.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ cur = bup;
+
+ while ( cur ) {
+ bp.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ al = ap.length;
+ bl = bp.length;
+
+ // Start walking down the tree looking for a discrepancy
+ for ( var i = 0; i < al && i < bl; i++ ) {
+ if ( ap[i] !== bp[i] ) {
+ return siblingCheck( ap[i], bp[i] );
+ }
+ }
+
+ // We ended someplace up the tree so do a sibling check
+ return i === al ?
+ siblingCheck( a, bp[i], -1 ) :
+ siblingCheck( ap[i], b, 1 );
+ };
+
+ siblingCheck = function( a, b, ret ) {
+ if ( a === b ) {
+ return ret;
+ }
+
+ var cur = a.nextSibling;
+
+ while ( cur ) {
+ if ( cur === b ) {
+ return -1;
+ }
+
+ cur = cur.nextSibling;
+ }
+
+ return 1;
+ };
+}
+
+// Document sorting and removing duplicates
+Sizzle.uniqueSort = function( results ) {
+ var elem,
+ i = 1;
+
+ if ( sortOrder ) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ for ( ; (elem = results[i]); i++ ) {
+ if ( elem === results[ i - 1 ] ) {
+ results.splice( i--, 1 );
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+function multipleContexts( selector, contexts, results, seed ) {
+ var i = 0,
+ len = contexts.length;
+ for ( ; i < len; i++ ) {
+ Sizzle( selector, contexts[i], results, seed );
+ }
+}
+
+function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) {
+ var results,
+ fn = Expr.setFilters[ posfilter.toLowerCase() ];
+
+ if ( !fn ) {
+ Sizzle.error( posfilter );
+ }
+
+ if ( selector || !(results = seed) ) {
+ multipleContexts( selector || "*", contexts, (results = []), seed );
+ }
+
+ return results.length > 0 ? fn( results, argument, not ) : [];
+}
+
+function handlePOS( selector, context, results, seed, groups ) {
+ var match, not, anchor, ret, elements, currentContexts, part, lastIndex,
+ i = 0,
+ len = groups.length,
+ rpos = matchExpr["POS"],
+ // This is generated here in case matchExpr["POS"] is extended
+ rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ),
+ // This is for making sure non-participating
+ // matching groups are represented cross-browser (IE6-8)
+ setUndefined = function() {
+ var i = 1,
+ len = arguments.length - 2;
+ for ( ; i < len; i++ ) {
+ if ( arguments[i] === undefined ) {
+ match[i] = undefined;
+ }
+ }
+ };
+
+ for ( ; i < len; i++ ) {
+ // Reset regex index to 0
+ rpos.exec("");
+ selector = groups[i];
+ ret = [];
+ anchor = 0;
+ elements = seed;
+ while ( (match = rpos.exec( selector )) ) {
+ lastIndex = rpos.lastIndex = match.index + match[0].length;
+ if ( lastIndex > anchor ) {
+ part = selector.slice( anchor, match.index );
+ anchor = lastIndex;
+ currentContexts = [ context ];
+
+ if ( rcombinators.test(part) ) {
+ if ( elements ) {
+ currentContexts = elements;
+ }
+ elements = seed;
+ }
+
+ if ( (not = rendsWithNot.test( part )) ) {
+ part = part.slice( 0, -5 ).replace( rcombinators, "$&*" );
+ }
+
+ if ( match.length > 1 ) {
+ match[0].replace( rposgroups, setUndefined );
+ }
+ elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not );
+ }
+ }
+
+ if ( elements ) {
+ ret = ret.concat( elements );
+
+ if ( (part = selector.slice( anchor )) && part !== ")" ) {
+ if ( rcombinators.test(part) ) {
+ multipleContexts( part, ret, results, seed );
+ } else {
+ Sizzle( part, context, results, seed ? seed.concat(elements) : elements );
+ }
+ } else {
+ push.apply( results, ret );
+ }
+ } else {
+ Sizzle( selector, context, results, seed );
+ }
+ }
+
+ // Do not sort if this is a single filter
+ return len === 1 ? results : Sizzle.uniqueSort( results );
+}
+
+function tokenize( selector, context, xml ) {
+ var tokens, soFar, type,
+ groups = [],
+ i = 0,
+
+ // Catch obvious selector issues: terminal ")"; nonempty fallback match
+ // rselector never fails to match *something*
+ match = rselector.exec( selector ),
+ matched = !match.pop() && !match.pop(),
+ selectorGroups = matched && selector.match( rgroups ) || [""],
+
+ preFilters = Expr.preFilter,
+ filters = Expr.filter,
+ checkContext = !xml && context !== document;
+
+ for ( ; (soFar = selectorGroups[i]) != null && matched; i++ ) {
+ groups.push( tokens = [] );
+
+ // Need to make sure we're within a narrower context if necessary
+ // Adding a descendant combinator will generate what is needed
+ if ( checkContext ) {
+ soFar = " " + soFar;
+ }
+
+ while ( soFar ) {
+ matched = false;
+
+ // Combinators
+ if ( (match = rcombinators.exec( soFar )) ) {
+ soFar = soFar.slice( match[0].length );
+
+ // Cast descendant combinators to space
+ matched = tokens.push({ part: match.pop().replace( rtrim, " " ), captures: match });
+ }
+
+ // Filters
+ for ( type in filters ) {
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+ (match = preFilters[ type ]( match, context, xml )) ) ) {
+
+ soFar = soFar.slice( match.shift().length );
+ matched = tokens.push({ part: type, captures: match });
+ }
+ }
+
+ if ( !matched ) {
+ break;
+ }
+ }
+ }
+
+ if ( !matched ) {
+ Sizzle.error( selector );
+ }
+
+ return groups;
+}
+
+function addCombinator( matcher, combinator, context ) {
+ var dir = combinator.dir,
+ doneName = done++;
+
+ if ( !matcher ) {
+ // If there is no matcher to check, check against the context
+ matcher = function( elem ) {
+ return elem === context;
+ };
+ }
+ return combinator.first ?
+ function( elem, context ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 ) {
+ return matcher( elem, context ) && elem;
+ }
+ }
+ } :
+ function( elem, context ) {
+ var cache,
+ dirkey = doneName + "." + dirruns,
+ cachedkey = dirkey + "." + cachedruns;
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 ) {
+ if ( (cache = elem[ expando ]) === cachedkey ) {
+ return elem.sizset;
+ } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
+ if ( elem.sizset ) {
+ return elem;
+ }
+ } else {
+ elem[ expando ] = cachedkey;
+ if ( matcher( elem, context ) ) {
+ elem.sizset = true;
+ return elem;
+ }
+ elem.sizset = false;
+ }
+ }
+ }
+ };
+}
+
+function addMatcher( higher, deeper ) {
+ return higher ?
+ function( elem, context ) {
+ var result = deeper( elem, context );
+ return result && higher( result === true ? elem : result, context );
+ } :
+ deeper;
+}
+
+// ["TAG", ">", "ID", " ", "CLASS"]
+function matcherFromTokens( tokens, context, xml ) {
+ var token, matcher,
+ i = 0;
+
+ for ( ; (token = tokens[i]); i++ ) {
+ if ( Expr.relative[ token.part ] ) {
+ matcher = addCombinator( matcher, Expr.relative[ token.part ], context );
+ } else {
+ token.captures.push( context, xml );
+ matcher = addMatcher( matcher, Expr.filter[ token.part ].apply( null, token.captures ) );
+ }
+ }
+
+ return matcher;
+}
+
+function matcherFromGroupMatchers( matchers ) {
+ return function( elem, context ) {
+ var matcher,
+ j = 0;
+ for ( ; (matcher = matchers[j]); j++ ) {
+ if ( matcher(elem, context) ) {
+ return true;
+ }
+ }
+ return false;
+ };
+}
+
+var compile = Sizzle.compile = function( selector, context, xml ) {
+ var tokens, group, i,
+ cached = compilerCache[ selector ];
+
+ // Return a cached group function if already generated (context dependent)
+ if ( cached && cached.context === context ) {
+ return cached;
+ }
+
+ // Generate a function of recursive functions that can be used to check each element
+ group = tokenize( selector, context, xml );
+ for ( i = 0; (tokens = group[i]); i++ ) {
+ group[i] = matcherFromTokens( tokens, context, xml );
+ }
+
+ // Cache the compiled function
+ cached = compilerCache[ selector ] = matcherFromGroupMatchers( group );
+ cached.context = context;
+ cached.runs = cached.dirruns = 0;
+ cachedSelectors.push( selector );
+ // Ensure only the most recent are cached
+ if ( cachedSelectors.length > Expr.cacheLength ) {
+ delete compilerCache[ cachedSelectors.shift() ];
+ }
+ return cached;
+};
+
+Sizzle.matches = function( expr, elements ) {
+ return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+ return Sizzle( expr, null, null, [ elem ] ).length > 0;
+};
+
+var select = function( selector, context, results, seed, xml ) {
+ // Remove excessive whitespace
+ selector = selector.replace( rtrim, "$1" );
+ var elements, matcher, i, len, elem, token,
+ type, findContext, notTokens,
+ match = selector.match( rgroups ),
+ tokens = selector.match( rtokens ),
+ contextNodeType = context.nodeType;
+
+ // POS handling
+ if ( matchExpr["POS"].test(selector) ) {
+ return handlePOS( selector, context, results, seed, match );
+ }
+
+ if ( seed ) {
+ elements = slice.call( seed, 0 );
+
+ // To maintain document order, only narrow the
+ // set if there is one group
+ } else if ( match && match.length === 1 ) {
+
+ // Take a shortcut and set the context if the root selector is an ID
+ if ( tokens.length > 1 && contextNodeType === 9 && !xml &&
+ (match = matchExpr["ID"].exec( tokens[0] )) ) {
+
+ context = Expr.find["ID"]( match[1], context, xml )[0];
+ if ( !context ) {
+ return results;
+ }
+
+ selector = selector.slice( tokens.shift().length );
+ }
+
+ findContext = ( (match = rsibling.exec( tokens[0] )) && !match.index && context.parentNode ) || context;
+
+ // Get the last token, excluding :not
+ notTokens = tokens.pop();
+ token = notTokens.split(":not")[0];
+
+ for ( i = 0, len = Expr.order.length; i < len; i++ ) {
+ type = Expr.order[i];
+
+ if ( (match = matchExpr[ type ].exec( token )) ) {
+ elements = Expr.find[ type ]( (match[1] || "").replace( rbackslash, "" ), findContext, xml );
+
+ if ( elements == null ) {
+ continue;
+ }
+
+ if ( token === notTokens ) {
+ selector = selector.slice( 0, selector.length - notTokens.length ) +
+ token.replace( matchExpr[ type ], "" );
+
+ if ( !selector ) {
+ push.apply( results, slice.call(elements, 0) );
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ // Only loop over the given elements once
+ // If selector is empty, we're already done
+ if ( selector ) {
+ matcher = compile( selector, context, xml );
+ dirruns = matcher.dirruns++;
+
+ if ( elements == null ) {
+ elements = Expr.find["TAG"]( "*", (rsibling.test( selector ) && context.parentNode) || context );
+ }
+ for ( i = 0; (elem = elements[i]); i++ ) {
+ cachedruns = matcher.runs++;
+ if ( matcher(elem, context) ) {
+ results.push( elem );
+ }
+ }
+ }
+
+ return results;
+};
+
+if ( document.querySelectorAll ) {
+ (function() {
+ var disconnectedMatch,
+ oldSelect = select,
+ rescape = /'|\\/g,
+ rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
+ rbuggyQSA = [],
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+ // A support test would require too much code (would include document ready)
+ // just skip matchesSelector for :active
+ rbuggyMatches = [":active"],
+ matches = docElem.matchesSelector ||
+ docElem.mozMatchesSelector ||
+ docElem.webkitMatchesSelector ||
+ docElem.oMatchesSelector ||
+ docElem.msMatchesSelector;
+
+ // Build QSA regex
+ // Regex strategy adopted from Diego Perini
+ assert(function( div ) {
+ div.innerHTML = "<select><option selected></option></select>";
+
+ // IE8 - Some boolean attributes are not treated correctly
+ if ( !div.querySelectorAll("[selected]").length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
+ }
+
+ // Webkit/Opera - :checked should return selected option elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ // IE8 throws error here (do not put tests after this one)
+ if ( !div.querySelectorAll(":checked").length ) {
+ rbuggyQSA.push(":checked");
+ }
+ });
+
+ assert(function( div ) {
+
+ // Opera 10-12/IE9 - ^= $= *= and empty values
+ // Should not select anything
+ div.innerHTML = "<p test=''></p>";
+ if ( div.querySelectorAll("[test^='']").length ) {
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
+ }
+
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+ // IE8 throws error here (do not put tests after this one)
+ div.innerHTML = "<input type='hidden'>";
+ if ( !div.querySelectorAll(":enabled").length ) {
+ rbuggyQSA.push(":enabled", ":disabled");
+ }
+ });
+
+ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+
+ select = function( selector, context, results, seed, xml ) {
+ // Only use querySelectorAll when not filtering,
+ // when this is not xml,
+ // and when no QSA bugs apply
+ if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+ if ( context.nodeType === 9 ) {
+ try {
+ push.apply( results, slice.call(context.querySelectorAll( selector ), 0) );
+ return results;
+ } catch(qsaError) {}
+ // qSA works strangely on Element-rooted queries
+ // We can work around this by specifying an extra ID on the root
+ // and working up from there (Thanks to Andrew Dupont for the technique)
+ // IE 8 doesn't work on object elements
+ } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+ var old = context.getAttribute("id"),
+ nid = old || expando,
+ newContext = rsibling.test( selector ) && context.parentNode || context;
+
+ if ( old ) {
+ nid = nid.replace( rescape, "\\$&" );
+ } else {
+ context.setAttribute( "id", nid );
+ }
+
+ try {
+ push.apply( results, slice.call( newContext.querySelectorAll(
+ selector.replace( rgroups, "[id='" + nid + "'] $&" )
+ ), 0 ) );
+ return results;
+ } catch(qsaError) {
+ } finally {
+ if ( !old ) {
+ context.removeAttribute("id");
+ }
+ }
+ }
+ }
+
+ return oldSelect( selector, context, results, seed, xml );
+ };
+
+ if ( matches ) {
+ assert(function( div ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9)
+ disconnectedMatch = matches.call( div, "div" );
+
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ try {
+ matches.call( div, "[test!='']:sizzle" );
+ rbuggyMatches.push( Expr.match.PSEUDO );
+ } catch ( e ) {}
+ });
+
+ // rbuggyMatches always contains :active, so no need for a length check
+ rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
+
+ Sizzle.matchesSelector = function( elem, expr ) {
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace( rattributeQuotes, "='$1']" );
+
+ // rbuggyMatches always contains :active, so no need for an existence check
+ if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) {
+ try {
+ var ret = matches.call( elem, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9
+ elem.document && elem.document.nodeType !== 11 ) {
+ return ret;
+ }
+ } catch(e) {}
+ }
+
+ return Sizzle( expr, null, null, [ elem ] ).length > 0;
+ };
+ }
+ })();
+}
+
// Override sizzle attribute retrieval
Sizzle.attr = jQuery.attr;
jQuery.find = Sizzle;
@@ -5134,9 +5134,9 @@ jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;
-
-
-})( window );
+
+
+})( window );
var runtil = /Until$/,
rparentsprev = /^(?:parents|prev(?:Until|All))/,
isSimple = /^.[^:#\[\.,]*$/,
@@ -6322,7 +6322,7 @@ jQuery.sub = function() {
var rootjQuerySub = jQuerySub(document);
return jQuerySub;
};
-
+
})();
var curCSS, iframe, iframeDoc,
ralpha = /alpha\([^)]*\)/i,
diff --git a/tests/jquery-1.8.1.js b/tests/jquery-1.8.1.js
index 973ef3d9a..f6cb2a6fb 100644
--- a/tests/jquery-1.8.1.js
+++ b/tests/jquery-1.8.1.js
@@ -3662,1532 +3662,1532 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
}
});
-/*!
- * Sizzle CSS Selector Engine
- * Copyright 2012 jQuery Foundation and other contributors
- * Released under the MIT license
- * http://sizzlejs.com/
- */
-(function( window, undefined ) {
-
-var dirruns,
- cachedruns,
- assertGetIdNotName,
- Expr,
- getText,
- isXML,
- contains,
- compile,
- sortOrder,
- hasDuplicate,
-
- baseHasDuplicate = true,
- strundefined = "undefined",
-
- expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
-
- document = window.document,
- docElem = document.documentElement,
- done = 0,
- slice = [].slice,
- push = [].push,
-
- // Augment a function for special use by Sizzle
- markFunction = function( fn, value ) {
- fn[ expando ] = value || true;
- return fn;
- },
-
- createCache = function() {
- var cache = {},
- keys = [];
-
- return markFunction(function( key, value ) {
- // Only keep the most recent entries
- if ( keys.push( key ) > Expr.cacheLength ) {
- delete cache[ keys.shift() ];
- }
-
- return (cache[ key ] = value);
- }, cache );
- },
-
- classCache = createCache(),
- tokenCache = createCache(),
- compilerCache = createCache(),
-
- // Regex
-
- // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
- whitespace = "[\\x20\\t\\r\\n\\f]",
- // http://www.w3.org/TR/css3-syntax/#characters
- characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
-
- // Loosely modeled on CSS identifier characters
- // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)
- // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
- identifier = characterEncoding.replace( "w", "w#" ),
-
- // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
- operators = "([*^$|!~]?=)",
- attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
- "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
-
- // Prefer arguments not in parens/brackets,
- // then attribute selectors and non-pseudos (denoted by :),
- // then anything else
- // These preferences are here to reduce the number of selectors
- // needing tokenize in the PSEUDO preFilter
- pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",
-
- // For matchExpr.POS and matchExpr.needsContext
- pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\(((?:-\\d)?\\d*)\\)|)(?=[^-]|$)",
-
- // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
- rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
-
- rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
- rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
- rpseudo = new RegExp( pseudos ),
-
- // Easily-parseable/retrievable ID or TAG or CLASS selectors
- rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
-
- rnot = /^:not/,
- rsibling = /[\x20\t\r\n\f]*[+~]/,
- rendsWithNot = /:not\($/,
-
- rheader = /h\d/i,
- rinputs = /input|select|textarea|button/i,
-
- rbackslash = /\\(?!\\)/g,
-
- matchExpr = {
- "ID": new RegExp( "^#(" + characterEncoding + ")" ),
- "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
- "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
- "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
- "ATTR": new RegExp( "^" + attributes ),
- "PSEUDO": new RegExp( "^" + pseudos ),
- "CHILD": new RegExp( "^:(only|nth|last|first)-child(?:\\(" + whitespace +
- "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
- "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
- "POS": new RegExp( pos, "ig" ),
- // For use in libraries implementing .is()
- "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
- },
-
- // Support
-
- // Used for testing something on an element
- assert = function( fn ) {
- var div = document.createElement("div");
-
- try {
- return fn( div );
- } catch (e) {
- return false;
- } finally {
- // release memory in IE
- div = null;
- }
- },
-
- // Check if getElementsByTagName("*") returns only elements
- assertTagNameNoComments = assert(function( div ) {
- div.appendChild( document.createComment("") );
- return !div.getElementsByTagName("*").length;
- }),
-
- // Check if getAttribute returns normalized href attributes
- assertHrefNotNormalized = assert(function( div ) {
- div.innerHTML = "<a href='#'></a>";
- return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
- div.firstChild.getAttribute("href") === "#";
- }),
-
- // Check if attributes should be retrieved by attribute nodes
- assertAttributes = assert(function( div ) {
- div.innerHTML = "<select></select>";
- var type = typeof div.lastChild.getAttribute("multiple");
- // IE8 returns a string for some attributes even when not present
- return type !== "boolean" && type !== "string";
- }),
-
- // Check if getElementsByClassName can be trusted
- assertUsableClassName = assert(function( div ) {
- // Opera can't find a second classname (in 9.6)
- div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
- if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
- return false;
- }
-
- // Safari 3.2 caches class attributes and doesn't catch changes
- div.lastChild.className = "e";
- return div.getElementsByClassName("e").length === 2;
- }),
-
- // Check if getElementById returns elements by name
- // Check if getElementsByName privileges form controls or returns elements by ID
- assertUsableName = assert(function( div ) {
- // Inject content
- div.id = expando + 0;
- div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
- docElem.insertBefore( div, docElem.firstChild );
-
- // Test
- var pass = document.getElementsByName &&
- // buggy browsers will return fewer than the correct 2
- document.getElementsByName( expando ).length === 2 +
- // buggy browsers will return more than the correct 0
- document.getElementsByName( expando + 0 ).length;
- assertGetIdNotName = !document.getElementById( expando );
-
- // Cleanup
- docElem.removeChild( div );
-
- return pass;
- });
-
-// If slice is not available, provide a backup
-try {
- slice.call( docElem.childNodes, 0 )[0].nodeType;
-} catch ( e ) {
- slice = function( i ) {
- var elem, results = [];
- for ( ; (elem = this[i]); i++ ) {
- results.push( elem );
- }
- return results;
- };
-}
-
-function Sizzle( selector, context, results, seed ) {
- results = results || [];
- context = context || document;
- var match, elem, xml, m,
- nodeType = context.nodeType;
-
- if ( nodeType !== 1 && nodeType !== 9 ) {
- return [];
- }
-
- if ( !selector || typeof selector !== "string" ) {
- return results;
- }
-
- xml = isXML( context );
-
- if ( !xml && !seed ) {
- if ( (match = rquickExpr.exec( selector )) ) {
- // Speed-up: Sizzle("#ID")
- if ( (m = match[1]) ) {
- if ( nodeType === 9 ) {
- elem = context.getElementById( m );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- if ( elem && elem.parentNode ) {
- // Handle the case where IE, Opera, and Webkit return items
- // by name instead of ID
- if ( elem.id === m ) {
- results.push( elem );
- return results;
- }
- } else {
- return results;
- }
- } else {
- // Context is not a document
- if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
- contains( context, elem ) && elem.id === m ) {
- results.push( elem );
- return results;
- }
- }
-
- // Speed-up: Sizzle("TAG")
- } else if ( match[2] ) {
- push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
- return results;
-
- // Speed-up: Sizzle(".CLASS")
- } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
- push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
- return results;
- }
- }
- }
-
- // All others
- return select( selector, context, results, seed, xml );
-}
-
-Sizzle.matches = function( expr, elements ) {
- return Sizzle( expr, null, null, elements );
-};
-
-Sizzle.matchesSelector = function( elem, expr ) {
- return Sizzle( expr, null, null, [ elem ] ).length > 0;
-};
-
-// Returns a function to use in pseudos for input types
-function createInputPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === type;
- };
-}
-
-// Returns a function to use in pseudos for buttons
-function createButtonPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return (name === "input" || name === "button") && elem.type === type;
- };
-}
-
-/**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-getText = Sizzle.getText = function( elem ) {
- var node,
- ret = "",
- i = 0,
- nodeType = elem.nodeType;
-
- if ( nodeType ) {
- if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
- // Use textContent for elements
- // innerText usage removed for consistency of new lines (see #11153)
- if ( typeof elem.textContent === "string" ) {
- return elem.textContent;
- } else {
- // Traverse its children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
- ret += getText( elem );
- }
- }
- } else if ( nodeType === 3 || nodeType === 4 ) {
- return elem.nodeValue;
- }
- // Do not include comment or processing instruction nodes
- } else {
-
- // If no nodeType, this is expected to be an array
- for ( ; (node = elem[i]); i++ ) {
- // Do not traverse comment nodes
- ret += getText( node );
- }
- }
- return ret;
-};
-
-isXML = Sizzle.isXML = function isXML( elem ) {
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = elem && (elem.ownerDocument || elem).documentElement;
- return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-// Element contains another
-contains = Sizzle.contains = docElem.contains ?
- function( a, b ) {
- var adown = a.nodeType === 9 ? a.documentElement : a,
- bup = b && b.parentNode;
- return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
- } :
- docElem.compareDocumentPosition ?
- function( a, b ) {
- return b && !!( a.compareDocumentPosition( b ) & 16 );
- } :
- function( a, b ) {
- while ( (b = b.parentNode) ) {
- if ( b === a ) {
- return true;
- }
- }
- return false;
- };
-
-Sizzle.attr = function( elem, name ) {
- var attr,
- xml = isXML( elem );
-
- if ( !xml ) {
- name = name.toLowerCase();
- }
- if ( Expr.attrHandle[ name ] ) {
- return Expr.attrHandle[ name ]( elem );
- }
- if ( assertAttributes || xml ) {
- return elem.getAttribute( name );
- }
- attr = elem.getAttributeNode( name );
- return attr ?
- typeof elem[ name ] === "boolean" ?
- elem[ name ] ? name : null :
- attr.specified ? attr.value : null :
- null;
-};
-
-Expr = Sizzle.selectors = {
-
- // Can be adjusted by the user
- cacheLength: 50,
-
- createPseudo: markFunction,
-
- match: matchExpr,
-
- order: new RegExp( "ID|TAG" +
- (assertUsableName ? "|NAME" : "") +
- (assertUsableClassName ? "|CLASS" : "")
- ),
-
- // IE6/7 return a modified href
- attrHandle: assertHrefNotNormalized ?
- {} :
- {
- "href": function( elem ) {
- return elem.getAttribute( "href", 2 );
- },
- "type": function( elem ) {
- return elem.getAttribute("type");
- }
- },
-
- find: {
- "ID": assertGetIdNotName ?
- function( id, context, xml ) {
- if ( typeof context.getElementById !== strundefined && !xml ) {
- var m = context.getElementById( id );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- return m && m.parentNode ? [m] : [];
- }
- } :
- function( id, context, xml ) {
- if ( typeof context.getElementById !== strundefined && !xml ) {
- var m = context.getElementById( id );
-
- return m ?
- m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
- [m] :
- undefined :
- [];
- }
- },
-
- "TAG": assertTagNameNoComments ?
- function( tag, context ) {
- if ( typeof context.getElementsByTagName !== strundefined ) {
- return context.getElementsByTagName( tag );
- }
- } :
- function( tag, context ) {
- var results = context.getElementsByTagName( tag );
-
- // Filter out possible comments
- if ( tag === "*" ) {
- var elem,
- tmp = [],
- i = 0;
-
- for ( ; (elem = results[i]); i++ ) {
- if ( elem.nodeType === 1 ) {
- tmp.push( elem );
- }
- }
-
- return tmp;
- }
- return results;
- },
-
- "NAME": function( tag, context ) {
- if ( typeof context.getElementsByName !== strundefined ) {
- return context.getElementsByName( name );
- }
- },
-
- "CLASS": function( className, context, xml ) {
- if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
- return context.getElementsByClassName( className );
- }
- }
- },
-
- relative: {
- ">": { dir: "parentNode", first: true },
- " ": { dir: "parentNode" },
- "+": { dir: "previousSibling", first: true },
- "~": { dir: "previousSibling" }
- },
-
- preFilter: {
- "ATTR": function( match ) {
- match[1] = match[1].replace( rbackslash, "" );
-
- // Move the given value to match[3] whether quoted or unquoted
- match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
-
- if ( match[2] === "~=" ) {
- match[3] = " " + match[3] + " ";
- }
-
- return match.slice( 0, 4 );
- },
-
- "CHILD": function( match ) {
- /* matches from matchExpr.CHILD
- 1 type (only|nth|...)
- 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
- 3 xn-component of xn+y argument ([+-]?\d*n|)
- 4 sign of xn-component
- 5 x of xn-component
- 6 sign of y-component
- 7 y of y-component
- */
- match[1] = match[1].toLowerCase();
-
- if ( match[1] === "nth" ) {
- // nth-child requires argument
- if ( !match[2] ) {
- Sizzle.error( match[0] );
- }
-
- // numeric x and y parameters for Expr.filter.CHILD
- // remember that false/true cast respectively to 0/1
- match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
- match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
-
- // other types prohibit arguments
- } else if ( match[2] ) {
- Sizzle.error( match[0] );
- }
-
- return match;
- },
-
- "PSEUDO": function( match, context, xml ) {
- var unquoted, excess;
- if ( matchExpr["CHILD"].test( match[0] ) ) {
- return null;
- }
-
- if ( match[3] ) {
- match[2] = match[3];
- } else if ( (unquoted = match[4]) ) {
- // Only check arguments that contain a pseudo
- if ( rpseudo.test(unquoted) &&
- // Get excess from tokenize (recursively)
- (excess = tokenize( unquoted, context, xml, true )) &&
- // advance to the next closing parenthesis
- (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
-
- // excess is a negative index
- unquoted = unquoted.slice( 0, excess );
- match[0] = match[0].slice( 0, excess );
- }
- match[2] = unquoted;
- }
-
- // Return only captures needed by the pseudo filter method (type and argument)
- return match.slice( 0, 3 );
- }
- },
-
- filter: {
- "ID": assertGetIdNotName ?
- function( id ) {
- id = id.replace( rbackslash, "" );
- return function( elem ) {
- return elem.getAttribute("id") === id;
- };
- } :
- function( id ) {
- id = id.replace( rbackslash, "" );
- return function( elem ) {
- var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
- return node && node.value === id;
- };
- },
-
- "TAG": function( nodeName ) {
- if ( nodeName === "*" ) {
- return function() { return true; };
- }
- nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
-
- return function( elem ) {
- return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
- };
- },
-
- "CLASS": function( className ) {
- var pattern = classCache[ expando ][ className ];
- if ( !pattern ) {
- pattern = classCache( className, new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)") );
- }
- return function( elem ) {
- return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
- };
- },
-
- "ATTR": function( name, operator, check ) {
- if ( !operator ) {
- return function( elem ) {
- return Sizzle.attr( elem, name ) != null;
- };
- }
-
- return function( elem ) {
- var result = Sizzle.attr( elem, name ),
- value = result + "";
-
- if ( result == null ) {
- return operator === "!=";
- }
-
- switch ( operator ) {
- case "=":
- return value === check;
- case "!=":
- return value !== check;
- case "^=":
- return check && value.indexOf( check ) === 0;
- case "*=":
- return check && value.indexOf( check ) > -1;
- case "$=":
- return check && value.substr( value.length - check.length ) === check;
- case "~=":
- return ( " " + value + " " ).indexOf( check ) > -1;
- case "|=":
- return value === check || value.substr( 0, check.length + 1 ) === check + "-";
- }
- };
- },
-
- "CHILD": function( type, argument, first, last ) {
-
- if ( type === "nth" ) {
- var doneName = done++;
-
- return function( elem ) {
- var parent, diff,
- count = 0,
- node = elem;
-
- if ( first === 1 && last === 0 ) {
- return true;
- }
-
- parent = elem.parentNode;
-
- if ( parent && (parent[ expando ] !== doneName || !elem.sizset) ) {
- for ( node = parent.firstChild; node; node = node.nextSibling ) {
- if ( node.nodeType === 1 ) {
- node.sizset = ++count;
- if ( node === elem ) {
- break;
- }
- }
- }
-
- parent[ expando ] = doneName;
- }
-
- diff = elem.sizset - last;
-
- if ( first === 0 ) {
- return diff === 0;
-
- } else {
- return ( diff % first === 0 && diff / first >= 0 );
- }
- };
- }
-
- return function( elem ) {
- var node = elem;
-
- switch ( type ) {
- case "only":
- case "first":
- while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
-
- if ( type === "first" ) {
- return true;
- }
-
- node = elem;
-
- /* falls through */
- case "last":
- while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
-
- return true;
- }
- };
- },
-
- "PSEUDO": function( pseudo, argument, context, xml ) {
- // pseudo-class names are case-insensitive
- // http://www.w3.org/TR/selectors/#pseudo-classes
- // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
- var args,
- fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ];
-
- if ( !fn ) {
- Sizzle.error( "unsupported pseudo: " + pseudo );
- }
-
- // The user may use createPseudo to indicate that
- // arguments are needed to create the filter function
- // just as Sizzle does
- if ( !fn[ expando ] ) {
- if ( fn.length > 1 ) {
- args = [ pseudo, pseudo, "", argument ];
- return function( elem ) {
- return fn( elem, 0, args );
- };
- }
- return fn;
- }
-
- return fn( argument, context, xml );
- }
- },
-
- pseudos: {
- "not": markFunction(function( selector, context, xml ) {
- // Trim the selector passed to compile
- // to avoid treating leading and trailing
- // spaces as combinators
- var matcher = compile( selector.replace( rtrim, "$1" ), context, xml );
- return function( elem ) {
- return !matcher( elem );
- };
- }),
-
- "enabled": function( elem ) {
- return elem.disabled === false;
- },
-
- "disabled": function( elem ) {
- return elem.disabled === true;
- },
-
- "checked": function( elem ) {
- // In CSS3, :checked should return both checked and selected elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- var nodeName = elem.nodeName.toLowerCase();
- return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
- },
-
- "selected": function( elem ) {
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- if ( elem.parentNode ) {
- elem.parentNode.selectedIndex;
- }
-
- return elem.selected === true;
- },
-
- "parent": function( elem ) {
- return !Expr.pseudos["empty"]( elem );
- },
-
- "empty": function( elem ) {
- // http://www.w3.org/TR/selectors/#empty-pseudo
- // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
- // not comment, processing instructions, or others
- // Thanks to Diego Perini for the nodeName shortcut
- // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
- var nodeType;
- elem = elem.firstChild;
- while ( elem ) {
- if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
- return false;
- }
- elem = elem.nextSibling;
- }
- return true;
- },
-
- "contains": markFunction(function( text ) {
- return function( elem ) {
- return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
- };
- }),
-
- "has": markFunction(function( selector ) {
- return function( elem ) {
- return Sizzle( selector, elem ).length > 0;
- };
- }),
-
- "header": function( elem ) {
- return rheader.test( elem.nodeName );
- },
-
- "text": function( elem ) {
- var type, attr;
- // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
- // use getAttribute instead to test this case
- return elem.nodeName.toLowerCase() === "input" &&
- (type = elem.type) === "text" &&
- ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
- },
-
- // Input types
- "radio": createInputPseudo("radio"),
- "checkbox": createInputPseudo("checkbox"),
- "file": createInputPseudo("file"),
- "password": createInputPseudo("password"),
- "image": createInputPseudo("image"),
-
- "submit": createButtonPseudo("submit"),
- "reset": createButtonPseudo("reset"),
-
- "button": function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === "button" || name === "button";
- },
-
- "input": function( elem ) {
- return rinputs.test( elem.nodeName );
- },
-
- "focus": function( elem ) {
- var doc = elem.ownerDocument;
- return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href);
- },
-
- "active": function( elem ) {
- return elem === elem.ownerDocument.activeElement;
- }
- },
-
- setFilters: {
- "first": function( elements, argument, not ) {
- return not ? elements.slice( 1 ) : [ elements[0] ];
- },
-
- "last": function( elements, argument, not ) {
- var elem = elements.pop();
- return not ? elements : [ elem ];
- },
-
- "even": function( elements, argument, not ) {
- var results = [],
- i = not ? 1 : 0,
- len = elements.length;
- for ( ; i < len; i = i + 2 ) {
- results.push( elements[i] );
- }
- return results;
- },
-
- "odd": function( elements, argument, not ) {
- var results = [],
- i = not ? 0 : 1,
- len = elements.length;
- for ( ; i < len; i = i + 2 ) {
- results.push( elements[i] );
- }
- return results;
- },
-
- "lt": function( elements, argument, not ) {
- return not ? elements.slice( +argument ) : elements.slice( 0, +argument );
- },
-
- "gt": function( elements, argument, not ) {
- return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 );
- },
-
- "eq": function( elements, argument, not ) {
- var elem = elements.splice( +argument, 1 );
- return not ? elements : elem;
- }
- }
-};
-
-function siblingCheck( a, b, ret ) {
- if ( a === b ) {
- return ret;
- }
-
- var cur = a.nextSibling;
-
- while ( cur ) {
- if ( cur === b ) {
- return -1;
- }
-
- cur = cur.nextSibling;
- }
-
- return 1;
-}
-
-sortOrder = docElem.compareDocumentPosition ?
- function( a, b ) {
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
- a.compareDocumentPosition :
- a.compareDocumentPosition(b) & 4
- ) ? -1 : 1;
- } :
- function( a, b ) {
- // The nodes are identical, we can exit early
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
-
- // Fallback to using sourceIndex (in IE) if it's available on both nodes
- } else if ( a.sourceIndex && b.sourceIndex ) {
- return a.sourceIndex - b.sourceIndex;
- }
-
- var al, bl,
- ap = [],
- bp = [],
- aup = a.parentNode,
- bup = b.parentNode,
- cur = aup;
-
- // If the nodes are siblings (or identical) we can do a quick check
- if ( aup === bup ) {
- return siblingCheck( a, b );
-
- // If no parents were found then the nodes are disconnected
- } else if ( !aup ) {
- return -1;
-
- } else if ( !bup ) {
- return 1;
- }
-
- // Otherwise they're somewhere else in the tree so we need
- // to build up a full list of the parentNodes for comparison
- while ( cur ) {
- ap.unshift( cur );
- cur = cur.parentNode;
- }
-
- cur = bup;
-
- while ( cur ) {
- bp.unshift( cur );
- cur = cur.parentNode;
- }
-
- al = ap.length;
- bl = bp.length;
-
- // Start walking down the tree looking for a discrepancy
- for ( var i = 0; i < al && i < bl; i++ ) {
- if ( ap[i] !== bp[i] ) {
- return siblingCheck( ap[i], bp[i] );
- }
- }
-
- // We ended someplace up the tree so do a sibling check
- return i === al ?
- siblingCheck( a, bp[i], -1 ) :
- siblingCheck( ap[i], b, 1 );
- };
-
-// Always assume the presence of duplicates if sort doesn't
-// pass them to our comparison function (as in Google Chrome).
-[0, 0].sort( sortOrder );
-baseHasDuplicate = !hasDuplicate;
-
-// Document sorting and removing duplicates
-Sizzle.uniqueSort = function( results ) {
- var elem,
- i = 1;
-
- hasDuplicate = baseHasDuplicate;
- results.sort( sortOrder );
-
- if ( hasDuplicate ) {
- for ( ; (elem = results[i]); i++ ) {
- if ( elem === results[ i - 1 ] ) {
- results.splice( i--, 1 );
- }
- }
- }
-
- return results;
-};
-
-Sizzle.error = function( msg ) {
- throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
-
-function tokenize( selector, context, xml, parseOnly ) {
- var matched, match, tokens, type,
- soFar, groups, group, i,
- preFilters, filters,
- checkContext = !xml && context !== document,
- // Token cache should maintain spaces
- key = ( checkContext ? "<s>" : "" ) + selector.replace( rtrim, "$1<s>" ),
- cached = tokenCache[ expando ][ key ];
-
- if ( cached ) {
- return parseOnly ? 0 : slice.call( cached, 0 );
- }
-
- soFar = selector;
- groups = [];
- i = 0;
- preFilters = Expr.preFilter;
- filters = Expr.filter;
-
- while ( soFar ) {
-
- // Comma and first run
- if ( !matched || (match = rcomma.exec( soFar )) ) {
- if ( match ) {
- soFar = soFar.slice( match[0].length );
- tokens.selector = group;
- }
- groups.push( tokens = [] );
- group = "";
-
- // Need to make sure we're within a narrower context if necessary
- // Adding a descendant combinator will generate what is needed
- if ( checkContext ) {
- soFar = " " + soFar;
- }
- }
-
- matched = false;
-
- // Combinators
- if ( (match = rcombinators.exec( soFar )) ) {
- group += match[0];
- soFar = soFar.slice( match[0].length );
-
- // Cast descendant combinators to space
- matched = tokens.push({
- part: match.pop().replace( rtrim, " " ),
- string: match[0],
- captures: match
- });
- }
-
- // Filters
- for ( type in filters ) {
- if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
- ( match = preFilters[ type ](match, context, xml) )) ) {
-
- group += match[0];
- soFar = soFar.slice( match[0].length );
- matched = tokens.push({
- part: type,
- string: match.shift(),
- captures: match
- });
- }
- }
-
- if ( !matched ) {
- break;
- }
- }
-
- // Attach the full group as a selector
- if ( group ) {
- tokens.selector = group;
- }
-
- // Return the length of the invalid excess
- // if we're just parsing
- // Otherwise, throw an error or return tokens
- return parseOnly ?
- soFar.length :
- soFar ?
- Sizzle.error( selector ) :
- // Cache the tokens
- slice.call( tokenCache(key, groups), 0 );
-}
-
-function addCombinator( matcher, combinator, context, xml ) {
- var dir = combinator.dir,
- doneName = done++;
-
- if ( !matcher ) {
- // If there is no matcher to check, check against the context
- matcher = function( elem ) {
- return elem === context;
- };
- }
- return combinator.first ?
- function( elem ) {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 ) {
- return matcher( elem ) && elem;
- }
- }
- } :
- xml ?
- function( elem ) {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 ) {
- if ( matcher( elem ) ) {
- return elem;
- }
- }
- }
- } :
- function( elem ) {
- var cache,
- dirkey = doneName + "." + dirruns,
- cachedkey = dirkey + "." + cachedruns;
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 ) {
- if ( (cache = elem[ expando ]) === cachedkey ) {
- return elem.sizset;
- } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
- if ( elem.sizset ) {
- return elem;
- }
- } else {
- elem[ expando ] = cachedkey;
- if ( matcher( elem ) ) {
- elem.sizset = true;
- return elem;
- }
- elem.sizset = false;
- }
- }
- }
- };
-}
-
-function addMatcher( higher, deeper ) {
- return higher ?
- function( elem ) {
- var result = deeper( elem );
- return result && higher( result === true ? elem : result );
- } :
- deeper;
-}
-
-// ["TAG", ">", "ID", " ", "CLASS"]
-function matcherFromTokens( tokens, context, xml ) {
- var token, matcher,
- i = 0;
-
- for ( ; (token = tokens[i]); i++ ) {
- if ( Expr.relative[ token.part ] ) {
- matcher = addCombinator( matcher, Expr.relative[ token.part ], context, xml );
- } else {
- matcher = addMatcher( matcher, Expr.filter[ token.part ].apply(null, token.captures.concat( context, xml )) );
- }
- }
-
- return matcher;
-}
-
-function matcherFromGroupMatchers( matchers ) {
- return function( elem ) {
- var matcher,
- j = 0;
- for ( ; (matcher = matchers[j]); j++ ) {
- if ( matcher(elem) ) {
- return true;
- }
- }
- return false;
- };
-}
-
-compile = Sizzle.compile = function( selector, context, xml ) {
- var group, i, len,
- cached = compilerCache[ expando ][ selector ];
-
- // Return a cached group function if already generated (context dependent)
- if ( cached && cached.context === context ) {
- return cached;
- }
-
- // Generate a function of recursive functions that can be used to check each element
- group = tokenize( selector, context, xml );
- for ( i = 0, len = group.length; i < len; i++ ) {
- group[i] = matcherFromTokens(group[i], context, xml);
- }
-
- // Cache the compiled function
- cached = compilerCache( selector, matcherFromGroupMatchers(group) );
- cached.context = context;
- cached.runs = cached.dirruns = 0;
- return cached;
-};
-
-function multipleContexts( selector, contexts, results, seed ) {
- var i = 0,
- len = contexts.length;
- for ( ; i < len; i++ ) {
- Sizzle( selector, contexts[i], results, seed );
- }
-}
-
-function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) {
- var results,
- fn = Expr.setFilters[ posfilter.toLowerCase() ];
-
- if ( !fn ) {
- Sizzle.error( posfilter );
- }
-
- if ( selector || !(results = seed) ) {
- multipleContexts( selector || "*", contexts, (results = []), seed );
- }
-
- return results.length > 0 ? fn( results, argument, not ) : [];
-}
-
-function handlePOS( groups, context, results, seed ) {
- var group, part, j, groupLen, token, selector,
- anchor, elements, match, matched,
- lastIndex, currentContexts, not,
- i = 0,
- len = groups.length,
- rpos = matchExpr["POS"],
- // This is generated here in case matchExpr["POS"] is extended
- rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ),
- // This is for making sure non-participating
- // matching groups are represented cross-browser (IE6-8)
- setUndefined = function() {
- var i = 1,
- len = arguments.length - 2;
- for ( ; i < len; i++ ) {
- if ( arguments[i] === undefined ) {
- match[i] = undefined;
- }
- }
- };
-
- for ( ; i < len; i++ ) {
- group = groups[i];
- part = "";
- elements = seed;
- for ( j = 0, groupLen = group.length; j < groupLen; j++ ) {
- token = group[j];
- selector = token.string;
- if ( token.part === "PSEUDO" ) {
- // Reset regex index to 0
- rpos.exec("");
- anchor = 0;
- while ( (match = rpos.exec( selector )) ) {
- matched = true;
- lastIndex = rpos.lastIndex = match.index + match[0].length;
- if ( lastIndex > anchor ) {
- part += selector.slice( anchor, match.index );
- anchor = lastIndex;
- currentContexts = [ context ];
-
- if ( rcombinators.test(part) ) {
- if ( elements ) {
- currentContexts = elements;
- }
- elements = seed;
- }
-
- if ( (not = rendsWithNot.test( part )) ) {
- part = part.slice( 0, -5 ).replace( rcombinators, "$&*" );
- anchor++;
- }
-
- if ( match.length > 1 ) {
- match[0].replace( rposgroups, setUndefined );
- }
- elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not );
- }
- part = "";
- }
-
- }
-
- if ( !matched ) {
- part += selector;
- }
- matched = false;
- }
-
- if ( part ) {
- if ( rcombinators.test(part) ) {
- multipleContexts( part, elements || [ context ], results, seed );
- } else {
- Sizzle( part, context, results, seed ? seed.concat(elements) : elements );
- }
- } else {
- push.apply( results, elements );
- }
- }
-
- // Do not sort if this is a single filter
- return len === 1 ? results : Sizzle.uniqueSort( results );
-}
-
-function select( selector, context, results, seed, xml ) {
- // Remove excessive whitespace
- selector = selector.replace( rtrim, "$1" );
- var elements, matcher, cached, elem,
- i, tokens, token, lastToken, findContext, type,
- match = tokenize( selector, context, xml ),
- contextNodeType = context.nodeType;
-
- // POS handling
- if ( matchExpr["POS"].test(selector) ) {
- return handlePOS( match, context, results, seed );
- }
-
- if ( seed ) {
- elements = slice.call( seed, 0 );
-
- // To maintain document order, only narrow the
- // set if there is one group
- } else if ( match.length === 1 ) {
-
- // Take a shortcut and set the context if the root selector is an ID
- if ( (tokens = slice.call( match[0], 0 )).length > 2 &&
- (token = tokens[0]).part === "ID" &&
- contextNodeType === 9 && !xml &&
- Expr.relative[ tokens[1].part ] ) {
-
- context = Expr.find["ID"]( token.captures[0].replace( rbackslash, "" ), context, xml )[0];
- if ( !context ) {
- return results;
- }
-
- selector = selector.slice( tokens.shift().string.length );
- }
-
- findContext = ( (match = rsibling.exec( tokens[0].string )) && !match.index && context.parentNode ) || context;
-
- // Reduce the set if possible
- lastToken = "";
- for ( i = tokens.length - 1; i >= 0; i-- ) {
- token = tokens[i];
- type = token.part;
- lastToken = token.string + lastToken;
- if ( Expr.relative[ type ] ) {
- break;
- }
- if ( Expr.order.test(type) ) {
- elements = Expr.find[ type ]( token.captures[0].replace( rbackslash, "" ), findContext, xml );
- if ( elements == null ) {
- continue;
- } else {
- selector = selector.slice( 0, selector.length - lastToken.length ) +
- lastToken.replace( matchExpr[ type ], "" );
-
- if ( !selector ) {
- push.apply( results, slice.call(elements, 0) );
- }
-
- break;
- }
- }
- }
- }
-
- // Only loop over the given elements once
- if ( selector ) {
- matcher = compile( selector, context, xml );
- dirruns = matcher.dirruns++;
- if ( elements == null ) {
- elements = Expr.find["TAG"]( "*", (rsibling.test( selector ) && context.parentNode) || context );
- }
-
- for ( i = 0; (elem = elements[i]); i++ ) {
- cachedruns = matcher.runs++;
- if ( matcher(elem) ) {
- results.push( elem );
- }
- }
- }
-
- return results;
-}
-
-if ( document.querySelectorAll ) {
- (function() {
- var disconnectedMatch,
- oldSelect = select,
- rescape = /'|\\/g,
- rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
- rbuggyQSA = [],
- // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
- // A support test would require too much code (would include document ready)
- // just skip matchesSelector for :active
- rbuggyMatches = [":active"],
- matches = docElem.matchesSelector ||
- docElem.mozMatchesSelector ||
- docElem.webkitMatchesSelector ||
- docElem.oMatchesSelector ||
- docElem.msMatchesSelector;
-
- // Build QSA regex
- // Regex strategy adopted from Diego Perini
- assert(function( div ) {
- // Select is set to empty string on purpose
- // This is to test IE's treatment of not explictly
- // setting a boolean content attribute,
- // since its presence should be enough
- // http://bugs.jquery.com/ticket/12359
- div.innerHTML = "<select><option selected=''></option></select>";
-
- // IE8 - Some boolean attributes are not treated correctly
- if ( !div.querySelectorAll("[selected]").length ) {
- rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
- }
-
- // Webkit/Opera - :checked should return selected option elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- // IE8 throws error here (do not put tests after this one)
- if ( !div.querySelectorAll(":checked").length ) {
- rbuggyQSA.push(":checked");
- }
- });
-
- assert(function( div ) {
-
- // Opera 10-12/IE9 - ^= $= *= and empty values
- // Should not select anything
- div.innerHTML = "<p test=''></p>";
- if ( div.querySelectorAll("[test^='']").length ) {
- rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
- }
-
- // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
- // IE8 throws error here (do not put tests after this one)
- div.innerHTML = "<input type='hidden'/>";
- if ( !div.querySelectorAll(":enabled").length ) {
- rbuggyQSA.push(":enabled", ":disabled");
- }
- });
-
- rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
-
- select = function( selector, context, results, seed, xml ) {
- // Only use querySelectorAll when not filtering,
- // when this is not xml,
- // and when no QSA bugs apply
- if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
- if ( context.nodeType === 9 ) {
- try {
- push.apply( results, slice.call(context.querySelectorAll( selector ), 0) );
- return results;
- } catch(qsaError) {}
- // qSA works strangely on Element-rooted queries
- // We can work around this by specifying an extra ID on the root
- // and working up from there (Thanks to Andrew Dupont for the technique)
- // IE 8 doesn't work on object elements
- } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
- var groups, i, len,
- old = context.getAttribute("id"),
- nid = old || expando,
- newContext = rsibling.test( selector ) && context.parentNode || context;
-
- if ( old ) {
- nid = nid.replace( rescape, "\\$&" );
- } else {
- context.setAttribute( "id", nid );
- }
-
- groups = tokenize(selector, context, xml);
- // Trailing space is unnecessary
- // There is always a context check
- nid = "[id='" + nid + "']";
- for ( i = 0, len = groups.length; i < len; i++ ) {
- groups[i] = nid + groups[i].selector;
- }
- try {
- push.apply( results, slice.call( newContext.querySelectorAll(
- groups.join(",")
- ), 0 ) );
- return results;
- } catch(qsaError) {
- } finally {
- if ( !old ) {
- context.removeAttribute("id");
- }
- }
- }
- }
-
- return oldSelect( selector, context, results, seed, xml );
- };
-
- if ( matches ) {
- assert(function( div ) {
- // Check to see if it's possible to do matchesSelector
- // on a disconnected node (IE 9)
- disconnectedMatch = matches.call( div, "div" );
-
- // This should fail with an exception
- // Gecko does not error, returns false instead
- try {
- matches.call( div, "[test!='']:sizzle" );
- rbuggyMatches.push( matchExpr["PSEUDO"].source, matchExpr["POS"].source, "!=" );
- } catch ( e ) {}
- });
-
- // rbuggyMatches always contains :active, so no need for a length check
- rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
-
- Sizzle.matchesSelector = function( elem, expr ) {
- // Make sure that attribute selectors are quoted
- expr = expr.replace( rattributeQuotes, "='$1']" );
-
- // rbuggyMatches always contains :active, so no need for an existence check
- if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) {
- try {
- var ret = matches.call( elem, expr );
-
- // IE 9's matchesSelector returns false on disconnected nodes
- if ( ret || disconnectedMatch ||
- // As well, disconnected nodes are said to be in a document
- // fragment in IE 9
- elem.document && elem.document.nodeType !== 11 ) {
- return ret;
- }
- } catch(e) {}
- }
-
- return Sizzle( expr, null, null, [ elem ] ).length > 0;
- };
- }
- })();
-}
-
-// Deprecated
-Expr.setFilters["nth"] = Expr.setFilters["eq"];
-
-// Back-compat
-Expr.filters = Expr.pseudos;
-
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://sizzlejs.com/
+ */
+(function( window, undefined ) {
+
+var dirruns,
+ cachedruns,
+ assertGetIdNotName,
+ Expr,
+ getText,
+ isXML,
+ contains,
+ compile,
+ sortOrder,
+ hasDuplicate,
+
+ baseHasDuplicate = true,
+ strundefined = "undefined",
+
+ expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
+
+ document = window.document,
+ docElem = document.documentElement,
+ done = 0,
+ slice = [].slice,
+ push = [].push,
+
+ // Augment a function for special use by Sizzle
+ markFunction = function( fn, value ) {
+ fn[ expando ] = value || true;
+ return fn;
+ },
+
+ createCache = function() {
+ var cache = {},
+ keys = [];
+
+ return markFunction(function( key, value ) {
+ // Only keep the most recent entries
+ if ( keys.push( key ) > Expr.cacheLength ) {
+ delete cache[ keys.shift() ];
+ }
+
+ return (cache[ key ] = value);
+ }, cache );
+ },
+
+ classCache = createCache(),
+ tokenCache = createCache(),
+ compilerCache = createCache(),
+
+ // Regex
+
+ // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+ whitespace = "[\\x20\\t\\r\\n\\f]",
+ // http://www.w3.org/TR/css3-syntax/#characters
+ characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
+
+ // Loosely modeled on CSS identifier characters
+ // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)
+ // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+ identifier = characterEncoding.replace( "w", "w#" ),
+
+ // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
+ operators = "([*^$|!~]?=)",
+ attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
+ "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
+
+ // Prefer arguments not in parens/brackets,
+ // then attribute selectors and non-pseudos (denoted by :),
+ // then anything else
+ // These preferences are here to reduce the number of selectors
+ // needing tokenize in the PSEUDO preFilter
+ pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",
+
+ // For matchExpr.POS and matchExpr.needsContext
+ pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\(((?:-\\d)?\\d*)\\)|)(?=[^-]|$)",
+
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+ rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
+ rpseudo = new RegExp( pseudos ),
+
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
+ rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
+
+ rnot = /^:not/,
+ rsibling = /[\x20\t\r\n\f]*[+~]/,
+ rendsWithNot = /:not\($/,
+
+ rheader = /h\d/i,
+ rinputs = /input|select|textarea|button/i,
+
+ rbackslash = /\\(?!\\)/g,
+
+ matchExpr = {
+ "ID": new RegExp( "^#(" + characterEncoding + ")" ),
+ "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+ "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
+ "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
+ "ATTR": new RegExp( "^" + attributes ),
+ "PSEUDO": new RegExp( "^" + pseudos ),
+ "CHILD": new RegExp( "^:(only|nth|last|first)-child(?:\\(" + whitespace +
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+ "POS": new RegExp( pos, "ig" ),
+ // For use in libraries implementing .is()
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
+ },
+
+ // Support
+
+ // Used for testing something on an element
+ assert = function( fn ) {
+ var div = document.createElement("div");
+
+ try {
+ return fn( div );
+ } catch (e) {
+ return false;
+ } finally {
+ // release memory in IE
+ div = null;
+ }
+ },
+
+ // Check if getElementsByTagName("*") returns only elements
+ assertTagNameNoComments = assert(function( div ) {
+ div.appendChild( document.createComment("") );
+ return !div.getElementsByTagName("*").length;
+ }),
+
+ // Check if getAttribute returns normalized href attributes
+ assertHrefNotNormalized = assert(function( div ) {
+ div.innerHTML = "<a href='#'></a>";
+ return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
+ div.firstChild.getAttribute("href") === "#";
+ }),
+
+ // Check if attributes should be retrieved by attribute nodes
+ assertAttributes = assert(function( div ) {
+ div.innerHTML = "<select></select>";
+ var type = typeof div.lastChild.getAttribute("multiple");
+ // IE8 returns a string for some attributes even when not present
+ return type !== "boolean" && type !== "string";
+ }),
+
+ // Check if getElementsByClassName can be trusted
+ assertUsableClassName = assert(function( div ) {
+ // Opera can't find a second classname (in 9.6)
+ div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
+ if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
+ return false;
+ }
+
+ // Safari 3.2 caches class attributes and doesn't catch changes
+ div.lastChild.className = "e";
+ return div.getElementsByClassName("e").length === 2;
+ }),
+
+ // Check if getElementById returns elements by name
+ // Check if getElementsByName privileges form controls or returns elements by ID
+ assertUsableName = assert(function( div ) {
+ // Inject content
+ div.id = expando + 0;
+ div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
+ docElem.insertBefore( div, docElem.firstChild );
+
+ // Test
+ var pass = document.getElementsByName &&
+ // buggy browsers will return fewer than the correct 2
+ document.getElementsByName( expando ).length === 2 +
+ // buggy browsers will return more than the correct 0
+ document.getElementsByName( expando + 0 ).length;
+ assertGetIdNotName = !document.getElementById( expando );
+
+ // Cleanup
+ docElem.removeChild( div );
+
+ return pass;
+ });
+
+// If slice is not available, provide a backup
+try {
+ slice.call( docElem.childNodes, 0 )[0].nodeType;
+} catch ( e ) {
+ slice = function( i ) {
+ var elem, results = [];
+ for ( ; (elem = this[i]); i++ ) {
+ results.push( elem );
+ }
+ return results;
+ };
+}
+
+function Sizzle( selector, context, results, seed ) {
+ results = results || [];
+ context = context || document;
+ var match, elem, xml, m,
+ nodeType = context.nodeType;
+
+ if ( nodeType !== 1 && nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ xml = isXML( context );
+
+ if ( !xml && !seed ) {
+ if ( (match = rquickExpr.exec( selector )) ) {
+ // Speed-up: Sizzle("#ID")
+ if ( (m = match[1]) ) {
+ if ( nodeType === 9 ) {
+ elem = context.getElementById( m );
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE, Opera, and Webkit return items
+ // by name instead of ID
+ if ( elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ } else {
+ return results;
+ }
+ } else {
+ // Context is not a document
+ if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
+ contains( context, elem ) && elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ }
+
+ // Speed-up: Sizzle("TAG")
+ } else if ( match[2] ) {
+ push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
+ return results;
+
+ // Speed-up: Sizzle(".CLASS")
+ } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
+ push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
+ return results;
+ }
+ }
+ }
+
+ // All others
+ return select( selector, context, results, seed, xml );
+}
+
+Sizzle.matches = function( expr, elements ) {
+ return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+ return Sizzle( expr, null, null, [ elem ] ).length > 0;
+};
+
+// Returns a function to use in pseudos for input types
+function createInputPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === type;
+ };
+}
+
+// Returns a function to use in pseudos for buttons
+function createButtonPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && elem.type === type;
+ };
+}
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+ var node,
+ ret = "",
+ i = 0,
+ nodeType = elem.nodeType;
+
+ if ( nodeType ) {
+ if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+ // Use textContent for elements
+ // innerText usage removed for consistency of new lines (see #11153)
+ if ( typeof elem.textContent === "string" ) {
+ return elem.textContent;
+ } else {
+ // Traverse its children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ ret += getText( elem );
+ }
+ }
+ } else if ( nodeType === 3 || nodeType === 4 ) {
+ return elem.nodeValue;
+ }
+ // Do not include comment or processing instruction nodes
+ } else {
+
+ // If no nodeType, this is expected to be an array
+ for ( ; (node = elem[i]); i++ ) {
+ // Do not traverse comment nodes
+ ret += getText( node );
+ }
+ }
+ return ret;
+};
+
+isXML = Sizzle.isXML = function isXML( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+// Element contains another
+contains = Sizzle.contains = docElem.contains ?
+ function( a, b ) {
+ var adown = a.nodeType === 9 ? a.documentElement : a,
+ bup = b && b.parentNode;
+ return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
+ } :
+ docElem.compareDocumentPosition ?
+ function( a, b ) {
+ return b && !!( a.compareDocumentPosition( b ) & 16 );
+ } :
+ function( a, b ) {
+ while ( (b = b.parentNode) ) {
+ if ( b === a ) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+Sizzle.attr = function( elem, name ) {
+ var attr,
+ xml = isXML( elem );
+
+ if ( !xml ) {
+ name = name.toLowerCase();
+ }
+ if ( Expr.attrHandle[ name ] ) {
+ return Expr.attrHandle[ name ]( elem );
+ }
+ if ( assertAttributes || xml ) {
+ return elem.getAttribute( name );
+ }
+ attr = elem.getAttributeNode( name );
+ return attr ?
+ typeof elem[ name ] === "boolean" ?
+ elem[ name ] ? name : null :
+ attr.specified ? attr.value : null :
+ null;
+};
+
+Expr = Sizzle.selectors = {
+
+ // Can be adjusted by the user
+ cacheLength: 50,
+
+ createPseudo: markFunction,
+
+ match: matchExpr,
+
+ order: new RegExp( "ID|TAG" +
+ (assertUsableName ? "|NAME" : "") +
+ (assertUsableClassName ? "|CLASS" : "")
+ ),
+
+ // IE6/7 return a modified href
+ attrHandle: assertHrefNotNormalized ?
+ {} :
+ {
+ "href": function( elem ) {
+ return elem.getAttribute( "href", 2 );
+ },
+ "type": function( elem ) {
+ return elem.getAttribute("type");
+ }
+ },
+
+ find: {
+ "ID": assertGetIdNotName ?
+ function( id, context, xml ) {
+ if ( typeof context.getElementById !== strundefined && !xml ) {
+ var m = context.getElementById( id );
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ return m && m.parentNode ? [m] : [];
+ }
+ } :
+ function( id, context, xml ) {
+ if ( typeof context.getElementById !== strundefined && !xml ) {
+ var m = context.getElementById( id );
+
+ return m ?
+ m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
+ [m] :
+ undefined :
+ [];
+ }
+ },
+
+ "TAG": assertTagNameNoComments ?
+ function( tag, context ) {
+ if ( typeof context.getElementsByTagName !== strundefined ) {
+ return context.getElementsByTagName( tag );
+ }
+ } :
+ function( tag, context ) {
+ var results = context.getElementsByTagName( tag );
+
+ // Filter out possible comments
+ if ( tag === "*" ) {
+ var elem,
+ tmp = [],
+ i = 0;
+
+ for ( ; (elem = results[i]); i++ ) {
+ if ( elem.nodeType === 1 ) {
+ tmp.push( elem );
+ }
+ }
+
+ return tmp;
+ }
+ return results;
+ },
+
+ "NAME": function( tag, context ) {
+ if ( typeof context.getElementsByName !== strundefined ) {
+ return context.getElementsByName( name );
+ }
+ },
+
+ "CLASS": function( className, context, xml ) {
+ if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
+ return context.getElementsByClassName( className );
+ }
+ }
+ },
+
+ relative: {
+ ">": { dir: "parentNode", first: true },
+ " ": { dir: "parentNode" },
+ "+": { dir: "previousSibling", first: true },
+ "~": { dir: "previousSibling" }
+ },
+
+ preFilter: {
+ "ATTR": function( match ) {
+ match[1] = match[1].replace( rbackslash, "" );
+
+ // Move the given value to match[3] whether quoted or unquoted
+ match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
+
+ if ( match[2] === "~=" ) {
+ match[3] = " " + match[3] + " ";
+ }
+
+ return match.slice( 0, 4 );
+ },
+
+ "CHILD": function( match ) {
+ /* matches from matchExpr.CHILD
+ 1 type (only|nth|...)
+ 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+ 3 xn-component of xn+y argument ([+-]?\d*n|)
+ 4 sign of xn-component
+ 5 x of xn-component
+ 6 sign of y-component
+ 7 y of y-component
+ */
+ match[1] = match[1].toLowerCase();
+
+ if ( match[1] === "nth" ) {
+ // nth-child requires argument
+ if ( !match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // numeric x and y parameters for Expr.filter.CHILD
+ // remember that false/true cast respectively to 0/1
+ match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
+ match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
+
+ // other types prohibit arguments
+ } else if ( match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ return match;
+ },
+
+ "PSEUDO": function( match, context, xml ) {
+ var unquoted, excess;
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
+ return null;
+ }
+
+ if ( match[3] ) {
+ match[2] = match[3];
+ } else if ( (unquoted = match[4]) ) {
+ // Only check arguments that contain a pseudo
+ if ( rpseudo.test(unquoted) &&
+ // Get excess from tokenize (recursively)
+ (excess = tokenize( unquoted, context, xml, true )) &&
+ // advance to the next closing parenthesis
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+ // excess is a negative index
+ unquoted = unquoted.slice( 0, excess );
+ match[0] = match[0].slice( 0, excess );
+ }
+ match[2] = unquoted;
+ }
+
+ // Return only captures needed by the pseudo filter method (type and argument)
+ return match.slice( 0, 3 );
+ }
+ },
+
+ filter: {
+ "ID": assertGetIdNotName ?
+ function( id ) {
+ id = id.replace( rbackslash, "" );
+ return function( elem ) {
+ return elem.getAttribute("id") === id;
+ };
+ } :
+ function( id ) {
+ id = id.replace( rbackslash, "" );
+ return function( elem ) {
+ var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+ return node && node.value === id;
+ };
+ },
+
+ "TAG": function( nodeName ) {
+ if ( nodeName === "*" ) {
+ return function() { return true; };
+ }
+ nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
+
+ return function( elem ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+ };
+ },
+
+ "CLASS": function( className ) {
+ var pattern = classCache[ expando ][ className ];
+ if ( !pattern ) {
+ pattern = classCache( className, new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)") );
+ }
+ return function( elem ) {
+ return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
+ };
+ },
+
+ "ATTR": function( name, operator, check ) {
+ if ( !operator ) {
+ return function( elem ) {
+ return Sizzle.attr( elem, name ) != null;
+ };
+ }
+
+ return function( elem ) {
+ var result = Sizzle.attr( elem, name ),
+ value = result + "";
+
+ if ( result == null ) {
+ return operator === "!=";
+ }
+
+ switch ( operator ) {
+ case "=":
+ return value === check;
+ case "!=":
+ return value !== check;
+ case "^=":
+ return check && value.indexOf( check ) === 0;
+ case "*=":
+ return check && value.indexOf( check ) > -1;
+ case "$=":
+ return check && value.substr( value.length - check.length ) === check;
+ case "~=":
+ return ( " " + value + " " ).indexOf( check ) > -1;
+ case "|=":
+ return value === check || value.substr( 0, check.length + 1 ) === check + "-";
+ }
+ };
+ },
+
+ "CHILD": function( type, argument, first, last ) {
+
+ if ( type === "nth" ) {
+ var doneName = done++;
+
+ return function( elem ) {
+ var parent, diff,
+ count = 0,
+ node = elem;
+
+ if ( first === 1 && last === 0 ) {
+ return true;
+ }
+
+ parent = elem.parentNode;
+
+ if ( parent && (parent[ expando ] !== doneName || !elem.sizset) ) {
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.sizset = ++count;
+ if ( node === elem ) {
+ break;
+ }
+ }
+ }
+
+ parent[ expando ] = doneName;
+ }
+
+ diff = elem.sizset - last;
+
+ if ( first === 0 ) {
+ return diff === 0;
+
+ } else {
+ return ( diff % first === 0 && diff / first >= 0 );
+ }
+ };
+ }
+
+ return function( elem ) {
+ var node = elem;
+
+ switch ( type ) {
+ case "only":
+ case "first":
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ if ( type === "first" ) {
+ return true;
+ }
+
+ node = elem;
+
+ /* falls through */
+ case "last":
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ };
+ },
+
+ "PSEUDO": function( pseudo, argument, context, xml ) {
+ // pseudo-class names are case-insensitive
+ // http://www.w3.org/TR/selectors/#pseudo-classes
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+ var args,
+ fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ];
+
+ if ( !fn ) {
+ Sizzle.error( "unsupported pseudo: " + pseudo );
+ }
+
+ // The user may use createPseudo to indicate that
+ // arguments are needed to create the filter function
+ // just as Sizzle does
+ if ( !fn[ expando ] ) {
+ if ( fn.length > 1 ) {
+ args = [ pseudo, pseudo, "", argument ];
+ return function( elem ) {
+ return fn( elem, 0, args );
+ };
+ }
+ return fn;
+ }
+
+ return fn( argument, context, xml );
+ }
+ },
+
+ pseudos: {
+ "not": markFunction(function( selector, context, xml ) {
+ // Trim the selector passed to compile
+ // to avoid treating leading and trailing
+ // spaces as combinators
+ var matcher = compile( selector.replace( rtrim, "$1" ), context, xml );
+ return function( elem ) {
+ return !matcher( elem );
+ };
+ }),
+
+ "enabled": function( elem ) {
+ return elem.disabled === false;
+ },
+
+ "disabled": function( elem ) {
+ return elem.disabled === true;
+ },
+
+ "checked": function( elem ) {
+ // In CSS3, :checked should return both checked and selected elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ var nodeName = elem.nodeName.toLowerCase();
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+ },
+
+ "selected": function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ "parent": function( elem ) {
+ return !Expr.pseudos["empty"]( elem );
+ },
+
+ "empty": function( elem ) {
+ // http://www.w3.org/TR/selectors/#empty-pseudo
+ // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
+ // not comment, processing instructions, or others
+ // Thanks to Diego Perini for the nodeName shortcut
+ // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
+ var nodeType;
+ elem = elem.firstChild;
+ while ( elem ) {
+ if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
+ return false;
+ }
+ elem = elem.nextSibling;
+ }
+ return true;
+ },
+
+ "contains": markFunction(function( text ) {
+ return function( elem ) {
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+ };
+ }),
+
+ "has": markFunction(function( selector ) {
+ return function( elem ) {
+ return Sizzle( selector, elem ).length > 0;
+ };
+ }),
+
+ "header": function( elem ) {
+ return rheader.test( elem.nodeName );
+ },
+
+ "text": function( elem ) {
+ var type, attr;
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // use getAttribute instead to test this case
+ return elem.nodeName.toLowerCase() === "input" &&
+ (type = elem.type) === "text" &&
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
+ },
+
+ // Input types
+ "radio": createInputPseudo("radio"),
+ "checkbox": createInputPseudo("checkbox"),
+ "file": createInputPseudo("file"),
+ "password": createInputPseudo("password"),
+ "image": createInputPseudo("image"),
+
+ "submit": createButtonPseudo("submit"),
+ "reset": createButtonPseudo("reset"),
+
+ "button": function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === "button" || name === "button";
+ },
+
+ "input": function( elem ) {
+ return rinputs.test( elem.nodeName );
+ },
+
+ "focus": function( elem ) {
+ var doc = elem.ownerDocument;
+ return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href);
+ },
+
+ "active": function( elem ) {
+ return elem === elem.ownerDocument.activeElement;
+ }
+ },
+
+ setFilters: {
+ "first": function( elements, argument, not ) {
+ return not ? elements.slice( 1 ) : [ elements[0] ];
+ },
+
+ "last": function( elements, argument, not ) {
+ var elem = elements.pop();
+ return not ? elements : [ elem ];
+ },
+
+ "even": function( elements, argument, not ) {
+ var results = [],
+ i = not ? 1 : 0,
+ len = elements.length;
+ for ( ; i < len; i = i + 2 ) {
+ results.push( elements[i] );
+ }
+ return results;
+ },
+
+ "odd": function( elements, argument, not ) {
+ var results = [],
+ i = not ? 0 : 1,
+ len = elements.length;
+ for ( ; i < len; i = i + 2 ) {
+ results.push( elements[i] );
+ }
+ return results;
+ },
+
+ "lt": function( elements, argument, not ) {
+ return not ? elements.slice( +argument ) : elements.slice( 0, +argument );
+ },
+
+ "gt": function( elements, argument, not ) {
+ return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 );
+ },
+
+ "eq": function( elements, argument, not ) {
+ var elem = elements.splice( +argument, 1 );
+ return not ? elements : elem;
+ }
+ }
+};
+
+function siblingCheck( a, b, ret ) {
+ if ( a === b ) {
+ return ret;
+ }
+
+ var cur = a.nextSibling;
+
+ while ( cur ) {
+ if ( cur === b ) {
+ return -1;
+ }
+
+ cur = cur.nextSibling;
+ }
+
+ return 1;
+}
+
+sortOrder = docElem.compareDocumentPosition ?
+ function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
+ a.compareDocumentPosition :
+ a.compareDocumentPosition(b) & 4
+ ) ? -1 : 1;
+ } :
+ function( a, b ) {
+ // The nodes are identical, we can exit early
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+
+ // Fallback to using sourceIndex (in IE) if it's available on both nodes
+ } else if ( a.sourceIndex && b.sourceIndex ) {
+ return a.sourceIndex - b.sourceIndex;
+ }
+
+ var al, bl,
+ ap = [],
+ bp = [],
+ aup = a.parentNode,
+ bup = b.parentNode,
+ cur = aup;
+
+ // If the nodes are siblings (or identical) we can do a quick check
+ if ( aup === bup ) {
+ return siblingCheck( a, b );
+
+ // If no parents were found then the nodes are disconnected
+ } else if ( !aup ) {
+ return -1;
+
+ } else if ( !bup ) {
+ return 1;
+ }
+
+ // Otherwise they're somewhere else in the tree so we need
+ // to build up a full list of the parentNodes for comparison
+ while ( cur ) {
+ ap.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ cur = bup;
+
+ while ( cur ) {
+ bp.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ al = ap.length;
+ bl = bp.length;
+
+ // Start walking down the tree looking for a discrepancy
+ for ( var i = 0; i < al && i < bl; i++ ) {
+ if ( ap[i] !== bp[i] ) {
+ return siblingCheck( ap[i], bp[i] );
+ }
+ }
+
+ // We ended someplace up the tree so do a sibling check
+ return i === al ?
+ siblingCheck( a, bp[i], -1 ) :
+ siblingCheck( ap[i], b, 1 );
+ };
+
+// Always assume the presence of duplicates if sort doesn't
+// pass them to our comparison function (as in Google Chrome).
+[0, 0].sort( sortOrder );
+baseHasDuplicate = !hasDuplicate;
+
+// Document sorting and removing duplicates
+Sizzle.uniqueSort = function( results ) {
+ var elem,
+ i = 1;
+
+ hasDuplicate = baseHasDuplicate;
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ for ( ; (elem = results[i]); i++ ) {
+ if ( elem === results[ i - 1 ] ) {
+ results.splice( i--, 1 );
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.error = function( msg ) {
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+function tokenize( selector, context, xml, parseOnly ) {
+ var matched, match, tokens, type,
+ soFar, groups, group, i,
+ preFilters, filters,
+ checkContext = !xml && context !== document,
+ // Token cache should maintain spaces
+ key = ( checkContext ? "<s>" : "" ) + selector.replace( rtrim, "$1<s>" ),
+ cached = tokenCache[ expando ][ key ];
+
+ if ( cached ) {
+ return parseOnly ? 0 : slice.call( cached, 0 );
+ }
+
+ soFar = selector;
+ groups = [];
+ i = 0;
+ preFilters = Expr.preFilter;
+ filters = Expr.filter;
+
+ while ( soFar ) {
+
+ // Comma and first run
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
+ if ( match ) {
+ soFar = soFar.slice( match[0].length );
+ tokens.selector = group;
+ }
+ groups.push( tokens = [] );
+ group = "";
+
+ // Need to make sure we're within a narrower context if necessary
+ // Adding a descendant combinator will generate what is needed
+ if ( checkContext ) {
+ soFar = " " + soFar;
+ }
+ }
+
+ matched = false;
+
+ // Combinators
+ if ( (match = rcombinators.exec( soFar )) ) {
+ group += match[0];
+ soFar = soFar.slice( match[0].length );
+
+ // Cast descendant combinators to space
+ matched = tokens.push({
+ part: match.pop().replace( rtrim, " " ),
+ string: match[0],
+ captures: match
+ });
+ }
+
+ // Filters
+ for ( type in filters ) {
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+ ( match = preFilters[ type ](match, context, xml) )) ) {
+
+ group += match[0];
+ soFar = soFar.slice( match[0].length );
+ matched = tokens.push({
+ part: type,
+ string: match.shift(),
+ captures: match
+ });
+ }
+ }
+
+ if ( !matched ) {
+ break;
+ }
+ }
+
+ // Attach the full group as a selector
+ if ( group ) {
+ tokens.selector = group;
+ }
+
+ // Return the length of the invalid excess
+ // if we're just parsing
+ // Otherwise, throw an error or return tokens
+ return parseOnly ?
+ soFar.length :
+ soFar ?
+ Sizzle.error( selector ) :
+ // Cache the tokens
+ slice.call( tokenCache(key, groups), 0 );
+}
+
+function addCombinator( matcher, combinator, context, xml ) {
+ var dir = combinator.dir,
+ doneName = done++;
+
+ if ( !matcher ) {
+ // If there is no matcher to check, check against the context
+ matcher = function( elem ) {
+ return elem === context;
+ };
+ }
+ return combinator.first ?
+ function( elem ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 ) {
+ return matcher( elem ) && elem;
+ }
+ }
+ } :
+ xml ?
+ function( elem ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 ) {
+ if ( matcher( elem ) ) {
+ return elem;
+ }
+ }
+ }
+ } :
+ function( elem ) {
+ var cache,
+ dirkey = doneName + "." + dirruns,
+ cachedkey = dirkey + "." + cachedruns;
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 ) {
+ if ( (cache = elem[ expando ]) === cachedkey ) {
+ return elem.sizset;
+ } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
+ if ( elem.sizset ) {
+ return elem;
+ }
+ } else {
+ elem[ expando ] = cachedkey;
+ if ( matcher( elem ) ) {
+ elem.sizset = true;
+ return elem;
+ }
+ elem.sizset = false;
+ }
+ }
+ }
+ };
+}
+
+function addMatcher( higher, deeper ) {
+ return higher ?
+ function( elem ) {
+ var result = deeper( elem );
+ return result && higher( result === true ? elem : result );
+ } :
+ deeper;
+}
+
+// ["TAG", ">", "ID", " ", "CLASS"]
+function matcherFromTokens( tokens, context, xml ) {
+ var token, matcher,
+ i = 0;
+
+ for ( ; (token = tokens[i]); i++ ) {
+ if ( Expr.relative[ token.part ] ) {
+ matcher = addCombinator( matcher, Expr.relative[ token.part ], context, xml );
+ } else {
+ matcher = addMatcher( matcher, Expr.filter[ token.part ].apply(null, token.captures.concat( context, xml )) );
+ }
+ }
+
+ return matcher;
+}
+
+function matcherFromGroupMatchers( matchers ) {
+ return function( elem ) {
+ var matcher,
+ j = 0;
+ for ( ; (matcher = matchers[j]); j++ ) {
+ if ( matcher(elem) ) {
+ return true;
+ }
+ }
+ return false;
+ };
+}
+
+compile = Sizzle.compile = function( selector, context, xml ) {
+ var group, i, len,
+ cached = compilerCache[ expando ][ selector ];
+
+ // Return a cached group function if already generated (context dependent)
+ if ( cached && cached.context === context ) {
+ return cached;
+ }
+
+ // Generate a function of recursive functions that can be used to check each element
+ group = tokenize( selector, context, xml );
+ for ( i = 0, len = group.length; i < len; i++ ) {
+ group[i] = matcherFromTokens(group[i], context, xml);
+ }
+
+ // Cache the compiled function
+ cached = compilerCache( selector, matcherFromGroupMatchers(group) );
+ cached.context = context;
+ cached.runs = cached.dirruns = 0;
+ return cached;
+};
+
+function multipleContexts( selector, contexts, results, seed ) {
+ var i = 0,
+ len = contexts.length;
+ for ( ; i < len; i++ ) {
+ Sizzle( selector, contexts[i], results, seed );
+ }
+}
+
+function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) {
+ var results,
+ fn = Expr.setFilters[ posfilter.toLowerCase() ];
+
+ if ( !fn ) {
+ Sizzle.error( posfilter );
+ }
+
+ if ( selector || !(results = seed) ) {
+ multipleContexts( selector || "*", contexts, (results = []), seed );
+ }
+
+ return results.length > 0 ? fn( results, argument, not ) : [];
+}
+
+function handlePOS( groups, context, results, seed ) {
+ var group, part, j, groupLen, token, selector,
+ anchor, elements, match, matched,
+ lastIndex, currentContexts, not,
+ i = 0,
+ len = groups.length,
+ rpos = matchExpr["POS"],
+ // This is generated here in case matchExpr["POS"] is extended
+ rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ),
+ // This is for making sure non-participating
+ // matching groups are represented cross-browser (IE6-8)
+ setUndefined = function() {
+ var i = 1,
+ len = arguments.length - 2;
+ for ( ; i < len; i++ ) {
+ if ( arguments[i] === undefined ) {
+ match[i] = undefined;
+ }
+ }
+ };
+
+ for ( ; i < len; i++ ) {
+ group = groups[i];
+ part = "";
+ elements = seed;
+ for ( j = 0, groupLen = group.length; j < groupLen; j++ ) {
+ token = group[j];
+ selector = token.string;
+ if ( token.part === "PSEUDO" ) {
+ // Reset regex index to 0
+ rpos.exec("");
+ anchor = 0;
+ while ( (match = rpos.exec( selector )) ) {
+ matched = true;
+ lastIndex = rpos.lastIndex = match.index + match[0].length;
+ if ( lastIndex > anchor ) {
+ part += selector.slice( anchor, match.index );
+ anchor = lastIndex;
+ currentContexts = [ context ];
+
+ if ( rcombinators.test(part) ) {
+ if ( elements ) {
+ currentContexts = elements;
+ }
+ elements = seed;
+ }
+
+ if ( (not = rendsWithNot.test( part )) ) {
+ part = part.slice( 0, -5 ).replace( rcombinators, "$&*" );
+ anchor++;
+ }
+
+ if ( match.length > 1 ) {
+ match[0].replace( rposgroups, setUndefined );
+ }
+ elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not );
+ }
+ part = "";
+ }
+
+ }
+
+ if ( !matched ) {
+ part += selector;
+ }
+ matched = false;
+ }
+
+ if ( part ) {
+ if ( rcombinators.test(part) ) {
+ multipleContexts( part, elements || [ context ], results, seed );
+ } else {
+ Sizzle( part, context, results, seed ? seed.concat(elements) : elements );
+ }
+ } else {
+ push.apply( results, elements );
+ }
+ }
+
+ // Do not sort if this is a single filter
+ return len === 1 ? results : Sizzle.uniqueSort( results );
+}
+
+function select( selector, context, results, seed, xml ) {
+ // Remove excessive whitespace
+ selector = selector.replace( rtrim, "$1" );
+ var elements, matcher, cached, elem,
+ i, tokens, token, lastToken, findContext, type,
+ match = tokenize( selector, context, xml ),
+ contextNodeType = context.nodeType;
+
+ // POS handling
+ if ( matchExpr["POS"].test(selector) ) {
+ return handlePOS( match, context, results, seed );
+ }
+
+ if ( seed ) {
+ elements = slice.call( seed, 0 );
+
+ // To maintain document order, only narrow the
+ // set if there is one group
+ } else if ( match.length === 1 ) {
+
+ // Take a shortcut and set the context if the root selector is an ID
+ if ( (tokens = slice.call( match[0], 0 )).length > 2 &&
+ (token = tokens[0]).part === "ID" &&
+ contextNodeType === 9 && !xml &&
+ Expr.relative[ tokens[1].part ] ) {
+
+ context = Expr.find["ID"]( token.captures[0].replace( rbackslash, "" ), context, xml )[0];
+ if ( !context ) {
+ return results;
+ }
+
+ selector = selector.slice( tokens.shift().string.length );
+ }
+
+ findContext = ( (match = rsibling.exec( tokens[0].string )) && !match.index && context.parentNode ) || context;
+
+ // Reduce the set if possible
+ lastToken = "";
+ for ( i = tokens.length - 1; i >= 0; i-- ) {
+ token = tokens[i];
+ type = token.part;
+ lastToken = token.string + lastToken;
+ if ( Expr.relative[ type ] ) {
+ break;
+ }
+ if ( Expr.order.test(type) ) {
+ elements = Expr.find[ type ]( token.captures[0].replace( rbackslash, "" ), findContext, xml );
+ if ( elements == null ) {
+ continue;
+ } else {
+ selector = selector.slice( 0, selector.length - lastToken.length ) +
+ lastToken.replace( matchExpr[ type ], "" );
+
+ if ( !selector ) {
+ push.apply( results, slice.call(elements, 0) );
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ // Only loop over the given elements once
+ if ( selector ) {
+ matcher = compile( selector, context, xml );
+ dirruns = matcher.dirruns++;
+ if ( elements == null ) {
+ elements = Expr.find["TAG"]( "*", (rsibling.test( selector ) && context.parentNode) || context );
+ }
+
+ for ( i = 0; (elem = elements[i]); i++ ) {
+ cachedruns = matcher.runs++;
+ if ( matcher(elem) ) {
+ results.push( elem );
+ }
+ }
+ }
+
+ return results;
+}
+
+if ( document.querySelectorAll ) {
+ (function() {
+ var disconnectedMatch,
+ oldSelect = select,
+ rescape = /'|\\/g,
+ rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
+ rbuggyQSA = [],
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+ // A support test would require too much code (would include document ready)
+ // just skip matchesSelector for :active
+ rbuggyMatches = [":active"],
+ matches = docElem.matchesSelector ||
+ docElem.mozMatchesSelector ||
+ docElem.webkitMatchesSelector ||
+ docElem.oMatchesSelector ||
+ docElem.msMatchesSelector;
+
+ // Build QSA regex
+ // Regex strategy adopted from Diego Perini
+ assert(function( div ) {
+ // Select is set to empty string on purpose
+ // This is to test IE's treatment of not explictly
+ // setting a boolean content attribute,
+ // since its presence should be enough
+ // http://bugs.jquery.com/ticket/12359
+ div.innerHTML = "<select><option selected=''></option></select>";
+
+ // IE8 - Some boolean attributes are not treated correctly
+ if ( !div.querySelectorAll("[selected]").length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
+ }
+
+ // Webkit/Opera - :checked should return selected option elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ // IE8 throws error here (do not put tests after this one)
+ if ( !div.querySelectorAll(":checked").length ) {
+ rbuggyQSA.push(":checked");
+ }
+ });
+
+ assert(function( div ) {
+
+ // Opera 10-12/IE9 - ^= $= *= and empty values
+ // Should not select anything
+ div.innerHTML = "<p test=''></p>";
+ if ( div.querySelectorAll("[test^='']").length ) {
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
+ }
+
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+ // IE8 throws error here (do not put tests after this one)
+ div.innerHTML = "<input type='hidden'/>";
+ if ( !div.querySelectorAll(":enabled").length ) {
+ rbuggyQSA.push(":enabled", ":disabled");
+ }
+ });
+
+ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+
+ select = function( selector, context, results, seed, xml ) {
+ // Only use querySelectorAll when not filtering,
+ // when this is not xml,
+ // and when no QSA bugs apply
+ if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+ if ( context.nodeType === 9 ) {
+ try {
+ push.apply( results, slice.call(context.querySelectorAll( selector ), 0) );
+ return results;
+ } catch(qsaError) {}
+ // qSA works strangely on Element-rooted queries
+ // We can work around this by specifying an extra ID on the root
+ // and working up from there (Thanks to Andrew Dupont for the technique)
+ // IE 8 doesn't work on object elements
+ } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+ var groups, i, len,
+ old = context.getAttribute("id"),
+ nid = old || expando,
+ newContext = rsibling.test( selector ) && context.parentNode || context;
+
+ if ( old ) {
+ nid = nid.replace( rescape, "\\$&" );
+ } else {
+ context.setAttribute( "id", nid );
+ }
+
+ groups = tokenize(selector, context, xml);
+ // Trailing space is unnecessary
+ // There is always a context check
+ nid = "[id='" + nid + "']";
+ for ( i = 0, len = groups.length; i < len; i++ ) {
+ groups[i] = nid + groups[i].selector;
+ }
+ try {
+ push.apply( results, slice.call( newContext.querySelectorAll(
+ groups.join(",")
+ ), 0 ) );
+ return results;
+ } catch(qsaError) {
+ } finally {
+ if ( !old ) {
+ context.removeAttribute("id");
+ }
+ }
+ }
+ }
+
+ return oldSelect( selector, context, results, seed, xml );
+ };
+
+ if ( matches ) {
+ assert(function( div ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9)
+ disconnectedMatch = matches.call( div, "div" );
+
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ try {
+ matches.call( div, "[test!='']:sizzle" );
+ rbuggyMatches.push( matchExpr["PSEUDO"].source, matchExpr["POS"].source, "!=" );
+ } catch ( e ) {}
+ });
+
+ // rbuggyMatches always contains :active, so no need for a length check
+ rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
+
+ Sizzle.matchesSelector = function( elem, expr ) {
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace( rattributeQuotes, "='$1']" );
+
+ // rbuggyMatches always contains :active, so no need for an existence check
+ if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) {
+ try {
+ var ret = matches.call( elem, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9
+ elem.document && elem.document.nodeType !== 11 ) {
+ return ret;
+ }
+ } catch(e) {}
+ }
+
+ return Sizzle( expr, null, null, [ elem ] ).length > 0;
+ };
+ }
+ })();
+}
+
+// Deprecated
+Expr.setFilters["nth"] = Expr.setFilters["eq"];
+
+// Back-compat
+Expr.filters = Expr.pseudos;
+
// Override sizzle attribute retrieval
Sizzle.attr = jQuery.attr;
jQuery.find = Sizzle;
@@ -5197,9 +5197,9 @@ jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;
-
-
-})( window );
+
+
+})( window );
var runtil = /Until$/,
rparentsprev = /^(?:parents|prev(?:Until|All))/,
isSimple = /^.[^:#\[\.,]*$/,
diff --git a/tests/jquery-1.8.2.js b/tests/jquery-1.8.2.js
index d4f3bb38c..12c7797fd 100644
--- a/tests/jquery-1.8.2.js
+++ b/tests/jquery-1.8.2.js
@@ -3665,1667 +3665,1667 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
}
});
-/*!
- * Sizzle CSS Selector Engine
- * Copyright 2012 jQuery Foundation and other contributors
- * Released under the MIT license
- * http://sizzlejs.com/
- */
-(function( window, undefined ) {
-
-var cachedruns,
- assertGetIdNotName,
- Expr,
- getText,
- isXML,
- contains,
- compile,
- sortOrder,
- hasDuplicate,
- outermostContext,
-
- baseHasDuplicate = true,
- strundefined = "undefined",
-
- expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
-
- Token = String,
- document = window.document,
- docElem = document.documentElement,
- dirruns = 0,
- done = 0,
- pop = [].pop,
- push = [].push,
- slice = [].slice,
- // Use a stripped-down indexOf if a native one is unavailable
- indexOf = [].indexOf || function( elem ) {
- var i = 0,
- len = this.length;
- for ( ; i < len; i++ ) {
- if ( this[i] === elem ) {
- return i;
- }
- }
- return -1;
- },
-
- // Augment a function for special use by Sizzle
- markFunction = function( fn, value ) {
- fn[ expando ] = value == null || value;
- return fn;
- },
-
- createCache = function() {
- var cache = {},
- keys = [];
-
- return markFunction(function( key, value ) {
- // Only keep the most recent entries
- if ( keys.push( key ) > Expr.cacheLength ) {
- delete cache[ keys.shift() ];
- }
-
- return (cache[ key ] = value);
- }, cache );
- },
-
- classCache = createCache(),
- tokenCache = createCache(),
- compilerCache = createCache(),
-
- // Regex
-
- // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
- whitespace = "[\\x20\\t\\r\\n\\f]",
- // http://www.w3.org/TR/css3-syntax/#characters
- characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
-
- // Loosely modeled on CSS identifier characters
- // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)
- // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
- identifier = characterEncoding.replace( "w", "w#" ),
-
- // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
- operators = "([*^$|!~]?=)",
- attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
- "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
-
- // Prefer arguments not in parens/brackets,
- // then attribute selectors and non-pseudos (denoted by :),
- // then anything else
- // These preferences are here to reduce the number of selectors
- // needing tokenize in the PSEUDO preFilter
- pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",
-
- // For matchExpr.POS and matchExpr.needsContext
- pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
- "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)",
-
- // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
- rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
-
- rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
- rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
- rpseudo = new RegExp( pseudos ),
-
- // Easily-parseable/retrievable ID or TAG or CLASS selectors
- rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
-
- rnot = /^:not/,
- rsibling = /[\x20\t\r\n\f]*[+~]/,
- rendsWithNot = /:not\($/,
-
- rheader = /h\d/i,
- rinputs = /input|select|textarea|button/i,
-
- rbackslash = /\\(?!\\)/g,
-
- matchExpr = {
- "ID": new RegExp( "^#(" + characterEncoding + ")" ),
- "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
- "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
- "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
- "ATTR": new RegExp( "^" + attributes ),
- "PSEUDO": new RegExp( "^" + pseudos ),
- "POS": new RegExp( pos, "i" ),
- "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace +
- "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
- "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
- // For use in libraries implementing .is()
- "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
- },
-
- // Support
-
- // Used for testing something on an element
- assert = function( fn ) {
- var div = document.createElement("div");
-
- try {
- return fn( div );
- } catch (e) {
- return false;
- } finally {
- // release memory in IE
- div = null;
- }
- },
-
- // Check if getElementsByTagName("*") returns only elements
- assertTagNameNoComments = assert(function( div ) {
- div.appendChild( document.createComment("") );
- return !div.getElementsByTagName("*").length;
- }),
-
- // Check if getAttribute returns normalized href attributes
- assertHrefNotNormalized = assert(function( div ) {
- div.innerHTML = "<a href='#'></a>";
- return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
- div.firstChild.getAttribute("href") === "#";
- }),
-
- // Check if attributes should be retrieved by attribute nodes
- assertAttributes = assert(function( div ) {
- div.innerHTML = "<select></select>";
- var type = typeof div.lastChild.getAttribute("multiple");
- // IE8 returns a string for some attributes even when not present
- return type !== "boolean" && type !== "string";
- }),
-
- // Check if getElementsByClassName can be trusted
- assertUsableClassName = assert(function( div ) {
- // Opera can't find a second classname (in 9.6)
- div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
- if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
- return false;
- }
-
- // Safari 3.2 caches class attributes and doesn't catch changes
- div.lastChild.className = "e";
- return div.getElementsByClassName("e").length === 2;
- }),
-
- // Check if getElementById returns elements by name
- // Check if getElementsByName privileges form controls or returns elements by ID
- assertUsableName = assert(function( div ) {
- // Inject content
- div.id = expando + 0;
- div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
- docElem.insertBefore( div, docElem.firstChild );
-
- // Test
- var pass = document.getElementsByName &&
- // buggy browsers will return fewer than the correct 2
- document.getElementsByName( expando ).length === 2 +
- // buggy browsers will return more than the correct 0
- document.getElementsByName( expando + 0 ).length;
- assertGetIdNotName = !document.getElementById( expando );
-
- // Cleanup
- docElem.removeChild( div );
-
- return pass;
- });
-
-// If slice is not available, provide a backup
-try {
- slice.call( docElem.childNodes, 0 )[0].nodeType;
-} catch ( e ) {
- slice = function( i ) {
- var elem,
- results = [];
- for ( ; (elem = this[i]); i++ ) {
- results.push( elem );
- }
- return results;
- };
-}
-
-function Sizzle( selector, context, results, seed ) {
- results = results || [];
- context = context || document;
- var match, elem, xml, m,
- nodeType = context.nodeType;
-
- if ( !selector || typeof selector !== "string" ) {
- return results;
- }
-
- if ( nodeType !== 1 && nodeType !== 9 ) {
- return [];
- }
-
- xml = isXML( context );
-
- if ( !xml && !seed ) {
- if ( (match = rquickExpr.exec( selector )) ) {
- // Speed-up: Sizzle("#ID")
- if ( (m = match[1]) ) {
- if ( nodeType === 9 ) {
- elem = context.getElementById( m );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- if ( elem && elem.parentNode ) {
- // Handle the case where IE, Opera, and Webkit return items
- // by name instead of ID
- if ( elem.id === m ) {
- results.push( elem );
- return results;
- }
- } else {
- return results;
- }
- } else {
- // Context is not a document
- if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
- contains( context, elem ) && elem.id === m ) {
- results.push( elem );
- return results;
- }
- }
-
- // Speed-up: Sizzle("TAG")
- } else if ( match[2] ) {
- push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
- return results;
-
- // Speed-up: Sizzle(".CLASS")
- } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
- push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
- return results;
- }
- }
- }
-
- // All others
- return select( selector.replace( rtrim, "$1" ), context, results, seed, xml );
-}
-
-Sizzle.matches = function( expr, elements ) {
- return Sizzle( expr, null, null, elements );
-};
-
-Sizzle.matchesSelector = function( elem, expr ) {
- return Sizzle( expr, null, null, [ elem ] ).length > 0;
-};
-
-// Returns a function to use in pseudos for input types
-function createInputPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === type;
- };
-}
-
-// Returns a function to use in pseudos for buttons
-function createButtonPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return (name === "input" || name === "button") && elem.type === type;
- };
-}
-
-// Returns a function to use in pseudos for positionals
-function createPositionalPseudo( fn ) {
- return markFunction(function( argument ) {
- argument = +argument;
- return markFunction(function( seed, matches ) {
- var j,
- matchIndexes = fn( [], seed.length, argument ),
- i = matchIndexes.length;
-
- // Match elements found at the specified indexes
- while ( i-- ) {
- if ( seed[ (j = matchIndexes[i]) ] ) {
- seed[j] = !(matches[j] = seed[j]);
- }
- }
- });
- });
-}
-
-/**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-getText = Sizzle.getText = function( elem ) {
- var node,
- ret = "",
- i = 0,
- nodeType = elem.nodeType;
-
- if ( nodeType ) {
- if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
- // Use textContent for elements
- // innerText usage removed for consistency of new lines (see #11153)
- if ( typeof elem.textContent === "string" ) {
- return elem.textContent;
- } else {
- // Traverse its children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
- ret += getText( elem );
- }
- }
- } else if ( nodeType === 3 || nodeType === 4 ) {
- return elem.nodeValue;
- }
- // Do not include comment or processing instruction nodes
- } else {
-
- // If no nodeType, this is expected to be an array
- for ( ; (node = elem[i]); i++ ) {
- // Do not traverse comment nodes
- ret += getText( node );
- }
- }
- return ret;
-};
-
-isXML = Sizzle.isXML = function( elem ) {
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = elem && (elem.ownerDocument || elem).documentElement;
- return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-// Element contains another
-contains = Sizzle.contains = docElem.contains ?
- function( a, b ) {
- var adown = a.nodeType === 9 ? a.documentElement : a,
- bup = b && b.parentNode;
- return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
- } :
- docElem.compareDocumentPosition ?
- function( a, b ) {
- return b && !!( a.compareDocumentPosition( b ) & 16 );
- } :
- function( a, b ) {
- while ( (b = b.parentNode) ) {
- if ( b === a ) {
- return true;
- }
- }
- return false;
- };
-
-Sizzle.attr = function( elem, name ) {
- var val,
- xml = isXML( elem );
-
- if ( !xml ) {
- name = name.toLowerCase();
- }
- if ( (val = Expr.attrHandle[ name ]) ) {
- return val( elem );
- }
- if ( xml || assertAttributes ) {
- return elem.getAttribute( name );
- }
- val = elem.getAttributeNode( name );
- return val ?
- typeof elem[ name ] === "boolean" ?
- elem[ name ] ? name : null :
- val.specified ? val.value : null :
- null;
-};
-
-Expr = Sizzle.selectors = {
-
- // Can be adjusted by the user
- cacheLength: 50,
-
- createPseudo: markFunction,
-
- match: matchExpr,
-
- // IE6/7 return a modified href
- attrHandle: assertHrefNotNormalized ?
- {} :
- {
- "href": function( elem ) {
- return elem.getAttribute( "href", 2 );
- },
- "type": function( elem ) {
- return elem.getAttribute("type");
- }
- },
-
- find: {
- "ID": assertGetIdNotName ?
- function( id, context, xml ) {
- if ( typeof context.getElementById !== strundefined && !xml ) {
- var m = context.getElementById( id );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- return m && m.parentNode ? [m] : [];
- }
- } :
- function( id, context, xml ) {
- if ( typeof context.getElementById !== strundefined && !xml ) {
- var m = context.getElementById( id );
-
- return m ?
- m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
- [m] :
- undefined :
- [];
- }
- },
-
- "TAG": assertTagNameNoComments ?
- function( tag, context ) {
- if ( typeof context.getElementsByTagName !== strundefined ) {
- return context.getElementsByTagName( tag );
- }
- } :
- function( tag, context ) {
- var results = context.getElementsByTagName( tag );
-
- // Filter out possible comments
- if ( tag === "*" ) {
- var elem,
- tmp = [],
- i = 0;
-
- for ( ; (elem = results[i]); i++ ) {
- if ( elem.nodeType === 1 ) {
- tmp.push( elem );
- }
- }
-
- return tmp;
- }
- return results;
- },
-
- "NAME": assertUsableName && function( tag, context ) {
- if ( typeof context.getElementsByName !== strundefined ) {
- return context.getElementsByName( name );
- }
- },
-
- "CLASS": assertUsableClassName && function( className, context, xml ) {
- if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
- return context.getElementsByClassName( className );
- }
- }
- },
-
- relative: {
- ">": { dir: "parentNode", first: true },
- " ": { dir: "parentNode" },
- "+": { dir: "previousSibling", first: true },
- "~": { dir: "previousSibling" }
- },
-
- preFilter: {
- "ATTR": function( match ) {
- match[1] = match[1].replace( rbackslash, "" );
-
- // Move the given value to match[3] whether quoted or unquoted
- match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
-
- if ( match[2] === "~=" ) {
- match[3] = " " + match[3] + " ";
- }
-
- return match.slice( 0, 4 );
- },
-
- "CHILD": function( match ) {
- /* matches from matchExpr["CHILD"]
- 1 type (only|nth|...)
- 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
- 3 xn-component of xn+y argument ([+-]?\d*n|)
- 4 sign of xn-component
- 5 x of xn-component
- 6 sign of y-component
- 7 y of y-component
- */
- match[1] = match[1].toLowerCase();
-
- if ( match[1] === "nth" ) {
- // nth-child requires argument
- if ( !match[2] ) {
- Sizzle.error( match[0] );
- }
-
- // numeric x and y parameters for Expr.filter.CHILD
- // remember that false/true cast respectively to 0/1
- match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
- match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
-
- // other types prohibit arguments
- } else if ( match[2] ) {
- Sizzle.error( match[0] );
- }
-
- return match;
- },
-
- "PSEUDO": function( match ) {
- var unquoted, excess;
- if ( matchExpr["CHILD"].test( match[0] ) ) {
- return null;
- }
-
- if ( match[3] ) {
- match[2] = match[3];
- } else if ( (unquoted = match[4]) ) {
- // Only check arguments that contain a pseudo
- if ( rpseudo.test(unquoted) &&
- // Get excess from tokenize (recursively)
- (excess = tokenize( unquoted, true )) &&
- // advance to the next closing parenthesis
- (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
-
- // excess is a negative index
- unquoted = unquoted.slice( 0, excess );
- match[0] = match[0].slice( 0, excess );
- }
- match[2] = unquoted;
- }
-
- // Return only captures needed by the pseudo filter method (type and argument)
- return match.slice( 0, 3 );
- }
- },
-
- filter: {
- "ID": assertGetIdNotName ?
- function( id ) {
- id = id.replace( rbackslash, "" );
- return function( elem ) {
- return elem.getAttribute("id") === id;
- };
- } :
- function( id ) {
- id = id.replace( rbackslash, "" );
- return function( elem ) {
- var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
- return node && node.value === id;
- };
- },
-
- "TAG": function( nodeName ) {
- if ( nodeName === "*" ) {
- return function() { return true; };
- }
- nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
-
- return function( elem ) {
- return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
- };
- },
-
- "CLASS": function( className ) {
- var pattern = classCache[ expando ][ className ];
- if ( !pattern ) {
- pattern = classCache( className, new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)") );
- }
- return function( elem ) {
- return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
- };
- },
-
- "ATTR": function( name, operator, check ) {
- return function( elem, context ) {
- var result = Sizzle.attr( elem, name );
-
- if ( result == null ) {
- return operator === "!=";
- }
- if ( !operator ) {
- return true;
- }
-
- result += "";
-
- return operator === "=" ? result === check :
- operator === "!=" ? result !== check :
- operator === "^=" ? check && result.indexOf( check ) === 0 :
- operator === "*=" ? check && result.indexOf( check ) > -1 :
- operator === "$=" ? check && result.substr( result.length - check.length ) === check :
- operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
- operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" :
- false;
- };
- },
-
- "CHILD": function( type, argument, first, last ) {
-
- if ( type === "nth" ) {
- return function( elem ) {
- var node, diff,
- parent = elem.parentNode;
-
- if ( first === 1 && last === 0 ) {
- return true;
- }
-
- if ( parent ) {
- diff = 0;
- for ( node = parent.firstChild; node; node = node.nextSibling ) {
- if ( node.nodeType === 1 ) {
- diff++;
- if ( elem === node ) {
- break;
- }
- }
- }
- }
-
- // Incorporate the offset (or cast to NaN), then check against cycle size
- diff -= last;
- return diff === first || ( diff % first === 0 && diff / first >= 0 );
- };
- }
-
- return function( elem ) {
- var node = elem;
-
- switch ( type ) {
- case "only":
- case "first":
- while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
-
- if ( type === "first" ) {
- return true;
- }
-
- node = elem;
-
- /* falls through */
- case "last":
- while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
-
- return true;
- }
- };
- },
-
- "PSEUDO": function( pseudo, argument ) {
- // pseudo-class names are case-insensitive
- // http://www.w3.org/TR/selectors/#pseudo-classes
- // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
- // Remember that setFilters inherits from pseudos
- var args,
- fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
- Sizzle.error( "unsupported pseudo: " + pseudo );
-
- // The user may use createPseudo to indicate that
- // arguments are needed to create the filter function
- // just as Sizzle does
- if ( fn[ expando ] ) {
- return fn( argument );
- }
-
- // But maintain support for old signatures
- if ( fn.length > 1 ) {
- args = [ pseudo, pseudo, "", argument ];
- return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
- markFunction(function( seed, matches ) {
- var idx,
- matched = fn( seed, argument ),
- i = matched.length;
- while ( i-- ) {
- idx = indexOf.call( seed, matched[i] );
- seed[ idx ] = !( matches[ idx ] = matched[i] );
- }
- }) :
- function( elem ) {
- return fn( elem, 0, args );
- };
- }
-
- return fn;
- }
- },
-
- pseudos: {
- "not": markFunction(function( selector ) {
- // Trim the selector passed to compile
- // to avoid treating leading and trailing
- // spaces as combinators
- var input = [],
- results = [],
- matcher = compile( selector.replace( rtrim, "$1" ) );
-
- return matcher[ expando ] ?
- markFunction(function( seed, matches, context, xml ) {
- var elem,
- unmatched = matcher( seed, null, xml, [] ),
- i = seed.length;
-
- // Match elements unmatched by `matcher`
- while ( i-- ) {
- if ( (elem = unmatched[i]) ) {
- seed[i] = !(matches[i] = elem);
- }
- }
- }) :
- function( elem, context, xml ) {
- input[0] = elem;
- matcher( input, null, xml, results );
- return !results.pop();
- };
- }),
-
- "has": markFunction(function( selector ) {
- return function( elem ) {
- return Sizzle( selector, elem ).length > 0;
- };
- }),
-
- "contains": markFunction(function( text ) {
- return function( elem ) {
- return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
- };
- }),
-
- "enabled": function( elem ) {
- return elem.disabled === false;
- },
-
- "disabled": function( elem ) {
- return elem.disabled === true;
- },
-
- "checked": function( elem ) {
- // In CSS3, :checked should return both checked and selected elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- var nodeName = elem.nodeName.toLowerCase();
- return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
- },
-
- "selected": function( elem ) {
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- if ( elem.parentNode ) {
- elem.parentNode.selectedIndex;
- }
-
- return elem.selected === true;
- },
-
- "parent": function( elem ) {
- return !Expr.pseudos["empty"]( elem );
- },
-
- "empty": function( elem ) {
- // http://www.w3.org/TR/selectors/#empty-pseudo
- // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
- // not comment, processing instructions, or others
- // Thanks to Diego Perini for the nodeName shortcut
- // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
- var nodeType;
- elem = elem.firstChild;
- while ( elem ) {
- if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
- return false;
- }
- elem = elem.nextSibling;
- }
- return true;
- },
-
- "header": function( elem ) {
- return rheader.test( elem.nodeName );
- },
-
- "text": function( elem ) {
- var type, attr;
- // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
- // use getAttribute instead to test this case
- return elem.nodeName.toLowerCase() === "input" &&
- (type = elem.type) === "text" &&
- ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
- },
-
- // Input types
- "radio": createInputPseudo("radio"),
- "checkbox": createInputPseudo("checkbox"),
- "file": createInputPseudo("file"),
- "password": createInputPseudo("password"),
- "image": createInputPseudo("image"),
-
- "submit": createButtonPseudo("submit"),
- "reset": createButtonPseudo("reset"),
-
- "button": function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === "button" || name === "button";
- },
-
- "input": function( elem ) {
- return rinputs.test( elem.nodeName );
- },
-
- "focus": function( elem ) {
- var doc = elem.ownerDocument;
- return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href);
- },
-
- "active": function( elem ) {
- return elem === elem.ownerDocument.activeElement;
- },
-
- // Positional types
- "first": createPositionalPseudo(function( matchIndexes, length, argument ) {
- return [ 0 ];
- }),
-
- "last": createPositionalPseudo(function( matchIndexes, length, argument ) {
- return [ length - 1 ];
- }),
-
- "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
- return [ argument < 0 ? argument + length : argument ];
- }),
-
- "even": createPositionalPseudo(function( matchIndexes, length, argument ) {
- for ( var i = 0; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "odd": createPositionalPseudo(function( matchIndexes, length, argument ) {
- for ( var i = 1; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
- for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
- for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- })
- }
-};
-
-function siblingCheck( a, b, ret ) {
- if ( a === b ) {
- return ret;
- }
-
- var cur = a.nextSibling;
-
- while ( cur ) {
- if ( cur === b ) {
- return -1;
- }
-
- cur = cur.nextSibling;
- }
-
- return 1;
-}
-
-sortOrder = docElem.compareDocumentPosition ?
- function( a, b ) {
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
- a.compareDocumentPosition :
- a.compareDocumentPosition(b) & 4
- ) ? -1 : 1;
- } :
- function( a, b ) {
- // The nodes are identical, we can exit early
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
-
- // Fallback to using sourceIndex (in IE) if it's available on both nodes
- } else if ( a.sourceIndex && b.sourceIndex ) {
- return a.sourceIndex - b.sourceIndex;
- }
-
- var al, bl,
- ap = [],
- bp = [],
- aup = a.parentNode,
- bup = b.parentNode,
- cur = aup;
-
- // If the nodes are siblings (or identical) we can do a quick check
- if ( aup === bup ) {
- return siblingCheck( a, b );
-
- // If no parents were found then the nodes are disconnected
- } else if ( !aup ) {
- return -1;
-
- } else if ( !bup ) {
- return 1;
- }
-
- // Otherwise they're somewhere else in the tree so we need
- // to build up a full list of the parentNodes for comparison
- while ( cur ) {
- ap.unshift( cur );
- cur = cur.parentNode;
- }
-
- cur = bup;
-
- while ( cur ) {
- bp.unshift( cur );
- cur = cur.parentNode;
- }
-
- al = ap.length;
- bl = bp.length;
-
- // Start walking down the tree looking for a discrepancy
- for ( var i = 0; i < al && i < bl; i++ ) {
- if ( ap[i] !== bp[i] ) {
- return siblingCheck( ap[i], bp[i] );
- }
- }
-
- // We ended someplace up the tree so do a sibling check
- return i === al ?
- siblingCheck( a, bp[i], -1 ) :
- siblingCheck( ap[i], b, 1 );
- };
-
-// Always assume the presence of duplicates if sort doesn't
-// pass them to our comparison function (as in Google Chrome).
-[0, 0].sort( sortOrder );
-baseHasDuplicate = !hasDuplicate;
-
-// Document sorting and removing duplicates
-Sizzle.uniqueSort = function( results ) {
- var elem,
- i = 1;
-
- hasDuplicate = baseHasDuplicate;
- results.sort( sortOrder );
-
- if ( hasDuplicate ) {
- for ( ; (elem = results[i]); i++ ) {
- if ( elem === results[ i - 1 ] ) {
- results.splice( i--, 1 );
- }
- }
- }
-
- return results;
-};
-
-Sizzle.error = function( msg ) {
- throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
-
-function tokenize( selector, parseOnly ) {
- var matched, match, tokens, type, soFar, groups, preFilters,
- cached = tokenCache[ expando ][ selector ];
-
- if ( cached ) {
- return parseOnly ? 0 : cached.slice( 0 );
- }
-
- soFar = selector;
- groups = [];
- preFilters = Expr.preFilter;
-
- while ( soFar ) {
-
- // Comma and first run
- if ( !matched || (match = rcomma.exec( soFar )) ) {
- if ( match ) {
- soFar = soFar.slice( match[0].length );
- }
- groups.push( tokens = [] );
- }
-
- matched = false;
-
- // Combinators
- if ( (match = rcombinators.exec( soFar )) ) {
- tokens.push( matched = new Token( match.shift() ) );
- soFar = soFar.slice( matched.length );
-
- // Cast descendant combinators to space
- matched.type = match[0].replace( rtrim, " " );
- }
-
- // Filters
- for ( type in Expr.filter ) {
- if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
- // The last two arguments here are (context, xml) for backCompat
- (match = preFilters[ type ]( match, document, true ))) ) {
-
- tokens.push( matched = new Token( match.shift() ) );
- soFar = soFar.slice( matched.length );
- matched.type = type;
- matched.matches = match;
- }
- }
-
- if ( !matched ) {
- break;
- }
- }
-
- // Return the length of the invalid excess
- // if we're just parsing
- // Otherwise, throw an error or return tokens
- return parseOnly ?
- soFar.length :
- soFar ?
- Sizzle.error( selector ) :
- // Cache the tokens
- tokenCache( selector, groups ).slice( 0 );
-}
-
-function addCombinator( matcher, combinator, base ) {
- var dir = combinator.dir,
- checkNonElements = base && combinator.dir === "parentNode",
- doneName = done++;
-
- return combinator.first ?
- // Check against closest ancestor/preceding element
- function( elem, context, xml ) {
- while ( (elem = elem[ dir ]) ) {
- if ( checkNonElements || elem.nodeType === 1 ) {
- return matcher( elem, context, xml );
- }
- }
- } :
-
- // Check against all ancestor/preceding elements
- function( elem, context, xml ) {
- // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
- if ( !xml ) {
- var cache,
- dirkey = dirruns + " " + doneName + " ",
- cachedkey = dirkey + cachedruns;
- while ( (elem = elem[ dir ]) ) {
- if ( checkNonElements || elem.nodeType === 1 ) {
- if ( (cache = elem[ expando ]) === cachedkey ) {
- return elem.sizset;
- } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
- if ( elem.sizset ) {
- return elem;
- }
- } else {
- elem[ expando ] = cachedkey;
- if ( matcher( elem, context, xml ) ) {
- elem.sizset = true;
- return elem;
- }
- elem.sizset = false;
- }
- }
- }
- } else {
- while ( (elem = elem[ dir ]) ) {
- if ( checkNonElements || elem.nodeType === 1 ) {
- if ( matcher( elem, context, xml ) ) {
- return elem;
- }
- }
- }
- }
- };
-}
-
-function elementMatcher( matchers ) {
- return matchers.length > 1 ?
- function( elem, context, xml ) {
- var i = matchers.length;
- while ( i-- ) {
- if ( !matchers[i]( elem, context, xml ) ) {
- return false;
- }
- }
- return true;
- } :
- matchers[0];
-}
-
-function condense( unmatched, map, filter, context, xml ) {
- var elem,
- newUnmatched = [],
- i = 0,
- len = unmatched.length,
- mapped = map != null;
-
- for ( ; i < len; i++ ) {
- if ( (elem = unmatched[i]) ) {
- if ( !filter || filter( elem, context, xml ) ) {
- newUnmatched.push( elem );
- if ( mapped ) {
- map.push( i );
- }
- }
- }
- }
-
- return newUnmatched;
-}
-
-function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
- if ( postFilter && !postFilter[ expando ] ) {
- postFilter = setMatcher( postFilter );
- }
- if ( postFinder && !postFinder[ expando ] ) {
- postFinder = setMatcher( postFinder, postSelector );
- }
- return markFunction(function( seed, results, context, xml ) {
- // Positional selectors apply to seed elements, so it is invalid to follow them with relative ones
- if ( seed && postFinder ) {
- return;
- }
-
- var i, elem, postFilterIn,
- preMap = [],
- postMap = [],
- preexisting = results.length,
-
- // Get initial elements from seed or context
- elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [], seed ),
-
- // Prefilter to get matcher input, preserving a map for seed-results synchronization
- matcherIn = preFilter && ( seed || !selector ) ?
- condense( elems, preMap, preFilter, context, xml ) :
- elems,
-
- matcherOut = matcher ?
- // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
- postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
-
- // ...intermediate processing is necessary
- [] :
-
- // ...otherwise use results directly
- results :
- matcherIn;
-
- // Find primary matches
- if ( matcher ) {
- matcher( matcherIn, matcherOut, context, xml );
- }
-
- // Apply postFilter
- if ( postFilter ) {
- postFilterIn = condense( matcherOut, postMap );
- postFilter( postFilterIn, [], context, xml );
-
- // Un-match failing elements by moving them back to matcherIn
- i = postFilterIn.length;
- while ( i-- ) {
- if ( (elem = postFilterIn[i]) ) {
- matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
- }
- }
- }
-
- // Keep seed and results synchronized
- if ( seed ) {
- // Ignore postFinder because it can't coexist with seed
- i = preFilter && matcherOut.length;
- while ( i-- ) {
- if ( (elem = matcherOut[i]) ) {
- seed[ preMap[i] ] = !(results[ preMap[i] ] = elem);
- }
- }
- } else {
- matcherOut = condense(
- matcherOut === results ?
- matcherOut.splice( preexisting, matcherOut.length ) :
- matcherOut
- );
- if ( postFinder ) {
- postFinder( null, results, matcherOut, xml );
- } else {
- push.apply( results, matcherOut );
- }
- }
- });
-}
-
-function matcherFromTokens( tokens ) {
- var checkContext, matcher, j,
- len = tokens.length,
- leadingRelative = Expr.relative[ tokens[0].type ],
- implicitRelative = leadingRelative || Expr.relative[" "],
- i = leadingRelative ? 1 : 0,
-
- // The foundational matcher ensures that elements are reachable from top-level context(s)
- matchContext = addCombinator( function( elem ) {
- return elem === checkContext;
- }, implicitRelative, true ),
- matchAnyContext = addCombinator( function( elem ) {
- return indexOf.call( checkContext, elem ) > -1;
- }, implicitRelative, true ),
- matchers = [ function( elem, context, xml ) {
- return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
- (checkContext = context).nodeType ?
- matchContext( elem, context, xml ) :
- matchAnyContext( elem, context, xml ) );
- } ];
-
- for ( ; i < len; i++ ) {
- if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
- matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
- } else {
- // The concatenated values are (context, xml) for backCompat
- matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
-
- // Return special upon seeing a positional matcher
- if ( matcher[ expando ] ) {
- // Find the next relative operator (if any) for proper handling
- j = ++i;
- for ( ; j < len; j++ ) {
- if ( Expr.relative[ tokens[j].type ] ) {
- break;
- }
- }
- return setMatcher(
- i > 1 && elementMatcher( matchers ),
- i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ),
- matcher,
- i < j && matcherFromTokens( tokens.slice( i, j ) ),
- j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
- j < len && tokens.join("")
- );
- }
- matchers.push( matcher );
- }
- }
-
- return elementMatcher( matchers );
-}
-
-function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
- var bySet = setMatchers.length > 0,
- byElement = elementMatchers.length > 0,
- superMatcher = function( seed, context, xml, results, expandContext ) {
- var elem, j, matcher,
- setMatched = [],
- matchedCount = 0,
- i = "0",
- unmatched = seed && [],
- outermost = expandContext != null,
- contextBackup = outermostContext,
- // We must always have either seed elements or context
- elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
- // Nested matchers should use non-integer dirruns
- dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);
-
- if ( outermost ) {
- outermostContext = context !== document && context;
- cachedruns = superMatcher.el;
- }
-
- // Add elements passing elementMatchers directly to results
- for ( ; (elem = elems[i]) != null; i++ ) {
- if ( byElement && elem ) {
- for ( j = 0; (matcher = elementMatchers[j]); j++ ) {
- if ( matcher( elem, context, xml ) ) {
- results.push( elem );
- break;
- }
- }
- if ( outermost ) {
- dirruns = dirrunsUnique;
- cachedruns = ++superMatcher.el;
- }
- }
-
- // Track unmatched elements for set filters
- if ( bySet ) {
- // They will have gone through all possible matchers
- if ( (elem = !matcher && elem) ) {
- matchedCount--;
- }
-
- // Lengthen the array for every element, matched or not
- if ( seed ) {
- unmatched.push( elem );
- }
- }
- }
-
- // Apply set filters to unmatched elements
- matchedCount += i;
- if ( bySet && i !== matchedCount ) {
- for ( j = 0; (matcher = setMatchers[j]); j++ ) {
- matcher( unmatched, setMatched, context, xml );
- }
-
- if ( seed ) {
- // Reintegrate element matches to eliminate the need for sorting
- if ( matchedCount > 0 ) {
- while ( i-- ) {
- if ( !(unmatched[i] || setMatched[i]) ) {
- setMatched[i] = pop.call( results );
- }
- }
- }
-
- // Discard index placeholder values to get only actual matches
- setMatched = condense( setMatched );
- }
-
- // Add matches to results
- push.apply( results, setMatched );
-
- // Seedless set matches succeeding multiple successful matchers stipulate sorting
- if ( outermost && !seed && setMatched.length > 0 &&
- ( matchedCount + setMatchers.length ) > 1 ) {
-
- Sizzle.uniqueSort( results );
- }
- }
-
- // Override manipulation of globals by nested matchers
- if ( outermost ) {
- dirruns = dirrunsUnique;
- outermostContext = contextBackup;
- }
-
- return unmatched;
- };
-
- superMatcher.el = 0;
- return bySet ?
- markFunction( superMatcher ) :
- superMatcher;
-}
-
-compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
- var i,
- setMatchers = [],
- elementMatchers = [],
- cached = compilerCache[ expando ][ selector ];
-
- if ( !cached ) {
- // Generate a function of recursive functions that can be used to check each element
- if ( !group ) {
- group = tokenize( selector );
- }
- i = group.length;
- while ( i-- ) {
- cached = matcherFromTokens( group[i] );
- if ( cached[ expando ] ) {
- setMatchers.push( cached );
- } else {
- elementMatchers.push( cached );
- }
- }
-
- // Cache the compiled function
- cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
- }
- return cached;
-};
-
-function multipleContexts( selector, contexts, results, seed ) {
- var i = 0,
- len = contexts.length;
- for ( ; i < len; i++ ) {
- Sizzle( selector, contexts[i], results, seed );
- }
- return results;
-}
-
-function select( selector, context, results, seed, xml ) {
- var i, tokens, token, type, find,
- match = tokenize( selector ),
- j = match.length;
-
- if ( !seed ) {
- // Try to minimize operations if there is only one group
- if ( match.length === 1 ) {
-
- // Take a shortcut and set the context if the root selector is an ID
- tokens = match[0] = match[0].slice( 0 );
- if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
- context.nodeType === 9 && !xml &&
- Expr.relative[ tokens[1].type ] ) {
-
- context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0];
- if ( !context ) {
- return results;
- }
-
- selector = selector.slice( tokens.shift().length );
- }
-
- // Fetch a seed set for right-to-left matching
- for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {
- token = tokens[i];
-
- // Abort if we hit a combinator
- if ( Expr.relative[ (type = token.type) ] ) {
- break;
- }
- if ( (find = Expr.find[ type ]) ) {
- // Search, expanding context for leading sibling combinators
- if ( (seed = find(
- token.matches[0].replace( rbackslash, "" ),
- rsibling.test( tokens[0].type ) && context.parentNode || context,
- xml
- )) ) {
-
- // If seed is empty or no tokens remain, we can return early
- tokens.splice( i, 1 );
- selector = seed.length && tokens.join("");
- if ( !selector ) {
- push.apply( results, slice.call( seed, 0 ) );
- return results;
- }
-
- break;
- }
- }
- }
- }
- }
-
- // Compile and execute a filtering function
- // Provide `match` to avoid retokenization if we modified the selector above
- compile( selector, match )(
- seed,
- context,
- xml,
- results,
- rsibling.test( selector )
- );
- return results;
-}
-
-if ( document.querySelectorAll ) {
- (function() {
- var disconnectedMatch,
- oldSelect = select,
- rescape = /'|\\/g,
- rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
-
- // qSa(:focus) reports false when true (Chrome 21),
- // A support test would require too much code (would include document ready)
- rbuggyQSA = [":focus"],
-
- // matchesSelector(:focus) reports false when true (Chrome 21),
- // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
- // A support test would require too much code (would include document ready)
- // just skip matchesSelector for :active
- rbuggyMatches = [ ":active", ":focus" ],
- matches = docElem.matchesSelector ||
- docElem.mozMatchesSelector ||
- docElem.webkitMatchesSelector ||
- docElem.oMatchesSelector ||
- docElem.msMatchesSelector;
-
- // Build QSA regex
- // Regex strategy adopted from Diego Perini
- assert(function( div ) {
- // Select is set to empty string on purpose
- // This is to test IE's treatment of not explictly
- // setting a boolean content attribute,
- // since its presence should be enough
- // http://bugs.jquery.com/ticket/12359
- div.innerHTML = "<select><option selected=''></option></select>";
-
- // IE8 - Some boolean attributes are not treated correctly
- if ( !div.querySelectorAll("[selected]").length ) {
- rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
- }
-
- // Webkit/Opera - :checked should return selected option elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- // IE8 throws error here (do not put tests after this one)
- if ( !div.querySelectorAll(":checked").length ) {
- rbuggyQSA.push(":checked");
- }
- });
-
- assert(function( div ) {
-
- // Opera 10-12/IE9 - ^= $= *= and empty values
- // Should not select anything
- div.innerHTML = "<p test=''></p>";
- if ( div.querySelectorAll("[test^='']").length ) {
- rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
- }
-
- // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
- // IE8 throws error here (do not put tests after this one)
- div.innerHTML = "<input type='hidden'/>";
- if ( !div.querySelectorAll(":enabled").length ) {
- rbuggyQSA.push(":enabled", ":disabled");
- }
- });
-
- // rbuggyQSA always contains :focus, so no need for a length check
- rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") );
-
- select = function( selector, context, results, seed, xml ) {
- // Only use querySelectorAll when not filtering,
- // when this is not xml,
- // and when no QSA bugs apply
- if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
- var groups, i,
- old = true,
- nid = expando,
- newContext = context,
- newSelector = context.nodeType === 9 && selector;
-
- // qSA works strangely on Element-rooted queries
- // We can work around this by specifying an extra ID on the root
- // and working up from there (Thanks to Andrew Dupont for the technique)
- // IE 8 doesn't work on object elements
- if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
- groups = tokenize( selector );
-
- if ( (old = context.getAttribute("id")) ) {
- nid = old.replace( rescape, "\\$&" );
- } else {
- context.setAttribute( "id", nid );
- }
- nid = "[id='" + nid + "'] ";
-
- i = groups.length;
- while ( i-- ) {
- groups[i] = nid + groups[i].join("");
- }
- newContext = rsibling.test( selector ) && context.parentNode || context;
- newSelector = groups.join(",");
- }
-
- if ( newSelector ) {
- try {
- push.apply( results, slice.call( newContext.querySelectorAll(
- newSelector
- ), 0 ) );
- return results;
- } catch(qsaError) {
- } finally {
- if ( !old ) {
- context.removeAttribute("id");
- }
- }
- }
- }
-
- return oldSelect( selector, context, results, seed, xml );
- };
-
- if ( matches ) {
- assert(function( div ) {
- // Check to see if it's possible to do matchesSelector
- // on a disconnected node (IE 9)
- disconnectedMatch = matches.call( div, "div" );
-
- // This should fail with an exception
- // Gecko does not error, returns false instead
- try {
- matches.call( div, "[test!='']:sizzle" );
- rbuggyMatches.push( "!=", pseudos );
- } catch ( e ) {}
- });
-
- // rbuggyMatches always contains :active and :focus, so no need for a length check
- rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
-
- Sizzle.matchesSelector = function( elem, expr ) {
- // Make sure that attribute selectors are quoted
- expr = expr.replace( rattributeQuotes, "='$1']" );
-
- // rbuggyMatches always contains :active, so no need for an existence check
- if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) {
- try {
- var ret = matches.call( elem, expr );
-
- // IE 9's matchesSelector returns false on disconnected nodes
- if ( ret || disconnectedMatch ||
- // As well, disconnected nodes are said to be in a document
- // fragment in IE 9
- elem.document && elem.document.nodeType !== 11 ) {
- return ret;
- }
- } catch(e) {}
- }
-
- return Sizzle( expr, null, null, [ elem ] ).length > 0;
- };
- }
- })();
-}
-
-// Deprecated
-Expr.pseudos["nth"] = Expr.pseudos["eq"];
-
-// Back-compat
-function setFilters() {}
-Expr.filters = setFilters.prototype = Expr.pseudos;
-Expr.setFilters = new setFilters();
-
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://sizzlejs.com/
+ */
+(function( window, undefined ) {
+
+var cachedruns,
+ assertGetIdNotName,
+ Expr,
+ getText,
+ isXML,
+ contains,
+ compile,
+ sortOrder,
+ hasDuplicate,
+ outermostContext,
+
+ baseHasDuplicate = true,
+ strundefined = "undefined",
+
+ expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
+
+ Token = String,
+ document = window.document,
+ docElem = document.documentElement,
+ dirruns = 0,
+ done = 0,
+ pop = [].pop,
+ push = [].push,
+ slice = [].slice,
+ // Use a stripped-down indexOf if a native one is unavailable
+ indexOf = [].indexOf || function( elem ) {
+ var i = 0,
+ len = this.length;
+ for ( ; i < len; i++ ) {
+ if ( this[i] === elem ) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ // Augment a function for special use by Sizzle
+ markFunction = function( fn, value ) {
+ fn[ expando ] = value == null || value;
+ return fn;
+ },
+
+ createCache = function() {
+ var cache = {},
+ keys = [];
+
+ return markFunction(function( key, value ) {
+ // Only keep the most recent entries
+ if ( keys.push( key ) > Expr.cacheLength ) {
+ delete cache[ keys.shift() ];
+ }
+
+ return (cache[ key ] = value);
+ }, cache );
+ },
+
+ classCache = createCache(),
+ tokenCache = createCache(),
+ compilerCache = createCache(),
+
+ // Regex
+
+ // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+ whitespace = "[\\x20\\t\\r\\n\\f]",
+ // http://www.w3.org/TR/css3-syntax/#characters
+ characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
+
+ // Loosely modeled on CSS identifier characters
+ // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)
+ // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+ identifier = characterEncoding.replace( "w", "w#" ),
+
+ // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
+ operators = "([*^$|!~]?=)",
+ attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
+ "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
+
+ // Prefer arguments not in parens/brackets,
+ // then attribute selectors and non-pseudos (denoted by :),
+ // then anything else
+ // These preferences are here to reduce the number of selectors
+ // needing tokenize in the PSEUDO preFilter
+ pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",
+
+ // For matchExpr.POS and matchExpr.needsContext
+ pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
+ "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)",
+
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+ rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
+ rpseudo = new RegExp( pseudos ),
+
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
+ rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
+
+ rnot = /^:not/,
+ rsibling = /[\x20\t\r\n\f]*[+~]/,
+ rendsWithNot = /:not\($/,
+
+ rheader = /h\d/i,
+ rinputs = /input|select|textarea|button/i,
+
+ rbackslash = /\\(?!\\)/g,
+
+ matchExpr = {
+ "ID": new RegExp( "^#(" + characterEncoding + ")" ),
+ "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+ "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
+ "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
+ "ATTR": new RegExp( "^" + attributes ),
+ "PSEUDO": new RegExp( "^" + pseudos ),
+ "POS": new RegExp( pos, "i" ),
+ "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace +
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+ // For use in libraries implementing .is()
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
+ },
+
+ // Support
+
+ // Used for testing something on an element
+ assert = function( fn ) {
+ var div = document.createElement("div");
+
+ try {
+ return fn( div );
+ } catch (e) {
+ return false;
+ } finally {
+ // release memory in IE
+ div = null;
+ }
+ },
+
+ // Check if getElementsByTagName("*") returns only elements
+ assertTagNameNoComments = assert(function( div ) {
+ div.appendChild( document.createComment("") );
+ return !div.getElementsByTagName("*").length;
+ }),
+
+ // Check if getAttribute returns normalized href attributes
+ assertHrefNotNormalized = assert(function( div ) {
+ div.innerHTML = "<a href='#'></a>";
+ return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
+ div.firstChild.getAttribute("href") === "#";
+ }),
+
+ // Check if attributes should be retrieved by attribute nodes
+ assertAttributes = assert(function( div ) {
+ div.innerHTML = "<select></select>";
+ var type = typeof div.lastChild.getAttribute("multiple");
+ // IE8 returns a string for some attributes even when not present
+ return type !== "boolean" && type !== "string";
+ }),
+
+ // Check if getElementsByClassName can be trusted
+ assertUsableClassName = assert(function( div ) {
+ // Opera can't find a second classname (in 9.6)
+ div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
+ if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
+ return false;
+ }
+
+ // Safari 3.2 caches class attributes and doesn't catch changes
+ div.lastChild.className = "e";
+ return div.getElementsByClassName("e").length === 2;
+ }),
+
+ // Check if getElementById returns elements by name
+ // Check if getElementsByName privileges form controls or returns elements by ID
+ assertUsableName = assert(function( div ) {
+ // Inject content
+ div.id = expando + 0;
+ div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
+ docElem.insertBefore( div, docElem.firstChild );
+
+ // Test
+ var pass = document.getElementsByName &&
+ // buggy browsers will return fewer than the correct 2
+ document.getElementsByName( expando ).length === 2 +
+ // buggy browsers will return more than the correct 0
+ document.getElementsByName( expando + 0 ).length;
+ assertGetIdNotName = !document.getElementById( expando );
+
+ // Cleanup
+ docElem.removeChild( div );
+
+ return pass;
+ });
+
+// If slice is not available, provide a backup
+try {
+ slice.call( docElem.childNodes, 0 )[0].nodeType;
+} catch ( e ) {
+ slice = function( i ) {
+ var elem,
+ results = [];
+ for ( ; (elem = this[i]); i++ ) {
+ results.push( elem );
+ }
+ return results;
+ };
+}
+
+function Sizzle( selector, context, results, seed ) {
+ results = results || [];
+ context = context || document;
+ var match, elem, xml, m,
+ nodeType = context.nodeType;
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ if ( nodeType !== 1 && nodeType !== 9 ) {
+ return [];
+ }
+
+ xml = isXML( context );
+
+ if ( !xml && !seed ) {
+ if ( (match = rquickExpr.exec( selector )) ) {
+ // Speed-up: Sizzle("#ID")
+ if ( (m = match[1]) ) {
+ if ( nodeType === 9 ) {
+ elem = context.getElementById( m );
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE, Opera, and Webkit return items
+ // by name instead of ID
+ if ( elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ } else {
+ return results;
+ }
+ } else {
+ // Context is not a document
+ if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
+ contains( context, elem ) && elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ }
+
+ // Speed-up: Sizzle("TAG")
+ } else if ( match[2] ) {
+ push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
+ return results;
+
+ // Speed-up: Sizzle(".CLASS")
+ } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
+ push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
+ return results;
+ }
+ }
+ }
+
+ // All others
+ return select( selector.replace( rtrim, "$1" ), context, results, seed, xml );
+}
+
+Sizzle.matches = function( expr, elements ) {
+ return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+ return Sizzle( expr, null, null, [ elem ] ).length > 0;
+};
+
+// Returns a function to use in pseudos for input types
+function createInputPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === type;
+ };
+}
+
+// Returns a function to use in pseudos for buttons
+function createButtonPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && elem.type === type;
+ };
+}
+
+// Returns a function to use in pseudos for positionals
+function createPositionalPseudo( fn ) {
+ return markFunction(function( argument ) {
+ argument = +argument;
+ return markFunction(function( seed, matches ) {
+ var j,
+ matchIndexes = fn( [], seed.length, argument ),
+ i = matchIndexes.length;
+
+ // Match elements found at the specified indexes
+ while ( i-- ) {
+ if ( seed[ (j = matchIndexes[i]) ] ) {
+ seed[j] = !(matches[j] = seed[j]);
+ }
+ }
+ });
+ });
+}
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+ var node,
+ ret = "",
+ i = 0,
+ nodeType = elem.nodeType;
+
+ if ( nodeType ) {
+ if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+ // Use textContent for elements
+ // innerText usage removed for consistency of new lines (see #11153)
+ if ( typeof elem.textContent === "string" ) {
+ return elem.textContent;
+ } else {
+ // Traverse its children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ ret += getText( elem );
+ }
+ }
+ } else if ( nodeType === 3 || nodeType === 4 ) {
+ return elem.nodeValue;
+ }
+ // Do not include comment or processing instruction nodes
+ } else {
+
+ // If no nodeType, this is expected to be an array
+ for ( ; (node = elem[i]); i++ ) {
+ // Do not traverse comment nodes
+ ret += getText( node );
+ }
+ }
+ return ret;
+};
+
+isXML = Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+// Element contains another
+contains = Sizzle.contains = docElem.contains ?
+ function( a, b ) {
+ var adown = a.nodeType === 9 ? a.documentElement : a,
+ bup = b && b.parentNode;
+ return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
+ } :
+ docElem.compareDocumentPosition ?
+ function( a, b ) {
+ return b && !!( a.compareDocumentPosition( b ) & 16 );
+ } :
+ function( a, b ) {
+ while ( (b = b.parentNode) ) {
+ if ( b === a ) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+Sizzle.attr = function( elem, name ) {
+ var val,
+ xml = isXML( elem );
+
+ if ( !xml ) {
+ name = name.toLowerCase();
+ }
+ if ( (val = Expr.attrHandle[ name ]) ) {
+ return val( elem );
+ }
+ if ( xml || assertAttributes ) {
+ return elem.getAttribute( name );
+ }
+ val = elem.getAttributeNode( name );
+ return val ?
+ typeof elem[ name ] === "boolean" ?
+ elem[ name ] ? name : null :
+ val.specified ? val.value : null :
+ null;
+};
+
+Expr = Sizzle.selectors = {
+
+ // Can be adjusted by the user
+ cacheLength: 50,
+
+ createPseudo: markFunction,
+
+ match: matchExpr,
+
+ // IE6/7 return a modified href
+ attrHandle: assertHrefNotNormalized ?
+ {} :
+ {
+ "href": function( elem ) {
+ return elem.getAttribute( "href", 2 );
+ },
+ "type": function( elem ) {
+ return elem.getAttribute("type");
+ }
+ },
+
+ find: {
+ "ID": assertGetIdNotName ?
+ function( id, context, xml ) {
+ if ( typeof context.getElementById !== strundefined && !xml ) {
+ var m = context.getElementById( id );
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ return m && m.parentNode ? [m] : [];
+ }
+ } :
+ function( id, context, xml ) {
+ if ( typeof context.getElementById !== strundefined && !xml ) {
+ var m = context.getElementById( id );
+
+ return m ?
+ m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
+ [m] :
+ undefined :
+ [];
+ }
+ },
+
+ "TAG": assertTagNameNoComments ?
+ function( tag, context ) {
+ if ( typeof context.getElementsByTagName !== strundefined ) {
+ return context.getElementsByTagName( tag );
+ }
+ } :
+ function( tag, context ) {
+ var results = context.getElementsByTagName( tag );
+
+ // Filter out possible comments
+ if ( tag === "*" ) {
+ var elem,
+ tmp = [],
+ i = 0;
+
+ for ( ; (elem = results[i]); i++ ) {
+ if ( elem.nodeType === 1 ) {
+ tmp.push( elem );
+ }
+ }
+
+ return tmp;
+ }
+ return results;
+ },
+
+ "NAME": assertUsableName && function( tag, context ) {
+ if ( typeof context.getElementsByName !== strundefined ) {
+ return context.getElementsByName( name );
+ }
+ },
+
+ "CLASS": assertUsableClassName && function( className, context, xml ) {
+ if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
+ return context.getElementsByClassName( className );
+ }
+ }
+ },
+
+ relative: {
+ ">": { dir: "parentNode", first: true },
+ " ": { dir: "parentNode" },
+ "+": { dir: "previousSibling", first: true },
+ "~": { dir: "previousSibling" }
+ },
+
+ preFilter: {
+ "ATTR": function( match ) {
+ match[1] = match[1].replace( rbackslash, "" );
+
+ // Move the given value to match[3] whether quoted or unquoted
+ match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
+
+ if ( match[2] === "~=" ) {
+ match[3] = " " + match[3] + " ";
+ }
+
+ return match.slice( 0, 4 );
+ },
+
+ "CHILD": function( match ) {
+ /* matches from matchExpr["CHILD"]
+ 1 type (only|nth|...)
+ 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+ 3 xn-component of xn+y argument ([+-]?\d*n|)
+ 4 sign of xn-component
+ 5 x of xn-component
+ 6 sign of y-component
+ 7 y of y-component
+ */
+ match[1] = match[1].toLowerCase();
+
+ if ( match[1] === "nth" ) {
+ // nth-child requires argument
+ if ( !match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // numeric x and y parameters for Expr.filter.CHILD
+ // remember that false/true cast respectively to 0/1
+ match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
+ match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
+
+ // other types prohibit arguments
+ } else if ( match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ return match;
+ },
+
+ "PSEUDO": function( match ) {
+ var unquoted, excess;
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
+ return null;
+ }
+
+ if ( match[3] ) {
+ match[2] = match[3];
+ } else if ( (unquoted = match[4]) ) {
+ // Only check arguments that contain a pseudo
+ if ( rpseudo.test(unquoted) &&
+ // Get excess from tokenize (recursively)
+ (excess = tokenize( unquoted, true )) &&
+ // advance to the next closing parenthesis
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+ // excess is a negative index
+ unquoted = unquoted.slice( 0, excess );
+ match[0] = match[0].slice( 0, excess );
+ }
+ match[2] = unquoted;
+ }
+
+ // Return only captures needed by the pseudo filter method (type and argument)
+ return match.slice( 0, 3 );
+ }
+ },
+
+ filter: {
+ "ID": assertGetIdNotName ?
+ function( id ) {
+ id = id.replace( rbackslash, "" );
+ return function( elem ) {
+ return elem.getAttribute("id") === id;
+ };
+ } :
+ function( id ) {
+ id = id.replace( rbackslash, "" );
+ return function( elem ) {
+ var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+ return node && node.value === id;
+ };
+ },
+
+ "TAG": function( nodeName ) {
+ if ( nodeName === "*" ) {
+ return function() { return true; };
+ }
+ nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
+
+ return function( elem ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+ };
+ },
+
+ "CLASS": function( className ) {
+ var pattern = classCache[ expando ][ className ];
+ if ( !pattern ) {
+ pattern = classCache( className, new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)") );
+ }
+ return function( elem ) {
+ return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
+ };
+ },
+
+ "ATTR": function( name, operator, check ) {
+ return function( elem, context ) {
+ var result = Sizzle.attr( elem, name );
+
+ if ( result == null ) {
+ return operator === "!=";
+ }
+ if ( !operator ) {
+ return true;
+ }
+
+ result += "";
+
+ return operator === "=" ? result === check :
+ operator === "!=" ? result !== check :
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
+ operator === "$=" ? check && result.substr( result.length - check.length ) === check :
+ operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
+ operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" :
+ false;
+ };
+ },
+
+ "CHILD": function( type, argument, first, last ) {
+
+ if ( type === "nth" ) {
+ return function( elem ) {
+ var node, diff,
+ parent = elem.parentNode;
+
+ if ( first === 1 && last === 0 ) {
+ return true;
+ }
+
+ if ( parent ) {
+ diff = 0;
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ diff++;
+ if ( elem === node ) {
+ break;
+ }
+ }
+ }
+ }
+
+ // Incorporate the offset (or cast to NaN), then check against cycle size
+ diff -= last;
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
+ };
+ }
+
+ return function( elem ) {
+ var node = elem;
+
+ switch ( type ) {
+ case "only":
+ case "first":
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ if ( type === "first" ) {
+ return true;
+ }
+
+ node = elem;
+
+ /* falls through */
+ case "last":
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ };
+ },
+
+ "PSEUDO": function( pseudo, argument ) {
+ // pseudo-class names are case-insensitive
+ // http://www.w3.org/TR/selectors/#pseudo-classes
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+ // Remember that setFilters inherits from pseudos
+ var args,
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+ Sizzle.error( "unsupported pseudo: " + pseudo );
+
+ // The user may use createPseudo to indicate that
+ // arguments are needed to create the filter function
+ // just as Sizzle does
+ if ( fn[ expando ] ) {
+ return fn( argument );
+ }
+
+ // But maintain support for old signatures
+ if ( fn.length > 1 ) {
+ args = [ pseudo, pseudo, "", argument ];
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+ markFunction(function( seed, matches ) {
+ var idx,
+ matched = fn( seed, argument ),
+ i = matched.length;
+ while ( i-- ) {
+ idx = indexOf.call( seed, matched[i] );
+ seed[ idx ] = !( matches[ idx ] = matched[i] );
+ }
+ }) :
+ function( elem ) {
+ return fn( elem, 0, args );
+ };
+ }
+
+ return fn;
+ }
+ },
+
+ pseudos: {
+ "not": markFunction(function( selector ) {
+ // Trim the selector passed to compile
+ // to avoid treating leading and trailing
+ // spaces as combinators
+ var input = [],
+ results = [],
+ matcher = compile( selector.replace( rtrim, "$1" ) );
+
+ return matcher[ expando ] ?
+ markFunction(function( seed, matches, context, xml ) {
+ var elem,
+ unmatched = matcher( seed, null, xml, [] ),
+ i = seed.length;
+
+ // Match elements unmatched by `matcher`
+ while ( i-- ) {
+ if ( (elem = unmatched[i]) ) {
+ seed[i] = !(matches[i] = elem);
+ }
+ }
+ }) :
+ function( elem, context, xml ) {
+ input[0] = elem;
+ matcher( input, null, xml, results );
+ return !results.pop();
+ };
+ }),
+
+ "has": markFunction(function( selector ) {
+ return function( elem ) {
+ return Sizzle( selector, elem ).length > 0;
+ };
+ }),
+
+ "contains": markFunction(function( text ) {
+ return function( elem ) {
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+ };
+ }),
+
+ "enabled": function( elem ) {
+ return elem.disabled === false;
+ },
+
+ "disabled": function( elem ) {
+ return elem.disabled === true;
+ },
+
+ "checked": function( elem ) {
+ // In CSS3, :checked should return both checked and selected elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ var nodeName = elem.nodeName.toLowerCase();
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+ },
+
+ "selected": function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ "parent": function( elem ) {
+ return !Expr.pseudos["empty"]( elem );
+ },
+
+ "empty": function( elem ) {
+ // http://www.w3.org/TR/selectors/#empty-pseudo
+ // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
+ // not comment, processing instructions, or others
+ // Thanks to Diego Perini for the nodeName shortcut
+ // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
+ var nodeType;
+ elem = elem.firstChild;
+ while ( elem ) {
+ if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
+ return false;
+ }
+ elem = elem.nextSibling;
+ }
+ return true;
+ },
+
+ "header": function( elem ) {
+ return rheader.test( elem.nodeName );
+ },
+
+ "text": function( elem ) {
+ var type, attr;
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // use getAttribute instead to test this case
+ return elem.nodeName.toLowerCase() === "input" &&
+ (type = elem.type) === "text" &&
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
+ },
+
+ // Input types
+ "radio": createInputPseudo("radio"),
+ "checkbox": createInputPseudo("checkbox"),
+ "file": createInputPseudo("file"),
+ "password": createInputPseudo("password"),
+ "image": createInputPseudo("image"),
+
+ "submit": createButtonPseudo("submit"),
+ "reset": createButtonPseudo("reset"),
+
+ "button": function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === "button" || name === "button";
+ },
+
+ "input": function( elem ) {
+ return rinputs.test( elem.nodeName );
+ },
+
+ "focus": function( elem ) {
+ var doc = elem.ownerDocument;
+ return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href);
+ },
+
+ "active": function( elem ) {
+ return elem === elem.ownerDocument.activeElement;
+ },
+
+ // Positional types
+ "first": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ return [ 0 ];
+ }),
+
+ "last": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ return [ length - 1 ];
+ }),
+
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ return [ argument < 0 ? argument + length : argument ];
+ }),
+
+ "even": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ for ( var i = 0; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "odd": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ for ( var i = 1; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ })
+ }
+};
+
+function siblingCheck( a, b, ret ) {
+ if ( a === b ) {
+ return ret;
+ }
+
+ var cur = a.nextSibling;
+
+ while ( cur ) {
+ if ( cur === b ) {
+ return -1;
+ }
+
+ cur = cur.nextSibling;
+ }
+
+ return 1;
+}
+
+sortOrder = docElem.compareDocumentPosition ?
+ function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
+ a.compareDocumentPosition :
+ a.compareDocumentPosition(b) & 4
+ ) ? -1 : 1;
+ } :
+ function( a, b ) {
+ // The nodes are identical, we can exit early
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+
+ // Fallback to using sourceIndex (in IE) if it's available on both nodes
+ } else if ( a.sourceIndex && b.sourceIndex ) {
+ return a.sourceIndex - b.sourceIndex;
+ }
+
+ var al, bl,
+ ap = [],
+ bp = [],
+ aup = a.parentNode,
+ bup = b.parentNode,
+ cur = aup;
+
+ // If the nodes are siblings (or identical) we can do a quick check
+ if ( aup === bup ) {
+ return siblingCheck( a, b );
+
+ // If no parents were found then the nodes are disconnected
+ } else if ( !aup ) {
+ return -1;
+
+ } else if ( !bup ) {
+ return 1;
+ }
+
+ // Otherwise they're somewhere else in the tree so we need
+ // to build up a full list of the parentNodes for comparison
+ while ( cur ) {
+ ap.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ cur = bup;
+
+ while ( cur ) {
+ bp.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ al = ap.length;
+ bl = bp.length;
+
+ // Start walking down the tree looking for a discrepancy
+ for ( var i = 0; i < al && i < bl; i++ ) {
+ if ( ap[i] !== bp[i] ) {
+ return siblingCheck( ap[i], bp[i] );
+ }
+ }
+
+ // We ended someplace up the tree so do a sibling check
+ return i === al ?
+ siblingCheck( a, bp[i], -1 ) :
+ siblingCheck( ap[i], b, 1 );
+ };
+
+// Always assume the presence of duplicates if sort doesn't
+// pass them to our comparison function (as in Google Chrome).
+[0, 0].sort( sortOrder );
+baseHasDuplicate = !hasDuplicate;
+
+// Document sorting and removing duplicates
+Sizzle.uniqueSort = function( results ) {
+ var elem,
+ i = 1;
+
+ hasDuplicate = baseHasDuplicate;
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ for ( ; (elem = results[i]); i++ ) {
+ if ( elem === results[ i - 1 ] ) {
+ results.splice( i--, 1 );
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.error = function( msg ) {
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+function tokenize( selector, parseOnly ) {
+ var matched, match, tokens, type, soFar, groups, preFilters,
+ cached = tokenCache[ expando ][ selector ];
+
+ if ( cached ) {
+ return parseOnly ? 0 : cached.slice( 0 );
+ }
+
+ soFar = selector;
+ groups = [];
+ preFilters = Expr.preFilter;
+
+ while ( soFar ) {
+
+ // Comma and first run
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
+ if ( match ) {
+ soFar = soFar.slice( match[0].length );
+ }
+ groups.push( tokens = [] );
+ }
+
+ matched = false;
+
+ // Combinators
+ if ( (match = rcombinators.exec( soFar )) ) {
+ tokens.push( matched = new Token( match.shift() ) );
+ soFar = soFar.slice( matched.length );
+
+ // Cast descendant combinators to space
+ matched.type = match[0].replace( rtrim, " " );
+ }
+
+ // Filters
+ for ( type in Expr.filter ) {
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+ // The last two arguments here are (context, xml) for backCompat
+ (match = preFilters[ type ]( match, document, true ))) ) {
+
+ tokens.push( matched = new Token( match.shift() ) );
+ soFar = soFar.slice( matched.length );
+ matched.type = type;
+ matched.matches = match;
+ }
+ }
+
+ if ( !matched ) {
+ break;
+ }
+ }
+
+ // Return the length of the invalid excess
+ // if we're just parsing
+ // Otherwise, throw an error or return tokens
+ return parseOnly ?
+ soFar.length :
+ soFar ?
+ Sizzle.error( selector ) :
+ // Cache the tokens
+ tokenCache( selector, groups ).slice( 0 );
+}
+
+function addCombinator( matcher, combinator, base ) {
+ var dir = combinator.dir,
+ checkNonElements = base && combinator.dir === "parentNode",
+ doneName = done++;
+
+ return combinator.first ?
+ // Check against closest ancestor/preceding element
+ function( elem, context, xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( checkNonElements || elem.nodeType === 1 ) {
+ return matcher( elem, context, xml );
+ }
+ }
+ } :
+
+ // Check against all ancestor/preceding elements
+ function( elem, context, xml ) {
+ // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+ if ( !xml ) {
+ var cache,
+ dirkey = dirruns + " " + doneName + " ",
+ cachedkey = dirkey + cachedruns;
+ while ( (elem = elem[ dir ]) ) {
+ if ( checkNonElements || elem.nodeType === 1 ) {
+ if ( (cache = elem[ expando ]) === cachedkey ) {
+ return elem.sizset;
+ } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
+ if ( elem.sizset ) {
+ return elem;
+ }
+ } else {
+ elem[ expando ] = cachedkey;
+ if ( matcher( elem, context, xml ) ) {
+ elem.sizset = true;
+ return elem;
+ }
+ elem.sizset = false;
+ }
+ }
+ }
+ } else {
+ while ( (elem = elem[ dir ]) ) {
+ if ( checkNonElements || elem.nodeType === 1 ) {
+ if ( matcher( elem, context, xml ) ) {
+ return elem;
+ }
+ }
+ }
+ }
+ };
+}
+
+function elementMatcher( matchers ) {
+ return matchers.length > 1 ?
+ function( elem, context, xml ) {
+ var i = matchers.length;
+ while ( i-- ) {
+ if ( !matchers[i]( elem, context, xml ) ) {
+ return false;
+ }
+ }
+ return true;
+ } :
+ matchers[0];
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+ var elem,
+ newUnmatched = [],
+ i = 0,
+ len = unmatched.length,
+ mapped = map != null;
+
+ for ( ; i < len; i++ ) {
+ if ( (elem = unmatched[i]) ) {
+ if ( !filter || filter( elem, context, xml ) ) {
+ newUnmatched.push( elem );
+ if ( mapped ) {
+ map.push( i );
+ }
+ }
+ }
+ }
+
+ return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+ if ( postFilter && !postFilter[ expando ] ) {
+ postFilter = setMatcher( postFilter );
+ }
+ if ( postFinder && !postFinder[ expando ] ) {
+ postFinder = setMatcher( postFinder, postSelector );
+ }
+ return markFunction(function( seed, results, context, xml ) {
+ // Positional selectors apply to seed elements, so it is invalid to follow them with relative ones
+ if ( seed && postFinder ) {
+ return;
+ }
+
+ var i, elem, postFilterIn,
+ preMap = [],
+ postMap = [],
+ preexisting = results.length,
+
+ // Get initial elements from seed or context
+ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [], seed ),
+
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
+ matcherIn = preFilter && ( seed || !selector ) ?
+ condense( elems, preMap, preFilter, context, xml ) :
+ elems,
+
+ matcherOut = matcher ?
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+ // ...intermediate processing is necessary
+ [] :
+
+ // ...otherwise use results directly
+ results :
+ matcherIn;
+
+ // Find primary matches
+ if ( matcher ) {
+ matcher( matcherIn, matcherOut, context, xml );
+ }
+
+ // Apply postFilter
+ if ( postFilter ) {
+ postFilterIn = condense( matcherOut, postMap );
+ postFilter( postFilterIn, [], context, xml );
+
+ // Un-match failing elements by moving them back to matcherIn
+ i = postFilterIn.length;
+ while ( i-- ) {
+ if ( (elem = postFilterIn[i]) ) {
+ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+ }
+ }
+ }
+
+ // Keep seed and results synchronized
+ if ( seed ) {
+ // Ignore postFinder because it can't coexist with seed
+ i = preFilter && matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) ) {
+ seed[ preMap[i] ] = !(results[ preMap[i] ] = elem);
+ }
+ }
+ } else {
+ matcherOut = condense(
+ matcherOut === results ?
+ matcherOut.splice( preexisting, matcherOut.length ) :
+ matcherOut
+ );
+ if ( postFinder ) {
+ postFinder( null, results, matcherOut, xml );
+ } else {
+ push.apply( results, matcherOut );
+ }
+ }
+ });
+}
+
+function matcherFromTokens( tokens ) {
+ var checkContext, matcher, j,
+ len = tokens.length,
+ leadingRelative = Expr.relative[ tokens[0].type ],
+ implicitRelative = leadingRelative || Expr.relative[" "],
+ i = leadingRelative ? 1 : 0,
+
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
+ matchContext = addCombinator( function( elem ) {
+ return elem === checkContext;
+ }, implicitRelative, true ),
+ matchAnyContext = addCombinator( function( elem ) {
+ return indexOf.call( checkContext, elem ) > -1;
+ }, implicitRelative, true ),
+ matchers = [ function( elem, context, xml ) {
+ return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+ (checkContext = context).nodeType ?
+ matchContext( elem, context, xml ) :
+ matchAnyContext( elem, context, xml ) );
+ } ];
+
+ for ( ; i < len; i++ ) {
+ if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+ matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
+ } else {
+ // The concatenated values are (context, xml) for backCompat
+ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+ // Return special upon seeing a positional matcher
+ if ( matcher[ expando ] ) {
+ // Find the next relative operator (if any) for proper handling
+ j = ++i;
+ for ( ; j < len; j++ ) {
+ if ( Expr.relative[ tokens[j].type ] ) {
+ break;
+ }
+ }
+ return setMatcher(
+ i > 1 && elementMatcher( matchers ),
+ i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ),
+ matcher,
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
+ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+ j < len && tokens.join("")
+ );
+ }
+ matchers.push( matcher );
+ }
+ }
+
+ return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+ var bySet = setMatchers.length > 0,
+ byElement = elementMatchers.length > 0,
+ superMatcher = function( seed, context, xml, results, expandContext ) {
+ var elem, j, matcher,
+ setMatched = [],
+ matchedCount = 0,
+ i = "0",
+ unmatched = seed && [],
+ outermost = expandContext != null,
+ contextBackup = outermostContext,
+ // We must always have either seed elements or context
+ elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
+ // Nested matchers should use non-integer dirruns
+ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);
+
+ if ( outermost ) {
+ outermostContext = context !== document && context;
+ cachedruns = superMatcher.el;
+ }
+
+ // Add elements passing elementMatchers directly to results
+ for ( ; (elem = elems[i]) != null; i++ ) {
+ if ( byElement && elem ) {
+ for ( j = 0; (matcher = elementMatchers[j]); j++ ) {
+ if ( matcher( elem, context, xml ) ) {
+ results.push( elem );
+ break;
+ }
+ }
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ cachedruns = ++superMatcher.el;
+ }
+ }
+
+ // Track unmatched elements for set filters
+ if ( bySet ) {
+ // They will have gone through all possible matchers
+ if ( (elem = !matcher && elem) ) {
+ matchedCount--;
+ }
+
+ // Lengthen the array for every element, matched or not
+ if ( seed ) {
+ unmatched.push( elem );
+ }
+ }
+ }
+
+ // Apply set filters to unmatched elements
+ matchedCount += i;
+ if ( bySet && i !== matchedCount ) {
+ for ( j = 0; (matcher = setMatchers[j]); j++ ) {
+ matcher( unmatched, setMatched, context, xml );
+ }
+
+ if ( seed ) {
+ // Reintegrate element matches to eliminate the need for sorting
+ if ( matchedCount > 0 ) {
+ while ( i-- ) {
+ if ( !(unmatched[i] || setMatched[i]) ) {
+ setMatched[i] = pop.call( results );
+ }
+ }
+ }
+
+ // Discard index placeholder values to get only actual matches
+ setMatched = condense( setMatched );
+ }
+
+ // Add matches to results
+ push.apply( results, setMatched );
+
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
+ if ( outermost && !seed && setMatched.length > 0 &&
+ ( matchedCount + setMatchers.length ) > 1 ) {
+
+ Sizzle.uniqueSort( results );
+ }
+ }
+
+ // Override manipulation of globals by nested matchers
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ outermostContext = contextBackup;
+ }
+
+ return unmatched;
+ };
+
+ superMatcher.el = 0;
+ return bySet ?
+ markFunction( superMatcher ) :
+ superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
+ var i,
+ setMatchers = [],
+ elementMatchers = [],
+ cached = compilerCache[ expando ][ selector ];
+
+ if ( !cached ) {
+ // Generate a function of recursive functions that can be used to check each element
+ if ( !group ) {
+ group = tokenize( selector );
+ }
+ i = group.length;
+ while ( i-- ) {
+ cached = matcherFromTokens( group[i] );
+ if ( cached[ expando ] ) {
+ setMatchers.push( cached );
+ } else {
+ elementMatchers.push( cached );
+ }
+ }
+
+ // Cache the compiled function
+ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+ }
+ return cached;
+};
+
+function multipleContexts( selector, contexts, results, seed ) {
+ var i = 0,
+ len = contexts.length;
+ for ( ; i < len; i++ ) {
+ Sizzle( selector, contexts[i], results, seed );
+ }
+ return results;
+}
+
+function select( selector, context, results, seed, xml ) {
+ var i, tokens, token, type, find,
+ match = tokenize( selector ),
+ j = match.length;
+
+ if ( !seed ) {
+ // Try to minimize operations if there is only one group
+ if ( match.length === 1 ) {
+
+ // Take a shortcut and set the context if the root selector is an ID
+ tokens = match[0] = match[0].slice( 0 );
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+ context.nodeType === 9 && !xml &&
+ Expr.relative[ tokens[1].type ] ) {
+
+ context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0];
+ if ( !context ) {
+ return results;
+ }
+
+ selector = selector.slice( tokens.shift().length );
+ }
+
+ // Fetch a seed set for right-to-left matching
+ for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {
+ token = tokens[i];
+
+ // Abort if we hit a combinator
+ if ( Expr.relative[ (type = token.type) ] ) {
+ break;
+ }
+ if ( (find = Expr.find[ type ]) ) {
+ // Search, expanding context for leading sibling combinators
+ if ( (seed = find(
+ token.matches[0].replace( rbackslash, "" ),
+ rsibling.test( tokens[0].type ) && context.parentNode || context,
+ xml
+ )) ) {
+
+ // If seed is empty or no tokens remain, we can return early
+ tokens.splice( i, 1 );
+ selector = seed.length && tokens.join("");
+ if ( !selector ) {
+ push.apply( results, slice.call( seed, 0 ) );
+ return results;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Compile and execute a filtering function
+ // Provide `match` to avoid retokenization if we modified the selector above
+ compile( selector, match )(
+ seed,
+ context,
+ xml,
+ results,
+ rsibling.test( selector )
+ );
+ return results;
+}
+
+if ( document.querySelectorAll ) {
+ (function() {
+ var disconnectedMatch,
+ oldSelect = select,
+ rescape = /'|\\/g,
+ rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
+
+ // qSa(:focus) reports false when true (Chrome 21),
+ // A support test would require too much code (would include document ready)
+ rbuggyQSA = [":focus"],
+
+ // matchesSelector(:focus) reports false when true (Chrome 21),
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+ // A support test would require too much code (would include document ready)
+ // just skip matchesSelector for :active
+ rbuggyMatches = [ ":active", ":focus" ],
+ matches = docElem.matchesSelector ||
+ docElem.mozMatchesSelector ||
+ docElem.webkitMatchesSelector ||
+ docElem.oMatchesSelector ||
+ docElem.msMatchesSelector;
+
+ // Build QSA regex
+ // Regex strategy adopted from Diego Perini
+ assert(function( div ) {
+ // Select is set to empty string on purpose
+ // This is to test IE's treatment of not explictly
+ // setting a boolean content attribute,
+ // since its presence should be enough
+ // http://bugs.jquery.com/ticket/12359
+ div.innerHTML = "<select><option selected=''></option></select>";
+
+ // IE8 - Some boolean attributes are not treated correctly
+ if ( !div.querySelectorAll("[selected]").length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
+ }
+
+ // Webkit/Opera - :checked should return selected option elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ // IE8 throws error here (do not put tests after this one)
+ if ( !div.querySelectorAll(":checked").length ) {
+ rbuggyQSA.push(":checked");
+ }
+ });
+
+ assert(function( div ) {
+
+ // Opera 10-12/IE9 - ^= $= *= and empty values
+ // Should not select anything
+ div.innerHTML = "<p test=''></p>";
+ if ( div.querySelectorAll("[test^='']").length ) {
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
+ }
+
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+ // IE8 throws error here (do not put tests after this one)
+ div.innerHTML = "<input type='hidden'/>";
+ if ( !div.querySelectorAll(":enabled").length ) {
+ rbuggyQSA.push(":enabled", ":disabled");
+ }
+ });
+
+ // rbuggyQSA always contains :focus, so no need for a length check
+ rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") );
+
+ select = function( selector, context, results, seed, xml ) {
+ // Only use querySelectorAll when not filtering,
+ // when this is not xml,
+ // and when no QSA bugs apply
+ if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+ var groups, i,
+ old = true,
+ nid = expando,
+ newContext = context,
+ newSelector = context.nodeType === 9 && selector;
+
+ // qSA works strangely on Element-rooted queries
+ // We can work around this by specifying an extra ID on the root
+ // and working up from there (Thanks to Andrew Dupont for the technique)
+ // IE 8 doesn't work on object elements
+ if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+ groups = tokenize( selector );
+
+ if ( (old = context.getAttribute("id")) ) {
+ nid = old.replace( rescape, "\\$&" );
+ } else {
+ context.setAttribute( "id", nid );
+ }
+ nid = "[id='" + nid + "'] ";
+
+ i = groups.length;
+ while ( i-- ) {
+ groups[i] = nid + groups[i].join("");
+ }
+ newContext = rsibling.test( selector ) && context.parentNode || context;
+ newSelector = groups.join(",");
+ }
+
+ if ( newSelector ) {
+ try {
+ push.apply( results, slice.call( newContext.querySelectorAll(
+ newSelector
+ ), 0 ) );
+ return results;
+ } catch(qsaError) {
+ } finally {
+ if ( !old ) {
+ context.removeAttribute("id");
+ }
+ }
+ }
+ }
+
+ return oldSelect( selector, context, results, seed, xml );
+ };
+
+ if ( matches ) {
+ assert(function( div ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9)
+ disconnectedMatch = matches.call( div, "div" );
+
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ try {
+ matches.call( div, "[test!='']:sizzle" );
+ rbuggyMatches.push( "!=", pseudos );
+ } catch ( e ) {}
+ });
+
+ // rbuggyMatches always contains :active and :focus, so no need for a length check
+ rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
+
+ Sizzle.matchesSelector = function( elem, expr ) {
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace( rattributeQuotes, "='$1']" );
+
+ // rbuggyMatches always contains :active, so no need for an existence check
+ if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) {
+ try {
+ var ret = matches.call( elem, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9
+ elem.document && elem.document.nodeType !== 11 ) {
+ return ret;
+ }
+ } catch(e) {}
+ }
+
+ return Sizzle( expr, null, null, [ elem ] ).length > 0;
+ };
+ }
+ })();
+}
+
+// Deprecated
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Back-compat
+function setFilters() {}
+Expr.filters = setFilters.prototype = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
// Override sizzle attribute retrieval
Sizzle.attr = jQuery.attr;
jQuery.find = Sizzle;
@@ -5335,9 +5335,9 @@ jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;
-
-
-})( window );
+
+
+})( window );
var runtil = /Until$/,
rparentsprev = /^(?:parents|prev(?:Until|All))/,
isSimple = /^.[^:#\[\.,]*$/,
diff --git a/tests/jquery.simulate.js b/tests/jquery.simulate.js
index 790c88c27..08cbaafda 100644
--- a/tests/jquery.simulate.js
+++ b/tests/jquery.simulate.js
@@ -228,7 +228,7 @@ function findCenter( elem ) {
document = $( elem.ownerDocument );
elem = $( elem );
offset = elem.offset();
-
+
return {
x: offset.left + elem.outerWidth() / 2 - document.scrollLeft(),
y: offset.top + elem.outerHeight() / 2 - document.scrollTop()
@@ -241,7 +241,7 @@ $.extend( $.simulate.prototype, {
options = this.options,
center = findCenter( target ),
x = Math.floor( center.x ),
- y = Math.floor( center.y ),
+ y = Math.floor( center.y ),
dx = options.dx || 0,
dy = options.dy || 0,
coord = { clientX: x, clientY: y };
diff --git a/tests/unit/accordion/accordion.html b/tests/unit/accordion/accordion.html
index b3b7caeae..4f40091bc 100644
--- a/tests/unit/accordion/accordion.html
+++ b/tests/unit/accordion/accordion.html
@@ -5,9 +5,6 @@
<title>jQuery UI Accordion Test Suite</title>
<script src="../../jquery.js"></script>
- <script>
- $.uiBackCompat = false;
- </script>
<link rel="stylesheet" href="../../../external/qunit.css">
<script src="../../../external/qunit.js"></script>
<script src="../../jquery.simulate.js"></script>
diff --git a/tests/unit/accordion/accordion_common_deprecated.js b/tests/unit/accordion/accordion_common_deprecated.js
deleted file mode 100644
index 22d5e1289..000000000
--- a/tests/unit/accordion/accordion_common_deprecated.js
+++ /dev/null
@@ -1,29 +0,0 @@
-TestHelpers.commonWidgetTests( "accordion", {
- defaults: {
- active: 0,
- animate: null,
- animated: "slide",
- autoHeight: true,
- clearStyle: false,
- collapsible: false,
- disabled: false,
- event: "click",
- fillSpace: false,
- header: "> li > :first-child,> :not(li):even",
- heightStyle: null,
- icons: {
- "activeHeader": null,
- "header": "ui-icon-triangle-1-e",
- "headerSelected": "ui-icon-triangle-1-s"
- },
- navigation: false,
- navigationFilter: function() {},
-
- // callbacks
- activate: null,
- beforeActivate: null,
- change: null,
- changestart: null,
- create: null
- }
-});
diff --git a/tests/unit/accordion/accordion_deprecated.html b/tests/unit/accordion/accordion_deprecated.html
deleted file mode 100644
index dfb9fa90e..000000000
--- a/tests/unit/accordion/accordion_deprecated.html
+++ /dev/null
@@ -1,140 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>jQuery UI Accordion Test Suite</title>
-
- <script src="../../jquery.js"></script>
- <link rel="stylesheet" href="../../../external/qunit.css">
- <script src="../../../external/qunit.js"></script>
- <script src="../../jquery.simulate.js"></script>
- <script src="../testsuite.js"></script>
- <script>
- TestHelpers.loadResources({
- css: [ "ui.core", "ui.accordion" ],
- js: [
- "ui/jquery.ui.core.js",
- "ui/jquery.ui.widget.js",
- "ui/jquery.ui.accordion.js"
- ]
- });
- </script>
-
- <script src="accordion_test_helpers.js"></script>
- <script src="accordion_common_deprecated.js"></script>
- <script src="accordion_core.js"></script>
- <script src="accordion_events.js"></script>
- <script src="accordion_methods.js"></script>
- <script src="accordion_options.js"></script>
- <script src="accordion_deprecated.js"></script>
-
- <script src="../swarminject.js"></script>
- <style>
- #list, #list1 *, #navigation, #navigation * {
- margin: 0;
- padding: 0;
- font-size: 12px;
- line-height: 15px;
- }
- </style>
-</head>
-<body>
-<h1 id="qunit-header">jQuery UI Accordion Test Suite</h1>
-<h2 id="qunit-banner"></h2>
-<div id="qunit-testrunner-toolbar"></div>
-<h2 id="qunit-userAgent"></h2>
-<ol id="qunit-tests"></ol>
-<div id="qunit-fixture">
-
-<div id="list1" class="foo">
- <h3 class="bar">There is one obvious advantage:</h3>
- <div class="foo">
- <p>
- You've seen it coming!
- <br>
- Buy now and get nothing for free!
- <br>
- Well, at least no free beer. Perhaps a bear, if you can afford it.
- </p>
- </div>
- <h3 class="bar">Now that you've got...</h3>
- <div class="foo">
- <p>
- your bear, you have to admit it!
- <br>
- No, we aren't <a href="#">selling bears</a>.
- </p>
- <p>
- We could talk about renting one.
- </p>
- </div>
- <h3 class="bar">Rent one bear, ...</h3>
- <div class="foo">
- <p>
- get two for three beer.
- </p>
- <p>
- And now, for something completely different.
- </p>
- </div>
-</div>
-
-<div id="navigationWrapper">
- <ul id="navigation">
- <li>
- <h2><a href="?p=1.1.1">Guitar</a></h2>
- <ul>
- <li><a href="?p=1.1.1.1">Electric</a></li>
- <li><a href="?p=1.1.1.2">Acoustic</a></li>
- <li><a href="?p=1.1.1.3">Amps</a></li>
- <li><a href="?p=1.1.1.4">Effects</a></li>
- <li><a href="?p=1.1.1.5">Accessories</a></li>
- </ul>
- </li>
- <li>
- <h2><a href="?p=1.1.2"><span>Bass</span></a></h2>
- <ul>
- <li><a href="?p=1.1.2.1">Electric</a></li>
- <li><a href="?p=1.1.2.2">Acoustic</a></li>
- <li><a href="?p=1.1.2.3">Amps</a></li>
- <li><a href="?p=1.1.2.4">Effects</a></li>
- <li><a href="?p=1.1.2.5">Accessories</a></li>
- <li><a href="?p=1.1.2.5">Accessories</a></li>
- <li><a href="?p=1.1.2.5">Accessories</a></li>
- </ul>
- </li>
- <li>
- <h2><a href="?p=1.1.3">Drums</a></h2>
- <ul>
- <li><a href="?p=1.1.3.2">Acoustic</a></li>
- <li><a href="?p=1.1.3.3">Electronic</a></li>
- <li><a href="?p=1.1.3.6">Accessories</a></li>
- </ul>
- </li>
- </ul>
-</div>
-
-<dl id="accordion-dl">
- <dt>
- Accordion Header 1
- </dt>
- <dd>
- Accordion Content 1
- </dd>
- <dt>
- Accordion Header 2
- </dt>
- <dd>
- Accordion Content 2
- </dd>
- <dt>
- Accordion Header 3
- </dt>
- <dd>
- Accordion Content 3
- </dd>
-</dl>
-
-</div>
-</body>
-</html>
diff --git a/tests/unit/accordion/accordion_deprecated.js b/tests/unit/accordion/accordion_deprecated.js
deleted file mode 100644
index 2068fef95..000000000
--- a/tests/unit/accordion/accordion_deprecated.js
+++ /dev/null
@@ -1,342 +0,0 @@
-(function( $ ) {
-
-var equalHeight = TestHelpers.accordion.equalHeight,
- setupTeardown = TestHelpers.accordion.setupTeardown,
- state = TestHelpers.accordion.state;
-
-module( "accordion (deprecated): expanded active option, activate method", setupTeardown() );
-
-test( "activate, numeric", function() {
- expect( 5 );
- var element = $( "#list1" ).accordion({ active: 1 });
- state( element, 0, 1, 0 );
- element.accordion( "activate", 2 );
- state( element, 0, 0, 1 );
- element.accordion( "activate", 0 );
- state( element, 1, 0, 0 );
- element.accordion( "activate", 1 );
- state( element, 0, 1, 0 );
- element.accordion( "activate", 2 );
- state( element, 0, 0, 1 );
-});
-
-test( "activate, numeric, collapsible:true", function() {
- expect( 3 );
- var element = $( "#list1" ).accordion({ collapsible: true });
- element.accordion( "activate", 2 );
- state( element, 0, 0, 1 );
- element.accordion( "activate", 0 );
- state( element, 1, 0, 0 );
- element.accordion( "activate", -1 );
- state( element, 0, 0, 0 );
-});
-
-test( "activate, boolean, collapsible: true", function() {
- expect( 2 );
- var element = $( "#list1" ).accordion({ collapsible: true });
- element.accordion( "activate", 2 );
- state( element, 0, 0, 1 );
- element.accordion( "activate", false );
- state( element, 0, 0, 0 );
-});
-
-test( "activate, boolean, collapsible: false", function() {
- expect( 2 );
- var element = $( "#list1" ).accordion();
- element.accordion( "activate", 2 );
- state( element, 0, 0, 1 );
- element.accordion( "activate", false );
- state( element, 0, 0, 1 );
-});
-
-test( "activate, string expression", function() {
- expect( 4 );
- var element = $( "#list1" ).accordion({ active: "h3:last" });
- state( element, 0, 0, 1 );
- element.accordion( "activate", ":first" );
- state( element, 1, 0, 0 );
- element.accordion( "activate", ":eq(1)" );
- state( element, 0, 1, 0 );
- element.accordion( "activate", ":last" );
- state( element, 0, 0, 1 );
-});
-
-test( "activate, jQuery or DOM element", function() {
- expect( 3 );
- var element = $( "#list1" ).accordion({ active: $( "#list1 h3:last" ) });
- state( element, 0, 0, 1 );
- element.accordion( "activate", $( "#list1 h3:first" ) );
- state( element, 1, 0, 0 );
- element.accordion( "activate", $( "#list1 h3" )[ 1 ] );
- state( element, 0, 1, 0 );
-});
-
-test( "{ active: Selector }", function() {
- expect( 2 );
- var element = $("#list1").accordion({
- active: "h3:last"
- });
- state( element, 0, 0, 1 );
- element.accordion( "option", "active", "h3:eq(1)" );
- state( element, 0, 1, 0 );
-});
-
-test( "{ active: Element }", function() {
- expect( 2 );
- var element = $( "#list1" ).accordion({
- active: $( "#list1 h3:last" )[ 0 ]
- });
- state( element, 0, 0, 1 );
- element.accordion( "option", "active", $( "#list1 h3:eq(1)" )[ 0 ] );
- state( element, 0, 1, 0 );
-});
-
-test( "{ active: jQuery Object }", function() {
- expect( 2 );
- var element = $( "#list1" ).accordion({
- active: $( "#list1 h3:last" )
- });
- state( element, 0, 0, 1 );
- element.accordion( "option", "active", $( "#list1 h3:eq(1)" ) );
- state( element, 0, 1, 0 );
-});
-
-
-
-
-
-module( "accordion (deprecated) - height options", setupTeardown() );
-
-test( "{ autoHeight: true }, default", function() {
- expect( 3 );
- equalHeight( $( "#navigation" ).accordion({ autoHeight: true }), 105 );
-});
-
-test( "{ autoHeight: false }", function() {
- expect( 3 );
- var element = $( "#navigation" ).accordion({ autoHeight: false }),
- sizes = [];
- element.find( ".ui-accordion-content" ).each(function() {
- sizes.push( $(this).height() );
- });
- ok( sizes[0] >= 70 && sizes[0] <= 105, "was " + sizes[0] );
- ok( sizes[1] >= 98 && sizes[1] <= 126, "was " + sizes[1] );
- ok( sizes[2] >= 42 && sizes[2] <= 54, "was " + sizes[2] );
-});
-
-test( "{ fillSpace: true }", function() {
- expect( 3 );
- $( "#navigationWrapper" ).height( 500 );
- var element = $( "#navigation" ).accordion({ fillSpace: true });
- equalHeight( element, 455 );
-});
-
-test( "{ fillSapce: true } with sibling", function() {
- expect( 3 );
- $( "#navigationWrapper" ).height( 500 );
- $( "<p>Lorem Ipsum</p>" )
- .css({
- height: 50,
- marginTop: 20,
- marginBottom: 30
- })
- .prependTo( "#navigationWrapper" );
- var element = $( "#navigation" ).accordion({ fillSpace: true });
- equalHeight( element , 355 );
-});
-
-test( "{ fillSpace: true } with multiple siblings", function() {
- expect( 3 );
- $( "#navigationWrapper" ).height( 500 );
- $( "<p>Lorem Ipsum</p>" )
- .css({
- height: 50,
- marginTop: 20,
- marginBottom: 30
- })
- .prependTo( "#navigationWrapper" );
- $( "<p>Lorem Ipsum</p>" )
- .css({
- height: 50,
- marginTop: 20,
- marginBottom: 30,
- position: "absolute"
- })
- .prependTo( "#navigationWrapper" );
- $( "<p>Lorem Ipsum</p>" )
- .css({
- height: 25,
- marginTop: 10,
- marginBottom: 15
- })
- .prependTo( "#navigationWrapper" );
- var element = $( "#navigation" ).accordion({ fillSpace: true });
- equalHeight( element, 305 );
-});
-
-
-
-
-
-module( "accordion (deprecated) - icons", setupTeardown() );
-
-test( "icons, headerSelected", function() {
- expect( 3 );
- var element = $( "#list1" ).accordion({
- icons: { headerSelected: "a1", header: "h1" }
- });
- ok( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ).hasClass( "a1" ) );
- element.accordion( "option", "icons", { headerSelected: "a2", header: "h2" } );
- ok( !element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ).hasClass( "a1" ) );
- ok( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ).hasClass( "a2" ) );
-});
-
-
-
-
-
-module( "accordion (deprecated) - resize", setupTeardown() );
-
-test( "resize", function() {
- expect( 6 );
- var element = $( "#navigation" )
- .parent()
- .height( 300 )
- .end()
- .accordion({
- heightStyle: "fill"
- });
- equalHeight( element, 255 );
-
- element.parent().height( 500 );
- element.accordion( "resize" );
- equalHeight( element, 455 );
-});
-
-
-
-
-
-module( "accordion (deprecated) - navigation", setupTeardown() );
-
-test( "{ navigation: true, navigationFilter: header }", function() {
- expect( 2 );
- var element = $( "#navigation" ).accordion({
- navigation: true,
- navigationFilter: function() {
- return (/\?p=1\.1\.3$/).test( this.href );
- }
- });
- equal( element.accordion( "option", "active" ), 2 );
- state( element, 0, 0, 1 );
-});
-
-test( "{ navigation: true, navigationFilter: content }", function() {
- expect( 2 );
- var element = $( "#navigation" ).accordion({
- navigation: true,
- navigationFilter: function() {
- return (/\?p=1\.1\.3\.2$/).test( this.href );
- }
- });
- equal( element.accordion( "option", "active" ), 2 );
- state( element, 0, 0, 1 );
-});
-
-
-
-
-
-module( "accordion (deprecated) - changestart/change events", setupTeardown() );
-
-test( "changestart", function() {
- expect( 26 );
- var element = $( "#list1" ).accordion({
- active: false,
- collapsible: true
- }),
- headers = element.find( ".ui-accordion-header" ),
- content = element.find( ".ui-accordion-content" );
-
- element.one( "accordionchangestart", function( event, ui ) {
- equal( ui.oldHeader.length, 0 );
- equal( ui.oldContent.length, 0 );
- equal( ui.newHeader.length, 1 );
- strictEqual( ui.newHeader[ 0 ], headers[ 0 ] );
- equal( ui.newContent.length, 1 );
- strictEqual( ui.newContent[ 0 ], content[ 0 ] );
- state( element, 0, 0, 0 );
- });
- element.accordion( "option", "active", 0 );
- state( element, 1, 0, 0 );
-
- element.one( "accordionchangestart", function( event, ui ) {
- equal( ui.oldHeader.length, 1 );
- strictEqual( ui.oldHeader[ 0 ], headers[ 0 ] );
- equal( ui.oldContent.length, 1 );
- strictEqual( ui.oldContent[ 0 ], content[ 0 ] );
- equal( ui.newHeader.length, 1 );
- strictEqual( ui.newHeader[ 0 ], headers[ 1 ] );
- equal( ui.newContent.length, 1 );
- strictEqual( ui.newContent[ 0 ], content[ 1 ] );
- state( element, 1, 0, 0 );
- });
- headers.eq( 1 ).click();
- state( element, 0, 1, 0 );
-
- element.one( "accordionchangestart", function( event, ui ) {
- equal( ui.oldHeader.length, 1 );
- strictEqual( ui.oldHeader[ 0 ], headers[ 1 ] );
- equal( ui.oldContent.length, 1 );
- strictEqual( ui.oldContent[ 0 ], content[ 1 ] );
- equal( ui.newHeader.length, 0 );
- equal( ui.newContent.length, 0 );
- state( element, 0, 1, 0 );
- });
- element.accordion( "option", "active", false );
- state( element, 0, 0, 0 );
-});
-
-test( "change", function() {
- expect( 20 );
- var element = $( "#list1" ).accordion({
- active: false,
- collapsible: true
- }),
- headers = element.find( ".ui-accordion-header" ),
- content = element.find( ".ui-accordion-content" );
-
- element.one( "accordionchange", function( event, ui ) {
- equal( ui.oldHeader.length, 0 );
- equal( ui.oldContent.length, 0 );
- equal( ui.newHeader.length, 1 );
- strictEqual( ui.newHeader[ 0 ], headers[ 0 ] );
- equal( ui.newContent.length, 1 );
- strictEqual( ui.newContent[ 0 ], content[ 0 ] );
- });
- element.accordion( "option", "active", 0 );
-
- element.one( "accordionchange", function( event, ui ) {
- equal( ui.oldHeader.length, 1 );
- strictEqual( ui.oldHeader[ 0 ], headers[ 0 ] );
- equal( ui.oldContent.length, 1 );
- strictEqual( ui.oldContent[ 0 ], content[ 0 ] );
- equal( ui.newHeader.length, 1 );
- strictEqual( ui.newHeader[ 0 ], headers[ 1 ] );
- equal( ui.newContent.length, 1 );
- strictEqual( ui.newContent[ 0 ], content[ 1 ] );
- });
- headers.eq( 1 ).click();
-
- element.one( "accordionchange", function( event, ui ) {
- equal( ui.oldHeader.length, 1 );
- strictEqual( ui.oldHeader[ 0 ], headers[ 1 ] );
- equal( ui.oldContent.length, 1 );
- strictEqual( ui.oldContent[ 0 ], content[ 1 ] );
- equal( ui.newHeader.length, 0 );
- equal( ui.newContent.length, 0 );
- });
- element.accordion( "option", "active", false );
-});
-
-})(jQuery);
diff --git a/tests/unit/accordion/accordion_options.js b/tests/unit/accordion/accordion_options.js
index 5d950e1ac..214753e40 100644
--- a/tests/unit/accordion/accordion_options.js
+++ b/tests/unit/accordion/accordion_options.js
@@ -13,6 +13,15 @@ test( "{ active: default }", function() {
state( element, 1, 0, 0 );
});
+test( "{ active: null }", function() {
+ expect( 2 );
+ var element = $( "#list1" ).accordion({
+ active: null
+ });
+ equal( element.accordion( "option", "active" ), 0 );
+ state( element, 1, 0, 0 );
+});
+
test( "{ active: false }", function() {
expect( 7 );
var element = $( "#list1" ).accordion({
@@ -56,28 +65,26 @@ test( "{ active: Number }", function() {
state( element, 0, 1, 0 );
});
-if ( $.uiBackCompat === false ) {
- test( "{ active: -Number }", function() {
- expect( 8 );
- var element = $( "#list1" ).accordion({
- active: -1
- });
- equal( element.accordion( "option", "active" ), 2 );
- state( element, 0, 0, 1 );
-
- element.accordion( "option", "active", -2 );
- equal( element.accordion( "option", "active" ), 1 );
- state( element, 0, 1, 0 );
-
- element.accordion( "option", "active", -10 );
- equal( element.accordion( "option", "active" ), 1 );
- state( element, 0, 1, 0 );
-
- element.accordion( "option", "active", -3 );
- equal( element.accordion( "option", "active" ), 0 );
- state( element, 1, 0, 0 );
+test( "{ active: -Number }", function() {
+ expect( 8 );
+ var element = $( "#list1" ).accordion({
+ active: -1
});
-}
+ equal( element.accordion( "option", "active" ), 2 );
+ state( element, 0, 0, 1 );
+
+ element.accordion( "option", "active", -2 );
+ equal( element.accordion( "option", "active" ), 1 );
+ state( element, 0, 1, 0 );
+
+ element.accordion( "option", "active", -10 );
+ equal( element.accordion( "option", "active" ), 1 );
+ state( element, 0, 1, 0 );
+
+ element.accordion( "option", "active", -3 );
+ equal( element.accordion( "option", "active" ), 0 );
+ state( element, 1, 0, 0 );
+});
test( "{ animate: false }", function() {
expect( 3 );
diff --git a/tests/unit/all-active.html b/tests/unit/all-active.html
deleted file mode 100644
index 36719acdf..000000000
--- a/tests/unit/all-active.html
+++ /dev/null
@@ -1,72 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>jQuery UI Test Suite</title>
-
- <script src="../../jquery-1.8.2.js"></script>
-
- <link rel="stylesheet" href="../../external/qunit.css">
- <link rel="stylesheet" href="qunit-composite.css">
- <script src="../../external/qunit.js"></script>
- <script src="qunit-composite.js"></script>
-
- <script>
- (function() {
-
- var params = [],
- suites = [
- "accordion/accordion.html",
- "accordion/accordion_deprecated.html",
- "autocomplete/autocomplete.html",
- "button/button.html",
- "core/core.html",
- //"datepicker/datepicker.html",
- //"dialog/dialog.html",
- //"draggable/draggable.html",
- //"droppable/droppable.html",
- "effects/effects.html",
- "menu/menu.html",
- "position/position.html",
- "position/position_deprecated.html",
- "progressbar/progressbar.html",
- //"resizable/resizable.html",
- //"selectable/selectable.html",
- //"slider/slider.html",
- //"sortable/sortable.html",
- "spinner/spinner.html",
- "tabs/tabs.html",
- "tabs/tabs_deprecated.html",
- "tooltip/tooltip.html",
- "widget/widget.html"
- ];
-
- $.each( QUnit.urlParams, function( key, value ) {
- if ( key === "filter" ) {
- return;
- }
- params.push( encodeURIComponent( key ) + "=" + encodeURIComponent( value ) );
- });
- if ( params.length ) {
- params = "?" + params.join( "&" );
- suites = $.map( suites, function( suite ) {
- return suite + params;
- });
- }
- QUnit.testSuites( suites );
-
- }());
- </script>
-</head>
-<body>
-
-<h1 id="qunit-header">jQuery UI Test Suite</h1>
-<h2 id="qunit-banner"></h2>
-<div id="qunit-testrunner-toolbar"></div>
-<h2 id="qunit-userAgent"></h2>
-<ol id="qunit-tests"></ol>
-<div id="qunit-fixture">
-
-</div>
-</body>
-</html>
diff --git a/tests/unit/all.html b/tests/unit/all.html
index c1b5d0383..d4d7a0376 100644
--- a/tests/unit/all.html
+++ b/tests/unit/all.html
@@ -17,26 +17,23 @@
var params = [],
suites = [
"accordion/accordion.html",
- "accordion/accordion_deprecated.html",
"autocomplete/autocomplete.html",
"button/button.html",
"core/core.html",
"datepicker/datepicker.html",
"dialog/dialog.html",
- //"draggable/draggable.html",
- //"droppable/droppable.html",
+ "draggable/draggable.html",
+ "droppable/droppable.html",
"effects/effects.html",
"menu/menu.html",
"position/position.html",
- "position/position_deprecated.html",
"progressbar/progressbar.html",
- //"resizable/resizable.html",
- //"selectable/selectable.html",
+ "resizable/resizable.html",
+ "selectable/selectable.html",
"slider/slider.html",
- //"sortable/sortable.html",
+ "sortable/sortable.html",
"spinner/spinner.html",
"tabs/tabs.html",
- "tabs/tabs_deprecated.html",
"tooltip/tooltip.html",
"widget/widget.html"
];
diff --git a/tests/unit/autocomplete/autocomplete_core.js b/tests/unit/autocomplete/autocomplete_core.js
index f0ad36a57..845a3b19d 100644
--- a/tests/unit/autocomplete/autocomplete_core.js
+++ b/tests/unit/autocomplete/autocomplete_core.js
@@ -99,7 +99,7 @@ test( "allow form submit on enter when menu is not active", function() {
delay: 0,
minLength: 0
});
- element.data( "autocomplete" )._move = function() {
+ element.data( "ui-autocomplete" )._move = function() {
didMove = true;
};
element.simulate( "keydown", { keyCode: ( isKeyUp ? $.ui.keyCode.UP : $.ui.keyCode.DOWN ) } );
@@ -109,13 +109,12 @@ test( "allow form submit on enter when menu is not active", function() {
function arrowsMoveFocus( id, isKeyUp ) {
expect( 1 );
- var didMove = false,
- element = $( id ).autocomplete({
+ var element = $( id ).autocomplete({
source: [ "a" ],
delay: 0,
minLength: 0
});
- element.data( "autocomplete" )._move = function() {
+ element.data( "ui-autocomplete" )._move = function() {
ok( true, "repsond to arrow" );
};
element.autocomplete( "search" );
diff --git a/tests/unit/autocomplete/autocomplete_events.js b/tests/unit/autocomplete/autocomplete_events.js
index 082263a35..fb1cf73a6 100644
--- a/tests/unit/autocomplete/autocomplete_events.js
+++ b/tests/unit/autocomplete/autocomplete_events.js
@@ -39,7 +39,7 @@ $.each([
], "response ui.content" );
ui.content.splice( 0, 1 );
},
- open: function( event ) {
+ open: function() {
ok( menu.is( ":visible" ), "menu open on open" );
},
focus: function( event, ui ) {
@@ -127,7 +127,7 @@ asyncTest( "cancel focus", function() {
element = $( "#autocomplete" ).autocomplete({
delay: 0,
source: data,
- focus: function( event, ui ) {
+ focus: function() {
$( this ).val( customVal );
return false;
}
@@ -146,7 +146,7 @@ asyncTest( "cancel select", function() {
element = $( "#autocomplete" ).autocomplete({
delay: 0,
source: data,
- select: function( event, ui ) {
+ select: function() {
$( this ).val( customVal );
return false;
}
diff --git a/tests/unit/autocomplete/autocomplete_options.js b/tests/unit/autocomplete/autocomplete_options.js
index 1ab40f36c..8331c53d5 100644
--- a/tests/unit/autocomplete/autocomplete_options.js
+++ b/tests/unit/autocomplete/autocomplete_options.js
@@ -33,7 +33,7 @@ function autoFocusTest( afValue, focusedLength ) {
autoFocus: afValue,
delay: 0,
source: data,
- open: function( event, ui ) {
+ open: function() {
equal( element.autocomplete( "widget" ).children( ".ui-menu-item:first" ).find( ".ui-state-focus" ).length,
focusedLength, "first item is " + (afValue ? "" : "not") + " auto focused" );
start();
diff --git a/tests/unit/button/button_events.js b/tests/unit/button/button_events.js
index a2154021d..40d2a1a96 100644
--- a/tests/unit/button/button_events.js
+++ b/tests/unit/button/button_events.js
@@ -1,7 +1,7 @@
/*
* button_events.js
*/
-(function($) {
+(function() {
module("button: events");
diff --git a/tests/unit/button/button_tickets.js b/tests/unit/button/button_tickets.js
index 846ca7ef4..eb70181ec 100644
--- a/tests/unit/button/button_tickets.js
+++ b/tests/unit/button/button_tickets.js
@@ -61,4 +61,12 @@ test( "#7534 - Button label selector works for ids with \":\"", function() {
ok( group.find( "label" ).is( ".ui-button" ), "Found an id with a :" );
});
+test( "#8237 - Anchor tags lose disabled state when refreshed", function() {
+ expect( 1 );
+ var element = $( "<a id='a8237'></a>" ).appendTo( "#qunit-fixture" );
+
+ element.button({ disabled: true }).button( "refresh" );
+ ok( element.button( "option", "disabled" ), "Anchor button should remain disabled after refresh" );
+});
+
})( jQuery );
diff --git a/tests/unit/core/core.html b/tests/unit/core/core.html
index e259f3270..41c8db827 100644
--- a/tests/unit/core/core.html
+++ b/tests/unit/core/core.html
@@ -112,6 +112,11 @@
<span id="spanTabindex-50" tabindex="-50">.</span>
</div>
+<div style="width: 0; height: 0;">
+ <input id="dimensionlessParent">
+ <input id="dimensionlessParent-dimensionless" style="height: 0; width: 0;">
+</div>
+
<div id="zIndex100" style="z-index: 100; position: absolute">
<div id="zIndexAutoWithParent">.</div>
</div>
diff --git a/tests/unit/core/selector.js b/tests/unit/core/selector.js
index 7876cdd07..f30ad17be 100644
--- a/tests/unit/core/selector.js
+++ b/tests/unit/core/selector.js
@@ -157,6 +157,12 @@ test("focusable - area elements", function() {
isNotFocusable('#areaNoImg', 'not associated with an image');
});
+test( "focusable - dimensionless parent with overflow", function() {
+ expect( 1 );
+
+ isFocusable( "#dimensionlessParent", "input" );
+});
+
test("tabbable - visible, enabled elements", function() {
expect(18);
@@ -236,4 +242,10 @@ test("tabbable - area elements", function() {
isNotTabbable('#areaNoImg', 'not associated with an image');
});
+test( "tabbable - dimensionless parent with overflow", function() {
+ expect( 1 );
+
+ isTabbable( "#dimensionlessParent", "input" );
+});
+
})(jQuery);
diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html
index bfff32d32..390d052c3 100644
--- a/tests/unit/datepicker/datepicker.html
+++ b/tests/unit/datepicker/datepicker.html
@@ -27,18 +27,8 @@
<script src="datepicker_events.js"></script>
<script src="datepicker_methods.js"></script>
<script src="datepicker_options.js"></script>
- <script src="datepicker_tickets.js"></script>
+ <script src="datepicker_test_helpers.js"></script>
- <script>
- // disable this stale testsuite for testswarm only
- var url = window.location.search;
- url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) );
- if ( url && url.indexOf("http") == 0 ) {
- // reset config to kill previous tests; make sure testsuite.js is loaded afterwards to init the testswarm script
- QUnit.init();
- test("datepicker", function() { ok(true, "disabled datepicker testsuite"); });
- }
- </script>
<script src="../swarminject.js"></script>
</head>
<body>
diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js
index e17b239e5..86f71a1c4 100644
--- a/tests/unit/datepicker/datepicker_core.js
+++ b/tests/unit/datepicker/datepicker_core.js
@@ -2,42 +2,6 @@
* datepicker_core.js
*/
-function equalsDate(d1, d2, message) {
- if (!d1 || !d2) {
- ok(false, message + ' - missing date');
- return;
- }
- d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate());
- d2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate());
- equal(d1.toString(), d2.toString(), message);
-}
-
-function equalsDateArray(a1, a2, message) {
- if (!a1 || !a2) {
- ok(false, message + ' - missing dates');
- return;
- }
- a1[0] = (a1[0] ? new Date(a1[0].getFullYear(), a1[0].getMonth(), a1[0].getDate()) : '');
- a1[1] = (a1[1] ? new Date(a1[1].getFullYear(), a1[1].getMonth(), a1[1].getDate()) : '');
- a2[0] = (a2[0] ? new Date(a2[0].getFullYear(), a2[0].getMonth(), a2[0].getDate()) : '');
- a2[1] = (a2[1] ? new Date(a2[1].getFullYear(), a2[1].getMonth(), a2[1].getDate()) : '');
- deepEqual(a1, a2, message);
-}
-
-function addMonths(date, offset) {
- var maxDay = 32 - new Date(date.getFullYear(), date.getMonth() + offset, 32).getDate();
- date.setDate(Math.min(date.getDate(), maxDay));
- date.setMonth(date.getMonth() + offset);
- return date;
-}
-
-function init(id, options) {
- $.datepicker.setDefaults($.datepicker.regional['']);
- return $(id).datepicker($.extend({showAnim: ''}, options || {}));
-}
-
-var PROP_NAME = 'datepicker';
-
(function($) {
module("datepicker: core");
@@ -55,15 +19,14 @@ test("widget method", function() {
});
test('baseStructure', function() {
- expect( 59 );
+ expect( 58 );
var header, title, table, thead, week, panel, inl, child,
- inp = init('#inp').focus(),
- dp = $('#ui-datepicker-div'),
- iframe = ($.ui.ie6);
+ inp = TestHelpers.datepicker.init('#inp').focus(),
+ dp = $('#ui-datepicker-div');
ok(dp.is(':visible'), 'Structure - datepicker visible');
ok(!dp.is('.ui-datepicker-rtl'), 'Structure - not right-to-left');
ok(!dp.is('.ui-datepicker-multi'), 'Structure - not multi-month');
- equal(dp.children().length, 2 + (iframe ? 1 : 0), 'Structure - child count');
+ equal(dp.children().length, 2, 'Structure - child count');
header = dp.children(':first');
ok(header.is('div.ui-datepicker-header'), 'Structure - header division');
@@ -90,11 +53,10 @@ test('baseStructure', function() {
equal(week.children().length, 7, 'Structure - week child count');
ok(week.children(':first').is('td.ui-datepicker-week-end'), 'Structure - month table first day cell');
ok(week.children(':last').is('td.ui-datepicker-week-end'), 'Structure - month table second day cell');
- ok(dp.children('iframe').length === (iframe ? 1 : 0), 'Structure - iframe');
inp.datepicker('hide').datepicker('destroy');
// Editable month/year and button panel
- inp = init('#inp', {changeMonth: true, changeYear: true, showButtonPanel: true});
+ inp = TestHelpers.datepicker.init('#inp', {changeMonth: true, changeYear: true, showButtonPanel: true});
inp.focus();
title = dp.find('div.ui-datepicker-title');
@@ -109,10 +71,10 @@ test('baseStructure', function() {
inp.datepicker('hide').datepicker('destroy');
// Multi-month 2
- inp = init('#inp', {numberOfMonths: 2});
+ inp = TestHelpers.datepicker.init('#inp', {numberOfMonths: 2});
inp.focus();
ok(dp.is('.ui-datepicker-multi'), 'Structure multi [2] - multi-month');
- equal(dp.children().length, 3 + (iframe ? 1 : 0), 'Structure multi [2] - child count');
+ equal(dp.children().length, 3, 'Structure multi [2] - child count');
child = dp.children(':first');
ok(child.is('div.ui-datepicker-group') && child.is('div.ui-datepicker-group-first'), 'Structure multi [2] - first month division');
child = dp.children(':eq(1)');
@@ -123,17 +85,17 @@ test('baseStructure', function() {
inp.datepicker('hide').datepicker('destroy');
// Multi-month 3
- inp = init('#inp', {numberOfMonths: 3});
+ inp = TestHelpers.datepicker.init('#inp', {numberOfMonths: 3});
inp.focus();
ok(dp.is('.ui-datepicker-multi-3'), 'Structure multi [3] - multi-3');
ok(! dp.is('.ui-datepicker-multi-2'), 'Structure multi [3] - Trac #6704');
inp.datepicker('hide').datepicker('destroy');
// Multi-month [2, 2]
- inp = init('#inp', {numberOfMonths: [2, 2]});
+ inp = TestHelpers.datepicker.init('#inp', {numberOfMonths: [2, 2]});
inp.focus();
ok(dp.is('.ui-datepicker-multi'), 'Structure multi - multi-month');
- equal(dp.children().length, 6 + (iframe ? 1 : 0), 'Structure multi [2,2] - child count');
+ equal(dp.children().length, 6, 'Structure multi [2,2] - child count');
child = dp.children(':first');
ok(child.is('div.ui-datepicker-group') && child.is('div.ui-datepicker-group-first'), 'Structure multi [2,2] - first month division');
child = dp.children(':eq(1)');
@@ -149,7 +111,7 @@ test('baseStructure', function() {
inp.datepicker('hide').datepicker('destroy');
// Inline
- inl = init('#inl');
+ inl = TestHelpers.datepicker.init('#inl');
dp = inl.children();
ok(dp.is('.ui-datepicker-inline'), 'Structure inline - main div');
ok(!dp.is('.ui-datepicker-rtl'), 'Structure inline - not right-to-left');
@@ -165,10 +127,10 @@ test('baseStructure', function() {
inl.datepicker('destroy');
// Inline multi-month
- inl = init('#inl', {numberOfMonths: 2});
+ inl = TestHelpers.datepicker.init('#inl', {numberOfMonths: 2});
dp = inl.children();
ok(dp.is('.ui-datepicker-inline') && dp.is('.ui-datepicker-multi'), 'Structure inline multi - main div');
- equal(dp.children().length, 3 + (iframe ? 1 : 0), 'Structure inline multi - child count');
+ equal(dp.children().length, 3, 'Structure inline multi - child count');
child = dp.children(':first');
ok(child.is('div.ui-datepicker-group') && child.is('div.ui-datepicker-group-first'), 'Structure inline multi - first month division');
child = dp.children(':eq(1)');
@@ -180,13 +142,12 @@ test('baseStructure', function() {
test('customStructure', function() {
expect( 20 );
- var iframe, header, panel, title, thead,
+ var header, panel, title, thead,
dp = $('#ui-datepicker-div'),
// Check right-to-left localisation
- inp = init('#inp', $.datepicker.regional.he);
+ inp = TestHelpers.datepicker.init('#inp', $.datepicker.regional.he);
inp.data('showButtonPanel.datepicker',true);
inp.focus();
- iframe = ($.ui.ie6);
ok(dp.is('.ui-datepicker-rtl'), 'Structure RTL - right-to-left');
header = dp.children(':first');
ok(header.is('div.ui-datepicker-header'), 'Structure RTL - header division');
@@ -201,7 +162,7 @@ test('customStructure', function() {
inp.datepicker('hide').datepicker('destroy');
// Hide prev/next
- inp = init('#inp', {hideIfNoPrevNext: true, minDate: new Date(2008, 2 - 1, 4), maxDate: new Date(2008, 2 - 1, 14)});
+ inp = TestHelpers.datepicker.init('#inp', {hideIfNoPrevNext: true, minDate: new Date(2008, 2 - 1, 4), maxDate: new Date(2008, 2 - 1, 14)});
inp.val('02/10/2008').focus();
header = dp.children(':first');
ok(header.is('div.ui-datepicker-header'), 'Structure hide prev/next - header division');
@@ -210,7 +171,7 @@ test('customStructure', function() {
inp.datepicker('hide').datepicker('destroy');
// Changeable Month with read-only year
- inp = init('#inp', {changeMonth: true});
+ inp = TestHelpers.datepicker.init('#inp', {changeMonth: true});
inp.focus();
title = dp.children(':first').children(':last');
equal(title.children().length, 2, 'Structure changeable month - title child count');
@@ -219,7 +180,7 @@ test('customStructure', function() {
inp.datepicker('hide').datepicker('destroy');
// Changeable year with read-only month
- inp = init('#inp', {changeYear: true});
+ inp = TestHelpers.datepicker.init('#inp', {changeYear: true});
inp.focus();
title = dp.children(':first').children(':last');
equal(title.children().length, 2, 'Structure changeable year - title child count');
@@ -228,7 +189,7 @@ test('customStructure', function() {
inp.datepicker('hide').datepicker('destroy');
// Read-only first day of week
- inp = init('#inp', {changeFirstDay: false});
+ inp = TestHelpers.datepicker.init('#inp', {changeFirstDay: false});
inp.focus();
thead = dp.find('.ui-datepicker-calendar thead tr');
equal(thead.children().length, 7, 'Structure read-only first day - thead child count');
@@ -238,19 +199,19 @@ test('customStructure', function() {
test('keystrokes', function() {
expect( 26 );
- var inp = init('#inp'),
+ var inp = TestHelpers.datepicker.init('#inp'),
date = new Date();
inp.val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), date, 'Keystroke enter');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Keystroke enter');
inp.val('02/04/2008').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 4),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 4),
'Keystroke enter - preset');
inp.val('02/04/2008').datepicker('show').
simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.HOME}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+home');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+home');
inp.val('02/04/2008').datepicker('show').
simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.END});
ok(inp.datepicker('getDate') == null, 'Keystroke ctrl+end');
@@ -259,95 +220,95 @@ test('keystrokes', function() {
ok(inp.datepicker('getDate') == null, 'Keystroke esc');
inp.val('02/04/2008').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ESCAPE});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 4),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 4),
'Keystroke esc - preset');
inp.val('02/04/2008').datepicker('show').
simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
simulate('keydown', {keyCode: $.ui.keyCode.ESCAPE});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 4),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 4),
'Keystroke esc - abandoned');
// Moving by day or week
inp.val('').datepicker('show').
simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.LEFT}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date.setDate(date.getDate() - 1);
- equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+left');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+left');
inp.val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.LEFT}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date.setDate(date.getDate() + 1);
- equalsDate(inp.datepicker('getDate'), date, 'Keystroke left');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Keystroke left');
inp.val('').datepicker('show').
simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.RIGHT}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date.setDate(date.getDate() + 1);
- equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+right');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+right');
inp.val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.RIGHT}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date.setDate(date.getDate() - 1);
- equalsDate(inp.datepicker('getDate'), date, 'Keystroke right');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Keystroke right');
inp.val('').datepicker('show').
simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.UP}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date.setDate(date.getDate() - 7);
- equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+up');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+up');
inp.val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.UP}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date.setDate(date.getDate() + 7);
- equalsDate(inp.datepicker('getDate'), date, 'Keystroke up');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Keystroke up');
inp.val('').datepicker('show').
simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date.setDate(date.getDate() + 7);
- equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+down');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+down');
inp.val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.DOWN}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date.setDate(date.getDate() - 7);
- equalsDate(inp.datepicker('getDate'), date, 'Keystroke down');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Keystroke down');
// Moving by month or year
inp.val('02/04/2008').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.PAGE_UP}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 1 - 1, 4),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 1 - 1, 4),
'Keystroke pgup');
inp.val('02/04/2008').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.PAGE_DOWN}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 3 - 1, 4),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 3 - 1, 4),
'Keystroke pgdn');
inp.val('02/04/2008').datepicker('show').
simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), new Date(2007, 2 - 1, 4),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2007, 2 - 1, 4),
'Keystroke ctrl+pgup');
inp.val('02/04/2008').datepicker('show').
simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), new Date(2009, 2 - 1, 4),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2009, 2 - 1, 4),
'Keystroke ctrl+pgdn');
// Check for moving to short months
inp.val('03/31/2008').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.PAGE_UP}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 29),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 29),
'Keystroke pgup - Feb');
inp.val('01/30/2008').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.PAGE_DOWN}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 29),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 29),
'Keystroke pgdn - Feb');
inp.val('02/29/2008').datepicker('show').
simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), new Date(2007, 2 - 1, 28),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2007, 2 - 1, 28),
'Keystroke ctrl+pgup - Feb');
inp.val('02/29/2008').datepicker('show').
simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), new Date(2009, 2 - 1, 28),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2009, 2 - 1, 28),
'Keystroke ctrl+pgdn - Feb');
// Goto current
inp.datepicker('option', {gotoCurrent: true}).
@@ -355,35 +316,35 @@ test('keystrokes', function() {
simulate('keydown', {keyCode: $.ui.keyCode.PAGE_DOWN}).
simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.HOME}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 4),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 4),
'Keystroke ctrl+home');
// Change steps
inp.datepicker('option', {stepMonths: 2, gotoCurrent: false}).
datepicker('hide').val('02/04/2008').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.PAGE_UP}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), new Date(2007, 12 - 1, 4),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2007, 12 - 1, 4),
'Keystroke pgup step 2');
inp.val('02/04/2008').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.PAGE_DOWN}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 4 - 1, 4),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 4 - 1, 4),
'Keystroke pgdn step 2');
});
test('mouse', function() {
expect( 15 );
var inl,
- inp = init('#inp'),
+ inp = TestHelpers.datepicker.init('#inp'),
dp = $('#ui-datepicker-div'),
date = new Date();
inp.val('').datepicker('show');
$('.ui-datepicker-calendar tbody a:contains(10)', dp).simulate('click', {});
date.setDate(10);
- equalsDate(inp.datepicker('getDate'), date, 'Mouse click');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Mouse click');
inp.val('02/04/2008').datepicker('show');
$('.ui-datepicker-calendar tbody a:contains(12)', dp).simulate('click', {});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 12),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 12),
'Mouse click - preset');
inp.val('02/04/2008').datepicker('show');
inp.val('').datepicker('show');
@@ -391,66 +352,66 @@ test('mouse', function() {
ok(inp.datepicker('getDate') == null, 'Mouse click - close');
inp.val('02/04/2008').datepicker('show');
$('button.ui-datepicker-close', dp).simulate('click', {});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 4),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 4),
'Mouse click - close + preset');
inp.val('02/04/2008').datepicker('show');
$('a.ui-datepicker-prev', dp).simulate('click', {});
$('button.ui-datepicker-close', dp).simulate('click', {});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 4),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 4),
'Mouse click - abandoned');
// Current/previous/next
inp.val('02/04/2008').datepicker('option', {showButtonPanel: true}).datepicker('show');
$('.ui-datepicker-current', dp).simulate('click', {});
$('.ui-datepicker-calendar tbody a:contains(14)', dp).simulate('click', {});
date.setDate(14);
- equalsDate(inp.datepicker('getDate'), date, 'Mouse click - current');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Mouse click - current');
inp.val('02/04/2008').datepicker('show');
$('.ui-datepicker-prev', dp).simulate('click');
$('.ui-datepicker-calendar tbody a:contains(16)', dp).simulate('click');
- equalsDate(inp.datepicker('getDate'), new Date(2008, 1 - 1, 16),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 1 - 1, 16),
'Mouse click - previous');
inp.val('02/04/2008').datepicker('show');
$('.ui-datepicker-next', dp).simulate('click');
$('.ui-datepicker-calendar tbody a:contains(18)', dp).simulate('click');
- equalsDate(inp.datepicker('getDate'), new Date(2008, 3 - 1, 18),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 3 - 1, 18),
'Mouse click - next');
// Previous/next with minimum/maximum
inp.datepicker('option', {minDate: new Date(2008, 2 - 1, 2),
maxDate: new Date(2008, 2 - 1, 26)}).val('02/04/2008').datepicker('show');
$('.ui-datepicker-prev', dp).simulate('click');
$('.ui-datepicker-calendar tbody a:contains(16)', dp).simulate('click');
- equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 16),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 16),
'Mouse click - previous + min/max');
inp.val('02/04/2008').datepicker('show');
$('.ui-datepicker-next', dp).simulate('click');
$('.ui-datepicker-calendar tbody a:contains(18)', dp).simulate('click');
- equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 18),
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 18),
'Mouse click - next + min/max');
// Inline
- inl = init('#inl');
+ inl = TestHelpers.datepicker.init('#inl');
dp = $('.ui-datepicker-inline', inl);
date = new Date();
inl.datepicker('setDate', date);
$('.ui-datepicker-calendar tbody a:contains(10)', dp).simulate('click', {});
date.setDate(10);
- equalsDate(inl.datepicker('getDate'), date, 'Mouse click inline');
+ TestHelpers.datepicker.equalsDate(inl.datepicker('getDate'), date, 'Mouse click inline');
inl.datepicker('option', {showButtonPanel: true}).datepicker('setDate', new Date(2008, 2 - 1, 4));
$('.ui-datepicker-calendar tbody a:contains(12)', dp).simulate('click', {});
- equalsDate(inl.datepicker('getDate'), new Date(2008, 2 - 1, 12), 'Mouse click inline - preset');
+ TestHelpers.datepicker.equalsDate(inl.datepicker('getDate'), new Date(2008, 2 - 1, 12), 'Mouse click inline - preset');
inl.datepicker('option', {showButtonPanel: true});
$('.ui-datepicker-current', dp).simulate('click', {});
$('.ui-datepicker-calendar tbody a:contains(14)', dp).simulate('click', {});
date.setDate(14);
- equalsDate(inl.datepicker('getDate'), date, 'Mouse click inline - current');
+ TestHelpers.datepicker.equalsDate(inl.datepicker('getDate'), date, 'Mouse click inline - current');
inl.datepicker('setDate', new Date(2008, 2 - 1, 4));
$('.ui-datepicker-prev', dp).simulate('click');
$('.ui-datepicker-calendar tbody a:contains(16)', dp).simulate('click');
- equalsDate(inl.datepicker('getDate'), new Date(2008, 1 - 1, 16),
+ TestHelpers.datepicker.equalsDate(inl.datepicker('getDate'), new Date(2008, 1 - 1, 16),
'Mouse click inline - previous');
inl.datepicker('setDate', new Date(2008, 2 - 1, 4));
$('.ui-datepicker-next', dp).simulate('click');
$('.ui-datepicker-calendar tbody a:contains(18)', dp).simulate('click');
- equalsDate(inl.datepicker('getDate'), new Date(2008, 3 - 1, 18),
+ TestHelpers.datepicker.equalsDate(inl.datepicker('getDate'), new Date(2008, 3 - 1, 18),
'Mouse click inline - next');
});
diff --git a/tests/unit/datepicker/datepicker_defaults.js b/tests/unit/datepicker/datepicker_defaults.js
index 28e150791..1e7d90852 100644
--- a/tests/unit/datepicker/datepicker_defaults.js
+++ b/tests/unit/datepicker/datepicker_defaults.js
@@ -2,8 +2,10 @@
* datepicker_defaults.js
*/
+/*
var datepicker_defaults = {
disabled: false
};
-//TestHelpers.commonWidgetTests('datepicker', { defaults: datepicker_defaults });
+TestHelpers.commonWidgetTests('datepicker', { defaults: datepicker_defaults });
+*/
diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js
index e35be62ce..5e8a35e0d 100644
--- a/tests/unit/datepicker/datepicker_events.js
+++ b/tests/unit/datepicker/datepicker_events.js
@@ -24,13 +24,13 @@ function callback2(year, month, inst) {
test('events', function() {
expect( 26 );
var dateStr, newMonthYear, inp2,
- inp = init('#inp', {onSelect: callback}),
+ inp = TestHelpers.datepicker.init('#inp', {onSelect: callback}),
date = new Date();
// onSelect
inp.val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
equal(selectedThis, inp[0], 'Callback selected this');
- equal(selectedInst, $.data(inp[0], PROP_NAME), 'Callback selected inst');
+ equal(selectedInst, $.data(inp[0], TestHelpers.datepicker.PROP_NAME), 'Callback selected inst');
equal(selectedDate, $.datepicker.formatDate('mm/dd/yy', date),
'Callback selected date');
inp.val('').datepicker('show').
@@ -59,7 +59,7 @@ test('events', function() {
inp.simulate('keydown', {keyCode: $.ui.keyCode.PAGE_UP});
date.setMonth(date.getMonth() - 1);
equal(selectedThis, inp[0], 'Callback change month/year this');
- equal(selectedInst, $.data(inp[0], PROP_NAME), 'Callback change month/year inst');
+ equal(selectedInst, $.data(inp[0], TestHelpers.datepicker.PROP_NAME), 'Callback change month/year inst');
equal(selectedDate, newMonthYear(date),
'Callback change month/year date - pgup');
inp.simulate('keydown', {keyCode: $.ui.keyCode.PAGE_DOWN});
@@ -107,7 +107,7 @@ test('events', function() {
val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ESCAPE});
equal(selectedThis, inp[0], 'Callback close this');
- equal(selectedInst, $.data(inp[0], PROP_NAME), 'Callback close inst');
+ equal(selectedInst, $.data(inp[0], TestHelpers.datepicker.PROP_NAME), 'Callback close inst');
equal(selectedDate, '', 'Callback close date - esc');
inp.val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
@@ -120,10 +120,29 @@ test('events', function() {
simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.END});
equal(selectedDate, '', 'Callback close date - ctrl+end');
- inp2 = init('#inp2');
+ inp2 = TestHelpers.datepicker.init('#inp2');
inp2.datepicker().datepicker('option', {onClose: callback}).datepicker('show');
inp.datepicker('show');
equal(selectedThis, inp2[0], 'Callback close this');
});
+test('beforeShowDay-getDate', function() {
+ expect( 3 );
+ var inp = TestHelpers.datepicker.init('#inp', {beforeShowDay: function() { inp.datepicker('getDate'); return [true, '']; }}),
+ dp = $('#ui-datepicker-div');
+ inp.val('01/01/2010').datepicker('show');
+ // contains non-breaking space
+ equal($('div.ui-datepicker-title').text(), 'January 2010', 'Initial month');
+ $('a.ui-datepicker-next', dp).click();
+ $('a.ui-datepicker-next', dp).click();
+ // contains non-breaking space
+ equal($('div.ui-datepicker-title').text(), 'March 2010', 'After next clicks');
+ inp.datepicker('hide').datepicker('show');
+ $('a.ui-datepicker-prev', dp).click();
+ $('a.ui-datepicker-prev', dp).click();
+ // contains non-breaking space
+ equal($('div.ui-datepicker-title').text(), 'November 2009', 'After prev clicks');
+ inp.datepicker('hide');
+});
+
})(jQuery);
diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js
index e7aa7602e..d2964a266 100644
--- a/tests/unit/datepicker/datepicker_methods.js
+++ b/tests/unit/datepicker/datepicker_methods.js
@@ -8,65 +8,65 @@ module("datepicker: methods");
test('destroy', function() {
expect( 33 );
var inl,
- inp = init('#inp');
+ inp = TestHelpers.datepicker.init('#inp');
ok(inp.is('.hasDatepicker'), 'Default - marker class set');
- ok($.data(inp[0], PROP_NAME), 'Default - instance present');
+ ok($.data(inp[0], TestHelpers.datepicker.PROP_NAME), 'Default - instance present');
ok(inp.next().is('#alt'), 'Default - button absent');
inp.datepicker('destroy');
inp = $('#inp');
ok(!inp.is('.hasDatepicker'), 'Default - marker class cleared');
- ok(!$.data(inp[0], PROP_NAME), 'Default - instance absent');
+ ok(!$.data(inp[0], TestHelpers.datepicker.PROP_NAME), 'Default - instance absent');
ok(inp.next().is('#alt'), 'Default - button absent');
// With button
- inp= init('#inp', {showOn: 'both'});
+ inp= TestHelpers.datepicker.init('#inp', {showOn: 'both'});
ok(inp.is('.hasDatepicker'), 'Button - marker class set');
- ok($.data(inp[0], PROP_NAME), 'Button - instance present');
+ ok($.data(inp[0], TestHelpers.datepicker.PROP_NAME), 'Button - instance present');
ok(inp.next().text() === '...', 'Button - button added');
inp.datepicker('destroy');
inp = $('#inp');
ok(!inp.is('.hasDatepicker'), 'Button - marker class cleared');
- ok(!$.data(inp[0], PROP_NAME), 'Button - instance absent');
+ ok(!$.data(inp[0], TestHelpers.datepicker.PROP_NAME), 'Button - instance absent');
ok(inp.next().is('#alt'), 'Button - button removed');
// With append text
- inp = init('#inp', {appendText: 'Testing'});
+ inp = TestHelpers.datepicker.init('#inp', {appendText: 'Testing'});
ok(inp.is('.hasDatepicker'), 'Append - marker class set');
- ok($.data(inp[0], PROP_NAME), 'Append - instance present');
+ ok($.data(inp[0], TestHelpers.datepicker.PROP_NAME), 'Append - instance present');
ok(inp.next().text() === 'Testing', 'Append - append text added');
inp.datepicker('destroy');
inp = $('#inp');
ok(!inp.is('.hasDatepicker'), 'Append - marker class cleared');
- ok(!$.data(inp[0], PROP_NAME), 'Append - instance absent');
+ ok(!$.data(inp[0], TestHelpers.datepicker.PROP_NAME), 'Append - instance absent');
ok(inp.next().is('#alt'), 'Append - append text removed');
// With both
- inp= init('#inp', {showOn: 'both', buttonImageOnly: true,
+ inp= TestHelpers.datepicker.init('#inp', {showOn: 'both', buttonImageOnly: true,
buttonImage: 'img/calendar.gif', appendText: 'Testing'});
ok(inp.is('.hasDatepicker'), 'Both - marker class set');
- ok($.data(inp[0], PROP_NAME), 'Both - instance present');
+ ok($.data(inp[0], TestHelpers.datepicker.PROP_NAME), 'Both - instance present');
ok(inp.next()[0].nodeName.toLowerCase() === 'img', 'Both - button added');
ok(inp.next().next().text() === 'Testing', 'Both - append text added');
inp.datepicker('destroy');
inp = $('#inp');
ok(!inp.is('.hasDatepicker'), 'Both - marker class cleared');
- ok(!$.data(inp[0], PROP_NAME), 'Both - instance absent');
+ ok(!$.data(inp[0], TestHelpers.datepicker.PROP_NAME), 'Both - instance absent');
ok(inp.next().is('#alt'), 'Both - button and append text absent');
// Inline
- inl = init('#inl');
+ inl = TestHelpers.datepicker.init('#inl');
ok(inl.is('.hasDatepicker'), 'Inline - marker class set');
ok(inl.html() !== '', 'Inline - datepicker present');
- ok($.data(inl[0], PROP_NAME), 'Inline - instance present');
+ ok($.data(inl[0], TestHelpers.datepicker.PROP_NAME), 'Inline - instance present');
ok(inl.next().length === 0 || inl.next().is('p'), 'Inline - button absent');
inl.datepicker('destroy');
inl = $('#inl');
ok(!inl.is('.hasDatepicker'), 'Inline - marker class cleared');
ok(inl.html() === '', 'Inline - datepicker absent');
- ok(!$.data(inl[0], PROP_NAME), 'Inline - instance absent');
+ ok(!$.data(inl[0], TestHelpers.datepicker.PROP_NAME), 'Inline - instance absent');
ok(inl.next().length === 0 || inl.next().is('p'), 'Inline - button absent');
});
test('enableDisable', function() {
expect( 33 );
var inl, dp,
- inp = init('#inp');
+ inp = TestHelpers.datepicker.init('#inp');
ok(!inp.datepicker('isDisabled'), 'Enable/disable - initially marked as enabled');
ok(!inp[0].disabled, 'Enable/disable - field initially enabled');
inp.datepicker('disable');
@@ -77,7 +77,7 @@ test('enableDisable', function() {
ok(!inp[0].disabled, 'Enable/disable - field now enabled');
inp.datepicker('destroy');
// With a button
- inp = init('#inp', {showOn: 'button'});
+ inp = TestHelpers.datepicker.init('#inp', {showOn: 'button'});
ok(!inp.datepicker('isDisabled'), 'Enable/disable button - initially marked as enabled');
ok(!inp[0].disabled, 'Enable/disable button - field initially enabled');
ok(!inp.next('button')[0].disabled, 'Enable/disable button - button initially enabled');
@@ -91,7 +91,7 @@ test('enableDisable', function() {
ok(!inp.next('button')[0].disabled, 'Enable/disable button - button now enabled');
inp.datepicker('destroy');
// With an image button
- inp = init('#inp', {showOn: 'button', buttonImageOnly: true,
+ inp = TestHelpers.datepicker.init('#inp', {showOn: 'button', buttonImageOnly: true,
buttonImage: 'img/calendar.gif'});
ok(!inp.datepicker('isDisabled'), 'Enable/disable image - initially marked as enabled');
ok(!inp[0].disabled, 'Enable/disable image - field initially enabled');
@@ -106,7 +106,7 @@ test('enableDisable', function() {
ok(parseFloat(inp.next('img').css('opacity')) === 1, 'Enable/disable image - image now enabled');
inp.datepicker('destroy');
// Inline
- inl = init('#inl', {changeYear: true});
+ inl = TestHelpers.datepicker.init('#inl', {changeYear: true});
dp = $('.ui-datepicker-inline', inl);
ok(!inl.datepicker('isDisabled'), 'Enable/disable inline - initially marked as enabled');
ok(!dp.children().is('.ui-state-disabled'), 'Enable/disable inline - not visually disabled initially');
diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js
index a01b9c7e0..9078a2374 100644
--- a/tests/unit/datepicker/datepicker_options.js
+++ b/tests/unit/datepicker/datepicker_options.js
@@ -8,7 +8,7 @@ module("datepicker: options");
test('setDefaults', function() {
expect( 3 );
- var inp = init('#inp');
+ TestHelpers.datepicker.init('#inp');
equal($.datepicker._defaults.showOn, 'focus', 'Initial showOn');
$.datepicker.setDefaults({showOn: 'button'});
equal($.datepicker._defaults.showOn, 'button', 'Change default showOn');
@@ -18,8 +18,8 @@ test('setDefaults', function() {
test('option', function() {
expect( 17 );
- var inp = init('#inp'),
- inst = $.data(inp[0], PROP_NAME);
+ var inp = TestHelpers.datepicker.init('#inp'),
+ inst = $.data(inp[0], TestHelpers.datepicker.PROP_NAME);
// Set option
equal(inst.settings.showOn, null, 'Initial setting showOn');
equal($.datepicker._get(inst, 'showOn'), 'focus', 'Initial instance showOn');
@@ -37,7 +37,7 @@ test('option', function() {
equal($.datepicker._get(inst, 'showOn'), 'focus', 'Restore instance showOn');
equal($.datepicker._defaults.showOn, 'focus', 'Retain default showOn');
// Get option
- inp = init('#inp');
+ inp = TestHelpers.datepicker.init('#inp');
equal(inp.datepicker('option', 'showOn'), 'focus', 'Initial setting showOn');
inp.datepicker('option', 'showOn', 'button');
equal(inp.datepicker('option', 'showOn'), 'button', 'Change instance showOn');
@@ -50,8 +50,8 @@ test('option', function() {
test('change', function() {
expect( 12 );
- var inp = init('#inp'),
- inst = $.data(inp[0], PROP_NAME);
+ var inp = TestHelpers.datepicker.init('#inp'),
+ inst = $.data(inp[0], TestHelpers.datepicker.PROP_NAME);
equal(inst.settings.showOn, null, 'Initial setting showOn');
equal($.datepicker._get(inst, 'showOn'), 'focus', 'Initial instance showOn');
equal($.datepicker._defaults.showOn, 'focus', 'Initial default showOn');
@@ -72,7 +72,7 @@ test('change', function() {
test('invocation', function() {
expect( 29 );
var button, image,
- inp = init('#inp'),
+ inp = TestHelpers.datepicker.init('#inp'),
dp = $('#ui-datepicker-div'),
body = $('body');
// On focus
@@ -90,7 +90,7 @@ test('invocation', function() {
ok(!dp.is(':visible'), 'Focus - hidden on external click');
inp.datepicker('hide').datepicker('destroy');
// On button
- inp = init('#inp', {showOn: 'button', buttonText: 'Popup'});
+ inp = TestHelpers.datepicker.init('#inp', {showOn: 'button', buttonText: 'Popup'});
ok(!dp.is(':visible'), 'Button - initially hidden');
button = inp.siblings('button');
image = inp.siblings('img');
@@ -105,7 +105,7 @@ test('invocation', function() {
ok(!dp.is(':visible'), 'Button - hidden on second button click');
inp.datepicker('hide').datepicker('destroy');
// On image button
- inp = init('#inp', {showOn: 'button', buttonImageOnly: true,
+ inp = TestHelpers.datepicker.init('#inp', {showOn: 'button', buttonImageOnly: true,
buttonImage: 'img/calendar.gif', buttonText: 'Cal'});
ok(!dp.is(':visible'), 'Image button - initially hidden');
button = inp.siblings('button');
@@ -122,7 +122,7 @@ test('invocation', function() {
ok(!dp.is(':visible'), 'Image button - hidden on second image click');
inp.datepicker('hide').datepicker('destroy');
// On both
- inp = init('#inp', {showOn: 'both', buttonImage: 'img/calendar.gif'});
+ inp = TestHelpers.datepicker.init('#inp', {showOn: 'both', buttonImage: 'img/calendar.gif'});
ok(!dp.is(':visible'), 'Both - initially hidden');
button = inp.siblings('button');
ok(button.length === 1, 'Both - button present');
@@ -143,7 +143,7 @@ test('invocation', function() {
test('otherMonths', function() {
expect( 8 );
- var inp = init('#inp'),
+ var inp = TestHelpers.datepicker.init('#inp'),
pop = $('#ui-datepicker-div');
inp.val('06/01/2009').datepicker('show');
equal(pop.find('tbody').text(), '\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0',
@@ -164,105 +164,106 @@ test('otherMonths', function() {
});
test('defaultDate', function() {
- expect( 17 );
- var inp = init('#inp'),
+ expect( 16 );
+ var inp = TestHelpers.datepicker.init('#inp'),
date = new Date();
inp.val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), date, 'Default date null');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date null');
+
// Numeric values
inp.datepicker('option', {defaultDate: -2}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date.setDate(date.getDate() - 2);
- equalsDate(inp.datepicker('getDate'), date, 'Default date -2');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date -2');
+
+ date = new Date();
inp.datepicker('option', {defaultDate: 3}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() + 5);
- equalsDate(inp.datepicker('getDate'), date, 'Default date 3');
- inp.datepicker('option', {defaultDate: 1 / 0}).
- datepicker('hide').val('').datepicker('show').
- simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- date.setDate(date.getDate() - 3);
- equalsDate(inp.datepicker('getDate'), date, 'Default date Infinity');
+ date.setDate(date.getDate() + 3);
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date 3');
+
+ date = new Date();
inp.datepicker('option', {defaultDate: 1 / 'a'}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), date, 'Default date NaN');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date NaN');
+
// String offset values
inp.datepicker('option', {defaultDate: '-1d'}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date.setDate(date.getDate() - 1);
- equalsDate(inp.datepicker('getDate'), date, 'Default date -1d');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date -1d');
inp.datepicker('option', {defaultDate: '+3D'}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date.setDate(date.getDate() + 4);
- equalsDate(inp.datepicker('getDate'), date, 'Default date +3D');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date +3D');
inp.datepicker('option', {defaultDate: ' -2 w '}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date = new Date();
date.setDate(date.getDate() - 14);
- equalsDate(inp.datepicker('getDate'), date, 'Default date -2 w');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date -2 w');
inp.datepicker('option', {defaultDate: '+1 W'}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date.setDate(date.getDate() + 21);
- equalsDate(inp.datepicker('getDate'), date, 'Default date +1 W');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date +1 W');
inp.datepicker('option', {defaultDate: ' -1 m '}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- date = addMonths(new Date(), -1);
- equalsDate(inp.datepicker('getDate'), date, 'Default date -1 m');
+ date = TestHelpers.datepicker.addMonths(new Date(), -1);
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date -1 m');
inp.datepicker('option', {defaultDate: '+2M'}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- date = addMonths(new Date(), 2);
- equalsDate(inp.datepicker('getDate'), date, 'Default date +2M');
+ date = TestHelpers.datepicker.addMonths(new Date(), 2);
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date +2M');
inp.datepicker('option', {defaultDate: '-2y'}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date = new Date();
date.setFullYear(date.getFullYear() - 2);
- equalsDate(inp.datepicker('getDate'), date, 'Default date -2y');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date -2y');
inp.datepicker('option', {defaultDate: '+1 Y '}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date.setFullYear(date.getFullYear() + 3);
- equalsDate(inp.datepicker('getDate'), date, 'Default date +1 Y');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date +1 Y');
inp.datepicker('option', {defaultDate: '+1M +10d'}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- date = addMonths(new Date(), 1);
+ date = TestHelpers.datepicker.addMonths(new Date(), 1);
date.setDate(date.getDate() + 10);
- equalsDate(inp.datepicker('getDate'), date, 'Default date +1M +10d');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date +1M +10d');
// String date values
inp.datepicker('option', {defaultDate: '07/04/2007'}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date = new Date(2007, 7 - 1, 4);
- equalsDate(inp.datepicker('getDate'), date, 'Default date 07/04/2007');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date 07/04/2007');
inp.datepicker('option', {dateFormat: 'yy-mm-dd', defaultDate: '2007-04-02'}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
date = new Date(2007, 4 - 1, 2);
- equalsDate(inp.datepicker('getDate'), date, 'Default date 2007-04-02');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date 2007-04-02');
// Date value
date = new Date(2007, 1 - 1, 26);
inp.datepicker('option', {dateFormat: 'mm/dd/yy', defaultDate: date}).
datepicker('hide').val('').datepicker('show').
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), date, 'Default date 01/26/2007');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date, 'Default date 01/26/2007');
});
test('miscellaneous', function() {
expect( 19 );
var curYear, longNames, shortNames, date,
dp = $('#ui-datepicker-div'),
- inp = init('#inp');
+ inp = TestHelpers.datepicker.init('#inp');
// Year range
function genRange(start, offset) {
var i = start,
@@ -323,7 +324,7 @@ test('miscellaneous', function() {
test('minMax', function() {
expect( 17 );
var date,
- inp = init('#inp'),
+ inp = TestHelpers.datepicker.init('#inp'),
lastYear = new Date(2007, 6 - 1, 4),
nextYear = new Date(2009, 6 - 1, 4),
minDate = new Date(2008, 2 - 1, 29),
@@ -331,45 +332,45 @@ test('minMax', function() {
inp.val('06/04/2008').datepicker('show');
inp.simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), lastYear,
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), lastYear,
'Min/max - null, null - ctrl+pgup');
inp.val('06/04/2008').datepicker('show');
inp.simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), nextYear,
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), nextYear,
'Min/max - null, null - ctrl+pgdn');
inp.datepicker('option', {minDate: minDate}).
datepicker('hide').val('06/04/2008').datepicker('show');
inp.simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), minDate,
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), minDate,
'Min/max - 02/29/2008, null - ctrl+pgup');
inp.val('06/04/2008').datepicker('show');
inp.simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), nextYear,
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), nextYear,
'Min/max - 02/29/2008, null - ctrl+pgdn');
inp.datepicker('option', {maxDate: maxDate}).
datepicker('hide').val('06/04/2008').datepicker('show');
inp.simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), minDate,
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), minDate,
'Min/max - 02/29/2008, 12/07/2008 - ctrl+pgup');
inp.val('06/04/2008').datepicker('show');
inp.simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), maxDate,
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), maxDate,
'Min/max - 02/29/2008, 12/07/2008 - ctrl+pgdn');
inp.datepicker('option', {minDate: null}).
datepicker('hide').val('06/04/2008').datepicker('show');
inp.simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), lastYear,
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), lastYear,
'Min/max - null, 12/07/2008 - ctrl+pgup');
inp.val('06/04/2008').datepicker('show');
inp.simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), maxDate,
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), maxDate,
'Min/max - null, 12/07/2008 - ctrl+pgdn');
// Relative dates
date = new Date();
@@ -378,80 +379,80 @@ test('minMax', function() {
datepicker('hide').val('').datepicker('show');
inp.simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), date,
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date,
'Min/max - -1w, +1 M +10 D - ctrl+pgup');
- date = addMonths(new Date(), 1);
+ date = TestHelpers.datepicker.addMonths(new Date(), 1);
date.setDate(date.getDate() + 10);
inp.val('').datepicker('show');
inp.simulate('keydown', {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}).
simulate('keydown', {keyCode: $.ui.keyCode.ENTER});
- equalsDate(inp.datepicker('getDate'), date,
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date,
'Min/max - -1w, +1 M +10 D - ctrl+pgdn');
// With existing date
- inp = init('#inp');
+ inp = TestHelpers.datepicker.init('#inp');
inp.val('06/04/2008').datepicker('option', {minDate: minDate});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 6 - 1, 4), 'Min/max - setDate > min');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 6 - 1, 4), 'Min/max - setDate > min');
inp.datepicker('option', {minDate: null}).val('01/04/2008').datepicker('option', {minDate: minDate});
- equalsDate(inp.datepicker('getDate'), minDate, 'Min/max - setDate < min');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), minDate, 'Min/max - setDate < min');
inp.datepicker('option', {minDate: null}).val('06/04/2008').datepicker('option', {maxDate: maxDate});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 6 - 1, 4), 'Min/max - setDate < max');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 6 - 1, 4), 'Min/max - setDate < max');
inp.datepicker('option', {maxDate: null}).val('01/04/2009').datepicker('option', {maxDate: maxDate});
- equalsDate(inp.datepicker('getDate'), maxDate, 'Min/max - setDate > max');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), maxDate, 'Min/max - setDate > max');
inp.datepicker('option', {maxDate: null}).val('01/04/2008').datepicker('option', {minDate: minDate, maxDate: maxDate});
- equalsDate(inp.datepicker('getDate'), minDate, 'Min/max - setDate < min');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), minDate, 'Min/max - setDate < min');
inp.datepicker('option', {maxDate: null}).val('06/04/2008').datepicker('option', {minDate: minDate, maxDate: maxDate});
- equalsDate(inp.datepicker('getDate'), new Date(2008, 6 - 1, 4), 'Min/max - setDate > min, < max');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), new Date(2008, 6 - 1, 4), 'Min/max - setDate > min, < max');
inp.datepicker('option', {maxDate: null}).val('01/04/2009').datepicker('option', {minDate: minDate, maxDate: maxDate});
- equalsDate(inp.datepicker('getDate'), maxDate, 'Min/max - setDate > max');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), maxDate, 'Min/max - setDate > max');
});
test('setDate', function() {
expect( 24 );
var inl, alt, minDate, maxDate, dateAndTimeToSet, dateAndTimeClone,
- inp = init('#inp'),
+ inp = TestHelpers.datepicker.init('#inp'),
date1 = new Date(2008, 6 - 1, 4),
date2 = new Date();
ok(inp.datepicker('getDate') == null, 'Set date - default');
inp.datepicker('setDate', date1);
- equalsDate(inp.datepicker('getDate'), date1, 'Set date - 2008-06-04');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date1, 'Set date - 2008-06-04');
date1 = new Date();
date1.setDate(date1.getDate() + 7);
inp.datepicker('setDate', +7);
- equalsDate(inp.datepicker('getDate'), date1, 'Set date - +7');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date1, 'Set date - +7');
date2.setFullYear(date2.getFullYear() + 2);
inp.datepicker('setDate', '+2y');
- equalsDate(inp.datepicker('getDate'), date2, 'Set date - +2y');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date2, 'Set date - +2y');
inp.datepicker('setDate', date1, date2);
- equalsDate(inp.datepicker('getDate'), date1, 'Set date - two dates');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date1, 'Set date - two dates');
inp.datepicker('setDate');
ok(inp.datepicker('getDate') == null, 'Set date - null');
// Relative to current date
date1 = new Date();
date1.setDate(date1.getDate() + 7);
inp.datepicker('setDate', 'c +7');
- equalsDate(inp.datepicker('getDate'), date1, 'Set date - c +7');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date1, 'Set date - c +7');
date1.setDate(date1.getDate() + 7);
inp.datepicker('setDate', 'c+7');
- equalsDate(inp.datepicker('getDate'), date1, 'Set date - c+7');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date1, 'Set date - c+7');
date1.setDate(date1.getDate() - 21);
inp.datepicker('setDate', 'c -3 w');
- equalsDate(inp.datepicker('getDate'), date1, 'Set date - c -3 w');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date1, 'Set date - c -3 w');
// Inline
- inl = init('#inl');
+ inl = TestHelpers.datepicker.init('#inl');
date1 = new Date(2008, 6 - 1, 4);
date2 = new Date();
- equalsDate(inl.datepicker('getDate'), date2, 'Set date inline - default');
+ TestHelpers.datepicker.equalsDate(inl.datepicker('getDate'), date2, 'Set date inline - default');
inl.datepicker('setDate', date1);
- equalsDate(inl.datepicker('getDate'), date1, 'Set date inline - 2008-06-04');
+ TestHelpers.datepicker.equalsDate(inl.datepicker('getDate'), date1, 'Set date inline - 2008-06-04');
date1 = new Date();
date1.setDate(date1.getDate() + 7);
inl.datepicker('setDate', +7);
- equalsDate(inl.datepicker('getDate'), date1, 'Set date inline - +7');
+ TestHelpers.datepicker.equalsDate(inl.datepicker('getDate'), date1, 'Set date inline - +7');
date2.setFullYear(date2.getFullYear() + 2);
inl.datepicker('setDate', '+2y');
- equalsDate(inl.datepicker('getDate'), date2, 'Set date inline - +2y');
+ TestHelpers.datepicker.equalsDate(inl.datepicker('getDate'), date2, 'Set date inline - +2y');
inl.datepicker('setDate', date1, date2);
- equalsDate(inl.datepicker('getDate'), date1, 'Set date inline - two dates');
+ TestHelpers.datepicker.equalsDate(inl.datepicker('getDate'), date1, 'Set date inline - two dates');
inl.datepicker('setDate');
ok(inl.datepicker('getDate') == null, 'Set date inline - null');
// Alternate field
@@ -462,23 +463,23 @@ test('setDate', function() {
equal(inp.val(), '06/04/2008', 'Set date alternate - 06/04/2008');
equal(alt.val(), '2008-06-04', 'Set date alternate - 2008-06-04');
// With minimum/maximum
- inp = init('#inp');
+ inp = TestHelpers.datepicker.init('#inp');
date1 = new Date(2008, 1 - 1, 4);
date2 = new Date(2008, 6 - 1, 4);
minDate = new Date(2008, 2 - 1, 29);
maxDate = new Date(2008, 3 - 1, 28);
inp.val('').datepicker('option', {minDate: minDate}).datepicker('setDate', date2);
- equalsDate(inp.datepicker('getDate'), date2, 'Set date min/max - setDate > min');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date2, 'Set date min/max - setDate > min');
inp.datepicker('setDate', date1);
- equalsDate(inp.datepicker('getDate'), minDate, 'Set date min/max - setDate < min');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), minDate, 'Set date min/max - setDate < min');
inp.val('').datepicker('option', {maxDate: maxDate, minDate: null}).datepicker('setDate', date1);
- equalsDate(inp.datepicker('getDate'), date1, 'Set date min/max - setDate < max');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), date1, 'Set date min/max - setDate < max');
inp.datepicker('setDate', date2);
- equalsDate(inp.datepicker('getDate'), maxDate, 'Set date min/max - setDate > max');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), maxDate, 'Set date min/max - setDate > max');
inp.val('').datepicker('option', {minDate: minDate}).datepicker('setDate', date1);
- equalsDate(inp.datepicker('getDate'), minDate, 'Set date min/max - setDate < min');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), minDate, 'Set date min/max - setDate < min');
inp.datepicker('setDate', date2);
- equalsDate(inp.datepicker('getDate'), maxDate, 'Set date min/max - setDate > max');
+ TestHelpers.datepicker.equalsDate(inp.datepicker('getDate'), maxDate, 'Set date min/max - setDate > max');
dateAndTimeToSet = new Date(2008, 3 - 1, 28, 1, 11, 0);
dateAndTimeClone = new Date(2008, 3 - 1, 28, 1, 11, 0);
inp.datepicker('setDate', dateAndTimeToSet);
@@ -487,7 +488,7 @@ test('setDate', function() {
test('altField', function() {
expect( 10 );
- var inp = init('#inp'),
+ var inp = TestHelpers.datepicker.init('#inp'),
alt = $('#alt');
// No alternate field set
alt.val('');
@@ -525,9 +526,10 @@ test('altField', function() {
});
test('autoSize', function() {
- expect( 15 );
- var inp = init('#inp');
- equal(inp.prop('size'), 20, 'Auto size - default');
+ expect( 14 );
+ var inp = TestHelpers.datepicker.init('#inp');
+ // todo: figure out why this test fails in Opera 11.6
+ //equal(inp.prop('size'), 20, 'Auto size - default');
inp.datepicker('option', 'autoSize', true);
equal(inp.prop('size'), 10, 'Auto size - mm/dd/yy');
inp.datepicker('option', 'dateFormat', 'm/d/yy');
@@ -536,6 +538,7 @@ test('autoSize', function() {
equal(inp.prop('size'), 15, 'Auto size - D M d yy');
inp.datepicker('option', 'dateFormat', 'DD, MM dd, yy');
equal(inp.prop('size'), 29, 'Auto size - DD, MM dd, yy');
+
// French
inp.datepicker('option', $.extend({autoSize: false}, $.datepicker.regional.fr));
equal(inp.prop('size'), 29, 'Auto size - fr - default');
@@ -547,6 +550,7 @@ test('autoSize', function() {
equal(inp.prop('size'), 18, 'Auto size - fr - D M d yy');
inp.datepicker('option', 'dateFormat', 'DD, MM dd, yy');
equal(inp.prop('size'), 28, 'Auto size - fr - DD, MM dd, yy');
+
// Hebrew
inp.datepicker('option', $.extend({autoSize: false}, $.datepicker.regional.he));
equal(inp.prop('size'), 28, 'Auto size - he - default');
@@ -562,7 +566,7 @@ test('autoSize', function() {
test('daylightSaving', function() {
expect( 25 );
- var inp = init('#inp'),
+ var inp = TestHelpers.datepicker.init('#inp'),
dp = $('#ui-datepicker-div');
ok(true, 'Daylight saving - ' + new Date());
// Australia, Sydney - AM change, southern hemisphere
@@ -665,21 +669,11 @@ function beforeDay(date) {
(date.getDate() % 3 === 0 ? 'Divisble by 3' : '')];
}
-function calcWeek(date) {
- var doy = date.getDate() + 6,
- m = date.getMonth() - 1;
- for (; m >= 0; m--) {
- doy += $.datepicker._getDaysInMonth(date.getFullYear(), m);
- }
- // Simple count from 01/01 starting at week 1
- return Math.floor(doy / 7);
-}
-
test('callbacks', function() {
expect( 13 );
// Before show
var dp, day20, day21,
- inp = init('#inp', {beforeShow: beforeAll}),
+ inp = TestHelpers.datepicker.init('#inp', {beforeShow: beforeAll}),
inst = $.data(inp[0], 'datepicker');
equal($.datepicker._get(inst, 'currentText'), 'Today', 'Before show - initial');
inp.val('02/04/2008').datepicker('show');
@@ -689,7 +683,7 @@ test('callbacks', function() {
deepEqual(beforeShowInst, inst, 'Before show - inst OK');
inp.datepicker('hide').datepicker('destroy');
// Before show day
- inp = init('#inp', {beforeShowDay: beforeDay});
+ inp = TestHelpers.datepicker.init('#inp', {beforeShowDay: beforeDay});
dp = $('#ui-datepicker-div');
inp.val('02/04/2008').datepicker('show');
ok(beforeShowDayThis.id === inp[0].id, 'Before show day - this OK');
@@ -708,7 +702,7 @@ test('callbacks', function() {
test('localisation', function() {
expect( 24 );
var dp, month, day, date,
- inp = init('#inp', $.datepicker.regional.fr);
+ inp = TestHelpers.datepicker.init('#inp', $.datepicker.regional.fr);
inp.datepicker('option', {dateFormat: 'DD, d MM yy', showButtonPanel:true, changeMonth:true, changeYear:true}).val('').datepicker('show');
dp = $('#ui-datepicker-div');
equal($('.ui-datepicker-close', dp).text(), 'Fermer', 'Localisation - close');
@@ -775,72 +769,72 @@ test('iso8601Week', function() {
test('parseDate', function() {
expect( 26 );
- init('#inp');
+ TestHelpers.datepicker.init('#inp');
var currentYear, gmtDate, fr, settings, zh;
ok($.datepicker.parseDate('d m y', '') == null, 'Parse date empty');
- equalsDate($.datepicker.parseDate('d m y', '3 2 01'),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('d m y', '3 2 01'),
new Date(2001, 2 - 1, 3), 'Parse date d m y');
- equalsDate($.datepicker.parseDate('dd mm yy', '03 02 2001'),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('dd mm yy', '03 02 2001'),
new Date(2001, 2 - 1, 3), 'Parse date dd mm yy');
- equalsDate($.datepicker.parseDate('d m y', '13 12 01'),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('d m y', '13 12 01'),
new Date(2001, 12 - 1, 13), 'Parse date d m y');
- equalsDate($.datepicker.parseDate('dd mm yy', '13 12 2001'),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('dd mm yy', '13 12 2001'),
new Date(2001, 12 - 1, 13), 'Parse date dd mm yy');
- equalsDate($.datepicker.parseDate('y-o', '01-34'),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('y-o', '01-34'),
new Date(2001, 2 - 1, 3), 'Parse date y-o');
- equalsDate($.datepicker.parseDate('yy-oo', '2001-347'),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('yy-oo', '2001-347'),
new Date(2001, 12 - 1, 13), 'Parse date yy-oo');
- equalsDate($.datepicker.parseDate('oo yy', '348 2004'),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('oo yy', '348 2004'),
new Date(2004, 12 - 1, 13), 'Parse date oo yy');
- equalsDate($.datepicker.parseDate('D d M y', 'Sat 3 Feb 01'),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('D d M y', 'Sat 3 Feb 01'),
new Date(2001, 2 - 1, 3), 'Parse date D d M y');
- equalsDate($.datepicker.parseDate('d MM DD yy', '3 February Saturday 2001'),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('d MM DD yy', '3 February Saturday 2001'),
new Date(2001, 2 - 1, 3), 'Parse date dd MM DD yy');
- equalsDate($.datepicker.parseDate('DD, MM d, yy', 'Saturday, February 3, 2001'),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('DD, MM d, yy', 'Saturday, February 3, 2001'),
new Date(2001, 2 - 1, 3), 'Parse date DD, MM d, yy');
- equalsDate($.datepicker.parseDate('\'day\' d \'of\' MM (\'\'DD\'\'), yy',
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('\'day\' d \'of\' MM (\'\'DD\'\'), yy',
'day 3 of February (\'Saturday\'), 2001'), new Date(2001, 2 - 1, 3),
'Parse date \'day\' d \'of\' MM (\'\'DD\'\'), yy');
currentYear = new Date().getFullYear();
- equalsDate($.datepicker.parseDate('y-m-d', (currentYear - 2000) + '-02-03'),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('y-m-d', (currentYear - 2000) + '-02-03'),
new Date(currentYear, 2 - 1, 3), 'Parse date y-m-d - default cutuff');
- equalsDate($.datepicker.parseDate('y-m-d', (currentYear - 2000 + 10) + '-02-03'),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('y-m-d', (currentYear - 2000 + 10) + '-02-03'),
new Date(currentYear+10, 2 - 1, 3), 'Parse date y-m-d - default cutuff');
- equalsDate($.datepicker.parseDate('y-m-d', (currentYear - 2000 + 11) + '-02-03'),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('y-m-d', (currentYear - 2000 + 11) + '-02-03'),
new Date(currentYear-89, 2 - 1, 3), 'Parse date y-m-d - default cutuff');
- equalsDate($.datepicker.parseDate('y-m-d', '80-02-03', {shortYearCutoff: 80}),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('y-m-d', '80-02-03', {shortYearCutoff: 80}),
new Date(2080, 2 - 1, 3), 'Parse date y-m-d - cutoff 80');
- equalsDate($.datepicker.parseDate('y-m-d', '81-02-03', {shortYearCutoff: 80}),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('y-m-d', '81-02-03', {shortYearCutoff: 80}),
new Date(1981, 2 - 1, 3), 'Parse date y-m-d - cutoff 80');
- equalsDate($.datepicker.parseDate('y-m-d', (currentYear - 2000 + 60) + '-02-03', {shortYearCutoff: '+60'}),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('y-m-d', (currentYear - 2000 + 60) + '-02-03', {shortYearCutoff: '+60'}),
new Date(currentYear + 60, 2 - 1, 3), 'Parse date y-m-d - cutoff +60');
- equalsDate($.datepicker.parseDate('y-m-d', (currentYear - 2000 + 61) + '-02-03', {shortYearCutoff: '+60'}),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('y-m-d', (currentYear - 2000 + 61) + '-02-03', {shortYearCutoff: '+60'}),
new Date(currentYear - 39, 2 - 1, 3), 'Parse date y-m-d - cutoff +60');
gmtDate = new Date(2001, 2 - 1, 3);
gmtDate.setMinutes(gmtDate.getMinutes() - gmtDate.getTimezoneOffset());
- equalsDate($.datepicker.parseDate('@', '981158400000'), gmtDate, 'Parse date @');
- equalsDate($.datepicker.parseDate('!', '631167552000000000'), gmtDate, 'Parse date !');
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('@', '981158400000'), gmtDate, 'Parse date @');
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('!', '631167552000000000'), gmtDate, 'Parse date !');
+
fr = $.datepicker.regional.fr;
settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames,
monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames};
- equalsDate($.datepicker.parseDate('D d M y', 'Lun. 9 Avril 01', settings),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('D d M y', 'Lun. 9 Avril 01', settings),
new Date(2001, 4 - 1, 9), 'Parse date D M y with settings');
- equalsDate($.datepicker.parseDate('d MM DD yy', '9 Avril Lundi 2001', settings),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('d MM DD yy', '9 Avril Lundi 2001', settings),
new Date(2001, 4 - 1, 9), 'Parse date d MM DD yy with settings');
- equalsDate($.datepicker.parseDate('DD, MM d, yy', 'Lundi, Avril 9, 2001', settings),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('DD, MM d, yy', 'Lundi, Avril 9, 2001', settings),
new Date(2001, 4 - 1, 9), 'Parse date DD, MM d, yy with settings');
- equalsDate($.datepicker.parseDate('\'jour\' d \'de\' MM (\'\'DD\'\'), yy',
- 'jour 9 de Avril (\'Lundi\'), 2001', settings), new Date(2001, 4 - 1, 9),
- 'Parse date \'jour\' d \'de\' MM (\'\'DD\'\'), yy with settings');
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate("'jour' d 'de' MM (''DD''), yy", "jour 9 de Avril ('Lundi'), 2001", settings),
+ new Date(2001, 4 - 1, 9), "Parse date 'jour' d 'de' MM (''DD''), yy with settings");
zh = $.datepicker.regional['zh-CN'];
- equalsDate($.datepicker.parseDate('yy M d', '2011 十一 22', zh),
+ TestHelpers.datepicker.equalsDate($.datepicker.parseDate('yy M d', '2011 十一月 22', zh),
new Date(2011, 11 - 1, 22), 'Parse date yy M d with zh-CN');
});
test('parseDateErrors', function() {
expect( 17 );
- init('#inp');
+ TestHelpers.datepicker.init('#inp');
var fr, settings;
function expectError(expr, value, error) {
try {
@@ -891,9 +885,29 @@ test('parseDateErrors', function() {
'Lun. 9 Apr 01 - D d M y', 'Unknown name at position 7');
});
+test('Ticket #7244: date parser does not fail when too many numbers are passed into the date function', function() {
+ expect( 4 );
+ var date;
+ try{
+ date = $.datepicker.parseDate('dd/mm/yy', '18/04/19881');
+ ok(false, "Did not properly detect an invalid date");
+ }catch(e){
+ ok("invalid date detected");
+ }
+
+ try {
+ date = $.datepicker.parseDate('dd/mm/yy', '18/04/1988 @ 2:43 pm');
+ equal(date.getDate(), 18);
+ equal(date.getMonth(), 3);
+ equal(date.getFullYear(), 1988);
+ } catch(e) {
+ ok(false, "Did not properly parse date with extra text separated by whitespace");
+ }
+});
+
test('formatDate', function() {
expect( 16 );
- init('#inp');
+ TestHelpers.datepicker.init('#inp');
var gmtDate, fr, settings;
equal($.datepicker.formatDate('d m y', new Date(2001, 2 - 1, 3)),
'3 2 01', 'Format date d m y');
@@ -934,4 +948,44 @@ test('formatDate', function() {
'Format date \'jour\' d \'de\' MM (\'\'DD\'\'), yy with settings');
});
+test('Ticket 6827: formatDate day of year calculation is wrong during day lights savings time', function(){
+ expect( 1 );
+ var time = $.datepicker.formatDate("oo", new Date("2010/03/30 12:00:00 CDT"));
+ equal(time, "089");
+});
+
+test('Ticket 7602: Stop datepicker from appearing with beforeShow event handler', function(){
+ expect( 3 );
+ var inp = TestHelpers.datepicker.init('#inp',{
+ beforeShow: function(){
+ return false;
+ }
+ }),
+ dp = $('#ui-datepicker-div');
+ inp.datepicker('show');
+ equal(dp.css('display'), 'none',"beforeShow returns false");
+ inp.datepicker('destroy');
+
+ inp = TestHelpers.datepicker.init('#inp',{
+ beforeShow: function(){
+ }
+ });
+ dp = $('#ui-datepicker-div');
+ inp.datepicker('show');
+ equal(dp.css('display'), 'block',"beforeShow returns nothing");
+ inp.datepicker('hide');
+ inp.datepicker('destroy');
+
+ inp = TestHelpers.datepicker.init('#inp',{
+ beforeShow: function(){
+ return true;
+ }
+ });
+ dp = $('#ui-datepicker-div');
+ inp.datepicker('show');
+ equal(dp.css('display'), 'block',"beforeShow returns true");
+ inp.datepicker('hide');
+ inp.datepicker('destroy');
+});
+
})(jQuery);
diff --git a/tests/unit/datepicker/datepicker_test_helpers.js b/tests/unit/datepicker/datepicker_test_helpers.js
new file mode 100644
index 000000000..2d374f561
--- /dev/null
+++ b/tests/unit/datepicker/datepicker_test_helpers.js
@@ -0,0 +1,22 @@
+TestHelpers.datepicker = {
+ addMonths: function(date, offset) {
+ var maxDay = 32 - new Date(date.getFullYear(), date.getMonth() + offset, 32).getDate();
+ date.setDate(Math.min(date.getDate(), maxDay));
+ date.setMonth(date.getMonth() + offset);
+ return date;
+ },
+ equalsDate: function(d1, d2, message) {
+ if (!d1 || !d2) {
+ ok(false, message + ' - missing date');
+ return;
+ }
+ d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate());
+ d2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate());
+ equal(d1.toString(), d2.toString(), message);
+ },
+ init: function(id, options) {
+ $.datepicker.setDefaults($.datepicker.regional['']);
+ return $(id).datepicker($.extend({showAnim: ''}, options || {}));
+ },
+ PROP_NAME: 'datepicker'
+}; \ No newline at end of file
diff --git a/tests/unit/datepicker/datepicker_tickets.js b/tests/unit/datepicker/datepicker_tickets.js
deleted file mode 100644
index e1b882a89..000000000
--- a/tests/unit/datepicker/datepicker_tickets.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * datepicker_tickets.js
- */
-(function($) {
-
-module("datepicker: tickets");
-
-// http://forum.jquery.com/topic/several-breaking-changes-in-jquery-ui-1-8rc1
-test('beforeShowDay-getDate', function() {
- expect( 3 );
- var inp = init('#inp', {beforeShowDay: function(date) { inp.datepicker('getDate'); return [true, '']; }}),
- dp = $('#ui-datepicker-div');
- inp.val('01/01/2010').datepicker('show');
- // contains non-breaking space
- equal($('div.ui-datepicker-title').text(), 'January 2010', 'Initial month');
- $('a.ui-datepicker-next', dp).click();
- $('a.ui-datepicker-next', dp).click();
- // contains non-breaking space
- equal($('div.ui-datepicker-title').text(), 'March 2010', 'After next clicks');
- inp.datepicker('hide').datepicker('show');
- $('a.ui-datepicker-prev', dp).click();
- $('a.ui-datepicker-prev', dp).click();
- // contains non-breaking space
- equal($('div.ui-datepicker-title').text(), 'November 2009', 'After prev clicks');
- inp.datepicker('hide');
-});
-
-test('Ticket 7602: Stop datepicker from appearing with beforeShow event handler', function(){
- expect( 3 );
- var inp = init('#inp',{
- beforeShow: function(){
- return false;
- }
- }),
- dp = $('#ui-datepicker-div');
- inp.datepicker('show');
- equal(dp.css('display'), 'none',"beforeShow returns false");
- inp.datepicker('destroy');
-
- inp = init('#inp',{
- beforeShow: function(){
- }
- });
- dp = $('#ui-datepicker-div');
- inp.datepicker('show');
- equal(dp.css('display'), 'block',"beforeShow returns nothing");
- inp.datepicker('hide');
- inp.datepicker('destroy');
-
- inp = init('#inp',{
- beforeShow: function(){
- return true;
- }
- });
- dp = $('#ui-datepicker-div');
- inp.datepicker('show');
- equal(dp.css('display'), 'block',"beforeShow returns true");
- inp.datepicker('hide');
- inp.datepicker('destroy');
-});
-
-test('Ticket 6827: formatDate day of year calculation is wrong during day lights savings time', function(){
- expect( 1 );
- var time = $.datepicker.formatDate("oo", new Date("2010/03/30 12:00:00 CDT"));
- equal(time, "089");
-});
-
-test('Ticket #7244: date parser does not fail when too many numbers are passed into the date function', function() {
- expect( 4 );
- var date;
- try{
- date = $.datepicker.parseDate('dd/mm/yy', '18/04/19881');
- ok(false, "Did not properly detect an invalid date");
- }catch(e){
- ok("invalid date detected");
- }
-
- try {
- date = $.datepicker.parseDate('dd/mm/yy', '18/04/1988 @ 2:43 pm');
- equal(date.getDate(), 18);
- equal(date.getMonth(), 3);
- equal(date.getFullYear(), 1988);
- } catch(e) {
- ok(false, "Did not properly parse date with extra text separated by whitespace");
- }
-});
-
-})(jQuery);
diff --git a/tests/unit/dialog/dialog.html b/tests/unit/dialog/dialog.html
index d804807f2..cb74bb654 100644
--- a/tests/unit/dialog/dialog.html
+++ b/tests/unit/dialog/dialog.html
@@ -5,7 +5,6 @@
<title>jQuery UI Dialog Test Suite</title>
<script src="../../jquery.js"></script>
- <script src="../../../external/jquery.bgiframe-2.1.2.js"></script>
<link rel="stylesheet" href="../../../external/qunit.css">
<script src="../../../external/qunit.js"></script>
<script src="../../jquery.simulate.js"></script>
@@ -30,18 +29,9 @@
<script src="dialog_events.js"></script>
<script src="dialog_methods.js"></script>
<script src="dialog_options.js"></script>
+ <script src="dialog_test_helpers.js"></script>
<script src="dialog_tickets.js"></script>
- <script>
- // disable this testsuite for testswarm only - until we fix it from freezing IE6
- var url = window.location.search;
- url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) );
- if ( url && url.indexOf("http") == 0 ) {
- // reset config to kill previous tests; make sure testsuite.js is loaded afterwards to init the testswarm script
- QUnit.init();
- test("dialog", function() { ok(true, "disabled dialog testsuite"); });
- }
- </script>
<script src="../swarminject.js"></script>
</head>
<body>
@@ -52,7 +42,8 @@
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">
-
+ <div id="dialog1"></div>
+ <div id="dialog2"></div>
</div>
</body>
</html>
diff --git a/tests/unit/dialog/dialog_common.js b/tests/unit/dialog/dialog_common.js
index 623908da7..2c0e86b46 100644
--- a/tests/unit/dialog/dialog_common.js
+++ b/tests/unit/dialog/dialog_common.js
@@ -23,10 +23,8 @@ TestHelpers.commonWidgetTests( "dialog", {
},
resizable: true,
show: null,
- stack: true,
title: '',
width: 300,
- zIndex: 1000,
// callbacks
create: null
diff --git a/tests/unit/dialog/dialog_core.js b/tests/unit/dialog/dialog_core.js
index e0a5c8701..b36f6204f 100644
--- a/tests/unit/dialog/dialog_core.js
+++ b/tests/unit/dialog/dialog_core.js
@@ -2,88 +2,6 @@
* dialog_core.js
*/
-var el,
- offsetBefore, offsetAfter,
- heightBefore, heightAfter,
- widthBefore, widthAfter,
- dragged;
-
-function dlg() {
- return el.dialog('widget');
-}
-
-function isOpen(why) {
- ok(dlg().is(":visible"), why);
-}
-
-function isNotOpen(why) {
- ok(!dlg().is(":visible"), why);
-}
-
-function drag(handle, dx, dy) {
- var d = dlg();
- offsetBefore = d.offset();
- heightBefore = d.height();
- widthBefore = d.width();
- //this mouseover is to work around a limitation in resizable
- //TODO: fix resizable so handle doesn't require mouseover in order to be used
- $(handle, d).simulate("mouseover");
- $(handle, d).simulate("drag", {
- dx: dx || 0,
- dy: dy || 0
- });
- dragged = { dx: dx, dy: dy };
- offsetAfter = d.offset();
- heightAfter = d.height();
- widthAfter = d.width();
-}
-
-function moved(dx, dy, msg) {
- msg = msg ? msg + "." : "";
- var actual = { left: Math.round(offsetAfter.left), top: Math.round(offsetAfter.top) },
- expected = { left: Math.round(offsetBefore.left + dx), top: Math.round(offsetBefore.top + dy) };
- deepEqual(actual, expected, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ' + msg);
-}
-
-function shouldmove(why) {
- var handle = $(".ui-dialog-titlebar", dlg());
- drag(handle, 50, -50);
- moved(50, -50, why);
-}
-
-function shouldnotmove(why) {
- var handle = $(".ui-dialog-titlebar", dlg());
- drag(handle, 50, -50);
- moved(0, 0, why);
-}
-
-function resized(dw, dh, msg) {
- msg = msg ? msg + "." : "";
- var actual = { width: widthAfter, height: heightAfter },
- expected = { width: widthBefore + dw, height: heightBefore + dh };
- deepEqual(actual, expected, 'resized[' + dragged.dx + ', ' + dragged.dy + '] ' + msg);
-}
-
-function shouldresize(why) {
- var handle = $(".ui-resizable-se", dlg());
- drag(handle, 50, 50);
- resized(50, 50, why);
-}
-
-function shouldnotresize(why) {
- var handle = $(".ui-resizable-se", dlg());
- drag(handle, 50, 50);
- resized(0, 0, why);
-}
-
-function broder(el, side){
- return parseInt(el.css('border-' + side + '-width'), 10);
-}
-
-function margin(el, side) {
- return parseInt(el.css('margin-' + side), 10);
-}
-
(function($) {
module("dialog: core");
@@ -91,8 +9,10 @@ module("dialog: core");
test("title id", function() {
expect(1);
- el = $('<div></div>').dialog();
- var titleId = dlg().find('.ui-dialog-title').attr('id');
+ var titleId,
+ el = $('<div></div>').dialog();
+
+ titleId = el.dialog('widget').find('.ui-dialog-title').attr('id');
ok( /ui-id-\d+$/.test( titleId ), 'auto-numbered title id');
el.remove();
});
@@ -100,16 +20,17 @@ test("title id", function() {
test("ARIA", function() {
expect(4);
- el = $('<div></div>').dialog();
+ var labelledBy,
+ el = $('<div></div>').dialog();
- equal(dlg().attr('role'), 'dialog', 'dialog role');
+ equal(el.dialog('widget').attr('role'), 'dialog', 'dialog role');
- var labelledBy = dlg().attr('aria-labelledby');
+ labelledBy = el.dialog('widget').attr('aria-labelledby');
ok(labelledBy.length > 0, 'has aria-labelledby attribute');
- equal(dlg().find('.ui-dialog-title').attr('id'), labelledBy,
+ equal(el.dialog('widget').find('.ui-dialog-title').attr('id'), labelledBy,
'proper aria-labelledby attribute');
- equal(dlg().find('.ui-dialog-titlebar-close').attr('role'), 'button',
+ equal(el.dialog('widget').find('.ui-dialog-titlebar-close').attr('role'), 'button',
'close link role');
el.remove();
diff --git a/tests/unit/dialog/dialog_events.js b/tests/unit/dialog/dialog_events.js
index 85afa5a3b..ee7a8bcb3 100644
--- a/tests/unit/dialog/dialog_events.js
+++ b/tests/unit/dialog/dialog_events.js
@@ -8,10 +8,10 @@ module("dialog: events");
test("open", function() {
expect(13);
- el = $("<div></div>");
+ var el = $("<div></div>");
el.dialog({
open: function(ev, ui) {
- ok(el.data("dialog")._isOpen, "interal _isOpen flag is set");
+ ok(el.data("ui-dialog")._isOpen, "interal _isOpen flag is set");
ok(true, 'autoOpen: true fires open callback');
equal(this, el[0], "context of callback");
equal(ev.type, 'dialogopen', 'event type in callback');
@@ -30,7 +30,7 @@ test("open", function() {
deepEqual(ui, {}, 'ui hash in callback');
}
}).bind('dialogopen', function(ev, ui) {
- ok(el.data("dialog")._isOpen, "interal _isOpen flag is set");
+ ok(el.data("ui-dialog")._isOpen, "interal _isOpen flag is set");
ok(true, 'dialog("open") fires open event');
equal(this, el[0], 'context of event');
deepEqual(ui, {}, 'ui hash in event');
@@ -42,168 +42,194 @@ test("open", function() {
test("dragStart", function() {
expect(9);
- el = $('<div></div>').dialog({
- dragStart: function(ev, ui) {
- ok(true, 'dragging fires dragStart callback');
- equal(this, el[0], "context of callback");
- equal(ev.type, 'dialogdragstart', 'event type in callback');
+ var handle,
+ el = $('<div></div>').dialog({
+ dragStart: function(ev, ui) {
+ ok(true, 'dragging fires dragStart callback');
+ equal(this, el[0], "context of callback");
+ equal(ev.type, 'dialogdragstart', 'event type in callback');
+ ok(ui.position !== undefined, "ui.position in callback");
+ ok(ui.offset !== undefined, "ui.offset in callback");
+ }
+ }).bind('dialogdragstart', function(ev, ui) {
+ ok(true, 'dragging fires dialogdragstart event');
+ equal(this, el[0], 'context of event');
ok(ui.position !== undefined, "ui.position in callback");
ok(ui.offset !== undefined, "ui.offset in callback");
- }
- }).bind('dialogdragstart', function(ev, ui) {
- ok(true, 'dragging fires dialogdragstart event');
- equal(this, el[0], 'context of event');
- ok(ui.position !== undefined, "ui.position in callback");
- ok(ui.offset !== undefined, "ui.offset in callback");
- });
- var handle = $(".ui-dialog-titlebar", dlg());
- drag(handle, 50, 50);
+ });
+
+ handle = $(".ui-dialog-titlebar", el.dialog('widget'));
+ TestHelpers.dialog.drag(el, handle, 50, 50);
el.remove();
});
test("drag", function() {
expect(9);
var handle,
- hasDragged = false;
+ hasDragged = false,
+ el = $('<div></div>').dialog({
+ drag: function(ev, ui) {
+ if (!hasDragged) {
+ ok(true, 'dragging fires drag callback');
+ equal(this, el[0], "context of callback");
+ equal(ev.type, 'dialogdrag', 'event type in callback');
+ ok(ui.position !== undefined, "ui.position in callback");
+ ok(ui.offset !== undefined, "ui.offset in callback");
- el = $('<div></div>').dialog({
- drag: function(ev, ui) {
- if (!hasDragged) {
- ok(true, 'dragging fires drag callback');
- equal(this, el[0], "context of callback");
- equal(ev.type, 'dialogdrag', 'event type in callback');
- ok(ui.position !== undefined, "ui.position in callback");
- ok(ui.offset !== undefined, "ui.offset in callback");
-
- hasDragged = true;
+ hasDragged = true;
+ }
}
- }
- }).one('dialogdrag', function(ev, ui) {
- ok(true, 'dragging fires dialogdrag event');
- equal(this, el[0], 'context of event');
- ok(ui.position !== undefined, "ui.position in callback");
- ok(ui.offset !== undefined, "ui.offset in callback");
- });
- handle = $(".ui-dialog-titlebar", dlg());
- drag(handle, 50, 50);
+ }).one('dialogdrag', function(ev, ui) {
+ ok(true, 'dragging fires dialogdrag event');
+ equal(this, el[0], 'context of event');
+ ok(ui.position !== undefined, "ui.position in callback");
+ ok(ui.offset !== undefined, "ui.offset in callback");
+ });
+
+ handle = $(".ui-dialog-titlebar", el.dialog('widget'));
+ TestHelpers.dialog.drag(el, handle, 50, 50);
el.remove();
});
test("dragStop", function() {
expect(9);
- el = $('<div></div>').dialog({
- dragStop: function(ev, ui) {
- ok(true, 'dragging fires dragStop callback');
- equal(this, el[0], "context of callback");
- equal(ev.type, 'dialogdragstop', 'event type in callback');
+ var handle,
+ el = $('<div></div>').dialog({
+ dragStop: function(ev, ui) {
+ ok(true, 'dragging fires dragStop callback');
+ equal(this, el[0], "context of callback");
+ equal(ev.type, 'dialogdragstop', 'event type in callback');
+ ok(ui.position !== undefined, "ui.position in callback");
+ ok(ui.offset !== undefined, "ui.offset in callback");
+ }
+ }).bind('dialogdragstop', function(ev, ui) {
+ ok(true, 'dragging fires dialogdragstop event');
+ equal(this, el[0], 'context of event');
ok(ui.position !== undefined, "ui.position in callback");
ok(ui.offset !== undefined, "ui.offset in callback");
- }
- }).bind('dialogdragstop', function(ev, ui) {
- ok(true, 'dragging fires dialogdragstop event');
- equal(this, el[0], 'context of event');
- ok(ui.position !== undefined, "ui.position in callback");
- ok(ui.offset !== undefined, "ui.offset in callback");
- });
- var handle = $(".ui-dialog-titlebar", dlg());
- drag(handle, 50, 50);
+ });
+
+ handle = $(".ui-dialog-titlebar", el.dialog('widget'));
+ TestHelpers.dialog.drag(el, handle, 50, 50);
el.remove();
});
test("resizeStart", function() {
expect(13);
- el = $('<div></div>').dialog({
- resizeStart: function(ev, ui) {
- ok(true, 'resizing fires resizeStart callback');
- equal(this, el[0], "context of callback");
- equal(ev.type, 'dialogresizestart', 'event type in callback');
+ var handle,
+ el = $('<div></div>').dialog({
+ resizeStart: function(ev, ui) {
+ ok(true, 'resizing fires resizeStart callback');
+ equal(this, el[0], "context of callback");
+ equal(ev.type, 'dialogresizestart', 'event type in callback');
+ ok(ui.originalPosition !== undefined, "ui.originalPosition in callback");
+ ok(ui.originalSize !== undefined, "ui.originalSize in callback");
+ ok(ui.position !== undefined, "ui.position in callback");
+ ok(ui.size !== undefined, "ui.size in callback");
+ }
+ }).bind('dialogresizestart', function(ev, ui) {
+ ok(true, 'resizing fires dialogresizestart event');
+ equal(this, el[0], 'context of event');
ok(ui.originalPosition !== undefined, "ui.originalPosition in callback");
ok(ui.originalSize !== undefined, "ui.originalSize in callback");
ok(ui.position !== undefined, "ui.position in callback");
ok(ui.size !== undefined, "ui.size in callback");
- }
- }).bind('dialogresizestart', function(ev, ui) {
- ok(true, 'resizing fires dialogresizestart event');
- equal(this, el[0], 'context of event');
- ok(ui.originalPosition !== undefined, "ui.originalPosition in callback");
- ok(ui.originalSize !== undefined, "ui.originalSize in callback");
- ok(ui.position !== undefined, "ui.position in callback");
- ok(ui.size !== undefined, "ui.size in callback");
- });
- var handle = $(".ui-resizable-se", dlg());
- drag(handle, 50, 50);
+ });
+
+ handle = $(".ui-resizable-se", el.dialog('widget'));
+ TestHelpers.dialog.drag(el, handle, 50, 50);
el.remove();
});
test("resize", function() {
expect(13);
var handle,
- hasResized = false;
+ hasResized = false,
+ el = $('<div></div>').dialog({
+ resize: function(ev, ui) {
+ if (!hasResized) {
+ ok(true, 'resizing fires resize callback');
+ equal(this, el[0], "context of callback");
+ equal(ev.type, 'dialogresize', 'event type in callback');
+ ok(ui.originalPosition !== undefined, "ui.originalPosition in callback");
+ ok(ui.originalSize !== undefined, "ui.originalSize in callback");
+ ok(ui.position !== undefined, "ui.position in callback");
+ ok(ui.size !== undefined, "ui.size in callback");
- el = $('<div></div>').dialog({
- resize: function(ev, ui) {
- if (!hasResized) {
- ok(true, 'resizing fires resize callback');
+ hasResized = true;
+ }
+ }
+ }).one('dialogresize', function(ev, ui) {
+ ok(true, 'resizing fires dialogresize event');
+ equal(this, el[0], 'context of event');
+ ok(ui.originalPosition !== undefined, "ui.originalPosition in callback");
+ ok(ui.originalSize !== undefined, "ui.originalSize in callback");
+ ok(ui.position !== undefined, "ui.position in callback");
+ ok(ui.size !== undefined, "ui.size in callback");
+ });
+
+ handle = $(".ui-resizable-se", el.dialog('widget'));
+ TestHelpers.dialog.drag(el, handle, 50, 50);
+ el.remove();
+});
+
+test("resizeStop", function() {
+ expect(13);
+
+ var handle,
+ el = $('<div></div>').dialog({
+ resizeStop: function(ev, ui) {
+ ok(true, 'resizing fires resizeStop callback');
equal(this, el[0], "context of callback");
- equal(ev.type, 'dialogresize', 'event type in callback');
+ equal(ev.type, 'dialogresizestop', 'event type in callback');
ok(ui.originalPosition !== undefined, "ui.originalPosition in callback");
ok(ui.originalSize !== undefined, "ui.originalSize in callback");
ok(ui.position !== undefined, "ui.position in callback");
ok(ui.size !== undefined, "ui.size in callback");
-
- hasResized = true;
}
- }
- }).one('dialogresize', function(ev, ui) {
- ok(true, 'resizing fires dialogresize event');
- equal(this, el[0], 'context of event');
- ok(ui.originalPosition !== undefined, "ui.originalPosition in callback");
- ok(ui.originalSize !== undefined, "ui.originalSize in callback");
- ok(ui.position !== undefined, "ui.position in callback");
- ok(ui.size !== undefined, "ui.size in callback");
- });
- handle = $(".ui-resizable-se", dlg());
- drag(handle, 50, 50);
+ }).bind('dialogresizestop', function(ev, ui) {
+ ok(true, 'resizing fires dialogresizestop event');
+ equal(this, el[0], 'context of event');
+ ok(ui.originalPosition !== undefined, "ui.originalPosition in callback");
+ ok(ui.originalSize !== undefined, "ui.originalSize in callback");
+ ok(ui.position !== undefined, "ui.position in callback");
+ ok(ui.size !== undefined, "ui.size in callback");
+ });
+
+ handle = $(".ui-resizable-se", el.dialog('widget'));
+ TestHelpers.dialog.drag(el, handle, 50, 50);
el.remove();
});
-test("resizeStop", function() {
- expect(13);
+asyncTest("close", function() {
+ expect(14);
- el = $('<div></div>').dialog({
- resizeStop: function(ev, ui) {
- ok(true, 'resizing fires resizeStop callback');
+ var el = $('<div></div>').dialog({
+ close: function(ev, ui) {
+ ok(true, '.dialog("close") fires close callback');
equal(this, el[0], "context of callback");
- equal(ev.type, 'dialogresizestop', 'event type in callback');
- ok(ui.originalPosition !== undefined, "ui.originalPosition in callback");
- ok(ui.originalSize !== undefined, "ui.originalSize in callback");
- ok(ui.position !== undefined, "ui.position in callback");
- ok(ui.size !== undefined, "ui.size in callback");
+ equal(ev.type, 'dialogclose', 'event type in callback');
+ deepEqual(ui, {}, 'ui hash in callback');
}
- }).bind('dialogresizestop', function(ev, ui) {
- ok(true, 'resizing fires dialogresizestop event');
+ }).bind('dialogclose', function(ev, ui) {
+ ok(true, '.dialog("close") fires dialogclose event');
equal(this, el[0], 'context of event');
- ok(ui.originalPosition !== undefined, "ui.originalPosition in callback");
- ok(ui.originalSize !== undefined, "ui.originalSize in callback");
- ok(ui.position !== undefined, "ui.position in callback");
- ok(ui.size !== undefined, "ui.size in callback");
+ deepEqual(ui, {}, 'ui hash in event');
});
- var handle = $(".ui-resizable-se", dlg());
- drag(handle, 50, 50);
+ el.dialog('close');
el.remove();
-});
-
-test("close", function() {
- expect(7);
+ // Close event with an effect
el = $('<div></div>').dialog({
+ hide: 10,
close: function(ev, ui) {
ok(true, '.dialog("close") fires close callback');
equal(this, el[0], "context of callback");
equal(ev.type, 'dialogclose', 'event type in callback');
deepEqual(ui, {}, 'ui hash in callback');
+ start();
}
}).bind('dialogclose', function(ev, ui) {
ok(true, '.dialog("close") fires dialogclose event');
@@ -211,13 +237,12 @@ test("close", function() {
deepEqual(ui, {}, 'ui hash in event');
});
el.dialog('close');
- el.remove();
});
test("beforeClose", function() {
expect(14);
- el = $('<div></div>').dialog({
+ var el = $('<div></div>').dialog({
beforeClose: function(ev, ui) {
ok(true, '.dialog("close") fires beforeClose callback');
equal(this, el[0], "context of callback");
@@ -226,8 +251,9 @@ test("beforeClose", function() {
return false;
}
});
+
el.dialog('close');
- isOpen('beforeClose callback should prevent dialog from closing');
+ ok( el.dialog("widget").is(":visible"), 'beforeClose callback should prevent dialog from closing');
el.remove();
el = $('<div></div>').dialog();
@@ -239,7 +265,8 @@ test("beforeClose", function() {
return false;
});
el.dialog('close');
- isOpen('beforeClose callback should prevent dialog from closing');
+
+ ok( el.dialog("widget").is(":visible"), 'beforeClose callback should prevent dialog from closing');
el.remove();
el = $('<div></div>').dialog().bind('dialogbeforeclose', function(ev, ui) {
@@ -249,7 +276,7 @@ test("beforeClose", function() {
return false;
});
el.dialog('close');
- isOpen('dialogbeforeclose event should prevent dialog from closing');
+ ok( el.dialog("widget").is(":visible"), 'dialogbeforeclose event should prevent dialog from closing');
el.remove();
});
diff --git a/tests/unit/dialog/dialog_methods.js b/tests/unit/dialog/dialog_methods.js
index ba0c2bd41..7048a76a9 100644
--- a/tests/unit/dialog/dialog_methods.js
+++ b/tests/unit/dialog/dialog_methods.js
@@ -24,8 +24,8 @@ test("init", function() {
$('<div></div>').appendTo('body').remove().dialog().remove();
ok(true, '.dialog() called on disconnected DOMElement - removed');
- el = $('<div></div>').dialog();
- var foo = el.dialog("option", "foo");
+ var el = $('<div></div>').dialog();
+ el.dialog("option", "foo");
el.remove();
ok(true, 'arbitrary option getter after init');
@@ -53,46 +53,49 @@ test("destroy", function() {
test("enable", function() {
expect( 3 );
- var expected = $('<div></div>').dialog(),
+ var el,
+ expected = $('<div></div>').dialog(),
actual = expected.dialog('enable');
equal(actual, expected, 'enable is chainable');
el = $('<div></div>').dialog({ disabled: true });
el.dialog('enable');
equal(el.dialog('option', 'disabled'), false, 'enable method sets disabled option to false');
- ok(!dlg().hasClass('ui-dialog-disabled'), 'enable method removes ui-dialog-disabled class from ui-dialog element');
+ ok(!el.dialog('widget').hasClass('ui-dialog-disabled'), 'enable method removes ui-dialog-disabled class from ui-dialog element');
});
test("disable", function() {
expect( 3 );
- var expected = $('<div></div>').dialog(),
+ var el,
+ expected = $('<div></div>').dialog(),
actual = expected.dialog('disable');
equal(actual, expected, 'disable is chainable');
el = $('<div></div>').dialog({ disabled: false });
el.dialog('disable');
equal(el.dialog('option', 'disabled'), true, 'disable method sets disabled option to true');
- ok(dlg().hasClass('ui-dialog-disabled'), 'disable method adds ui-dialog-disabled class to ui-dialog element');
+ ok(el.dialog('widget').hasClass('ui-dialog-disabled'), 'disable method adds ui-dialog-disabled class to ui-dialog element');
});
test("close", function() {
expect( 3 );
- var expected = $('<div></div>').dialog(),
+ var el,
+ expected = $('<div></div>').dialog(),
actual = expected.dialog('close');
equal(actual, expected, 'close is chainable');
el = $('<div></div>').dialog();
- ok(dlg().is(':visible') && !dlg().is(':hidden'), 'dialog visible before close method called');
+ ok(el.dialog('widget').is(':visible') && !el.dialog('widget').is(':hidden'), 'dialog visible before close method called');
el.dialog('close');
- ok(dlg().is(':hidden') && !dlg().is(':visible'), 'dialog hidden after close method called');
+ ok(el.dialog('widget').is(':hidden') && !el.dialog('widget').is(':visible'), 'dialog hidden after close method called');
});
test("isOpen", function() {
expect(4);
- el = $('<div></div>').dialog();
+ var el = $('<div></div>').dialog();
equal(el.dialog('isOpen'), true, "dialog is open after init");
el.dialog('close');
equal(el.dialog('isOpen'), false, "dialog is closed");
@@ -106,36 +109,43 @@ test("isOpen", function() {
});
test("moveToTop", function() {
- expect( 3 );
-
- var d1, d2, dlg1, dlg2,
- expected = $('<div></div>').dialog(),
- actual = expected.dialog('moveToTop');
- equal(actual, expected, 'moveToTop is chainable');
-
- d1 = $('<div></div>').dialog();
- dlg1 = d1.parents('.ui-dialog');
- d1.dialog('close');
- d1.dialog('open');
- d2 = $('<div></div>').dialog();
- dlg2 = d2.parents('.ui-dialog');
- d2.dialog('close');
- d2.dialog('open');
- ok(dlg1.css('zIndex') < dlg2.css('zIndex'), 'dialog 1 under dialog 2 before moveToTop method called');
- d1.dialog('moveToTop');
- ok(dlg1.css('zIndex') > dlg2.css('zIndex'), 'dialog 1 above dialog 2 after moveToTop method called');
+ expect( 5 );
+ function order() {
+ var actual = $( ".ui-dialog" ).map(function() {
+ return +$( this ).find( ".ui-dialog-content" ).attr( "id" ).replace( /\D+/, "" );
+ }).get().reverse();
+ deepEqual( actual, $.makeArray( arguments ) );
+ }
+ var dialog1, dialog2,
+ focusOn = "dialog1";
+ dialog1 = $( "#dialog1" ).dialog({
+ focus: function() {
+ equal( focusOn, "dialog1" );
+ }
+ });
+ focusOn = "dialog2";
+ dialog2 = $( "#dialog2" ).dialog({
+ focus: function() {
+ equal( focusOn, "dialog2" );
+ }
+ });
+ order( 2, 1 );
+ focusOn = "dialog1";
+ dialog1.dialog( "moveToTop" );
+ order( 1, 2 );
});
test("open", function() {
expect( 3 );
- var expected = $('<div></div>').dialog(),
+ var el,
+ expected = $('<div></div>').dialog(),
actual = expected.dialog('open');
equal(actual, expected, 'open is chainable');
el = $('<div></div>').dialog({ autoOpen: false });
- ok(dlg().is(':hidden') && !dlg().is(':visible'), 'dialog hidden before open method called');
+ ok(el.dialog('widget').is(':hidden') && !el.dialog('widget').is(':visible'), 'dialog hidden before open method called');
el.dialog('open');
- ok(dlg().is(':visible') && !dlg().is(':hidden'), 'dialog visible after open method called');
+ ok(el.dialog('widget').is(':visible') && !el.dialog('widget').is(':hidden'), 'dialog visible after open method called');
});
})(jQuery);
diff --git a/tests/unit/dialog/dialog_options.js b/tests/unit/dialog/dialog_options.js
index ba217c6f4..c58cf6915 100644
--- a/tests/unit/dialog/dialog_options.js
+++ b/tests/unit/dialog/dialog_options.js
@@ -8,12 +8,12 @@ module("dialog: options");
test("autoOpen", function() {
expect(2);
- el = $('<div></div>').dialog({ autoOpen: false });
- isNotOpen('.dialog({ autoOpen: false })');
+ var el = $('<div></div>').dialog({ autoOpen: false });
+ ok( !el.dialog("widget").is(":visible"), '.dialog({ autoOpen: false })');
el.remove();
el = $('<div></div>').dialog({ autoOpen: true });
- isOpen('.dialog({ autoOpen: true })');
+ ok( el.dialog("widget").is(":visible"), '.dialog({ autoOpen: true })');
el.remove();
});
@@ -22,24 +22,24 @@ test("buttons", function() {
var btn, i, newButtons,
buttons = {
- "Ok": function(ev, ui) {
- ok(true, "button click fires callback");
- equal(this, el[0], "context of callback");
- equal(ev.target, btn[0], "event target");
+ "Ok": function( ev ) {
+ ok(true, "button click fires callback");
+ equal(this, el[0], "context of callback");
+ equal(ev.target, btn[0], "event target");
+ },
+ "Cancel": function( ev ) {
+ ok(true, "button click fires callback");
+ equal(this, el[0], "context of callback");
+ equal(ev.target, btn[1], "event target");
+ }
},
- "Cancel": function(ev, ui) {
- ok(true, "button click fires callback");
- equal(this, el[0], "context of callback");
- equal(ev.target, btn[1], "event target");
- }
- };
+ el = $('<div></div>').dialog({ buttons: buttons });
- el = $('<div></div>').dialog({ buttons: buttons });
- btn = $("button", dlg());
+ btn = $("button", el.dialog('widget'));
equal(btn.length, 2, "number of buttons");
i = 0;
- $.each(buttons, function(key, val) {
+ $.each(buttons, function( key ) {
equal(btn.eq(i).text(), key, "text of button " + (i+1));
i++;
});
@@ -50,7 +50,7 @@ test("buttons", function() {
btn.trigger("click");
newButtons = {
- "Close": function(ev, ui) {
+ "Close": function( ev ) {
ok(true, "button click fires callback");
equal(this, el[0], "context of callback");
equal(ev.target, btn[0], "event target");
@@ -61,18 +61,18 @@ test("buttons", function() {
el.dialog("option", "buttons", newButtons);
deepEqual(el.dialog("option", "buttons"), newButtons, '.dialog("option", "buttons", ...) setter');
- btn = $("button", dlg());
+ btn = $("button", el.dialog('widget'));
equal(btn.length, 1, "number of buttons after setter");
btn.trigger('click');
i = 0;
- $.each(newButtons, function(key, val) {
+ $.each(newButtons, function( key ) {
equal(btn.eq(i).text(), key, "text of button " + (i+1));
i += 1;
});
el.dialog("option", "buttons", null);
- btn = $("button", dlg());
+ btn = $("button", el.dialog('widget'));
equal(btn.length, 0, "all buttons have been removed");
equal(el.find(".ui-dialog-buttonset").length, 0, "buttonset has been removed");
equal(el.parent().hasClass('ui-dialog-buttons'), false, "dialog wrapper removes class about having buttons");
@@ -83,19 +83,21 @@ test("buttons", function() {
test("buttons - advanced", function() {
expect(5);
- el = $("<div></div>").dialog({
- buttons: [
- {
- text: "a button",
- "class": "additional-class",
- id: "my-button-id",
- click: function() {
- equal(this, el[0], "correct context");
+ var buttons,
+ el = $("<div></div>").dialog({
+ buttons: [
+ {
+ text: "a button",
+ "class": "additional-class",
+ id: "my-button-id",
+ click: function() {
+ equal(this, el[0], "correct context");
+ }
}
- }
- ]
- });
- var buttons = dlg().find("button");
+ ]
+ });
+
+ buttons = el.dialog('widget').find("button");
equal(buttons.length, 1, "correct number of buttons");
equal(buttons.attr("id"), "my-button-id", "correct id");
equal(buttons.text(), "a button", "correct label");
@@ -107,40 +109,40 @@ test("buttons - advanced", function() {
test("closeOnEscape", function() {
expect( 6 );
- el = $('<div></div>').dialog({ closeOnEscape: false });
+ var el = $('<div></div>').dialog({ closeOnEscape: false });
ok(true, 'closeOnEscape: false');
- ok(dlg().is(':visible') && !dlg().is(':hidden'), 'dialog is open before ESC');
+ ok(el.dialog('widget').is(':visible') && !el.dialog('widget').is(':hidden'), 'dialog is open before ESC');
el.simulate('keydown', { keyCode: $.ui.keyCode.ESCAPE })
.simulate('keypress', { keyCode: $.ui.keyCode.ESCAPE })
.simulate('keyup', { keyCode: $.ui.keyCode.ESCAPE });
- ok(dlg().is(':visible') && !dlg().is(':hidden'), 'dialog is open after ESC');
+ ok(el.dialog('widget').is(':visible') && !el.dialog('widget').is(':hidden'), 'dialog is open after ESC');
el.remove();
el = $('<div></div>').dialog({ closeOnEscape: true });
ok(true, 'closeOnEscape: true');
- ok(dlg().is(':visible') && !dlg().is(':hidden'), 'dialog is open before ESC');
+ ok(el.dialog('widget').is(':visible') && !el.dialog('widget').is(':hidden'), 'dialog is open before ESC');
el.simulate('keydown', { keyCode: $.ui.keyCode.ESCAPE })
.simulate('keypress', { keyCode: $.ui.keyCode.ESCAPE })
.simulate('keyup', { keyCode: $.ui.keyCode.ESCAPE });
- ok(dlg().is(':hidden') && !dlg().is(':visible'), 'dialog is closed after ESC');
+ ok(el.dialog('widget').is(':hidden') && !el.dialog('widget').is(':visible'), 'dialog is closed after ESC');
});
test("closeText", function() {
expect(3);
- el = $('<div></div>').dialog();
- equal(dlg().find('.ui-dialog-titlebar-close span').text(), 'close',
+ var el = $('<div></div>').dialog();
+ equal(el.dialog('widget').find('.ui-dialog-titlebar-close span').text(), 'close',
'default close text');
el.remove();
el = $('<div></div>').dialog({ closeText: "foo" });
- equal(dlg().find('.ui-dialog-titlebar-close span').text(), 'foo',
+ equal(el.dialog('widget').find('.ui-dialog-titlebar-close span').text(), 'foo',
'closeText on init');
el.remove();
el = $('<div></div>').dialog().dialog('option', 'closeText', 'bar');
- equal(dlg().find('.ui-dialog-titlebar-close span').text(), 'bar',
+ equal(el.dialog('widget').find('.ui-dialog-titlebar-close span').text(), 'bar',
'closeText via option method');
el.remove();
});
@@ -148,131 +150,132 @@ test("closeText", function() {
test("dialogClass", function() {
expect(4);
- el = $('<div></div>').dialog();
- equal(dlg().is(".foo"), false, 'dialogClass not specified. foo class added');
+ var el = $('<div></div>').dialog();
+ equal(el.dialog('widget').is(".foo"), false, 'dialogClass not specified. foo class added');
el.remove();
el = $('<div></div>').dialog({ dialogClass: "foo" });
- equal(dlg().is(".foo"), true, 'dialogClass in init. foo class added');
+ equal(el.dialog('widget').is(".foo"), true, 'dialogClass in init. foo class added');
el.remove();
el = $('<div></div>').dialog({ dialogClass: "foo bar" });
- equal(dlg().is(".foo"), true, 'dialogClass in init, two classes. foo class added');
- equal(dlg().is(".bar"), true, 'dialogClass in init, two classes. bar class added');
+ equal(el.dialog('widget').is(".foo"), true, 'dialogClass in init, two classes. foo class added');
+ equal(el.dialog('widget').is(".bar"), true, 'dialogClass in init, two classes. bar class added');
el.remove();
});
test("draggable", function() {
expect(4);
- el = $('<div></div>').dialog({ draggable: false });
- shouldnotmove();
+ var el = $('<div></div>').dialog({ draggable: false });
+
+ TestHelpers.dialog.testDrag(el, 50, -50, 0, 0);
el.dialog('option', 'draggable', true);
- shouldmove();
+ TestHelpers.dialog.testDrag(el, 50, -50, 50, -50);
el.remove();
el = $('<div></div>').dialog({ draggable: true });
- shouldmove();
+ TestHelpers.dialog.testDrag(el, 50, -50, 50, -50);
el.dialog('option', 'draggable', false);
- shouldnotmove();
+ TestHelpers.dialog.testDrag(el, 50, -50, 0, 0);
el.remove();
});
test("height", function() {
expect(4);
- el = $('<div></div>').dialog();
- equal(dlg().outerHeight(), 150, "default height");
+ var el = $('<div></div>').dialog();
+ equal(el.dialog('widget').outerHeight(), 150, "default height");
el.remove();
el = $('<div></div>').dialog({ height: 237 });
- equal(dlg().outerHeight(), 237, "explicit height");
+ equal(el.dialog('widget').outerHeight(), 237, "explicit height");
el.remove();
el = $('<div></div>').dialog();
el.dialog('option', 'height', 238);
- equal(dlg().outerHeight(), 238, "explicit height set after init");
+ equal(el.dialog('widget').outerHeight(), 238, "explicit height set after init");
el.remove();
el = $('<div></div>').css("padding", "20px")
.dialog({ height: 240 });
- equal(dlg().outerHeight(), 240, "explicit height with padding");
+ equal(el.dialog('widget').outerHeight(), 240, "explicit height with padding");
el.remove();
});
test("maxHeight", function() {
expect(3);
- el = $('<div></div>').dialog({ maxHeight: 200 });
- drag('.ui-resizable-s', 1000, 1000);
- equal(heightAfter, 200, "maxHeight");
+ var el = $('<div></div>').dialog({ maxHeight: 200 });
+ TestHelpers.dialog.drag(el, '.ui-resizable-s', 1000, 1000);
+ closeEnough(el.dialog('widget').height(), 200, 1, "maxHeight");
el.remove();
el = $('<div></div>').dialog({ maxHeight: 200 });
- drag('.ui-resizable-n', -1000, -1000);
- equal(heightAfter, 200, "maxHeight");
+ TestHelpers.dialog.drag(el, '.ui-resizable-n', -1000, -1000);
+ closeEnough(el.dialog('widget').height(), 200, 1, "maxHeight");
el.remove();
el = $('<div></div>').dialog({ maxHeight: 200 }).dialog('option', 'maxHeight', 300);
- drag('.ui-resizable-s', 1000, 1000);
- equal(heightAfter, 300, "maxHeight");
+ TestHelpers.dialog.drag(el, '.ui-resizable-s', 1000, 1000);
+ closeEnough(el.dialog('widget').height(), 300, 1, "maxHeight");
el.remove();
});
test("maxWidth", function() {
expect(3);
- el = $('<div></div>').dialog({ maxWidth: 200 });
- drag('.ui-resizable-e', 1000, 1000);
- equal(widthAfter, 200, "maxWidth");
+ var el = $('<div></div>').dialog({ maxWidth: 200 });
+ TestHelpers.dialog.drag(el, '.ui-resizable-e', 1000, 1000);
+ closeEnough(el.dialog('widget').width(), 200, 1, "maxWidth");
el.remove();
el = $('<div></div>').dialog({ maxWidth: 200 });
- drag('.ui-resizable-w', -1000, -1000);
- equal(widthAfter, 200, "maxWidth");
+ TestHelpers.dialog.drag(el, '.ui-resizable-w', -1000, -1000);
+ closeEnough(el.dialog('widget').width(), 200, 1, "maxWidth");
el.remove();
el = $('<div></div>').dialog({ maxWidth: 200 }).dialog('option', 'maxWidth', 300);
- drag('.ui-resizable-w', -1000, -1000);
- equal(widthAfter, 300, "maxWidth");
+ TestHelpers.dialog.drag(el, '.ui-resizable-w', -1000, -1000);
+ closeEnough(el.dialog('widget').width(), 300, 1, "maxWidth");
el.remove();
});
test("minHeight", function() {
expect(3);
- el = $('<div></div>').dialog({ minHeight: 10 });
- drag('.ui-resizable-s', -1000, -1000);
- equal(heightAfter, 10, "minHeight");
+ var el = $('<div></div>').dialog({ minHeight: 10 });
+ TestHelpers.dialog.drag(el, '.ui-resizable-s', -1000, -1000);
+ closeEnough(el.dialog('widget').height(), 10, 1, "minHeight");
el.remove();
el = $('<div></div>').dialog({ minHeight: 10 });
- drag('.ui-resizable-n', 1000, 1000);
- equal(heightAfter, 10, "minHeight");
+ TestHelpers.dialog.drag(el, '.ui-resizable-n', 1000, 1000);
+ closeEnough(el.dialog('widget').height(), 10, 1, "minHeight");
el.remove();
el = $('<div></div>').dialog({ minHeight: 10 }).dialog('option', 'minHeight', 30);
- drag('.ui-resizable-n', 1000, 1000);
- equal(heightAfter, 30, "minHeight");
+ TestHelpers.dialog.drag(el, '.ui-resizable-n', 1000, 1000);
+ closeEnough(el.dialog('widget').height(), 30, 1, "minHeight");
el.remove();
});
test("minWidth", function() {
expect(3);
- el = $('<div></div>').dialog({ minWidth: 10 });
- drag('.ui-resizable-e', -1000, -1000);
- equal(widthAfter, 10, "minWidth");
+ var el = $('<div></div>').dialog({ minWidth: 10 });
+ TestHelpers.dialog.drag(el, '.ui-resizable-e', -1000, -1000);
+ closeEnough(el.dialog('widget').width(), 10, 1, "minWidth");
el.remove();
el = $('<div></div>').dialog({ minWidth: 10 });
- drag('.ui-resizable-w', 1000, 1000);
- equal(widthAfter, 10, "minWidth");
+ TestHelpers.dialog.drag(el, '.ui-resizable-w', 1000, 1000);
+ closeEnough(el.dialog('widget').width(), 10, 1, "minWidth");
el.remove();
el = $('<div></div>').dialog({ minWidth: 30 }).dialog('option', 'minWidth', 30);
- drag('.ui-resizable-w', 1000, 1000);
- equal(widthAfter, 30, "minWidth");
+ TestHelpers.dialog.drag(el, '.ui-resizable-w', 1000, 1000);
+ closeEnough(el.dialog('widget').width(), 30, 1, "minWidth");
el.remove();
});
@@ -281,8 +284,8 @@ test("position, default center on window", function() {
var el = $('<div></div>').dialog(),
dialog = el.dialog('widget'),
offset = dialog.offset();
- deepEqual(offset.left, Math.round($(window).width() / 2 - dialog.outerWidth() / 2) + $(window).scrollLeft());
- deepEqual(offset.top, Math.round($(window).height() / 2 - dialog.outerHeight() / 2) + $(window).scrollTop());
+ closeEnough(offset.left, Math.round($(window).width() / 2 - dialog.outerWidth() / 2) + $(window).scrollLeft(), 1);
+ closeEnough(offset.top, Math.round($(window).height() / 2 - dialog.outerHeight() / 2) + $(window).scrollTop(), 1);
el.remove();
});
@@ -291,8 +294,8 @@ test("position, top on window", function() {
var el = $('<div></div>').dialog({ position: "top" }),
dialog = el.dialog('widget'),
offset = dialog.offset();
- deepEqual(offset.left, Math.round($(window).width() / 2 - dialog.outerWidth() / 2) + $(window).scrollLeft());
- deepEqual(offset.top, $(window).scrollTop());
+ closeEnough(offset.left, Math.round($(window).width() / 2 - dialog.outerWidth() / 2) + $(window).scrollLeft(), 1);
+ closeEnough(offset.top, $(window).scrollTop(), 1);
el.remove();
});
@@ -301,54 +304,59 @@ test("position, left on window", function() {
var el = $('<div></div>').dialog({ position: "left" }),
dialog = el.dialog('widget'),
offset = dialog.offset();
- deepEqual(offset.left, 0);
- deepEqual(offset.top, Math.round($(window).height() / 2 - dialog.outerHeight() / 2) + $(window).scrollTop());
+ closeEnough(offset.left, 0, 1);
+ closeEnough(offset.top, Math.round($(window).height() / 2 - dialog.outerHeight() / 2) + $(window).scrollTop(), 1);
el.remove();
});
-test("position, right bottom on window", function() {
- expect( 2 );
- var el = $('<div></div>').dialog({ position: "right bottom" }),
- dialog = el.dialog('widget'),
- offset = dialog.offset();
- deepEqual(offset.left, $(window).width() - dialog.outerWidth() + $(window).scrollLeft());
- deepEqual(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop());
- el.remove();
-});
+// todo: figure out these fails in IE7
+if ( !$.ui.ie ) {
+
+ test("position, right bottom on window", function() {
+ expect( 2 );
+ var el = $('<div></div>').dialog({ position: "right bottom" }),
+ dialog = el.dialog('widget'),
+ offset = dialog.offset();
+ closeEnough(offset.left, $(window).width() - dialog.outerWidth() + $(window).scrollLeft(), 1);
+ closeEnough(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop(), 1);
+ el.remove();
+ });
-test("position, right bottom on window w/array", function() {
- expect( 2 );
- var el = $('<div></div>').dialog({ position: ["right", "bottom"] }),
- dialog = el.dialog('widget'),
- offset = dialog.offset();
- deepEqual(offset.left, $(window).width() - dialog.outerWidth() + $(window).scrollLeft());
- deepEqual(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop());
- el.remove();
-});
+ test("position, right bottom on window w/array", function() {
+ expect( 2 );
+ var el = $('<div></div>').dialog({ position: ["right", "bottom"] }),
+ dialog = el.dialog('widget'),
+ offset = dialog.offset();
+ closeEnough(offset.left, $(window).width() - dialog.outerWidth() + $(window).scrollLeft(), 1);
+ closeEnough(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop(), 1);
+ el.remove();
+ });
+
+ test("position, right bottom at right bottom via ui.position args", function() {
+ expect( 2 );
+ var el = $('<div></div>').dialog({
+ position: {
+ my: "right bottom",
+ at: "right bottom"
+ }
+ }),
+ dialog = el.dialog('widget'),
+ offset = dialog.offset();
+
+ closeEnough(offset.left, $(window).width() - dialog.outerWidth() + $(window).scrollLeft(), 1);
+ closeEnough(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop(), 1);
+ el.remove();
+ });
+
+}
test("position, offset from top left w/array", function() {
expect( 2 );
var el = $('<div></div>').dialog({ position: [10, 10] }),
dialog = el.dialog('widget'),
offset = dialog.offset();
- deepEqual(offset.left, 10 + $(window).scrollLeft());
- deepEqual(offset.top, 10 + $(window).scrollTop());
- el.remove();
-});
-
-test("position, right bottom at right bottom via ui.position args", function() {
- expect( 2 );
- var el = $('<div></div>').dialog({
- position: {
- my: "right bottom",
- at: "right bottom"
- }
- }),
- dialog = el.dialog('widget'),
- offset = dialog.offset();
-
- deepEqual(offset.left, $(window).width() - dialog.outerWidth() + $(window).scrollLeft());
- deepEqual(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop());
+ closeEnough(offset.left, 10 + $(window).scrollLeft(), 1);
+ closeEnough(offset.top, 10 + $(window).scrollTop(), 1);
el.remove();
});
@@ -394,16 +402,16 @@ test("position, at another element", function() {
test("resizable", function() {
expect(4);
- el = $('<div></div>').dialog();
- shouldresize("[default]");
+ var el = $('<div></div>').dialog();
+ TestHelpers.dialog.shouldResize(el, 50, 50, "[default]");
el.dialog('option', 'resizable', false);
- shouldnotresize('disabled after init');
+ TestHelpers.dialog.shouldResize(el, 0, 0, 'disabled after init');
el.remove();
el = $('<div></div>').dialog({ resizable: false });
- shouldnotresize("disabled in init options");
+ TestHelpers.dialog.shouldResize(el, 0, 0, "disabled in init options");
el.dialog('option', 'resizable', true);
- shouldresize('enabled after init');
+ TestHelpers.dialog.shouldResize(el, 50, 50, 'enabled after init');
el.remove();
});
@@ -411,13 +419,13 @@ test("title", function() {
expect(9);
function titleText() {
- return dlg().find(".ui-dialog-title").html();
+ return el.dialog('widget').find(".ui-dialog-title").html();
}
- el = $('<div></div>').dialog();
+ var el = $('<div></div>').dialog();
// some browsers return a non-breaking space and some return "&nbsp;"
// so we get the text to normalize to the actual non-breaking space
- equal(dlg().find(".ui-dialog-title").text(), " ", "[default]");
+ equal(el.dialog('widget').find(".ui-dialog-title").text(), " ", "[default]");
equal(el.dialog("option", "title"), "", "option not changed");
el.remove();
@@ -444,14 +452,14 @@ test("title", function() {
test("width", function() {
expect(3);
- el = $('<div></div>').dialog();
- equal(dlg().width(), 300, "default width");
+ var el = $('<div></div>').dialog();
+ closeEnough(el.dialog('widget').width(), 300, 1, "default width");
el.remove();
el = $('<div></div>').dialog({width: 437 });
- equal(dlg().width(), 437, "explicit width");
+ closeEnough(el.dialog('widget').width(), 437, 1, "explicit width");
el.dialog('option', 'width', 438);
- equal(dlg().width(), 438, 'explicit width after init');
+ closeEnough(el.dialog('widget').width(), 438, 1, 'explicit width after init');
el.remove();
});
diff --git a/tests/unit/dialog/dialog_test_helpers.js b/tests/unit/dialog/dialog_test_helpers.js
new file mode 100644
index 000000000..bbf43f48f
--- /dev/null
+++ b/tests/unit/dialog/dialog_test_helpers.js
@@ -0,0 +1,45 @@
+TestHelpers.dialog = {
+ drag: function(el, handle, dx, dy) {
+ var d = el.dialog('widget');
+ //this mouseover is to work around a limitation in resizable
+ //TODO: fix resizable so handle doesn't require mouseover in order to be used
+ $(handle, d).simulate("mouseover");
+ $(handle, d).simulate("drag", {
+ dx: dx || 0,
+ dy: dy || 0
+ });
+ },
+ testDrag: function(el, dx, dy, expectedDX, expectedDY, msg) {
+ var actual, expected, offsetAfter,
+ d = el.dialog('widget'),
+ handle = $(".ui-dialog-titlebar", d),
+ offsetBefore = d.offset();
+
+ TestHelpers.dialog.drag(el, handle, dx, dy);
+
+ offsetAfter = d.offset();
+
+ msg = msg ? msg + "." : "";
+
+ actual = { left: Math.round(offsetAfter.left), top: Math.round(offsetAfter.top) },
+ expected = { left: Math.round(offsetBefore.left + expectedDX), top: Math.round(offsetBefore.top + expectedDY) };
+ deepEqual(actual, expected, 'dragged[' + expectedDX + ', ' + expectedDY + '] ' + msg);
+ },
+ shouldResize: function(el, dw, dh, msg) {
+ var heightAfter, widthAfter, actual, expected,
+ d = el.dialog('widget'),
+ handle = $(".ui-resizable-se", d),
+ heightBefore = d.height(),
+ widthBefore = d.width();
+
+ TestHelpers.dialog.drag(el, handle, 50, 50);
+
+ heightAfter = d.height();
+ widthAfter = d.width();
+
+ msg = msg ? msg + "." : "";
+ actual = { width: widthAfter, height: heightAfter },
+ expected = { width: widthBefore + dw, height: heightBefore + dh };
+ deepEqual(actual, expected, 'resized[' + 50 + ', ' + 50 + '] ' + msg);
+ }
+}; \ No newline at end of file
diff --git a/tests/unit/dialog/dialog_tickets.js b/tests/unit/dialog/dialog_tickets.js
index 5c3277c2f..3055c5fc1 100644
--- a/tests/unit/dialog/dialog_tickets.js
+++ b/tests/unit/dialog/dialog_tickets.js
@@ -36,21 +36,21 @@ asyncTest( "#3123: Prevent tabbing out of modal dialogs", function() {
test("#4826: setting resizable false toggles resizable on dialog", function() {
expect(6);
- var i;
+ var i,
+ el = $('<div></div>').dialog({ resizable: false });
- el = $('<div></div>').dialog({ resizable: false });
- shouldnotresize("[default]");
+ TestHelpers.dialog.shouldResize(el, 0, 0, "[default]");
for (i=0; i<2; i++) {
el.dialog('close').dialog('open');
- shouldnotresize('initialized with resizable false toggle ('+ (i+1) +')');
+ TestHelpers.dialog.shouldResize(el, 0, 0, 'initialized with resizable false toggle ('+ (i+1) +')');
}
el.remove();
el = $('<div></div>').dialog({ resizable: true });
- shouldresize("[default]");
+ TestHelpers.dialog.shouldResize(el, 50, 50, "[default]");
for (i=0; i<2; i++) {
el.dialog('close').dialog('option', 'resizable', false).dialog('open');
- shouldnotresize('set option resizable false toggle ('+ (i+1) +')');
+ TestHelpers.dialog.shouldResize(el, 0, 0, 'set option resizable false toggle ('+ (i+1) +')');
}
el.remove();
@@ -59,11 +59,11 @@ test("#4826: setting resizable false toggles resizable on dialog", function() {
test("#5184: isOpen in dialogclose event is true", function() {
expect( 3 );
- el = $( "<div></div>" ).dialog({
- close: function() {
- ok( !el.dialog("isOpen"), "dialog is not open during close" );
- }
- });
+ var el = $( "<div></div>" ).dialog({
+ close: function() {
+ ok( !el.dialog("isOpen"), "dialog is not open during close" );
+ }
+ });
ok( el.dialog("isOpen"), "dialog is open after init" );
el.dialog( "close" );
ok( !el.dialog("isOpen"), "dialog is not open after close" );
@@ -72,7 +72,7 @@ test("#5184: isOpen in dialogclose event is true", function() {
test("#5531: dialog width should be at least minWidth on creation", function () {
expect( 4 );
- el = $('<div></div>').dialog({
+ var el = $('<div></div>').dialog({
width: 200,
minWidth: 300
});
@@ -95,107 +95,33 @@ test("#5531: dialog width should be at least minWidth on creation", function ()
test("#6137: dialog('open') causes form elements to reset on IE7", function() {
expect(2);
- d1 = $('<form><input type="radio" name="radio" id="a" value="a" checked="checked"></input>' +
+ var d1 = $('<form><input type="radio" name="radio" id="a" value="a" checked="checked"></input>' +
'<input type="radio" name="radio" id="b" value="b">b</input></form>').appendTo( "body" ).dialog({autoOpen: false});
d1.find('#b').prop( "checked", true );
- equal($('input:checked').val(), 'b', "checkbox b is checked");
+ equal(d1.find('input:checked').val(), 'b', "checkbox b is checked");
d1.dialog('open');
- equal($('input:checked').val(), 'b', "checkbox b is checked");
+ equal(d1.find('input:checked').val(), 'b', "checkbox b is checked");
d1.remove();
});
test("#6645: Missing element not found check in overlay", function(){
expect(2);
- d1 = $('<div title="dialog 1">Dialog 1</div>').dialog({modal: true});
- d2 = $('<div title="dialog 2">Dialog 2</div>').dialog({modal: true, close: function(){ d2.remove(); }});
+ var d1 = $('<div title="dialog 1">Dialog 1</div>').dialog({modal: true}),
+ d2 = $('<div title="dialog 2">Dialog 2</div>').dialog({modal: true, close: function(){ d2.remove(); }});
+
equal($.ui.dialog.overlay.instances.length, 2, 'two overlays created');
d2.dialog('close');
equal($.ui.dialog.overlay.instances.length, 1, 'one overlay remains after closing the 2nd overlay');
d1.add(d2).remove();
});
-test("#6966: Escape key closes all dialogs, not the top one", function(){
- expect(24);
- // test with close function removing dialog triggered through the overlay
- d1 = $('<div title="dialog 1">Dialog 1</div>').dialog({modal: true, close: function(){ d1.remove(); }});
- d2 = $('<div title="dialog 2">Dialog 2</div>').dialog({modal: true, close: function(){ d2.remove(); }});
-
- ok(d1.data('dialog') && d1.dialog('isOpen'), 'first dialog is open');
- ok(d2.data('dialog') && d2.dialog('isOpen'), 'second dialog is open');
-
- $( document ).simulate('keydown', {keyCode: $.ui.keyCode.ESCAPE});
- ok(d1.data('dialog') && d1.dialog('isOpen'), 'first dialog still open');
- ok(!d2.data('dialog'), 'second dialog is closed');
-
- $( document ).simulate('keydown', {keyCode: $.ui.keyCode.ESCAPE});
- ok(!d1.data('dialog'), 'first dialog is closed');
- ok(!d2.data('dialog'), 'second dialog is closed');
-
- d2.remove();
- d1.remove();
-
- // test with close function removing dialog triggered through the dialog
- d1 = $('<div title="dialog 1">Dialog 1</div>').dialog({modal: true, close: function(){ d1.remove(); }});
- d2 = $('<div title="dialog 2">Dialog 2</div>').dialog({modal: true, close: function(){ d2.remove(); }});
-
- ok(d1.data('dialog') && d1.dialog('isOpen'), 'first dialog is open');
- ok(d2.data('dialog') && d2.dialog('isOpen'), 'second dialog is open');
-
- d2.simulate('keydown', {keyCode: $.ui.keyCode.ESCAPE});
- ok(d1.data('dialog') && d1.dialog('isOpen'), 'first dialog still open');
- ok(!d2.data('dialog'), 'second dialog is closed');
-
- d1.simulate('keydown', {keyCode: $.ui.keyCode.ESCAPE});
- ok(!d1.data('dialog'), 'first dialog is closed');
- ok(!d2.data('dialog'), 'second dialog is closed');
-
- d2.remove();
- d1.remove();
-
- // test without close function removing dialog
- d1 = $('<div title="dialog 1">Dialog 1</div>').dialog({modal: true});
- d2 = $('<div title="dialog 2">Dialog 2</div>').dialog({modal: true});
-
- ok(d1.dialog("isOpen"), 'first dialog is open');
- ok(d2.dialog("isOpen"), 'second dialog is open');
-
- d2.simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE});
- ok(d1.dialog("isOpen"), 'first dialog still open');
- ok(!d2.dialog("isOpen"), 'second dialog is closed');
-
- d1.simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE});
- ok(!d1.dialog("isOpen"), 'first dialog is closed');
- ok(!d2.dialog("isOpen"), 'second dialog is closed');
-
- d2.remove();
- d1.remove();
-
- // test without close function removing dialog triggered through the overlay
- d1 = $('<div title="dialog 1">Dialog 1</div>').dialog({modal: true});
- d2 = $('<div title="dialog 2">Dialog 2</div>').dialog({modal: true});
-
- ok(d1.dialog("isOpen"), 'first dialog is open');
- ok(d2.dialog("isOpen"), 'second dialog is open');
-
- $( document ).simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE});
- ok(d1.dialog("isOpen"), 'first dialog still open');
- ok(!d2.dialog("isOpen"), 'second dialog is closed');
-
- $( document ).simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE});
- ok(!d1.dialog("isOpen"), 'first dialog is closed');
- ok(!d2.dialog("isOpen"), 'second dialog is closed');
-
- d2.remove();
- d1.remove();
-});
-
test("#4980: Destroy should place element back in original DOM position", function(){
expect( 2 );
- container = $('<div id="container"><div id="modal">Content</div></div>');
- modal = container.find('#modal');
+ var container = $('<div id="container"><div id="modal">Content</div></div>'),
+ modal = container.find('#modal');
modal.dialog();
ok(!$.contains(container[0], modal[0]), 'dialog should move modal element to outside container element');
modal.dialog('destroy');
diff --git a/tests/unit/draggable/draggable.html b/tests/unit/draggable/draggable.html
index 09bc191c9..dce226a9a 100644
--- a/tests/unit/draggable/draggable.html
+++ b/tests/unit/draggable/draggable.html
@@ -26,17 +26,8 @@
<script src="draggable_events.js"></script>
<script src="draggable_methods.js"></script>
<script src="draggable_options.js"></script>
+ <script src="draggable_test_helpers.js"></script>
- <script>
- // disable this stale testsuite for testswarm only
- var url = window.location.search;
- url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) );
- if ( url && url.indexOf("http") == 0 ) {
- // reset config to kill previous tests; make sure testsuite.js is loaded afterwards to init the testswarm script
- QUnit.init();
- test("draggable", function() { ok(true, "disabled draggable testsuite"); });
- }
- </script>
<script src="../swarminject.js"></script>
</head>
<body>
@@ -48,11 +39,14 @@
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">
+<div id="main"></div>
+
<div id="draggable1" style="background: green; width: 200px; height: 100px;">Relative</div>
<div id="draggable2" style="background: green; width: 200px; height: 100px; position: absolute; top: 10px; left: 10px;"><span>Absolute</span></div>
<div style='width: 1px; height: 1000px;'></div>
<div style="position: absolute; width: 1px; height: 2000px;"></div>
</div>
+
</body>
</html>
diff --git a/tests/unit/draggable/draggable_common.js b/tests/unit/draggable/draggable_common.js
index 64f8ce4a3..34fd20564 100644
--- a/tests/unit/draggable/draggable_common.js
+++ b/tests/unit/draggable/draggable_common.js
@@ -6,6 +6,7 @@ TestHelpers.commonWidgetTests( "draggable", {
cancel: "input,textarea,button,select,option",
connectToSortable: false,
containment: false,
+ create: null,
cursor: "auto",
cursorAt: false,
delay: 0,
diff --git a/tests/unit/draggable/draggable_core.js b/tests/unit/draggable/draggable_core.js
index 9193881ad..31002addc 100644
--- a/tests/unit/draggable/draggable_core.js
+++ b/tests/unit/draggable/draggable_core.js
@@ -2,34 +2,6 @@
* draggable_core.js
*/
-var el, offsetBefore, offsetAfter, dragged;
-
-function drag(handle, dx, dy) {
- var element = el.data("draggable").element;
- offsetBefore = el.offset();
- $(handle).simulate("drag", {
- dx: dx || 0,
- dy: dy || 0
- });
- dragged = { dx: dx, dy: dy };
- offsetAfter = el.offset();
-}
-
-function moved(dx, dy, msg) {
- msg = msg ? msg + "." : "";
- var actual = { left: offsetAfter.left, top: offsetAfter.top },
- expected = { left: offsetBefore.left + dx, top: offsetBefore.top + dy };
- deepEqual(actual, expected, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ' + msg);
-}
-
-function restoreScroll(what) {
- if(what) {
- $(document).scrollTop(0); $(document).scrollLeft(0);
- } else {
- $("#main")[0].scrollTop = 0; $("#main")[0].scrollLeft = 0;
- }
-}
-
(function($) {
module("draggable");
@@ -37,31 +9,39 @@ module("draggable");
test("element types", function() {
var typeNames = ('p,h1,h2,h3,h4,h5,h6,blockquote,ol,ul,dl,div,form' +
',table,fieldset,address,ins,del,em,strong,q,cite,dfn,abbr' +
- ',acronym,code,samp,kbd,var,img,object,hr' +
+ ',acronym,code,samp,kbd,var,img,hr' +
',input,button,label,select,iframe').split(',');
+ expect( typeNames.length * 2 );
+
$.each(typeNames, function(i) {
- var typeName = typeNames[i];
- el = $(document.createElement(typeName)).appendTo('body');
+ var offsetBefore, offsetAfter,
+ typeName = typeNames[i],
+ el = $(document.createElement(typeName)).appendTo('#main');
+
(typeName === 'table' && el.append("<tr><td>content</td></tr>"));
el.draggable({ cancel: '' });
- drag(el, 50, 50);
- moved(50, 50, "&lt;" + typeName + "&gt;");
+ offsetBefore = el.offset();
+ TestHelpers.draggable.drag(el, 50, 50);
+ offsetAfter = el.offset();
+ // there are some rounding errors in FF, Chrome, and IE9, so we can't say equal, we have to settle for close enough
+ closeEnough(offsetBefore.left, offsetAfter.left - 50, 1, "dragged[50, 50] " + "<" + typeName + ">");
+ closeEnough(offsetBefore.top, offsetAfter.top - 50, 1, "dragged[50, 50] " + "<" + typeName + ">");
el.draggable("destroy");
el.remove();
});
});
test("No options, relative", function() {
- el = $("#draggable1").draggable();
- drag(el, 50, 50);
- moved(50, 50);
+ expect( 1 );
+ var el = $("#draggable1").draggable();
+ TestHelpers.draggable.shouldMove(el);
});
test("No options, absolute", function() {
- el = $("#draggable2").draggable();
- drag(el, 50, 50);
- moved(50, 50);
+ expect( 1 );
+ var el = $("#draggable2").draggable();
+ TestHelpers.draggable.shouldMove(el);
});
})(jQuery);
diff --git a/tests/unit/draggable/draggable_events.js b/tests/unit/draggable/draggable_events.js
index 2b2104ed4..5eab97713 100644
--- a/tests/unit/draggable/draggable_events.js
+++ b/tests/unit/draggable/draggable_events.js
@@ -9,14 +9,16 @@ test("callbacks occurrence count", function() {
expect(3);
- var start = 0, stop = 0, dragc = 0;
- el = $("#draggable2").draggable({
- start: function() { start++; },
- drag: function() { dragc++; },
- stop: function() { stop++; }
- });
+ var start = 0,
+ stop = 0,
+ dragc = 0,
+ el = $("#draggable2").draggable({
+ start: function() { start++; },
+ drag: function() { dragc++; },
+ stop: function() { stop++; }
+ });
- drag(el, 10, 10);
+ TestHelpers.draggable.drag(el, 10, 10);
equal(start, 1, "start callback should happen exactly once");
equal(dragc, 3, "drag callback should happen exactly once per mousemove");
@@ -28,14 +30,16 @@ test("stopping the start callback", function() {
expect(3);
- var start = 0, stop = 0, dragc = 0;
- el = $("#draggable2").draggable({
- start: function() { start++; return false; },
- drag: function() { dragc++; },
- stop: function() { stop++; }
- });
+ var start = 0,
+ stop = 0,
+ dragc = 0,
+ el = $("#draggable2").draggable({
+ start: function() { start++; return false; },
+ drag: function() { dragc++; },
+ stop: function() { stop++; }
+ });
- drag(el, 10, 10);
+ TestHelpers.draggable.drag(el, 10, 10);
equal(start, 1, "start callback should happen exactly once");
equal(dragc, 0, "drag callback should not happen at all");
@@ -47,14 +51,16 @@ test("stopping the drag callback", function() {
expect(3);
- var start = 0, stop = 0, dragc = 0;
- el = $("#draggable2").draggable({
- start: function() { start++;},
- drag: function() { dragc++; return false; },
- stop: function() { stop++; }
- });
+ var start = 0,
+ stop = 0,
+ dragc = 0,
+ el = $("#draggable2").draggable({
+ start: function() { start++;},
+ drag: function() { dragc++; return false; },
+ stop: function() { stop++; }
+ });
- drag(el, 10, 10);
+ TestHelpers.draggable.drag(el, 10, 10);
equal(start, 1, "start callback should happen exactly once");
equal(dragc, 1, "drag callback should happen exactly once");
@@ -66,14 +72,14 @@ test("stopping the stop callback", function() {
expect(1);
- el = $("#draggable2").draggable({
+ var el = $("#draggable2").draggable({
helper: 'clone',
stop: function() { return false; }
});
- drag(el, 10, 10);
+ TestHelpers.draggable.drag(el, 10, 10);
- ok($("#draggable2").data('draggable').helper, "the clone should not be deleted if the stop callback is stopped");
+ ok($("#draggable2").data('ui-draggable').helper, "the clone should not be deleted if the stop callback is stopped");
});
diff --git a/tests/unit/draggable/draggable_methods.js b/tests/unit/draggable/draggable_methods.js
index bb3fd0771..9ea353ca6 100644
--- a/tests/unit/draggable/draggable_methods.js
+++ b/tests/unit/draggable/draggable_methods.js
@@ -3,20 +3,10 @@
*/
(function($) {
-function shouldmove(why) {
- drag(el, 50, 50);
- moved(50, 50, why);
-}
-
-function shouldnotmove(why) {
- drag(el, 50, 50);
- moved(0, 0, why);
-}
-
module("draggable: methods");
test("init", function() {
- expect(6);
+ expect(5);
$("<div></div>").appendTo('body').draggable().remove();
ok(true, '.draggable() called on element');
@@ -27,9 +17,6 @@ test("init", function() {
$("<div></div>").draggable();
ok(true, '.draggable() called on disconnected DOMElement');
- $("<div></div>").draggable().draggable("foo");
- ok(true, 'arbitrary method called after init');
-
$("<div></div>").draggable().draggable("option", "foo");
ok(true, 'arbitrary option getter after init');
@@ -38,6 +25,7 @@ test("init", function() {
});
test("destroy", function() {
+ expect(4);
$("<div></div>").appendTo('body').draggable().draggable("destroy").remove();
ok(true, '.draggable("destroy") called on element');
@@ -47,9 +35,6 @@ test("destroy", function() {
$("<div></div>").draggable().draggable("destroy");
ok(true, '.draggable("destroy") called on disconnected DOMElement');
- $("<div></div>").draggable().draggable("destroy").draggable("foo");
- ok(true, 'arbitrary method called after destroy');
-
var expected = $('<div></div>').draggable(),
actual = expected.draggable('destroy');
equal(actual, expected, 'destroy is chainable');
@@ -57,42 +42,52 @@ test("destroy", function() {
test("enable", function() {
expect(7);
+
+ var expected, actual, el;
+
el = $("#draggable2").draggable({ disabled: true });
- shouldnotmove('.draggable({ disabled: true })');
+ TestHelpers.draggable.shouldNotMove(el, '.draggable({ disabled: true })');
+
el.draggable("enable");
- shouldmove('.draggable("enable")');
+ TestHelpers.draggable.shouldMove(el, '.draggable("enable")');
equal(el.draggable("option", "disabled"), false, "disabled option getter");
el.draggable("destroy");
el.draggable({ disabled: true });
- shouldnotmove('.draggable({ disabled: true })');
+ TestHelpers.draggable.shouldNotMove(el, '.draggable({ disabled: true })');
+
el.draggable("option", "disabled", false);
equal(el.draggable("option", "disabled"), false, "disabled option setter");
- shouldmove('.draggable("option", "disabled", false)');
+ TestHelpers.draggable.shouldMove(el, '.draggable("option", "disabled", false)');
- var expected = $('<div></div>').draggable(),
- actual = expected.draggable('enable');
+ expected = $('<div></div>').draggable(),
+ actual = expected.draggable('enable');
equal(actual, expected, 'enable is chainable');
});
test("disable", function() {
expect(7);
+
+ var expected, actual, el;
+
el = $("#draggable2").draggable({ disabled: false });
- shouldmove('.draggable({ disabled: false })');
+ TestHelpers.draggable.shouldMove(el, '.draggable({ disabled: false })');
+
el.draggable("disable");
- shouldnotmove('.draggable("disable")');
+ TestHelpers.draggable.shouldNotMove(el, '.draggable("disable")');
equal(el.draggable("option", "disabled"), true, "disabled option getter");
el.draggable("destroy");
el.draggable({ disabled: false });
- shouldmove('.draggable({ disabled: false })');
+ TestHelpers.draggable.shouldMove(el, '.draggable({ disabled: false })');
+
el.draggable("option", "disabled", true);
equal(el.draggable("option", "disabled"), true, "disabled option setter");
- shouldnotmove('.draggable("option", "disabled", true)');
+ TestHelpers.draggable.shouldNotMove(el, '.draggable("option", "disabled", true)');
- var expected = $('<div></div>').draggable(),
- actual = expected.draggable('disable');
+ expected = $('<div></div>').draggable(),
+ actual = expected.draggable('disable');
equal(actual, expected, 'disable is chainable');
});
diff --git a/tests/unit/draggable/draggable_options.js b/tests/unit/draggable/draggable_options.js
index ea4611d69..3f4592d31 100644
--- a/tests/unit/draggable/draggable_options.js
+++ b/tests/unit/draggable/draggable_options.js
@@ -3,203 +3,211 @@
*/
(function($) {
-function testScroll(position) {
- $("#main").css('position', position);
- drag(el, 50, 50);
- moved(50, 50, position+' parent');
-}
-
-function setScroll(what) {
- if(what) {
- $(document).scrollTop(100); $(document).scrollLeft(100);
- } else {
- $("#main")[0].scrollTop = 100; $("#main")[0].scrollLeft = 100;
- }
-}
-
-function border(el, side) {
- return parseInt(el.css('border-' + side + '-width'), 10);
-}
-function margin(el, side) {
- return parseInt(el.css('margin-' + side), 10);
-}
-
module("draggable: options");
test("{ addClasses: true }, default", function() {
- el = $("<div></div>").draggable({ addClasses: true });
+ expect( 1 );
+ var el = $("<div></div>").draggable({ addClasses: true });
ok(el.is(".ui-draggable"), "'ui-draggable' class added");
el.draggable("destroy");
});
test("{ addClasses: false }", function() {
- el = $("<div></div>").draggable({ addClasses: false });
+ expect( 1 );
+ var el = $("<div></div>").draggable({ addClasses: false });
ok(!el.is(".ui-draggable"), "'ui-draggable' class not added");
el.draggable("destroy");
});
test("{ appendTo: 'parent' }, default", function() {
- el = $("#draggable2").draggable({ appendTo: 'parent' });
- drag(el, 50, 50);
- moved(50, 50);
+ expect( 2 );
+ var el = $("#draggable2").draggable({ appendTo: 'parent' });
+ TestHelpers.draggable.shouldMove(el);
el = $("#draggable1").draggable({ appendTo: 'parent' });
- drag(el, 50, 50);
- moved(50, 50);
+ TestHelpers.draggable.shouldMove(el);
});
test("{ appendTo: Element }", function() {
- el = $("#draggable2").draggable({ appendTo: $("#draggable2").parent()[0] });
- drag(el, 50, 50);
- moved(50, 50);
+ expect( 2 );
+ var el = $("#draggable2").draggable({ appendTo: $("#draggable2").parent()[0] });
+ TestHelpers.draggable.shouldMove(el);
el = $("#draggable1").draggable({ appendTo: $("#draggable2").parent()[0] });
- drag(el, 50, 50);
- moved(50, 50);
+ TestHelpers.draggable.shouldMove(el);
});
test("{ appendTo: Selector }", function() {
- el = $("#draggable2").draggable({ appendTo: "#main" });
- drag(el, 50, 50);
- moved(50, 50);
+ expect( 2 );
+ var el = $("#draggable2").draggable({ appendTo: "#main" });
+ TestHelpers.draggable.shouldMove(el);
el = $("#draggable1").draggable({ appendTo: "#main" });
- drag(el, 50, 50);
- moved(50, 50);
+ TestHelpers.draggable.shouldMove(el);
});
test("{ axis: false }, default", function() {
- el = $("#draggable2").draggable({ axis: false });
- drag(el, 50, 50);
- moved(50, 50);
+ expect( 1 );
+ var el = $("#draggable2").draggable({ axis: false });
+ TestHelpers.draggable.shouldMove(el);
});
test("{ axis: 'x' }", function() {
- el = $("#draggable2").draggable({ axis: "x" });
- drag(el, 50, 50);
- moved(50, 0);
+ expect( 1 );
+ var el = $("#draggable2").draggable({ axis: "x" });
+ TestHelpers.draggable.testDrag(el, el, 50, 50, 50, 0);
});
test("{ axis: 'y' }", function() {
- el = $("#draggable2").draggable({ axis: "y" });
- drag(el, 50, 50);
- moved(0, 50);
+ expect( 1 );
+ var el = $("#draggable2").draggable({ axis: "y" });
+ TestHelpers.draggable.testDrag(el, el, 50, 50, 0, 50);
});
test("{ axis: ? }, unexpected", function() {
- var unexpected = {
- "true": true,
- "{}": {},
- "[]": [],
- "null": null,
- "undefined": undefined,
- "function() {}": function() {}
- };
+ var el,
+ unexpected = {
+ "true": true,
+ "{}": {},
+ "[]": [],
+ "null": null,
+ "undefined": undefined,
+ "function() {}": function() {}
+ };
+
+ expect( 6 );
+
$.each(unexpected, function(key, val) {
el = $("#draggable2").draggable({ axis: val });
- drag(el, 50, 50);
- moved(50, 50, "axis: " + key);
+ TestHelpers.draggable.testDrag(el, el, 50, 50, 50, 50, "axis: " + key);
el.draggable("destroy");
});
});
test("{ cancel: 'input,textarea,button,select,option' }, default", function() {
+ expect( 2 );
+
$('<div id="draggable-option-cancel-default"><input type="text"></div>').appendTo('#main');
- el = $("#draggable-option-cancel-default").draggable({ cancel: "input,textarea,button,select,option" });
- drag("#draggable-option-cancel-default", 50, 50);
- moved(50, 50);
+ var el = $("#draggable-option-cancel-default").draggable({ cancel: "input,textarea,button,select,option" });
+ TestHelpers.draggable.shouldMove(el);
- el = $("#draggable-option-cancel-default").draggable({ cancel: "input,textarea,button,select,option" });
- drag("#draggable-option-cancel-default input", 50, 50);
- moved(0, 0);
+ el.draggable("destroy");
+ el = $("#draggable-option-cancel-default").draggable({ cancel: "input,textarea,button,select,option" });
+ TestHelpers.draggable.testDrag(el, "#draggable-option-cancel-default input", 50, 50, 0, 0);
el.draggable("destroy");
});
test("{ cancel: 'span' }", function() {
- el = $("#draggable2").draggable();
- drag("#draggable2 span", 50, 50);
- moved(50, 50);
+ expect( 2 );
+
+ var el = $("#draggable2").draggable();
+ TestHelpers.draggable.testDrag(el, "#draggable2 span", 50, 50, 50, 50);
el.draggable("destroy");
el = $("#draggable2").draggable({ cancel: 'span' });
- drag("#draggable2 span", 50, 50);
- moved(0, 0);
+ TestHelpers.draggable.testDrag(el, "#draggable2 span", 50, 50, 0, 0);
});
test("{ cancel: ? }, unexpected", function() {
- var unexpected = {
- "true": true,
- "false": false,
- "{}": {},
- "[]": [],
- "null": null,
- "undefined": undefined,
- "function() {return '';}": function() {return '';},
- "function() {return true;}": function() {return true;},
- "function() {return false;}": function() {return false;}
- };
+ var el,
+ unexpected = {
+ "true": true,
+ "false": false,
+ "{}": {},
+ "[]": [],
+ "null": null,
+ "undefined": undefined,
+ "function() {return '';}": function() {return '';},
+ "function() {return true;}": function() {return true;},
+ "function() {return false;}": function() {return false;}
+ };
+
+ expect( 9 );
+
$.each(unexpected, function(key, val) {
el = $("#draggable2").draggable({ cancel: val });
- drag(el, 50, 50);
- var expected = [50, 50];
- moved(expected[0], expected[1], "cancel: " + key);
+ TestHelpers.draggable.shouldMove(el, "cancel: " + key);
el.draggable("destroy");
});
});
+/*
test("{ containment: false }, default", function() {
+ expect( 1 );
+
ok(false, 'missing test - untested code is broken code');
});
test("{ containment: Element }", function() {
+ expect( 1 );
+
ok(false, 'missing test - untested code is broken code');
});
+*/
test("{ containment: 'parent' }, relative", function() {
- el = $("#draggable1").draggable({ containment: 'parent' });
- var p = el.parent(),
+ expect( 1 );
+
+ var offsetAfter,
+ el = $("#draggable1").draggable({ containment: 'parent' }),
+ p = el.parent(),
po = p.offset(),
expected = {
- left: po.left + border(p, 'left') + margin(el, 'left'),
- top: po.top + border(p, 'top') + margin(el, 'top')
+ left: po.left + TestHelpers.draggable.border(p, 'left') + TestHelpers.draggable.margin(el, 'left'),
+ top: po.top + TestHelpers.draggable.border(p, 'top') + TestHelpers.draggable.margin(el, 'top')
};
- drag(el, -100, -100);
+ TestHelpers.draggable.drag(el, -100, -100);
+ offsetAfter = el.offset();
deepEqual(offsetAfter, expected, 'compare offset to parent');
});
test("{ containment: 'parent' }, absolute", function() {
- el = $("#draggable2").draggable({ containment: 'parent' });
- var p = el.parent(),
+ expect( 1 );
+
+ var offsetAfter,
+ el = $("#draggable2").draggable({ containment: 'parent' }),
+ p = el.parent(),
po = p.offset(),
expected = {
- left: po.left + border(p, 'left') + margin(el, 'left'),
- top: po.top + border(p, 'top') + margin(el, 'top')
+ left: po.left + TestHelpers.draggable.border(p, 'left') + TestHelpers.draggable.margin(el, 'left'),
+ top: po.top + TestHelpers.draggable.border(p, 'top') + TestHelpers.draggable.margin(el, 'top')
};
- drag(el, -100, -100);
+ TestHelpers.draggable.drag(el, -100, -100);
+ offsetAfter = el.offset();
deepEqual(offsetAfter, expected, 'compare offset to parent');
});
+/*
test("{ containment: 'document' }", function() {
+ expect( 1 );
+
ok(false, 'missing test - untested code is broken code');
});
test("{ containment: 'window' }", function() {
+ expect( 1 );
+
ok(false, 'missing test - untested code is broken code');
});
test("{ containment: Selector }", function() {
+ expect( 1 );
+
ok(false, 'missing test - untested code is broken code');
});
test("{ containment: [x1, y1, x2, y2] }", function() {
+ expect( 1 );
+
ok(false, 'missing test - untested code is broken code');
});
+*/
test("{ cursor: 'auto' }, default", function() {
function getCursor() { return $("#draggable2").css("cursor"); }
@@ -208,15 +216,15 @@ test("{ cursor: 'auto' }, default", function() {
var expected = "auto", actual, before, after;
- el = $("#draggable2").draggable({
+ $("#draggable2").draggable({
cursor: expected,
- start: function(event, ui) {
+ start: function() {
actual = getCursor();
}
});
before = getCursor();
- drag("#draggable2", -1, -1);
+ TestHelpers.draggable.drag("#draggable2", -1, -1);
after = getCursor();
equal(actual, expected, "start callback: cursor '" + expected + "'");
@@ -232,15 +240,15 @@ test("{ cursor: 'move' }", function() {
var expected = "move", actual, before, after;
- el = $("#draggable2").draggable({
+ $("#draggable2").draggable({
cursor: expected,
- start: function(event, ui) {
+ start: function() {
actual = getCursor();
}
});
before = getCursor();
- drag("#draggable2", -1, -1);
+ TestHelpers.draggable.drag("#draggable2", -1, -1);
after = getCursor();
equal(actual, expected, "start callback: cursor '" + expected + "'");
@@ -248,9 +256,13 @@ test("{ cursor: 'move' }", function() {
});
+/*
test("{ cursorAt: false}, default", function() {
+ expect( 1 );
+
ok(false, 'missing test - untested code is broken code');
});
+*/
test("{ cursorAt: { left: -5, top: -5 } }", function() {
expect(4);
@@ -260,23 +272,26 @@ test("{ cursorAt: { left: -5, top: -5 } }", function() {
cursorAtX = -5, cursorAtY = -5;
$.each(['relative', 'absolute'], function(i, position) {
- var el = $('#draggable' + (i + 1)).draggable({
- cursorAt: { left: cursorAtX, top: cursorAtY },
- drag: function(event, ui) {
- equal(ui.offset.left, expected.left, position + ' left');
- equal(ui.offset.top, expected.top, position + ' top');
- }
- }),
- before = el.offset(),
- pos = {
- clientX: before.left + offsetX,
- clientY: before.top + offsetY
- },
- expected = {
- left: before.left + offsetX - cursorAtX + deltaX,
- top: before.top + offsetY - cursorAtY + deltaY
- };
+ var before, pos, expected,
+ el = $('#draggable' + (i + 1)).draggable({
+ cursorAt: { left: cursorAtX, top: cursorAtY },
+ drag: function(event, ui) {
+ equal(ui.offset.left, expected.left, position + ' left');
+ equal(ui.offset.top, expected.top, position + ' top');
+ }
+ });
+
+ before = el.offset();
+ pos = {
+ clientX: before.left + offsetX,
+ clientY: before.top + offsetY
+ };
+ expected = {
+ left: before.left + offsetX - cursorAtX + deltaX - TestHelpers.draggable.unreliableOffset,
+ top: before.top + offsetY - cursorAtY + deltaY - TestHelpers.draggable.unreliableOffset
+ };
+ // todo: replace this with simulated drag event
el.simulate("mousedown", pos);
pos.clientX += deltaX;
pos.clientY += deltaY;
@@ -293,23 +308,25 @@ test("{ cursorAt: { right: 10, bottom: 20 } }", function() {
cursorAtX = 10, cursorAtY = 20;
$.each(['relative', 'absolute'], function(i, position) {
- var el = $('#draggable' + (i + 1)).draggable({
+ var before, pos, expected,
+ el = $('#draggable' + (i + 1)).draggable({
cursorAt: { right: cursorAtX, bottom: cursorAtY },
drag: function(event, ui) {
equal(ui.offset.left, expected.left, position + ' left');
equal(ui.offset.top, expected.top, position + ' top');
}
- }),
- before = el.offset(),
- pos = {
- clientX: before.left + offsetX,
- clientY: before.top + offsetY
- },
- expected = {
- left: before.left + offsetX - el.width() + cursorAtX + deltaX,
- top: before.top + offsetY - el.height() + cursorAtY + deltaY
- };
+ });
+ before = el.offset();
+ pos = {
+ clientX: before.left + offsetX,
+ clientY: before.top + offsetY
+ };
+ expected = {
+ left: before.left + offsetX - el.width() + cursorAtX + deltaX - TestHelpers.draggable.unreliableOffset,
+ top: before.top + offsetY - el.height() + cursorAtY + deltaY - TestHelpers.draggable.unreliableOffset
+ };
+ // todo: replace this with simulated drag event
el.simulate("mousedown", pos);
pos.clientX += deltaX;
pos.clientY += deltaY;
@@ -326,23 +343,26 @@ test("{ cursorAt: [10, 20] }", function() {
cursorAtX = 10, cursorAtY = 20;
$.each(['relative', 'absolute'], function(i, position) {
- var el = $('#draggable' + (i + 1)).draggable({
+ var before, pos, expected,
+ el = $('#draggable' + (i + 1)).draggable({
cursorAt: { left: cursorAtX, top: cursorAtY },
drag: function(event, ui) {
equal(ui.offset.left, expected.left, position + ' left');
equal(ui.offset.top, expected.top, position + ' top');
}
- }),
- before = el.offset(),
- pos = {
- clientX: before.left + offsetX,
- clientY: before.top + offsetY
- },
- expected = {
- left: before.left + offsetX - cursorAtX + deltaX,
- top: before.top + offsetY - cursorAtY + deltaY
- };
+ });
+ before = el.offset();
+ pos = {
+ clientX: before.left + offsetX,
+ clientY: before.top + offsetY
+ };
+ expected = {
+ left: before.left + offsetX - cursorAtX + deltaX - TestHelpers.draggable.unreliableOffset,
+ top: before.top + offsetY - cursorAtY + deltaY - TestHelpers.draggable.unreliableOffset
+ };
+
+ // todo: replace this with simulated drag event
el.simulate("mousedown", pos);
pos.clientX += deltaX;
pos.clientY += deltaY;
@@ -359,23 +379,26 @@ test("{ cursorAt: '20, 40' }", function() {
cursorAtX = 20, cursorAtY = 40;
$.each(['relative', 'absolute'], function(i, position) {
- var el = $('#draggable' + (i + 1)).draggable({
+ var before, pos, expected,
+ el = $('#draggable' + (i + 1)).draggable({
cursorAt: { left: cursorAtX, top: cursorAtY },
drag: function(event, ui) {
equal(ui.offset.left, expected.left, position + ' left');
equal(ui.offset.top, expected.top, position + ' top');
}
- }),
- before = el.offset(),
- pos = {
- clientX: before.left + offsetX,
- clientY: before.top + offsetY
- },
- expected = {
- left: before.left + offsetX - cursorAtX + deltaX,
- top: before.top + offsetY - cursorAtY + deltaY
- };
+ });
+ before = el.offset();
+ pos = {
+ clientX: before.left + offsetX,
+ clientY: before.top + offsetY
+ };
+ expected = {
+ left: before.left + offsetX - cursorAtX + deltaX - TestHelpers.draggable.unreliableOffset,
+ top: before.top + offsetY - cursorAtY + deltaY - TestHelpers.draggable.unreliableOffset
+ };
+
+ // todo: replace this with simulated drag event
el.simulate("mousedown", pos);
pos.clientX += deltaX;
pos.clientY += deltaY;
@@ -385,321 +408,341 @@ test("{ cursorAt: '20, 40' }", function() {
});
test("{ distance: 10 }", function() {
+ expect( 3 );
- el = $("#draggable2").draggable({ distance: 10 });
- drag(el, -9, -9);
- moved(0, 0, 'distance not met');
+ var el = $("#draggable2").draggable({ distance: 10 });
+ TestHelpers.draggable.testDrag(el, el, -9, -9, 0, 0, 'distance not met');
- drag(el, -10, -10);
- moved(-10, -10, 'distance met');
+ TestHelpers.draggable.testDrag(el, el, -10, -10, -10, -10, 'distance met');
- drag(el, 9, 9);
- moved(0, 0, 'distance not met');
+ TestHelpers.draggable.testDrag(el, el, 9, 9, 0, 0, 'distance not met');
});
test("{ grid: [50, 50] }, relative", function() {
- el = $("#draggable1").draggable({ grid: [50, 50] });
- drag(el, 24, 24);
- moved(0, 0);
- drag(el, 26, 25);
- moved(50, 50);
+ expect( 2 );
+
+ var el = $("#draggable1").draggable({ grid: [50, 50] });
+ TestHelpers.draggable.testDrag(el, el, 24, 24, 0, 0);
+ TestHelpers.draggable.testDrag(el, el, 26, 25, 50, 50);
});
test("{ grid: [50, 50] }, absolute", function() {
- el = $("#draggable2").draggable({ grid: [50, 50] });
- drag(el, 24, 24);
- moved(0, 0);
- drag(el, 26, 25);
- moved(50, 50);
+ expect( 2 );
+
+ var el = $("#draggable2").draggable({ grid: [50, 50] });
+ TestHelpers.draggable.testDrag(el, el, 24, 24, 0, 0);
+ TestHelpers.draggable.testDrag(el, el, 26, 25, 50, 50);
});
test("{ handle: 'span' }", function() {
- el = $("#draggable2").draggable({ handle: 'span' });
+ expect( 2 );
- drag("#draggable2 span", 50, 50);
- moved(50, 50, "drag span");
+ var el = $("#draggable2").draggable({ handle: 'span' });
- drag("#draggable2", 50, 50);
- moved(0, 0, "drag element");
+ TestHelpers.draggable.testDrag(el, "#draggable2 span", 50, 50, 50, 50, "drag span");
+ TestHelpers.draggable.shouldNotMove(el, "drag element");
});
test("{ helper: 'clone' }, relative", function() {
- el = $("#draggable1").draggable({ helper: "clone" });
- drag(el, 50, 50);
- moved(0, 0);
+ expect( 1 );
+
+ var el = $("#draggable1").draggable({ helper: "clone" });
+ TestHelpers.draggable.shouldNotMove(el);
});
test("{ helper: 'clone' }, absolute", function() {
- el = $("#draggable2").draggable({ helper: "clone" });
- drag(el, 50, 50);
- moved(0, 0);
+ expect( 1 );
+
+ var el = $("#draggable2").draggable({ helper: "clone" });
+ TestHelpers.draggable.shouldNotMove(el);
});
test("{ helper: 'original' }, relative, with scroll offset on parent", function() {
+ expect( 3 );
- el = $("#draggable1").draggable({ helper: "original" });
+ var el = $("#draggable1").draggable({ helper: "original" });
- setScroll();
- testScroll('relative');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.testScroll(el, 'relative');
- setScroll();
- testScroll('static');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.testScroll(el, 'static');
- setScroll();
- testScroll('absolute');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.testScroll(el, 'absolute');
- restoreScroll();
+ TestHelpers.draggable.restoreScroll();
});
test("{ helper: 'original' }, relative, with scroll offset on root", function() {
+ expect( 3 );
- el = $("#draggable1").draggable({ helper: "original" });
+ var el = $("#draggable1").draggable({ helper: "original" });
- setScroll('root');
- testScroll('relative');
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'relative');
- setScroll('root');
- testScroll('static');
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'static');
- setScroll('root');
- testScroll('absolute');
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'absolute');
- restoreScroll('root');
+ TestHelpers.draggable.restoreScroll('root');
});
test("{ helper: 'original' }, relative, with scroll offset on root and parent", function() {
- el = $("#draggable1").draggable({ helper: "original" });
+ expect(3);
+
+ var el = $("#draggable1").draggable({ helper: "original" });
- setScroll();
- setScroll('root');
- testScroll('relative');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'relative');
- setScroll();
- setScroll('root');
- testScroll('static');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'static');
- setScroll();
- setScroll('root');
- testScroll('absolute');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'absolute');
- restoreScroll();
- restoreScroll('root');
+ TestHelpers.draggable.restoreScroll();
+ TestHelpers.draggable.restoreScroll('root');
});
test("{ helper: 'original' }, absolute, with scroll offset on parent", function() {
- el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });
+ expect(3);
- setScroll();
- testScroll('relative');
+ var el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });
- setScroll();
- testScroll('static');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.testScroll(el, 'relative');
- setScroll();
- testScroll('absolute');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.testScroll(el, 'static');
- restoreScroll();
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.testScroll(el, 'absolute');
+
+ TestHelpers.draggable.restoreScroll();
});
test("{ helper: 'original' }, absolute, with scroll offset on root", function() {
- el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });
+ expect(3);
+
+ var el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });
- setScroll('root');
- testScroll('relative');
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'relative');
- setScroll('root');
- testScroll('static');
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'static');
- setScroll('root');
- testScroll('absolute');
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'absolute');
- restoreScroll('root');
+ TestHelpers.draggable.restoreScroll('root');
});
test("{ helper: 'original' }, absolute, with scroll offset on root and parent", function() {
- el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });
+ expect(3);
- setScroll();
- setScroll('root');
- testScroll('relative');
+ var el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });
- setScroll();
- setScroll('root');
- testScroll('static');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'relative');
- setScroll();
- setScroll('root');
- testScroll('absolute');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'static');
- restoreScroll();
- restoreScroll('root');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'absolute');
+
+ TestHelpers.draggable.restoreScroll();
+ TestHelpers.draggable.restoreScroll('root');
});
test("{ helper: 'original' }, fixed, with scroll offset on parent", function() {
- el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });
+ expect(3);
+
+ var el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });
- setScroll();
- testScroll('relative');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.testScroll(el, 'relative');
- setScroll();
- testScroll('static');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.testScroll(el, 'static');
- setScroll();
- testScroll('absolute');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.testScroll(el, 'absolute');
- restoreScroll();
+ TestHelpers.draggable.restoreScroll();
});
test("{ helper: 'original' }, fixed, with scroll offset on root", function() {
- el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });
+ expect(3);
- setScroll('root');
- testScroll('relative');
+ var el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });
- setScroll('root');
- testScroll('static');
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'relative');
- setScroll('root');
- testScroll('absolute');
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'static');
- restoreScroll('root');
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'absolute');
+
+ TestHelpers.draggable.restoreScroll('root');
});
test("{ helper: 'original' }, fixed, with scroll offset on root and parent", function() {
- el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });
+ expect(3);
+
+ var el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });
- setScroll();
- setScroll('root');
- testScroll('relative');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'relative');
- setScroll();
- setScroll('root');
- testScroll('static');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'static');
- setScroll();
- setScroll('root');
- testScroll('absolute');
+ TestHelpers.draggable.setScroll();
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.testScroll(el, 'absolute');
- restoreScroll();
- restoreScroll('root');
+ TestHelpers.draggable.restoreScroll();
+ TestHelpers.draggable.restoreScroll('root');
});
test("{ helper: 'clone' }, absolute", function() {
- var helperOffset = null,
- origOffset = $("#draggable1").offset();
+ expect(1);
- el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
- helperOffset = ui.helper.offset();
- } });
+ var helperOffset = null,
+ origOffset = $("#draggable1").offset(),
+ el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
+ helperOffset = ui.helper.offset();
+ } });
- drag(el, 1, 1);
- deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+ TestHelpers.draggable.drag(el, 1, 1);
+ deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[1, 1] ');
});
test("{ helper: 'clone' }, absolute with scroll offset on parent", function() {
- setScroll();
- var helperOffset = null,
- origOffset = null;
+ expect(3);
- el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
- helperOffset = ui.helper.offset();
- } });
+ TestHelpers.draggable.setScroll();
+ var helperOffset = null,
+ origOffset = null,
+ el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
+ helperOffset = ui.helper.offset();
+ } });
$("#main").css('position', 'relative');
origOffset = $("#draggable1").offset();
- drag(el, 1, 1);
- deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+ TestHelpers.draggable.drag(el, 1, 1);
+ deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[1, 1] ');
$("#main").css('position', 'static');
origOffset = $("#draggable1").offset();
- drag(el, 1, 1);
- deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+ TestHelpers.draggable.drag(el, 1, 1);
+ deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[1, 1] ');
$("#main").css('position', 'absolute');
origOffset = $("#draggable1").offset();
- drag(el, 1, 1);
- deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+ TestHelpers.draggable.drag(el, 1, 1);
+ deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[1, 1] ');
- restoreScroll();
+ TestHelpers.draggable.restoreScroll();
});
test("{ helper: 'clone' }, absolute with scroll offset on root", function() {
- setScroll('root');
- var helperOffset = null,
- origOffset = null;
+ expect(3);
- el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
- helperOffset = ui.helper.offset();
- } });
+ TestHelpers.draggable.setScroll('root');
+ var helperOffset = null,
+ origOffset = null,
+ el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
+ helperOffset = ui.helper.offset();
+ } });
$("#main").css('position', 'relative');
origOffset = $("#draggable1").offset();
- drag(el, 1, 1);
- deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+ TestHelpers.draggable.drag(el, 1, 1);
+ deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[1, 1] ');
$("#main").css('position', 'static');
origOffset = $("#draggable1").offset();
- drag(el, 1, 1);
- deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+ TestHelpers.draggable.drag(el, 1, 1);
+ deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[1, 1] ');
$("#main").css('position', 'absolute');
origOffset = $("#draggable1").offset();
- drag(el, 1, 1);
- deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+ TestHelpers.draggable.drag(el, 1, 1);
+ deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[1, 1] ');
- restoreScroll('root');
+ TestHelpers.draggable.restoreScroll('root');
});
test("{ helper: 'clone' }, absolute with scroll offset on root and parent", function() {
- setScroll('root');
- setScroll();
- var helperOffset = null,
- origOffset = null;
+ expect(3);
- el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
- helperOffset = ui.helper.offset();
- } });
+ TestHelpers.draggable.setScroll('root');
+ TestHelpers.draggable.setScroll();
+
+ var helperOffset = null,
+ origOffset = null,
+ el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
+ helperOffset = ui.helper.offset();
+ } });
$("#main").css('position', 'relative');
origOffset = $("#draggable1").offset();
- drag(el, 1, 1);
- deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+ TestHelpers.draggable.drag(el, 1, 1);
+ deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[1, 1] ');
$("#main").css('position', 'static');
origOffset = $("#draggable1").offset();
- drag(el, 1, 1);
- deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+ TestHelpers.draggable.drag(el, 1, 1);
+ deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[1, 1] ');
$("#main").css('position', 'absolute');
origOffset = $("#draggable1").offset();
- drag(el, 1, 1);
- deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+ TestHelpers.draggable.drag(el, 1, 1);
+ deepEqual({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[1, 1] ');
- restoreScroll('root');
- restoreScroll();
+ TestHelpers.draggable.restoreScroll('root');
+ TestHelpers.draggable.restoreScroll();
});
@@ -708,14 +751,15 @@ test("{ opacity: 0.5 }", function() {
expect(1);
var opacity = null;
- el = $("#draggable2").draggable({
+
+ $("#draggable2").draggable({
opacity: 0.5,
- start: function(event, ui) {
+ start: function() {
opacity = $(this).css("opacity");
}
});
- drag("#draggable2", -1, -1);
+ TestHelpers.draggable.drag("#draggable2", -1, -1);
equal(opacity, 0.5, "start callback: opacity is");
@@ -726,16 +770,16 @@ test("{ zIndex: 10 }", function() {
expect(1);
var actual,
- expected = 10,
- zIndex = null;
- el = $("#draggable2").draggable({
+ expected = 10;
+
+ $("#draggable2").draggable({
zIndex: expected,
- start: function(event, ui) {
+ start: function() {
actual = $(this).css("zIndex");
}
});
- drag("#draggable2", -1, -1);
+ TestHelpers.draggable.drag("#draggable2", -1, -1);
equal(actual, expected, "start callback: zIndex is");
diff --git a/tests/unit/draggable/draggable_test_helpers.js b/tests/unit/draggable/draggable_test_helpers.js
new file mode 100644
index 000000000..7057df1f8
--- /dev/null
+++ b/tests/unit/draggable/draggable_test_helpers.js
@@ -0,0 +1,57 @@
+TestHelpers.draggable = {
+ // todo: remove the unreliable offset hacks
+ unreliableOffset: $.ui.ie && ( !document.documentMode || document.documentMode < 8 ) ? 2 : 0,
+ drag: function(handle, dx, dy) {
+ $(handle).simulate("drag", {
+ dx: dx || 0,
+ dy: dy || 0
+ });
+ },
+ testDrag: function(el, handle, dx, dy, expectedDX, expectedDY, msg) {
+ var offsetAfter, actual, expected,
+ offsetBefore = el.offset();
+
+ TestHelpers.draggable.drag(handle, dx, dy);
+ offsetAfter = el.offset();
+
+ actual = { left: offsetAfter.left, top: offsetAfter.top },
+ expected = { left: offsetBefore.left + expectedDX, top: offsetBefore.top + expectedDY };
+
+ msg = msg ? msg + "." : "";
+ deepEqual(actual, expected, 'dragged[' + dx + ', ' + dy + '] ' + msg);
+ },
+ shouldMove: function(el, why) {
+ TestHelpers.draggable.testDrag(el, el, 50, 50, 50, 50, why);
+ },
+ shouldNotMove: function(el, why) {
+ TestHelpers.draggable.testDrag(el, el, 50, 50, 0, 0, why);
+ },
+ testScroll: function(el, position ) {
+ var oldPosition = $("#main").css('position');
+ $("#main").css('position', position);
+ TestHelpers.draggable.shouldMove(el, position+' parent');
+ $("#main").css('position', oldPosition);
+ },
+ restoreScroll: function( what ) {
+ if( what ) {
+ $(document).scrollTop(0); $(document).scrollLeft(0);
+ } else {
+ $("#main").scrollTop(0); $("#main").scrollLeft(0);
+ }
+ },
+ setScroll: function( what ) {
+ if(what) {
+ // todo: currently, the draggable interaction doesn't properly account for scrolled pages,
+ // uncomment the line below to make the tests fail that should when the page is scrolled
+ // $(document).scrollTop(100); $(document).scrollLeft(100);
+ } else {
+ $("#main").scrollTop(100); $("#main").scrollLeft(100);
+ }
+ },
+ border: function(el, side) {
+ return parseInt(el.css('border-' + side + '-width'), 10) || 0;
+ },
+ margin: function(el, side) {
+ return parseInt(el.css('margin-' + side), 10) || 0;
+ }
+}; \ No newline at end of file
diff --git a/tests/unit/droppable/droppable.html b/tests/unit/droppable/droppable.html
index 49ebf6beb..7cd5eb0f5 100644
--- a/tests/unit/droppable/droppable.html
+++ b/tests/unit/droppable/droppable.html
@@ -27,17 +27,8 @@
<script src="droppable_events.js"></script>
<script src="droppable_methods.js"></script>
<script src="droppable_options.js"></script>
+ <script src="droppable_test_helpers.js"></script>
- <script>
- // disable this stale testsuite for testswarm only
- var url = window.location.search;
- url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) );
- if ( url && url.indexOf("http") == 0 ) {
- // reset config to kill previous tests; make sure testsuite.js is loaded afterwards to init the testswarm script
- QUnit.init();
- test("droppable", function() { ok(true, "disabled droppable testsuite"); });
- }
- </script>
<script src="../swarminject.js"></script>
</head>
<body>
diff --git a/tests/unit/droppable/droppable_common.js b/tests/unit/droppable/droppable_common.js
index 985dba06d..d86afe3dd 100644
--- a/tests/unit/droppable/droppable_common.js
+++ b/tests/unit/droppable/droppable_common.js
@@ -3,6 +3,7 @@ TestHelpers.commonWidgetTests( "droppable", {
accept: "*",
activeClass: false,
addClasses: true,
+ create: null,
disabled: false,
greedy: false,
hoverClass: false,
diff --git a/tests/unit/droppable/droppable_core.js b/tests/unit/droppable/droppable_core.js
index 3f709d25d..c98850a03 100644
--- a/tests/unit/droppable/droppable_core.js
+++ b/tests/unit/droppable/droppable_core.js
@@ -2,16 +2,6 @@
* droppable_core.js
*/
-var el, drg;
-
-function shouldBeDroppable() {
- ok(false, 'missing test - untested code is broken code');
-}
-
-function shouldNotBeDroppable() {
- ok(false, 'missing test - untested code is broken code');
-}
-
(function($) {
module("droppable: core");
@@ -19,15 +9,18 @@ module("droppable: core");
test("element types", function() {
var typeNames = ('p,h1,h2,h3,h4,h5,h6,blockquote,ol,ul,dl,div,form' +
',table,fieldset,address,ins,del,em,strong,q,cite,dfn,abbr' +
- ',acronym,code,samp,kbd,var,img,object,hr' +
+ ',acronym,code,samp,kbd,var,img,hr' +
',input,button,label,select,iframe').split(',');
+ expect( typeNames.length );
+
$.each(typeNames, function(i) {
- var typeName = typeNames[i];
- el = $(document.createElement(typeName)).appendTo('body');
+ var typeName = typeNames[i],
+ el = $(document.createElement(typeName)).appendTo('body');
+
(typeName === 'table' && el.append("<tr><td>content</td></tr>"));
el.droppable();
- shouldBeDroppable();
+ TestHelpers.droppable.shouldDrop();
el.droppable("destroy");
el.remove();
});
diff --git a/tests/unit/droppable/droppable_events.js b/tests/unit/droppable/droppable_events.js
index f22a03540..8f842e942 100644
--- a/tests/unit/droppable/droppable_events.js
+++ b/tests/unit/droppable/droppable_events.js
@@ -5,6 +5,12 @@
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
+/*
test("activate", function() {
ok(false, 'missing test - untested code is broken code');
});
@@ -24,5 +30,6 @@ test("out", function() {
test("drop", function() {
ok(false, 'missing test - untested code is broken code');
});
+*/
})(jQuery);
diff --git a/tests/unit/droppable/droppable_methods.js b/tests/unit/droppable/droppable_methods.js
index 8fd49d265..76501c5b1 100644
--- a/tests/unit/droppable/droppable_methods.js
+++ b/tests/unit/droppable/droppable_methods.js
@@ -6,7 +6,7 @@
module("droppable: methods");
test("init", function() {
- expect(6);
+ expect( 5 );
$("<div></div>").appendTo('body').droppable().remove();
ok(true, '.droppable() called on element');
@@ -17,9 +17,6 @@ test("init", function() {
$("<div></div>").droppable();
ok(true, '.droppable() called on disconnected DOMElement');
- $("<div></div>").droppable().droppable("foo");
- ok(true, 'arbitrary method called after init');
-
$("<div></div>").droppable().droppable("option", "foo");
ok(true, 'arbitrary option getter after init');
@@ -28,6 +25,8 @@ test("init", function() {
});
test("destroy", function() {
+ expect( 4 );
+
$("<div></div>").appendTo('body').droppable().droppable("destroy").remove();
ok(true, '.droppable("destroy") called on element');
@@ -37,9 +36,6 @@ test("destroy", function() {
$("<div></div>").droppable().droppable("destroy");
ok(true, '.droppable("destroy") called on disconnected DOMElement');
- $("<div></div>").droppable().droppable("destroy").droppable("foo");
- ok(true, 'arbitrary method called after destroy');
-
var expected = $('<div></div>').droppable(),
actual = expected.droppable('destroy');
equal(actual, expected, 'destroy is chainable');
@@ -47,39 +43,45 @@ test("destroy", function() {
test("enable", function() {
expect(7);
+
+ var el, expected, actual;
+
el = $("#droppable1").droppable({ disabled: true });
- shouldNotBeDroppable();
+ TestHelpers.droppable.shouldNotDrop();
el.droppable("enable");
- shouldBeDroppable();
+ TestHelpers.droppable.shouldDrop();
equal(el.droppable("option", "disabled"), false, "disabled option getter");
el.droppable("destroy");
el.droppable({ disabled: true });
- shouldNotBeDroppable();
+ TestHelpers.droppable.shouldNotDrop();
el.droppable("option", "disabled", false);
equal(el.droppable("option", "disabled"), false, "disabled option setter");
- shouldBeDroppable();
+ TestHelpers.droppable.shouldDrop();
- var expected = $('<div></div>').droppable(),
- actual = expected.droppable('enable');
+ expected = $('<div></div>').droppable(),
+ actual = expected.droppable('enable');
equal(actual, expected, 'enable is chainable');
});
test("disable", function() {
expect(7);
+
+ var el, actual, expected;
+
el = $("#droppable1").droppable({ disabled: false });
- shouldBeDroppable();
+ TestHelpers.droppable.shouldDrop();
el.droppable("disable");
- shouldNotBeDroppable();
+ TestHelpers.droppable.shouldNotDrop();
equal(el.droppable("option", "disabled"), true, "disabled option getter");
el.droppable("destroy");
el.droppable({ disabled: false });
- shouldBeDroppable();
+ TestHelpers.droppable.shouldDrop();
el.droppable("option", "disabled", true);
equal(el.droppable("option", "disabled"), true, "disabled option setter");
- shouldNotBeDroppable();
+ TestHelpers.droppable.shouldNotDrop();
- var expected = $('<div></div>').droppable(),
- actual = expected.droppable('disable');
+ expected = $('<div></div>').droppable(),
+ actual = expected.droppable('disable');
equal(actual, expected, 'disable is chainable');
});
diff --git a/tests/unit/droppable/droppable_options.js b/tests/unit/droppable/droppable_options.js
index 19295778b..c2ecdcfda 100644
--- a/tests/unit/droppable/droppable_options.js
+++ b/tests/unit/droppable/droppable_options.js
@@ -5,6 +5,7 @@
module("droppable: options");
+/*
test("{ accept '*' }, default ", function() {
ok(false, 'missing test - untested code is broken code');
});
@@ -20,19 +21,21 @@ test("{ accept: function(draggable) }", function() {
test("activeClass", function() {
ok(false, 'missing test - untested code is broken code');
});
-
+*/
test("{ addClasses: true }, default", function() {
- el = $("<div></div>").droppable({ addClasses: true });
+ expect( 1 );
+ var el = $("<div></div>").droppable({ addClasses: true });
ok(el.is(".ui-droppable"), "'ui-droppable' class added");
el.droppable("destroy");
});
test("{ addClasses: false }", function() {
- el = $("<div></div>").droppable({ addClasses: false });
+ expect( 1 );
+ var el = $("<div></div>").droppable({ addClasses: false });
ok(!el.is(".ui-droppable"), "'ui-droppable' class not added");
el.droppable("destroy");
});
-
+/*
test("greedy", function() {
ok(false, 'missing test - untested code is broken code');
});
@@ -60,5 +63,5 @@ test("tolerance, pointer", function() {
test("tolerance, touch", function() {
ok(false, 'missing test - untested code is broken code');
});
-
+*/
})(jQuery);
diff --git a/tests/unit/droppable/droppable_test_helpers.js b/tests/unit/droppable/droppable_test_helpers.js
new file mode 100644
index 000000000..79311788c
--- /dev/null
+++ b/tests/unit/droppable/droppable_test_helpers.js
@@ -0,0 +1,10 @@
+TestHelpers.droppable = {
+ shouldDrop: function() {
+ // todo: actually implement this
+ ok(true, 'missing test - untested code is broken code');
+ },
+ shouldNotDrop: function() {
+ // todo: actually implement this
+ ok(true, 'missing test - untested code is broken code');
+ }
+}; \ No newline at end of file
diff --git a/tests/unit/effects/effects.html b/tests/unit/effects/effects.html
index 9305fcd21..c283eabff 100644
--- a/tests/unit/effects/effects.html
+++ b/tests/unit/effects/effects.html
@@ -5,9 +5,6 @@
<title>jQuery UI Effects Test Suite</title>
<script src="../../jquery.js"></script>
- <script>
- $.uiBackCompat = false;
- </script>
<link rel="stylesheet" href="../../../external/qunit.css">
<script src="../../../external/qunit.js"></script>
<script src="../../jquery.simulate.js"></script>
diff --git a/tests/unit/effects/effects_core.js b/tests/unit/effects/effects_core.js
index 9b4787a57..26390b7d3 100644
--- a/tests/unit/effects/effects_core.js
+++ b/tests/unit/effects/effects_core.js
@@ -12,10 +12,7 @@ function notPresent( value, array, message ) {
var minDuration = 15,
// duration is used for "long" animates where we plan on testing properties during animation
- duration = 200,
-
- // mid is used for testing in the "middle" of the "duration" animations
- mid = duration / 2;
+ duration = 200;
module( "effects.core" );
@@ -31,6 +28,17 @@ test( "Immediate Return Conditions", function() {
equal( ++count, 3, "Both Functions worked properly" );
});
+asyncTest( "Parse of null for options", function() {
+ var hidden = $( "div.hidden" ),
+ count = 0;
+ expect( 1 );
+ hidden.show( "blind", null, 1, function() {
+ equal( ++count, 1, "null for options still works" );
+ start();
+ });
+});
+
+
/* TODO: Disabled - Can't figure out why this is failing in IE 6/7
test( "createWrapper and removeWrapper retain focused elements (#7595)", function() {
expect( 2 );
@@ -47,8 +55,7 @@ test( "createWrapper and removeWrapper retain focused elements (#7595)", functio
module( "effects.core: animateClass" );
asyncTest( "animateClass works with borderStyle", function() {
- var test = $("div.animateClass"),
- count = 0;
+ var test = $("div.animateClass");
expect(3);
test.toggleClass("testAddBorder", minDuration, function() {
test.toggleClass("testAddBorder", minDuration, function() {
@@ -62,8 +69,8 @@ asyncTest( "animateClass works with borderStyle", function() {
asyncTest( "animateClass works with colors", function() {
var test = $("div.animateClass"),
- count = 0,
oldStep = jQuery.fx.step.backgroundColor;
+
expect(2);
// we want to catch the first frame of animation
@@ -91,7 +98,7 @@ asyncTest( "animateClass works with colors", function() {
asyncTest( "animateClass calls step option", 1, function() {
var test = jQuery( "div.animateClass" ),
- step = function( fx ) {
+ step = function() {
ok( true, "Step Function Called" );
test.stop();
start();
@@ -205,7 +212,7 @@ $.each( $.effects.effect, function( effect ) {
equal( hidden.css("display"), "block", "Hidden is shown after .show(\"" +effect+ "\", time)" );
})).queue( queueTest() ).hide( effect, minDuration, queueTest(function() {
equal( hidden.css("display"), "none", "Back to hidden after .hide(\"" +effect+ "\", time)" );
- })).queue( queueTest(function(next) {
+ })).queue( queueTest(function() {
deepEqual( hidden.queue(), ["inprogress"], "Only the inprogress sentinel remains");
start();
}));
diff --git a/tests/unit/menu/menu_events.js b/tests/unit/menu/menu_events.js
index d69fc46a3..a94968138 100644
--- a/tests/unit/menu/menu_events.js
+++ b/tests/unit/menu/menu_events.js
@@ -13,7 +13,7 @@ module( "menu: events", {
test( "handle click on menu", function() {
expect( 1 );
var element = $( "#menu1" ).menu({
- select: function( event, ui ) {
+ select: function() {
log();
}
});
@@ -29,7 +29,7 @@ test( "handle click on menu", function() {
test( "handle click on custom item menu", function() {
expect( 1 );
var element = $( "#menu5" ).menu({
- select: function( event, ui ) {
+ select: function() {
log();
},
menus: "div"
@@ -47,7 +47,7 @@ asyncTest( "handle blur", function() {
expect( 1 );
var blurHandled = false,
element = $( "#menu1" ).menu({
- blur: function( event, ui ) {
+ blur: function( event ) {
// Ignore duplicate blur event fired by IE
if ( !blurHandled ) {
blurHandled = true;
@@ -69,7 +69,7 @@ asyncTest( "handle blur via click outside", function() {
expect( 1 );
var blurHandled = false,
element = $( "#menu1" ).menu({
- blur: function( event, ui ) {
+ blur: function( event ) {
// Ignore duplicate blur event fired by IE
if ( !blurHandled ) {
blurHandled = true;
@@ -90,7 +90,7 @@ asyncTest( "handle blur via click outside", function() {
test( "handle focus of menu with active item", function() {
expect( 1 );
var element = $( "#menu1" ).menu({
- focus: function( event, ui ) {
+ focus: function( event ) {
log( $( event.target ).find( ".ui-state-focus" ).parent().index() );
}
});
@@ -168,7 +168,7 @@ test( "handle keyboard navigation on menu without scroll and without submenus",
select: function( event, ui ) {
log( $( ui.item[0] ).text() );
},
- focus: function( event, ui ) {
+ focus: function( event ) {
log( $( event.target ).find( ".ui-state-focus" ).parent().index() );
}
});
@@ -230,13 +230,13 @@ asyncTest( "handle keyboard navigation on menu without scroll and with submenus"
select: function( event, ui ) {
log( $( ui.item[0] ).text() );
},
- focus: function( event, ui ) {
+ focus: function( event ) {
log( $( event.target ).find( ".ui-state-focus" ).parent().index() );
}
});
log( "keydown", true );
- element.one( "menufocus", function( event, ui ) {
+ element.one( "menufocus", function() {
element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
equal( logOutput(), "keydown,1,2", "Keydown DOWN" );
@@ -350,7 +350,7 @@ test( "handle keyboard navigation on menu with scroll and without submenus", fun
select: function( event, ui ) {
log( $( ui.item[0] ).text() );
},
- focus: function( event, ui ) {
+ focus: function( event ) {
log( $( event.target ).find( ".ui-state-focus" ).parent().index());
}
});
@@ -421,13 +421,13 @@ asyncTest( "handle keyboard navigation on menu with scroll and with submenus", f
select: function( event, ui ) {
log( $( ui.item[0] ).text() );
},
- focus: function( event, ui ) {
+ focus: function( event ) {
log( $( event.target ).find( ".ui-state-focus" ).parent().index());
}
});
log( "keydown", true );
- element.one( "menufocus", function( event, ui ) {
+ element.one( "menufocus", function() {
element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
equal( logOutput(), "keydown,1,2", "Keydown DOWN" );
@@ -516,13 +516,13 @@ asyncTest( "handle keyboard navigation and mouse click on menu with disabled ite
select: function( event, ui ) {
log( $( ui.item[0] ).text() );
},
- focus: function( event, ui ) {
+ focus: function( event ) {
log( $( event.target ).find( ".ui-state-focus" ).parent().index());
}
});
log( "keydown", true );
- element.one( "menufocus", function( event, ui ) {
+ element.one( "menufocus", function() {
element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
equal( logOutput(), "keydown,1", "Keydown focus but not select disabled item" );
@@ -564,13 +564,13 @@ asyncTest( "handle keyboard navigation and mouse click on menu with disabled ite
test( "handle keyboard navigation with spelling of menu items", function() {
expect( 2 );
var element = $( "#menu2" ).menu({
- focus: function( event, ui ) {
+ focus: function( event ) {
log( $( event.target ).find( ".ui-state-focus" ).parent().index() );
}
});
log( "keydown", true );
- element.one( "menufocus", function( event, ui ) {
+ element.one( "menufocus", function() {
element.simulate( "keydown", { keyCode: 65 } );
element.simulate( "keydown", { keyCode: 68 } );
element.simulate( "keydown", { keyCode: 68 } );
diff --git a/tests/unit/menu/menu_methods.js b/tests/unit/menu/menu_methods.js
index f9241f27b..a7e78ea69 100644
--- a/tests/unit/menu/menu_methods.js
+++ b/tests/unit/menu/menu_methods.js
@@ -29,7 +29,7 @@ test( "destroy", function() {
test( "enable/disable", function() {
expect( 3 );
var element = $( "#menu1" ).menu({
- select: function( event, ui ) {
+ select: function() {
log();
}
});
@@ -60,6 +60,15 @@ test( "refresh", function() {
equal( element.find( ".ui-menu-item" ).length, 5, "Incorrect number of menu items" );
});
+test( "refresh submenu", function() {
+ expect( 2 );
+ var element = $( "#menu2" ).menu();
+ equal( element.find( "ul:first .ui-menu-item" ).length, 3 );
+ element.find( "ul" ).andSelf().append( "<li><a href=\"#\">New Item</a></li>" );
+ element.menu("refresh");
+ equal( element.find( "ul:first .ui-menu-item" ).length, 4 );
+});
+
test( "widget", function() {
expect( 2 );
var element = $( "#menu1" ).menu(),
diff --git a/tests/unit/menu/menu_options.js b/tests/unit/menu/menu_options.js
index a8b029201..2c8749e3c 100644
--- a/tests/unit/menu/menu_options.js
+++ b/tests/unit/menu/menu_options.js
@@ -14,7 +14,7 @@ test( "{ disabled: true }", function() {
expect( 2 );
var element = $( "#menu1" ).menu({
disabled: true,
- select: function(event, ui) {
+ select: function() {
log();
}
});
@@ -29,7 +29,7 @@ test( "{ disabled: false }", function() {
expect( 2 );
var element = $( "#menu1" ).menu({
disabled: false,
- select: function( event, ui ) {
+ select: function() {
log();
}
});
diff --git a/tests/unit/position/position.html b/tests/unit/position/position.html
index 8738ae667..f3b1ad86c 100644
--- a/tests/unit/position/position.html
+++ b/tests/unit/position/position.html
@@ -5,9 +5,6 @@
<title>jQuery UI Position Test Suite</title>
<script src="../../jquery.js"></script>
- <script>
- $.uiBackCompat = false;
- </script>
<link rel="stylesheet" href="../../../external/qunit.css">
<script src="../../../external/qunit.js"></script>
<script src="../../jquery.simulate.js"></script>
diff --git a/tests/unit/position/position_core.js b/tests/unit/position/position_core.js
index 3b749a218..7b51223ac 100644
--- a/tests/unit/position/position_core.js
+++ b/tests/unit/position/position_core.js
@@ -342,6 +342,8 @@ test( "collision: fit, no collision", function() {
}, "with offset" );
});
+// Currently failing in IE8 due to the iframe used by TestSwarm
+if ( !/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ) ) {
test( "collision: fit, collision", function() {
expect( 2 + (scrollTopSupport() ? 1 : 0) );
@@ -372,6 +374,7 @@ test( "collision: fit, collision", function() {
win.scrollTop( 0 ).scrollLeft( 0 );
}
});
+}
test( "collision: flip, no collision", function() {
expect( 2 );
diff --git a/tests/unit/position/position_deprecated.html b/tests/unit/position/position_deprecated.html
deleted file mode 100644
index 84aae61f8..000000000
--- a/tests/unit/position/position_deprecated.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>jQuery UI Position Test Suite</title>
-
- <script src="../../jquery.js"></script>
-
-
-
- <link rel="stylesheet" href="../../../external/qunit.css">
- <script src="../../../external/qunit.js"></script>
- <script src="../../jquery.simulate.js"></script>
- <script src="../testsuite.js"></script>
- <script>
- TestHelpers.loadResources({
- js: [ "ui/jquery.ui.position.js" ]
- });
- </script>
-
- <script src="position_core.js"></script>
- <script src="position_deprecated.js"></script>
- <script src="../swarminject.js"></script>
-</head>
-<body>
-<div id="qunit" style="position:relative; z-index:2;"></div>
-
-<!--
-elements smaller than 20px have a line-height set on them to avoid a bug in IE6
-.height() returns the greater of the height and line-height
--->
-
-<div id="qunit-fixture" style="top: 0; left: 0; z-index:1">
- <div id="el1" style="position: absolute; width: 6px; height: 6px; line-height: 6px;"></div>
- <div id="el2" style="position: absolute; width: 6px; height: 6px; line-height: 6px;"></div>
- <div id="parent" style="position: absolute; width: 6px; height: 6px; top: 4px; left: 4px; line-height: 6px;"></div>
- <div id="within" style="position: absolute; width: 12px; height: 12px; top: 2px; left: 0px; line-height: 12px;"></div>
-
- <div id="scrollx" style="position: absolute; top: 0px; left: 0px">
- <div id="elx" style="position: absolute; width: 10px; height: 10px; line-height: 10px;"></div>
- <div id="parentx" style="position: absolute; width: 20px; height: 20px; top: 40px; left: 40px;"></div>
- </div>
-
- <div style="position: absolute; height: 5000px; width: 5000px;"></div>
-
- <div id="fractions-parent" style="position: absolute; left: 10.7432222px; top: 10.532325px; height: 30px; width: 201px;">
- <div id="fractions-element"></div>
- </div>
-
- <div id="bug-5280" style="height: 30px; width: 201px;">
- <div style="width: 50px; height: 10px;"></div>
- </div>
-</div>
-
-</body>
-</html>
diff --git a/tests/unit/position/position_deprecated.js b/tests/unit/position/position_deprecated.js
deleted file mode 100644
index 789d4e608..000000000
--- a/tests/unit/position/position_deprecated.js
+++ /dev/null
@@ -1,33 +0,0 @@
-(function( $ ) {
-
-test( "offset", function() {
- expect( 3 );
- $( "#elx" ).position({
- my: "left top",
- at: "left bottom",
- of: "#parentx",
- offset: "10",
- collision: "none"
- });
- deepEqual( $( "#elx" ).offset(), { top: 70, left: 50 }, "single value" );
-
- $( "#elx" ).position({
- my: "left top",
- at: "left bottom",
- of: "#parentx",
- offset: "5 -3",
- collision: "none"
- });
- deepEqual( $( "#elx" ).offset(), { top: 57, left: 45 }, "two values" );
-
- $( "#elx" ).position({
- my: "left top",
- at: "left bottom",
- of: "#parentx",
- offset: "5px -3px",
- collision: "none"
- });
- deepEqual( $( "#elx" ).offset(), { top: 57, left: 45 }, "with units" );
-});
-
-}( jQuery ) );
diff --git a/tests/unit/progressbar/progressbar_options.js b/tests/unit/progressbar/progressbar_options.js
index fd5988ebd..e4d9b7ab8 100644
--- a/tests/unit/progressbar/progressbar_options.js
+++ b/tests/unit/progressbar/progressbar_options.js
@@ -60,3 +60,21 @@ test( "{ max : 5, value : 10 }", function() {
});
deepEqual( 5, $( "#progressbar" ).progressbar( "value" ) );
});
+
+test( "{ value : 10, max : 5 }", function() {
+ expect( 1 );
+ $("#progressbar").progressbar({
+ max: 5,
+ value: 10
+ });
+ deepEqual( 5, $( "#progressbar" ).progressbar( "value" ) );
+});
+
+test( "{ max : 5 }", function() {
+ expect( 1 );
+ $("#progressbar").progressbar({
+ max: 10,
+ value: 10
+ }).progressbar( "option", "max", 5 );
+ deepEqual( 5, $( "#progressbar" ).progressbar( "value" ) );
+});
diff --git a/tests/unit/resizable/resizable.html b/tests/unit/resizable/resizable.html
index 558574c5f..eca465ae9 100644
--- a/tests/unit/resizable/resizable.html
+++ b/tests/unit/resizable/resizable.html
@@ -26,17 +26,8 @@
<script src="resizable_events.js"></script>
<script src="resizable_methods.js"></script>
<script src="resizable_options.js"></script>
+ <script src="resizable_test_helpers.js"></script>
- <script>
- // disable this stale testsuite for testswarm only
- var url = window.location.search;
- url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) );
- if ( url && url.indexOf("http") == 0 ) {
- // reset config to kill previous tests; make sure testsuite.js is loaded afterwards to init the testswarm script
- QUnit.init();
- test("resizable", function() { ok(true, "disabled resizable testsuite"); });
- }
- </script>
<script src="../swarminject.js"></script>
</head>
<body>
diff --git a/tests/unit/resizable/resizable_core.js b/tests/unit/resizable/resizable_core.js
index aef2ae15c..a1ac22272 100644
--- a/tests/unit/resizable/resizable_core.js
+++ b/tests/unit/resizable/resizable_core.js
@@ -2,22 +2,6 @@
* resizable_core.js
*/
-var el;
-
-var drag = function(el, dx, dy, complete) {
-
- // speed = sync -> Drag syncrhonously.
- // speed = fast|slow -> Drag asyncrhonously - animated.
-
- //this mouseover is to work around a limitation in resizable
- //TODO: fix resizable so handle doesn't require mouseover in order to be used
- $(el).simulate("mouseover");
-
- return $(el).simulate("drag", {
- dx: dx||0, dy: dy||0, speed: 'sync', complete: complete
- });
-};
-
(function($) {
module("resizable: core");
@@ -46,10 +30,10 @@ test("n", function() {
var handle = '.ui-resizable-n', target = $('#resizable1').resizable({ handles: 'all' });
- drag(handle, 0, -50);
+ TestHelpers.resizable.drag(handle, 0, -50);
equal( target.height(), 150, "compare height" );
- drag(handle, 0, 50);
+ TestHelpers.resizable.drag(handle, 0, 50);
equal( target.height(), 100, "compare height" );
});
@@ -58,10 +42,10 @@ test("s", function() {
var handle = '.ui-resizable-s', target = $('#resizable1').resizable({ handles: 'all' });
- drag(handle, 0, 50);
+ TestHelpers.resizable.drag(handle, 0, 50);
equal( target.height(), 150, "compare height" );
- drag(handle, 0, -50);
+ TestHelpers.resizable.drag(handle, 0, -50);
equal( target.height(), 100, "compare height" );
});
@@ -70,10 +54,10 @@ test("e", function() {
var handle = '.ui-resizable-e', target = $('#resizable1').resizable({ handles: 'all' });
- drag(handle, 50);
+ TestHelpers.resizable.drag(handle, 50);
equal( target.width(), 150, "compare width");
- drag(handle, -50);
+ TestHelpers.resizable.drag(handle, -50);
equal( target.width(), 100, "compare width" );
});
@@ -82,10 +66,10 @@ test("w", function() {
var handle = '.ui-resizable-w', target = $('#resizable1').resizable({ handles: 'all' });
- drag(handle, -50);
+ TestHelpers.resizable.drag(handle, -50);
equal( target.width(), 150, "compare width" );
- drag(handle, 50);
+ TestHelpers.resizable.drag(handle, 50);
equal( target.width(), 100, "compare width" );
});
@@ -94,11 +78,11 @@ test("ne", function() {
var handle = '.ui-resizable-ne', target = $('#resizable1').css({ overflow: 'hidden' }).resizable({ handles: 'all' });
- drag(handle, -50, -50);
+ TestHelpers.resizable.drag(handle, -50, -50);
equal( target.width(), 50, "compare width" );
equal( target.height(), 150, "compare height" );
- drag(handle, 50, 50);
+ TestHelpers.resizable.drag(handle, 50, 50);
equal( target.width(), 100, "compare width" );
equal( target.height(), 100, "compare height" );
});
@@ -108,11 +92,11 @@ test("se", function() {
var handle = '.ui-resizable-se', target = $('#resizable1').resizable({ handles: 'all' });
- drag(handle, 50, 50);
+ TestHelpers.resizable.drag(handle, 50, 50);
equal( target.width(), 150, "compare width" );
equal( target.height(), 150, "compare height" );
- drag(handle, -50, -50);
+ TestHelpers.resizable.drag(handle, -50, -50);
equal( target.width(), 100, "compare width" );
equal( target.height(), 100, "compare height" );
});
@@ -122,11 +106,11 @@ test("sw", function() {
var handle = '.ui-resizable-sw', target = $('#resizable1').resizable({ handles: 'all' });
- drag(handle, -50, -50);
+ TestHelpers.resizable.drag(handle, -50, -50);
equal( target.width(), 150, "compare width" );
equal( target.height(), 50, "compare height" );
- drag(handle, 50, 50);
+ TestHelpers.resizable.drag(handle, 50, 50);
equal( target.width(), 100, "compare width" );
equal( target.height(), 100, "compare height" );
});
@@ -136,13 +120,33 @@ test("nw", function() {
var handle = '.ui-resizable-nw', target = $('#resizable1').resizable({ handles: 'all' });
- drag(handle, -50, -50);
+ TestHelpers.resizable.drag(handle, -50, -50);
equal( target.width(), 150, "compare width" );
equal( target.height(), 150, "compare height" );
- drag(handle, 50, 50);
+ TestHelpers.resizable.drag(handle, 50, 50);
equal( target.width(), 100, "compare width" );
equal( target.height(), 100, "compare height" );
});
+test("handle with complex markup (#8756)", function() {
+ expect(2);
+
+ $('#resizable1')
+ .append(
+ $('<div>')
+ .addClass("ui-resizable-handle")
+ .addClass("ui-resizable-w")
+ .append($('<div>'))
+ );
+
+ var handle = '.ui-resizable-w div', target = $('#resizable1').resizable({ handles: 'all' });
+
+ TestHelpers.resizable.drag(handle, -50);
+ equal( target.width(), 150, "compare width" );
+
+ TestHelpers.resizable.drag(handle, 50);
+ equal( target.width(), 100, "compare width" );
+});
+
})(jQuery);
diff --git a/tests/unit/resizable/resizable_events.js b/tests/unit/resizable/resizable_events.js
index 52d55731c..d7793ff2f 100644
--- a/tests/unit/resizable/resizable_events.js
+++ b/tests/unit/resizable/resizable_events.js
@@ -5,4 +5,8 @@
module("resizable: events");
+// this is here to make JSHint pass "unused", and we don't want to
+// remove the parameter for when we finally implement
+$.noop();
+
})(jQuery);
diff --git a/tests/unit/resizable/resizable_methods.js b/tests/unit/resizable/resizable_methods.js
index 87859acf7..b12f3035a 100644
--- a/tests/unit/resizable/resizable_methods.js
+++ b/tests/unit/resizable/resizable_methods.js
@@ -5,5 +5,8 @@
module("resizable: methods");
+// this is here to make JSHint pass "unused", and we don't want to
+// remove the parameter for when we finally implement
+$.noop();
})(jQuery);
diff --git a/tests/unit/resizable/resizable_options.js b/tests/unit/resizable/resizable_options.js
index e10a55a31..4b47762ab 100644
--- a/tests/unit/resizable/resizable_options.js
+++ b/tests/unit/resizable/resizable_options.js
@@ -10,11 +10,11 @@ test("aspectRatio: 'preserve' (e)", function() {
var handle = '.ui-resizable-e', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
- drag(handle, 80);
+ TestHelpers.resizable.drag(handle, 80);
equal( target.width(), 130, "compare maxWidth");
equal( target.height(), 130, "compare maxHeight");
- drag(handle, -130);
+ TestHelpers.resizable.drag(handle, -130);
equal( target.width(), 70, "compare minWidth");
equal( target.height(), 70, "compare minHeight");
});
@@ -24,11 +24,11 @@ test("aspectRatio: 'preserve' (w)", function() {
var handle = '.ui-resizable-w', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
- drag(handle, -80);
+ TestHelpers.resizable.drag(handle, -80);
equal( target.width(), 130, "compare maxWidth");
equal( target.height(), 130, "compare maxHeight");
- drag(handle, 130);
+ TestHelpers.resizable.drag(handle, 130);
equal( target.width(), 70, "compare minWidth");
equal( target.height(), 70, "compare minHeight");
});
@@ -38,11 +38,11 @@ test("aspectRatio: 'preserve' (n)", function() {
var handle = '.ui-resizable-n', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
- drag(handle, 0, -80);
+ TestHelpers.resizable.drag(handle, 0, -80);
equal( target.width(), 130, "compare maxWidth");
equal( target.height(), 130, "compare maxHeight");
- drag(handle, 0, 80);
+ TestHelpers.resizable.drag(handle, 0, 80);
equal( target.width(), 70, "compare minWidth");
equal( target.height(), 70, "compare minHeight");
});
@@ -52,11 +52,11 @@ test("aspectRatio: 'preserve' (s)", function() {
var handle = '.ui-resizable-s', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
- drag(handle, 0, 80);
+ TestHelpers.resizable.drag(handle, 0, 80);
equal( target.width(), 130, "compare maxWidth");
equal( target.height(), 130, "compare maxHeight");
- drag(handle, 0, -80);
+ TestHelpers.resizable.drag(handle, 0, -80);
equal( target.width(), 70, "compare minWidth");
equal( target.height(), 70, "compare minHeight");
});
@@ -66,11 +66,11 @@ test("aspectRatio: 'preserve' (se)", function() {
var handle = '.ui-resizable-se', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
- drag(handle, 80, 80);
+ TestHelpers.resizable.drag(handle, 80, 80);
equal( target.width(), 130, "compare maxWidth");
equal( target.height(), 130, "compare maxHeight");
- drag(handle, -80, -80);
+ TestHelpers.resizable.drag(handle, -80, -80);
equal( target.width(), 70, "compare minWidth");
equal( target.height(), 70, "compare minHeight");
});
@@ -80,11 +80,11 @@ test("aspectRatio: 'preserve' (sw)", function() {
var handle = '.ui-resizable-sw', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
- drag(handle, -80, 80);
+ TestHelpers.resizable.drag(handle, -80, 80);
equal( target.width(), 130, "compare maxWidth");
equal( target.height(), 130, "compare maxHeight");
- drag(handle, 80, -80);
+ TestHelpers.resizable.drag(handle, 80, -80);
equal( target.width(), 70, "compare minWidth");
equal( target.height(), 70, "compare minHeight");
});
@@ -94,11 +94,11 @@ test("aspectRatio: 'preserve' (ne)", function() {
var handle = '.ui-resizable-ne', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
- drag(handle, 80, -80);
+ TestHelpers.resizable.drag(handle, 80, -80);
equal( target.width(), 130, "compare maxWidth");
equal( target.height(), 130, "compare maxHeight");
- drag(handle, -80, 80);
+ TestHelpers.resizable.drag(handle, -80, 80);
equal( target.width(), 70, "compare minWidth");
equal( target.height(), 70, "compare minHeight");
});
@@ -108,25 +108,39 @@ test("grid", function() {
var handle = '.ui-resizable-se', target = $('#resizable1').resizable({ handles: 'all', grid: [0, 20] });
- drag(handle, 3, 9);
+ TestHelpers.resizable.drag(handle, 3, 9);
equal( target.width(), 103, "compare width");
equal( target.height(), 100, "compare height");
- drag(handle, 15, 11);
+ TestHelpers.resizable.drag(handle, 15, 11);
equal( target.width(), 118, "compare width");
equal( target.height(), 120, "compare height");
});
+test("grid (min/max dimensions)", function() {
+ expect(4);
+
+ var handle = ".ui-resizable-se", target = $("#resizable1").resizable({ handles: "all", grid: 20, minWidth: 65, minHeight: 65, maxWidth: 135, maxHeight: 135 });
+
+ TestHelpers.resizable.drag(handle, 50, 50);
+ equal( target.width(), 120, "grid should respect maxWidth");
+ equal( target.height(), 120, "grid should respect maxHeight");
+
+ TestHelpers.resizable.drag(handle, -100, -100);
+ equal( target.width(), 80, "grid should respect minWidth");
+ equal( target.height(), 80, "grid should respect minHeight");
+});
+
test("grid (wrapped)", function() {
expect(4);
var handle = '.ui-resizable-se', target = $('#resizable2').resizable({ handles: 'all', grid: [0, 20] });
- drag(handle, 3, 9);
+ TestHelpers.resizable.drag(handle, 3, 9);
equal( target.width(), 103, "compare width");
equal( target.height(), 100, "compare height");
- drag(handle, 15, 11);
+ TestHelpers.resizable.drag(handle, 15, 11);
equal( target.width(), 118, "compare width");
equal( target.height(), 120, "compare height");
});
@@ -136,11 +150,11 @@ test("ui-resizable-se { handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 1
var handle = '.ui-resizable-se', target = $('#resizable1').resizable({ handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 100, maxHeight: 100 });
- drag(handle, -50, -50);
+ TestHelpers.resizable.drag(handle, -50, -50);
equal( target.width(), 60, "compare minWidth" );
equal( target.height(), 60, "compare minHeight" );
- drag(handle, 70, 70);
+ TestHelpers.resizable.drag(handle, 70, 70);
equal( target.width(), 100, "compare maxWidth" );
equal( target.height(), 100, "compare maxHeight" );
});
@@ -150,11 +164,11 @@ test("ui-resizable-sw { handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 1
var handle = '.ui-resizable-sw', target = $('#resizable1').resizable({ handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 100, maxHeight: 100 });
- drag(handle, 50, -50);
+ TestHelpers.resizable.drag(handle, 50, -50);
equal( target.width(), 60, "compare minWidth" );
equal( target.height(), 60, "compare minHeight" );
- drag(handle, -70, 70);
+ TestHelpers.resizable.drag(handle, -70, 70);
equal( target.width(), 100, "compare maxWidth" );
equal( target.height(), 100, "compare maxHeight" );
});
@@ -164,11 +178,11 @@ test("ui-resizable-ne { handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 1
var handle = '.ui-resizable-ne', target = $('#resizable1').resizable({ handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 100, maxHeight: 100 });
- drag(handle, -50, 50);
+ TestHelpers.resizable.drag(handle, -50, 50);
equal( target.width(), 60, "compare minWidth" );
equal( target.height(), 60, "compare minHeight" );
- drag(handle, 70, -70);
+ TestHelpers.resizable.drag(handle, 70, -70);
equal( target.width(), 100, "compare maxWidth" );
equal( target.height(), 100, "compare maxHeight" );
});
@@ -178,11 +192,11 @@ test("ui-resizable-nw { handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 1
var handle = '.ui-resizable-nw', target = $('#resizable1').resizable({ handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 100, maxHeight: 100 });
- drag(handle, 70, 70);
+ TestHelpers.resizable.drag(handle, 70, 70);
equal( target.width(), 60, "compare minWidth" );
equal( target.height(), 60, "compare minHeight" );
- drag(handle, -70, -70);
+ TestHelpers.resizable.drag(handle, -70, -70);
equal( target.width(), 100, "compare maxWidth" );
equal( target.height(), 100, "compare maxHeight" );
});
diff --git a/tests/unit/resizable/resizable_test_helpers.js b/tests/unit/resizable/resizable_test_helpers.js
new file mode 100644
index 000000000..fe6c84900
--- /dev/null
+++ b/tests/unit/resizable/resizable_test_helpers.js
@@ -0,0 +1,15 @@
+TestHelpers.resizable = {
+ drag: function(el, dx, dy, complete) {
+
+ // speed = sync -> Drag syncrhonously.
+ // speed = fast|slow -> Drag asyncrhonously - animated.
+
+ //this mouseover is to work around a limitation in resizable
+ //TODO: fix resizable so handle doesn't require mouseover in order to be used
+ $(el).simulate("mouseover");
+
+ return $(el).simulate("drag", {
+ dx: dx||0, dy: dy||0, speed: 'sync', complete: complete
+ });
+ }
+}; \ No newline at end of file
diff --git a/tests/unit/selectable/selectable.html b/tests/unit/selectable/selectable.html
index 7b0ca6ffe..13718e1f3 100644
--- a/tests/unit/selectable/selectable.html
+++ b/tests/unit/selectable/selectable.html
@@ -26,17 +26,8 @@
<script src="selectable_events.js"></script>
<script src="selectable_methods.js"></script>
<script src="selectable_options.js"></script>
+ <script src="selectable_test_helpers.js"></script>
- <script>
- // disable this stale testsuite for testswarm only
- var url = window.location.search;
- url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) );
- if ( url && url.indexOf("http") == 0 ) {
- // reset config to kill previous tests; make sure testsuite.js is loaded afterwards to init the testswarm script
- QUnit.init();
- test("selectable", function() { ok(true, "disabled selectable testsuite"); });
- }
- </script>
<script src="../swarminject.js"></script>
</head>
<body>
diff --git a/tests/unit/selectable/selectable_common.js b/tests/unit/selectable/selectable_common.js
index 885e79401..aee6a15ac 100644
--- a/tests/unit/selectable/selectable_common.js
+++ b/tests/unit/selectable/selectable_common.js
@@ -3,6 +3,7 @@ TestHelpers.commonWidgetTests('selectable', {
appendTo: 'body',
autoRefresh: true,
cancel: 'input,textarea,button,select,option',
+ create: null,
delay: 0,
disabled: false,
distance: 0,
diff --git a/tests/unit/selectable/selectable_core.js b/tests/unit/selectable/selectable_core.js
index 18ea3a302..9953b6c07 100644
--- a/tests/unit/selectable/selectable_core.js
+++ b/tests/unit/selectable/selectable_core.js
@@ -1,16 +1,3 @@
/*
* selectable_core.js
- */
-
-var el;
-
-var drag = function(dx, dy) {
- var off = el.offset(), pos = { clientX: off.left, clientY: off.top };
- el.simulate("mousedown", pos);
- $(document).simulate("mousemove", pos);
- pos.clientX += dx;
- pos.clientY += dy;
- $(document).simulate("mousemove", pos);
- $(document).simulate("mouseup", pos);
-};
-
+ */ \ No newline at end of file
diff --git a/tests/unit/selectable/selectable_events.js b/tests/unit/selectable/selectable_events.js
index 2623818a7..331bae146 100644
--- a/tests/unit/selectable/selectable_events.js
+++ b/tests/unit/selectable/selectable_events.js
@@ -7,9 +7,9 @@ module("selectable: events");
test("start", function() {
expect(2);
- el = $("#selectable1");
+ var el = $("#selectable1");
el.selectable({
- start: function(ev, ui) {
+ start: function() {
ok(true, "drag fired start callback");
equal(this, el[0], "context of callback");
}
@@ -19,9 +19,9 @@ test("start", function() {
test("stop", function() {
expect(2);
- el = $("#selectable1");
+ var el = $("#selectable1");
el.selectable({
- start: function(ev, ui) {
+ start: function() {
ok(true, "drag fired stop callback");
equal(this, el[0], "context of callback");
}
diff --git a/tests/unit/selectable/selectable_methods.js b/tests/unit/selectable/selectable_methods.js
index dbc88f269..aa8924176 100644
--- a/tests/unit/selectable/selectable_methods.js
+++ b/tests/unit/selectable/selectable_methods.js
@@ -6,7 +6,7 @@
module("selectable: methods");
test("init", function() {
- expect(6);
+ expect( 5 );
$("<div></div>").appendTo('body').selectable().remove();
ok(true, '.selectable() called on element');
@@ -17,11 +17,8 @@ test("init", function() {
$("<div></div>").selectable().remove();
ok(true, '.selectable() called on disconnected DOMElement');
- $("<div></div>").selectable().selectable("foo").remove();
- ok(true, 'arbitrary method called after init');
-
- el = $("<div></div>").selectable();
- var foo = el.selectable("option", "foo");
+ var el = $("<div></div>").selectable();
+ el.selectable("option", "foo");
el.remove();
ok(true, 'arbitrary option getter after init');
@@ -30,6 +27,8 @@ test("init", function() {
});
test("destroy", function() {
+ expect( 4 );
+
$("<div></div>").appendTo('body').selectable().selectable("destroy").remove();
ok(true, '.selectable("destroy") called on element');
@@ -39,9 +38,6 @@ test("destroy", function() {
$("<div></div>").selectable().selectable("destroy").remove();
ok(true, '.selectable("destroy") called on disconnected DOMElement');
- $("<div></div>").selectable().selectable("destroy").selectable("foo").remove();
- ok(true, 'arbitrary method called after destroy');
-
var expected = $('<div></div>').selectable(),
actual = expected.selectable('destroy');
equal(actual, expected, 'destroy is chainable');
@@ -50,9 +46,9 @@ test("destroy", function() {
test("enable", function() {
expect(3);
var expected, actual,
- fired = false;
+ fired = false,
+ el = $("#selectable1");
- el = $("#selectable1");
el.selectable({
disabled: true,
start: function() { fired = true; }
@@ -72,9 +68,9 @@ test("enable", function() {
test("disable", function() {
expect(3);
var expected, actual,
- fired = false;
+ fired = false,
+ el = $("#selectable1");
- el = $("#selectable1");
el.selectable({
disabled: false,
start: function() { fired = true; }
diff --git a/tests/unit/selectable/selectable_options.js b/tests/unit/selectable/selectable_options.js
index be9fdf5fe..50e047427 100644
--- a/tests/unit/selectable/selectable_options.js
+++ b/tests/unit/selectable/selectable_options.js
@@ -7,13 +7,15 @@ module("selectable: options");
test("autoRefresh", function() {
expect(3);
- el = $("#selectable1");
- var actual, sel = $("*", el), selected = function() { actual += 1; };
- actual = 0;
+ var actual = 0,
+ el = $("#selectable1"),
+ sel = $("*", el),
+ selected = function() { actual += 1; };
+
el = $("#selectable1").selectable({ autoRefresh: false, selected: selected });
sel.hide();
- drag(1000, 1000);
+ TestHelpers.selectable.drag(el, 1000, 1000);
equal(actual, sel.length);
el.selectable("destroy");
@@ -21,10 +23,10 @@ test("autoRefresh", function() {
sel.show();
el = $("#selectable1").selectable({ autoRefresh: true, selected: selected });
sel.hide();
- drag(1000, 1000);
+ TestHelpers.selectable.drag(el, 1000, 1000);
equal(actual, 0);
sel.show();
- drag(1000, 1000);
+ TestHelpers.selectable.drag( sel[ 0 ], 1000, 1000 );
equal(actual, sel.length);
el.selectable("destroy");
sel.show();
@@ -32,12 +34,15 @@ test("autoRefresh", function() {
test("filter", function() {
expect(2);
- el = $("#selectable1");
- var actual, sel = $("*", el), selected = function() { actual += 1; };
- actual = 0;
+ var actual =0,
+ el = $("#selectable1"),
+ sel = $("*", el),
+ selected = function() { actual += 1; };
+
+
el = $("#selectable1").selectable({ filter: '.special', selected: selected });
- drag(1000, 1000);
+ TestHelpers.selectable.drag(el, 1000, 1000);
ok(sel.length !== 1, "this test assumes more than 1 selectee");
equal(actual, 1);
el.selectable("destroy");
diff --git a/tests/unit/selectable/selectable_test_helpers.js b/tests/unit/selectable/selectable_test_helpers.js
new file mode 100644
index 000000000..6f87efbb3
--- /dev/null
+++ b/tests/unit/selectable/selectable_test_helpers.js
@@ -0,0 +1,8 @@
+TestHelpers.selectable = {
+ drag: function( el, dx, dy ) {
+ $( el ).simulate( "drag", {
+ dx: dx || 0,
+ dy: dy || 0
+ });
+ }
+}; \ No newline at end of file
diff --git a/tests/unit/slider/slider.html b/tests/unit/slider/slider.html
index 3aec78b4b..98adfa3ae 100644
--- a/tests/unit/slider/slider.html
+++ b/tests/unit/slider/slider.html
@@ -27,16 +27,6 @@
<script src="slider_methods.js"></script>
<script src="slider_options.js"></script>
- <script>
- // disable this stale testsuite for testswarm only
- var url = window.location.search;
- url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) );
- if ( url && url.indexOf("http") == 0 ) {
- // reset config to kill previous tests; make sure testsuite.js is loaded afterwards to init the testswarm script
- QUnit.init();
- test("slider", function() { ok(true, "disabled slider testsuite"); });
- }
- </script>
<script src="../swarminject.js"></script>
</head>
<body>
diff --git a/tests/unit/slider/slider_events.js b/tests/unit/slider/slider_events.js
index 4d0896442..2fb9b37b6 100644
--- a/tests/unit/slider/slider_events.js
+++ b/tests/unit/slider/slider_events.js
@@ -14,16 +14,16 @@ test( "mouse based interaction", function() {
var el = $( "#slider1" )
.slider({
- start: function(event, ui) {
+ start: function( event ) {
equal( event.originalEvent.type, "mousedown", "start triggered by mousedown" );
},
- slide: function(event, ui) {
+ slide: function( event) {
equal( event.originalEvent.type, "mousemove", "slider triggered by mousemove" );
},
- stop: function(event, ui) {
+ stop: function( event ) {
equal( event.originalEvent.type, "mouseup", "stop triggered by mouseup" );
},
- change: function(event, ui) {
+ change: function( event ) {
equal( event.originalEvent.type, "mouseup", "change triggered by mouseup" );
}
});
@@ -38,16 +38,16 @@ test( "keyboard based interaction", function() {
// Test keyup at end of handle slide (keyboard)
var el = $( "#slider1" )
.slider({
- start: function(event, ui) {
+ start: function( event ) {
equal( event.originalEvent.type, "keydown", "start triggered by keydown" );
},
- slide: function(event, ui) {
+ slide: function() {
ok( false, "Slider never triggered by keys" );
},
- stop: function(event, ui) {
+ stop: function( event ) {
equal( event.originalEvent.type, "keyup", "stop triggered by keyup" );
},
- change: function(event, ui) {
+ change: function( event ) {
equal( event.originalEvent.type, "keyup", "change triggered by keyup" );
}
});
@@ -64,7 +64,7 @@ test( "programmatic event triggers", function() {
// Test value method
var el = $( "<div></div>" )
.slider({
- change: function(event, ui) {
+ change: function() {
ok( true, "change triggered by value method" );
}
})
@@ -75,7 +75,7 @@ test( "programmatic event triggers", function() {
el = $( "<div></div>" )
.slider({
values: [ 10, 20 ],
- change: function(event, ui) {
+ change: function() {
ok( true, "change triggered by values method" );
}
})
@@ -85,7 +85,7 @@ test( "programmatic event triggers", function() {
// Test value option
el = $( "<div></div>" )
.slider({
- change: function(event, ui) {
+ change: function() {
ok( true, "change triggered by value option" );
}
})
@@ -96,7 +96,7 @@ test( "programmatic event triggers", function() {
el = $( "<div></div>" )
.slider({
values: [ 10, 20 ],
- change: function(event, ui) {
+ change: function() {
ok( true, "change triggered by values option" );
}
})
diff --git a/tests/unit/slider/slider_methods.js b/tests/unit/slider/slider_methods.js
index 1a6b493c9..11d679845 100644
--- a/tests/unit/slider/slider_methods.js
+++ b/tests/unit/slider/slider_methods.js
@@ -17,8 +17,8 @@ test("init", function() {
$('<div></div>').slider().remove();
ok(true, '.slider() called on disconnected DOMElement');
- var el = $('<div></div>').slider(),
- foo = el.slider("option", "foo");
+ var el = $('<div></div>').slider();
+ el.slider("option", "foo");
el.remove();
ok(true, 'arbitrary option getter after init');
diff --git a/tests/unit/sortable/sortable.html b/tests/unit/sortable/sortable.html
index c84c62197..b7b7b0007 100644
--- a/tests/unit/sortable/sortable.html
+++ b/tests/unit/sortable/sortable.html
@@ -26,19 +26,26 @@
<script src="sortable_events.js"></script>
<script src="sortable_methods.js"></script>
<script src="sortable_options.js"></script>
+ <script src="sortable_test_helpers.js"></script>
<script src="sortable_tickets.js"></script>
- <script>
- // disable this stale testsuite for testswarm only
- var url = window.location.search;
- url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) );
- if ( url && url.indexOf("http") == 0 ) {
- // reset config to kill previous tests; make sure testsuite.js is loaded afterwards to init the testswarm script
- QUnit.init();
- test("sortable", function() { ok(true, "disabled sortable testsuite"); });
- }
- </script>
<script src="../swarminject.js"></script>
+ <style>
+ #sortable, #sortable2 {
+ position:relative;
+ top:0;
+ left:0;
+ padding: 0;
+ margin: 1px;
+ border-width: 0;
+ }
+ #sortable li{
+ padding: 0;
+ margin: 0;
+ border-width: 0;
+ height:19px;
+ }
+ </style>
</head>
<body>
diff --git a/tests/unit/sortable/sortable_common.js b/tests/unit/sortable/sortable_common.js
index ae21f7dd2..0a8e9f2b9 100644
--- a/tests/unit/sortable/sortable_common.js
+++ b/tests/unit/sortable/sortable_common.js
@@ -5,6 +5,7 @@ TestHelpers.commonWidgetTests( "sortable", {
cancel: "input,textarea,button,select,option",
connectWith: false,
containment: false,
+ create: null,
cursor: "auto",
cursorAt: false,
delay: 0,
diff --git a/tests/unit/sortable/sortable_core.js b/tests/unit/sortable/sortable_core.js
index ff1859874..211f8ac95 100644
--- a/tests/unit/sortable/sortable_core.js
+++ b/tests/unit/sortable/sortable_core.js
@@ -1,9 +1,3 @@
/*
* sortable_core.js
- */
-
-(function($) {
-
-module("sortable: core");
-
-})(jQuery);
+ */ \ No newline at end of file
diff --git a/tests/unit/sortable/sortable_events.js b/tests/unit/sortable/sortable_events.js
index 6ed54e1b6..556f539e1 100644
--- a/tests/unit/sortable/sortable_events.js
+++ b/tests/unit/sortable/sortable_events.js
@@ -6,6 +6,7 @@
module("sortable: events");
test("start", function() {
+ expect( 7 );
var hash;
$("#sortable")
@@ -15,15 +16,18 @@ test("start", function() {
ok(hash, 'start event triggered');
ok(hash.helper, 'UI hash includes: helper');
ok(hash.placeholder, 'UI hash includes: placeholder');
- ok(hash.position && (hash.position.top && hash.position.left), 'UI hash includes: position');
- ok(hash.offset && (hash.offset.top && hash.offset.left), 'UI hash includes: offset');
ok(hash.item, 'UI hash includes: item');
ok(!hash.sender, 'UI hash does not include: sender');
+ // todo: see if these events should actually have sane values in them
+ ok('position' in hash, 'UI hash includes: position');
+ ok('offset' in hash, 'UI hash includes: offset');
+
});
test("sort", function() {
+ expect( 7 );
var hash;
$("#sortable")
@@ -33,7 +37,7 @@ test("sort", function() {
ok(hash, 'sort event triggered');
ok(hash.helper, 'UI hash includes: helper');
ok(hash.placeholder, 'UI hash includes: placeholder');
- ok(hash.position && (hash.position.top && hash.position.left), 'UI hash includes: position');
+ ok(hash.position && ('top' in hash.position && 'left' in hash.position), 'UI hash includes: position');
ok(hash.offset && (hash.offset.top && hash.offset.left), 'UI hash includes: offset');
ok(hash.item, 'UI hash includes: item');
ok(!hash.sender, 'UI hash does not include: sender');
@@ -41,6 +45,7 @@ test("sort", function() {
});
test("change", function() {
+ expect( 8 );
var hash;
$("#sortable")
@@ -51,12 +56,12 @@ test("change", function() {
$("#sortable")
.sortable({ change: function(e, ui) { hash = ui; } })
- .find('li:eq(0)').simulate("drag", { dx: 0, dy: 20 });
+ .find('li:eq(0)').simulate("drag", { dx: 0, dy: 22 });
ok(hash, 'change event triggered');
ok(hash.helper, 'UI hash includes: helper');
ok(hash.placeholder, 'UI hash includes: placeholder');
- ok(hash.position && (hash.position.top && hash.position.left), 'UI hash includes: position');
+ ok(hash.position && ('top' in hash.position && 'left' in hash.position), 'UI hash includes: position');
ok(hash.offset && (hash.offset.top && hash.offset.left), 'UI hash includes: offset');
ok(hash.item, 'UI hash includes: item');
ok(!hash.sender, 'UI hash does not include: sender');
@@ -64,6 +69,7 @@ test("change", function() {
});
test("beforeStop", function() {
+ expect( 7 );
var hash;
$("#sortable")
@@ -73,7 +79,7 @@ test("beforeStop", function() {
ok(hash, 'beforeStop event triggered');
ok(hash.helper, 'UI hash includes: helper');
ok(hash.placeholder, 'UI hash includes: placeholder');
- ok(hash.position && (hash.position.top && hash.position.left), 'UI hash includes: position');
+ ok(hash.position && ('top' in hash.position && 'left' in hash.position), 'UI hash includes: position');
ok(hash.offset && (hash.offset.top && hash.offset.left), 'UI hash includes: offset');
ok(hash.item, 'UI hash includes: item');
ok(!hash.sender, 'UI hash does not include: sender');
@@ -81,6 +87,7 @@ test("beforeStop", function() {
});
test("stop", function() {
+ expect( 7 );
var hash;
$("#sortable")
@@ -90,7 +97,7 @@ test("stop", function() {
ok(hash, 'stop event triggered');
ok(!hash.helper, 'UI should not include: helper');
ok(hash.placeholder, 'UI hash includes: placeholder');
- ok(hash.position && (hash.position.top && hash.position.left), 'UI hash includes: position');
+ ok(hash.position && ('top' in hash.position && 'left' in hash.position), 'UI hash includes: position');
ok(hash.offset && (hash.offset.top && hash.offset.left), 'UI hash includes: offset');
ok(hash.item, 'UI hash includes: item');
ok(!hash.sender, 'UI hash does not include: sender');
@@ -98,6 +105,7 @@ test("stop", function() {
});
test("update", function() {
+ expect( 8 );
var hash;
$("#sortable")
@@ -108,18 +116,19 @@ test("update", function() {
$("#sortable")
.sortable({ update: function(e, ui) { hash = ui; } })
- .find('li:eq(0)').simulate("drag", { dx: 0, dy: 20 });
+ .find('li:eq(0)').simulate("drag", { dx: 0, dy: 22 });
ok(hash, 'update event triggered');
ok(!hash.helper, 'UI hash should not include: helper');
ok(hash.placeholder, 'UI hash includes: placeholder');
- ok(hash.position && (hash.position.top && hash.position.left), 'UI hash includes: position');
+ ok(hash.position && ('top' in hash.position && 'left' in hash.position), 'UI hash includes: position');
ok(hash.offset && (hash.offset.top && hash.offset.left), 'UI hash includes: offset');
ok(hash.item, 'UI hash includes: item');
ok(!hash.sender, 'UI hash does not include: sender');
});
+/*
test("receive", function() {
ok(false, "missing test - untested code is broken code.");
});
@@ -143,5 +152,6 @@ test("activate", function() {
test("deactivate", function() {
ok(false, "missing test - untested code is broken code.");
});
+*/
})(jQuery);
diff --git a/tests/unit/sortable/sortable_methods.js b/tests/unit/sortable/sortable_methods.js
index c2a0b9548..de32e2f5d 100644
--- a/tests/unit/sortable/sortable_methods.js
+++ b/tests/unit/sortable/sortable_methods.js
@@ -3,27 +3,10 @@
*/
(function($) {
-var el, offsetBefore, offsetAfter, dragged;
-
-function drag(handle, dx, dy) {
- offsetBefore = $(handle).offset();
- $(handle).simulate("drag", {
- dx: dx || 0,
- dy: dy || 0
- });
- dragged = { dx: dx, dy: dy };
- offsetAfter = $(handle).offset();
-}
-
-function sort(handle, dx, dy, index, msg) {
- drag(handle, dx, dy);
- equal($(handle).parent().children().index(handle), index, msg);
-}
-
module("sortable: methods");
test("init", function() {
- expect(6);
+ expect(5);
$("<div></div>").appendTo('body').sortable().remove();
ok(true, '.sortable() called on element');
@@ -34,9 +17,6 @@ test("init", function() {
$("<div></div>").sortable();
ok(true, '.sortable() called on disconnected DOMElement');
- $("<div></div>").sortable().sortable("foo");
- ok(true, 'arbitrary method called after init');
-
$("<div></div>").sortable().sortable("option", "foo");
ok(true, 'arbitrary option getter after init');
@@ -45,6 +25,7 @@ test("init", function() {
});
test("destroy", function() {
+ expect(4);
$("<div></div>").appendTo('body').sortable().sortable("destroy").remove();
ok(true, '.sortable("destroy") called on element');
@@ -54,9 +35,6 @@ test("destroy", function() {
$("<div></div>").sortable().sortable("destroy");
ok(true, '.sortable("destroy") called on disconnected DOMElement');
- $("<div></div>").sortable().sortable("destroy").sortable("foo");
- ok(true, 'arbitrary method called after destroy');
-
var expected = $('<div></div>').sortable(),
actual = expected.sortable('destroy');
equal(actual, expected, 'destroy is chainable');
@@ -64,9 +42,12 @@ test("destroy", function() {
test("enable", function() {
expect(5);
+
+ var el, actual, expected;
+
el = $("#sortable").sortable({ disabled: true });
- sort($("li", el)[0], 0, 40, 0, '.sortable({ disabled: true })');
+ TestHelpers.sortable.sort($("li", el)[0], 0, 44, 0, '.sortable({ disabled: true })');
el.sortable("enable");
equal(el.sortable("option", "disabled"), false, "disabled option getter");
@@ -76,32 +57,35 @@ test("enable", function() {
el.sortable("option", "disabled", false);
equal(el.sortable("option", "disabled"), false, "disabled option setter");
- sort($("li", el)[0], 0, 40, 2, '.sortable("option", "disabled", false)');
+ TestHelpers.sortable.sort($("li", el)[0], 0, 44, 2, '.sortable("option", "disabled", false)');
- var expected = $('<div></div>').sortable(),
- actual = expected.sortable('enable');
+ expected = $('<div></div>').sortable(),
+ actual = expected.sortable('enable');
equal(actual, expected, 'enable is chainable');
});
test("disable", function() {
expect(7);
+
+ var el, actual, expected;
+
el = $("#sortable").sortable({ disabled: false });
- sort($("li", el)[0], 0, 40, 2, '.sortable({ disabled: false })');
+ TestHelpers.sortable.sort($("li", el)[0], 0, 44, 2, '.sortable({ disabled: false })');
el.sortable("disable");
- sort($("li", el)[0], 0, 40, 0, 'disabled.sortable getter');
+ TestHelpers.sortable.sort($("li", el)[0], 0, 44, 0, 'disabled.sortable getter');
el.sortable("destroy");
el.sortable({ disabled: false });
- sort($("li", el)[0], 0, 40, 2, '.sortable({ disabled: false })');
+ TestHelpers.sortable.sort($("li", el)[0], 0, 44, 2, '.sortable({ disabled: false })');
el.sortable("option", "disabled", true);
equal(el.sortable("option", "disabled"), true, "disabled option setter");
ok(el.sortable("widget").is(":not(.ui-state-disabled)"), "sortable element does not get ui-state-disabled since it's an interaction");
- sort($("li", el)[0], 0, 40, 0, '.sortable("option", "disabled", true)');
+ TestHelpers.sortable.sort($("li", el)[0], 0, 44, 0, '.sortable("option", "disabled", true)');
- var expected = $('<div></div>').sortable(),
- actual = expected.sortable('disable');
+ expected = $('<div></div>').sortable(),
+ actual = expected.sortable('disable');
equal(actual, expected, 'disable is chainable');
});
diff --git a/tests/unit/sortable/sortable_options.js b/tests/unit/sortable/sortable_options.js
index a043e68fe..cf35aedb1 100644
--- a/tests/unit/sortable/sortable_options.js
+++ b/tests/unit/sortable/sortable_options.js
@@ -5,6 +5,11 @@
module("sortable: options");
+// this is here to make JSHint pass "unused", and we don't want to
+// remove the parameter for when we finally implement
+$.noop();
+
+/*
test("{ appendTo: 'parent' }, default", function() {
ok(false, "missing test - untested code is broken code.");
});
@@ -252,5 +257,5 @@ test("{ zIndex: 1 }", function() {
test("{ zIndex: false }", function() {
ok(false, "missing test - untested code is broken code.");
});
-
+*/
})(jQuery);
diff --git a/tests/unit/sortable/sortable_test_helpers.js b/tests/unit/sortable/sortable_test_helpers.js
new file mode 100644
index 000000000..7569b5797
--- /dev/null
+++ b/tests/unit/sortable/sortable_test_helpers.js
@@ -0,0 +1,9 @@
+TestHelpers.sortable = {
+ sort: function(handle, dx, dy, index, msg) {
+ $(handle).simulate("drag", {
+ dx: dx || 0,
+ dy: dy || 0
+ });
+ equal($(handle).parent().children().index(handle), index, msg);
+ }
+}; \ No newline at end of file
diff --git a/tests/unit/sortable/sortable_tickets.js b/tests/unit/sortable/sortable_tickets.js
index 22ad61baf..eebd8dc21 100644
--- a/tests/unit/sortable/sortable_tickets.js
+++ b/tests/unit/sortable/sortable_tickets.js
@@ -3,59 +3,45 @@
*/
(function($) {
-var el, offsetBefore, offsetAfter, dragged;
-
-function drag(handle, dx, dy) {
- offsetBefore = $(handle).offset();
- $(handle).simulate("drag", {
- dx: dx || 0,
- dy: dy || 0
- });
- dragged = { dx: dx, dy: dy };
- offsetAfter = $(handle).offset();
-}
-
-function sort(handle, dx, dy, index, msg) {
- drag(handle, dx, dy);
- equal($(handle).parent().children().index(handle), index, msg);
-}
-
module("sortable: tickets");
test("#3019: Stop fires too early", function() {
+ expect(2);
- var helper = null;
- el = $("#sortable").sortable({
- stop: function(event, ui) {
- helper = ui.helper;
- }
- });
+ var helper = null,
+ el = $("#sortable").sortable({
+ stop: function(event, ui) {
+ helper = ui.helper;
+ }
+ });
- sort($("li", el)[0], 0, 40, 2, 'Dragging the sortable');
+ TestHelpers.sortable.sort($("li", el)[0], 0, 44, 2, 'Dragging the sortable');
equal(helper, null, "helper should be false");
});
test('#4752: link event firing on sortable with connect list', function () {
+ expect( 10 );
+
var fired = {},
hasFired = function (type) { return (type in fired) && (true === fired[type]); };
$('#sortable').clone().attr('id', 'sortable2').insertAfter('#sortable');
- $('#main ul').sortable({
- connectWith: '#main ul',
- change: function (e, ui) {
+ $('#qunit-fixture ul').sortable({
+ connectWith: '#qunit-fixture ul',
+ change: function () {
fired.change = true;
},
- receive: function (e, ui) {
+ receive: function () {
fired.receive = true;
},
- remove: function (e, ui) {
+ remove: function () {
fired.remove = true;
}
});
- $('#main ul li').live('click.ui-sortable-test', function () {
+ $('#qunit-fixture ul').bind('click.ui-sortable-test', function () {
fired.click = true;
});
diff --git a/tests/unit/spinner/spinner_options.js b/tests/unit/spinner/spinner_options.js
index 1f6646a33..284e03a3e 100644
--- a/tests/unit/spinner/spinner_options.js
+++ b/tests/unit/spinner/spinner_options.js
@@ -1,7 +1,5 @@
(function( $ ) {
-var simulateKeyDownUp = TestHelpers.spinner.simulateKeyDownUp;
-
module( "spinner: options" );
// culture is tested after numberFormat, since it depends on numberFormat
@@ -28,7 +26,7 @@ test( "icons: custom ", function() {
test( "incremental, false", function() {
expect( 100 );
- var i, diff,
+ var i,
prev = 0,
element = $( "#spin" ).val( prev ).spinner({
incremental: false,
@@ -53,7 +51,7 @@ test( "incremental, true", function() {
});
}
- var i, diff,
+ var i,
prev = 0,
expected = [].concat( fill( 18, 1 ), fill( 37, 2 ), fill( 14, 3 ),
fill( 9, 4 ), fill( 6, 5 ), fill( 5, 6 ), fill ( 5, 7 ),
diff --git a/tests/unit/subsuite.js b/tests/unit/subsuite.js
index 1a16a9e94..148f35b1e 100644
--- a/tests/unit/subsuite.js
+++ b/tests/unit/subsuite.js
@@ -7,9 +7,7 @@ var versions = [
"git"
],
additionalTests = {
- accordion: [ "accordion_deprecated.html" ],
- position: [ "position_deprecated.html" ],
- tabs: [ "tabs_deprecated.html" ]
+ // component: [ "other_test.html" ]
};
window.testAllVersions = function( widget ) {
diff --git a/tests/unit/swarminject.js b/tests/unit/swarminject.js
index 78d37ef46..ebd3ccfac 100644
--- a/tests/unit/swarminject.js
+++ b/tests/unit/swarminject.js
@@ -1,9 +1,10 @@
// load testswarm agent
(function() {
- var url = window.location.search;
+ var url = window.location.search;
url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) );
if ( !url || url.indexOf("http") !== 0 ) {
return;
}
- document.write( "<scr" + "ipt src='http://swarm.jquery.org/js/inject.js?" + (new Date()).getTime() + "'></scr" + "ipt>" );
+ document.write( "<scr" + "ipt src='http://swarm.jquery.org/js/inject.js?" +
+ (new Date()).getTime() + "'></scr" + "ipt>" );
})();
diff --git a/tests/unit/tabs/tabs.html b/tests/unit/tabs/tabs.html
index e6c954727..7c7982303 100644
--- a/tests/unit/tabs/tabs.html
+++ b/tests/unit/tabs/tabs.html
@@ -5,9 +5,6 @@
<title>jQuery UI Tabs Test Suite</title>
<script src="../../jquery.js"></script>
- <script>
- $.uiBackCompat = false;
- </script>
<link rel="stylesheet" href="../../../external/qunit.css">
<script src="../../../external/qunit.js"></script>
<script src="../../jquery.simulate.js"></script>
diff --git a/tests/unit/tabs/tabs_common_deprecated.js b/tests/unit/tabs/tabs_common_deprecated.js
deleted file mode 100644
index 5b41014da..000000000
--- a/tests/unit/tabs/tabs_common_deprecated.js
+++ /dev/null
@@ -1,32 +0,0 @@
-TestHelpers.commonWidgetTests( "tabs", {
- defaults: {
- active: null,
- ajaxOptions: null,
- cache: false,
- collapsible: false,
- cookie: null,
- disabled: false,
- event: "click",
- heightStyle: "content",
- hide: null,
- fx: null,
- idPrefix: "ui-tabs-",
- panelTemplate: "<div></div>",
- // show: null, // conflicts with old show callback
- spinner: "<em>Loading&#8230;</em>",
- tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>",
-
- // callbacks
- activate: null,
- add: null,
- beforeActivate: null,
- beforeLoad: null,
- create: null,
- disable: null,
- enable: null,
- load: null,
- remove: null,
- select: null,
- show: null
- }
-});
diff --git a/tests/unit/tabs/tabs_core.js b/tests/unit/tabs/tabs_core.js
index 5dbe1d6b1..20364a37d 100644
--- a/tests/unit/tabs/tabs_core.js
+++ b/tests/unit/tabs/tabs_core.js
@@ -33,7 +33,7 @@ test( "nested list", function() {
expect( 1 );
var element = $( "#tabs6" ).tabs();
- equal( element.data( "tabs" ).anchors.length, 2, "should contain 2 tab" );
+ equal( element.data( "ui-tabs" ).anchors.length, 2, "should contain 2 tab" );
});
test( "disconnected from DOM", function() {
@@ -132,7 +132,6 @@ test( "accessibility", function() {
asyncTest( "accessibility - ajax", function() {
expect( 4 );
var element = $( "#tabs2" ).tabs(),
- tab = element.find( ".ui-tabs-nav li" ).eq( 3 ),
panel = $( "#custom-id" );
equal( panel.attr( "aria-live" ), "polite", "remote panel has aria-live" );
@@ -156,7 +155,7 @@ asyncTest( "keyboard support - LEFT, RIGHT, UP, DOWN, HOME, END, SPACE, ENTER",
panels = element.find( ".ui-tabs-panel" ),
keyCode = $.ui.keyCode;
- element.data( "tabs" ).delay = 50;
+ element.data( "ui-tabs" ).delay = 50;
equal( tabs.filter( ".ui-state-focus" ).length, 0, "no tabs focused on init" );
tabs.eq( 0 ).simulate( "focus" );
@@ -307,7 +306,7 @@ asyncTest( "keyboard support - CTRL navigation", function() {
panels = element.find( ".ui-tabs-panel" ),
keyCode = $.ui.keyCode;
- element.data( "tabs" ).delay = 50;
+ element.data( "ui-tabs" ).delay = 50;
equal( tabs.filter( ".ui-state-focus" ).length, 0, "no tabs focused on init" );
tabs.eq( 0 ).simulate( "focus" );
@@ -588,7 +587,7 @@ asyncTest( "keyboard support - CTRL+UP, ALT+PAGE_DOWN, ALT+PAGE_UP", function()
test( "#3627 - Ajax tab with url containing a fragment identifier fails to load", function() {
expect( 1 );
- var element = $( "#tabs2" ).tabs({
+ $( "#tabs2" ).tabs({
active: 2,
beforeLoad: function( event, ui ) {
event.preventDefault();
@@ -603,7 +602,7 @@ test( "#4033 - IE expands hash to full url and misinterprets tab as ajax", funct
var element = $( "<div><ul><li><a href='#tab'>Tab</a></li></ul><div id='tab'></div></div>" );
element.appendTo( "#main" );
element.tabs({
- beforeLoad: function( event, ui ) {
+ beforeLoad: function() {
event.preventDefault();
ok( false, "should not be an ajax tab" );
}
diff --git a/tests/unit/tabs/tabs_deprecated.html b/tests/unit/tabs/tabs_deprecated.html
deleted file mode 100644
index 9d3ecef3a..000000000
--- a/tests/unit/tabs/tabs_deprecated.html
+++ /dev/null
@@ -1,157 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>jQuery UI Tabs Test Suite</title>
-
- <script src="../../jquery.js"></script>
- <script src="../../../external/jquery.cookie.js"></script>
- <link rel="stylesheet" href="../../../external/qunit.css">
- <script src="../../../external/qunit.js"></script>
- <script src="../../jquery.simulate.js"></script>
- <script src="../testsuite.js"></script>
- <script>
- TestHelpers.loadResources({
- css: [ "ui.core", "ui.tabs" ],
- js: [
- "ui/jquery.ui.core.js",
- "ui/jquery.ui.widget.js",
- "ui/jquery.ui.tabs.js"
- ]
- });
- </script>
-
- <script src="tabs_test_helpers.js"></script>
- <script src="tabs_common_deprecated.js"></script>
- <script src="tabs_core.js"></script>
- <script src="tabs_events.js"></script>
- <script src="tabs_methods.js"></script>
- <script src="tabs_options.js"></script>
- <script src="tabs_deprecated.js"></script>
-
- <script src="../swarminject.js"></script>
- <style>
- #tabs8, #tabs8 * {
- margin: 0;
- padding: 0;
- font-size: 12px;
- line-height: 15px;
- }
- </style>
-</head>
-<body>
-
-<h1 id="qunit-header">jQuery UI Tabs Test Suite</h1>
-<h2 id="qunit-banner"></h2>
-<div id="qunit-testrunner-toolbar"></div>
-<h2 id="qunit-userAgent"></h2>
-<ol id="qunit-tests"></ol>
-<div id="qunit-fixture">
-
-<div id="tabs1">
- <ul>
- <li><a href="#fragment-1"><span>1</span></a></li>
- <li><a href="#fragment-2"><span>2</span></a></li>
- <li><a href="#fragment-3"><span>3</span></a></li>
- </ul>
- <div id="fragment-1"></div>
- <div id="fragment-2"></div>
- <div id="fragment-3"></div>
-</div>
-
-<div id="tabs2">
- <ul>
- <li><a href="#colon:test"><span>1</span></a></li>
- <li><a href="#inline-style"><span>2</span></a></li>
- <li><a href="data/test.html#test"><span>3</span></a></li>
- <li aria-controls="custom-id"><a href="data/test.html"><span>4</span></a></li>
- <li><a href="data/test.html" title="∫ßáö Սե"><span>5</span></a></li>
- </ul>
- <div id="colon:test"></div>
- <div style="height: 300px;" id="inline-style"></div>
- <div id="custom-id"></div>
-</div>
-
-<div id="tabs3">
- <div>
- <ul id="tabs3-list">
- <li><a href="#tabs3-1">1</a></li>
- </ul>
- </div>
-</div>
-
-<div id="tabs4">
- <ul id="tabs4-list">
- <li><a href="#tabs4-1">1</a></li>
- </ul>
- <ol>
- <li><a href="#tabs4-1">1</a></li>
- </ol>
-</div>
-
-<div id="tabs4a">
- <ol id="tabs4a-list">
- <li><a href="#tabs4a-1">1</a></li>
- </ol>
- <ul>
- <li><a href="#tabs4a-1">1</a></li>
- </ul>
-</div>
-
-<div id="tabs5">
- <div>
- <ul id="tabs5-list"></ul>
- </div>
-</div>
-
-<div id="tabs6">
- <ul id="tabs6-list">
- <li><a href="#tabs6-1">1</a>
- <ul>
- <li><a href="#item6-3">3</a></li>
- <li><a href="#item6-4">4</a></li>
- </ul>
- </li>
- <li><a href="#tabs6-2">2</a></li>
- </ul>
- <div id="tabs6-1"></div>
- <div id="tabs6-2"></div>
-</div>
-
-<div id="tabs7">
- <ul id="tabs7-list">
- <li><a href="#tabs7-1">1</a></li>
- <li><a href="#tabs7-2">2</a></li>
- </ul>
- <div id="tabs7-2"></div>
- <div id="tabs7-1"></div>
-</div>
-
-<div id="tabs8Wrapper">
- <div id="tabs8">
- <ul id="tabs8-list">
- <li><a href="#tabs8-1">1</a></li>
- <li><a href="#tabs8-2">2</a></li>
- </ul>
- <div id="tabs8-1">
- <p>Lorem ipsum</p>
- <p>Lorem ipsum</p>
- <p>Lorem ipsum</p>
- </div>
- <div id="tabs8-2">
- <p>Lorem ipsum</p>
- </div>
- </div>
-</div>
-
-<div id="tabs9">
- <ul>
- <li>not a tab</li>
- <li><a href="#tabs9-1">tab</a></li>
- </ul>
- <div id="tabs9-1"></div>
-</div>
-
-</div>
-</body>
-</html>
diff --git a/tests/unit/tabs/tabs_deprecated.js b/tests/unit/tabs/tabs_deprecated.js
deleted file mode 100644
index 4a938c078..000000000
--- a/tests/unit/tabs/tabs_deprecated.js
+++ /dev/null
@@ -1,599 +0,0 @@
-(function( $ ) {
-
-var state = TestHelpers.tabs.state;
-
-module( "tabs (deprecated): core" );
-
-test( "panel ids", function() {
- expect( 2 );
-
- var element = $( "#tabs2" ).tabs();
-
- element.one( "tabsbeforeload", function( event, ui ) {
- equal( ui.panel.attr( "id" ), "∫ßáö_Սե", "from title attribute" );
- event.preventDefault();
- });
- element.tabs( "option", "active", 4 );
-
- element.one( "tabsbeforeload", function( event, ui ) {
- ok( /^ui-tabs-\d+$/.test( ui.panel.attr( "id" ) ), "generated id" );
- event.preventDefault();
- });
- element.tabs( "option", "active", 2 );
-});
-
-module( "tabs (deprecated): options" );
-
-asyncTest( "ajaxOptions", function() {
- expect( 2 );
-
- var element = $( "#tabs2" ).tabs({
- ajaxOptions: {
- data: "foo=bar",
- converters: {
- "text html": function() {
- return "test";
- }
- }
- }
- });
- element.one( "tabsbeforeload", function( event, ui ) {
- equal( ui.ajaxSettings.url.replace( /^[^\?]+/, "" ), "?foo=bar", "ajaxOptions.data" );
- });
- element.one( "tabsload", function( event, ui ) {
- equal( $( ui.panel ).html(), "test" );
- start();
- });
- element.tabs( "option", "active", 2 );
-});
-
-asyncTest( "cache", function() {
- expect( 5 );
-
- var element = $( "#tabs2" ).tabs({
- cache: true
- });
- element.one( "tabsshow", function( event, ui ) {
- state( element, 0, 0, 1, 0, 0 );
- });
- element.one( "tabsload", function( event, ui ) {
- ok( true, "tabsload" );
-
- setTimeout(function() {
- element.tabs( "option", "active", 0 );
- state( element, 1, 0, 0, 0, 0 );
-
- element.one( "tabsshow", function( event, ui ) {
- state( element, 0, 0, 1, 0, 0 );
- });
- element.one( "tabsload", function( event, ui ) {
- ok( false, "should be cached" );
- });
- element.tabs( "option", "active", 2 );
- start();
- }, 1 );
- });
- element.tabs( "option", "active", 2 );
- state( element, 0, 0, 1, 0, 0 );
-});
-
-test( "idPrefix", function() {
- expect( 1 );
-
- $( "#tabs2" )
- .one( "tabsbeforeload", function( event, ui ) {
- ok( /^testing-\d+$/.test( ui.panel.attr( "id" ) ), "generated id" );
- event.preventDefault();
- })
- .tabs({
- idPrefix: "testing-",
- active: 2
- });
-});
-
-test( "tabTemplate + panelTemplate", function() {
- // defaults are tested in the add method test
- expect( 11 );
-
- var tab, anchor,
- element = $( "#tabs2" ).tabs({
- tabTemplate: "<li class='customTab'><a href='http://example.com/#{href}'>#{label}</a></li>",
- panelTemplate: "<div class='customPanel'></div>"
- });
- element.one( "tabsadd", function( event, ui ) {
- var anchor = $( ui.tab );
- equal( ui.index, 5, "ui.index" );
- equal( anchor.text(), "New", "ui.tab" );
- equal( anchor.attr( "href" ), "http://example.com/#new", "tab href" );
- ok( anchor.parent().hasClass( "customTab" ), "tab custom class" );
- equal( ui.panel.id, "new", "ui.panel" );
- ok( $( ui.panel ).hasClass( "customPanel" ), "panel custom class" );
- });
- element.tabs( "add", "#new", "New" );
- tab = element.find( ".ui-tabs-nav li" ).last();
- anchor = tab.find( ".ui-tabs-anchor" );
- equal( tab.text(), "New", "label" );
- ok( tab.hasClass( "customTab" ), "tab custom class" );
- equal( anchor.attr( "href" ), "http://example.com/#new", "href" );
- equal( tab.attr( "aria-controls" ), "new", "aria-controls" );
- ok( element.find( "#new" ).hasClass( "customPanel" ), "panel custom class" );
-});
-
-test( "cookie", function() {
- expect( 6 );
-
- var element = $( "#tabs1" ),
- cookieName = "tabs_test",
- cookieObj = { name: cookieName };
- $.cookie( cookieName, null );
- function cookie() {
- return parseInt( $.cookie( cookieName ), 10 );
- }
-
- element.tabs({ cookie: cookieObj });
- equal( cookie(), 0, "initial cookie value" );
-
- element.tabs( "destroy" );
- element.tabs({ active: 1, cookie: cookieObj });
- equal( cookie(), 1, "initial cookie value, from active property" );
-
- element.tabs( "option", "active", 2 );
- equal( cookie(), 2, "cookie value updated after activating" );
-
- element.tabs( "destroy" );
- $.cookie( cookieName, 1 );
- element.tabs({ cookie: cookieObj });
- equal( cookie(), 1, "initial cookie value, from existing cookie" );
-
- element.tabs( "destroy" );
- element.tabs({ cookie: cookieObj, collapsible: true });
- element.tabs( "option", "active", false );
- equal( cookie(), -1, "cookie value for all tabs unselected" );
-
- element.tabs( "destroy" );
- ok( $.cookie( cookieName ) === null, "erase cookie after destroy" );
-});
-
-asyncTest( "spinner", function() {
- expect( 2 );
-
- var element = $( "#tabs2" ).tabs();
-
- element.one( "tabsbeforeload", function( event, ui ) {
- equal( element.find( ".ui-tabs-nav li:eq(2) em" ).length, 1, "beforeload" );
- });
- element.one( "tabsload", function( event, ui ) {
- // wait until after the load finishes before checking for the spinner to be removed
- setTimeout(function() {
- equal( element.find( ".ui-tabs-nav li:eq(2) em" ).length, 0, "load" );
- start();
- }, 1 );
- });
- element.tabs( "option", "active", 2 );
-});
-
-test( "selected", function() {
- expect( 19 );
-
- var element = $( "#tabs1" ).tabs();
- equal( element.tabs( "option", "selected" ), 0, "should be 0 by default" );
- state( element, 1, 0, 0 );
- element.tabs( "destroy" );
-
- location.hash = "#fragment-3";
- element = $( "#tabs1" ).tabs();
- equal( element.tabs( "option", "selected" ), 2, "should be 2 based on URL" );
- state( element, 0, 0, 1 );
- element.tabs( "destroy" );
-
- el = $('#tabs1').tabs({
- selected: -1,
- collapsible: true
- });
- state( element, 0, 0, 0 );
- equal( element.find( ".ui-tabs-nav .ui-state-active" ).length, 0, "no tabs selected" );
- strictEqual( element.tabs( "option", "selected" ), -1 );
-
- element.tabs( "option", "collapsible", false );
- state( element, 1, 0, 0 );
- equal( element.tabs( "option", "selected" ), 0 );
- element.tabs( "destroy" );
-
- element.tabs({
- selected: -1
- });
- state( element, 1, 0, 0 );
- strictEqual( element.tabs( "option", "selected" ), 0 );
- element.tabs( "destroy" );
-
- element.tabs({ selected: 2 });
- equal( element.tabs( "option", "selected" ), 2 );
- state( element, 0, 0, 1 );
-
- element.tabs( "option", "selected", 0 );
- equal( element.tabs( "option", "selected" ), 0 );
- state( element, 1, 0, 0 );
-
- element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 1 ).click();
- equal( element.tabs( "option", "selected" ), 1 );
- state( element, 0, 1, 0 );
-
- element.tabs( "option", "selected", 10 );
- equal( element.tabs( "option", "selected" ), 1 );
- state( element, 0, 1, 0 );
-
- location.hash = "#";
-});
-
-module( "tabs (deprecated): events" );
-
-asyncTest( "load", function() {
- expect( 15 );
-
- var tab, anchor, panelId, panel,
- element = $( "#tabs2" );
-
- // init
- element.one( "tabsload", function( event, ui ) {
- tab = element.find( ".ui-tabs-nav li" ).eq( 2 );
- anchor = tab.find( ".ui-tabs-anchor" );
- panelId = tab.attr( "aria-controls" );
- panel = $( "#" + panelId );
-
- ok( !( "originalEvent" in event ), "originalEvent" );
- strictEqual( ui.tab, anchor[ 0 ], "tab" );
- strictEqual( ui.panel, panel[ 0 ], "panel" );
- equal( $( ui.panel ).find( "p" ).length, 1, "panel html" );
- state( element, 0, 0, 1, 0, 0 );
- tabsload1();
- });
- element.tabs({ active: 2 });
-
- function tabsload1() {
- // .option()
- element.one( "tabsload", function( event, ui ) {
- tab = element.find( ".ui-tabs-nav li" ).eq( 3 );
- anchor = tab.find( ".ui-tabs-anchor" );
- panelId = tab.attr( "aria-controls" );
- panel = $( "#" + panelId );
-
- ok( !( "originalEvent" in event ), "originalEvent" );
- strictEqual( ui.tab, anchor[ 0 ], "tab" );
- strictEqual( ui.panel, panel[ 0 ], "panel" );
- equal( $( ui.panel ).find( "p" ).length, 1, "panel html" );
- state( element, 0, 0, 0, 1, 0 );
- tabsload2();
- });
- element.tabs( "option", "active", 3 );
- }
-
- function tabsload2() {
- // click, change panel content
- element.one( "tabsload", function( event, ui ) {
- tab = element.find( ".ui-tabs-nav li" ).eq( 4 );
- anchor = tab.find( ".ui-tabs-anchor" );
- panelId = tab.attr( "aria-controls" );
- panel = $( "#" + panelId );
-
- equal( event.originalEvent.type, "click", "originalEvent" );
- strictEqual( ui.tab, anchor[ 0 ], "tab" );
- strictEqual( ui.panel, panel[ 0 ], "panel" );
- equal( $( ui.panel ).find( "p" ).length, 1, "panel html" );
- state( element, 0, 0, 0, 0, 1 );
- start();
- });
- element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 4 ).click();
- }
-});
-
-test( "enable", function() {
- expect( 3 );
-
- var element = $( "#tabs1" ).tabs({
- disabled: [ 0, 1 ],
- enable: function( event, ui ) {
- equal( ui.tab, element.find( ".ui-tabs-nav .ui-tabs-anchor" )[ 1 ], "ui.tab" );
- equal( ui.panel, element.find( ".ui-tabs-panel" )[ 1 ], "ui.panel" );
- equal( ui.index, 1, "ui.index" );
- }
- });
- element.tabs( "enable", 1 );
- // shouldn't trigger event
- element.tabs( "enable", 2 );
-});
-
-test( "disable", function() {
- expect( 3 );
-
- var element = $( "#tabs1" ).tabs({
- disable: function( event, ui ) {
- equal( ui.tab, element.find( ".ui-tabs-nav .ui-tabs-anchor" )[ 1 ], "ui.tab" );
- equal( ui.panel, element.find( ".ui-tabs-panel" )[ 1 ], "ui.panel" );
- equal( ui.index, 1, "ui.index" );
- }
- });
- element.tabs( "disable", 1 );
- // shouldn't trigger event
- element.tabs( "disable", 1 );
-});
-
-
-test( "show", function() {
- expect( 13 );
-
- var element = $( "#tabs1" ).tabs({
- active: false,
- collapsible: true
- }),
- anchors = element.find( ".ui-tabs-nav .ui-tabs-anchor" ),
- panels = element.find( ".ui-tabs-panel" );
-
- // from collapsed
- element.one( "tabsshow", function( event, ui ) {
- ok( !( "originalEvent" in event ), "originalEvent" );
- strictEqual( ui.tab, anchors[ 0 ], "ui.tab" );
- strictEqual( ui.panel, panels[ 0 ], "ui.panel" );
- equal( ui.index, 0, "ui.index" );
- state( element, 1, 0, 0 );
- });
- element.tabs( "option", "active", 0 );
- state( element, 1, 0, 0 );
-
- // switching tabs
- element.one( "tabsshow", function( event, ui ) {
- equal( event.originalEvent.type, "click", "originalEvent" );
- strictEqual( ui.tab, anchors[ 1 ], "ui.tab" );
- strictEqual( ui.panel, panels[ 1 ], "ui.panel" );
- equal( ui.index, 1, "ui.index" );
- state( element, 0, 1, 0 );
- });
- anchors.eq( 1 ).click();
- state( element, 0, 1, 0 );
-
- // collapsing
- element.one( "tabsshow", function( event, ui ) {
- ok( false, "collapsing" );
- });
- element.tabs( "option", "active", false );
- state( element, 0, 0, 0 );
-});
-
-test( "select", function() {
- expect( 13 );
-
- var element = $( "#tabs1" ).tabs({
- active: false,
- collapsible: true
- }),
- anchors = element.find( ".ui-tabs-nav .ui-tabs-anchor" ),
- panels = element.find( ".ui-tabs-panel" );
-
- // from collapsed
- element.one( "tabsselect", function( event, ui ) {
- ok( !( "originalEvent" in event ), "originalEvent" );
- strictEqual( ui.tab, anchors[ 0 ], "ui.tab" );
- strictEqual( ui.panel, panels[ 0 ], "ui.panel" );
- equal( ui.index, 0, "ui.index" );
- state( element, 0, 0, 0 );
- });
- element.tabs( "option", "active", 0 );
- state( element, 1, 0, 0 );
-
- // switching tabs
- element.one( "tabsselect", function( event, ui ) {
- equal( event.originalEvent.type, "click", "originalEvent" );
- strictEqual( ui.tab, anchors[ 1 ], "ui.tab" );
- strictEqual( ui.panel, panels[ 1 ], "ui.panel" );
- equal( ui.index, 1, "ui.index" );
- state( element, 1, 0, 0 );
- });
- anchors.eq( 1 ).click();
- state( element, 0, 1, 0 );
-
- // collapsing
- element.one( "tabsselect", function( event, ui ) {
- ok( false, "collapsing" );
- });
- element.tabs( "option", "active", false );
- state( element, 0, 0, 0 );
-});
-
-module( "tabs (deprecated): methods" );
-
-test( "add", function() {
- expect( 28 );
-
- var tab, anchor,
- element = $( "#tabs1" ).tabs();
-
- function stripLeadingSlash( str ) {
- return str.substr( str.charAt( 0 ) === "/" ? 1 : 0 );
- }
-
- state( element, 1, 0, 0 );
-
- // add without index
- element.one( "tabsadd", function( event, ui ) {
- equal( ui.index, 3, "ui.index" );
- equal( $( ui.tab ).text(), "New", "ui.tab" );
- equal( ui.panel.id, "new", "ui.panel" );
- });
- element.tabs( "add", "#new", "New" );
- state( element, 1, 0, 0, 0 );
- tab = element.find( ".ui-tabs-nav li" ).last();
- anchor = tab.find( ".ui-tabs-anchor" );
- equal( tab.text(), "New", "label" );
- equal( stripLeadingSlash( anchor[0].pathname ), stripLeadingSlash( location.pathname ), "href pathname" );
- equal( anchor[0].hash, "#new", "href hash" );
- equal( tab.attr( "aria-controls" ), "new", "aria-controls" );
- ok( !tab.hasClass( "ui-state-hover" ), "not hovered" );
- anchor.simulate( "mouseover" );
- ok( tab.hasClass( "ui-state-hover" ), "hovered" );
- anchor.simulate( "click" );
- state( element, 0, 0, 0, 1 );
-
- // add remote tab with index
- element.one( "tabsadd", function( event, ui ) {
- equal( ui.index, 1, "ui.index" );
- equal( $( ui.tab ).text(), "New Remote", "ui.tab" );
- equal( ui.panel.id, $( ui.tab ).closest( "li" ).attr( "aria-controls" ), "ui.panel" );
- });
- element.tabs( "add", "data/test.html", "New Remote", 1 );
- state( element, 0, 0, 0, 0, 1 );
- tab = element.find( ".ui-tabs-nav li" ).eq( 1 );
- anchor = tab.find( ".ui-tabs-anchor" );
- equal( tab.text(), "New Remote", "label" );
- equal( stripLeadingSlash( stripLeadingSlash(
- anchor[0].pathname.replace( stripLeadingSlash( location.pathname ).split( "/" ).slice( 0, -1 ).join( "/" ), "" )
- ) ), "data/test.html", "href" );
- ok( /^ui-tabs-\d+$/.test( tab.attr( "aria-controls" ) ), "aria controls" );
- ok( !tab.hasClass( "ui-state-hover" ), "not hovered" );
- anchor.simulate( "mouseover" );
- ok( tab.hasClass( "ui-state-hover" ), "hovered" );
- anchor.simulate( "click" );
- state( element, 0, 1, 0, 0, 0 );
-
- // add to empty tab set
- element = $( "<div><ul></ul></div>" ).tabs();
- equal( element.tabs( "option", "active" ), false, "active: false on init" );
- element.one( "tabsadd", function( event, ui ) {
- equal( ui.index, 0, "ui.index" );
- equal( $( ui.tab ).text(), "First", "ui.tab" );
- equal( ui.panel.id, "first", "ui.panel" );
- });
- element.tabs( "add", "#first", "First" );
- state( element, 1 );
- equal( element.tabs( "option", "active" ), 0, "active: 0 after add" );
-});
-
-test( "#5069 - ui.tabs.add creates two tab panels when using a full URL", function() {
- expect( 2 );
-
- var element = $( "#tabs2" ).tabs();
- equal( element.children( "div" ).length, element.find( ".ui-tabs-nav li" ).length );
- element.tabs( "add", "/new", "New" );
- equal( element.children( "div" ).length, element.find( ".ui-tabs-nav li" ).length );
-});
-
-test( "remove", function() {
- expect( 17 );
-
- var element = $( "#tabs1" ).tabs({ active: 1 });
- state( element, 0, 1, 0 );
-
- element.one( "tabsremove", function( event, ui ) {
- equal( ui.index, -1, "ui.index" );
- equal( $( ui.tab ).text(), "2", "ui.tab" );
- equal( ui.panel.id, "fragment-2", "ui.panel" );
- });
- element.tabs( "remove", 1 );
- state( element, 0, 1 );
- equal( element.tabs( "option", "active" ), 1 );
- equal( element.find( ".ui-tabs-nav li a[href$='fragment-2']" ).length, 0,
- "remove correct list item" );
- equal( element.find( "#fragment-2" ).length, 0, "remove correct panel" );
-
- element.one( "tabsremove", function( event, ui ) {
- equal( ui.index, -1, "ui.index" );
- equal( $( ui.tab ).text(), "3", "ui.tab" );
- equal( ui.panel.id, "fragment-3", "ui.panel" );
- });
- element.tabs( "remove", 1 );
- state( element, 1 );
- equal( element.tabs( "option", "active"), 0 );
-
- element.one( "tabsremove", function( event, ui ) {
- equal( ui.index, -1, "ui.index" );
- equal( $( ui.tab ).text(), "1", "ui.tab" );
- equal( ui.panel.id, "fragment-1", "ui.panel" );
- });
- element.tabs( "remove", 0 );
- equal( element.tabs( "option", "active" ), false );
-});
-
-test( "select", function() {
- expect( 23 );
-
- var element = $( "#tabs1" ).tabs();
- state( element, 1, 0, 0 );
- element.tabs( "select", 1 );
- state( element, 0, 1, 0 );
- equal( element.tabs( "option", "active" ), 1, "active" );
- equal( element.tabs( "option", "selected" ), 1, "selected" );
- element.tabs( "destroy" );
-
- element.tabs({ collapsible: true });
- state( element, 1, 0, 0 );
- element.tabs( "select", 0 );
- state( element, 0, 0, 0 );
- equal( element.tabs( "option", "active" ), false, "active" );
- equal( element.tabs( "option", "selected" ), -1, "selected" );
- element.tabs( "destroy" );
-
- element.tabs({ collapsible: true });
- element.tabs( "select", -1 );
- state( element, 0, 0, 0 );
- equal( element.tabs( "option", "active" ), false, "active" );
- equal( element.tabs( "option", "selected" ), -1, "selected" );
- element.tabs( "destroy" );
-
- element.tabs();
- state( element, 1, 0, 0 );
- equal( element.tabs( "option", "active" ), 0, "active" );
- equal( element.tabs( "option", "selected" ), 0, "selected" );
- element.tabs( "select", 0 );
- state( element, 1, 0, 0 );
- equal( element.tabs( "option", "active" ), 0, "active" );
- equal( element.tabs( "option", "selected" ), 0, "selected" );
- element.tabs( "select", -1 );
- state( element, 1, 0, 0 );
- equal( element.tabs( "option", "active" ), 0, "active" );
- equal( element.tabs( "option", "selected" ), 0, "selected" );
-
- element.tabs( "select", "#fragment-2" );
- state( element, 0, 1, 0 );
- equal( element.tabs( "option", "active" ), 1, "active" );
- equal( element.tabs( "option", "selected" ), 1, "selected" );
-});
-
-test( "length", function() {
- expect( 2 );
-
- equal( $( "#tabs1" ).tabs().tabs( "length" ), 3, "basic tabs" );
- equal( $( "#tabs2" ).tabs().tabs( "length" ), 5, "ajax tabs with missing panels" );
-});
-
-test( "url", function() {
- expect( 2 );
-
- var element = $( "#tabs2" ).tabs(),
- anchor = element.find( ".ui-tabs-anchor" ).eq( 3 );
-
- element.tabs( "url", 3, "data/test2.html" );
- equal( anchor.attr( "href" ), "data/test2.html", "href was updated" );
- element.one( "tabsbeforeload", function( event, ui ) {
- equal( ui.ajaxSettings.url, "data/test2.html", "ajaxSettings.url" );
- event.preventDefault();
- });
- element.tabs( "option", "active", 3 );
-});
-
-asyncTest( "abort", function() {
- expect( 1 );
-
- var element = $( "#tabs2" ).tabs();
- element.one( "tabsbeforeload", function( event, ui ) {
- ui.jqXHR.error(function( jqXHR, status ) {
- equal( status, "abort", "aborted" );
- start();
- });
- });
- // prevent IE from caching the request, so that it won't resolve before we call abort
- element.find( ".ui-tabs-nav li:eq(2) .ui-tabs-anchor" ).attr( "href", function( href ) {
- return href + "?" + (+ new Date());
- });
- element.tabs( "option", "active", 2 );
- element.tabs( "abort" );
-});
-
-}( jQuery ) );
diff --git a/tests/unit/tabs/tabs_events.js b/tests/unit/tabs/tabs_events.js
index 57011bdad..f9b1755f7 100644
--- a/tests/unit/tabs/tabs_events.js
+++ b/tests/unit/tabs/tabs_events.js
@@ -253,16 +253,33 @@ test( "beforeLoad", function() {
equal( panel.html().toLowerCase(), "<p>testing</p>", "panel html after" );
});
-if ( $.uiBackCompat === false ) {
- asyncTest( "load", function() {
- expect( 21 );
+asyncTest( "load", function() {
+ expect( 21 );
- var tab, panelId, panel,
- element = $( "#tabs2" );
+ var tab, panelId, panel,
+ element = $( "#tabs2" );
+
+ // init
+ element.one( "tabsload", function( event, ui ) {
+ tab = element.find( ".ui-tabs-nav li" ).eq( 2 );
+ panelId = tab.attr( "aria-controls" );
+ panel = $( "#" + panelId );
+
+ ok( !( "originalEvent" in event ), "originalEvent" );
+ equal( ui.tab.length, 1, "tab length" );
+ strictEqual( ui.tab[ 0 ], tab[ 0 ], "tab" );
+ equal( ui.panel.length, 1, "panel length" );
+ strictEqual( ui.panel[ 0 ], panel[ 0 ], "panel" );
+ equal( ui.panel.find( "p" ).length, 1, "panel html" );
+ state( element, 0, 0, 1, 0, 0 );
+ tabsload1();
+ });
+ element.tabs({ active: 2 });
- // init
+ function tabsload1() {
+ // .option()
element.one( "tabsload", function( event, ui ) {
- tab = element.find( ".ui-tabs-nav li" ).eq( 2 );
+ tab = element.find( ".ui-tabs-nav li" ).eq( 3 );
panelId = tab.attr( "aria-controls" );
panel = $( "#" + panelId );
@@ -272,49 +289,30 @@ if ( $.uiBackCompat === false ) {
equal( ui.panel.length, 1, "panel length" );
strictEqual( ui.panel[ 0 ], panel[ 0 ], "panel" );
equal( ui.panel.find( "p" ).length, 1, "panel html" );
- state( element, 0, 0, 1, 0, 0 );
- tabsload1();
+ state( element, 0, 0, 0, 1, 0 );
+ tabsload2();
});
- element.tabs({ active: 2 });
-
- function tabsload1() {
- // .option()
- element.one( "tabsload", function( event, ui ) {
- tab = element.find( ".ui-tabs-nav li" ).eq( 3 );
- panelId = tab.attr( "aria-controls" );
- panel = $( "#" + panelId );
-
- ok( !( "originalEvent" in event ), "originalEvent" );
- equal( ui.tab.length, 1, "tab length" );
- strictEqual( ui.tab[ 0 ], tab[ 0 ], "tab" );
- equal( ui.panel.length, 1, "panel length" );
- strictEqual( ui.panel[ 0 ], panel[ 0 ], "panel" );
- equal( ui.panel.find( "p" ).length, 1, "panel html" );
- state( element, 0, 0, 0, 1, 0 );
- tabsload2();
- });
- element.tabs( "option", "active", 3 );
- }
+ element.tabs( "option", "active", 3 );
+ }
- function tabsload2() {
- // click, change panel content
- element.one( "tabsload", function( event, ui ) {
- tab = element.find( ".ui-tabs-nav li" ).eq( 4 );
- panelId = tab.attr( "aria-controls" );
- panel = $( "#" + panelId );
-
- equal( event.originalEvent.type, "click", "originalEvent" );
- equal( ui.tab.length, 1, "tab length" );
- strictEqual( ui.tab[ 0 ], tab[ 0 ], "tab" );
- equal( ui.panel.length, 1, "panel length" );
- strictEqual( ui.panel[ 0 ], panel[ 0 ], "panel" );
- equal( ui.panel.find( "p" ).length, 1, "panel html" );
- state( element, 0, 0, 0, 0, 1 );
- start();
- });
- element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 4 ).click();
- }
- });
-}
+ function tabsload2() {
+ // click, change panel content
+ element.one( "tabsload", function( event, ui ) {
+ tab = element.find( ".ui-tabs-nav li" ).eq( 4 );
+ panelId = tab.attr( "aria-controls" );
+ panel = $( "#" + panelId );
+
+ equal( event.originalEvent.type, "click", "originalEvent" );
+ equal( ui.tab.length, 1, "tab length" );
+ strictEqual( ui.tab[ 0 ], tab[ 0 ], "tab" );
+ equal( ui.panel.length, 1, "panel length" );
+ strictEqual( ui.panel[ 0 ], panel[ 0 ], "panel" );
+ equal( ui.panel.find( "p" ).length, 1, "panel html" );
+ state( element, 0, 0, 0, 0, 1 );
+ start();
+ });
+ element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 4 ).click();
+ }
+});
}( jQuery ) );
diff --git a/tests/unit/tabs/tabs_methods.js b/tests/unit/tabs/tabs_methods.js
index fa6535158..076c3f379 100644
--- a/tests/unit/tabs/tabs_methods.js
+++ b/tests/unit/tabs/tabs_methods.js
@@ -198,11 +198,7 @@ asyncTest( "load", function() {
ok( !( "originalEvent" in event ), "originalEvent" );
equal( uiTab.length, 1, "tab length" );
- if ( $.uiBackCompat === false ) {
- strictEqual( uiTab[ 0 ], tab[ 0 ], "tab" );
- } else {
- strictEqual( uiTab[ 0 ], tab.find( ".ui-tabs-anchor" )[ 0 ], "tab" );
- }
+ strictEqual( uiTab[ 0 ], tab[ 0 ], "tab" );
equal( uiPanel.length, 1, "panel length" );
strictEqual( uiPanel[ 0 ], panel[ 0 ], "panel" );
equal( uiPanel.find( "p" ).length, 1, "panel html" );
@@ -249,11 +245,7 @@ asyncTest( "load", function() {
ok( !( "originalEvent" in event ), "originalEvent" );
equal( uiTab.length, 1, "tab length" );
- if ( $.uiBackCompat === false ) {
- strictEqual( uiTab[ 0 ], tab[ 0 ], "tab" );
- } else {
- strictEqual( uiTab[ 0 ], tab.find( ".ui-tabs-anchor" )[ 0 ], "tab" );
- }
+ strictEqual( uiTab[ 0 ], tab[ 0 ], "tab" );
equal( uiPanel.length, 1, "panel length" );
strictEqual( uiPanel[ 0 ], panel[ 0 ], "panel" );
state( element, 0, 0, 0, 1, 0 );
diff --git a/tests/unit/tabs/tabs_options.js b/tests/unit/tabs/tabs_options.js
index 1b468f2b6..f6e89e84f 100644
--- a/tests/unit/tabs/tabs_options.js
+++ b/tests/unit/tabs/tabs_options.js
@@ -73,29 +73,27 @@ test( "{ active: Number }", function() {
state( element, 0, 1, 0 );
});
-if ( $.uiBackCompat === false ) {
- test( "{ active: -Number }", function() {
- expect( 8 );
-
- var element = $( "#tabs1" ).tabs({
- active: -1
- });
- equal( element.tabs( "option", "active" ), 2 );
- state( element, 0, 0, 1 );
-
- element.tabs( "option", "active", -2 );
- equal( element.tabs( "option", "active" ), 1 );
- state( element, 0, 1, 0 );
-
- element.tabs( "option", "active", -10 );
- equal( element.tabs( "option", "active" ), 1 );
- state( element, 0, 1, 0 );
-
- element.tabs( "option", "active", -3 );
- equal( element.tabs( "option", "active" ), 0 );
- state( element, 1, 0, 0 );
+test( "{ active: -Number }", function() {
+ expect( 8 );
+
+ var element = $( "#tabs1" ).tabs({
+ active: -1
});
-}
+ equal( element.tabs( "option", "active" ), 2 );
+ state( element, 0, 0, 1 );
+
+ element.tabs( "option", "active", -2 );
+ equal( element.tabs( "option", "active" ), 1 );
+ state( element, 0, 1, 0 );
+
+ element.tabs( "option", "active", -10 );
+ equal( element.tabs( "option", "active" ), 1 );
+ state( element, 0, 1, 0 );
+
+ element.tabs( "option", "active", -3 );
+ equal( element.tabs( "option", "active" ), 0 );
+ state( element, 1, 0, 0 );
+});
test( "active - mismatched tab/panel order", function() {
expect( 3 );
@@ -292,7 +290,7 @@ test( "hide and show: false", function() {
show: false,
hide: false
}),
- widget = element.data( "tabs" ),
+ widget = element.data( "ui-tabs" ),
panels = element.find( ".ui-tabs-panel" );
widget._show = function() {
ok( false, "_show() called" );
@@ -313,7 +311,7 @@ asyncTest( "hide and show - animation", function() {
show: "drop",
hide: 2000
}),
- widget = element.data( "tabs" ),
+ widget = element.data( "ui-tabs" ),
panels = element.find( ".ui-tabs-panel" );
widget._show = function( element, options, callback ) {
strictEqual( element[ 0 ], panels[ 1 ], "correct element in _show()" );
diff --git a/tests/unit/testsuite.js b/tests/unit/testsuite.js
index 06890d8d9..f3c0982fb 100644
--- a/tests/unit/testsuite.js
+++ b/tests/unit/testsuite.js
@@ -12,6 +12,10 @@ function includeScript( url ) {
document.write( "<script src='../../../" + url + "'></script>" );
}
+function url( value ) {
+ return value + (/\?/.test(value) ? "&" : "?") + new Date().getTime() + "" + parseInt(Math.random() * 100000, 10);
+}
+
reset = QUnit.reset;
QUnit.reset = function() {
// Ensure jQuery events and data on the fixture are properly removed
@@ -65,11 +69,11 @@ TestHelpers.testJshint = function( module ) {
$.when(
$.ajax({
- url: "../../../ui/.jshintrc",
+ url: url("../../../ui/.jshintrc"),
dataType: "json"
}),
$.ajax({
- url: "../../../ui/jquery.ui." + module + ".js",
+ url: url("../../../ui/jquery.ui." + module + ".js"),
dataType: "text"
})
).done(function( hintArgs, srcArgs ) {
@@ -112,7 +116,7 @@ function testWidgetDefaults( widget, defaults ) {
// ensure that all defaults were tested
test( "tested defaults", function() {
var count = 0;
- $.each( pluginDefaults, function( key, val ) {
+ $.each( pluginDefaults, function( key ) {
expect( ++count );
ok( key in defaults, key );
});
@@ -166,6 +170,14 @@ TestHelpers.commonWidgetTests = function( widget, settings ) {
};
/*
+ * Taken from https://github.com/jquery/qunit/tree/master/addons/close-enough
+ */
+window.closeEnough = function( actual, expected, maxDifference, message ) {
+ var passes = (actual === expected) || Math.abs(actual - expected) <= maxDifference;
+ QUnit.push(passes, actual, expected, message);
+};
+
+/*
* Experimental assertion for comparing DOM objects.
*
* Serializes an element and some properties and attributes and it's children if any, otherwise the text.
@@ -201,6 +213,33 @@ window.domEqual = function( selector, modifier, message ) {
"title"
];
+ function getElementStyles( elem ) {
+ var key, len,
+ style = elem.ownerDocument.defaultView ?
+ elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
+ elem.currentStyle,
+ styles = {};
+
+ if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
+ len = style.length;
+ while ( len-- ) {
+ key = style[ len ];
+ if ( typeof style[ key ] === "string" ) {
+ styles[ $.camelCase( key ) ] = style[ key ];
+ }
+ }
+ // support: Opera, IE <9
+ } else {
+ for ( key in style ) {
+ if ( typeof style[ key ] === "string" ) {
+ styles[ key ] = style[ key ];
+ }
+ }
+ }
+
+ return styles;
+ }
+
function extract( elem ) {
if ( !elem || !elem.length ) {
QUnit.push( false, actual, expected,
@@ -218,12 +257,13 @@ window.domEqual = function( selector, modifier, message ) {
var value = elem.attr( attr );
result[ attr ] = value !== undefined ? value : "";
});
+ result.style = getElementStyles( elem[ 0 ] );
result.events = $._data( elem[ 0 ], "events" );
result.data = $.extend( {}, elem.data() );
delete result.data[ $.expando ];
children = elem.children();
if ( children.length ) {
- result.children = elem.children().map(function( ind ) {
+ result.children = elem.children().map(function() {
return extract( $( this ) );
}).get();
} else {
diff --git a/tests/unit/tooltip/tooltip.html b/tests/unit/tooltip/tooltip.html
index f6e60b367..ec616be13 100644
--- a/tests/unit/tooltip/tooltip.html
+++ b/tests/unit/tooltip/tooltip.html
@@ -43,8 +43,13 @@
<input title="inputtitle">
<span id="multiple-describedby" aria-describedby="fixture-span" title="...">aria-describedby</span>
<span id="fixture-span" title="title-text">span</span>
+ <span id="contains-tooltipped" title="parent"><span id="contained-tooltipped" title="child">baz</span></span>
</div>
+<form id="tooltip-form">
+ <input name="title" title="attroperties">
+</form>
+
</div>
</body>
</html>
diff --git a/tests/unit/tooltip/tooltip_common.js b/tests/unit/tooltip/tooltip_common.js
index 6d503aecd..2d6ea91ec 100644
--- a/tests/unit/tooltip/tooltip_common.js
+++ b/tests/unit/tooltip/tooltip_common.js
@@ -3,11 +3,11 @@ TestHelpers.commonWidgetTests( "tooltip", {
content: function() {},
disabled: false,
hide: true,
- items: "[title]",
+ items: "[title]:not([disabled])",
position: {
- my: "left+15 center",
- at: "right center",
- collision: "flipfit flipfit"
+ my: "left top+15",
+ at: "left bottom",
+ collision: "flipfit flip"
},
show: true,
tooltipClass: null,
diff --git a/tests/unit/tooltip/tooltip_core.js b/tests/unit/tooltip/tooltip_core.js
index 2b39253a2..69936dba2 100644
--- a/tests/unit/tooltip/tooltip_core.js
+++ b/tests/unit/tooltip/tooltip_core.js
@@ -44,4 +44,67 @@ test( "accessibility", function() {
equal( element.attr( "title" ), "...", "title restored when closed" );
});
+test( "delegated removal", function() {
+ expect( 2 );
+
+ var container = $( "#contains-tooltipped" ).tooltip(),
+ element = $( "#contained-tooltipped" );
+
+ element.trigger( "mouseover" );
+ equal( $( ".ui-tooltip" ).length, 1 );
+
+ container.empty();
+ equal( $( ".ui-tooltip" ).length, 0 );
+});
+
+test( "nested tooltips", function() {
+ expect( 2 );
+
+ var child = $( "#contained-tooltipped" ),
+ parent = $( "#contains-tooltipped" ).tooltip({
+ show: null,
+ hide: null
+ });
+
+ parent.trigger( "mouseover" );
+ equal( $( ".ui-tooltip:visible" ).text(), "parent" );
+
+ child.trigger( "mouseover" );
+ equal( $( ".ui-tooltip" ).text(), "child" );
+});
+
+// #8742
+test( "form containing an input with name title", function() {
+ expect( 4 );
+
+ var form = $( "#tooltip-form" ).tooltip({
+ show: null,
+ hide: null
+ }),
+ input = form.find( "[name=title]" );
+
+ equal( $( ".ui-tooltip" ).length, 0, "no tooltips on init" );
+
+ input.trigger( "mouseover" );
+ equal( $( ".ui-tooltip" ).length, 1, "tooltip for input" );
+ input.trigger( "mouseleave" );
+ equal( $( ".ui-tooltip" ).length, 0, "tooltip for input closed" );
+
+ form.trigger( "mouseover" );
+ equal( $( ".ui-tooltip" ).length, 0, "no tooltip for form" );
+});
+
+test( "tooltip on .ui-state-disabled element", function() {
+ expect( 2 );
+
+ var container = $( "#contains-tooltipped" ).tooltip(),
+ element = $( "#contained-tooltipped" ).addClass( "ui-state-disabled" );
+
+ element.trigger( "mouseover" );
+ equal( $( ".ui-tooltip" ).length, 1 );
+
+ container.empty();
+ equal( $( ".ui-tooltip" ).length, 0 );
+});
+
}( jQuery ) );
diff --git a/tests/unit/tooltip/tooltip_events.js b/tests/unit/tooltip/tooltip_events.js
index fc5f1acc5..de16471ae 100644
--- a/tests/unit/tooltip/tooltip_events.js
+++ b/tests/unit/tooltip/tooltip_events.js
@@ -26,14 +26,15 @@ test( "mouse events", function() {
expect( 2 );
var element = $( "#tooltipped1" ).tooltip();
- element.one( "tooltipopen", function( event ) {
+ element.bind( "tooltipopen", function( event ) {
deepEqual( event.originalEvent.type, "mouseover" );
});
element.trigger( "mouseover" );
- element.one( "tooltipclose", function( event ) {
+ element.bind( "tooltipclose", function( event ) {
deepEqual( event.originalEvent.type, "mouseleave" );
});
+ element.trigger( "focusout" );
element.trigger( "mouseleave" );
});
@@ -41,43 +42,16 @@ test( "focus events", function() {
expect( 2 );
var element = $( "#tooltipped1" ).tooltip();
- element.one( "tooltipopen", function( event ) {
+ element.bind( "tooltipopen", function( event ) {
deepEqual( event.originalEvent.type, "focusin" );
});
element.trigger( "focusin" );
- element.one( "tooltipclose", function( event ) {
- deepEqual( event.originalEvent.type, "focusout" );
- });
- element.trigger( "focusout" );
-});
-
-asyncTest( "mixed events", function() {
- expect( 2 );
- var element = $( "#tooltipped1" ).tooltip();
-
- element.one( "tooltipopen", function( event ) {
- deepEqual( event.originalEvent.type, "focusin" );
- });
- element.simulate( "focus" );
-
- element.one( "tooltipopen", function() {
- ok( false, "open triggered while already open" );
- });
- element.trigger( "mouseover" );
-
element.bind( "tooltipclose", function( event ) {
- ok( false, "close triggered while still focused" );
- });
- element.trigger( "mouseleave" );
- element.unbind( "tooltipclose" );
-
- // blurring is async in IE
- element.one( "tooltipclose", function( event ) {
deepEqual( event.originalEvent.type, "focusout" );
- start();
});
- element.simulate( "blur" );
+ element.trigger( "mouseleave" );
+ element.trigger( "focusout" );
});
}( jQuery ) );
diff --git a/tests/unit/tooltip/tooltip_options.js b/tests/unit/tooltip/tooltip_options.js
index db193e8fa..f9da27fb7 100644
--- a/tests/unit/tooltip/tooltip_options.js
+++ b/tests/unit/tooltip/tooltip_options.js
@@ -2,6 +2,14 @@
module( "tooltip: options" );
+test( "disabled: true", function() {
+ expect( 1 );
+ $( "#tooltipped1" ).tooltip({
+ disabled: true
+ }).tooltip( "open" );
+ equal( $( ".ui-tooltip" ).length, 0 );
+});
+
test( "content: default", function() {
expect( 1 );
var element = $( "#tooltipped1" ).tooltip().tooltip( "open" );
@@ -67,7 +75,7 @@ test( "content: change while open", function() {
test( "content: string", function() {
expect( 1 );
- var element = $( "#tooltipped1" ).tooltip({
+ $( "#tooltipped1" ).tooltip({
content: "just a string",
open: function( event, ui ) {
equal( ui.tooltip.text(), "just a string" );
@@ -103,4 +111,47 @@ test( "tooltipClass", function() {
ok( $( "#" + element.data( "ui-tooltip-id" ) ).hasClass( "custom" ) );
});
+test( "track + show delay", function() {
+ expect( 2 );
+ var event,
+ leftVal = 314,
+ topVal = 159,
+ offsetVal = 26,
+ element = $( "#tooltipped1" ).tooltip({
+ track: true,
+ show: {
+ delay: 1
+ },
+ position: {
+ my: "left+" + offsetVal + " top+" + offsetVal,
+ at: "right bottom"
+ }
+ });
+
+ event = $.Event( "mouseover" );
+ event.target = $( "#tooltipped1" )[ 0 ];
+ event.originalEvent = { type: "mouseover" };
+ event.pageX = leftVal;
+ event.pageY = topVal;
+ element.trigger( event );
+
+ event = $.Event( "mousemove" );
+ event.target = $( "#tooltipped1" )[ 0 ];
+ event.originalEvent = { type: "mousemove" };
+ event.pageX = leftVal;
+ event.pageY = topVal;
+ element.trigger( event );
+
+ equal( $( ".ui-tooltip" ).css( "left" ), leftVal + offsetVal + "px" );
+ equal( $( ".ui-tooltip" ).css( "top" ), topVal + offsetVal + "px" );
+});
+
+test( "track and programmatic focus", function() {
+ expect( 1 );
+ $( "#qunit-fixture div input" ).tooltip({
+ track: true
+ }).focus();
+ equal( "inputtitle", $( ".ui-tooltip" ).text() );
+});
+
}( jQuery ) );
diff --git a/tests/unit/widget/widget_core.js b/tests/unit/widget/widget_core.js
index 5efd91268..18b93d92e 100644
--- a/tests/unit/widget/widget_core.js
+++ b/tests/unit/widget/widget_core.js
@@ -4,6 +4,7 @@ module( "widget factory", {
teardown: function() {
if ( $.ui ) {
delete $.ui.testWidget;
+ delete $.fn.testWidget;
}
}
});
@@ -88,9 +89,9 @@ test( "custom selector expression", function() {
});
test( "jQuery usage", function() {
- expect( 16 );
+ expect( 14 );
- var elem, instance, ret, bcInstance,
+ var elem, instance, ret,
shouldCreate = false;
$.widget( "ui.testWidget", {
@@ -133,12 +134,6 @@ test( "jQuery usage", function() {
ret = elem.testWidget( "methodWithParams", "value1", "value2" );
equal( ret, elem, "jQuery object returned from method call" );
- // 1.9 BC for #7810
- // TODO remove
- bcInstance = elem.data("testWidget");
- equal( typeof bcInstance, "object", "instance stored in .data(pluginName)" );
- equal( bcInstance.element[0], elem[0], "element stored on widget" );
-
ret = elem.testWidget( "getterSetterMethod" );
equal( ret, 5, "getter/setter can act as getter" );
ret = elem.testWidget( "getterSetterMethod", 30 );
@@ -313,7 +308,7 @@ test( "re-init", function() {
_init: function() {
actions.push( "init" );
},
- _setOption: function( key, value ) {
+ _setOption: function( key ) {
actions.push( "option" + key );
}
});
@@ -331,8 +326,8 @@ test( "re-init", function() {
deepEqual( actions, [ "optionfoo", "init" ], "correct methods called on re-init with options" );
});
-test( "inheritance - options", function() {
- expect( 4 );
+test( "inheritance", function() {
+ expect( 6 );
// #5830 - Widget: Using inheritance overwrites the base classes options
$.widget( "ui.testWidgetBase", {
options: {
@@ -353,6 +348,8 @@ test( "inheritance - options", function() {
}
});
+ equal( $.ui.testWidgetBase.prototype.widgetEventPrefix, "testWidgetBase",
+ "base class event prefix" );
deepEqual( $.ui.testWidgetBase.prototype.options.obj, {
key1: "foo",
key2: "bar"
@@ -360,6 +357,8 @@ test( "inheritance - options", function() {
deepEqual( $.ui.testWidgetBase.prototype.options.arr, [ "testing" ],
"base class option array not overridden");
+ equal( $.ui.testWidgetExtension.prototype.widgetEventPrefix, "testWidgetExtension",
+ "extension class event prefix" );
deepEqual( $.ui.testWidgetExtension.prototype.options.obj, {
key1: "baz",
key2: "bar"
@@ -661,6 +660,46 @@ test( "._on() to element (default)", function() {
.trigger( "keydown" );
});
+test( "._on() to element with suppressDisabledCheck", function() {
+ expect( 18 );
+ var that, widget;
+ $.widget( "ui.testWidget", {
+ _create: function() {
+ that = this;
+ this._on( true, {
+ keyup: this.keyup,
+ keydown: "keydown"
+ });
+ },
+ keyup: function( event ) {
+ equal( that, this );
+ equal( that.element[0], event.currentTarget );
+ equal( "keyup", event.type );
+ },
+ keydown: function( event ) {
+ equal( that, this );
+ equal( that.element[0], event.currentTarget );
+ equal( "keydown", event.type );
+ }
+ });
+ widget = $( "<div></div>" )
+ .testWidget()
+ .trigger( "keyup" )
+ .trigger( "keydown" );
+ widget
+ .testWidget( "disable" )
+ .trigger( "keyup" )
+ .trigger( "keydown" );
+ widget
+ .testWidget( "enable" )
+ .trigger( "keyup" )
+ .trigger( "keydown" );
+ widget
+ .testWidget( "destroy" )
+ .trigger( "keyup" )
+ .trigger( "keydown" );
+});
+
test( "._on() to descendent", function() {
expect( 12 );
var that, widget, descendant;
@@ -760,6 +799,30 @@ test( "_on() with delegate", function() {
$.ui.testWidget();
});
+test( "_on() with delegate to descendent", function() {
+ expect( 4 );
+ $.widget( "ui.testWidget", {
+ _create: function() {
+ this.target = $( "<p><strong>hello</strong> world</p>" );
+ this.child = this.target.children();
+ this._on( this.target, {
+ "keyup": "handlerDirect",
+ "keyup strong": "handlerDelegated"
+ });
+ this.child.trigger( "keyup" );
+ },
+ handlerDirect: function( event ) {
+ deepEqual( event.currentTarget, this.target[ 0 ] );
+ deepEqual( event.target, this.child[ 0 ] );
+ },
+ handlerDelegated: function( event ) {
+ deepEqual( event.currentTarget, this.child[ 0 ] );
+ deepEqual( event.target, this.child[ 0 ] );
+ }
+ });
+ $.ui.testWidget();
+});
+
test( "_on() to common element", function() {
expect( 1 );
$.widget( "ui.testWidget", {
@@ -772,7 +835,7 @@ test( "_on() to common element", function() {
ok( true, "handler triggered" );
}
});
- var widget = $( "#widget" ).testWidget().data( "testWidget" );
+ var widget = $( "#widget" ).testWidget().data( "ui-testWidget" );
$( "#widget-wrapper" ).testWidget();
widget.destroy();
$( document ).trigger( "customevent" );
@@ -784,7 +847,7 @@ test( "_off() - single event", function() {
$.widget( "ui.testWidget", {} );
var shouldTriggerWidget, shouldTriggerOther,
element = $( "#widget" ),
- widget = element.testWidget().data( "testWidget" );
+ widget = element.testWidget().data( "ui-testWidget" );
widget._on( element, { foo: function() {
ok( shouldTriggerWidget, "foo called from _on" );
}});
@@ -805,7 +868,7 @@ test( "_off() - multiple events", function() {
$.widget( "ui.testWidget", {} );
var shouldTriggerWidget, shouldTriggerOther,
element = $( "#widget" ),
- widget = element.testWidget().data( "testWidget" );
+ widget = element.testWidget().data( "ui-testWidget" );
widget._on( element, {
foo: function() {
ok( shouldTriggerWidget, "foo called from _on" );
@@ -833,7 +896,7 @@ test( "_off() - all events", function() {
$.widget( "ui.testWidget", {} );
var shouldTriggerWidget, shouldTriggerOther,
element = $( "#widget" ),
- widget = element.testWidget().data( "testWidget" );
+ widget = element.testWidget().data( "ui-testWidget" );
widget._on( element, {
foo: function() {
ok( shouldTriggerWidget, "foo called from _on" );
@@ -959,11 +1022,11 @@ test( "._trigger() - cancelled event", function() {
});
$( "#widget" ).testWidget({
- foo: function( event, ui ) {
+ foo: function() {
ok( true, "callback invoked even if event is cancelled" );
}
})
- .bind( "testwidgetfoo", function( event, ui ) {
+ .bind( "testwidgetfoo", function() {
ok( true, "event was triggered" );
return false;
});
@@ -978,7 +1041,7 @@ test( "._trigger() - cancelled callback", function() {
});
$( "#widget" ).testWidget({
- foo: function( event, ui ) {
+ foo: function() {
return false;
}
});
@@ -1138,6 +1201,12 @@ test( "._trigger() - instance as element", function() {
});
});
+ test( "auto-destroy - .remove() when disabled", function() {
+ shouldDestroy( true, function() {
+ $( "#widget" ).testWidget({ disabled: true }).remove();
+ });
+ });
+
test( "auto-destroy - .remove() on parent", function() {
shouldDestroy( true, function() {
$( "#widget" ).testWidget().parent().remove();
@@ -1167,6 +1236,13 @@ test( "._trigger() - instance as element", function() {
$( "#widget" ).testWidget().detach();
});
});
+
+ test( "destroy - remove event bubbling", function() {
+ shouldDestroy( false, function() {
+ $( "<div>child</div>" ).appendTo( $( "#widget" ).testWidget() )
+ .trigger( "remove" );
+ });
+ });
}());
test( "redefine", function() {
@@ -1233,6 +1309,21 @@ test( "redefine deep prototype chain", function() {
delete $.ui.testWidget2;
});
+test( "redefine - widgetEventPrefix", function() {
+ expect( 2 );
+
+ $.widget( "ui.testWidget", {
+ widgetEventPrefix: "test"
+ });
+ equal( $.ui.testWidget.prototype.widgetEventPrefix, "test",
+ "cusotm prefix in original" );
+
+ $.widget( "ui.testWidget", $.ui.testWidget, {} );
+ equal( $.ui.testWidget.prototype.widgetEventPrefix, "test",
+ "cusotm prefix in extension" );
+
+});
+
asyncTest( "_delay", function() {
expect( 6 );
var order = 0,
@@ -1259,4 +1350,56 @@ asyncTest( "_delay", function() {
$( "#widget" ).testWidget();
});
+test( "$.widget.bridge()", function() {
+ expect( 9 );
+
+ var instance, ret,
+ elem = $( "<div>" );
+
+ function TestWidget( options, element ) {
+ deepEqual( options, { foo: "bar" }, "options passed" );
+ strictEqual( element, elem[ 0 ], "element passed" );
+ }
+
+ $.extend( TestWidget.prototype, {
+ method: function( param ) {
+ ok( true, "method called via .pluginName(methodName)" );
+ equal( param, "value1",
+ "parameter passed via .pluginName(methodName, param)" );
+ },
+ getter: function() {
+ return "qux";
+ }
+ });
+
+ $.widget.bridge( "testWidget", TestWidget );
+
+ ok( $.isFunction( $.fn.testWidget ), "jQuery plugin was created" );
+
+ strictEqual( elem.testWidget({ foo: "bar" }), elem, "plugin returns original jQuery object" );
+ instance = elem.data( "testWidget" );
+ equal( typeof instance, "object", "instance stored in .data(pluginName)" );
+
+ ret = elem.testWidget( "method", "value1" );
+ equal( ret, elem, "jQuery object returned from method call" );
+
+ ret = elem.testWidget( "getter" );
+ equal( ret, "qux", "getter returns value" );
+});
+
+test( "$.widget.bridge() - widgetFullName", function() {
+ expect( 1 );
+
+ var instance,
+ elem = $( "<div>" );
+
+ function TestWidget() {}
+ TestWidget.prototype.widgetFullName = "custom-widget";
+ $.widget.bridge( "testWidget", TestWidget );
+
+ elem.testWidget();
+ instance = elem.data( "custom-widget" );
+ equal( typeof instance, "object", "instance stored in .data(widgetFullName)" );
+});
+
}( jQuery ) );
diff --git a/tests/unit/widget/widget_extend.js b/tests/unit/widget/widget_extend.js
index ae9855929..14f9a46e0 100644
--- a/tests/unit/widget/widget_extend.js
+++ b/tests/unit/widget/widget_extend.js
@@ -1,5 +1,5 @@
test( "$.widget.extend()", function() {
- expect( 26 );
+ expect( 27 );
var ret, empty, optionsWithLength, optionsWithDate, myKlass, customObject, optionsWithCustomObject, nullUndef,
target, recursive, obj, input, output,
@@ -76,13 +76,16 @@ test( "$.widget.extend()", function() {
ret = $.widget.extend( { foo: [] }, { foo: [0] } ); // 1907
equal( ret.foo.length, 1, "Check to make sure a value with coersion 'false' copies over when necessary to fix #1907" );
- ret = $.widget.extend( { foo: "1,2,3" }, { foo: [1, 2, 3] } );
- strictEqual( typeof ret.foo, "object", "Check to make sure values equal with coersion (but not actually equal) overwrite correctly" );
+ ret = $.widget.extend( { foo: "1,2,3" }, { foo: [ 1, 2, 3 ] } );
+ deepEqual( ret.foo, [ 1, 2, 3 ], "Properly extend a string to array." );
- ret = $.widget.extend( { foo:"bar" }, { foo:null } );
- strictEqual( typeof ret.foo, "object", "Make sure a null value doesn't crash with deep extend, for #1908" );
+ ret = $.widget.extend( { foo: "1,2,3" }, { foo: { to: "object" } } );
+ deepEqual( ret.foo, { to: "object" }, "Properly extend a string to object." );
- obj = { foo:null };
+ ret = $.widget.extend( { foo: "bar" }, { foo: null } );
+ strictEqual( ret.foo, null, "Make sure a null value doesn't crash with deep extend, for #1908" );
+
+ obj = { foo: null };
$.widget.extend( obj, { foo:"notnull" } );
equal( obj.foo, "notnull", "Make sure a null value can be overwritten" );
diff --git a/tests/visual/dialog/animated.html b/tests/visual/dialog/animated.html
new file mode 100644
index 000000000..8fc296471
--- /dev/null
+++ b/tests/visual/dialog/animated.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>Dialog Visual Test</title>
+ <link rel="stylesheet" href="../../../themes/base/jquery.ui.all.css">
+ <script src="../../../jquery-1.8.2.js"></script>
+ <script src="../../../ui/jquery.ui.core.js"></script>
+ <script src="../../../ui/jquery.ui.widget.js"></script>
+ <script src="../../../ui/jquery.ui.mouse.js"></script>
+ <script src="../../../ui/jquery.ui.draggable.js"></script>
+ <script src="../../../ui/jquery.ui.position.js"></script>
+ <script src="../../../ui/jquery.ui.resizable.js"></script>
+ <script src="../../../ui/jquery.ui.dialog.js"></script>
+ <script src="../../../ui/jquery.ui.effect.js"></script>
+ <script src="../../../ui/jquery.ui.effect-blind.js"></script>
+ <script src="../../../ui/jquery.ui.effect-explode.js"></script>
+ <script>
+ $(function() {
+ $( "#dialog" ).dialog({
+ autoOpen: false,
+ show: {
+ effect: "blind",
+ duration: 1000
+ },
+ hide: {
+ effect: "explode",
+ duration: 1000
+ },
+ modal: true
+ });
+
+ $( "#opener" ).click(function() {
+ $( "#dialog" ).dialog( "open" );
+ });
+ });
+ </script>
+</head>
+<body>
+
+<p>WHAT: A animated modal dialog, using blind effect to show, explode to hide.</p>
+<p>EXPECTED: Dialog shows up on top of the overlay and stays there during and after the animation. Focus is set to the input inside the dialog and stays there after the animation finishes.</p>
+
+<div id="dialog" title="Are you sure?">
+ <p>Please enter password to continue.</p>
+ <label for="password">Password</label><input id="password">
+</div>
+
+<button id="opener">Open Dialog</button>
+
+</body>
+</html>
diff --git a/tests/visual/dialog/complex-dialogs.html b/tests/visual/dialog/complex-dialogs.html
new file mode 100644
index 000000000..f6d4aa162
--- /dev/null
+++ b/tests/visual/dialog/complex-dialogs.html
@@ -0,0 +1,94 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>Dialog Visual Test</title>
+ <link rel="stylesheet" href="../../../themes/base/jquery.ui.all.css">
+ <script src="../../../jquery-1.8.2.js"></script>
+ <script src="../../../ui/jquery.ui.core.js"></script>
+ <script src="../../../ui/jquery.ui.widget.js"></script>
+ <script src="../../../ui/jquery.ui.mouse.js"></script>
+ <script src="../../../ui/jquery.ui.draggable.js"></script>
+ <script src="../../../ui/jquery.ui.position.js"></script>
+ <script src="../../../ui/jquery.ui.resizable.js"></script>
+ <script src="../../../ui/jquery.ui.dialog.js"></script>
+
+ <!-- stuff needed to make things complex -->
+ <script src="../../../ui/jquery.ui.datepicker.js"></script>
+ <script src="../../../ui/jquery.ui.menu.js"></script>
+ <script src="../../../ui/jquery.ui.autocomplete.js"></script>
+ <script src="../../../ui/jquery.ui.tooltip.js"></script>
+
+ <script>
+ $(function() {
+ var dialog = $( "#dialog" ).dialog({
+ modal: true,
+ height: 300,
+ width: 500
+ }),
+
+ datepickerDialog = $( "#dialog-datepicker" ).dialog({
+ autoOpen: false,
+ modal: true
+ }),
+
+ autocompleteDialog = $( "#dialog-autocomplete" ).dialog({
+ autoOpen: false,
+ modal: false,
+ width: 600
+ });
+
+ $( "#open-dialog" ).click(function() {
+ dialog.dialog( "open" );
+ });
+
+ $( "#open-datepicker" ).click(function() {
+ datepickerDialog.dialog( "open" );
+ });
+
+ $( "#open-autocomplete" ).click(function() {
+ autocompleteDialog.dialog( "open" );
+ });
+
+ $( "#datepicker" ).datepicker();
+
+ $( "#autocomplete" ).autocomplete({
+ source: [
+ "ActionScript",
+ "AppleScript",
+ "Asp",
+ "BASIC",
+ "Scheme"
+ ]
+ });
+
+ $( document ).tooltip();
+ });
+ </script>
+</head>
+<body>
+
+<p>WHAT: A modal dialog opening another modal dialog (including a datepicker), opening a non-modal dialog (including an autocomplete with tooltip applied). A regular link on the page, outside of the dialogs.</p>
+<p>EXPECTED: As long as a modal dialog is open, focus stays within the dialogs. Both mouse and keyboard interactions are captured and restricted to the dialog. When the nested modal dialog is open, the first modal dialog can't be interacted with, until the nested dialog is closed. When the third dialog is open (not modal), switching between the two dialogs is possible, both can be interacted with.</p>
+
+<a href="#">Outside link</a>
+
+<button id="open-dialog">Reopen dialog</button>
+
+<div id="dialog" title="Basic dialog">
+ <p>This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.</p>
+ <p><button id="open-datepicker">Open another window with a datepicker.</button></p>
+</div>
+
+<div id="dialog-datepicker" title="A dialog with a datepicker">
+ <p>Date: <input id="datepicker"></p>
+ <p><button id="open-autocomplete">Open another window with an autocomplete and a tooltip.</button></p>
+</div>
+
+<div id="dialog-autocomplete">
+ <label for="autocomplete">Tags: </label>
+ <input id="autocomplete" title="Try typing something!">
+</div>
+
+</body>
+</html>
diff --git a/tests/visual/dialog/form.html b/tests/visual/dialog/form.html
new file mode 100644
index 000000000..47ed5e0b5
--- /dev/null
+++ b/tests/visual/dialog/form.html
@@ -0,0 +1,69 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>Dialog Visual Test</title>
+ <link rel="stylesheet" href="../../../themes/base/jquery.ui.all.css">
+ <script src="../../../jquery-1.8.2.js"></script>
+ <script src="../../../ui/jquery.ui.core.js"></script>
+ <script src="../../../ui/jquery.ui.widget.js"></script>
+ <script src="../../../ui/jquery.ui.mouse.js"></script>
+ <script src="../../../ui/jquery.ui.draggable.js"></script>
+ <script src="../../../ui/jquery.ui.position.js"></script>
+ <script src="../../../ui/jquery.ui.resizable.js"></script>
+ <script src="../../../ui/jquery.ui.dialog.js"></script>
+ <script src="../../../ui/jquery.ui.effect.js"></script>
+ <script src="../../../ui/jquery.ui.effect-blind.js"></script>
+ <script src="../../../ui/jquery.ui.effect-explode.js"></script>
+ <script>
+ $(function() {
+ $( "#form-dialog, #prompt-dialog" ).dialog({
+ autoOpen: false,
+ modal: true
+ });
+
+ $( "#open-form" ).click(function() {
+ $( "#form-dialog" ).dialog( "open" );
+ });
+
+ $( "#open-prompt" ).click(function() {
+ $( "#prompt-dialog" ).dialog( "open" );
+ });
+ });
+ </script>
+ <style>
+ label {
+ display: block;
+ }
+ </style>
+</head>
+<body>
+
+<p>WHAT: A modal dialog containing form fields, with groups to describe each section. A second modal dialog with just an input and some text markup.</p>
+<p>EXPECTED: Dialog shows up, screenreader reads the dialog's title, the word "dialog" (or equivalent), the text before the first input (description of the first section) and the label of the first, focused input. When tabbing to the next group, the screenreader should announce the description of that group, along with the label of the focused field.</p>
+<p>For the second dialog, the behaviour should be similar, except that the whole content is read as the description of the dialog, likely causing the input's label to be read twice.</p>
+<p>NOTE: Using <code>fieldset</code> with <code>legend</code> seems to have the same result as using <code>role="group"</code> and <code>aria-describedby</code>. The latter needs an id-attribute, offers more flexibilty in markup order and has no built-in styling.</p>
+
+<div id="form-dialog" title="Profile Information">
+ <fieldset>
+ <legend>Please share some personal information</legend>
+ <label for="favorite-animal">Your favorite animal</label><input id="favorite-animal">
+ <label for="favorite-color">Your favorite color</label><input id="favorite-color">
+ </fieldset>
+ <div role="group" aria-describedby="section2">
+ <p id="section2">Some more (optional) information</p>
+ <label for="favorite-food">Favorite food</label><input id="favorite-food">
+ </div>
+</div>
+
+<button id="open-form">Open Form Dialog</button>
+
+<div id="prompt-dialog" title="Are you sure?">
+ <p>Please enter password to continue.</p>
+ <label for="password">Password</label><input id="password">
+</div>
+
+<button id="open-prompt">Open Prompt Dialog</button>
+
+</body>
+</html>
diff --git a/tests/visual/dialog/performance.html b/tests/visual/dialog/performance.html
index 0b3bc6e58..fb863488d 100644
--- a/tests/visual/dialog/performance.html
+++ b/tests/visual/dialog/performance.html
@@ -5,7 +5,6 @@
<title>Dialog Visual Test - Modal Dialog in Large DOM</title>
<link rel="stylesheet" href="../../../themes/base/jquery.ui.all.css">
<script src="../../../jquery-1.8.2.js"></script>
- <script src="../../../external/jquery.bgiframe-2.1.2.js"></script>
<script src="../../../ui/jquery.ui.core.js"></script>
<script src="../../../ui/jquery.ui.position.js"></script>
<script src="../../../ui/jquery.ui.widget.js"></script>
diff --git a/tests/visual/position/position_feedback.html b/tests/visual/position/position_feedback.html
index fe1f04e5b..fb3bf00fd 100644
--- a/tests/visual/position/position_feedback.html
+++ b/tests/visual/position/position_feedback.html
@@ -55,25 +55,24 @@
});
element.width( 150 );
- $( document ).on( "mousemove", function( event ) {
- var base = {
+ function positionWithOffset( horizontal, vertical ) {
+ return {
my: "left top",
- at: "left top",
+ at: "left" + (horizontal < 0 ? horizontal : "+" + horizontal) + " " +
+ "top" + (vertical < 0 ? vertical : "+" + vertical),
of: target,
using: using
};
- element.position( $.extend({
- offset: (event.pageX - targetOffset.left) + " " + (event.pageY - targetOffset.top)
- }, base ));
- oppositeElement.position( $.extend({
- offset: (-1 * (event.pageX - targetOffset.left)) + " " + (-1 * (event.pageY - targetOffset.top))
- }, base ));
- leftElement.position( $.extend({
- offset: (-0.9 * (event.pageX - targetOffset.left)) + " " + (0.9 * (event.pageY - targetOffset.top))
- }, base ));
- rightElement.position( $.extend({
- offset: (0.9 * (event.pageX - targetOffset.left)) + " " + (-0.9 * (event.pageY - targetOffset.top))
- }, base) );
+ };
+ $( document ).on( "mousemove", function( event ) {
+ element.position( positionWithOffset(
+ event.pageX - targetOffset.left, event.pageY - targetOffset.top ) );
+ oppositeElement.position( positionWithOffset(
+ -1 * (event.pageX - targetOffset.left), -1 * (event.pageY - targetOffset.top) ) );
+ leftElement.position( positionWithOffset(
+ -0.9 * (event.pageX - targetOffset.left), 0.9 * (event.pageY - targetOffset.top) ) );
+ rightElement.position( positionWithOffset(
+ 0.9 * (event.pageX - targetOffset.left), -0.9 * (event.pageY - targetOffset.top) ) );
});
});
</script>
diff --git a/tests/visual/tooltip/tooltip.html b/tests/visual/tooltip/tooltip.html
index 56e5db10e..706ed5091 100644
--- a/tests/visual/tooltip/tooltip.html
+++ b/tests/visual/tooltip/tooltip.html
@@ -66,8 +66,7 @@
tooltipClass: "ui-state-highlight",
position: {
my: "center top",
- at: "center bottom",
- offset: "0 10"
+ at: "center bottom+10"
}
});
@@ -86,10 +85,18 @@
$( "#buttons" ).tooltip({
position: {
my: "center bottom",
- at: "center top",
- offset: "0 -5"
+ at: "center top-5"
}
});
+
+ $( "#blurs-on-click" ).tooltip({
+ track: true,
+ show: {
+ delay: 500
+ }
+ }).click(function() {
+ $( "#focus-on-me" ).focus();
+ });
});
</script>
</head>
@@ -140,16 +147,23 @@
<div class="group" style="width: 300px;">
<p>Nested elements.</p>
<div id="context2">
- <div title="something else" style="border:1px solid red;">
+ <div title="nested parent" style="border:1px solid red;">
tooltipped
- <span title="something more" style="border:1px solid green; padding-left: 50px;">nested tooltipped</span>
+ <span title="nested child" style="border:1px solid green; padding-left: 25px;">
+ nested tooltipped
+ <span title="nested nested child" style="border:1px solid blue; padding-left: 25px;">third level</span>
+ </span>
</div>
+ <input title="nested input title">
</div>
<div id="childish" style="border: 1px solid black;" title="element with child elements">
Text in <strong>bold</strong>.
</div>
</div>
+ <button id="blurs-on-click" title="button title text">click me to focus something else</button>
+ <input id="focus-on-me">
+
<div class="group">
<p>Play around with focusing and hovering of form elements.</p>
<form>
diff --git a/themes/base/jquery.ui.autocomplete.css b/themes/base/jquery.ui.autocomplete.css
index 05ae3108f..39f9001a2 100644
--- a/themes/base/jquery.ui.autocomplete.css
+++ b/themes/base/jquery.ui.autocomplete.css
@@ -10,9 +10,7 @@
*/
.ui-autocomplete {
position: absolute;
- top: 0; /* #8656 */
+ top: 0;
+ left: 0;
cursor: default;
}
-
-/* workarounds */
-* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
diff --git a/themes/base/jquery.ui.core.css b/themes/base/jquery.ui.core.css
index 8cf4d02ef..5bfe620b9 100644
--- a/themes/base/jquery.ui.core.css
+++ b/themes/base/jquery.ui.core.css
@@ -12,13 +12,15 @@
/* Layout helpers
----------------------------------*/
.ui-helper-hidden { display: none; }
-.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
+.ui-helper-hidden-accessible { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
.ui-helper-clearfix:after { clear: both; }
.ui-helper-clearfix { zoom: 1; }
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+.ui-front { z-index: 100; }
+
/* Interaction Cues
----------------------------------*/
@@ -36,4 +38,4 @@
----------------------------------*/
/* Overlays */
-.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+.ui-widget-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; }
diff --git a/themes/base/jquery.ui.datepicker.css b/themes/base/jquery.ui.datepicker.css
index c1f269999..e25d8ea56 100644
--- a/themes/base/jquery.ui.datepicker.css
+++ b/themes/base/jquery.ui.datepicker.css
@@ -54,14 +54,3 @@
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
-
-/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
-.ui-datepicker-cover {
- position: absolute; /*must have*/
- z-index: -1; /*must have*/
- filter: mask(); /*must have*/
- top: -4px; /*must have*/
- left: -4px; /*must have*/
- width: 200px; /*must have*/
- height: 200px; /*must have*/
-} \ No newline at end of file
diff --git a/themes/base/jquery.ui.dialog.css b/themes/base/jquery.ui.dialog.css
index 2937af9b7..2f523b30c 100644
--- a/themes/base/jquery.ui.dialog.css
+++ b/themes/base/jquery.ui.dialog.css
@@ -8,7 +8,7 @@
*
* http://docs.jquery.com/UI/Dialog#theming
*/
-.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog { position: absolute; top: 0; left: 0; padding: .2em; width: 300px; overflow: hidden; outline: 0; }
.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
diff --git a/themes/base/jquery.ui.spinner.css b/themes/base/jquery.ui.spinner.css
index 94b73fa05..95f865b92 100644
--- a/themes/base/jquery.ui.spinner.css
+++ b/themes/base/jquery.ui.spinner.css
@@ -10,14 +10,13 @@
*/
.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; }
.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; }
-.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; z-index: 100; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; }
+.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; }
.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */
.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */
.ui-spinner-up { top: 0; }
.ui-spinner-down { bottom: 0; }
/* TR overrides */
-span.ui-spinner { background: none; }
.ui-spinner .ui-icon-triangle-1-s {
/* need to fix icons sprite */
background-position:-65px -16px;
diff --git a/themes/base/jquery.ui.theme.css b/themes/base/jquery.ui.theme.css
index d70b9df90..67b74dcd7 100644
--- a/themes/base/jquery.ui.theme.css
+++ b/themes/base/jquery.ui.theme.css
@@ -41,12 +41,13 @@
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+.ui-state-disabled .ui-icon { filter:Alpha(Opacity=35); } /* For IE8 - See #6059 */
/* Icons
----------------------------------*/
/* states and images */
-.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; background-position: 16px 16px; }
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsHeader}*/; }
.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png)/*{iconsDefault}*/; }
@@ -244,4 +245,4 @@
/* Overlays */
.ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityOverlay}*/; }
-.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -khtml-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; border-radius: 8px/*{cornerRadiusShadow}*/; } \ No newline at end of file
+.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -khtml-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; border-radius: 8px/*{cornerRadiusShadow}*/; }
diff --git a/themes/base/jquery.ui.tooltip.css b/themes/base/jquery.ui.tooltip.css
index e293eeb23..b7efbe10c 100644
--- a/themes/base/jquery.ui.tooltip.css
+++ b/themes/base/jquery.ui.tooltip.css
@@ -7,16 +7,11 @@
* http://jquery.org/license
*/
.ui-tooltip {
- padding:8px;
- position:absolute;
- z-index:9999;
- -o-box-shadow: 0 0 5px #aaa;
- -moz-box-shadow: 0 0 5px #aaa;
+ padding: 8px;
+ position: absolute;
+ z-index: 9999;
+ max-width: 300px;
-webkit-box-shadow: 0 0 5px #aaa;
box-shadow: 0 0 5px #aaa;
}
-/* Fades and background-images don't work well together in IE6, drop the image */
-* html .ui-tooltip {
- background-image: none;
-}
-body .ui-tooltip { border-width:2px; }
+body .ui-tooltip { border-width: 2px; }
diff --git a/ui/.jshintrc b/ui/.jshintrc
index 415d69e90..edf09721b 100644
--- a/ui/.jshintrc
+++ b/ui/.jshintrc
@@ -8,9 +8,9 @@
"latedef": true,
"noarg": true,
"onevar": true,
- "smarttabs": true,
"trailing": true,
"undef": true,
+ "unused": true,
"predef": [
"Globalize"
]
diff --git a/ui/i18n/jquery.ui.datepicker-ar.js b/ui/i18n/jquery.ui.datepicker-ar.js
index f0d009667..cef0f08fd 100644
--- a/ui/i18n/jquery.ui.datepicker-ar.js
+++ b/ui/i18n/jquery.ui.datepicker-ar.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['ar']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-az.js b/ui/i18n/jquery.ui.datepicker-az.js
index 1101c8b91..a133a9eb2 100644
--- a/ui/i18n/jquery.ui.datepicker-az.js
+++ b/ui/i18n/jquery.ui.datepicker-az.js
@@ -20,4 +20,4 @@ jQuery(function($) {
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['az']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-bs.js b/ui/i18n/jquery.ui.datepicker-bs.js
index d64573755..f08870ffe 100644
--- a/ui/i18n/jquery.ui.datepicker-bs.js
+++ b/ui/i18n/jquery.ui.datepicker-bs.js
@@ -2,10 +2,10 @@
/* Written by Kenan Konjo. */
jQuery(function($){
$.datepicker.regional['bs'] = {
- closeText: 'Zatvori',
- prevText: '&#x3C;',
- nextText: '&#x3E;',
- currentText: 'Danas',
+ closeText: 'Zatvori',
+ prevText: '&#x3C;',
+ nextText: '&#x3E;',
+ currentText: 'Danas',
monthNames: ['Januar','Februar','Mart','April','Maj','Juni',
'Juli','August','Septembar','Oktobar','Novembar','Decembar'],
monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['bs']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-cy-GB.js b/ui/i18n/jquery.ui.datepicker-cy-GB.js
index dfee2f9d4..cf3a38e6c 100644
--- a/ui/i18n/jquery.ui.datepicker-cy-GB.js
+++ b/ui/i18n/jquery.ui.datepicker-cy-GB.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['cy-GB']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-el.js b/ui/i18n/jquery.ui.datepicker-el.js
index 6d775f995..1ac47561a 100644
--- a/ui/i18n/jquery.ui.datepicker-el.js
+++ b/ui/i18n/jquery.ui.datepicker-el.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['el']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-es.js b/ui/i18n/jquery.ui.datepicker-es.js
index 63368aecc..97a2d6ead 100644
--- a/ui/i18n/jquery.ui.datepicker-es.js
+++ b/ui/i18n/jquery.ui.datepicker-es.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['es']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-et.js b/ui/i18n/jquery.ui.datepicker-et.js
index 32702b243..62cbea8fa 100644
--- a/ui/i18n/jquery.ui.datepicker-et.js
+++ b/ui/i18n/jquery.ui.datepicker-et.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['et']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-eu.js b/ui/i18n/jquery.ui.datepicker-eu.js
index 846ce3abc..a71db2c72 100644
--- a/ui/i18n/jquery.ui.datepicker-eu.js
+++ b/ui/i18n/jquery.ui.datepicker-eu.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['eu']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-fa.js b/ui/i18n/jquery.ui.datepicker-fa.js
index be8acd2a5..bb957f6d8 100644
--- a/ui/i18n/jquery.ui.datepicker-fa.js
+++ b/ui/i18n/jquery.ui.datepicker-fa.js
@@ -37,7 +37,7 @@ jQuery(function($) {
'س',
'چ',
'پ',
- 'ج',
+ 'ج',
'ش'
],
dayNamesMin: [
@@ -46,7 +46,7 @@ jQuery(function($) {
'س',
'چ',
'پ',
- 'ج',
+ 'ج',
'ش'
],
weekHeader: 'هف',
@@ -56,4 +56,4 @@ jQuery(function($) {
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['fa']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-fr-CH.js b/ui/i18n/jquery.ui.datepicker-fr-CH.js
index fec03a042..e574537b0 100644
--- a/ui/i18n/jquery.ui.datepicker-fr-CH.js
+++ b/ui/i18n/jquery.ui.datepicker-fr-CH.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['fr-CH']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-gl.js b/ui/i18n/jquery.ui.datepicker-gl.js
index 0de64968f..59b989a6d 100644
--- a/ui/i18n/jquery.ui.datepicker-gl.js
+++ b/ui/i18n/jquery.ui.datepicker-gl.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['gl']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-hr.js b/ui/i18n/jquery.ui.datepicker-hr.js
index 6bc5aade1..2fe37b64b 100644
--- a/ui/i18n/jquery.ui.datepicker-hr.js
+++ b/ui/i18n/jquery.ui.datepicker-hr.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['hr']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-hy.js b/ui/i18n/jquery.ui.datepicker-hy.js
index b42851596..6d4eca555 100644
--- a/ui/i18n/jquery.ui.datepicker-hy.js
+++ b/ui/i18n/jquery.ui.datepicker-hy.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['hy']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-id.js b/ui/i18n/jquery.ui.datepicker-id.js
index 4ad46f640..6327fa60c 100644
--- a/ui/i18n/jquery.ui.datepicker-id.js
+++ b/ui/i18n/jquery.ui.datepicker-id.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['id']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-is.js b/ui/i18n/jquery.ui.datepicker-is.js
index f1b067ebf..925341a7a 100644
--- a/ui/i18n/jquery.ui.datepicker-is.js
+++ b/ui/i18n/jquery.ui.datepicker-is.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['is']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-ja.js b/ui/i18n/jquery.ui.datepicker-ja.js
index afd298315..4d0b63c77 100644
--- a/ui/i18n/jquery.ui.datepicker-ja.js
+++ b/ui/i18n/jquery.ui.datepicker-ja.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: true,
yearSuffix: '年'};
$.datepicker.setDefaults($.datepicker.regional['ja']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-ko.js b/ui/i18n/jquery.ui.datepicker-ko.js
index 04112424d..af36f3d6b 100644
--- a/ui/i18n/jquery.ui.datepicker-ko.js
+++ b/ui/i18n/jquery.ui.datepicker-ko.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: true,
yearSuffix: '년'};
$.datepicker.setDefaults($.datepicker.regional['ko']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-ky.js b/ui/i18n/jquery.ui.datepicker-ky.js
new file mode 100644
index 000000000..d4466b12e
--- /dev/null
+++ b/ui/i18n/jquery.ui.datepicker-ky.js
@@ -0,0 +1,24 @@
+/* Kyrgyz (UTF-8) initialisation for the jQuery UI date picker plugin. */
+/* Written by Sergey Kartashov (ebishkek@yandex.ru). */
+jQuery(function($){
+ $.datepicker.regional['ky'] = {
+ closeText: 'Жабуу',
+ prevText: '&#x3c;Мур',
+ nextText: 'Кий&#x3e;',
+ currentText: 'Бүгүн',
+ monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь',
+ 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'],
+ monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн',
+ 'Июл','Авг','Сен','Окт','Ноя','Дек'],
+ dayNames: ['жекшемби', 'дүйшөмбү', 'шейшемби', 'шаршемби', 'бейшемби', 'жума', 'ишемби'],
+ dayNamesShort: ['жек', 'дүй', 'шей', 'шар', 'бей', 'жум', 'ише'],
+ dayNamesMin: ['Жк','Дш','Шш','Шр','Бш','Жм','Иш'],
+ weekHeader: 'Жум',
+ dateFormat: 'dd.mm.yy',
+ firstDay: 1,
+ isRTL: false,
+ showMonthAfterYear: false,
+ yearSuffix: ''
+ };
+ $.datepicker.setDefaults($.datepicker.regional['ky']);
+});
diff --git a/ui/i18n/jquery.ui.datepicker-lt.js b/ui/i18n/jquery.ui.datepicker-lt.js
index 2970f8f37..1afaaac5d 100644
--- a/ui/i18n/jquery.ui.datepicker-lt.js
+++ b/ui/i18n/jquery.ui.datepicker-lt.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['lt']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-lv.js b/ui/i18n/jquery.ui.datepicker-lv.js
index 003934e72..28cc102fc 100644
--- a/ui/i18n/jquery.ui.datepicker-lv.js
+++ b/ui/i18n/jquery.ui.datepicker-lv.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['lv']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-ml.js b/ui/i18n/jquery.ui.datepicker-ml.js
index 1e3432c0a..9b8f460db 100644
--- a/ui/i18n/jquery.ui.datepicker-ml.js
+++ b/ui/i18n/jquery.ui.datepicker-ml.js
@@ -3,7 +3,7 @@
jQuery(function($){
$.datepicker.regional['ml'] = {
closeText: 'ശരി',
- prevText: 'മുന്നത്തെ',
+ prevText: 'മുന്നത്തെ',
nextText: 'അടുത്തത് ',
currentText: 'ഇന്ന്',
monthNames: ['ജനുവരി','ഫെബ്രുവരി','മാര്‍ച്ച്','ഏപ്രില്‍','മേയ്','ജൂണ്‍',
diff --git a/ui/i18n/jquery.ui.datepicker-ms.js b/ui/i18n/jquery.ui.datepicker-ms.js
index c290af10a..e70de7299 100644
--- a/ui/i18n/jquery.ui.datepicker-ms.js
+++ b/ui/i18n/jquery.ui.datepicker-ms.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['ms']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-nl.js b/ui/i18n/jquery.ui.datepicker-nl.js
index 781fe6191..203f16069 100644
--- a/ui/i18n/jquery.ui.datepicker-nl.js
+++ b/ui/i18n/jquery.ui.datepicker-nl.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional.nl);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-pt-BR.js b/ui/i18n/jquery.ui.datepicker-pt-BR.js
index 0741892ab..521967ec3 100644
--- a/ui/i18n/jquery.ui.datepicker-pt-BR.js
+++ b/ui/i18n/jquery.ui.datepicker-pt-BR.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['pt-BR']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-pt.js b/ui/i18n/jquery.ui.datepicker-pt.js
index 98925b455..999f20e3e 100644
--- a/ui/i18n/jquery.ui.datepicker-pt.js
+++ b/ui/i18n/jquery.ui.datepicker-pt.js
@@ -19,4 +19,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['pt']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-ru.js b/ui/i18n/jquery.ui.datepicker-ru.js
index 2017e0537..a51971405 100644
--- a/ui/i18n/jquery.ui.datepicker-ru.js
+++ b/ui/i18n/jquery.ui.datepicker-ru.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['ru']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-th.js b/ui/i18n/jquery.ui.datepicker-th.js
index d57541f64..aecfd27cc 100644
--- a/ui/i18n/jquery.ui.datepicker-th.js
+++ b/ui/i18n/jquery.ui.datepicker-th.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['th']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-tj.js b/ui/i18n/jquery.ui.datepicker-tj.js
index ed662392c..9a20e4d37 100644
--- a/ui/i18n/jquery.ui.datepicker-tj.js
+++ b/ui/i18n/jquery.ui.datepicker-tj.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['tj']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-tr.js b/ui/i18n/jquery.ui.datepicker-tr.js
index 1b5cafc39..75b583a77 100644
--- a/ui/i18n/jquery.ui.datepicker-tr.js
+++ b/ui/i18n/jquery.ui.datepicker-tr.js
@@ -20,4 +20,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['tr']);
-}); \ No newline at end of file
+});
diff --git a/ui/i18n/jquery.ui.datepicker-uk.js b/ui/i18n/jquery.ui.datepicker-uk.js
index 31964af44..2bdc82ff7 100644
--- a/ui/i18n/jquery.ui.datepicker-uk.js
+++ b/ui/i18n/jquery.ui.datepicker-uk.js
@@ -21,4 +21,4 @@ jQuery(function($){
showMonthAfterYear: false,
yearSuffix: ''};
$.datepicker.setDefaults($.datepicker.regional['uk']);
-}); \ No newline at end of file
+});
diff --git a/ui/jquery.ui.accordion.js b/ui/jquery.ui.accordion.js
index 48e880a05..17ce155a8 100644
--- a/ui/jquery.ui.accordion.js
+++ b/ui/jquery.ui.accordion.js
@@ -59,8 +59,8 @@ $.widget( "ui.accordion", {
.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
.hide();
- // don't allow collapsible: false and active: false
- if ( !options.collapsible && options.active === false ) {
+ // don't allow collapsible: false and active: false / null
+ if ( !options.collapsible && (options.active === false || options.active == null) ) {
options.active = 0;
}
// handle negative values
@@ -75,7 +75,6 @@ $.widget( "ui.accordion", {
.show();
this._createIcons();
- this.originalHeight = this.element[0].style.height;
this.refresh();
// ARIA
@@ -198,7 +197,6 @@ $.widget( "ui.accordion", {
}
});
if ( this.options.heightStyle !== "content" ) {
- this.element.css( "height", this.originalHeight );
contents.css( "height", "" );
}
},
@@ -285,21 +283,11 @@ $.widget( "ui.accordion", {
},
refresh: function() {
- var maxHeight, overflow,
+ var maxHeight,
heightStyle = this.options.heightStyle,
parent = this.element.parent();
- this.element.css( "height", this.originalHeight );
-
if ( heightStyle === "fill" ) {
- // IE 6 treats height like minHeight, so we need to turn off overflow
- // in order to get a reliable height
- // we use the minHeight support test because we assume that only
- // browsers that don't support minHeight will treat height as minHeight
- if ( !$.support.minHeight ) {
- overflow = parent.css( "overflow" );
- parent.css( "overflow", "hidden");
- }
maxHeight = parent.height();
this.element.siblings( ":visible" ).each(function() {
var elem = $( this ),
@@ -310,9 +298,6 @@ $.widget( "ui.accordion", {
}
maxHeight -= elem.outerHeight( true );
});
- if ( overflow ) {
- parent.css( "overflow", overflow );
- }
this.headers.each(function() {
maxHeight -= $( this ).outerHeight( true );
@@ -332,10 +317,6 @@ $.widget( "ui.accordion", {
})
.height( maxHeight );
}
-
- if ( heightStyle !== "content" ) {
- this.element.height( this.element.height() );
- }
},
_activate: function( index ) {
@@ -547,192 +528,4 @@ $.widget( "ui.accordion", {
}
});
-
-
-// DEPRECATED
-if ( $.uiBackCompat !== false ) {
- // navigation options
- (function( $, prototype ) {
- $.extend( prototype.options, {
- navigation: false,
- navigationFilter: function() {
- return this.href.toLowerCase() === location.href.toLowerCase();
- }
- });
-
- var _create = prototype._create;
- prototype._create = function() {
- if ( this.options.navigation ) {
- var that = this,
- headers = this.element.find( this.options.header ),
- content = headers.next(),
- current = headers.add( content )
- .find( "a" )
- .filter( this.options.navigationFilter )
- [ 0 ];
- if ( current ) {
- headers.add( content ).each( function( index ) {
- if ( $.contains( this, current ) ) {
- that.options.active = Math.floor( index / 2 );
- return false;
- }
- });
- }
- }
- _create.call( this );
- };
- }( jQuery, jQuery.ui.accordion.prototype ) );
-
- // height options
- (function( $, prototype ) {
- $.extend( prototype.options, {
- heightStyle: null, // remove default so we fall back to old values
- autoHeight: true, // use heightStyle: "auto"
- clearStyle: false, // use heightStyle: "content"
- fillSpace: false // use heightStyle: "fill"
- });
-
- var _create = prototype._create,
- _setOption = prototype._setOption;
-
- $.extend( prototype, {
- _create: function() {
- this.options.heightStyle = this.options.heightStyle ||
- this._mergeHeightStyle();
-
- _create.call( this );
- },
-
- _setOption: function( key, value ) {
- if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) {
- this.options.heightStyle = this._mergeHeightStyle();
- }
- _setOption.apply( this, arguments );
- },
-
- _mergeHeightStyle: function() {
- var options = this.options;
-
- if ( options.fillSpace ) {
- return "fill";
- }
-
- if ( options.clearStyle ) {
- return "content";
- }
-
- if ( options.autoHeight ) {
- return "auto";
- }
- }
- });
- }( jQuery, jQuery.ui.accordion.prototype ) );
-
- // icon options
- (function( $, prototype ) {
- $.extend( prototype.options.icons, {
- activeHeader: null, // remove default so we fall back to old values
- headerSelected: "ui-icon-triangle-1-s"
- });
-
- var _createIcons = prototype._createIcons;
- prototype._createIcons = function() {
- if ( this.options.icons ) {
- this.options.icons.activeHeader = this.options.icons.activeHeader ||
- this.options.icons.headerSelected;
- }
- _createIcons.call( this );
- };
- }( jQuery, jQuery.ui.accordion.prototype ) );
-
- // expanded active option, activate method
- (function( $, prototype ) {
- prototype.activate = prototype._activate;
-
- var _findActive = prototype._findActive;
- prototype._findActive = function( index ) {
- if ( index === -1 ) {
- index = false;
- }
- if ( index && typeof index !== "number" ) {
- index = this.headers.index( this.headers.filter( index ) );
- if ( index === -1 ) {
- index = false;
- }
- }
- return _findActive.call( this, index );
- };
- }( jQuery, jQuery.ui.accordion.prototype ) );
-
- // resize method
- jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh;
-
- // change events
- (function( $, prototype ) {
- $.extend( prototype.options, {
- change: null,
- changestart: null
- });
-
- var _trigger = prototype._trigger;
- prototype._trigger = function( type, event, data ) {
- var ret = _trigger.apply( this, arguments );
- if ( !ret ) {
- return false;
- }
-
- if ( type === "beforeActivate" ) {
- ret = _trigger.call( this, "changestart", event, {
- oldHeader: data.oldHeader,
- oldContent: data.oldPanel,
- newHeader: data.newHeader,
- newContent: data.newPanel
- });
- } else if ( type === "activate" ) {
- ret = _trigger.call( this, "change", event, {
- oldHeader: data.oldHeader,
- oldContent: data.oldPanel,
- newHeader: data.newHeader,
- newContent: data.newPanel
- });
- }
- return ret;
- };
- }( jQuery, jQuery.ui.accordion.prototype ) );
-
- // animated option
- // NOTE: this only provides support for "slide", "bounceslide", and easings
- // not the full $.ui.accordion.animations API
- (function( $, prototype ) {
- $.extend( prototype.options, {
- animate: null,
- animated: "slide"
- });
-
- var _create = prototype._create;
- prototype._create = function() {
- var options = this.options;
- if ( options.animate === null ) {
- if ( !options.animated ) {
- options.animate = false;
- } else if ( options.animated === "slide" ) {
- options.animate = 300;
- } else if ( options.animated === "bounceslide" ) {
- options.animate = {
- duration: 200,
- down: {
- easing: "easeOutBounce",
- duration: 1000
- }
- };
- } else {
- options.animate = options.animated;
- }
- }
-
- _create.call( this );
- };
- }( jQuery, jQuery.ui.accordion.prototype ) );
-}
-
})( jQuery );
diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js
index f181e9180..f5ab57bd4 100644
--- a/ui/jquery.ui.autocomplete.js
+++ b/ui/jquery.ui.autocomplete.js
@@ -64,7 +64,7 @@ $.widget( "ui.autocomplete", {
.addClass( "ui-autocomplete-input" )
.attr( "autocomplete", "off" );
- this._on({
+ this._on( this.element, {
keydown: function( event ) {
if ( this.element.prop( "readOnly" ) ) {
suppressKeyPress = true;
@@ -190,7 +190,8 @@ $.widget( "ui.autocomplete", {
})
.zIndex( this.element.zIndex() + 1 )
.hide()
- .data( "menu" );
+ .data( "ui-menu" );
+
this._on( this.menu.element, {
mousedown: function( event ) {
// prevent moving focus out of the text field
@@ -236,9 +237,7 @@ $.widget( "ui.autocomplete", {
}
}
- // back compat for _renderItem using item.autocomplete, via #7810
- // TODO remove the fallback, see #8156
- var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" );
+ var item = ui.item.data( "ui-autocomplete-item" );
if ( false !== this._trigger( "focus", event, { item: item } ) ) {
// use value to match what will end up in the input, if it was a key event
if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
@@ -254,9 +253,7 @@ $.widget( "ui.autocomplete", {
}
},
menuselect: function( event, ui ) {
- // back compat for _renderItem using item.autocomplete, via #7810
- // TODO remove the fallback, see #8156
- var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ),
+ var item = ui.item.data( "ui-autocomplete-item" ),
previous = this.previous;
// only trigger when focus was lost (click on menu)
@@ -291,10 +288,6 @@ $.widget( "ui.autocomplete", {
.addClass( "ui-helper-hidden-accessible" )
.insertAfter( this.element );
- if ( $.fn.bgiframe ) {
- this.menu.element.bgiframe();
- }
-
// turning off autocomplete prevents the browser from remembering the
// value when navigating through history, so we re-enable autocomplete
// if the page is unloaded before the widget is destroyed. #7790
@@ -359,7 +352,7 @@ $.widget( "ui.autocomplete", {
url: url,
data: request,
dataType: "json",
- success: function( data, status ) {
+ success: function( data ) {
response( data );
},
error: function() {
@@ -541,7 +534,7 @@ $.widget( "ui.autocomplete", {
return this.menu.element;
},
- _value: function( value ) {
+ _value: function() {
return this.valueMethod.apply( this.element, arguments );
},
diff --git a/ui/jquery.ui.button.js b/ui/jquery.ui.button.js
index 5ae526488..6d7b94a38 100644
--- a/ui/jquery.ui.button.js
+++ b/ui/jquery.ui.button.js
@@ -282,7 +282,7 @@ $.widget( "ui.button", {
},
refresh: function() {
- var isDisabled = this.element.is( ":disabled" );
+ var isDisabled = this.element.is( ":disabled" ) || this.element.hasClass( "ui-button-disabled" );
if ( isDisabled !== this.options.disabled ) {
this._setOption( "disabled", isDisabled );
}
@@ -358,7 +358,7 @@ $.widget( "ui.button", {
$.widget( "ui.buttonset", {
version: "@VERSION",
options: {
- items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)"
+ items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
},
_create: function() {
diff --git a/ui/jquery.ui.core.js b/ui/jquery.ui.core.js
index e569eea42..288634376 100644
--- a/ui/jquery.ui.core.js
+++ b/ui/jquery.ui.core.js
@@ -128,53 +128,6 @@ $.fn.extend({
}
});
-// support: jQuery <1.8
-if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
- $.each( [ "Width", "Height" ], function( i, name ) {
- var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
- type = name.toLowerCase(),
- orig = {
- innerWidth: $.fn.innerWidth,
- innerHeight: $.fn.innerHeight,
- outerWidth: $.fn.outerWidth,
- outerHeight: $.fn.outerHeight
- };
-
- function reduce( elem, size, border, margin ) {
- $.each( side, function() {
- size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
- if ( border ) {
- size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
- }
- if ( margin ) {
- size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
- }
- });
- return size;
- }
-
- $.fn[ "inner" + name ] = function( size ) {
- if ( size === undefined ) {
- return orig[ "inner" + name ].call( this );
- }
-
- return this.each(function() {
- $( this ).css( type, reduce( this, size ) + "px" );
- });
- };
-
- $.fn[ "outer" + name] = function( size, margin ) {
- if ( typeof size !== "number" ) {
- return orig[ "outer" + name ].call( this, size );
- }
-
- return this.each(function() {
- $( this).css( type, reduce( this, size, true, margin ) + "px" );
- });
- };
- });
-}
-
// selectors
function focusable( element, isTabIndexNotNaN ) {
var map, mapName, img,
@@ -198,10 +151,10 @@ function focusable( element, isTabIndexNotNaN ) {
}
function visible( element ) {
- return !$( element ).parents().andSelf().filter(function() {
- return $.css( this, "visibility" ) === "hidden" ||
- $.expr.filters.hidden( this );
- }).length;
+ return $.expr.filters.visible( element ) &&
+ !$( element ).parents().andSelf().filter(function() {
+ return $.css( this, "visibility" ) === "hidden";
+ }).length;
}
$.extend( $.expr[ ":" ], {
@@ -228,41 +181,74 @@ $.extend( $.expr[ ":" ], {
});
// support
-$(function() {
- var body = document.body,
- div = body.appendChild( div = document.createElement( "div" ) );
-
- // access offsetHeight before setting the style to prevent a layout bug
- // in IE 9 which causes the element to continue to take up space even
- // after it is removed from the DOM (#8026)
- div.offsetHeight;
-
- $.extend( div.style, {
- minHeight: "100px",
- height: "auto",
- padding: 0,
- borderWidth: 0
- });
+$.support.selectstart = "onselectstart" in document.createElement( "div" );
- $.support.minHeight = div.offsetHeight === 100;
- $.support.selectstart = "onselectstart" in div;
+// support: jQuery <1.8
+if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
+ $.each( [ "Width", "Height" ], function( i, name ) {
+ var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
+ type = name.toLowerCase(),
+ orig = {
+ innerWidth: $.fn.innerWidth,
+ innerHeight: $.fn.innerHeight,
+ outerWidth: $.fn.outerWidth,
+ outerHeight: $.fn.outerHeight
+ };
- // set display to none to avoid a layout bug in IE
- // http://dev.jquery.com/ticket/4014
- body.removeChild( div ).style.display = "none";
-});
+ function reduce( elem, size, border, margin ) {
+ $.each( side, function() {
+ size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
+ if ( border ) {
+ size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
+ }
+ if ( margin ) {
+ size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
+ }
+ });
+ return size;
+ }
+ $.fn[ "inner" + name ] = function( size ) {
+ if ( size === undefined ) {
+ return orig[ "inner" + name ].call( this );
+ }
+
+ return this.each(function() {
+ $( this ).css( type, reduce( this, size ) + "px" );
+ });
+ };
+
+ $.fn[ "outer" + name] = function( size, margin ) {
+ if ( typeof size !== "number" ) {
+ return orig[ "outer" + name ].call( this, size );
+ }
+
+ return this.each(function() {
+ $( this).css( type, reduce( this, size, true, margin ) + "px" );
+ });
+ };
+ });
+}
+
+// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
+if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
+ $.fn.removeData = (function( removeData ) {
+ return function( key ) {
+ if ( arguments.length ) {
+ return removeData.call( this, $.camelCase( key ) );
+ } else {
+ return removeData.call( this );
+ }
+ };
+ })( $.fn.removeData );
+}
-// deprecated
-(function() {
- var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || [];
- $.ui.ie = uaMatch.length ? true : false;
- $.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6;
-})();
+// deprecated
+$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
$.fn.extend({
disableSelection: function() {
diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js
index 4643af2eb..c7ecafffb 100644
--- a/ui/jquery.ui.datepicker.js
+++ b/ui/jquery.ui.datepicker.js
@@ -13,6 +13,7 @@
*/
(function( $, undefined ) {
+/*jshint onevar: false, curly: false, eqeqeq: false, shadow: true, devel: true, evil: true */
$.extend($.ui, { datepicker: { version: "@VERSION" } });
var PROP_NAME = 'datepicker';
@@ -116,7 +117,7 @@ function Datepicker() {
$.extend(Datepicker.prototype, {
/* Class name added to elements to indicate already configured with a date picker. */
markerClassName: 'hasDatepicker',
-
+
//Keep track of the maximum number of rows displayed (see #7043)
maxRows: 4,
@@ -125,23 +126,25 @@ $.extend(Datepicker.prototype, {
if (this.debug)
console.log.apply('', arguments);
},
-
+
// TODO rename to "widget" when switching to widget factory
_widgetDatepicker: function() {
return this.dpDiv;
},
/* Override the default settings for all instances of the date picker.
- @param settings object - the new settings to use as defaults (anonymous object)
- @return the manager object */
+ * @param settings object - the new settings to use as defaults (anonymous object)
+ * @return the manager object
+ */
setDefaults: function(settings) {
extendRemove(this._defaults, settings || {});
return this;
},
/* Attach the date picker to a jQuery selection.
- @param target element - the target input field or division or span
- @param settings object - the new settings to use for this date picker instance (anonymous) */
+ * @param target element - the target input field or division or span
+ * @param settings object - the new settings to use for this date picker instance (anonymous)
+ */
_attachDatepicker: function(target, settings) {
// check for settings on the control itself - in namespace 'date:'
var inlineSettings = null;
@@ -173,7 +176,7 @@ $.extend(Datepicker.prototype, {
/* Create a new instance object. */
_newInst: function(target, inline) {
- var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
+ var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, '\\\\$1'); // escape jQuery meta chars
return {id: id, input: target, // associated target
selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
drawMonth: 0, drawYear: 0, // month being drawn
@@ -228,14 +231,14 @@ $.extend(Datepicker.prototype, {
$('<img/>').addClass(this._triggerClass).
attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
$('<button type="button"></button>').addClass(this._triggerClass).
- html(buttonImage == '' ? buttonText : $('<img/>').attr(
+ html(!buttonImage ? buttonText : $('<img/>').attr(
{ src:buttonImage, alt:buttonText, title:buttonText })));
input[isRTL ? 'before' : 'after'](inst.trigger);
inst.trigger.click(function() {
if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
$.datepicker._hideDatepicker();
else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
- $.datepicker._hideDatepicker();
+ $.datepicker._hideDatepicker();
$.datepicker._showDatepicker(input[0]);
} else
$.datepicker._showDatepicker(input[0]);
@@ -295,14 +298,15 @@ $.extend(Datepicker.prototype, {
},
/* Pop-up the date picker in a "dialog" box.
- @param input element - ignored
- @param date string or Date - the initial date to display
- @param onSelect function - the function to call when a date is selected
- @param settings object - update the dialog date picker instance's settings (anonymous object)
- @param pos int[2] - coordinates for the dialog's position within the screen or
- event - with x/y coordinates or
- leave empty for default (screen centre)
- @return the manager object */
+ * @param input element - ignored
+ * @param date string or Date - the initial date to display
+ * @param onSelect function - the function to call when a date is selected
+ * @param settings object - update the dialog date picker instance's settings (anonymous object)
+ * @param pos int[2] - coordinates for the dialog's position within the screen or
+ * event - with x/y coordinates or
+ * leave empty for default (screen centre)
+ * @return the manager object
+ */
_dialogDatepicker: function(input, date, onSelect, settings, pos) {
var inst = this._dialogInst; // internal instance
if (!inst) {
@@ -343,7 +347,8 @@ $.extend(Datepicker.prototype, {
},
/* Detach a datepicker from its control.
- @param target element - the target input field or division or span */
+ * @param target element - the target input field or division or span
+ */
_destroyDatepicker: function(target) {
var $target = $(target);
var inst = $.data(target, PROP_NAME);
@@ -365,7 +370,8 @@ $.extend(Datepicker.prototype, {
},
/* Enable the date picker to a jQuery selection.
- @param target element - the target input field or division or span */
+ * @param target element - the target input field or division or span
+ */
_enableDatepicker: function(target) {
var $target = $(target);
var inst = $.data(target, PROP_NAME);
@@ -390,7 +396,8 @@ $.extend(Datepicker.prototype, {
},
/* Disable the date picker to a jQuery selection.
- @param target element - the target input field or division or span */
+ * @param target element - the target input field or division or span
+ */
_disableDatepicker: function(target) {
var $target = $(target);
var inst = $.data(target, PROP_NAME);
@@ -416,8 +423,9 @@ $.extend(Datepicker.prototype, {
},
/* Is the first field in a jQuery collection disabled as a datepicker?
- @param target element - the target input field or division or span
- @return boolean - true if disabled, false if enabled */
+ * @param target element - the target input field or division or span
+ * @return boolean - true if disabled, false if enabled
+ */
_isDisabledDatepicker: function(target) {
if (!target) {
return false;
@@ -430,9 +438,10 @@ $.extend(Datepicker.prototype, {
},
/* Retrieve the instance data for the target control.
- @param target element - the target input field or division or span
- @return object - the associated instance data
- @throws error if a jQuery problem getting data */
+ * @param target element - the target input field or division or span
+ * @return object - the associated instance data
+ * @throws error if a jQuery problem getting data
+ */
_getInst: function(target) {
try {
return $.data(target, PROP_NAME);
@@ -443,13 +452,14 @@ $.extend(Datepicker.prototype, {
},
/* Update or retrieve the settings for a date picker attached to an input field or division.
- @param target element - the target input field or division or span
- @param name object - the new settings to update or
- string - the name of the setting to change or retrieve,
- when retrieving also 'all' for all instance settings or
- 'defaults' for all global defaults
- @param value any - the new value for the setting
- (omit if above is an object or to retrieve a value) */
+ * @param target element - the target input field or division or span
+ * @param name object - the new settings to update or
+ * string - the name of the setting to change or retrieve,
+ * when retrieving also 'all' for all instance settings or
+ * 'defaults' for all global defaults
+ * @param value any - the new value for the setting
+ * (omit if above is an object or to retrieve a value)
+ */
_optionDatepicker: function(target, name, value) {
var inst = this._getInst(target);
if (arguments.length == 2 && typeof name == 'string') {
@@ -471,9 +481,9 @@ $.extend(Datepicker.prototype, {
var maxDate = this._getMinMaxDate(inst, 'max');
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)
+ if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined)
inst.settings.minDate = this._formatDate(inst, minDate);
- if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
+ if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined)
inst.settings.maxDate = this._formatDate(inst, maxDate);
this._attachments($(target), inst);
this._autoSize(inst);
@@ -489,7 +499,8 @@ $.extend(Datepicker.prototype, {
},
/* Redraw the date picker attached to an input field or division.
- @param target element - the target input field or division or span */
+ * @param target element - the target input field or division or span
+ */
_refreshDatepicker: function(target) {
var inst = this._getInst(target);
if (inst) {
@@ -498,8 +509,9 @@ $.extend(Datepicker.prototype, {
},
/* Set the dates for a jQuery selection.
- @param target element - the target input field or division or span
- @param date Date - the new date */
+ * @param target element - the target input field or division or span
+ * @param date Date - the new date
+ */
_setDateDatepicker: function(target, date) {
var inst = this._getInst(target);
if (inst) {
@@ -510,9 +522,10 @@ $.extend(Datepicker.prototype, {
},
/* Get the date(s) for the first entry in a jQuery selection.
- @param target element - the target input field or division or span
- @param noDefault boolean - true if no default date is to be used
- @return Date - the current date */
+ * @param target element - the target input field or division or span
+ * @param noDefault boolean - true if no default date is to be used
+ * @return Date - the current date
+ */
_getDateDatepicker: function(target, noDefault) {
var inst = this._getInst(target);
if (inst && !inst.inline)
@@ -531,7 +544,7 @@ $.extend(Datepicker.prototype, {
case 9: $.datepicker._hideDatepicker();
handled = false;
break; // hide on tab out
- case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
+ case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
$.datepicker._currentClass + ')', inst.dpDiv);
if (sel[0])
$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
@@ -545,7 +558,6 @@ $.extend(Datepicker.prototype, {
else
$.datepicker._hideDatepicker();
return false; // don't submit the form
- break; // select the value on enter
case 27: $.datepicker._hideDatepicker();
break; // hide on escape
case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
@@ -602,7 +614,7 @@ $.extend(Datepicker.prototype, {
var inst = $.datepicker._getInst(event.target);
if ($.datepicker._get(inst, 'constrainInput')) {
var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
- var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
+ var chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
}
},
@@ -629,9 +641,10 @@ $.extend(Datepicker.prototype, {
},
/* Pop-up the date picker for a given input field.
- If false returned from beforeShow event handler do not show.
- @param input element - the input field attached to the date picker or
- event - if triggered by focus */
+ * If false returned from beforeShow event handler do not show.
+ * @param input element - the input field attached to the date picker or
+ * event - if triggered by focus
+ */
_showDatepicker: function(input) {
input = input.target || input;
if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
@@ -682,24 +695,13 @@ $.extend(Datepicker.prototype, {
if (!inst.inline) {
var showAnim = $.datepicker._get(inst, 'showAnim');
var duration = $.datepicker._get(inst, 'duration');
- var postProcess = function() {
- var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
- if( !! cover.length ){
- var borders = $.datepicker._getBorders(inst.dpDiv);
- cover.css({left: -borders[0], top: -borders[1],
- width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
- }
- };
inst.dpDiv.zIndex($(input).zIndex()+1);
$.datepicker._datepickerShowing = true;
- // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
- if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
- inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
+ if ( $.effects && $.effects.effect[ showAnim ] )
+ inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration);
else
- inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
- if (!showAnim || !duration)
- postProcess();
+ inst.dpDiv[showAnim || 'show'](showAnim ? duration : null);
if (inst.input.is(':visible') && !inst.input.is(':disabled'))
inst.input.focus();
$.datepicker._curInst = inst;
@@ -709,14 +711,9 @@ $.extend(Datepicker.prototype, {
/* Generate the date picker content. */
_updateDatepicker: function(inst) {
this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
- var borders = $.datepicker._getBorders(inst.dpDiv);
instActive = inst; // for delegate hover events
inst.dpDiv.empty().append(this._generateHTML(inst));
this._attachHandlers(inst);
- var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
- if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
- cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
- }
inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
var numMonths = this._getNumberOfMonths(inst);
var cols = numMonths[1];
@@ -733,7 +730,7 @@ $.extend(Datepicker.prototype, {
// this breaks the change event in IE
inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
inst.input.focus();
- // deffered render of the years select (to avoid flashes on Firefox)
+ // deffered render of the years select (to avoid flashes on Firefox)
if( inst.yearshtml ){
var origyearshtml = inst.yearshtml;
setTimeout(function(){
@@ -747,8 +744,9 @@ $.extend(Datepicker.prototype, {
},
/* Retrieve the size of left and top borders for an element.
- @param elem (jQuery object) the element of interest
- @return (number[2]) the left and top borders */
+ * @param elem (jQuery object) the element of interest
+ * @return (number[2]) the left and top borders
+ */
_getBorders: function(elem) {
var convert = function(value) {
return {thin: 1, medium: 2, thick: 3}[value] || value;
@@ -791,7 +789,8 @@ $.extend(Datepicker.prototype, {
},
/* Hide the date picker from view.
- @param input element - the input field attached to the date picker */
+ * @param input element - the input field attached to the date picker
+ */
_hideDatepicker: function(input) {
var inst = this._curInst;
if (!inst || (input && inst != $.data(input, PROP_NAME)))
@@ -842,7 +841,7 @@ $.extend(Datepicker.prototype, {
inst = $.datepicker._getInst($target[0]);
if ( ( ( $target[0].id != $.datepicker._mainDivId &&
- $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
+ $target.parents('#' + $.datepicker._mainDivId).length === 0 &&
!$target.hasClass($.datepicker.markerClassName) &&
!$target.closest("." + $.datepicker._triggerClass).length &&
$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
@@ -910,7 +909,6 @@ $.extend(Datepicker.prototype, {
/* Erase the input field and hide the date picker. */
_clearDate: function(id) {
var target = $(id);
- var inst = this._getInst(target[0]);
this._selectDate(target, '');
},
@@ -950,16 +948,18 @@ $.extend(Datepicker.prototype, {
},
/* Set as beforeShowDay function to prevent selection of weekends.
- @param date Date - the date to customise
- @return [boolean, string] - is this date selectable?, what is its CSS class? */
+ * @param date Date - the date to customise
+ * @return [boolean, string] - is this date selectable?, what is its CSS class?
+ */
noWeekends: function(date) {
var day = date.getDay();
return [(day > 0 && day < 6), ''];
},
/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
- @param date Date - the date to get the week for
- @return number - the number of the week within the year that contains this date */
+ * @param date Date - the date to get the week for
+ * @return number - the number of the week within the year that contains this date
+ */
iso8601Week: function(date) {
var checkDate = new Date(date.getTime());
// Find Thursday of this week starting on Monday
@@ -971,22 +971,23 @@ $.extend(Datepicker.prototype, {
},
/* Parse a string value into a date object.
- See formatDate below for the possible formats.
-
- @param format string - the expected format of the date
- @param value string - the date in the above format
- @param settings Object - attributes include:
- shortYearCutoff number - the cutoff year for determining the century (optional)
- dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
- dayNames string[7] - names of the days from Sunday (optional)
- monthNamesShort string[12] - abbreviated names of the months (optional)
- monthNames string[12] - names of the months (optional)
- @return Date - the extracted date value or null if value is blank */
+ * See formatDate below for the possible formats.
+ *
+ * @param format string - the expected format of the date
+ * @param value string - the date in the above format
+ * @param settings Object - attributes include:
+ * shortYearCutoff number - the cutoff year for determining the century (optional)
+ * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
+ * dayNames string[7] - names of the days from Sunday (optional)
+ * monthNamesShort string[12] - abbreviated names of the months (optional)
+ * monthNames string[12] - names of the months (optional)
+ * @return Date - the extracted date value or null if value is blank
+ */
parseDate: function (format, value, settings) {
if (format == null || value == null)
throw 'Invalid arguments';
value = (typeof value == 'object' ? value.toString() : value + '');
- if (value == '')
+ if (value === '')
return null;
var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
@@ -1141,32 +1142,33 @@ $.extend(Datepicker.prototype, {
Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
/* Format a date object into a string value.
- The format can be combinations of the following:
- d - day of month (no leading zero)
- dd - day of month (two digit)
- o - day of year (no leading zeros)
- oo - day of year (three digit)
- D - day name short
- DD - day name long
- m - month of year (no leading zero)
- mm - month of year (two digit)
- M - month name short
- MM - month name long
- y - year (two digit)
- yy - year (four digit)
- @ - Unix timestamp (ms since 01/01/1970)
- ! - Windows ticks (100ns since 01/01/0001)
- '...' - literal text
- '' - single quote
-
- @param format string - the desired format of the date
- @param date Date - the date value to format
- @param settings Object - attributes include:
- dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
- dayNames string[7] - names of the days from Sunday (optional)
- monthNamesShort string[12] - abbreviated names of the months (optional)
- monthNames string[12] - names of the months (optional)
- @return string - the date in the above format */
+ * The format can be combinations of the following:
+ * d - day of month (no leading zero)
+ * dd - day of month (two digit)
+ * o - day of year (no leading zeros)
+ * oo - day of year (three digit)
+ * D - day name short
+ * DD - day name long
+ * m - month of year (no leading zero)
+ * mm - month of year (two digit)
+ * M - month name short
+ * MM - month name long
+ * y - year (two digit)
+ * yy - year (four digit)
+ * @ - Unix timestamp (ms since 01/01/1970)
+ * ! - Windows ticks (100ns since 01/01/0001)
+ * '...' - literal text
+ * '' - single quote
+ *
+ * @param format string - the desired format of the date
+ * @param date Date - the date value to format
+ * @param settings Object - attributes include:
+ * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
+ * dayNames string[7] - names of the days from Sunday (optional)
+ * monthNamesShort string[12] - abbreviated names of the months (optional)
+ * monthNames string[12] - names of the months (optional)
+ * @return string - the date in the above format
+ */
formatDate: function (format, date, settings) {
if (!date)
return '';
@@ -1336,7 +1338,7 @@ $.extend(Datepicker.prototype, {
var year = date.getFullYear();
var month = date.getMonth();
var day = date.getDate();
- var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
+ var pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
var matches = pattern.exec(offset);
while (matches) {
switch (matches[2] || 'd') {
@@ -1370,11 +1372,12 @@ $.extend(Datepicker.prototype, {
},
/* Handle switch to/from daylight saving.
- Hours may be non-zero on daylight saving cut-over:
- > 12 when midnight changeover, but then cannot generate
- midnight datetime, so jump to 1AM, otherwise reset.
- @param date (Date) the date to check
- @return (Date) the corrected date */
+ * Hours may be non-zero on daylight saving cut-over:
+ * > 12 when midnight changeover, but then cannot generate
+ * midnight datetime, so jump to 1AM, otherwise reset.
+ * @param date (Date) the date to check
+ * @return (Date) the corrected date
+ */
_daylightSavingAdjust: function(date) {
if (!date) return null;
date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
@@ -1400,7 +1403,7 @@ $.extend(Datepicker.prototype, {
/* Retrieve the date(s) directly. */
_getDate: function(inst) {
- var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
+ var startDate = (!inst.currentYear || (inst.input && inst.input.val() === '') ? null :
this._daylightSavingAdjust(new Date(
inst.currentYear, inst.currentMonth, inst.currentDay)));
return startDate;
@@ -1442,7 +1445,7 @@ $.extend(Datepicker.prototype, {
$(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]);
});
},
-
+
/* Generate the HTML for the current state of the date picker. */
_generateHTML: function(inst) {
var today = new Date();
@@ -1509,14 +1512,12 @@ $.extend(Datepicker.prototype, {
firstDay = (isNaN(firstDay) ? 0 : firstDay);
var showWeek = this._get(inst, 'showWeek');
var dayNames = this._get(inst, 'dayNames');
- var dayNamesShort = this._get(inst, 'dayNamesShort');
var dayNamesMin = this._get(inst, 'dayNamesMin');
var monthNames = this._get(inst, 'monthNames');
var monthNamesShort = this._get(inst, 'monthNamesShort');
var beforeShowDay = this._get(inst, 'beforeShowDay');
var showOtherMonths = this._get(inst, 'showOtherMonths');
var selectOtherMonths = this._get(inst, 'selectOtherMonths');
- var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
var defaultDate = this._getDefaultDate(inst);
var html = '';
for (var row = 0; row < numMonths[0]; row++) {
@@ -1539,8 +1540,8 @@ $.extend(Datepicker.prototype, {
calender += '">';
}
calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
- (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
- (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
+ (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : '') +
+ (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : '') +
this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
'</div><table class="ui-datepicker-calendar"><thead>' +
@@ -1599,14 +1600,13 @@ $.extend(Datepicker.prototype, {
drawMonth = 0;
drawYear++;
}
- calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
+ calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
group += calender;
}
html += group;
}
- html += buttonPanel + ($.ui.ie6 && !inst.inline ?
- '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
+ html += buttonPanel;
inst._keyEvent = false;
return html;
},
@@ -1647,8 +1647,8 @@ $.extend(Datepicker.prototype, {
var years = this._get(inst, 'yearRange').split(':');
var thisYear = new Date().getFullYear();
var determineYear = function(value) {
- var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
- (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
+ var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
+ (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
parseInt(value, 10)));
return (isNaN(year) ? thisYear : year);
};
@@ -1663,7 +1663,7 @@ $.extend(Datepicker.prototype, {
'>' + year + '</option>';
}
inst.yearshtml += '</select>';
-
+
html += inst.yearshtml;
inst.yearshtml = null;
}
@@ -1774,7 +1774,7 @@ $.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.
- */
+ */
function bindHover(dpDiv) {
var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
return dpDiv.delegate(selector, 'mouseout', function() {
@@ -1796,22 +1796,22 @@ function bindHover(dpDiv) {
function extendRemove(target, props) {
$.extend(target, props);
for (var name in props)
- if (props[name] == null || props[name] == undefined)
+ if (props[name] == null)
target[name] = props[name];
return target;
-};
+}
/* Invoke the datepicker functionality.
@param options string - a command, optionally followed by additional parameters or
- Object - settings for attaching new datepicker functionality
+ Object - settings for attaching new datepicker functionality
@return jQuery object */
$.fn.datepicker = function(options){
-
+
/* Verify an empty collection wasn't passed - Fixes #6976 */
if ( !this.length ) {
return this;
}
-
+
/* Initialise the date picker. */
if (!$.datepicker.initialized) {
$(document).mousedown($.datepicker._checkExternalClick).
diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js
index 8593fff85..07c5c7cb6 100644
--- a/ui/jquery.ui.dialog.js
+++ b/ui/jquery.ui.dialog.js
@@ -19,7 +19,7 @@
*/
(function( $, undefined ) {
-var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ",
+var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front ",
sizeRelatedOptions = {
buttons: true,
height: true,
@@ -67,10 +67,8 @@ $.widget("ui.dialog", {
},
resizable: true,
show: null,
- stack: true,
title: "",
- width: 300,
- zIndex: 1000
+ width: 300
},
_create: function() {
@@ -88,14 +86,15 @@ $.widget("ui.dialog", {
options = this.options,
title = options.title || "&#160;",
+ uiDialog,
+ uiDialogTitlebar,
+ uiDialogTitlebarClose,
+ uiDialogTitle,
+ uiDialogButtonPane;
uiDialog = ( this.uiDialog = $( "<div>" ) )
.addClass( uiDialogClasses + options.dialogClass )
- .css({
- display: "none",
- outline: 0, // TODO: move to stylesheet
- zIndex: options.zIndex
- })
+ .hide()
// setting tabIndex makes the div focusable
.attr( "tabIndex", -1)
.keydown(function( event ) {
@@ -106,20 +105,24 @@ $.widget("ui.dialog", {
}
})
.mousedown(function( event ) {
- that.moveToTop( false, event );
+ that.moveToTop( event );
})
- .appendTo( "body" ),
+ .appendTo( this.document[ 0 ].body );
- uiDialogContent = this.element
+ this.element
.show()
.removeAttr( "title" )
.addClass( "ui-dialog-content ui-widget-content" )
- .appendTo( uiDialog ),
+ .appendTo( uiDialog );
uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) )
.addClass( "ui-dialog-titlebar ui-widget-header " +
"ui-corner-all ui-helper-clearfix" )
- .prependTo( uiDialog ),
+ .bind( "mousedown", function() {
+ // Dialog isn't getting focus when dragging (#8063)
+ uiDialog.focus();
+ })
+ .prependTo( uiDialog );
uiDialogTitlebarClose = $( "<a href='#'></a>" )
.addClass( "ui-dialog-titlebar-close ui-corner-all" )
@@ -128,23 +131,23 @@ $.widget("ui.dialog", {
event.preventDefault();
that.close( event );
})
- .appendTo( uiDialogTitlebar ),
+ .appendTo( uiDialogTitlebar );
- uiDialogTitlebarCloseText = ( this.uiDialogTitlebarCloseText = $( "<span>" ) )
+ ( this.uiDialogTitlebarCloseText = $( "<span>" ) )
.addClass( "ui-icon ui-icon-closethick" )
.text( options.closeText )
- .appendTo( uiDialogTitlebarClose ),
+ .appendTo( uiDialogTitlebarClose );
uiDialogTitle = $( "<span>" )
.uniqueId()
.addClass( "ui-dialog-title" )
.html( title )
- .prependTo( uiDialogTitlebar ),
+ .prependTo( uiDialogTitlebar );
uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) )
- .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ),
+ .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
- uiButtonSet = ( this.uiButtonSet = $( "<div>" ) )
+ ( this.uiButtonSet = $( "<div>" ) )
.addClass( "ui-dialog-buttonset" )
.appendTo( uiDialogButtonPane );
@@ -167,13 +170,9 @@ $.widget("ui.dialog", {
this._createButtons( options.buttons );
this._isOpen = false;
- if ( $.fn.bgiframe ) {
- uiDialog.bgiframe();
- }
-
- // prevent tabbing out of modal dialogs
+ // prevent tabbing out of dialogs
this._on( uiDialog, { keydown: function( event ) {
- if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) {
+ if ( event.keyCode !== $.ui.keyCode.TAB ) {
return;
}
@@ -181,10 +180,10 @@ $.widget("ui.dialog", {
first = tabbables.filter( ":first" ),
last = tabbables.filter( ":last" );
- if ( event.target === last[0] && !event.shiftKey ) {
+ if ( ( event.target === last[ 0 ] || event.target === uiDialog[ 0 ] ) && !event.shiftKey ) {
first.focus( 1 );
return false;
- } else if ( event.target === first[0] && event.shiftKey ) {
+ } else if ( ( event.target === first[ 0 ] || event.target === uiDialog[ 0 ] ) && event.shiftKey ) {
last.focus( 1 );
return false;
}
@@ -229,8 +228,7 @@ $.widget("ui.dialog", {
},
close: function( event ) {
- var that = this,
- maxZ, thisZ;
+ var that = this;
if ( !this._isOpen ) {
return;
@@ -246,71 +244,27 @@ $.widget("ui.dialog", {
this.overlay.destroy();
}
- if ( this.options.hide ) {
- this.uiDialog.hide( this.options.hide, function() {
- that._trigger( "close", event );
- });
- } else {
- this.uiDialog.hide();
- this._trigger( "close", event );
+ if ( !this.opener.filter( ":focusable" ).focus().length ) {
+ // Hiding a focused element doesn't trigger blur in WebKit
+ // so in case we have nothing to focus on, explicitly blur the active element
+ // https://bugs.webkit.org/show_bug.cgi?id=47182
+ $( this.document[ 0 ].activeElement ).blur();
}
- $.ui.dialog.overlay.resize();
-
- // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
- if ( this.options.modal ) {
- maxZ = 0;
- $( ".ui-dialog" ).each(function() {
- if ( this !== that.uiDialog[0] ) {
- thisZ = $( this ).css( "z-index" );
- if ( !isNaN( thisZ ) ) {
- maxZ = Math.max( maxZ, thisZ );
- }
- }
- });
- $.ui.dialog.maxZ = maxZ;
- }
-
- return this;
+ this._hide( this.uiDialog, this.options.hide, function() {
+ that._trigger( "close", event );
+ });
},
isOpen: function() {
return this._isOpen;
},
- // the force parameter allows us to move modal dialogs to their correct
- // position on open
- moveToTop: function( force, event ) {
- var options = this.options,
- saveScroll;
-
- if ( ( options.modal && !force ) ||
- ( !options.stack && !options.modal ) ) {
- return this._trigger( "focus", event );
+ moveToTop: function( event, silent ) {
+ var moved = this.uiDialog.nextAll( ":visible" ).insertBefore( this.uiDialog );
+ if ( !silent && moved.length ) {
+ this._trigger( "focus", event );
}
-
- if ( options.zIndex > $.ui.dialog.maxZ ) {
- $.ui.dialog.maxZ = options.zIndex;
- }
- if ( this.overlay ) {
- $.ui.dialog.maxZ += 1;
- $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ;
- this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ );
- }
-
- // Save and then restore scroll
- // Opera 9.5+ resets when parent z-index is changed.
- // http://bugs.jqueryui.com/ticket/3193
- saveScroll = {
- scrollTop: this.element.scrollTop(),
- scrollLeft: this.element.scrollLeft()
- };
- $.ui.dialog.maxZ += 1;
- this.uiDialog.css( "z-index", $.ui.dialog.maxZ );
- this.element.attr( saveScroll );
- this._trigger( "focus", event );
-
- return this;
},
open: function() {
@@ -322,11 +276,13 @@ $.widget("ui.dialog", {
options = this.options,
uiDialog = this.uiDialog;
+ this.opener = $( this.document[ 0 ].activeElement );
+
this._size();
this._position( options.position );
- uiDialog.show( options.show );
this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null;
- this.moveToTop( true );
+ this.moveToTop( null, true );
+ this._show( uiDialog, options.show );
// set focus to the first tabbable element in the content area or the first button
// if there are no tabbable elements, set focus on the dialog itself
@@ -341,13 +297,30 @@ $.widget("ui.dialog", {
this._isOpen = true;
this._trigger( "open" );
+ this._trigger( "focus" );
return this;
},
+ _keepFocus: function( event ) {
+ function checkFocus() {
+ var activeElement = this.document[ 0 ].activeElement,
+ isActive = this.uiDialog[ 0 ] === activeElement ||
+ $.contains( this.uiDialog[ 0 ], activeElement );
+ if ( !isActive ) {
+ this.uiDialog.focus();
+ }
+ }
+ event.preventDefault();
+ checkFocus.call( this );
+ // support: IE
+ // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
+ // so we check again later
+ this._delay( checkFocus );
+ },
+
_createButtons: function( buttons ) {
- var uiDialogButtonPane, uiButtonSet,
- that = this,
+ var that = this,
hasButtons = false;
// if we already have a button pane, remove it
@@ -361,15 +334,18 @@ $.widget("ui.dialog", {
}
if ( hasButtons ) {
$.each( buttons, function( name, props ) {
+ var button, click;
props = $.isFunction( props ) ?
{ click: props, text: name } :
props;
- var button = $( "<button type='button'></button>" )
- .attr( props, true )
- .unbind( "click" )
- .click(function() {
- props.click.apply( that.element[0], arguments );
- })
+ // Default to a non-submitting button
+ props = $.extend( { type: "button" }, props );
+ // Change the context for the click callback to be the main element
+ click = props.click;
+ props.click = function() {
+ click.apply( that.element[0], arguments );
+ };
+ button = $( "<button></button>", props )
.appendTo( that.uiButtonSet );
if ( $.fn.button ) {
button.button();
@@ -413,7 +389,6 @@ $.widget("ui.dialog", {
$( this )
.removeClass( "ui-dialog-dragging" );
that._trigger( "dragStop", event, filteredUi( ui ) );
- $.ui.dialog.overlay.resize();
}
});
},
@@ -459,7 +434,6 @@ $.widget("ui.dialog", {
options.height = $( this ).height();
options.width = $( this ).width();
that._trigger( "resizeStop", event, filteredUi( ui ) );
- $.ui.dialog.overlay.resize();
}
})
.css( "position", position )
@@ -501,9 +475,9 @@ $.widget("ui.dialog", {
});
position = {
- my: myAt.join( " " ),
- at: myAt.join( " " ),
- offset: offset.join( " " )
+ my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
+ myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
+ at: myAt.join( " " )
};
}
@@ -542,7 +516,7 @@ $.widget("ui.dialog", {
if ( resize ) {
this._size();
}
- if ( this.uiDialog.is( ":data(resizable)" ) ) {
+ if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
this.uiDialog.resizable( "option", resizableOptions );
}
},
@@ -572,7 +546,7 @@ $.widget("ui.dialog", {
}
break;
case "draggable":
- isDraggable = uiDialog.is( ":data(draggable)" );
+ isDraggable = uiDialog.is( ":data(ui-draggable)" );
if ( isDraggable && !value ) {
uiDialog.draggable( "destroy" );
}
@@ -586,7 +560,7 @@ $.widget("ui.dialog", {
break;
case "resizable":
// currently resizable, becoming non-resizable
- isResizable = uiDialog.is( ":data(resizable)" );
+ isResizable = uiDialog.is( ":data(ui-resizable)" );
if ( isResizable && !value ) {
uiDialog.resizable( "destroy" );
}
@@ -612,12 +586,11 @@ $.widget("ui.dialog", {
},
_size: function() {
- /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
- * divs will both have width and height set, so we need to reset them
- */
- var nonContentHeight, minContentHeight, autoHeight,
- options = this.options,
- isVisible = this.uiDialog.is( ":visible" );
+
+ // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
+ // divs will both have width and height set, so we need to reset them
+ var nonContentHeight, minContentHeight,
+ options = this.options;
// reset content sizing
this.element.show().css({
@@ -640,25 +613,15 @@ $.widget("ui.dialog", {
minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
if ( options.height === "auto" ) {
- // only needed for IE6 support
- if ( $.support.minHeight ) {
- this.element.css({
- minHeight: minContentHeight,
- height: "auto"
- });
- } else {
- this.uiDialog.show();
- autoHeight = this.element.css( "height", "auto" ).height();
- if ( !isVisible ) {
- this.uiDialog.hide();
- }
- this.element.height( Math.max( autoHeight, minContentHeight ) );
- }
+ this.element.css({
+ minHeight: minContentHeight,
+ height: "auto"
+ });
} else {
this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
}
- if (this.uiDialog.is( ":data(resizable)" ) ) {
+ if (this.uiDialog.is( ":data(ui-resizable)" ) ) {
this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
}
}
@@ -666,7 +629,6 @@ $.widget("ui.dialog", {
$.extend($.ui.dialog, {
uuid: 0,
- maxZ: 0,
getTitleId: function($el) {
var id = $el.attr( "id" );
@@ -686,66 +648,22 @@ $.extend( $.ui.dialog.overlay, {
instances: [],
// reuse old instances due to IE memory leak with alpha transparency (see #5185)
oldInstances: [],
- maxZ: 0,
- events: $.map(
- "focus,mousedown,mouseup,keydown,keypress,click".split( "," ),
- function( event ) {
- return event + ".dialog-overlay";
- }
- ).join( " " ),
create: function( dialog ) {
- if ( this.instances.length === 0 ) {
- // prevent use of anchors and inputs
- // we use a setTimeout in case the overlay is created from an
- // event that we're going to be cancelling (see #2804)
- setTimeout(function() {
- // handle $(el).dialog().dialog('close') (see #4065)
- if ( $.ui.dialog.overlay.instances.length ) {
- $( document ).bind( $.ui.dialog.overlay.events, function( event ) {
- // stop events if the z-index of the target is < the z-index of the overlay
- // we cannot return true when we don't want to cancel the event (#3523)
- if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) {
- return false;
- }
- });
- }
- }, 1 );
- // handle window resize
- $( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize );
- }
+ var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay ui-front" ) );
- var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) );
+ $el.appendTo( document.body );
- // allow closing by pressing the escape key
- $( document ).bind( "keydown.dialog-overlay", function( event ) {
- var instances = $.ui.dialog.overlay.instances;
- // only react to the event if we're the top overlay
- if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el &&
- dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
- event.keyCode === $.ui.keyCode.ESCAPE ) {
-
- dialog.close( event );
- event.preventDefault();
- }
- });
-
- $el.appendTo( document.body ).css({
- width: this.width(),
- height: this.height()
+ $el.bind( "mousedown", function( event ) {
+ dialog._keepFocus( event );
});
- if ( $.fn.bgiframe ) {
- $el.bgiframe();
- }
-
this.instances.push( $el );
return $el;
},
destroy: function( $el ) {
- var indexOf = $.inArray( $el, this.instances ),
- maxZ = 0;
+ var indexOf = $.inArray( $el, this.instances );
if ( indexOf !== -1 ) {
this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] );
@@ -755,86 +673,7 @@ $.extend( $.ui.dialog.overlay, {
$( [ document, window ] ).unbind( ".dialog-overlay" );
}
- $el.height( 0 ).width( 0 ).remove();
-
- // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
- $.each( this.instances, function() {
- maxZ = Math.max( maxZ, this.css( "z-index" ) );
- });
- this.maxZ = maxZ;
- },
-
- height: function() {
- var scrollHeight,
- offsetHeight;
- // handle IE
- if ( $.ui.ie ) {
- scrollHeight = Math.max(
- document.documentElement.scrollHeight,
- document.body.scrollHeight
- );
- offsetHeight = Math.max(
- document.documentElement.offsetHeight,
- document.body.offsetHeight
- );
-
- if ( scrollHeight < offsetHeight ) {
- return $( window ).height() + "px";
- } else {
- return scrollHeight + "px";
- }
- // handle "good" browsers
- } else {
- return $( document ).height() + "px";
- }
- },
-
- width: function() {
- var scrollWidth,
- offsetWidth;
- // handle IE
- if ( $.ui.ie ) {
- scrollWidth = Math.max(
- document.documentElement.scrollWidth,
- document.body.scrollWidth
- );
- offsetWidth = Math.max(
- document.documentElement.offsetWidth,
- document.body.offsetWidth
- );
-
- if ( scrollWidth < offsetWidth ) {
- return $( window ).width() + "px";
- } else {
- return scrollWidth + "px";
- }
- // handle "good" browsers
- } else {
- return $( document ).width() + "px";
- }
- },
-
- resize: function() {
- /* If the dialog is draggable and the user drags it past the
- * right edge of the window, the document becomes wider so we
- * need to stretch the overlay. If the user then drags the
- * dialog back to the left, the document will become narrower,
- * so we need to shrink the overlay to the appropriate size.
- * This is handled by shrinking the overlay before setting it
- * to the full document size.
- */
- var $overlays = $( [] );
- $.each( $.ui.dialog.overlay.instances, function() {
- $overlays = $overlays.add( this );
- });
-
- $overlays.css({
- width: 0,
- height: 0
- }).css({
- width: $.ui.dialog.overlay.width(),
- height: $.ui.dialog.overlay.height()
- });
+ $el.remove();
}
});
diff --git a/ui/jquery.ui.draggable.js b/ui/jquery.ui.draggable.js
index 5d91a3d94..1f3c8d52c 100644
--- a/ui/jquery.ui.draggable.js
+++ b/ui/jquery.ui.draggable.js
@@ -15,6 +15,7 @@
*/
(function( $, undefined ) {
+/*jshint onevar: false, curly: false, eqeqeq: false, laxbreak: true, shadow: true, funcscope: true */
$.widget("ui.draggable", $.ui.mouse, {
version: "@VERSION",
widgetEventPrefix: "drag",
@@ -73,7 +74,7 @@ $.widget("ui.draggable", $.ui.mouse, {
this.handle = this._getHandle(event);
if (!this.handle)
return false;
-
+
$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
.css({
@@ -157,12 +158,12 @@ $.widget("ui.draggable", $.ui.mouse, {
if ($.ui.ddmanager && !o.dropBehaviour)
$.ui.ddmanager.prepareOffsets(this, event);
-
+
this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
-
+
//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
-
+
return true;
},
@@ -201,7 +202,7 @@ $.widget("ui.draggable", $.ui.mouse, {
dropped = this.dropped;
this.dropped = false;
}
-
+
//if the original element is no longer in the DOM don't bother to continue (see #8269)
var element = this.element[0], elementInDom = false;
while ( element && (element = element.parentNode) ) {
@@ -227,29 +228,29 @@ $.widget("ui.draggable", $.ui.mouse, {
return false;
},
-
+
_mouseUp: function(event) {
//Remove frame helpers
- $("div.ui-draggable-iframeFix").each(function() {
- this.parentNode.removeChild(this);
+ $("div.ui-draggable-iframeFix").each(function() {
+ this.parentNode.removeChild(this);
});
-
+
//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
-
+
return $.ui.mouse.prototype._mouseUp.call(this, event);
},
-
+
cancel: function() {
-
+
if(this.helper.is(".ui-draggable-dragging")) {
this._mouseUp({});
} else {
this._clear();
}
-
+
return this;
-
+
},
_getHandle: function(event) {
@@ -372,7 +373,6 @@ $.widget("ui.draggable", $.ui.mouse, {
if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
var c = $(o.containment);
var ce = c[0]; if(!ce) return;
- var co = c.offset();
var over = ($(ce).css("overflow") != 'hidden');
this.containment = [
@@ -393,7 +393,7 @@ $.widget("ui.draggable", $.ui.mouse, {
if(!pos) pos = this.position;
var mod = d == "absolute" ? 1 : -1;
- var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+ var scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
return {
top: (
@@ -446,10 +446,10 @@ $.widget("ui.draggable", $.ui.mouse, {
if(o.grid) {
//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
- pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+ pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
- pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+ pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
}
}
@@ -492,7 +492,7 @@ $.widget("ui.draggable", $.ui.mouse, {
plugins: {},
- _uiHash: function(event) {
+ _uiHash: function() {
return {
helper: this.helper,
position: this.position,
@@ -506,11 +506,11 @@ $.widget("ui.draggable", $.ui.mouse, {
$.ui.plugin.add("draggable", "connectToSortable", {
start: function(event, ui) {
- var inst = $(this).data("draggable"), o = inst.options,
+ var inst = $(this).data("ui-draggable"), o = inst.options,
uiSortable = $.extend({}, ui, { item: inst.element });
inst.sortables = [];
$(o.connectToSortable).each(function() {
- var sortable = $.data(this, 'sortable');
+ var sortable = $.data(this, 'ui-sortable');
if (sortable && !sortable.options.disabled) {
inst.sortables.push({
instance: sortable,
@@ -525,7 +525,7 @@ $.ui.plugin.add("draggable", "connectToSortable", {
stop: function(event, ui) {
//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
- var inst = $(this).data("draggable"),
+ var inst = $(this).data("ui-draggable"),
uiSortable = $.extend({}, ui, { item: inst.element });
$.each(inst.sortables, function() {
@@ -558,26 +558,17 @@ $.ui.plugin.add("draggable", "connectToSortable", {
},
drag: function(event, ui) {
- var inst = $(this).data("draggable"), that = this;
-
- var checkPos = function(o) {
- var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
- var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
- var itemHeight = o.height, itemWidth = o.width;
- var itemTop = o.top, itemLeft = o.left;
+ var inst = $(this).data("ui-draggable"), that = this;
- return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
- };
+ $.each(inst.sortables, function() {
- $.each(inst.sortables, function(i) {
-
var innermostIntersecting = false;
var thisSortable = this;
//Copy over some variables to allow calling the sortable's native _intersectsWith
this.instance.positionAbs = inst.positionAbs;
this.instance.helperProportions = inst.helperProportions;
this.instance.offset.click = inst.offset.click;
-
+
if(this.instance._intersectsWith(this.instance.containerCache)) {
innermostIntersecting = true;
$.each(inst.sortables, function () {
@@ -601,7 +592,7 @@ $.ui.plugin.add("draggable", "connectToSortable", {
//Now we fake the start of dragging for the sortable instance,
//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
- this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
+ this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("ui-sortable-item", true);
this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
this.instance.options.helper = function() { return ui.helper[0]; };
@@ -634,13 +625,13 @@ $.ui.plugin.add("draggable", "connectToSortable", {
this.instance.isOver = 0;
this.instance.cancelHelperRemoval = true;
-
+
//Prevent reverting on this forced stop
this.instance.options.revert = false;
-
+
// The out event needs to be triggered independently
this.instance._trigger('out', event, this.instance._uiHash(this.instance));
-
+
this.instance._mouseStop(event, true);
this.instance.options.helper = this.instance.options._helper;
@@ -652,7 +643,7 @@ $.ui.plugin.add("draggable", "connectToSortable", {
inst.dropped = false; //draggable revert needs that
}
- };
+ }
});
@@ -660,37 +651,37 @@ $.ui.plugin.add("draggable", "connectToSortable", {
});
$.ui.plugin.add("draggable", "cursor", {
- start: function(event, ui) {
- var t = $('body'), o = $(this).data('draggable').options;
+ start: function() {
+ var t = $('body'), o = $(this).data('ui-draggable').options;
if (t.css("cursor")) o._cursor = t.css("cursor");
t.css("cursor", o.cursor);
},
- stop: function(event, ui) {
- var o = $(this).data('draggable').options;
+ stop: function() {
+ var o = $(this).data('ui-draggable').options;
if (o._cursor) $('body').css("cursor", o._cursor);
}
});
$.ui.plugin.add("draggable", "opacity", {
start: function(event, ui) {
- var t = $(ui.helper), o = $(this).data('draggable').options;
+ var t = $(ui.helper), o = $(this).data('ui-draggable').options;
if(t.css("opacity")) o._opacity = t.css("opacity");
t.css('opacity', o.opacity);
},
stop: function(event, ui) {
- var o = $(this).data('draggable').options;
+ var o = $(this).data('ui-draggable').options;
if(o._opacity) $(ui.helper).css('opacity', o._opacity);
}
});
$.ui.plugin.add("draggable", "scroll", {
- start: function(event, ui) {
- var i = $(this).data("draggable");
+ start: function() {
+ var i = $(this).data("ui-draggable");
if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
},
- drag: function(event, ui) {
+ drag: function( event ) {
- var i = $(this).data("draggable"), o = i.options, scrolled = false;
+ var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
@@ -733,12 +724,12 @@ $.ui.plugin.add("draggable", "scroll", {
});
$.ui.plugin.add("draggable", "snap", {
- start: function(event, ui) {
+ start: function() {
- var i = $(this).data("draggable"), o = i.options;
+ var i = $(this).data("ui-draggable"), o = i.options;
i.snapElements = [];
- $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
+ $(o.snap.constructor != String ? ( o.snap.items || ':data(ui-draggable)' ) : o.snap).each(function() {
var $t = $(this); var $o = $t.offset();
if(this != i.element[0]) i.snapElements.push({
item: this,
@@ -750,7 +741,7 @@ $.ui.plugin.add("draggable", "snap", {
},
drag: function(event, ui) {
- var inst = $(this).data("draggable"), o = inst.options;
+ var inst = $(this).data("ui-draggable"), o = inst.options;
var d = o.snapTolerance;
var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
@@ -796,22 +787,22 @@ $.ui.plugin.add("draggable", "snap", {
(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
- };
+ }
}
});
$.ui.plugin.add("draggable", "stack", {
- start: function(event, ui) {
+ start: function() {
- var o = $(this).data("draggable").options;
+ var o = $(this).data("ui-draggable").options;
var 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; }
-
- var min = parseInt(group[0].style.zIndex) || 0;
+
+ var min = parseInt(group[0].style.zIndex, 10) || 0;
$(group).each(function(i) {
this.style.zIndex = min + i;
});
@@ -823,12 +814,12 @@ $.ui.plugin.add("draggable", "stack", {
$.ui.plugin.add("draggable", "zIndex", {
start: function(event, ui) {
- var t = $(ui.helper), o = $(this).data("draggable").options;
+ var t = $(ui.helper), o = $(this).data("ui-draggable").options;
if(t.css("zIndex")) o._zIndex = t.css("zIndex");
t.css('zIndex', o.zIndex);
},
stop: function(event, ui) {
- var o = $(this).data("draggable").options;
+ var o = $(this).data("ui-draggable").options;
if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
}
});
diff --git a/ui/jquery.ui.droppable.js b/ui/jquery.ui.droppable.js
index 93e74d211..f27d56b85 100644
--- a/ui/jquery.ui.droppable.js
+++ b/ui/jquery.ui.droppable.js
@@ -16,6 +16,7 @@
*/
(function( $, undefined ) {
+/*jshint onevar: false, curly: false, eqeqeq: false, laxbreak: true */
$.widget("ui.droppable", {
version: "@VERSION",
widgetEventPrefix: "drop",
@@ -109,8 +110,8 @@ $.widget("ui.droppable", {
if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
var childrenIntersection = false;
- this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
- var inst = $.data(this, 'droppable');
+ this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
+ var inst = $.data(this, 'ui-droppable');
if(
inst.options.greedy
&& !inst.options.disabled
@@ -156,33 +157,28 @@ $.ui.intersect = function(draggable, droppable, toleranceMode) {
case 'fit':
return (l <= x1 && x2 <= r
&& t <= y1 && y2 <= b);
- break;
case 'intersect':
return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
- break;
case 'pointer':
var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
return isOver;
- break;
case 'touch':
return (
- (y1 >= t && y1 <= b) || // Top edge touching
- (y2 >= t && y2 <= b) || // Bottom edge touching
- (y1 < t && y2 > b) // Surrounded vertically
- ) && (
- (x1 >= l && x1 <= r) || // Left edge touching
- (x2 >= l && x2 <= r) || // Right edge touching
- (x1 < l && x2 > r) // Surrounded horizontally
- );
- break;
+ (y1 >= t && y1 <= b) || // Top edge touching
+ (y2 >= t && y2 <= b) || // Bottom edge touching
+ (y1 < t && y2 > b) // Surrounded vertically
+ ) && (
+ (x1 >= l && x1 <= r) || // Left edge touching
+ (x2 >= l && x2 <= r) || // Right edge touching
+ (x1 < l && x2 > r) // Surrounded horizontally
+ );
default:
return false;
- break;
}
};
@@ -197,13 +193,19 @@ $.ui.ddmanager = {
var m = $.ui.ddmanager.droppables[t.options.scope] || [];
var type = event ? event.type : null; // workaround for #2317
- var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
+ var list = (t.currentItem || t.element).find(":data(ui-droppable)").andSelf();
droppablesLoop: for (var i = 0; i < m.length; i++) {
if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
- for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
- m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
+ // Filter out elements in the current dragged item
+ for (var j=0; j < list.length; j++) {
+ if(list[j] == m[i].element[0]) {
+ m[i].proportions.height = 0;
+ continue droppablesLoop;
+ }
+ }
+ m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
@@ -248,27 +250,27 @@ $.ui.ddmanager = {
if(this.options.disabled || this.greedyChild || !this.visible) return;
var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
- var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
+ var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover === 0 ? 'isover' : null);
if(!c) return;
var parentInstance;
if (this.options.greedy) {
// find droppable parents with same scope
var scope = this.options.scope;
- var parent = this.element.parents(':data(droppable)').filter(function () {
- return $.data(this, 'droppable').options.scope === scope;
+ var parent = this.element.parents(':data(ui-droppable)').filter(function () {
+ return $.data(this, 'ui-droppable').options.scope === scope;
});
if (parent.length) {
- parentInstance = $.data(parent[0], 'droppable');
+ parentInstance = $.data(parent[0], 'ui-droppable');
parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
}
}
// we just moved into a greedy child
if (parentInstance && c == 'isover') {
- parentInstance['isover'] = 0;
- parentInstance['isout'] = 1;
+ parentInstance.isover = 0;
+ parentInstance.isout = 1;
parentInstance._out.call(parentInstance, event);
}
@@ -277,8 +279,8 @@ $.ui.ddmanager = {
// we just moved out of a greedy child
if (parentInstance && c == 'isout') {
- parentInstance['isout'] = 0;
- parentInstance['isover'] = 1;
+ parentInstance.isout = 0;
+ parentInstance.isover = 1;
parentInstance._over.call(parentInstance, event);
}
});
diff --git a/ui/jquery.ui.effect-highlight.js b/ui/jquery.ui.effect-highlight.js
index 0b0dbd988..99c41de2f 100644
--- a/ui/jquery.ui.effect-highlight.js
+++ b/ui/jquery.ui.effect-highlight.js
@@ -26,7 +26,7 @@ $.effects.effect.highlight = function( o, done ) {
}
$.effects.save( elem, props );
-
+
elem
.show()
.css({
diff --git a/ui/jquery.ui.effect-scale.js b/ui/jquery.ui.effect-scale.js
index 933530a67..7fa04bed6 100644
--- a/ui/jquery.ui.effect-scale.js
+++ b/ui/jquery.ui.effect-scale.js
@@ -102,8 +102,9 @@ $.effects.effect.scale = function( o, done ) {
$.effects.effect.size = function( o, done ) {
// Create element
- var el = $( this ),
- props = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
+ var original, baseline, factor,
+ el = $( this ),
+ props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
// Always restore
props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
@@ -119,8 +120,12 @@ $.effects.effect.size = function( o, done ) {
restore = o.restore || mode !== "effect",
scale = o.scale || "both",
origin = o.origin || [ "middle", "center" ],
- original, baseline, factor,
- position = el.css( "position" );
+ position = el.css( "position" ),
+ props = restore ? props0 : props1,
+ zero = {
+ height: 0,
+ width: 0
+ };
if ( mode === "show" ) {
el.show();
@@ -132,8 +137,13 @@ $.effects.effect.size = function( o, done ) {
outerWidth: el.outerWidth()
};
- el.from = o.from || original;
- el.to = o.to || original;
+ if ( o.mode === "toggle" && mode === "show" ) {
+ el.from = o.to || zero;
+ el.to = o.from || original;
+ } else {
+ el.from = o.from || ( mode === "show" ? zero : original );
+ el.to = o.to || ( mode === "hide" ? zero : original );
+ }
// Set scaling factor
factor = {
@@ -170,13 +180,13 @@ $.effects.effect.size = function( o, done ) {
// Vertical props scaling
if ( factor.from.y !== factor.to.y ) {
- props = props.concat( cProps );
+ props = props.concat( cProps ).concat( props2 );
el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
}
}
- $.effects.save( el, restore ? props : props1 );
+ $.effects.save( el, props );
el.show();
$.effects.createWrapper( el );
el.css( "overflow", "hidden" ).css( el.from );
@@ -197,7 +207,7 @@ $.effects.effect.size = function( o, done ) {
// Add margins/font-size
vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
hProps = hProps.concat([ "marginLeft", "marginRight" ]);
- props2 = props.concat(vProps).concat(hProps);
+ props2 = props0.concat(vProps).concat(hProps);
el.find( "*[width]" ).each( function(){
var child = $( this ),
@@ -254,7 +264,7 @@ $.effects.effect.size = function( o, done ) {
if( mode === "hide" ) {
el.hide();
}
- $.effects.restore( el, restore ? props : props1 );
+ $.effects.restore( el, props );
if ( !restore ) {
// we need to calculate our new positioning based on the scaling
diff --git a/ui/jquery.ui.effect.js b/ui/jquery.ui.effect.js
index d5d306783..fee3359bf 100644
--- a/ui/jquery.ui.effect.js
+++ b/ui/jquery.ui.effect.js
@@ -10,9 +10,7 @@
*/
;(jQuery.effects || (function($, undefined) {
-var backCompat = $.uiBackCompat !== false,
- // prefix used for storing data on .data()
- dataSpace = "ui-effects-";
+var dataSpace = "ui-effects-";
$.effects = {
effect: {}
@@ -245,8 +243,7 @@ color.fn = jQuery.extend( color.prototype, {
var inst = this,
type = jQuery.type( red ),
- rgba = this._rgba = [],
- source;
+ rgba = this._rgba = [];
// more than 1 argument specified - assume ( red, green, blue, alpha )
if ( green !== undefined ) {
@@ -427,7 +424,7 @@ color.fn = jQuery.extend( color.prototype, {
rgba.push( ~~( alpha * 255 ) );
}
- return "#" + jQuery.map( rgba, function( v, i ) {
+ return "#" + jQuery.map( rgba, function( v ) {
// default to 0 when nulls exist
v = ( v || 0 ).toString( 16 );
@@ -501,8 +498,7 @@ spaces.hsla.from = function ( hsla ) {
l = hsla[ 2 ],
a = hsla[ 3 ],
q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
- p = 2 * l - q,
- r, g, b;
+ p = 2 * l - q;
return [
Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
@@ -619,7 +615,7 @@ each( stepHooks, function( i, hook ) {
}
try {
elem.style[ hook ] = value;
- } catch( value ) {
+ } catch( error ) {
// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
}
}
@@ -704,33 +700,31 @@ $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopS
};
});
-function getElementStyles() {
- var style = this.ownerDocument.defaultView ?
- this.ownerDocument.defaultView.getComputedStyle( this, null ) :
- this.currentStyle,
- newStyle = {},
- key,
- camelCase,
- len;
+function getElementStyles( elem ) {
+ var key, len,
+ style = elem.ownerDocument.defaultView ?
+ elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
+ elem.currentStyle,
+ styles = {};
- // webkit enumerates style porperties
if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
len = style.length;
while ( len-- ) {
key = style[ len ];
if ( typeof style[ key ] === "string" ) {
- newStyle[ $.camelCase( key ) ] = style[ key ];
+ styles[ $.camelCase( key ) ] = style[ key ];
}
}
+ // support: Opera, IE <9
} else {
for ( key in style ) {
if ( typeof style[ key ] === "string" ) {
- newStyle[ key ] = style[ key ];
+ styles[ key ] = style[ key ];
}
}
}
- return newStyle;
+ return styles;
}
@@ -766,7 +760,7 @@ $.effects.animateClass = function( value, duration, easing, callback ) {
var el = $( this );
return {
el: el,
- start: getElementStyles.call( this )
+ start: getElementStyles( this )
};
});
@@ -782,7 +776,7 @@ $.effects.animateClass = function( value, duration, easing, callback ) {
// map all animated objects again - calculate new styles and diff
allAnimations = allAnimations.map(function() {
- this.end = getElementStyles.call( this.el[ 0 ] );
+ this.end = getElementStyles( this.el[ 0 ] );
this.diff = styleDifference( this.start, this.end );
return this;
});
@@ -1045,7 +1039,7 @@ $.extend( $.effects, {
// return an effect options object for the given parameters:
function _normalizeArguments( effect, options, speed, callback ) {
- // allow passing all optinos as the first parameter
+ // allow passing all options as the first parameter
if ( $.isPlainObject( effect ) ) {
options = effect;
effect = effect.effect;
@@ -1054,8 +1048,8 @@ function _normalizeArguments( effect, options, speed, callback ) {
// convert to an object
effect = { effect: effect };
- // catch (effect)
- if ( options === undefined ) {
+ // catch (effect, null, ...)
+ if ( options == null ) {
options = {};
}
@@ -1102,28 +1096,17 @@ function standardSpeed( speed ) {
}
// invalid strings - treat as "normal" speed
- if ( typeof speed === "string" && !$.effects.effect[ speed ] ) {
- // TODO: remove in 2.0 (#7115)
- if ( backCompat && $.effects[ speed ] ) {
- return false;
- }
- return true;
- }
-
- return false;
+ return typeof speed === "string" && !$.effects.effect[ speed ];
}
$.fn.extend({
- effect: function( effect, options, speed, callback ) {
+ effect: function( /* effect, options, speed, callback */ ) {
var args = _normalizeArguments.apply( this, arguments ),
mode = args.mode,
queue = args.queue,
- effectMethod = $.effects.effect[ args.effect ],
+ effectMethod = $.effects.effect[ args.effect ];
- // DEPRECATED: remove in 2.0 (#7115)
- oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ];
-
- if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) {
+ if ( $.fx.off || !effectMethod ) {
// delegate to the original method (e.g., .show()) if possible
if ( mode ) {
return this[ mode ]( args.duration, args.complete );
@@ -1159,18 +1142,7 @@ $.fn.extend({
}
}
- // TODO: remove this check in 2.0, effectMethod will always be true
- if ( effectMethod ) {
- return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
- } else {
- // DEPRECATED: remove in 2.0 (#7115)
- return oldEffectMethod.call(this, {
- options: args,
- duration: args.duration,
- callback: args.complete,
- mode: args.mode
- });
- }
+ return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
},
_show: $.fn.show,
diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js
index 5d401da53..45c1ec2e4 100644
--- a/ui/jquery.ui.menu.js
+++ b/ui/jquery.ui.menu.js
@@ -277,21 +277,35 @@ $.widget( "ui.menu", {
},
refresh: function() {
- // Initialize nested menus
var menus,
icon = this.options.icons.submenu,
- submenus = this.element.find( this.options.menus + ":not(.ui-menu)" )
- .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
- .hide()
- .attr({
- role: this.options.role,
- "aria-hidden": "true",
- "aria-expanded": "false"
- });
+ submenus = this.element.find( this.options.menus );
+
+ // Initialize nested menus
+ submenus.filter( ":not(.ui-menu)" )
+ .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
+ .hide()
+ .attr({
+ role: this.options.role,
+ "aria-hidden": "true",
+ "aria-expanded": "false"
+ })
+ .each(function() {
+ var menu = $( this ),
+ item = menu.prev( "a" ),
+ submenuCarat = $( "<span>" )
+ .addClass( "ui-menu-icon ui-icon " + icon )
+ .data( "ui-menu-submenu-carat", true );
+
+ item
+ .attr( "aria-haspopup", "true" )
+ .prepend( submenuCarat );
+ menu.attr( "aria-labelledby", item.attr( "id" ) );
+ });
- // Don't refresh list items that are already adapted
menus = submenus.add( this.element );
+ // Don't refresh list items that are already adapted
menus.children( ":not(.ui-menu-item):has(a)" )
.addClass( "ui-menu-item" )
.attr( "role", "presentation" )
@@ -315,19 +329,6 @@ $.widget( "ui.menu", {
// Add aria-disabled attribute to any disabled menu item
menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
- submenus.each(function() {
- var menu = $( this ),
- item = menu.prev( "a" ),
- submenuCarat = $( "<span>" )
- .addClass( "ui-menu-icon ui-icon " + icon )
- .data( "ui-menu-submenu-carat", true );
-
- item
- .attr( "aria-haspopup", "true" )
- .prepend( submenuCarat );
- menu.attr( "aria-labelledby", item.attr( "id" ) );
- });
-
// If the active item has been removed, blur the menu
if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
this.blur();
diff --git a/ui/jquery.ui.mouse.js b/ui/jquery.ui.mouse.js
index f5069d00c..6abd5ceaf 100644
--- a/ui/jquery.ui.mouse.js
+++ b/ui/jquery.ui.mouse.js
@@ -14,7 +14,7 @@
(function( $, undefined ) {
var mouseHandled = false;
-$( document ).mouseup( function( e ) {
+$( document ).mouseup( function() {
mouseHandled = false;
});
@@ -104,14 +104,14 @@ $.widget("ui.mouse", {
.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
event.preventDefault();
-
+
mouseHandled = true;
return true;
},
_mouseMove: function(event) {
// IE mouseup check - mouseup happened when mouse was out of window
- if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
+ if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
return this._mouseUp(event);
}
@@ -155,15 +155,15 @@ $.widget("ui.mouse", {
);
},
- _mouseDelayMet: function(event) {
+ _mouseDelayMet: function(/* event */) {
return this.mouseDelayMet;
},
// These are placeholder methods, to be overriden by extending plugin
- _mouseStart: function(event) {},
- _mouseDrag: function(event) {},
- _mouseStop: function(event) {},
- _mouseCapture: function(event) { return true; }
+ _mouseStart: function(/* event */) {},
+ _mouseDrag: function(/* event */) {},
+ _mouseStop: function(/* event */) {},
+ _mouseCapture: function(/* event */) { return true; }
});
})(jQuery);
diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js
index 5b595a8c0..a5dc31834 100644
--- a/ui/jquery.ui.position.js
+++ b/ui/jquery.ui.position.js
@@ -230,10 +230,6 @@ $.fn.position = function( options ) {
}
});
- if ( $.fn.bgiframe ) {
- elem.bgiframe();
- }
-
if ( options.using ) {
// adds feedback as second argument to using callback, if present
using = function( props ) {
@@ -478,40 +474,4 @@ $.ui.position = {
testElementParent.removeChild( testElement );
})();
-// DEPRECATED
-if ( $.uiBackCompat !== false ) {
- // offset option
- (function( $ ) {
- var _position = $.fn.position;
- $.fn.position = function( options ) {
- if ( !options || !options.offset ) {
- return _position.call( this, options );
- }
- var offset = options.offset.split( " " ),
- at = options.at.split( " " );
- if ( offset.length === 1 ) {
- offset[ 1 ] = offset[ 0 ];
- }
- if ( /^\d/.test( offset[ 0 ] ) ) {
- offset[ 0 ] = "+" + offset[ 0 ];
- }
- if ( /^\d/.test( offset[ 1 ] ) ) {
- offset[ 1 ] = "+" + offset[ 1 ];
- }
- if ( at.length === 1 ) {
- if ( /left|center|right/.test( at[ 0 ] ) ) {
- at[ 1 ] = "center";
- } else {
- at[ 1 ] = at[ 0 ];
- at[ 0 ] = "center";
- }
- }
- return _position.call( this, $.extend( options, {
- at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
- offset: undefined
- } ) );
- };
- }( jQuery ) );
-}
-
}( jQuery ) );
diff --git a/ui/jquery.ui.progressbar.js b/ui/jquery.ui.progressbar.js
index cb561ebc6..5a7fd87d3 100644
--- a/ui/jquery.ui.progressbar.js
+++ b/ui/jquery.ui.progressbar.js
@@ -24,19 +24,22 @@ $.widget( "ui.progressbar", {
min: 0,
_create: function() {
+ // Constrain initial value
+ this.options.value = this._constrainedValue();
+
this.element
.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
.attr({
role: "progressbar",
"aria-valuemin": this.min,
"aria-valuemax": this.options.max,
- "aria-valuenow": this._value()
+ "aria-valuenow": this.options.value
});
this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
.appendTo( this.element );
- this.oldValue = this._value();
+ this.oldValue = this.options.value;
this._refreshValue();
},
@@ -53,52 +56,82 @@ $.widget( "ui.progressbar", {
value: function( newValue ) {
if ( newValue === undefined ) {
- return this._value();
+ return this.options.value;
}
- this._setOption( "value", newValue );
+ this._setOption( "value", this._constrainedValue( newValue ) );
return this;
},
- _setOption: function( key, value ) {
- if ( key === "value" ) {
- this.options.value = value;
- this._refreshValue();
- if ( this._value() === this.options.max ) {
- this._trigger( "complete" );
- }
+ _constrainedValue: function( newValue ) {
+ var val;
+ if ( newValue === undefined ) {
+ val = this.options.value;
+ } else {
+ val = newValue;
}
- this._super( key, value );
- },
-
- _value: function() {
- var val = this.options.value;
- // normalize invalid value
+ // sanitize value
if ( typeof val !== "number" ) {
val = 0;
}
return Math.min( this.options.max, Math.max( this.min, val ) );
},
+ _setOptions: function( options ) {
+ var key, val;
+
+ for ( key in options ) {
+ if ( key === "value" ) {
+ // Store value to update last in case max is being updated at the same time
+ val = options[ key ];
+ } else {
+ this._setOption( key, options[ key ] );
+ }
+ }
+
+ if ( val !== undefined ) {
+ this._setOption( "value", val );
+ }
+ },
+
+ _setOption: function( key, value ) {
+ if ( key === "max" ) {
+ // Don't allow a max less than min
+ this.options.max = Math.max( this.min, value );
+ this.options.value = this._constrainedValue();
+ }
+ if ( key === "value" ) {
+ this.options.value = this._constrainedValue( value );
+ }
+ else {
+ this._super( key, value );
+ }
+
+ this._refreshValue();
+ },
+
_percentage: function() {
- return 100 * this._value() / this.options.max;
+ return 100 * this.options.value / this.options.max;
},
_refreshValue: function() {
- var value = this.value(),
- percentage = this._percentage();
+ var percentage = this._percentage();
- if ( this.oldValue !== value ) {
- this.oldValue = value;
+ if ( this.oldValue !== this.options.value ) {
+ this.oldValue = this.options.value;
this._trigger( "change" );
}
+ if ( this.options.value === this.options.max ) {
+ this._trigger( "complete" );
+ }
this.valueDiv
- .toggle( value > this.min )
- .toggleClass( "ui-corner-right", value === this.options.max )
+ .toggle( this.options.value > this.min )
+ .toggleClass( "ui-corner-right", this.options.value === this.options.max )
.width( percentage.toFixed(0) + "%" );
- this.element.attr( "aria-valuenow", value );
+ this.element.attr( "aria-valuemax", this.options.max );
+ this.element.attr( "aria-valuenow", this.options.value );
}
});
diff --git a/ui/jquery.ui.resizable.js b/ui/jquery.ui.resizable.js
index cc82b8b92..fba9216e1 100644
--- a/ui/jquery.ui.resizable.js
+++ b/ui/jquery.ui.resizable.js
@@ -15,6 +15,16 @@
*/
(function( $, undefined ) {
+/*jshint onevar: false, curly: false, eqeqeq: false, funcscope: true, loopfunc: true */
+
+function num(v) {
+ return parseInt(v, 10) || 0;
+}
+
+function isNumber(value) {
+ return !isNaN(parseInt(value, 10));
+}
+
$.widget("ui.resizable", $.ui.mouse, {
version: "@VERSION",
widgetEventPrefix: "resize",
@@ -65,7 +75,7 @@ $.widget("ui.resizable", $.ui.mouse, {
//Overwrite the original this.element
this.element = this.element.parent().data(
- "resizable", this.element.data('resizable')
+ "ui-resizable", this.element.data('ui-resizable')
);
this.elementIsWrapper = true;
@@ -106,7 +116,7 @@ $.widget("ui.resizable", $.ui.mouse, {
//TODO : What's going on here?
if ('se' == handle) {
axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
- };
+ }
//Insert into internal handles object and append to element
this.handles[handle] = '.ui-resizable-'+handle;
@@ -204,15 +214,14 @@ $.widget("ui.resizable", $.ui.mouse, {
if (this.elementIsWrapper) {
_destroy(this.element);
var wrapper = this.element;
- wrapper.after(
- this.originalElement.css({
- position: wrapper.css('position'),
- width: wrapper.outerWidth(),
- height: wrapper.outerHeight(),
- top: wrapper.css('top'),
- left: wrapper.css('left')
- })
- ).remove();
+ this.originalElement.css({
+ position: wrapper.css('position'),
+ width: wrapper.outerWidth(),
+ height: wrapper.outerHeight(),
+ top: wrapper.css('top'),
+ left: wrapper.css('left')
+ }).insertAfter( wrapper );
+ wrapper.remove();
}
this.originalElement.css('resize', this.originalResizeStyle);
@@ -222,14 +231,15 @@ $.widget("ui.resizable", $.ui.mouse, {
},
_mouseCapture: function(event) {
- var handle = false;
+ var capture = false;
for (var i in this.handles) {
- if ($(this.handles[i])[0] == event.target) {
- handle = true;
+ var handle = $(this.handles[i])[0];
+ if (handle == event.target || $.contains(handle, event.target)) {
+ capture = true;
}
}
- return !this.options.disabled && handle;
+ return !this.options.disabled && capture;
},
_mouseStart: function(event) {
@@ -276,8 +286,8 @@ $.widget("ui.resizable", $.ui.mouse, {
_mouseDrag: function(event) {
//Increase performance, avoid regex
- var el = this.helper, o = this.options, props = {},
- that = this, smp = this.originalMousePosition, a = this.axis;
+ var el = this.helper,
+ smp = this.originalMousePosition, a = this.axis;
var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
var trigger = this._change[a];
@@ -373,7 +383,6 @@ $.widget("ui.resizable", $.ui.mouse, {
},
_updateCache: function(data) {
- var o = this.options;
this.offset = this.helper.offset();
if (isNumber(data.left)) this.position.left = data.left;
if (isNumber(data.top)) this.position.top = data.top;
@@ -381,9 +390,9 @@ $.widget("ui.resizable", $.ui.mouse, {
if (isNumber(data.width)) this.size.width = data.width;
},
- _updateRatio: function(data, event) {
+ _updateRatio: function( data ) {
- var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
+ var cpos = this.position, csize = this.size, a = this.axis;
if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
@@ -400,11 +409,11 @@ $.widget("ui.resizable", $.ui.mouse, {
return data;
},
- _respectSize: function(data, event) {
+ _respectSize: function( data ) {
- var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
- ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
- isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
+ 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);
if (isminw) data.width = o.minWidth;
if (isminh) data.height = o.minHeight;
@@ -429,7 +438,6 @@ $.widget("ui.resizable", $.ui.mouse, {
_proportionallyResize: function() {
- var o = this.options;
if (!this._proportionallyResizeElements.length) return;
var element = this.helper || this.element;
@@ -452,7 +460,7 @@ $.widget("ui.resizable", $.ui.mouse, {
width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
});
- };
+ }
},
@@ -465,16 +473,12 @@ $.widget("ui.resizable", $.ui.mouse, {
this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
- // fix ie6 offset TODO: This seems broken
- var ie6offset = ($.ui.ie6 ? 1 : 0),
- pxyoffset = ( $.ui.ie6 ? 2 : -1 );
-
this.helper.addClass(this._helper).css({
- width: this.element.outerWidth() + pxyoffset,
- height: this.element.outerHeight() + pxyoffset,
+ width: this.element.outerWidth() - 1,
+ height: this.element.outerHeight() - 1,
position: 'absolute',
- left: this.elementOffset.left - ie6offset +'px',
- top: this.elementOffset.top - ie6offset +'px',
+ left: this.elementOffset.left +'px',
+ top: this.elementOffset.top +'px',
zIndex: ++o.zIndex //TODO: Don't modify option
});
@@ -489,15 +493,15 @@ $.widget("ui.resizable", $.ui.mouse, {
},
_change: {
- e: function(event, dx, dy) {
+ e: function(event, dx) {
return { width: this.originalSize.width + dx };
},
- w: function(event, dx, dy) {
- var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+ w: function(event, dx) {
+ var cs = this.originalSize, sp = this.originalPosition;
return { left: sp.left + dx, width: cs.width - dx };
},
n: function(event, dx, dy) {
- var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+ var cs = this.originalSize, sp = this.originalPosition;
return { top: sp.top + dy, height: cs.height - dy };
},
s: function(event, dx, dy) {
@@ -544,13 +548,13 @@ $.widget("ui.resizable", $.ui.mouse, {
$.ui.plugin.add("resizable", "alsoResize", {
- start: function (event, ui) {
- var that = $(this).data("resizable"), o = that.options;
+ start: function () {
+ var that = $(this).data("ui-resizable"), o = that.options;
var _store = function (exp) {
$(exp).each(function() {
var el = $(this);
- el.data("resizable-alsoresize", {
+ el.data("ui-resizable-alsoresize", {
width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
});
@@ -566,7 +570,7 @@ $.ui.plugin.add("resizable", "alsoResize", {
},
resize: function (event, ui) {
- var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition;
+ var that = $(this).data("ui-resizable"), o = that.options, os = that.originalSize, op = that.originalPosition;
var delta = {
height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
@@ -575,7 +579,7 @@ $.ui.plugin.add("resizable", "alsoResize", {
_alsoResize = function (exp, c) {
$(exp).each(function() {
- var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
+ var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
$.each(css, function (i, prop) {
@@ -595,15 +599,15 @@ $.ui.plugin.add("resizable", "alsoResize", {
}
},
- stop: function (event, ui) {
+ stop: function () {
$(this).removeData("resizable-alsoresize");
}
});
$.ui.plugin.add("resizable", "animate", {
- stop: function(event, ui) {
- var that = $(this).data("resizable"), o = that.options;
+ stop: function( event ) {
+ var that = $(this).data("ui-resizable"), o = that.options;
var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
@@ -641,8 +645,8 @@ $.ui.plugin.add("resizable", "animate", {
$.ui.plugin.add("resizable", "containment", {
- start: function(event, ui) {
- var that = $(this).data("resizable"), o = that.options, el = that.element;
+ start: function() {
+ var that = $(this).data("ui-resizable"), o = that.options, el = that.element;
var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
if (!ce) return;
@@ -676,10 +680,10 @@ $.ui.plugin.add("resizable", "containment", {
}
},
- resize: function(event, ui) {
- var that = $(this).data("resizable"), o = that.options,
- ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position,
- pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement;
+ resize: function( event ) {
+ var that = $(this).data("ui-resizable"), o = that.options,
+ co = that.containerOffset, cp = that.position,
+ pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement;
if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
@@ -717,8 +721,8 @@ $.ui.plugin.add("resizable", "containment", {
}
},
- stop: function(event, ui){
- var that = $(this).data("resizable"), o = that.options, cp = that.position,
+ stop: function(){
+ var that = $(this).data("ui-resizable"), o = that.options,
co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement;
var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height;
@@ -734,13 +738,13 @@ $.ui.plugin.add("resizable", "containment", {
$.ui.plugin.add("resizable", "ghost", {
- start: function(event, ui) {
+ start: function() {
- var that = $(this).data("resizable"), o = that.options, cs = that.size;
+ var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
that.ghost = that.originalElement.clone();
that.ghost
- .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
+ .css({ opacity: 0.25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
.addClass('ui-resizable-ghost')
.addClass(typeof o.ghost == 'string' ? o.ghost : '');
@@ -748,13 +752,13 @@ $.ui.plugin.add("resizable", "ghost", {
},
- resize: function(event, ui){
- var that = $(this).data("resizable"), o = that.options;
+ resize: function(){
+ var that = $(this).data("ui-resizable");
if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width });
},
- stop: function(event, ui){
- var that = $(this).data("resizable"), o = that.options;
+ stop: function() {
+ var that = $(this).data("ui-resizable");
if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0));
}
@@ -762,28 +766,42 @@ $.ui.plugin.add("resizable", "ghost", {
$.ui.plugin.add("resizable", "grid", {
- resize: function(event, ui) {
- var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey;
+ resize: function() {
+ var that = $(this).data("ui-resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis;
o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
- var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
+ var gridX = (o.grid[0]||1), gridY = (o.grid[1]||1),
+ ox = Math.round((cs.width - os.width) / gridX) * gridX, oy = Math.round((cs.height - os.height) / gridY) * gridY,
+ newWidth = os.width + ox, newHeight = os.height + oy,
+ isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
+ isMinWidth = o.minWidth && (o.minWidth > newWidth), isMinHeight = o.minHeight && (o.minHeight > newHeight);
+
+ if (isMinWidth) {
+ newWidth = newWidth + gridX;
+ }
+ if (isMinHeight) {
+ newHeight = newHeight + gridY;
+ }
+ if (isMaxWidth) {
+ newWidth = newWidth - gridX;
+ }
+ if (isMaxHeight) {
+ newHeight = newHeight - gridY;
+ }
if (/^(se|s|e)$/.test(a)) {
- that.size.width = os.width + ox;
- that.size.height = os.height + oy;
- }
- else if (/^(ne)$/.test(a)) {
- that.size.width = os.width + ox;
- that.size.height = os.height + oy;
+ that.size.width = newWidth;
+ that.size.height = newHeight;
+ } else if (/^(ne)$/.test(a)) {
+ that.size.width = newWidth;
+ that.size.height = newHeight;
that.position.top = op.top - oy;
- }
- else if (/^(sw)$/.test(a)) {
- that.size.width = os.width + ox;
- that.size.height = os.height + oy;
+ } else if (/^(sw)$/.test(a)) {
+ that.size.width = newWidth;
+ that.size.height = newHeight;
that.position.left = op.left - ox;
- }
- else {
- that.size.width = os.width + ox;
- that.size.height = os.height + oy;
+ } else {
+ that.size.width = newWidth;
+ that.size.height = newHeight;
that.position.top = op.top - oy;
that.position.left = op.left - ox;
}
@@ -791,12 +809,4 @@ $.ui.plugin.add("resizable", "grid", {
});
-var num = function(v) {
- return parseInt(v, 10) || 0;
-};
-
-var isNumber = function(value) {
- return !isNaN(parseInt(value, 10));
-};
-
})(jQuery);
diff --git a/ui/jquery.ui.selectable.js b/ui/jquery.ui.selectable.js
index 80e32ca7a..a9b15b20b 100644
--- a/ui/jquery.ui.selectable.js
+++ b/ui/jquery.ui.selectable.js
@@ -25,20 +25,20 @@ $.widget("ui.selectable", $.ui.mouse, {
tolerance: 'touch'
},
_create: function() {
- var that = this;
+ var selectees,
+ that = this;
this.element.addClass("ui-selectable");
this.dragged = false;
// cache selectee children based on filter
- var selectees;
this.refresh = function() {
selectees = $(that.options.filter, that.element[0]);
selectees.addClass("ui-selectee");
selectees.each(function() {
- var $this = $(this);
- var pos = $this.offset();
+ var $this = $(this),
+ pos = $this.offset();
$.data(this, "selectable-item", {
element: this,
$element: $this,
@@ -72,14 +72,14 @@ $.widget("ui.selectable", $.ui.mouse, {
},
_mouseStart: function(event) {
- var that = this;
+ var that = this,
+ options = this.options;
this.opos = [event.pageX, event.pageY];
- if (this.options.disabled)
+ if (this.options.disabled) {
return;
-
- var options = this.options;
+ }
this.selectees = $(options.filter, this.element[0]);
@@ -114,9 +114,10 @@ $.widget("ui.selectable", $.ui.mouse, {
});
$(event.target).parents().andSelf().each(function() {
- var selectee = $.data(this, "selectable-item");
+ var doSelect,
+ selectee = $.data(this, "selectable-item");
if (selectee) {
- var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
+ doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
selectee.$element
.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
@@ -140,28 +141,37 @@ $.widget("ui.selectable", $.ui.mouse, {
},
_mouseDrag: function(event) {
- var that = this;
+
this.dragged = true;
- if (this.options.disabled)
+ if (this.options.disabled) {
return;
+ }
- var options = this.options;
+ var tmp,
+ that = this,
+ options = this.options,
+ x1 = this.opos[0],
+ y1 = this.opos[1],
+ x2 = event.pageX,
+ y2 = event.pageY;
- var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
- if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
- if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
+ if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
+ if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
this.selectees.each(function() {
- var selectee = $.data(this, "selectable-item");
+ var selectee = $.data(this, "selectable-item"),
+ hit = false;
+
//prevent helper from being selected if appendTo: selectable
- if (!selectee || selectee.element == that.element[0])
+ if (!selectee || selectee.element === that.element[0]) {
return;
- var hit = false;
- if (options.tolerance == 'touch') {
+ }
+
+ if (options.tolerance === 'touch') {
hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
- } else if (options.tolerance == 'fit') {
+ } else if (options.tolerance === 'fit') {
hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
}
@@ -228,8 +238,6 @@ $.widget("ui.selectable", $.ui.mouse, {
this.dragged = false;
- var options = this.options;
-
$('.ui-unselecting', this.element[0]).each(function() {
var selectee = $.data(this, "selectable-item");
selectee.$element.removeClass('ui-unselecting');
diff --git a/ui/jquery.ui.slider.js b/ui/jquery.ui.slider.js
index f24982878..18f7113d4 100644
--- a/ui/jquery.ui.slider.js
+++ b/ui/jquery.ui.slider.js
@@ -36,11 +36,10 @@ $.widget( "ui.slider", $.ui.mouse, {
},
_create: function() {
- var i,
+ var i, handleCount,
o = this.options,
existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
- handleCount = ( o.values && o.values.length ) || 1,
handles = [];
this._keySliding = false;
@@ -79,6 +78,8 @@ $.widget( "ui.slider", $.ui.mouse, {
( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
}
+ handleCount = ( o.values && o.values.length ) || 1;
+
for ( i = existingHandles.length; i < handleCount; i++ ) {
handles.push( handle );
}
@@ -277,7 +278,7 @@ $.widget( "ui.slider", $.ui.mouse, {
return true;
},
- _mouseStart: function( event ) {
+ _mouseStart: function() {
return true;
},
@@ -509,6 +510,12 @@ $.widget( "ui.slider", $.ui.mouse, {
}
this._animateOff = false;
break;
+ case "min":
+ case "max":
+ this._animateOff = true;
+ this._refreshValue();
+ this._animateOff = false;
+ break;
}
},
@@ -584,7 +591,7 @@ $.widget( "ui.slider", $.ui.mouse, {
_set = {};
if ( this.options.values && this.options.values.length ) {
- this.handles.each(function( i, j ) {
+ this.handles.each(function( i ) {
valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
diff --git a/ui/jquery.ui.sortable.js b/ui/jquery.ui.sortable.js
index a2132a9bd..a98e46632 100644
--- a/ui/jquery.ui.sortable.js
+++ b/ui/jquery.ui.sortable.js
@@ -15,6 +15,7 @@
*/
(function( $, undefined ) {
+/*jshint onevar: false, curly: false, eqeqeq: false, laxbreak: true, shadow: true, loopfunc: true */
$.widget("ui.sortable", $.ui.mouse, {
version: "@VERSION",
widgetEventPrefix: "sort",
@@ -62,7 +63,7 @@ $.widget("ui.sortable", $.ui.mouse, {
this._mouseInit();
//We're ready to go
- this.ready = true
+ this.ready = true;
},
@@ -101,7 +102,9 @@ $.widget("ui.sortable", $.ui.mouse, {
this._refreshItems(event);
//Find out if the clicked node (or one of its parents) is a actual item in this.items
- var currentItem = null, nodes = $(event.target).parents().each(function() {
+ var currentItem = null;
+
+ $(event.target).parents().each(function() {
if($.data(this, that.widgetName + '-item') == that) {
currentItem = $(this);
return false;
@@ -221,7 +224,7 @@ $.widget("ui.sortable", $.ui.mouse, {
//Post 'activate' events to possible containers
if(!noActivation) {
- for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
+ for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
}
//Prepare possible droppables
@@ -418,7 +421,7 @@ $.widget("ui.sortable", $.ui.mouse, {
var str = []; o = o || {};
$(items).each(function() {
- var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
+ var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[\-=_](.+)/));
if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
});
@@ -458,7 +461,7 @@ $.widget("ui.sortable", $.ui.mouse, {
var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
- if( this.options.tolerance == "pointer"
+ if (this.options.tolerance == "pointer"
|| this.options.forcePointerForContainers
|| (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
) {
@@ -507,12 +510,12 @@ $.widget("ui.sortable", $.ui.mouse, {
_getDragVerticalDirection: function() {
var delta = this.positionAbs.top - this.lastPositionAbs.top;
- return delta != 0 && (delta > 0 ? "down" : "up");
+ return delta !== 0 && (delta > 0 ? "down" : "up");
},
_getDragHorizontalDirection: function() {
var delta = this.positionAbs.left - this.lastPositionAbs.left;
- return delta != 0 && (delta > 0 ? "right" : "left");
+ return delta !== 0 && (delta > 0 ? "right" : "left");
},
refresh: function(event) {
@@ -538,12 +541,12 @@ $.widget("ui.sortable", $.ui.mouse, {
for (var i = connectWith.length - 1; i >= 0; i--){
var cur = $(connectWith[i]);
for (var j = cur.length - 1; j >= 0; j--){
- var inst = $.data(cur[j], this.widgetName);
+ var inst = $.data(cur[j], this.widgetFullName);
if(inst && inst != this && !inst.options.disabled) {
queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
}
- };
- };
+ }
+ }
}
queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
@@ -552,7 +555,7 @@ $.widget("ui.sortable", $.ui.mouse, {
queries[i][0].each(function() {
items.push(this);
});
- };
+ }
return $(items);
@@ -566,7 +569,7 @@ $.widget("ui.sortable", $.ui.mouse, {
for (var j=0; j < list.length; j++) {
if(list[j] == item.item[0])
return false;
- };
+ }
return true;
});
@@ -584,13 +587,13 @@ $.widget("ui.sortable", $.ui.mouse, {
for (var i = connectWith.length - 1; i >= 0; i--){
var cur = $(connectWith[i]);
for (var j = cur.length - 1; j >= 0; j--){
- var inst = $.data(cur[j], this.widgetName);
+ var inst = $.data(cur[j], this.widgetFullName);
if(inst && inst != this && !inst.options.disabled) {
queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
this.containers.push(inst);
}
- };
- };
+ }
+ }
}
for (var i = queries.length - 1; i >= 0; i--) {
@@ -608,8 +611,8 @@ $.widget("ui.sortable", $.ui.mouse, {
width: 0, height: 0,
left: 0, top: 0
});
- };
- };
+ }
+ }
},
@@ -637,7 +640,7 @@ $.widget("ui.sortable", $.ui.mouse, {
var p = t.offset();
item.left = p.left;
item.top = p.top;
- };
+ }
if(this.options.custom && this.options.custom.refreshContainers) {
this.options.custom.refreshContainers.call(this);
@@ -648,7 +651,7 @@ $.widget("ui.sortable", $.ui.mouse, {
this.containers[i].containerCache.top = p.top;
this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
- };
+ }
}
return this;
@@ -679,8 +682,8 @@ $.widget("ui.sortable", $.ui.mouse, {
if(className && !o.forcePlaceholderSize) return;
//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
- if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); };
- if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); };
+ if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); }
+ if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); }
}
};
}
@@ -786,8 +789,8 @@ $.widget("ui.sortable", $.ui.mouse, {
if(helper[0] == this.currentItem[0])
this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
- if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
- if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
+ if(!helper[0].style.width || o.forceHelperSize) helper.width(this.currentItem.width());
+ if(!helper[0].style.height || o.forceHelperSize) helper.height(this.currentItem.height());
return helper;
@@ -899,7 +902,7 @@ $.widget("ui.sortable", $.ui.mouse, {
if(!pos) pos = this.position;
var mod = d == "absolute" ? 1 : -1;
- var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+ var scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
return {
top: (
@@ -949,10 +952,10 @@ $.widget("ui.sortable", $.ui.mouse, {
if(o.grid) {
var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
- pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+ pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
- pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+ pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
}
}
@@ -1047,7 +1050,9 @@ $.widget("ui.sortable", $.ui.mouse, {
if(this.cancelHelperRemoval) {
if(!noPropagation) {
this._trigger("beforeStop", event, this._uiHash());
- for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
+ for (var i=0; i < delayedTriggers.length; i++) {
+ delayedTriggers[i].call(this, event);
+ } //Trigger all delayed events
this._trigger("stop", event, this._uiHash());
}
@@ -1063,7 +1068,9 @@ $.widget("ui.sortable", $.ui.mouse, {
if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
if(!noPropagation) {
- for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
+ for (var i=0; i < delayedTriggers.length; i++) {
+ delayedTriggers[i].call(this, event);
+ } //Trigger all delayed events
this._trigger("stop", event, this._uiHash());
}
diff --git a/ui/jquery.ui.spinner.js b/ui/jquery.ui.spinner.js
index 23cce18ef..406eefb91 100644
--- a/ui/jquery.ui.spinner.js
+++ b/ui/jquery.ui.spinner.js
@@ -94,7 +94,6 @@ $.widget( "ui.spinner", {
},
keyup: "_stop",
focus: function() {
- this.uiSpinner.addClass( "ui-state-active" );
this.previous = this.element.val();
},
blur: function( event ) {
@@ -104,7 +103,6 @@ $.widget( "ui.spinner", {
}
this._refresh();
- this.uiSpinner.removeClass( "ui-state-active" );
if ( this.previous !== this.element.val() ) {
this._trigger( "change", event );
}
@@ -196,7 +194,6 @@ $.widget( "ui.spinner", {
.parent()
// add buttons
.append( this._buttonHtml() );
- this._hoverable( uiSpinner );
this.element.attr( "role", "spinbutton" );
@@ -242,7 +239,7 @@ $.widget( "ui.spinner", {
},
_uiSpinnerHtml: function() {
- return "<span class='ui-spinner ui-state-default ui-widget ui-widget-content ui-corner-all'></span>";
+ return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
},
_buttonHtml: function() {
diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js
index 7d38fb46e..5b5227128 100644
--- a/ui/jquery.ui.tabs.js
+++ b/ui/jquery.ui.tabs.js
@@ -22,11 +22,13 @@ function getNextTabId() {
}
function isLocal( anchor ) {
- // clone the node to work around IE 6 not normalizing the href property
- // if it's manually set, i.e., a.href = "#foo" kills the normalization
- anchor = anchor.cloneNode( false );
return anchor.hash.length > 1 &&
- anchor.href.replace( rhash, "" ) === location.href.replace( rhash, "" );
+ anchor.href.replace( rhash, "" ) ===
+ location.href.replace( rhash, "" )
+ // support: Safari 5.1
+ // Safari 5.1 doesn't encode spaces in window.location
+ // but it does encode spaces from anchors (#8777)
+ .replace( /\s/g, "%20" );
}
$.widget( "ui.tabs", {
@@ -48,8 +50,7 @@ $.widget( "ui.tabs", {
},
_create: function() {
- var panel,
- that = this,
+ var that = this,
options = this.options,
active = options.active,
locationHash = location.hash.substring( 1 );
@@ -298,8 +299,7 @@ $.widget( "ui.tabs", {
},
refresh: function() {
- var next,
- options = this.options,
+ var options = this.options,
lis = this.tablist.children( ":has(a[href])" );
// get disabled tabs from class attribute from HTML
@@ -492,18 +492,10 @@ $.widget( "ui.tabs", {
},
_setupHeightStyle: function( heightStyle ) {
- var maxHeight, overflow,
+ var maxHeight,
parent = this.element.parent();
if ( heightStyle === "fill" ) {
- // IE 6 treats height like minHeight, so we need to turn off overflow
- // in order to get a reliable height
- // we use the minHeight support test because we assume that only
- // browsers that don't support minHeight will treat height as minHeight
- if ( !$.support.minHeight ) {
- overflow = parent.css( "overflow" );
- parent.css( "overflow", "hidden");
- }
maxHeight = parent.height();
this.element.siblings( ":visible" ).each(function() {
var elem = $( this ),
@@ -514,9 +506,6 @@ $.widget( "ui.tabs", {
}
maxHeight -= elem.outerHeight( true );
});
- if ( overflow ) {
- parent.css( "overflow", overflow );
- }
this.element.children().not( this.panels ).each(function() {
maxHeight -= $( this ).outerHeight( true );
@@ -727,6 +716,8 @@ $.widget( "ui.tabs", {
}
});
+ this.panels.show();
+
if ( this.options.heightStyle !== "content" ) {
this.panels.css( "height", "" );
}
@@ -830,7 +821,6 @@ $.widget( "ui.tabs", {
}
},
- // TODO: Remove this function in 1.10 when ajaxOptions is removed
_ajaxSettings: function( anchor, event, eventData ) {
var that = this;
return {
@@ -848,512 +838,4 @@ $.widget( "ui.tabs", {
}
});
-// DEPRECATED
-if ( $.uiBackCompat !== false ) {
-
- // helper method for a lot of the back compat extensions
- $.ui.tabs.prototype._ui = function( tab, panel ) {
- return {
- tab: tab,
- panel: panel,
- index: this.anchors.index( tab )
- };
- };
-
- // url method
- $.widget( "ui.tabs", $.ui.tabs, {
- url: function( index, url ) {
- this.anchors.eq( index ).attr( "href", url );
- }
- });
-
- // TODO: Remove _ajaxSettings() method when removing this extension
- // ajaxOptions and cache options
- $.widget( "ui.tabs", $.ui.tabs, {
- options: {
- ajaxOptions: null,
- cache: false
- },
-
- _create: function() {
- this._super();
-
- var that = this;
-
- this._on({ tabsbeforeload: function( event, ui ) {
- // tab is already cached
- if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) {
- event.preventDefault();
- return;
- }
-
- ui.jqXHR.success(function() {
- if ( that.options.cache ) {
- $.data( ui.tab[ 0 ], "cache.tabs", true );
- }
- });
- }});
- },
-
- _ajaxSettings: function( anchor, event, ui ) {
- var ajaxOptions = this.options.ajaxOptions;
- return $.extend( {}, ajaxOptions, {
- error: function( xhr, s, e ) {
- try {
- // Passing index avoid a race condition when this method is
- // called after the user has selected another tab.
- // Pass the anchor that initiated this request allows
- // loadError to manipulate the tab content panel via $(a.hash)
- ajaxOptions.error(
- xhr, s, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] );
- }
- catch ( e ) {}
- }
- }, this._superApply( arguments ) );
- },
-
- _setOption: function( key, value ) {
- // reset cache if switching from cached to not cached
- if ( key === "cache" && value === false ) {
- this.anchors.removeData( "cache.tabs" );
- }
- this._super( key, value );
- },
-
- _destroy: function() {
- this.anchors.removeData( "cache.tabs" );
- this._super();
- },
-
- url: function( index, url ){
- this.anchors.eq( index ).removeData( "cache.tabs" );
- this._superApply( arguments );
- }
- });
-
- // abort method
- $.widget( "ui.tabs", $.ui.tabs, {
- abort: function() {
- if ( this.xhr ) {
- this.xhr.abort();
- }
- }
- });
-
- // spinner
- $.widget( "ui.tabs", $.ui.tabs, {
- options: {
- spinner: "<em>Loading&#8230;</em>"
- },
- _create: function() {
- this._super();
- this._on({
- tabsbeforeload: function( event, ui ) {
- // Don't react to nested tabs or tabs that don't use a spinner
- if ( event.target !== this.element[ 0 ] ||
- !this.options.spinner ) {
- return;
- }
-
- var span = ui.tab.find( "span" ),
- html = span.html();
- span.html( this.options.spinner );
- ui.jqXHR.complete(function() {
- span.html( html );
- });
- }
- });
- }
- });
-
- // enable/disable events
- $.widget( "ui.tabs", $.ui.tabs, {
- options: {
- enable: null,
- disable: null
- },
-
- enable: function( index ) {
- var options = this.options,
- trigger;
-
- if ( index && options.disabled === true ||
- ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) {
- trigger = true;
- }
-
- this._superApply( arguments );
-
- if ( trigger ) {
- this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
- }
- },
-
- disable: function( index ) {
- var options = this.options,
- trigger;
-
- if ( index && options.disabled === false ||
- ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) {
- trigger = true;
- }
-
- this._superApply( arguments );
-
- if ( trigger ) {
- this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
- }
- }
- });
-
- // add/remove methods and events
- $.widget( "ui.tabs", $.ui.tabs, {
- options: {
- add: null,
- remove: null,
- tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
- },
-
- add: function( url, label, index ) {
- if ( index === undefined ) {
- index = this.anchors.length;
- }
-
- var doInsertAfter, panel,
- options = this.options,
- li = $( options.tabTemplate
- .replace( /#\{href\}/g, url )
- .replace( /#\{label\}/g, label ) ),
- id = !url.indexOf( "#" ) ?
- url.replace( "#", "" ) :
- this._tabId( li );
-
- li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true );
- li.attr( "aria-controls", id );
-
- doInsertAfter = index >= this.tabs.length;
-
- // try to find an existing element before creating a new one
- panel = this.element.find( "#" + id );
- if ( !panel.length ) {
- panel = this._createPanel( id );
- if ( doInsertAfter ) {
- if ( index > 0 ) {
- panel.insertAfter( this.panels.eq( -1 ) );
- } else {
- panel.appendTo( this.element );
- }
- } else {
- panel.insertBefore( this.panels[ index ] );
- }
- }
- panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide();
-
- if ( doInsertAfter ) {
- li.appendTo( this.tablist );
- } else {
- li.insertBefore( this.tabs[ index ] );
- }
-
- options.disabled = $.map( options.disabled, function( n ) {
- return n >= index ? ++n : n;
- });
-
- this.refresh();
- if ( this.tabs.length === 1 && options.active === false ) {
- this.option( "active", 0 );
- }
-
- this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
- return this;
- },
-
- remove: function( index ) {
- index = this._getIndex( index );
- var options = this.options,
- tab = this.tabs.eq( index ).remove(),
- panel = this._getPanelForTab( tab ).remove();
-
- // If selected tab was removed focus tab to the right or
- // in case the last tab was removed the tab to the left.
- // We check for more than 2 tabs, because if there are only 2,
- // then when we remove this tab, there will only be one tab left
- // so we don't need to detect which tab to activate.
- if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) {
- this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
- }
-
- options.disabled = $.map(
- $.grep( options.disabled, function( n ) {
- return n !== index;
- }),
- function( n ) {
- return n >= index ? --n : n;
- });
-
- this.refresh();
-
- this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) );
- return this;
- }
- });
-
- // length method
- $.widget( "ui.tabs", $.ui.tabs, {
- length: function() {
- return this.anchors.length;
- }
- });
-
- // panel ids (idPrefix option + title attribute)
- $.widget( "ui.tabs", $.ui.tabs, {
- options: {
- idPrefix: "ui-tabs-"
- },
-
- _tabId: function( tab ) {
- var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab;
- a = a[0];
- return $( a ).closest( "li" ).attr( "aria-controls" ) ||
- a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) ||
- this.options.idPrefix + getNextTabId();
- }
- });
-
- // _createPanel method
- $.widget( "ui.tabs", $.ui.tabs, {
- options: {
- panelTemplate: "<div></div>"
- },
-
- _createPanel: function( id ) {
- return $( this.options.panelTemplate )
- .attr( "id", id )
- .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
- .data( "ui-tabs-destroy", true );
- }
- });
-
- // selected option
- $.widget( "ui.tabs", $.ui.tabs, {
- _create: function() {
- var options = this.options;
- if ( options.active === null && options.selected !== undefined ) {
- options.active = options.selected === -1 ? false : options.selected;
- }
- this._super();
- options.selected = options.active;
- if ( options.selected === false ) {
- options.selected = -1;
- }
- },
-
- _setOption: function( key, value ) {
- if ( key !== "selected" ) {
- return this._super( key, value );
- }
-
- var options = this.options;
- this._super( "active", value === -1 ? false : value );
- options.selected = options.active;
- if ( options.selected === false ) {
- options.selected = -1;
- }
- },
-
- _eventHandler: function( event ) {
- this._superApply( arguments );
- this.options.selected = this.options.active;
- if ( this.options.selected === false ) {
- this.options.selected = -1;
- }
- }
- });
-
- // show and select event
- $.widget( "ui.tabs", $.ui.tabs, {
- options: {
- show: null,
- select: null
- },
- _create: function() {
- this._super();
- if ( this.options.active !== false ) {
- this._trigger( "show", null, this._ui(
- this.active.find( ".ui-tabs-anchor" )[ 0 ],
- this._getPanelForTab( this.active )[ 0 ] ) );
- }
- },
- _trigger: function( type, event, data ) {
- var ret = this._superApply( arguments );
- if ( !ret ) {
- return false;
- }
- if ( type === "beforeActivate" && data.newTab.length ) {
- ret = this._super( "select", event, {
- tab: data.newTab.find( ".ui-tabs-anchor" )[ 0],
- panel: data.newPanel[ 0 ],
- index: data.newTab.closest( "li" ).index()
- });
- } else if ( type === "activate" && data.newTab.length ) {
- ret = this._super( "show", event, {
- tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ],
- panel: data.newPanel[ 0 ],
- index: data.newTab.closest( "li" ).index()
- });
- }
- return ret;
- }
- });
-
- // select method
- $.widget( "ui.tabs", $.ui.tabs, {
- select: function( index ) {
- index = this._getIndex( index );
- if ( index === -1 ) {
- if ( this.options.collapsible && this.options.selected !== -1 ) {
- index = this.options.selected;
- } else {
- return;
- }
- }
- this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace );
- }
- });
-
- // cookie option
- (function() {
-
- var listId = 0;
-
- $.widget( "ui.tabs", $.ui.tabs, {
- options: {
- cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
- },
- _create: function() {
- var options = this.options,
- active;
- if ( options.active == null && options.cookie ) {
- active = parseInt( this._cookie(), 10 );
- if ( active === -1 ) {
- active = false;
- }
- options.active = active;
- }
- this._super();
- },
- _cookie: function( active ) {
- var cookie = [ this.cookie ||
- ( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ];
- if ( arguments.length ) {
- cookie.push( active === false ? -1 : active );
- cookie.push( this.options.cookie );
- }
- return $.cookie.apply( null, cookie );
- },
- _refresh: function() {
- this._super();
- if ( this.options.cookie ) {
- this._cookie( this.options.active, this.options.cookie );
- }
- },
- _eventHandler: function( event ) {
- this._superApply( arguments );
- if ( this.options.cookie ) {
- this._cookie( this.options.active, this.options.cookie );
- }
- },
- _destroy: function() {
- this._super();
- if ( this.options.cookie ) {
- this._cookie( null, this.options.cookie );
- }
- }
- });
-
- })();
-
- // load event
- $.widget( "ui.tabs", $.ui.tabs, {
- _trigger: function( type, event, data ) {
- var _data = $.extend( {}, data );
- if ( type === "load" ) {
- _data.panel = _data.panel[ 0 ];
- _data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ];
- }
- return this._super( type, event, _data );
- }
- });
-
- // fx option
- // The new animation options (show, hide) conflict with the old show callback.
- // The old fx option wins over show/hide anyway (always favor back-compat).
- // If a user wants to use the new animation API, they must give up the old API.
- $.widget( "ui.tabs", $.ui.tabs, {
- options: {
- fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 }
- },
-
- _getFx: function() {
- var hide, show,
- fx = this.options.fx;
-
- if ( fx ) {
- if ( $.isArray( fx ) ) {
- hide = fx[ 0 ];
- show = fx[ 1 ];
- } else {
- hide = show = fx;
- }
- }
-
- return fx ? { show: show, hide: hide } : null;
- },
-
- _toggle: function( event, eventData ) {
- var that = this,
- toShow = eventData.newPanel,
- toHide = eventData.oldPanel,
- fx = this._getFx();
-
- if ( !fx ) {
- return this._super( event, eventData );
- }
-
- that.running = true;
-
- function complete() {
- that.running = false;
- that._trigger( "activate", event, eventData );
- }
-
- function show() {
- eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
-
- if ( toShow.length && fx.show ) {
- toShow
- .animate( fx.show, fx.show.duration, function() {
- complete();
- });
- } else {
- toShow.show();
- complete();
- }
- }
-
- // start out by hiding, then showing, then completing
- if ( toHide.length && fx.hide ) {
- toHide.animate( fx.hide, fx.hide.duration, function() {
- eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
- show();
- });
- } else {
- eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
- toHide.hide();
- show();
- }
- }
- });
-}
-
})( jQuery );
diff --git a/ui/jquery.ui.tooltip.js b/ui/jquery.ui.tooltip.js
index 980b43868..e5b496bee 100644
--- a/ui/jquery.ui.tooltip.js
+++ b/ui/jquery.ui.tooltip.js
@@ -49,11 +49,12 @@ $.widget( "ui.tooltip", {
return $( this ).attr( "title" );
},
hide: true,
- items: "[title]",
+ // Disabled elements have inconsistent behavior across browsers (#8661)
+ items: "[title]:not([disabled])",
position: {
- my: "left+15 center",
- at: "right center",
- collision: "flipfit flipfit"
+ my: "left top+15",
+ at: "left bottom",
+ collision: "flipfit flip"
},
show: true,
tooltipClass: null,
@@ -72,6 +73,12 @@ $.widget( "ui.tooltip", {
// IDs of generated tooltips, needed for destroy
this.tooltips = {};
+ // IDs of parent tooltips where we removed the title attribute
+ this.parents = {};
+
+ if ( this.options.disabled ) {
+ this._disable();
+ }
},
_setOption: function( key, value ) {
@@ -125,7 +132,10 @@ $.widget( "ui.tooltip", {
},
open: function( event ) {
- var target = $( event ? event.target : this.element )
+ var that = this,
+ target = $( event ? event.target : this.element )
+ // we need closest here due to mouseover bubbling,
+ // but always pointing at the same event target
.closest( this.options.items );
// No element to show a tooltip for
@@ -149,7 +159,28 @@ $.widget( "ui.tooltip", {
target.data( "ui-tooltip-title", target.attr( "title" ) );
}
- target.data( "tooltip-open", true );
+ target.data( "ui-tooltip-open", true );
+
+ // kill parent tooltips, custom or native, for hover
+ if ( event && event.type === "mouseover" ) {
+ target.parents().each(function() {
+ var parent = $( this ),
+ blurEvent;
+ if ( parent.data( "ui-tooltip-open" ) ) {
+ blurEvent = $.Event( "blur" );
+ blurEvent.target = blurEvent.currentTarget = this;
+ that.close( blurEvent, true );
+ }
+ if ( parent.attr( "title" ) ) {
+ parent.uniqueId();
+ that.parents[ this.id ] = {
+ element: this,
+ title: parent.attr( "title" )
+ };
+ parent.attr( "title", "" );
+ }
+ });
+ }
this._updateContent( target, event );
},
@@ -165,7 +196,7 @@ $.widget( "ui.tooltip", {
content = contentOption.call( target[0], function( response ) {
// ignore async response if tooltip was closed already
- if ( !target.data( "tooltip-open" ) ) {
+ if ( !target.data( "ui-tooltip-open" ) ) {
return;
}
// IE may instantly serve a cached response for ajax requests
@@ -180,7 +211,9 @@ $.widget( "ui.tooltip", {
},
_open: function( event, target, content ) {
- var tooltip, positionOption;
+ var tooltip, events, delayedShow,
+ positionOption = $.extend( {}, this.options.position );
+
if ( !content ) {
return;
}
@@ -214,10 +247,12 @@ $.widget( "ui.tooltip", {
function position( event ) {
positionOption.of = event;
+ if ( tooltip.is( ":hidden" ) ) {
+ return;
+ }
tooltip.position( positionOption );
}
- if ( this.options.track && event && /^mouse/.test( event.originalEvent.type ) ) {
- positionOption = $.extend( {}, this.options.position );
+ if ( this.options.track && event && /^mouse/.test( event.type ) ) {
this._on( this.document, {
mousemove: position
});
@@ -232,23 +267,42 @@ $.widget( "ui.tooltip", {
tooltip.hide();
this._show( tooltip, this.options.show );
+ // Handle tracking tooltips that are shown with a delay (#8644). As soon
+ // as the tooltip is visible, position the tooltip using the most recent
+ // event.
+ if ( this.options.show && this.options.show.delay ) {
+ delayedShow = setInterval(function() {
+ if ( tooltip.is( ":visible" ) ) {
+ position( positionOption.of );
+ clearInterval( delayedShow );
+ }
+ }, $.fx.interval );
+ }
this._trigger( "open", event, { tooltip: tooltip } );
- this._on( target, {
- mouseleave: "close",
- focusout: "close",
+ events = {
keyup: function( event ) {
if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
var fakeEvent = $.Event(event);
fakeEvent.currentTarget = target[0];
this.close( fakeEvent, true );
}
+ },
+ remove: function() {
+ this._removeTooltip( tooltip );
}
- });
+ };
+ if ( !event || event.type === "mouseover" ) {
+ events.mouseleave = "close";
+ }
+ if ( !event || event.type === "focusin" ) {
+ events.focusout = "close";
+ }
+ this._on( true, target, events );
},
- close: function( event, force ) {
+ close: function( event ) {
var that = this,
target = $( event ? event.currentTarget : this.element ),
tooltip = this._find( target );
@@ -259,16 +313,6 @@ $.widget( "ui.tooltip", {
return;
}
- // don't close if the element has focus
- // this prevents the tooltip from closing if you hover while focused
- //
- // we have to check the event type because tabbing out of the document
- // may leave the element as the activeElement
- if ( !force && event && event.type !== "focusout" &&
- this.document[0].activeElement === target[0] ) {
- return;
- }
-
// only set title if we had one before (see comment in _open())
if ( target.data( "ui-tooltip-title" ) ) {
target.attr( "title", target.data( "ui-tooltip-title" ) );
@@ -278,14 +322,24 @@ $.widget( "ui.tooltip", {
tooltip.stop( true );
this._hide( tooltip, this.options.hide, function() {
- $( this ).remove();
- delete that.tooltips[ this.id ];
+ that._removeTooltip( $( this ) );
});
- target.removeData( "tooltip-open" );
+ target.removeData( "ui-tooltip-open" );
this._off( target, "mouseleave focusout keyup" );
+ // Remove 'remove' binding only on delegated targets
+ if ( target[0] !== this.element[0] ) {
+ this._off( target, "remove" );
+ }
this._off( this.document, "mousemove" );
+ if ( event && event.type === "mouseleave" ) {
+ $.each( this.parents, function( id, parent ) {
+ $( parent.element ).attr( "title", parent.title );
+ delete that.parents[ id ];
+ });
+ }
+
this.closing = true;
this._trigger( "close", event, { tooltip: tooltip } );
this.closing = false;
@@ -304,9 +358,6 @@ $.widget( "ui.tooltip", {
.addClass( "ui-tooltip-content" )
.appendTo( tooltip );
tooltip.appendTo( this.document[0].body );
- if ( $.fn.bgiframe ) {
- tooltip.bgiframe();
- }
this.tooltips[ id ] = element;
return tooltip;
},
@@ -316,6 +367,11 @@ $.widget( "ui.tooltip", {
return id ? $( "#" + id ) : $();
},
+ _removeTooltip: function( tooltip ) {
+ tooltip.remove();
+ delete this.tooltips[ tooltip.attr( "id" ) ];
+ },
+
_destroy: function() {
var that = this;
diff --git a/ui/jquery.ui.widget.js b/ui/jquery.ui.widget.js
index a125dd5ac..06f25576a 100644
--- a/ui/jquery.ui.widget.js
+++ b/ui/jquery.ui.widget.js
@@ -101,13 +101,11 @@ $.widget = function( name, base, prototype ) {
// TODO: remove support for widgetEventPrefix
// always use the name + a colon as the prefix, e.g., draggable:start
// don't prefix for widgets that aren't DOM-based
- widgetEventPrefix: name
+ widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
}, prototype, {
constructor: constructor,
namespace: namespace,
widgetName: name,
- // TODO remove widgetBaseClass, see #8155
- widgetBaseClass: fullName,
widgetFullName: fullName
});
@@ -142,8 +140,17 @@ $.widget.extend = function( target ) {
for ( ; inputIndex < inputLength; inputIndex++ ) {
for ( key in input[ inputIndex ] ) {
value = input[ inputIndex ][ key ];
- if (input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
- target[ key ] = $.isPlainObject( value ) ? $.widget.extend( {}, target[ key ], value ) : value;
+ if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
+ // Clone objects
+ if ( $.isPlainObject( value ) ) {
+ target[ key ] = $.isPlainObject( target[ key ] ) ?
+ $.widget.extend( {}, target[ key ], value ) :
+ // Don't extend strings, arrays, etc. with objects
+ $.widget.extend( {}, value );
+ // Copy everything else by reference
+ } else {
+ target[ key ] = value;
+ }
}
}
}
@@ -151,7 +158,7 @@ $.widget.extend = function( target ) {
};
$.widget.bridge = function( name, object ) {
- var fullName = object.prototype.widgetFullName;
+ var fullName = object.prototype.widgetFullName || name;
$.fn[ name ] = function( options ) {
var isMethodCall = typeof options === "string",
args = slice.call( arguments, 1 ),
@@ -187,7 +194,7 @@ $.widget.bridge = function( name, object ) {
if ( instance ) {
instance.option( options || {} )._init();
} else {
- new object( options, this );
+ $.data( this, fullName, new object( options, this ) );
}
});
}
@@ -196,7 +203,7 @@ $.widget.bridge = function( name, object ) {
};
};
-$.Widget = function( options, element ) {};
+$.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = [];
$.Widget.prototype = {
@@ -224,11 +231,14 @@ $.Widget.prototype = {
this.focusable = $();
if ( element !== this ) {
- // 1.9 BC for #7810
- // TODO remove dual storage
- $.data( element, this.widgetName, this );
$.data( element, this.widgetFullName, this );
- this._on({ remove: "destroy" });
+ this._on( true, this.element, {
+ remove: function( event ) {
+ if ( event.target === element ) {
+ this.destroy();
+ }
+ }
+ });
this.document = $( element.style ?
// element within the document
element.ownerDocument :
@@ -346,25 +356,36 @@ $.Widget.prototype = {
return this._setOption( "disabled", true );
},
- _on: function( element, handlers ) {
+ _on: function( suppressDisabledCheck, element, handlers ) {
+ var delegateElement,
+ instance = this;
+
+ // no suppressDisabledCheck flag, shuffle arguments
+ if ( typeof suppressDisabledCheck !== "boolean" ) {
+ handlers = element;
+ element = suppressDisabledCheck;
+ suppressDisabledCheck = false;
+ }
+
// no element argument, shuffle and use this.element
if ( !handlers ) {
handlers = element;
element = this.element;
+ delegateElement = this.widget();
} else {
// accept selectors, DOM elements
- element = $( element );
+ element = delegateElement = $( element );
this.bindings = this.bindings.add( element );
}
- var instance = this;
$.each( handlers, function( event, handler ) {
function handlerProxy() {
// allow widgets to customize the disabled handling
// - disabled as an array instead of boolean
// - disabled class as method for disabling individual parts
- if ( instance.options.disabled === true ||
- $( this ).hasClass( "ui-state-disabled" ) ) {
+ if ( !suppressDisabledCheck &&
+ ( instance.options.disabled === true ||
+ $( this ).hasClass( "ui-state-disabled" ) ) ) {
return;
}
return ( typeof handler === "string" ? instance[ handler ] : handler )
@@ -381,7 +402,7 @@ $.Widget.prototype = {
eventName = match[1] + instance.eventNamespace,
selector = match[2];
if ( selector ) {
- instance.widget().delegate( selector, eventName, handlerProxy );
+ delegateElement.delegate( selector, eventName, handlerProxy );
} else {
element.bind( eventName, handlerProxy );
}
@@ -476,7 +497,7 @@ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
if ( options.delay ) {
element.delay( options.delay );
}
- if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
+ if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
element[ method ]( options );
} else if ( effectName !== method && element[ effectName ] ) {
element[ effectName ]( options.duration, options.easing, callback );
@@ -492,11 +513,4 @@ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
};
});
-// DEPRECATED
-if ( $.uiBackCompat !== false ) {
- $.Widget.prototype._getCreateOptions = function() {
- return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
- };
-}
-
})( jQuery );