diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2013-01-18 16:46:04 +0100 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2013-01-18 16:46:04 +0100 |
commit | 63601400e476c6cf43d985f3e7b9864681695ed4 (patch) | |
tree | f7846203a952e38aaf66989d0a4702779f549962 /resources | |
parent | 8ff01378c9e0207f9169b81966a51def645b6a51 (diff) |
Update to MediaWiki 1.20.2
this update includes:
* adjusted Arch Linux skin
* updated FluxBBAuthPlugin
* patch for https://bugzilla.wikimedia.org/show_bug.cgi?id=44024
Diffstat (limited to 'resources')
256 files changed, 14241 insertions, 10770 deletions
diff --git a/resources/Resources.php b/resources/Resources.php index ab2610ce..0a70c5a2 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -4,15 +4,25 @@ return array( /* Special modules who have their own classes */ + // Scripts managed by the local wiki (stored in the MediaWiki namespace) 'site' => array( 'class' => 'ResourceLoaderSiteModule' ), 'noscript' => array( 'class' => 'ResourceLoaderNoscriptModule' ), 'startup' => array( 'class' => 'ResourceLoaderStartUpModule' ), - 'user' => array( 'class' => 'ResourceLoaderUserModule' ), + 'filepage' => array( 'class' => 'ResourceLoaderFilePageModule' ), 'user.groups' => array( 'class' => 'ResourceLoaderUserGroupsModule' ), - 'user.options' => array( 'class' => 'ResourceLoaderUserOptionsModule' ), + + // Scripts managed by the current user (stored in their user space) + 'user' => array( 'class' => 'ResourceLoaderUserModule' ), + + // Scripts generated based on the current user's preferences 'user.cssprefs' => array( 'class' => 'ResourceLoaderUserCSSPrefsModule' ), + + // Populate mediawiki.user placeholders with information about the current user + 'user.options' => array( 'class' => 'ResourceLoaderUserOptionsModule' ), 'user.tokens' => array( 'class' => 'ResourceLoaderUserTokensModule' ), - 'filepage' => array( 'class' => 'ResourceLoaderFilePageModule' ), + + // Scripts for the dynamic language specific data, like grammar forms. + 'mediawiki.language.data' => array( 'class' => 'ResourceLoaderLanguageDataModule' ), /* Skins */ @@ -68,7 +78,7 @@ return array( 'localBasePath' => $GLOBALS['wgStyleDirectory'], ), 'skins.standard' => array( - 'styles' => array( 'common/wikistandard.css' => array( 'media' => 'screen' ) ), + 'styles' => array( 'standard/main.css' => array( 'media' => 'screen' ) ), 'remoteBasePath' => $GLOBALS['wgStylePath'], 'localBasePath' => $GLOBALS['wgStyleDirectory'], ), @@ -79,6 +89,7 @@ return array( 'common/commonContent.css' => array( 'media' => 'screen' ), 'common/commonInterface.css' => array( 'media' => 'screen' ), 'vector/screen.css' => array( 'media' => 'screen' ), + 'vector/screen-hd.css' => array( 'media' => 'screen and (min-width: 982px)' ), ), 'scripts' => 'vector/vector.js', 'remoteBasePath' => $GLOBALS['wgStylePath'], @@ -108,6 +119,10 @@ return array( 'scripts' => 'resources/jquery/jquery.autoEllipsis.js', 'dependencies' => 'jquery.highlightText', ), + 'jquery.badge' => array( + 'scripts' => 'resources/jquery/jquery.badge.js', + 'styles' => 'resources/jquery/jquery.badge.css', + ), 'jquery.byteLength' => array( 'scripts' => 'resources/jquery/jquery.byteLength.js', ), @@ -158,6 +173,7 @@ return array( ), 'jquery.highlightText' => array( 'scripts' => 'resources/jquery/jquery.highlightText.js', + 'dependencies' => 'jquery.mwExtension', ), 'jquery.hoverIntent' => array( 'scripts' => 'resources/jquery/jquery.hoverIntent.js', @@ -173,10 +189,6 @@ return array( 'styles' => 'resources/jquery/jquery.makeCollapsible.css', 'messages' => array( 'collapsible-expand', 'collapsible-collapse' ), ), - 'jquery.messageBox' => array( - 'scripts' => 'resources/jquery/jquery.messageBox.js', - 'styles' => 'resources/jquery/jquery.messageBox.css', - ), 'jquery.mockjax' => array( 'scripts' => 'resources/jquery/jquery.mockjax.js', ), @@ -202,6 +214,10 @@ return array( 'scripts' => 'resources/jquery/jquery.spinner.js', 'styles' => 'resources/jquery/jquery.spinner.css', ), + 'jquery.jStorage' => array( + 'scripts' => 'resources/jquery/jquery.jStorage.js', + 'dependencies' => 'jquery.json', + ), 'jquery.suggestions' => array( 'scripts' => 'resources/jquery/jquery.suggestions.js', 'styles' => 'resources/jquery/jquery.suggestions.css', @@ -214,9 +230,11 @@ return array( 'scripts' => 'resources/jquery/jquery.tablesorter.js', 'styles' => 'resources/jquery/jquery.tablesorter.css', 'messages' => array( 'sort-descending', 'sort-ascending' ), + 'dependencies' => 'jquery.mwExtension', ), 'jquery.textSelection' => array( 'scripts' => 'resources/jquery/jquery.textSelection.js', + 'dependencies' => 'jquery.client', ), 'jquery.validate' => array( 'scripts' => 'resources/jquery/jquery.validate.js', @@ -353,10 +371,10 @@ return array( 'fa' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-fa.js', 'fi' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-fi.js', 'fo' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-fo.js', - 'fr-ch' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-fr-CH.js', 'fr' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-fr.js', 'gl' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-gl.js', 'he' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-he.js', + 'hi' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-hi.js', 'hr' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-hr.js', 'hu' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-hu.js', 'hy' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-hy.js', @@ -364,7 +382,9 @@ return array( 'is' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-is.js', 'it' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-it.js', 'ja' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-ja.js', + 'ka' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-ka.js', 'kk' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-kk.js', + 'km' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-km.js', 'ko' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-ko.js', 'lb' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-lb.js', 'lt' => 'resources/jquery.ui/i18n/jquery.ui.datepicker-lt.js', @@ -524,34 +544,37 @@ return array( 'scripts' => 'resources/mediawiki.api/mediawiki.api.js', 'dependencies' => 'mediawiki.util', ), - 'mediawiki.api.category' => array( + 'mediawiki.api.category' => array( 'scripts' => 'resources/mediawiki.api/mediawiki.api.category.js', - 'dependencies' => array( + 'dependencies' => array( 'mediawiki.api', - 'mediawiki.Title' + 'mediawiki.Title', ), ), - 'mediawiki.api.edit' => array( + 'mediawiki.api.edit' => array( 'scripts' => 'resources/mediawiki.api/mediawiki.api.edit.js', - 'dependencies' => array( + 'dependencies' => array( 'mediawiki.api', - 'mediawiki.Title' + 'mediawiki.Title', ), ), - 'mediawiki.api.parse' => array( + 'mediawiki.api.parse' => array( 'scripts' => 'resources/mediawiki.api/mediawiki.api.parse.js', 'dependencies' => 'mediawiki.api', ), - 'mediawiki.api.titleblacklist' => array( + 'mediawiki.api.titleblacklist' => array( 'scripts' => 'resources/mediawiki.api/mediawiki.api.titleblacklist.js', - 'dependencies' => array( + 'dependencies' => array( 'mediawiki.api', - 'mediawiki.Title' + 'mediawiki.Title', ), ), - 'mediawiki.api.watch' => array( + 'mediawiki.api.watch' => array( 'scripts' => 'resources/mediawiki.api/mediawiki.api.watch.js', - 'dependencies' => array('mediawiki.api', 'mediawiki.user'), + 'dependencies' => array( + 'mediawiki.api', + 'user.tokens', + ), ), 'mediawiki.debug' => array( 'scripts' => 'resources/mediawiki/mediawiki.debug.js', @@ -569,13 +592,13 @@ return array( 'mediawiki.feedback' => array( 'scripts' => 'resources/mediawiki/mediawiki.feedback.js', 'styles' => 'resources/mediawiki/mediawiki.feedback.css', - 'dependencies' => array( - 'mediawiki.api.edit', + 'dependencies' => array( + 'mediawiki.api.edit', 'mediawiki.Title', 'mediawiki.jqueryMsg', 'jquery.ui.dialog', ), - 'messages' => array( + 'messages' => array( 'feedback-bugornote', 'feedback-subject', 'feedback-message', @@ -594,6 +617,29 @@ return array( 'mediawiki.htmlform' => array( 'scripts' => 'resources/mediawiki/mediawiki.htmlform.js', ), + 'mediawiki.notification' => array( + 'styles' => 'resources/mediawiki/mediawiki.notification.css', + 'scripts' => 'resources/mediawiki/mediawiki.notification.js', + 'dependencies' => array( + 'mediawiki.page.startup', + ), + ), + 'mediawiki.notify' => array( + 'scripts' => 'resources/mediawiki/mediawiki.notify.js', + ), + 'mediawiki.searchSuggest' => array( + 'scripts' => 'resources/mediawiki/mediawiki.searchSuggest.js', + 'messages' => array( + 'searchsuggest-search', + 'searchsuggest-containing', + ), + 'dependencies' => array( + 'jquery.autoEllipsis', + 'jquery.client', + 'jquery.placeholder', + 'jquery.suggestions', + ), + ), 'mediawiki.Title' => array( 'scripts' => 'resources/mediawiki/mediawiki.Title.js', 'dependencies' => 'mediawiki.util', @@ -605,6 +651,7 @@ return array( 'scripts' => 'resources/mediawiki/mediawiki.user.js', 'dependencies' => array( 'jquery.cookie', + 'mediawiki.api', ), ), 'mediawiki.util' => array( @@ -612,8 +659,8 @@ return array( 'dependencies' => array( 'jquery.client', 'jquery.cookie', - 'jquery.messageBox', 'jquery.mwExtension', + 'mediawiki.notify', ), 'messages' => array( 'showtoc', 'hidetoc' ), 'position' => 'top', // For $wgPreloadJavaScriptMwUtil @@ -627,10 +674,17 @@ return array( 'jquery.textSelection', 'jquery.byteLimit', ), + 'position' => 'top', + ), + 'mediawiki.action.edit.preview' => array( + 'scripts' => 'resources/mediawiki.action/mediawiki.action.edit.preview.js', + 'dependencies' => array( + 'jquery.form', + 'jquery.spinner', + ), ), 'mediawiki.action.history' => array( 'scripts' => 'resources/mediawiki.action/mediawiki.action.history.js', - 'dependencies' => 'jquery.ui.button', 'group' => 'mediawiki.action.history', ), 'mediawiki.action.history.diff' => array( @@ -651,21 +705,9 @@ return array( 'mediawiki.action.view.rightClickEdit' => array( 'scripts' => 'resources/mediawiki.action/mediawiki.action.view.rightClickEdit.js', ), + // Alias for backwards compatibility 'mediawiki.action.watch.ajax' => array( - 'scripts' => 'resources/mediawiki.action/mediawiki.action.watch.ajax.js', - 'dependencies' => array( - 'mediawiki.api.watch', - 'mediawiki.util', - ), - 'messages' => array( - 'watch', - 'unwatch', - 'watching', - 'unwatching', - 'tooltip-ca-watch', - 'tooltip-ca-unwatch', - 'watcherrortext', - ), + 'dependencies' => 'mediawiki.page.watch.ajax' ), /* MediaWiki Language */ @@ -673,59 +715,47 @@ return array( 'mediawiki.language' => array( 'scripts' => 'resources/mediawiki.language/mediawiki.language.js', 'languageScripts' => array( - 'am' => 'resources/mediawiki.language/languages/am.js', - 'ar' => 'resources/mediawiki.language/languages/ar.js', - 'bat-smg' => 'resources/mediawiki.language/languages/bat-smg.js', - 'be' => 'resources/mediawiki.language/languages/be.js', - 'be-tarask' => 'resources/mediawiki.language/languages/be-tarask.js', - 'bh' => 'resources/mediawiki.language/languages/bh.js', 'bs' => 'resources/mediawiki.language/languages/bs.js', - 'cs' => 'resources/mediawiki.language/languages/cs.js', - 'cu' => 'resources/mediawiki.language/languages/cu.js', - 'cy' => 'resources/mediawiki.language/languages/cy.js', 'dsb' => 'resources/mediawiki.language/languages/dsb.js', - 'fr' => 'resources/mediawiki.language/languages/fr.js', + 'fi' => 'resources/mediawiki.language/languages/fi.js', 'ga' => 'resources/mediawiki.language/languages/ga.js', - 'gd' => 'resources/mediawiki.language/languages/gd.js', - 'gv' => 'resources/mediawiki.language/languages/gv.js', 'he' => 'resources/mediawiki.language/languages/he.js', - 'hi' => 'resources/mediawiki.language/languages/hi.js', - 'hr' => 'resources/mediawiki.language/languages/hr.js', 'hsb' => 'resources/mediawiki.language/languages/hsb.js', + 'hu' => 'resources/mediawiki.language/languages/hu.js', 'hy' => 'resources/mediawiki.language/languages/hy.js', - 'ksh' => 'resources/mediawiki.language/languages/ksh.js', - 'ln' => 'resources/mediawiki.language/languages/ln.js', - 'lt' => 'resources/mediawiki.language/languages/lt.js', - 'lv' => 'resources/mediawiki.language/languages/lv.js', - 'mg' => 'resources/mediawiki.language/languages/mg.js', - 'mk' => 'resources/mediawiki.language/languages/mk.js', - 'mo' => 'resources/mediawiki.language/languages/mo.js', - 'mt' => 'resources/mediawiki.language/languages/mt.js', - 'nl' => 'resources/mediawiki.language/languages/nl.js', - 'nso' => 'resources/mediawiki.language/languages/nso.js', - 'pl' => 'resources/mediawiki.language/languages/pl.js', - 'pt' => 'resources/mediawiki.language/languages/pt.js', - 'pt-br' => 'resources/mediawiki.language/languages/pt-br.js', - 'ro' => 'resources/mediawiki.language/languages/ro.js', + 'la' => 'resources/mediawiki.language/languages/la.js', + 'os' => 'resources/mediawiki.language/languages/os.js', 'ru' => 'resources/mediawiki.language/languages/ru.js', - 'se' => 'resources/mediawiki.language/languages/se.js', - 'sh' => 'resources/mediawiki.language/languages/sh.js', - 'sk' => 'resources/mediawiki.language/languages/sk.js', 'sl' => 'resources/mediawiki.language/languages/sl.js', - 'sma' => 'resources/mediawiki.language/languages/sma.js', - 'sr-ec' => 'resources/mediawiki.language/languages/sr-ec.js', - 'sr-el' => 'resources/mediawiki.language/languages/sr-el.js', - 'sr' => 'resources/mediawiki.language/languages/sr.js', - 'ti' => 'resources/mediawiki.language/languages/ti.js', - 'tl' => 'resources/mediawiki.language/languages/tl.js', 'uk' => 'resources/mediawiki.language/languages/uk.js', - 'wa' => 'resources/mediawiki.language/languages/wa.js', ), + 'dependencies' => array( + 'mediawiki.language.data', + 'mediawiki.cldr' + ), + ), + + 'mediawiki.cldr' => array( + 'scripts' => 'resources/mediawiki.language/mediawiki.cldr.js', + 'dependencies' => array( + 'mediawiki.libs.pluralruleparser', + ), + ), + + 'mediawiki.libs.pluralruleparser' => array( + 'scripts' => 'resources/mediawiki.libs/CLDRPluralRuleParser.js', + ), + + 'mediawiki.language.init' => array( + 'scripts' => 'resources/mediawiki.language/mediawiki.language.init.js', ), 'mediawiki.jqueryMsg' => array( - 'dependencies' => array( 'mediawiki.language', 'mediawiki.util' ), - 'scripts' => 'resources/mediawiki/mediawiki.jqueryMsg.js' + 'scripts' => 'resources/mediawiki/mediawiki.jqueryMsg.js', + 'dependencies' => array( + 'mediawiki.util', + 'mediawiki.language', + ), ), /* MediaWiki Libs */ @@ -754,7 +784,25 @@ return array( ), 'position' => 'top', ), - + 'mediawiki.page.watch.ajax' => array( + 'scripts' => 'resources/mediawiki.page/mediawiki.page.watch.ajax.js', + 'dependencies' => array( + 'mediawiki.page.startup', + 'mediawiki.api.watch', + 'mediawiki.util', + 'mediawiki.notify', + 'jquery.mwExtension', + ), + 'messages' => array( + 'watch', + 'unwatch', + 'watching', + 'unwatching', + 'tooltip-ca-watch', + 'tooltip-ca-unwatch', + 'watcherrortext', + ), + ), /* MediaWiki Special pages */ @@ -789,6 +837,7 @@ return array( ), 'mediawiki.special.preferences' => array( 'scripts' => 'resources/mediawiki.special/mediawiki.special.preferences.js', + 'styles' => 'resources/mediawiki.special/mediawiki.special.preferences.css', ), 'mediawiki.special.recentchanges' => array( 'scripts' => 'resources/mediawiki.special/mediawiki.special.recentchanges.js', @@ -798,6 +847,11 @@ return array( 'mediawiki.special.search' => array( 'scripts' => 'resources/mediawiki.special/mediawiki.special.search.js', 'styles' => 'resources/mediawiki.special/mediawiki.special.search.css', + 'messages' => array( + 'powersearch-togglelabel', + 'powersearch-toggleall', + 'powersearch-togglenone', + ), ), 'mediawiki.special.undelete' => array( 'scripts' => 'resources/mediawiki.special/mediawiki.special.undelete.js', @@ -868,19 +922,6 @@ return array( 'localBasePath' => $GLOBALS['wgStyleDirectory'], 'dependencies' => 'mediawiki.legacy.wikibits', ), - 'mediawiki.legacy.mwsuggest' => array( - 'scripts' => 'common/mwsuggest.js', - 'remoteBasePath' => $GLOBALS['wgStylePath'], - 'localBasePath' => $GLOBALS['wgStyleDirectory'], - 'dependencies' => 'mediawiki.legacy.wikibits', - 'messages' => array( 'search-mwsuggest-enabled', 'search-mwsuggest-disabled' ), - ), - 'mediawiki.legacy.preview' => array( - 'scripts' => 'common/preview.js', - 'remoteBasePath' => $GLOBALS['wgStylePath'], - 'localBasePath' => $GLOBALS['wgStyleDirectory'], - 'dependencies' => 'mediawiki.legacy.wikibits', - ), 'mediawiki.legacy.protect' => array( 'scripts' => 'common/protect.js', 'remoteBasePath' => $GLOBALS['wgStylePath'], diff --git a/resources/jquery.effects/jquery.effects.blind.js b/resources/jquery.effects/jquery.effects.blind.js index 2ecbbed3..1e997690 100644 --- a/resources/jquery.effects/jquery.effects.blind.js +++ b/resources/jquery.effects/jquery.effects.blind.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects Blind 1.8.17 +/*! + * jQuery UI Effects Blind 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.effects/jquery.effects.bounce.js b/resources/jquery.effects/jquery.effects.bounce.js index f8e44730..7927a4a9 100644 --- a/resources/jquery.effects/jquery.effects.bounce.js +++ b/resources/jquery.effects/jquery.effects.bounce.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects Bounce 1.8.17 +/*! + * jQuery UI Effects Bounce 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -32,7 +32,7 @@ $.effects.bounce = function(o) { $.effects.createWrapper(el); // Create Wrapper var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; - var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3); + var distance = o.options.distance || (ref == 'top' ? el.outerHeight(true) / 3 : el.outerWidth(true) / 3); if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift if (mode == 'hide') distance = distance / (times * 2); if (mode != 'hide') times--; diff --git a/resources/jquery.effects/jquery.effects.clip.js b/resources/jquery.effects/jquery.effects.clip.js index 74845c08..d8b8218f 100644 --- a/resources/jquery.effects/jquery.effects.clip.js +++ b/resources/jquery.effects/jquery.effects.clip.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects Clip 1.8.17 +/*! + * jQuery UI Effects Clip 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.effects/jquery.effects.core.js b/resources/jquery.effects/jquery.effects.core.js index 7f568964..91ac5755 100644 --- a/resources/jquery.effects/jquery.effects.core.js +++ b/resources/jquery.effects/jquery.effects.core.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects 1.8.17 +/*! + * jQuery UI Effects 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -75,7 +75,8 @@ function getColor(elem, attr) { var color; do { - color = $.curCSS(elem, attr); + // jQuery <1.4.3 uses curCSS, in 1.4.3 - 1.7.2 curCSS = css, 1.8+ only has css + color = ($.curCSS || $.css)(elem, attr); // Keep going until we find an element that has color, or we hit the body if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") ) @@ -236,7 +237,7 @@ $.effects.animateClass = function(value, duration, easing, callback) { originalStyleAttr = that.attr('style') || ' ', originalStyle = filterStyles(getElementStyles.call(this)), newStyle, - className = that.attr('class'); + className = that.attr('class') || ""; $.each(classAnimationActions, function(i, action) { if (value[action]) { @@ -306,7 +307,7 @@ $.fn.extend({ /******************************************************************************/ $.extend($.effects, { - version: "1.8.17", + version: "1.8.23", // Saves a set of properties in a data storage save: function(element, set) { @@ -370,7 +371,16 @@ $.extend($.effects, { }), active = document.activeElement; - element.wrap(wrapper); + // support: Firefox + // Firefox incorrectly exposes anonymous content + // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 + try { + active.id; + } catch( e ) { + active = document.body; + } + + element.wrap( wrapper ); // Fixes #7595 - Elements lose focus when wrapped. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { @@ -419,7 +429,7 @@ $.extend($.effects, { setTransition: function(element, list, factor, value) { value = value || {}; $.each(list, function(i, x){ - unit = element.cssUnit(x); + var unit = element.cssUnit(x); if (unit[0] > 0) value[x] = unit[0] * factor + unit[1]; }); return value; @@ -554,210 +564,49 @@ $.fn.extend({ /*********************************** EASING ***********************************/ /******************************************************************************/ -/* - * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ - * - * Uses the built in easing capabilities added In jQuery 1.1 - * to offer multiple easing options - * - * TERMS OF USE - jQuery Easing - * - * Open source under the BSD License. - * - * Copyright 2008 George McGinley Smith - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Neither the name of the author nor the names of contributors may be used to endorse - * or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ +// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) -// t: current time, b: begInnIng value, c: change In value, d: duration -$.easing.jswing = $.easing.swing; +var baseEasings = {}; -$.extend($.easing, -{ - def: 'easeOutQuad', - swing: function (x, t, b, c, d) { - //alert($.easing.default); - return $.easing[$.easing.def](x, t, b, c, d); - }, - easeInQuad: function (x, t, b, c, d) { - return c*(t/=d)*t + b; - }, - easeOutQuad: function (x, t, b, c, d) { - return -c *(t/=d)*(t-2) + b; - }, - easeInOutQuad: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t + b; - return -c/2 * ((--t)*(t-2) - 1) + b; - }, - easeInCubic: function (x, t, b, c, d) { - return c*(t/=d)*t*t + b; - }, - easeOutCubic: function (x, t, b, c, d) { - return c*((t=t/d-1)*t*t + 1) + b; - }, - easeInOutCubic: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t*t + b; - return c/2*((t-=2)*t*t + 2) + b; - }, - easeInQuart: function (x, t, b, c, d) { - return c*(t/=d)*t*t*t + b; - }, - easeOutQuart: function (x, t, b, c, d) { - return -c * ((t=t/d-1)*t*t*t - 1) + b; - }, - easeInOutQuart: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t*t*t + b; - return -c/2 * ((t-=2)*t*t*t - 2) + b; - }, - easeInQuint: function (x, t, b, c, d) { - return c*(t/=d)*t*t*t*t + b; - }, - easeOutQuint: function (x, t, b, c, d) { - return c*((t=t/d-1)*t*t*t*t + 1) + b; - }, - easeInOutQuint: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; - return c/2*((t-=2)*t*t*t*t + 2) + b; - }, - easeInSine: function (x, t, b, c, d) { - return -c * Math.cos(t/d * (Math.PI/2)) + c + b; - }, - easeOutSine: function (x, t, b, c, d) { - return c * Math.sin(t/d * (Math.PI/2)) + b; - }, - easeInOutSine: function (x, t, b, c, d) { - return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; - }, - easeInExpo: function (x, t, b, c, d) { - return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; - }, - easeOutExpo: function (x, t, b, c, d) { - return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; - }, - easeInOutExpo: function (x, t, b, c, d) { - if (t==0) return b; - if (t==d) return b+c; - if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; - return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; - }, - easeInCirc: function (x, t, b, c, d) { - return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; - }, - easeOutCirc: function (x, t, b, c, d) { - return c * Math.sqrt(1 - (t=t/d-1)*t) + b; - }, - easeInOutCirc: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; - return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; - }, - easeInElastic: function (x, t, b, c, d) { - var s=1.70158;var p=0;var a=c; - if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; - if (a < Math.abs(c)) { a=c; var s=p/4; } - else var s = p/(2*Math.PI) * Math.asin (c/a); - return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; - }, - easeOutElastic: function (x, t, b, c, d) { - var s=1.70158;var p=0;var a=c; - if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; - if (a < Math.abs(c)) { a=c; var s=p/4; } - else var s = p/(2*Math.PI) * Math.asin (c/a); - return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; - }, - easeInOutElastic: function (x, t, b, c, d) { - var s=1.70158;var p=0;var a=c; - if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); - if (a < Math.abs(c)) { a=c; var s=p/4; } - else var s = p/(2*Math.PI) * Math.asin (c/a); - if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; - return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; - }, - easeInBack: function (x, t, b, c, d, s) { - if (s == undefined) s = 1.70158; - return c*(t/=d)*t*((s+1)*t - s) + b; - }, - easeOutBack: function (x, t, b, c, d, s) { - if (s == undefined) s = 1.70158; - return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; +$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { + baseEasings[ name ] = function( p ) { + return Math.pow( p, i + 2 ); + }; +}); + +$.extend( baseEasings, { + Sine: function ( p ) { + return 1 - Math.cos( p * Math.PI / 2 ); }, - easeInOutBack: function (x, t, b, c, d, s) { - if (s == undefined) s = 1.70158; - if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; - return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; + Circ: function ( p ) { + return 1 - Math.sqrt( 1 - p * p ); }, - easeInBounce: function (x, t, b, c, d) { - return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b; + Elastic: function( p ) { + return p === 0 || p === 1 ? p : + -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); }, - easeOutBounce: function (x, t, b, c, d) { - if ((t/=d) < (1/2.75)) { - return c*(7.5625*t*t) + b; - } else if (t < (2/2.75)) { - return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; - } else if (t < (2.5/2.75)) { - return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; - } else { - return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; - } + Back: function( p ) { + return p * p * ( 3 * p - 2 ); }, - easeInOutBounce: function (x, t, b, c, d) { - if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; - return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; + Bounce: function ( p ) { + var pow2, + bounce = 4; + + while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} + return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); } }); -/* - * - * TERMS OF USE - EASING EQUATIONS - * - * Open source under the BSD License. - * - * Copyright 2001 Robert Penner - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Neither the name of the author nor the names of contributors may be used to endorse - * or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ +$.each( baseEasings, function( name, easeIn ) { + $.easing[ "easeIn" + name ] = easeIn; + $.easing[ "easeOut" + name ] = function( p ) { + return 1 - easeIn( 1 - p ); + }; + $.easing[ "easeInOut" + name ] = function( p ) { + return p < .5 ? + easeIn( p * 2 ) / 2 : + easeIn( p * -2 + 2 ) / -2 + 1; + }; +}); })(jQuery); diff --git a/resources/jquery.effects/jquery.effects.drop.js b/resources/jquery.effects/jquery.effects.drop.js index 4bbd1087..6d25bd30 100644 --- a/resources/jquery.effects/jquery.effects.drop.js +++ b/resources/jquery.effects/jquery.effects.drop.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects Drop 1.8.17 +/*! + * jQuery UI Effects Drop 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -28,7 +28,7 @@ $.effects.drop = function(o) { $.effects.createWrapper(el); // Create Wrapper var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; - var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2); + var distance = o.options.distance || (ref == 'top' ? el.outerHeight( true ) / 2 : el.outerWidth( true ) / 2); if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift // Animation diff --git a/resources/jquery.effects/jquery.effects.explode.js b/resources/jquery.effects/jquery.effects.explode.js index 2c12fdb4..1caeca86 100644 --- a/resources/jquery.effects/jquery.effects.explode.js +++ b/resources/jquery.effects/jquery.effects.explode.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects Explode 1.8.17 +/*! + * jQuery UI Effects Explode 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.effects/jquery.effects.fade.js b/resources/jquery.effects/jquery.effects.fade.js index bae63661..61249798 100644 --- a/resources/jquery.effects/jquery.effects.fade.js +++ b/resources/jquery.effects/jquery.effects.fade.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects Fade 1.8.17 +/*! + * jQuery UI Effects Fade 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.effects/jquery.effects.fold.js b/resources/jquery.effects/jquery.effects.fold.js index 8e732739..81b15b83 100644 --- a/resources/jquery.effects/jquery.effects.fold.js +++ b/resources/jquery.effects/jquery.effects.fold.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects Fold 1.8.17 +/*! + * jQuery UI Effects Fold 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.effects/jquery.effects.highlight.js b/resources/jquery.effects/jquery.effects.highlight.js index 306d515b..dee0639f 100644 --- a/resources/jquery.effects/jquery.effects.highlight.js +++ b/resources/jquery.effects/jquery.effects.highlight.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects Highlight 1.8.17 +/*! + * jQuery UI Effects Highlight 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.effects/jquery.effects.pulsate.js b/resources/jquery.effects/jquery.effects.pulsate.js index 766690fb..45cdc884 100644 --- a/resources/jquery.effects/jquery.effects.pulsate.js +++ b/resources/jquery.effects/jquery.effects.pulsate.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects Pulsate 1.8.17 +/*! + * jQuery UI Effects Pulsate 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -15,8 +15,8 @@ $.effects.pulsate = function(o) { return this.queue(function() { var elem = $(this), - mode = $.effects.setMode(elem, o.options.mode || 'show'); - times = ((o.options.times || 5) * 2) - 1; + mode = $.effects.setMode(elem, o.options.mode || 'show'), + times = ((o.options.times || 5) * 2) - 1, duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2, isVisible = elem.is(':visible'), animateTo = 0; diff --git a/resources/jquery.effects/jquery.effects.scale.js b/resources/jquery.effects/jquery.effects.scale.js index 4cb73822..44ecee18 100644 --- a/resources/jquery.effects/jquery.effects.scale.js +++ b/resources/jquery.effects/jquery.effects.scale.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects Scale 1.8.17 +/*! + * jQuery UI Effects Scale 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -140,7 +140,7 @@ $.effects.size = function(o) { hProps = hProps.concat(['marginLeft','marginRight']); // Add margins props2 = props.concat(vProps).concat(hProps); // Concat el.find("*[width]").each(function(){ - child = $(this); + var child = $(this); if (restore) $.effects.save(child, props2); var c_original = {height: child.height(), width: child.width()}; // Save original child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x}; diff --git a/resources/jquery.effects/jquery.effects.shake.js b/resources/jquery.effects/jquery.effects.shake.js index b5a7352e..bc1fd191 100644 --- a/resources/jquery.effects/jquery.effects.shake.js +++ b/resources/jquery.effects/jquery.effects.shake.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects Shake 1.8.17 +/*! + * jQuery UI Effects Shake 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.effects/jquery.effects.slide.js b/resources/jquery.effects/jquery.effects.slide.js index e41869b9..0a430278 100644 --- a/resources/jquery.effects/jquery.effects.slide.js +++ b/resources/jquery.effects/jquery.effects.slide.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects Slide 1.8.17 +/*! + * jQuery UI Effects Slide 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -28,7 +28,7 @@ $.effects.slide = function(o) { $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; - var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true})); + var distance = o.options.distance || (ref == 'top' ? el.outerHeight( true ) : el.outerWidth( true )); if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift // Animation diff --git a/resources/jquery.effects/jquery.effects.transfer.js b/resources/jquery.effects/jquery.effects.transfer.js index d51b9c43..64f2a17b 100644 --- a/resources/jquery.effects/jquery.effects.transfer.js +++ b/resources/jquery.effects/jquery.effects.transfer.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Effects Transfer 1.8.17 +/*! + * jQuery UI Effects Transfer 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.tipsy/images/tipsy.png b/resources/jquery.tipsy/images/tipsy.png Binary files differindex 9a80e942..fef8c4b5 100644 --- a/resources/jquery.tipsy/images/tipsy.png +++ b/resources/jquery.tipsy/images/tipsy.png diff --git a/resources/jquery.ui/i18n/jquery.ui.datepicker-ar.js b/resources/jquery.ui/i18n/jquery.ui.datepicker-ar.js index 743a15db..8a9218d8 100644 --- a/resources/jquery.ui/i18n/jquery.ui.datepicker-ar.js +++ b/resources/jquery.ui/i18n/jquery.ui.datepicker-ar.js @@ -12,7 +12,7 @@ jQuery(function($){ monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], - dayNamesMin: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'], weekHeader: 'أسبوع', dateFormat: 'dd/mm/yy', firstDay: 6, diff --git a/resources/jquery.ui/i18n/jquery.ui.datepicker-de.js b/resources/jquery.ui/i18n/jquery.ui.datepicker-de.js index 166f5371..f3ef9e82 100644 --- a/resources/jquery.ui/i18n/jquery.ui.datepicker-de.js +++ b/resources/jquery.ui/i18n/jquery.ui.datepicker-de.js @@ -13,7 +13,7 @@ jQuery(function($){ dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'], dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'], - weekHeader: 'Wo', + weekHeader: 'KW', dateFormat: 'dd.mm.yy', firstDay: 1, isRTL: false, diff --git a/resources/jquery.ui/i18n/jquery.ui.datepicker-et.js b/resources/jquery.ui/i18n/jquery.ui.datepicker-et.js index 92f81f63..32702b24 100644 --- a/resources/jquery.ui/i18n/jquery.ui.datepicker-et.js +++ b/resources/jquery.ui/i18n/jquery.ui.datepicker-et.js @@ -13,7 +13,7 @@ jQuery(function($){ dayNames: ['Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'], dayNamesShort: ['Pühap', 'Esmasp', 'Teisip', 'Kolmap', 'Neljap', 'Reede', 'Laup'], dayNamesMin: ['P','E','T','K','N','R','L'], - weekHeader: 'Sm', + weekHeader: 'näd', dateFormat: 'dd.mm.yy', firstDay: 1, isRTL: false, diff --git a/resources/jquery.ui/i18n/jquery.ui.datepicker-eu.js b/resources/jquery.ui/i18n/jquery.ui.datepicker-eu.js index bee4bfba..ff66e494 100644 --- a/resources/jquery.ui/i18n/jquery.ui.datepicker-eu.js +++ b/resources/jquery.ui/i18n/jquery.ui.datepicker-eu.js @@ -6,15 +6,15 @@ jQuery(function($){ prevText: '<Aur', nextText: 'Hur>', currentText: 'Gaur', - monthNames: ['Urtarrila','Otsaila','Martxoa','Apirila','Maiatza','Ekaina', - 'Uztaila','Abuztua','Iraila','Urria','Azaroa','Abendua'], - monthNamesShort: ['Urt','Ots','Mar','Api','Mai','Eka', - 'Uzt','Abu','Ira','Urr','Aza','Abe'], - dayNames: ['Igandea','Astelehena','Asteartea','Asteazkena','Osteguna','Ostirala','Larunbata'], - dayNamesShort: ['Iga','Ast','Ast','Ast','Ost','Ost','Lar'], - dayNamesMin: ['Ig','As','As','As','Os','Os','La'], - weekHeader: 'Wk', - dateFormat: 'yy/mm/dd', + monthNames: ['urtarrila','otsaila','martxoa','apirila','maiatza','ekaina', + 'uztaila','abuztua','iraila','urria','azaroa','abendua'], + monthNamesShort: ['urt.','ots.','mar.','api.','mai.','eka.', + 'uzt.','abu.','ira.','urr.','aza.','abe.'], + dayNames: ['igandea','astelehena','asteartea','asteazkena','osteguna','ostirala','larunbata'], + dayNamesShort: ['ig.','al.','ar.','az.','og.','ol.','lr.'], + dayNamesMin: ['ig','al','ar','az','og','ol','lr'], + weekHeader: 'As', + dateFormat: 'yy-mm-dd', firstDay: 1, isRTL: false, showMonthAfterYear: false, diff --git a/resources/jquery.ui/i18n/jquery.ui.datepicker-fa.js b/resources/jquery.ui/i18n/jquery.ui.datepicker-fa.js index 81de4da4..be8acd2a 100644 --- a/resources/jquery.ui/i18n/jquery.ui.datepicker-fa.js +++ b/resources/jquery.ui/i18n/jquery.ui.datepicker-fa.js @@ -4,15 +4,51 @@ jQuery(function($) { $.datepicker.regional['fa'] = { closeText: 'بستن', - prevText: '<قبلي', - nextText: 'بعدي>', + prevText: '<قبلی', + nextText: 'بعدی>', currentText: 'امروز', - monthNames: ['فروردين','ارديبهشت','خرداد','تير','مرداد','شهريور', - 'مهر','آبان','آذر','دي','بهمن','اسفند'], + monthNames: [ + 'فروردين', + 'ارديبهشت', + 'خرداد', + 'تير', + 'مرداد', + 'شهريور', + 'مهر', + 'آبان', + 'آذر', + 'دی', + 'بهمن', + 'اسفند' + ], monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'], - dayNames: ['يکشنبه','دوشنبه','سهشنبه','چهارشنبه','پنجشنبه','جمعه','شنبه'], - dayNamesShort: ['ي','د','س','چ','پ','ج', 'ش'], - dayNamesMin: ['ي','د','س','چ','پ','ج', 'ش'], + dayNames: [ + 'يکشنبه', + 'دوشنبه', + 'سهشنبه', + 'چهارشنبه', + 'پنجشنبه', + 'جمعه', + 'شنبه' + ], + dayNamesShort: [ + 'ی', + 'د', + 'س', + 'چ', + 'پ', + 'ج', + 'ش' + ], + dayNamesMin: [ + 'ی', + 'د', + 'س', + 'چ', + 'پ', + 'ج', + 'ش' + ], weekHeader: 'هف', dateFormat: 'yy/mm/dd', firstDay: 6, diff --git a/resources/jquery.ui/i18n/jquery.ui.datepicker-fi.js b/resources/jquery.ui/i18n/jquery.ui.datepicker-fi.js index e1f25fd8..4c5adda3 100644 --- a/resources/jquery.ui/i18n/jquery.ui.datepicker-fi.js +++ b/resources/jquery.ui/i18n/jquery.ui.datepicker-fi.js @@ -1,23 +1,23 @@ /* Finnish initialisation for the jQuery UI date picker plugin. */ -/* Written by Harri Kilpi� (harrikilpio@gmail.com). */ +/* Written by Harri Kilpiö (harrikilpio@gmail.com). */ jQuery(function($){ - $.datepicker.regional['fi'] = { + $.datepicker.regional['fi'] = { closeText: 'Sulje', - prevText: '«Edellinen', - nextText: 'Seuraava»', - currentText: 'Tänään', - monthNames: ['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kesäkuu', - 'Heinäkuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu'], - monthNamesShort: ['Tammi','Helmi','Maalis','Huhti','Touko','Kesä', - 'Heinä','Elo','Syys','Loka','Marras','Joulu'], - dayNamesShort: ['Su','Ma','Ti','Ke','To','Pe','Su'], + prevText: '«Edellinen', + nextText: 'Seuraava»', + currentText: 'Tänään', + monthNames: ['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kesäkuu', + 'Heinäkuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu'], + monthNamesShort: ['Tammi','Helmi','Maalis','Huhti','Touko','Kesä', + 'Heinä','Elo','Syys','Loka','Marras','Joulu'], + dayNamesShort: ['Su','Ma','Ti','Ke','To','Pe','La'], dayNames: ['Sunnuntai','Maanantai','Tiistai','Keskiviikko','Torstai','Perjantai','Lauantai'], dayNamesMin: ['Su','Ma','Ti','Ke','To','Pe','La'], weekHeader: 'Vk', - dateFormat: 'dd.mm.yy', + dateFormat: 'dd.mm.yy', firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['fi']); + $.datepicker.setDefaults($.datepicker.regional['fi']); }); diff --git a/resources/jquery.ui/i18n/jquery.ui.datepicker-fr-CH.js b/resources/jquery.ui/i18n/jquery.ui.datepicker-fr-CH.js deleted file mode 100644 index 244eacff..00000000 --- a/resources/jquery.ui/i18n/jquery.ui.datepicker-fr-CH.js +++ /dev/null @@ -1,23 +0,0 @@ -/* Swiss-French initialisation for the jQuery UI date picker plugin. */ -/* Written Martin Voelkle (martin.voelkle@e-tc.ch). */ -jQuery(function($){ - $.datepicker.regional['fr-CH'] = { - closeText: 'Fermer', - prevText: '<Préc', - nextText: 'Suiv>', - currentText: 'Courant', - monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', - 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], - monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun', - 'Jul','Aoû','Sep','Oct','Nov','Déc'], - dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], - dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'], - dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'], - weekHeader: 'Sm', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['fr-CH']); -});
\ No newline at end of file diff --git a/resources/jquery.ui/i18n/jquery.ui.datepicker-he.js b/resources/jquery.ui/i18n/jquery.ui.datepicker-he.js index 88a78668..135cdec1 100644 --- a/resources/jquery.ui/i18n/jquery.ui.datepicker-he.js +++ b/resources/jquery.ui/i18n/jquery.ui.datepicker-he.js @@ -8,8 +8,8 @@ jQuery(function($){ currentText: 'היום', monthNames: ['ינואר','פברואר','מרץ','אפריל','מאי','יוני', 'יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'], - monthNamesShort: ['1','2','3','4','5','6', - '7','8','9','10','11','12'], + monthNamesShort: ['ינו','פבר','מרץ','אפר','מאי','יוני', + 'יולי','אוג','ספט','אוק','נוב','דצמ'], dayNames: ['ראשון','שני','שלישי','רביעי','חמישי','שישי','שבת'], dayNamesShort: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], dayNamesMin: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], diff --git a/resources/jquery.ui/i18n/jquery.ui.datepicker-hi.js b/resources/jquery.ui/i18n/jquery.ui.datepicker-hi.js new file mode 100644 index 00000000..6c563b99 --- /dev/null +++ b/resources/jquery.ui/i18n/jquery.ui.datepicker-hi.js @@ -0,0 +1,23 @@ +/* Hindi initialisation for the jQuery UI date picker plugin. */ +/* Written by Michael Dawart. */ +jQuery(function($){ + $.datepicker.regional['hi'] = { + closeText: 'बंद', + prevText: 'पिछला', + nextText: 'अगला', + currentText: 'आज', + monthNames: ['जनवरी ','फरवरी','मार्च','अप्रेल','मई','जून', + 'जूलाई','अगस्त ','सितम्बर','अक्टूबर','नवम्बर','दिसम्बर'], + monthNamesShort: ['जन', 'फर', 'मार्च', 'अप्रेल', 'मई', 'जून', + 'जूलाई', 'अग', 'सित', 'अक्ट', 'नव', 'दि'], + dayNames: ['रविवार', 'सोमवार', 'मंगलवार', 'बुधवार', 'गुरुवार', 'शुक्रवार', 'शनिवार'], + dayNamesShort: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], + dayNamesMin: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], + weekHeader: 'हफ्ता', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hi']); +}); diff --git a/resources/jquery.ui/i18n/jquery.ui.datepicker-ka.js b/resources/jquery.ui/i18n/jquery.ui.datepicker-ka.js new file mode 100644 index 00000000..c10658d7 --- /dev/null +++ b/resources/jquery.ui/i18n/jquery.ui.datepicker-ka.js @@ -0,0 +1,21 @@ +/* Georgian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Lado Lomidze (lado.lomidze@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ka'] = { + closeText: 'დახურვა', + prevText: '< წინა', + nextText: 'შემდეგი >', + currentText: 'დღეს', + monthNames: ['იანვარი','თებერვალი','მარტი','აპრილი','მაისი','ივნისი', 'ივლისი','აგვისტო','სექტემბერი','ოქტომბერი','ნოემბერი','დეკემბერი'], + monthNamesShort: ['იან','თებ','მარ','აპრ','მაი','ივნ', 'ივლ','აგვ','სექ','ოქტ','ნოე','დეკ'], + dayNames: ['კვირა','ორშაბათი','სამშაბათი','ოთხშაბათი','ხუთშაბათი','პარასკევი','შაბათი'], + dayNamesShort: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], + dayNamesMin: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], + weekHeader: 'კვირა', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ka']); +}); diff --git a/resources/jquery.ui/i18n/jquery.ui.datepicker-km.js b/resources/jquery.ui/i18n/jquery.ui.datepicker-km.js new file mode 100644 index 00000000..f9c4e3a0 --- /dev/null +++ b/resources/jquery.ui/i18n/jquery.ui.datepicker-km.js @@ -0,0 +1,23 @@ +/* Khmer initialisation for the jQuery calendar extension. */ +/* Written by Chandara Om (chandara.teacher@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['km'] = { + closeText: 'ធ្វើរួច', + prevText: 'មុន', + nextText: 'បន្ទាប់', + currentText: 'ថ្ងៃនេះ', + monthNames: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', + 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], + monthNamesShort: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', + 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], + dayNames: ['អាទិត្យ', 'ចន្ទ', 'អង្គារ', 'ពុធ', 'ព្រហស្បតិ៍', 'សុក្រ', 'សៅរ៍'], + dayNamesShort: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], + dayNamesMin: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], + weekHeader: 'សប្ដាហ៍', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['km']); +}); diff --git a/resources/jquery.ui/i18n/jquery.ui.datepicker-ko.js b/resources/jquery.ui/i18n/jquery.ui.datepicker-ko.js index 5b353165..04112424 100644 --- a/resources/jquery.ui/i18n/jquery.ui.datepicker-ko.js +++ b/resources/jquery.ui/i18n/jquery.ui.datepicker-ko.js @@ -1,23 +1,23 @@ /* Korean initialisation for the jQuery calendar extension. */ -/* Written by DaeKwon Kang (ncrash.dk@gmail.com). */ +/* Written by DaeKwon Kang (ncrash.dk@gmail.com), Edited by Genie. */ jQuery(function($){ $.datepicker.regional['ko'] = { closeText: '닫기', prevText: '이전달', nextText: '다음달', currentText: '오늘', - monthNames: ['1월(JAN)','2월(FEB)','3월(MAR)','4월(APR)','5월(MAY)','6월(JUN)', - '7월(JUL)','8월(AUG)','9월(SEP)','10월(OCT)','11월(NOV)','12월(DEC)'], - monthNamesShort: ['1월(JAN)','2월(FEB)','3월(MAR)','4월(APR)','5월(MAY)','6월(JUN)', - '7월(JUL)','8월(AUG)','9월(SEP)','10월(OCT)','11월(NOV)','12월(DEC)'], - dayNames: ['일','월','화','수','목','금','토'], + monthNames: ['1월','2월','3월','4월','5월','6월', + '7월','8월','9월','10월','11월','12월'], + monthNamesShort: ['1월','2월','3월','4월','5월','6월', + '7월','8월','9월','10월','11월','12월'], + dayNames: ['일요일','월요일','화요일','수요일','목요일','금요일','토요일'], dayNamesShort: ['일','월','화','수','목','금','토'], dayNamesMin: ['일','월','화','수','목','금','토'], weekHeader: 'Wk', dateFormat: 'yy-mm-dd', firstDay: 0, isRTL: false, - showMonthAfterYear: false, + showMonthAfterYear: true, yearSuffix: '년'}; $.datepicker.setDefaults($.datepicker.regional['ko']); });
\ No newline at end of file diff --git a/resources/jquery.ui/i18n/jquery.ui.datepicker-mk.js b/resources/jquery.ui/i18n/jquery.ui.datepicker-mk.js index 554ad20b..02853255 100644 --- a/resources/jquery.ui/i18n/jquery.ui.datepicker-mk.js +++ b/resources/jquery.ui/i18n/jquery.ui.datepicker-mk.js @@ -6,15 +6,15 @@ jQuery(function($){ prevText: '<', nextText: '>', currentText: 'Денес', - monthNames: ['Јануари','Фебруари','Март','Април','Мај','Јуни', + monthNames: ['Јануари','Февруари','Март','Април','Мај','Јуни', 'Јули','Август','Септември','Октомври','Ноември','Декември'], - monthNamesShort: ['Јан','Феб','Мар','Апр','Мај','Јун', + monthNamesShort: ['Јан','Фев','Мар','Апр','Мај','Јун', 'Јул','Авг','Сеп','Окт','Ное','Дек'], dayNames: ['Недела','Понеделник','Вторник','Среда','Четврток','Петок','Сабота'], dayNamesShort: ['Нед','Пон','Вто','Сре','Чет','Пет','Саб'], dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Са'], weekHeader: 'Сед', - dateFormat: 'dd/mm/yy', + dateFormat: 'dd.mm.yy', firstDay: 1, isRTL: false, showMonthAfterYear: false, diff --git a/resources/jquery.ui/jquery.ui.accordion.js b/resources/jquery.ui/jquery.ui.accordion.js index 8fa8c0b8..b3340e09 100644 --- a/resources/jquery.ui/jquery.ui.accordion.js +++ b/resources/jquery.ui/jquery.ui.accordion.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Accordion 1.8.17 +/*! + * jQuery UI Accordion 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -518,7 +518,7 @@ $.widget( "ui.accordion", { }); $.extend( $.ui.accordion, { - version: "1.8.17", + version: "1.8.23", animations: { slide: function( options, additions ) { options = $.extend({ diff --git a/resources/jquery.ui/jquery.ui.autocomplete.js b/resources/jquery.ui/jquery.ui.autocomplete.js index 48ede20b..b634cce5 100644 --- a/resources/jquery.ui/jquery.ui.autocomplete.js +++ b/resources/jquery.ui/jquery.ui.autocomplete.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Autocomplete 1.8.17 +/*! + * jQuery UI Autocomplete 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -37,6 +37,7 @@ $.widget( "ui.autocomplete", { var self = this, doc = this.element[ 0 ].ownerDocument, suppressKeyPress; + this.isMultiLine = this.element.is( "textarea" ); this.element .addClass( "ui-autocomplete-input" ) @@ -62,14 +63,10 @@ $.widget( "ui.autocomplete", { self._move( "nextPage", event ); break; case keyCode.UP: - self._move( "previous", event ); - // prevent moving cursor to beginning of text field in some browsers - event.preventDefault(); + self._keyEvent( "previous", event ); break; case keyCode.DOWN: - self._move( "next", event ); - // prevent moving cursor to end of text field in some browsers - event.preventDefault(); + self._keyEvent( "next", event ); break; case keyCode.ENTER: case keyCode.NUMPAD_ENTER: @@ -131,9 +128,6 @@ $.widget( "ui.autocomplete", { }, 150 ); }); this._initSource(); - this.response = function() { - return self._response.apply( self, arguments ); - }; this.menu = $( "<ul></ul>" ) .addClass( "ui-autocomplete" ) .appendTo( $( this.options.appendTo || "body", doc )[0] ) @@ -268,16 +262,11 @@ $.widget( "ui.autocomplete", { url: url, data: request, dataType: "json", - autocompleteRequest: ++requestIndex, success: function( data, status ) { - if ( this.autocompleteRequest === requestIndex ) { - response( data ); - } + response( data ); }, error: function() { - if ( this.autocompleteRequest === requestIndex ) { - response( [] ); - } + response( [] ); } }); }; @@ -308,10 +297,26 @@ $.widget( "ui.autocomplete", { this.pending++; this.element.addClass( "ui-autocomplete-loading" ); - this.source( { term: value }, this.response ); + this.source( { term: value }, this._response() ); + }, + + _response: function() { + var that = this, + index = ++requestIndex; + + return function( content ) { + if ( index === requestIndex ) { + that.__response( content ); + } + + that.pending--; + if ( !that.pending ) { + that.element.removeClass( "ui-autocomplete-loading" ); + } + }; }, - _response: function( content ) { + __response: function( content ) { if ( !this.options.disabled && content && content.length ) { content = this._normalize( content ); this._suggest( content ); @@ -319,10 +324,6 @@ $.widget( "ui.autocomplete", { } else { this.close(); } - this.pending--; - if ( !this.pending ) { - this.element.removeClass( "ui-autocomplete-loading" ); - } }, close: function( event ) { @@ -420,6 +421,14 @@ $.widget( "ui.autocomplete", { widget: function() { return this.menu.element; + }, + _keyEvent: function( keyEvent, event ) { + if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { + this._move( keyEvent, event ); + + // prevents moving cursor to beginning/end of the text field in some browsers + event.preventDefault(); + } } }); @@ -592,7 +601,7 @@ $.widget("ui.menu", { } var base = this.active.offset().top, - height = this.element.height(); + height = this.element.height(), result = this.element.children(".ui-menu-item").filter(function() { var close = $(this).offset().top - base + height - $(this).height(); // TODO improve approximation diff --git a/resources/jquery.ui/jquery.ui.button.js b/resources/jquery.ui/jquery.ui.button.js index 94dce1c3..db2637e8 100644 --- a/resources/jquery.ui/jquery.ui.button.js +++ b/resources/jquery.ui/jquery.ui.button.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Button 1.8.17 +/*! + * jQuery UI Button 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -56,7 +56,9 @@ $.widget( "ui.button", { .bind( "reset.button", formResetHandler ); if ( typeof this.options.disabled !== "boolean" ) { - this.options.disabled = this.element.propAttr( "disabled" ); + this.options.disabled = !!this.element.propAttr( "disabled" ); + } else { + this.element.propAttr( "disabled", this.options.disabled ); } this._determineButtonType(); @@ -72,10 +74,6 @@ $.widget( "ui.button", { options.label = this.buttonElement.html(); } - if ( this.element.is( ":disabled" ) ) { - options.disabled = true; - } - this.buttonElement .addClass( baseClasses ) .attr( "role", "button" ) diff --git a/resources/jquery.ui/jquery.ui.core.js b/resources/jquery.ui/jquery.ui.core.js index 6d82ff13..1285a6dd 100644 --- a/resources/jquery.ui/jquery.ui.core.js +++ b/resources/jquery.ui/jquery.ui.core.js @@ -1,7 +1,7 @@ /*! - * jQuery UI 1.8.17 + * jQuery UI 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -18,7 +18,7 @@ if ( $.ui.version ) { } $.extend( $.ui, { - version: "1.8.17", + version: "1.8.23", keyCode: { ALT: 18, @@ -131,49 +131,52 @@ $.fn.extend({ } }); -$.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 - }; +// 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( $.curCSS( elem, "padding" + this, true) ) || 0; + if ( border ) { + size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0; + } + if ( margin ) { + size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0; + } + }); + return size; + } - function reduce( elem, size, border, margin ) { - $.each( side, function() { - size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0; - if ( border ) { - size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0; - } - if ( margin ) { - size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0; + $.fn[ "inner" + name ] = function( size ) { + if ( size === undefined ) { + return orig[ "inner" + name ].call( this ); } - }); - 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" ); - }); - }; + 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 ); - } + $.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" ); - }); - }; -}); + return this.each(function() { + $( this).css( type, reduce( this, size, true, margin ) + "px" ); + }); + }; + }); +} // selectors function focusable( element, isTabIndexNotNaN ) { @@ -205,9 +208,16 @@ function visible( element ) { } $.extend( $.expr[ ":" ], { - data: function( elem, i, match ) { - return !!$.data( elem, match[ 3 ] ); - }, + data: $.expr.createPseudo ? + $.expr.createPseudo(function( dataName ) { + return function( elem ) { + return !!$.data( elem, dataName ); + }; + }) : + // support: jQuery <1.8 + function( elem, i, match ) { + return !!$.data( elem, match[ 3 ] ); + }, focusable: function( element ) { return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); @@ -225,6 +235,11 @@ $(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 elemnt to continue to take up space even + // after it is removed from the DOM (#8026) + div.offsetHeight; + $.extend( div.style, { minHeight: "100px", height: "auto", @@ -240,6 +255,11 @@ $(function() { body.removeChild( div ).style.display = "none"; }); +// jQuery <1.4.3 uses curCSS, in 1.4.3 - 1.7.2 curCSS = css, 1.8+ only has css +if ( !$.curCSS ) { + $.curCSS = $.css; +} + diff --git a/resources/jquery.ui/jquery.ui.datepicker.js b/resources/jquery.ui/jquery.ui.datepicker.js index bbf59175..7ea5b079 100644 --- a/resources/jquery.ui/jquery.ui.datepicker.js +++ b/resources/jquery.ui/jquery.ui.datepicker.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Datepicker 1.8.17 +/*! + * jQuery UI Datepicker 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -12,7 +12,7 @@ */ (function( $, undefined ) { -$.extend($.ui, { datepicker: { version: "1.8.17" } }); +$.extend($.ui, { datepicker: { version: "1.8.23" } }); var PROP_NAME = 'datepicker'; var dpuuid = new Date().getTime(); @@ -233,7 +233,10 @@ $.extend(Datepicker.prototype, { inst.trigger.click(function() { if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0]) $.datepicker._hideDatepicker(); - else + else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) { + $.datepicker._hideDatepicker(); + $.datepicker._showDatepicker(input[0]); + } else $.datepicker._showDatepicker(input[0]); return false; }); @@ -305,7 +308,7 @@ $.extend(Datepicker.prototype, { this.uuid += 1; var id = 'dp' + this.uuid; this._dialogInput = $('<input type="text" id="' + id + - '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>'); + '" style="position: absolute; top: -100px; width: 0px;"/>'); this._dialogInput.keydown(this._doKeyDown); $('body').append(this._dialogInput); inst = this._dialogInst = this._newInst(this._dialogInput, false); @@ -617,8 +620,8 @@ $.extend(Datepicker.prototype, { $.datepicker._updateDatepicker(inst); } } - catch (event) { - $.datepicker.log(event); + catch (err) { + $.datepicker.log(err); } } return true; @@ -711,6 +714,7 @@ $.extend(Datepicker.prototype, { 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()}) @@ -761,8 +765,8 @@ $.extend(Datepicker.prototype, { var dpHeight = inst.dpDiv.outerHeight(); var inputWidth = inst.input ? inst.input.outerWidth() : 0; var inputHeight = inst.input ? inst.input.outerHeight() : 0; - var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft(); - var viewHeight = document.documentElement.clientHeight + $(document).scrollTop(); + var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()); + var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0); offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0; @@ -797,10 +801,8 @@ $.extend(Datepicker.prototype, { if (this._datepickerShowing) { var showAnim = this._get(inst, 'showAnim'); var duration = this._get(inst, 'duration'); - var self = this; var postProcess = function() { $.datepicker._tidyDialog(inst); - self._curInst = null; }; if ($.effects && $.effects[showAnim]) inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); @@ -842,7 +844,7 @@ $.extend(Datepicker.prototype, { if ( ( ( $target[0].id != $.datepicker._mainDivId && $target.parents('#' + $.datepicker._mainDivId).length == 0 && !$target.hasClass($.datepicker.markerClassName) && - !$target.hasClass($.datepicker._triggerClass) && + !$target.closest("." + $.datepicker._triggerClass).length && $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) ) $.datepicker._hideDatepicker(); @@ -1401,6 +1403,43 @@ $.extend(Datepicker.prototype, { return startDate; }, + /* Attach the onxxx handlers. These are declared statically so + * they work with static code transformers like Caja. + */ + _attachHandlers: function(inst) { + var stepMonths = this._get(inst, 'stepMonths'); + var id = '#' + inst.id.replace( /\\\\/g, "\\" ); + inst.dpDiv.find('[data-handler]').map(function () { + var handler = { + prev: function () { + window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M'); + }, + next: function () { + window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M'); + }, + hide: function () { + window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker(); + }, + today: function () { + window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id); + }, + selectDay: function () { + window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this); + return false; + }, + selectMonth: function () { + window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M'); + return false; + }, + selectYear: function () { + window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y'); + return false; + } + }; + $(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(); @@ -1443,8 +1482,7 @@ $.extend(Datepicker.prototype, { this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), this._getFormatConfig(inst))); var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? - '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid + - '.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' + + '<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' + ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' : (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>')); var nextText = this._get(inst, 'nextText'); @@ -1452,19 +1490,17 @@ $.extend(Datepicker.prototype, { this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), this._getFormatConfig(inst))); var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? - '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid + - '.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' + + '<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' + ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' : (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>')); var currentText = this._get(inst, 'currentText'); var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); currentText = (!navigationAsDateFormat ? currentText : this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); - var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid + - '.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : ''); + var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">' + + this._get(inst, 'closeText') + '</button>' : ''); var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') + - (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid + - '.datepicker._gotoToday(\'#' + inst.id + '\');"' + + (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" data-handler="today" data-event="click"' + '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : ''; var firstDay = parseInt(this._get(inst, 'firstDay'),10); firstDay = (isNaN(firstDay) ? 0 : firstDay); @@ -1543,8 +1579,7 @@ $.extend(Datepicker.prototype, { (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different) ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title - (unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' + - inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions + (unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions (otherMonth && !showOtherMonths ? ' ' : // display for other months (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' + (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') + @@ -1587,9 +1622,7 @@ $.extend(Datepicker.prototype, { else { var inMinYear = (minDate && minDate.getFullYear() == drawYear); var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); - monthHtml += '<select class="ui-datepicker-month" ' + - 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' + - '>'; + monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">'; for (var month = 0; month < 12; month++) { if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) @@ -1620,9 +1653,7 @@ $.extend(Datepicker.prototype, { var endYear = Math.max(year, determineYear(years[1] || '')); year = (minDate ? Math.max(year, minDate.getFullYear()) : year); endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); - inst.yearshtml += '<select class="ui-datepicker-year" ' + - 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' + - '>'; + inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">'; for (; year <= endYear; year++) { inst.yearshtml += '<option value="' + year + '"' + (year == drawYear ? ' selected="selected"' : '') + @@ -1814,7 +1845,7 @@ $.fn.datepicker = function(options){ $.datepicker = new Datepicker(); // singleton instance $.datepicker.initialized = false; $.datepicker.uuid = new Date().getTime(); -$.datepicker.version = "1.8.17"; +$.datepicker.version = "1.8.23"; // Workaround for #4055 // Add another global to avoid noConflict issues with inline event handlers diff --git a/resources/jquery.ui/jquery.ui.dialog.js b/resources/jquery.ui/jquery.ui.dialog.js index 33119af2..082bf2c0 100644 --- a/resources/jquery.ui/jquery.ui.dialog.js +++ b/resources/jquery.ui/jquery.ui.dialog.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Dialog 1.8.17 +/*! + * jQuery UI Dialog 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -37,18 +37,6 @@ var uiDialogClasses = maxWidth: true, minHeight: true, minWidth: true - }, - // support for jQuery 1.3.2 - handle common attrFn methods for dialog - attrFn = $.attrFn || { - val: true, - css: true, - html: true, - text: true, - data: true, - width: true, - height: true, - offset: true, - click: true }; $.widget("ui.dialog", { @@ -397,7 +385,7 @@ $.widget("ui.dialog", { if ( key === "click" ) { return; } - if ( key in attrFn ) { + if ( key in button ) { button[ key ]( value ); } else { button.attr( key, value ); @@ -702,7 +690,7 @@ $.widget("ui.dialog", { }); $.extend($.ui.dialog, { - version: "1.8.17", + version: "1.8.23", uuid: 0, maxZ: 0, diff --git a/resources/jquery.ui/jquery.ui.draggable.js b/resources/jquery.ui/jquery.ui.draggable.js index 41aba9d6..6da1aafe 100644 --- a/resources/jquery.ui/jquery.ui.draggable.js +++ b/resources/jquery.ui/jquery.ui.draggable.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Draggable 1.8.17 +/*! + * jQuery UI Draggable 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -103,6 +103,8 @@ $.widget("ui.draggable", $.ui.mouse, { //Create and append the visible helper this.helper = this._createHelper(event); + this.helper.addClass("ui-draggable-dragging"); + //Cache the helper size this._cacheHelperProportions(); @@ -163,7 +165,7 @@ $.widget("ui.draggable", $.ui.mouse, { if ($.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, event); - this.helper.addClass("ui-draggable-dragging"); + this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) @@ -208,8 +210,14 @@ $.widget("ui.draggable", $.ui.mouse, { this.dropped = false; } - //if the original element is removed, don't bother to continue if helper is set to "original" - if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original") + //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) ) { + if (element == document ) { + elementInDom = true; + } + } + if ( !elementInDom && this.options.helper === "original" ) return false; if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { @@ -505,7 +513,7 @@ $.widget("ui.draggable", $.ui.mouse, { }); $.extend($.ui.draggable, { - version: "1.8.17" + version: "1.8.23" }); $.ui.plugin.add("draggable", "connectToSortable", { diff --git a/resources/jquery.ui/jquery.ui.droppable.js b/resources/jquery.ui/jquery.ui.droppable.js index afce00aa..4b98b3ad 100644 --- a/resources/jquery.ui/jquery.ui.droppable.js +++ b/resources/jquery.ui/jquery.ui.droppable.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Droppable 1.8.17 +/*! + * jQuery UI Droppable 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -147,7 +147,7 @@ $.widget("ui.droppable", { }); $.extend($.ui.droppable, { - version: "1.8.17" + version: "1.8.23" }); $.ui.intersect = function(draggable, droppable, toleranceMode) { diff --git a/resources/jquery.ui/jquery.ui.mouse.js b/resources/jquery.ui/jquery.ui.mouse.js index 6bb65de0..e051055d 100644 --- a/resources/jquery.ui/jquery.ui.mouse.js +++ b/resources/jquery.ui/jquery.ui.mouse.js @@ -1,7 +1,7 @@ /*! - * jQuery UI Mouse 1.8.17 + * jQuery UI Mouse 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -45,6 +45,11 @@ $.widget("ui.mouse", { // other instances of mouse _mouseDestroy: function() { this.element.unbind('.'+this.widgetName); + if ( this._mouseMoveDelegate ) { + $(document) + .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) + .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); + } }, _mouseDown: function(event) { diff --git a/resources/jquery.ui/jquery.ui.position.js b/resources/jquery.ui/jquery.ui.position.js index 8eb30f62..03f2606c 100644 --- a/resources/jquery.ui/jquery.ui.position.js +++ b/resources/jquery.ui/jquery.ui.position.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Position 1.8.17 +/*! + * jQuery UI Position 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -243,7 +243,12 @@ if ( !$.offset.setOffset ) { $.fn.offset = function( options ) { var elem = this[ 0 ]; if ( !elem || !elem.ownerDocument ) { return null; } - if ( options ) { + if ( options ) { + if ( $.isFunction( options ) ) { + return this.each(function( i ) { + $( this ).offset( options.call( this, i, $( this ).offset() ) ); + }); + } return this.each(function() { $.offset.setOffset( this, options ); }); @@ -252,6 +257,11 @@ if ( !$.offset.setOffset ) { }; } +// jQuery <1.4.3 uses curCSS, in 1.4.3 - 1.7.2 curCSS = css, 1.8+ only has css +if ( !$.curCSS ) { + $.curCSS = $.css; +} + // fraction support test (older versions of jQuery don't support fractions) (function () { var body = document.getElementsByTagName( "body" )[ 0 ], @@ -269,7 +279,7 @@ if ( !$.offset.setOffset ) { background: "none" }; if ( body ) { - jQuery.extend( testElementStyle, { + $.extend( testElementStyle, { position: "absolute", left: "-1000px", top: "-1000px" diff --git a/resources/jquery.ui/jquery.ui.progressbar.js b/resources/jquery.ui/jquery.ui.progressbar.js index 27bae872..c1d9f3c2 100644 --- a/resources/jquery.ui/jquery.ui.progressbar.js +++ b/resources/jquery.ui/jquery.ui.progressbar.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Progressbar 1.8.17 +/*! + * jQuery UI Progressbar 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -103,7 +103,7 @@ $.widget( "ui.progressbar", { }); $.extend( $.ui.progressbar, { - version: "1.8.17" + version: "1.8.23" }); })( jQuery ); diff --git a/resources/jquery.ui/jquery.ui.resizable.js b/resources/jquery.ui/jquery.ui.resizable.js index 52b1fc4f..f6ce6949 100644 --- a/resources/jquery.ui/jquery.ui.resizable.js +++ b/resources/jquery.ui/jquery.ui.resizable.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Resizable 1.8.17 +/*! + * jQuery UI Resizable 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -50,10 +50,6 @@ $.widget("ui.resizable", $.ui.mouse, { //Wrap the element if it cannot hold child nodes if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { - //Opera fix for relative positioning - if (/relative/.test(this.element.css('position')) && $.browser.opera) - this.element.css({ position: 'relative', top: 'auto', left: 'auto' }); - //Create a wrapper element and set the wrapper to the new current internal element this.element.wrap( $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({ @@ -102,9 +98,8 @@ $.widget("ui.resizable", $.ui.mouse, { var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle; var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>'); - // increase zIndex of sw, se, ne, nw axis - //TODO : this modifies original option - if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex }); + // Apply zIndex to all handles - see #7960 + axis.css({ zIndex: o.zIndex }); //TODO : What's going on here? if ('se' == handle) { @@ -247,10 +242,6 @@ $.widget("ui.resizable", $.ui.mouse, { el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left }); } - //Opera fixing relative position - if ($.browser.opera && (/relative/).test(el.css('position'))) - el.css({ position: 'relative', top: 'auto', left: 'auto' }); - this._renderProxy(); var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); @@ -549,7 +540,7 @@ $.widget("ui.resizable", $.ui.mouse, { }); $.extend($.ui.resizable, { - version: "1.8.17" + version: "1.8.23" }); /* @@ -566,8 +557,7 @@ $.ui.plugin.add("resizable", "alsoResize", { var el = $(this); el.data("resizable-alsoresize", { width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), - left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10), - position: el.css('position') // to reset Opera on stop() + left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10) }); }); }; @@ -599,12 +589,6 @@ $.ui.plugin.add("resizable", "alsoResize", { style[prop] = sum || null; }); - // Opera fixing relative position - if ($.browser.opera && /relative/.test(el.css('position'))) { - self._revertToRelativePosition = true; - el.css({ position: 'absolute', top: 'auto', left: 'auto' }); - } - el.css(style); }); }; @@ -617,25 +601,6 @@ $.ui.plugin.add("resizable", "alsoResize", { }, stop: function (event, ui) { - var self = $(this).data("resizable"), o = self.options; - - var _reset = function (exp) { - $(exp).each(function() { - var el = $(this); - // reset position for Opera - no need to verify it was changed - el.css({ position: el.data("resizable-alsoresize").position }); - }); - }; - - if (self._revertToRelativePosition) { - self._revertToRelativePosition = false; - if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { - $.each(o.alsoResize, function (exp) { _reset(exp); }); - }else{ - _reset(o.alsoResize); - } - } - $(this).removeData("resizable-alsoresize"); } }); @@ -725,13 +690,13 @@ $.ui.plugin.add("resizable", "containment", { if (cp.left < (self._helper ? co.left : 0)) { self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left)); - if (pRatio) self.size.height = self.size.width / o.aspectRatio; + if (pRatio) self.size.height = self.size.width / self.aspectRatio; self.position.left = o.helper ? co.left : 0; } if (cp.top < (self._helper ? co.top : 0)) { self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top); - if (pRatio) self.size.width = self.size.height * o.aspectRatio; + if (pRatio) self.size.width = self.size.height * self.aspectRatio; self.position.top = self._helper ? co.top : 0; } diff --git a/resources/jquery.ui/jquery.ui.selectable.js b/resources/jquery.ui/jquery.ui.selectable.js index d790ac0d..ac5bf046 100644 --- a/resources/jquery.ui/jquery.ui.selectable.js +++ b/resources/jquery.ui/jquery.ui.selectable.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Selectable 1.8.17 +/*! + * jQuery UI Selectable 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -261,7 +261,7 @@ $.widget("ui.selectable", $.ui.mouse, { }); $.extend($.ui.selectable, { - version: "1.8.17" + version: "1.8.23" }); })(jQuery); diff --git a/resources/jquery.ui/jquery.ui.slider.js b/resources/jquery.ui/jquery.ui.slider.js index 53fdc42a..5ea589e6 100644 --- a/resources/jquery.ui/jquery.ui.slider.js +++ b/resources/jquery.ui/jquery.ui.slider.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Slider 1.8.17 +/*! + * jQuery UI Slider 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -115,8 +115,7 @@ $.widget( "ui.slider", $.ui.mouse, { this.handles .keydown(function( event ) { - var ret = true, - index = $( this ).data( "index.ui-slider-handle" ), + var index = $( this ).data( "index.ui-slider-handle" ), allowed, curVal, newVal, @@ -135,7 +134,7 @@ $.widget( "ui.slider", $.ui.mouse, { case $.ui.keyCode.RIGHT: case $.ui.keyCode.DOWN: case $.ui.keyCode.LEFT: - ret = false; + event.preventDefault(); if ( !self._keySliding ) { self._keySliding = true; $( this ).addClass( "ui-state-active" ); @@ -184,9 +183,6 @@ $.widget( "ui.slider", $.ui.mouse, { } self._slide( event, index, newVal ); - - return ret; - }) .keyup(function( event ) { var index = $( this ).data( "index.ui-slider-handle" ); @@ -660,7 +656,7 @@ $.widget( "ui.slider", $.ui.mouse, { }); $.extend( $.ui.slider, { - version: "1.8.17" + version: "1.8.23" }); }(jQuery)); diff --git a/resources/jquery.ui/jquery.ui.sortable.js b/resources/jquery.ui/jquery.ui.sortable.js index 26ba85f0..1d87f653 100644 --- a/resources/jquery.ui/jquery.ui.sortable.js +++ b/resources/jquery.ui/jquery.ui.sortable.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Sortable 1.8.17 +/*! + * jQuery UI Sortable 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -16,6 +16,7 @@ $.widget("ui.sortable", $.ui.mouse, { widgetEventPrefix: "sort", + ready: false, options: { appendTo: "parent", axis: false, @@ -57,10 +58,14 @@ $.widget("ui.sortable", $.ui.mouse, { //Initialize mouse events for interaction this._mouseInit(); + + //We're ready to go + this.ready = true }, destroy: function() { + $.Widget.prototype.destroy.call( this ); this.element .removeClass("ui-sortable ui-sortable-disabled"); this._mouseDestroy(); @@ -150,11 +155,6 @@ $.widget("ui.sortable", $.ui.mouse, { left: this.offset.left - this.margins.left }; - // Only after we got the offset, we can change the helper's position to absolute - // TODO: Still need to figure out a way to make relative sorting possible - this.helper.css("position", "absolute"); - this.cssPosition = this.helper.css("position"); - $.extend(this.offset, { click: { //Where the click happened, relative to the element left: event.pageX - this.offset.left, @@ -164,6 +164,11 @@ $.widget("ui.sortable", $.ui.mouse, { relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper }); + // Only after we got the offset, we can change the helper's position to absolute + // TODO: Still need to figure out a way to make relative sorting possible + this.helper.css("position", "absolute"); + this.cssPosition = this.helper.css("position"); + //Generate the original position this.originalPosition = this._generatePosition(event); this.originalPageX = event.pageX; @@ -463,8 +468,8 @@ $.widget("ui.sortable", $.ui.mouse, { _intersectsWithPointer: function(item) { - var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), - isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), + var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), + isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), isOverElement = isOverElementHeight && isOverElementWidth, verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); @@ -571,7 +576,7 @@ $.widget("ui.sortable", $.ui.mouse, { var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]]; var connectWith = this._connectWith(); - if(connectWith) { + if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down for (var i = connectWith.length - 1; i >= 0; i--){ var cur = $(connectWith[i]); for (var j = cur.length - 1; j >= 0; j--){ @@ -725,30 +730,31 @@ $.widget("ui.sortable", $.ui.mouse, { if(this.containers.length === 1) { this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); this.containers[innermostIndex].containerCache.over = 1; - } else if(this.currentContainer != this.containers[innermostIndex]) { - - //When entering a new container, we will find the item with the least distance and append our item near it - var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; - for (var j = this.items.length - 1; j >= 0; j--) { - if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; - var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top']; - if(Math.abs(cur - base) < dist) { - dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; - } - } - - if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled - return; - - this.currentContainer = this.containers[innermostIndex]; - itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); - this._trigger("change", event, this._uiHash()); - this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); - - //Update the placeholder - this.options.placeholder.update(this.currentContainer, this.placeholder); - - this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); + } else if(this.currentContainer != this.containers[innermostIndex]) { + + //When entering a new container, we will find the item with the least distance and append our item near it + var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; + for (var j = this.items.length - 1; j >= 0; j--) { + if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; + var cur = this.containers[innermostIndex].floating ? this.items[j].item.offset().left : this.items[j].item.offset().top; + if(Math.abs(cur - base) < dist) { + dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; + this.direction = (cur - base > 0) ? 'down' : 'up'; + } + } + + if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled + return; + + this.currentContainer = this.containers[innermostIndex]; + itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); + this._trigger("change", event, this._uiHash()); + this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); + + //Update the placeholder + this.options.placeholder.update(this.currentContainer, this.placeholder); + + this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); this.containers[innermostIndex].containerCache.over = 1; } @@ -1028,6 +1034,8 @@ $.widget("ui.sortable", $.ui.mouse, { for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events this._trigger("stop", event, this._uiHash()); } + + this.fromOutside = false; return false; } @@ -1070,7 +1078,7 @@ $.widget("ui.sortable", $.ui.mouse, { }); $.extend($.ui.sortable, { - version: "1.8.17" + version: "1.8.23" }); })(jQuery); diff --git a/resources/jquery.ui/jquery.ui.tabs.js b/resources/jquery.ui/jquery.ui.tabs.js index ff7938ce..de453cc3 100644 --- a/resources/jquery.ui/jquery.ui.tabs.js +++ b/resources/jquery.ui/jquery.ui.tabs.js @@ -1,7 +1,7 @@ -/* - * jQuery UI Tabs 1.8.17 +/*! + * jQuery UI Tabs 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -427,7 +427,7 @@ $.widget( "ui.tabs", { // meta-function to give users option to provide a href string instead of a numerical index. // also sanitizes numerical indexes to valid values. if ( typeof index == "string" ) { - index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) ); + index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); } return index; @@ -698,7 +698,7 @@ $.widget( "ui.tabs", { }); $.extend( $.ui.tabs, { - version: "1.8.17" + version: "1.8.23" }); /* @@ -733,7 +733,6 @@ $.extend( $.ui.tabs.prototype, { } } : function( e ) { - t = o.selected; rotate(); }); diff --git a/resources/jquery.ui/jquery.ui.widget.js b/resources/jquery.ui/jquery.ui.widget.js index facd77b3..befdcc25 100644 --- a/resources/jquery.ui/jquery.ui.widget.js +++ b/resources/jquery.ui/jquery.ui.widget.js @@ -1,7 +1,7 @@ /*! - * jQuery UI Widget 1.8.17 + * jQuery UI Widget 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.ui/themes/default/jquery.ui.accordion.css b/resources/jquery.ui/themes/default/jquery.ui.accordion.css index e426c762..1ce7d5ea 100644 --- a/resources/jquery.ui/themes/default/jquery.ui.accordion.css +++ b/resources/jquery.ui/themes/default/jquery.ui.accordion.css @@ -1,7 +1,7 @@ -/* - * jQuery UI Accordion 1.8.17 +/*! + * jQuery UI Accordion 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.ui/themes/default/jquery.ui.autocomplete.css b/resources/jquery.ui/themes/default/jquery.ui.autocomplete.css index 4613938a..a9817ceb 100644 --- a/resources/jquery.ui/themes/default/jquery.ui.autocomplete.css +++ b/resources/jquery.ui/themes/default/jquery.ui.autocomplete.css @@ -1,7 +1,7 @@ -/* - * jQuery UI Autocomplete 1.8.17 +/*! + * jQuery UI Autocomplete 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -13,7 +13,7 @@ * html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ /* - * jQuery UI Menu 1.8.17 + * jQuery UI Menu 1.8.23 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. diff --git a/resources/jquery.ui/themes/default/jquery.ui.button.css b/resources/jquery.ui/themes/default/jquery.ui.button.css index a7565af8..c1f26009 100644 --- a/resources/jquery.ui/themes/default/jquery.ui.button.css +++ b/resources/jquery.ui/themes/default/jquery.ui.button.css @@ -1,7 +1,7 @@ -/* - * jQuery UI Button 1.8.17 +/*! + * jQuery UI Button 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.ui/themes/default/jquery.ui.core.css b/resources/jquery.ui/themes/default/jquery.ui.core.css index bde176d2..c24627e7 100644 --- a/resources/jquery.ui/themes/default/jquery.ui.core.css +++ b/resources/jquery.ui/themes/default/jquery.ui.core.css @@ -1,7 +1,7 @@ -/* - * jQuery UI CSS Framework 1.8.17 +/*! + * jQuery UI CSS Framework 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.ui/themes/default/jquery.ui.datepicker.css b/resources/jquery.ui/themes/default/jquery.ui.datepicker.css index 6cb5aefc..0282eeee 100644 --- a/resources/jquery.ui/themes/default/jquery.ui.datepicker.css +++ b/resources/jquery.ui/themes/default/jquery.ui.datepicker.css @@ -1,7 +1,7 @@ -/* - * jQuery UI Datepicker 1.8.17 +/*! + * jQuery UI Datepicker 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -56,8 +56,6 @@ /* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ .ui-datepicker-cover { - display: none; /*sorry for IE5*/ - display/**/: block; /*sorry for IE5*/ position: absolute; /*must have*/ z-index: -1; /*must have*/ filter: mask(); /*must have*/ diff --git a/resources/jquery.ui/themes/default/jquery.ui.dialog.css b/resources/jquery.ui/themes/default/jquery.ui.dialog.css index a5914ff1..ba50ba5a 100644 --- a/resources/jquery.ui/themes/default/jquery.ui.dialog.css +++ b/resources/jquery.ui/themes/default/jquery.ui.dialog.css @@ -1,7 +1,7 @@ -/* - * jQuery UI Dialog 1.8.17 +/*! + * jQuery UI Dialog 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.ui/themes/default/jquery.ui.progressbar.css b/resources/jquery.ui/themes/default/jquery.ui.progressbar.css index 630fab39..c775a33a 100644 --- a/resources/jquery.ui/themes/default/jquery.ui.progressbar.css +++ b/resources/jquery.ui/themes/default/jquery.ui.progressbar.css @@ -1,7 +1,7 @@ -/* - * jQuery UI Progressbar 1.8.17 +/*! + * jQuery UI Progressbar 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.ui/themes/default/jquery.ui.resizable.css b/resources/jquery.ui/themes/default/jquery.ui.resizable.css index 582bcb31..420c4afa 100644 --- a/resources/jquery.ui/themes/default/jquery.ui.resizable.css +++ b/resources/jquery.ui/themes/default/jquery.ui.resizable.css @@ -1,14 +1,14 @@ -/* - * jQuery UI Resizable 1.8.17 +/*! + * jQuery UI Resizable 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Resizable#theming */ .ui-resizable { position: relative;} -.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } +.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; } .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } diff --git a/resources/jquery.ui/themes/default/jquery.ui.selectable.css b/resources/jquery.ui/themes/default/jquery.ui.selectable.css index b36b8988..33202748 100644 --- a/resources/jquery.ui/themes/default/jquery.ui.selectable.css +++ b/resources/jquery.ui/themes/default/jquery.ui.selectable.css @@ -1,7 +1,7 @@ -/* - * jQuery UI Selectable 1.8.17 +/*! + * jQuery UI Selectable 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.ui/themes/default/jquery.ui.slider.css b/resources/jquery.ui/themes/default/jquery.ui.slider.css index 4cc54810..650ad7e2 100644 --- a/resources/jquery.ui/themes/default/jquery.ui.slider.css +++ b/resources/jquery.ui/themes/default/jquery.ui.slider.css @@ -1,7 +1,7 @@ -/* - * jQuery UI Slider 1.8.17 +/*! + * jQuery UI Slider 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.ui/themes/default/jquery.ui.tabs.css b/resources/jquery.ui/themes/default/jquery.ui.tabs.css index fb827458..64ac9bf5 100644 --- a/resources/jquery.ui/themes/default/jquery.ui.tabs.css +++ b/resources/jquery.ui/themes/default/jquery.ui.tabs.css @@ -1,7 +1,7 @@ -/* - * jQuery UI Tabs 1.8.17 +/*! + * jQuery UI Tabs 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.ui/themes/default/jquery.ui.theme.css b/resources/jquery.ui/themes/default/jquery.ui.theme.css index d0c93afb..536c8e0e 100644 --- a/resources/jquery.ui/themes/default/jquery.ui.theme.css +++ b/resources/jquery.ui/themes/default/jquery.ui.theme.css @@ -1,7 +1,7 @@ -/* - * jQuery UI CSS Framework 1.8.17 +/*! + * jQuery UI CSS Framework 1.8.23 * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * diff --git a/resources/jquery.ui/themes/vector/images/button-blue-hover-large.png b/resources/jquery.ui/themes/vector/images/button-blue-hover-large.png Binary files differnew file mode 100644 index 00000000..8f7cf74e --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-blue-hover-large.png diff --git a/resources/jquery.ui/themes/vector/images/button-blue-hover.png b/resources/jquery.ui/themes/vector/images/button-blue-hover.png Binary files differnew file mode 100644 index 00000000..1fc28163 --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-blue-hover.png diff --git a/resources/jquery.ui/themes/vector/images/button-blue-large.png b/resources/jquery.ui/themes/vector/images/button-blue-large.png Binary files differnew file mode 100644 index 00000000..22ee5e59 --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-blue-large.png diff --git a/resources/jquery.ui/themes/vector/images/button-blue.png b/resources/jquery.ui/themes/vector/images/button-blue.png Binary files differnew file mode 100644 index 00000000..2e6d121a --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-blue.png diff --git a/resources/jquery.ui/themes/vector/images/button-disabled-blue.png b/resources/jquery.ui/themes/vector/images/button-disabled-blue.png Binary files differindex 6242aca3..28eb1fcd 100644 --- a/resources/jquery.ui/themes/vector/images/button-disabled-blue.png +++ b/resources/jquery.ui/themes/vector/images/button-disabled-blue.png diff --git a/resources/jquery.ui/themes/vector/images/button-disabled-green.png b/resources/jquery.ui/themes/vector/images/button-disabled-green.png Binary files differindex 16209389..0e29d85b 100644 --- a/resources/jquery.ui/themes/vector/images/button-disabled-green.png +++ b/resources/jquery.ui/themes/vector/images/button-disabled-green.png diff --git a/resources/jquery.ui/themes/vector/images/button-disabled-red.png b/resources/jquery.ui/themes/vector/images/button-disabled-red.png Binary files differindex 0658a1db..ede69988 100644 --- a/resources/jquery.ui/themes/vector/images/button-disabled-red.png +++ b/resources/jquery.ui/themes/vector/images/button-disabled-red.png diff --git a/resources/jquery.ui/themes/vector/images/button-disabled.png b/resources/jquery.ui/themes/vector/images/button-disabled.png Binary files differindex cde3b1fb..e4e4ec1c 100644 --- a/resources/jquery.ui/themes/vector/images/button-disabled.png +++ b/resources/jquery.ui/themes/vector/images/button-disabled.png diff --git a/resources/jquery.ui/themes/vector/images/button-down-blue.png b/resources/jquery.ui/themes/vector/images/button-down-blue.png Binary files differindex e0f5a6c0..766e5746 100644 --- a/resources/jquery.ui/themes/vector/images/button-down-blue.png +++ b/resources/jquery.ui/themes/vector/images/button-down-blue.png diff --git a/resources/jquery.ui/themes/vector/images/button-down-green.png b/resources/jquery.ui/themes/vector/images/button-down-green.png Binary files differindex edfd4275..90969c39 100644 --- a/resources/jquery.ui/themes/vector/images/button-down-green.png +++ b/resources/jquery.ui/themes/vector/images/button-down-green.png diff --git a/resources/jquery.ui/themes/vector/images/button-down-red.png b/resources/jquery.ui/themes/vector/images/button-down-red.png Binary files differindex b0565fd8..f6257298 100644 --- a/resources/jquery.ui/themes/vector/images/button-down-red.png +++ b/resources/jquery.ui/themes/vector/images/button-down-red.png diff --git a/resources/jquery.ui/themes/vector/images/button-down.png b/resources/jquery.ui/themes/vector/images/button-down.png Binary files differindex 160330ec..c6467571 100644 --- a/resources/jquery.ui/themes/vector/images/button-down.png +++ b/resources/jquery.ui/themes/vector/images/button-down.png diff --git a/resources/jquery.ui/themes/vector/images/button-green-hover-large.png b/resources/jquery.ui/themes/vector/images/button-green-hover-large.png Binary files differnew file mode 100644 index 00000000..dd8851e1 --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-green-hover-large.png diff --git a/resources/jquery.ui/themes/vector/images/button-green-hover.png b/resources/jquery.ui/themes/vector/images/button-green-hover.png Binary files differnew file mode 100644 index 00000000..19c39911 --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-green-hover.png diff --git a/resources/jquery.ui/themes/vector/images/button-green-large.png b/resources/jquery.ui/themes/vector/images/button-green-large.png Binary files differnew file mode 100644 index 00000000..a8e830eb --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-green-large.png diff --git a/resources/jquery.ui/themes/vector/images/button-green.png b/resources/jquery.ui/themes/vector/images/button-green.png Binary files differnew file mode 100644 index 00000000..54c418e9 --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-green.png diff --git a/resources/jquery.ui/themes/vector/images/button-large-disabled-green.png b/resources/jquery.ui/themes/vector/images/button-large-disabled-green.png Binary files differnew file mode 100644 index 00000000..f76f7b05 --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-large-disabled-green.png diff --git a/resources/jquery.ui/themes/vector/images/button-large-off-green.png b/resources/jquery.ui/themes/vector/images/button-large-off-green.png Binary files differnew file mode 100644 index 00000000..f997431b --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-large-off-green.png diff --git a/resources/jquery.ui/themes/vector/images/button-off-blue.png b/resources/jquery.ui/themes/vector/images/button-off-blue.png Binary files differindex 8a8224b0..82dedb53 100644 --- a/resources/jquery.ui/themes/vector/images/button-off-blue.png +++ b/resources/jquery.ui/themes/vector/images/button-off-blue.png diff --git a/resources/jquery.ui/themes/vector/images/button-off-green.png b/resources/jquery.ui/themes/vector/images/button-off-green.png Binary files differindex c6f5ee4f..109907f0 100644 --- a/resources/jquery.ui/themes/vector/images/button-off-green.png +++ b/resources/jquery.ui/themes/vector/images/button-off-green.png diff --git a/resources/jquery.ui/themes/vector/images/button-off-red.png b/resources/jquery.ui/themes/vector/images/button-off-red.png Binary files differindex 1c609166..5a85b8aa 100644 --- a/resources/jquery.ui/themes/vector/images/button-off-red.png +++ b/resources/jquery.ui/themes/vector/images/button-off-red.png diff --git a/resources/jquery.ui/themes/vector/images/button-off.png b/resources/jquery.ui/themes/vector/images/button-off.png Binary files differindex 1bdc85c7..cc5eb119 100644 --- a/resources/jquery.ui/themes/vector/images/button-off.png +++ b/resources/jquery.ui/themes/vector/images/button-off.png diff --git a/resources/jquery.ui/themes/vector/images/button-orange-hover-large.png b/resources/jquery.ui/themes/vector/images/button-orange-hover-large.png Binary files differnew file mode 100644 index 00000000..6f0dbd5d --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-orange-hover-large.png diff --git a/resources/jquery.ui/themes/vector/images/button-orange-hover.png b/resources/jquery.ui/themes/vector/images/button-orange-hover.png Binary files differnew file mode 100644 index 00000000..a1077c58 --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-orange-hover.png diff --git a/resources/jquery.ui/themes/vector/images/button-orange-large.png b/resources/jquery.ui/themes/vector/images/button-orange-large.png Binary files differnew file mode 100644 index 00000000..3d7f37f6 --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-orange-large.png diff --git a/resources/jquery.ui/themes/vector/images/button-orange.png b/resources/jquery.ui/themes/vector/images/button-orange.png Binary files differnew file mode 100644 index 00000000..02347cf9 --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-orange.png diff --git a/resources/jquery.ui/themes/vector/images/button-over-blue.png b/resources/jquery.ui/themes/vector/images/button-over-blue.png Binary files differindex a744947d..9edb7aa2 100644 --- a/resources/jquery.ui/themes/vector/images/button-over-blue.png +++ b/resources/jquery.ui/themes/vector/images/button-over-blue.png diff --git a/resources/jquery.ui/themes/vector/images/button-over-green.png b/resources/jquery.ui/themes/vector/images/button-over-green.png Binary files differindex d47eb758..47a0b1b8 100644 --- a/resources/jquery.ui/themes/vector/images/button-over-green.png +++ b/resources/jquery.ui/themes/vector/images/button-over-green.png diff --git a/resources/jquery.ui/themes/vector/images/button-over-red.png b/resources/jquery.ui/themes/vector/images/button-over-red.png Binary files differindex 28003bd8..a2445365 100644 --- a/resources/jquery.ui/themes/vector/images/button-over-red.png +++ b/resources/jquery.ui/themes/vector/images/button-over-red.png diff --git a/resources/jquery.ui/themes/vector/images/button-over.png b/resources/jquery.ui/themes/vector/images/button-over.png Binary files differindex 23d13ecb..558f1f80 100644 --- a/resources/jquery.ui/themes/vector/images/button-over.png +++ b/resources/jquery.ui/themes/vector/images/button-over.png diff --git a/resources/jquery.ui/themes/vector/images/button-red-hover-large.png b/resources/jquery.ui/themes/vector/images/button-red-hover-large.png Binary files differnew file mode 100644 index 00000000..11ccef06 --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-red-hover-large.png diff --git a/resources/jquery.ui/themes/vector/images/button-red-hover.png b/resources/jquery.ui/themes/vector/images/button-red-hover.png Binary files differnew file mode 100644 index 00000000..55a61743 --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-red-hover.png diff --git a/resources/jquery.ui/themes/vector/images/button-red-large.png b/resources/jquery.ui/themes/vector/images/button-red-large.png Binary files differnew file mode 100644 index 00000000..8d089efd --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-red-large.png diff --git a/resources/jquery.ui/themes/vector/images/button-red.png b/resources/jquery.ui/themes/vector/images/button-red.png Binary files differnew file mode 100644 index 00000000..7a292fc1 --- /dev/null +++ b/resources/jquery.ui/themes/vector/images/button-red.png diff --git a/resources/jquery.ui/themes/vector/images/close.png b/resources/jquery.ui/themes/vector/images/close.png Binary files differindex 41d53913..ef0dd9e3 100644 --- a/resources/jquery.ui/themes/vector/images/close.png +++ b/resources/jquery.ui/themes/vector/images/close.png diff --git a/resources/jquery.ui/themes/vector/images/titlebar-fade.png b/resources/jquery.ui/themes/vector/images/titlebar-fade.png Binary files differindex b491ec49..f9fde8b3 100644 --- a/resources/jquery.ui/themes/vector/images/titlebar-fade.png +++ b/resources/jquery.ui/themes/vector/images/titlebar-fade.png diff --git a/resources/jquery.ui/themes/vector/images/ui-bg_flat_15_cd0a0a_40x100.png b/resources/jquery.ui/themes/vector/images/ui-bg_flat_15_cd0a0a_40x100.png Binary files differindex 7680b543..09de537f 100644 --- a/resources/jquery.ui/themes/vector/images/ui-bg_flat_15_cd0a0a_40x100.png +++ b/resources/jquery.ui/themes/vector/images/ui-bg_flat_15_cd0a0a_40x100.png diff --git a/resources/jquery.ui/themes/vector/images/ui-bg_flat_70_000000_40x100.png b/resources/jquery.ui/themes/vector/images/ui-bg_flat_70_000000_40x100.png Binary files differindex abdc0108..c06dd561 100644 --- a/resources/jquery.ui/themes/vector/images/ui-bg_flat_70_000000_40x100.png +++ b/resources/jquery.ui/themes/vector/images/ui-bg_flat_70_000000_40x100.png diff --git a/resources/jquery.ui/themes/vector/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png b/resources/jquery.ui/themes/vector/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png Binary files differindex 28b566c2..5308b466 100644 --- a/resources/jquery.ui/themes/vector/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png +++ b/resources/jquery.ui/themes/vector/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png diff --git a/resources/jquery.ui/themes/vector/images/ui-bg_highlight-hard_80_d7ebf9_1x100.png b/resources/jquery.ui/themes/vector/images/ui-bg_highlight-hard_80_d7ebf9_1x100.png Binary files differindex dac84622..0c8997f7 100644 --- a/resources/jquery.ui/themes/vector/images/ui-bg_highlight-hard_80_d7ebf9_1x100.png +++ b/resources/jquery.ui/themes/vector/images/ui-bg_highlight-hard_80_d7ebf9_1x100.png diff --git a/resources/jquery.ui/themes/vector/images/ui-bg_highlight-soft_100_e4f1fb_1x100.png b/resources/jquery.ui/themes/vector/images/ui-bg_highlight-soft_100_e4f1fb_1x100.png Binary files differindex ad7f982b..31492556 100644 --- a/resources/jquery.ui/themes/vector/images/ui-bg_highlight-soft_100_e4f1fb_1x100.png +++ b/resources/jquery.ui/themes/vector/images/ui-bg_highlight-soft_100_e4f1fb_1x100.png diff --git a/resources/jquery.ui/themes/vector/images/ui-bg_highlight-soft_100_ffffff_1x100.png b/resources/jquery.ui/themes/vector/images/ui-bg_highlight-soft_100_ffffff_1x100.png Binary files differindex 8169ec3e..09b23761 100644 --- a/resources/jquery.ui/themes/vector/images/ui-bg_highlight-soft_100_ffffff_1x100.png +++ b/resources/jquery.ui/themes/vector/images/ui-bg_highlight-soft_100_ffffff_1x100.png diff --git a/resources/jquery.ui/themes/vector/images/ui-bg_highlight-soft_25_ffef8f_1x100.png b/resources/jquery.ui/themes/vector/images/ui-bg_highlight-soft_25_ffef8f_1x100.png Binary files differindex 54aff0cb..66627c18 100644 --- a/resources/jquery.ui/themes/vector/images/ui-bg_highlight-soft_25_ffef8f_1x100.png +++ b/resources/jquery.ui/themes/vector/images/ui-bg_highlight-soft_25_ffef8f_1x100.png diff --git a/resources/jquery.ui/themes/vector/images/ui-bg_inset-hard_100_f0f0f0_1x100.png b/resources/jquery.ui/themes/vector/images/ui-bg_inset-hard_100_f0f0f0_1x100.png Binary files differindex 3d87ac7b..ccb6dc06 100644 --- a/resources/jquery.ui/themes/vector/images/ui-bg_inset-hard_100_f0f0f0_1x100.png +++ b/resources/jquery.ui/themes/vector/images/ui-bg_inset-hard_100_f0f0f0_1x100.png diff --git a/resources/jquery.ui/themes/vector/images/ui-icons_2694e8_256x240.png b/resources/jquery.ui/themes/vector/images/ui-icons_2694e8_256x240.png Binary files differindex 9d192c2f..998ac3bc 100644 --- a/resources/jquery.ui/themes/vector/images/ui-icons_2694e8_256x240.png +++ b/resources/jquery.ui/themes/vector/images/ui-icons_2694e8_256x240.png diff --git a/resources/jquery.ui/themes/vector/images/ui-icons_2e83ff_256x240.png b/resources/jquery.ui/themes/vector/images/ui-icons_2e83ff_256x240.png Binary files differindex 09d1cdc8..34e38d11 100644 --- a/resources/jquery.ui/themes/vector/images/ui-icons_2e83ff_256x240.png +++ b/resources/jquery.ui/themes/vector/images/ui-icons_2e83ff_256x240.png diff --git a/resources/jquery.ui/themes/vector/images/ui-icons_3d80b3_256x240.png b/resources/jquery.ui/themes/vector/images/ui-icons_3d80b3_256x240.png Binary files differindex f13b2066..ec129a8b 100644 --- a/resources/jquery.ui/themes/vector/images/ui-icons_3d80b3_256x240.png +++ b/resources/jquery.ui/themes/vector/images/ui-icons_3d80b3_256x240.png diff --git a/resources/jquery.ui/themes/vector/images/ui-icons_666666_256x240.png b/resources/jquery.ui/themes/vector/images/ui-icons_666666_256x240.png Binary files differindex f87de1ca..a32c57d8 100644 --- a/resources/jquery.ui/themes/vector/images/ui-icons_666666_256x240.png +++ b/resources/jquery.ui/themes/vector/images/ui-icons_666666_256x240.png diff --git a/resources/jquery.ui/themes/vector/images/ui-icons_72a7cf_256x240.png b/resources/jquery.ui/themes/vector/images/ui-icons_72a7cf_256x240.png Binary files differindex 0d20b730..88fad1a5 100644 --- a/resources/jquery.ui/themes/vector/images/ui-icons_72a7cf_256x240.png +++ b/resources/jquery.ui/themes/vector/images/ui-icons_72a7cf_256x240.png diff --git a/resources/jquery.ui/themes/vector/images/ui-icons_ffffff_256x240.png b/resources/jquery.ui/themes/vector/images/ui-icons_ffffff_256x240.png Binary files differindex 42f8f992..29ba7d28 100644 --- a/resources/jquery.ui/themes/vector/images/ui-icons_ffffff_256x240.png +++ b/resources/jquery.ui/themes/vector/images/ui-icons_ffffff_256x240.png diff --git a/resources/jquery.ui/themes/vector/jquery.ui.button.css b/resources/jquery.ui/themes/vector/jquery.ui.button.css index 631fa756..006bbeac 100644 --- a/resources/jquery.ui/themes/vector/jquery.ui.button.css +++ b/resources/jquery.ui/themes/vector/jquery.ui.button.css @@ -4,18 +4,16 @@ .ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ .ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ -.ui-button-icons-only { width: 3.4em; } -button.ui-button-icons-only { width: 3.7em; } +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } /*button text element */ -.ui-button .ui-button-text { display: block; line-height: 1.4em; } +.ui-button .ui-button-text { display: block; line-height: 1.4; } .ui-button-text-only .ui-button-text { padding: 0.3em 1em 0.25em 1em; } .ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: 0.3em; text-indent: -9999999px; } .ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: 0.3em 1em 0.25em 2.1em; } .ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: 0.3em 2.1em 0.25em 1em; } .ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } -/* for older versions of jQuery UI */ -.ui-button-text-icon .ui-button-text { padding: 0.3em 1em 0.3em 2.1em; } /* no icon support for input elements, provide padding by default */ input.ui-button { padding: 0.3em 1em; } @@ -34,10 +32,7 @@ input.ui-button { padding: 0.3em 1em; } button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ body .ui-button { - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - border-radius: 4px; - margin: 0.5em 0 0.5em 0.4em !important; + margin: 0.5em 0 0.5em 0.4em; border: 1px solid #a6a6a6 !important; /* @embed */ background: #f2f2f2 url(images/button-off.png) repeat-x scroll 50% 100% !important; @@ -47,6 +42,15 @@ body .ui-button { width: auto; overflow: visible; } + +/* Corner radius */ +/* This is normally handled in jquery.ui.theme.css, but in our case, the corner + styling of our buttons doesn't match our default widget corner styling */ +.ui-button.ui-corner-all, .ui-button.ui-corner-top, .ui-button.ui-corner-left, .ui-button.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-button.ui-corner-all, .ui-button.ui-corner-top, .ui-button.ui-corner-right, .ui-button.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-button.ui-corner-all, .ui-button.ui-corner-bottom, .ui-button.ui-corner-left, .ui-button.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-button.ui-corner-all, .ui-button.ui-corner-bottom, .ui-button.ui-corner-right, .ui-button.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } + body .ui-button:hover { border-color: #6e7273; /* @embed */ @@ -65,83 +69,127 @@ body .ui-button.disabled { background: #f2f2f2 url(images/button-disabled.png) repeat-x scroll 50% 100% !important; } /* Disables the annoying dashed border Firefox puts on active buttons */ -body button.ui-button::-moz-focus-inner { +body button.ui-button::-moz-focus-inner { border: 0; } +/* Give large buttons some extra padding */ +body .ui-button-large { + padding: 5px; +} +/* Use white icons for colored buttons */ +.ui-button-green .ui-icon, .ui-button-blue .ui-icon, .ui-button-red .ui-icon, .ui-button-orange .ui-icon { + /* @embed */ + background-image: url(images/ui-icons_ffffff_256x240.png) !important; +} /* Green buttons */ body .ui-button.ui-button-green { - color: white; + color: white !important; border-color: #97af7e !important; /* @embed */ - background: #85c940 url(images/button-off-green.png) repeat-x scroll 50% 100% !important; + background: #3cb677 url(images/button-green.png) repeat-x scroll 50% 100% !important; } body .ui-button.ui-button-green:hover { - border-color: #778e61; + border-color: #778e61 !important; /* @embed */ - background: #77ad40 url(images/button-over-green.png) repeat-x scroll 50% 100% !important; + background: #339b65 url(images/button-green-hover.png) repeat-x scroll 50% 100% !important; } -body .ui-button.ui-button-green:active, -body .ui-button.ui-button-green:focus { - border-color: #61b000; +body .ui-button.ui-button-green.ui-button-large { /* @embed */ - background: #54a800 url(images/button-down-green.png) repeat-x scroll 50% 100% !important; + background: #3cb677 url(images/button-green-large.png) repeat-x scroll 50% 100% !important; } -body .ui-button.ui-button-green.disabled { - color: #7f7f7f; - border-color: #b8d29f; +body .ui-button.ui-button-green.ui-button-large:hover { /* @embed */ - background: #c9cfc3 url(images/button-disabled-green.png) repeat-x scroll 50% 100% !important; + background: #339b65 url(images/button-green-hover-large.png) repeat-x scroll 50% 100% !important; +} +body .ui-button.ui-button-green.disabled { + filter:alpha(opacity=50); + -moz-opacity:0.50; + -khtml-opacity: 0.50; + opacity: 0.50; } /* Blue buttons */ body .ui-button.ui-button-blue { - color: white; - border-color: #407ec9 !important; + color: white !important; + border-color: #628acb !important; /* @embed */ - background: #407ec9 url(images/button-off-blue.png) repeat-x scroll 50% 100% !important; + background: #3365ba url(images/button-blue.png) repeat-x scroll 50% 100% !important; } body .ui-button.ui-button-blue:hover { - border-color: #245289; + border-color: #5375ad !important; /* @embed */ - background: #4071ad url(images/button-over-blue.png) repeat-x scroll 50% 100% !important; + background: #2b569e url(images/button-blue-hover.png) repeat-x scroll 50% 100% !important; } -body .ui-button.ui-button-blue:active, -body .ui-button.ui-button-blue:focus { - border-color: #003980; +body .ui-button.ui-button-blue.ui-button-large { /* @embed */ - background: #004daa url(images/button-down-blue.png) repeat-x scroll 50% 100% !important; + background: #3365ba url(images/button-blue-large.png) repeat-x scroll 50% 100% !important; } -body .ui-button.ui-button-blue.disabled { - border-color: #9eafc6; +body .ui-button.ui-button-blue.ui-button-large:hover { /* @embed */ - background: #c3c8cf url(images/button-disabled-blue.png) repeat-x scroll 50% 100% !important; + background: #2b569e url(images/button-blue-hover-large.png) repeat-x scroll 50% 100% !important; +} +body .ui-button.ui-button-blue.disabled { + filter:alpha(opacity=50); + -moz-opacity:0.50; + -khtml-opacity: 0.50; + opacity: 0.50; } /* Red buttons */ body .ui-button.ui-button-red { - color: white; + color: white !important; border-color: #af977e !important; /* @embed */ - background: #c9404c url(images/button-off-red.png) repeat-x scroll 50% 100% !important; + background: #cb0000 url(images/button-red.png) repeat-x scroll 50% 100% !important; } body .ui-button.ui-button-red:hover { - border-color: #8e7761; + border-color: #8e7761 !important; /* @embed */ - background: #ad404a url(images/button-over-red.png) repeat-x scroll 50% 100% !important; + background: #ad0000 url(images/button-red-hover.png) repeat-x scroll 50% 100% !important; } -body .ui-button.ui-button-red:active, -body .ui-button.ui-button-red:focus { - border-color: #b06100; +body .ui-button.ui-button-red.ui-button-large { /* @embed */ - background: #aa000f url(images/button-down-red.png) repeat-x scroll 50% 100% !important; + background: #cb0000 url(images/button-red.png) repeat-x scroll 50% 100% !important; +} +body .ui-button.ui-button-red.ui-button-large:hover { + /* @embed */ + background: #ad0000 url(images/button-red-hover.png) repeat-x scroll 50% 100% !important; } body .ui-button.ui-button-red.disabled { - color: #7f7f7f; - border-color: #c3acae; + filter:alpha(opacity=50); + -moz-opacity:0.50; + -khtml-opacity: 0.50; + opacity: 0.50; +} + +/* Orange buttons */ + +body .ui-button.ui-button-orange { + color: white !important; + border-color: #f3a863 !important; + /* @embed */ + background: #f07f14 url(images/button-orange.png) repeat-x scroll 50% 100% !important; +} +body .ui-button.ui-button-orange:hover { + border-color: #ce9055 !important; + /* @embed */ + background: #cc6c11 url(images/button-orange-hover.png) repeat-x scroll 50% 100% !important; +} +body .ui-button.ui-button-orange.ui-button-large { /* @embed */ - background: #cfc3c4 url(images/button-disabled-red.png) repeat-x scroll 50% 100% !important; + background: #f07f14 url(images/button-orange-large.png) repeat-x scroll 50% 100% !important; +} +body .ui-button.ui-button-orange.ui-button-large:hover { + /* @embed */ + background: #cc6c11 url(images/button-orange-hover-large.png) repeat-x scroll 50% 100% !important; +} +body .ui-button.ui-button-orange.disabled { + filter:alpha(opacity=50); + -moz-opacity:0.50; + -khtml-opacity: 0.50; + opacity: 0.50; } diff --git a/resources/jquery.ui/themes/vector/jquery.ui.resizable.css b/resources/jquery.ui/themes/vector/jquery.ui.resizable.css index 366643b5..f1bd7c5e 100644 --- a/resources/jquery.ui/themes/vector/jquery.ui.resizable.css +++ b/resources/jquery.ui/themes/vector/jquery.ui.resizable.css @@ -5,9 +5,15 @@ .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +/* @noflip */ .ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +/* @noflip */ .ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +/* @noflip */ .ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +/* @noflip */ .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +/* @noflip */ .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +/* @noflip */ .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
\ No newline at end of file diff --git a/resources/jquery/images/jquery.arrowSteps.divider-ltr.png b/resources/jquery/images/jquery.arrowSteps.divider-ltr.png Binary files differindex 0de1ae9c..83d6ff84 100644 --- a/resources/jquery/images/jquery.arrowSteps.divider-ltr.png +++ b/resources/jquery/images/jquery.arrowSteps.divider-ltr.png diff --git a/resources/jquery/images/jquery.arrowSteps.divider-rtl.png b/resources/jquery/images/jquery.arrowSteps.divider-rtl.png Binary files differindex f3f06519..529d7b84 100644 --- a/resources/jquery/images/jquery.arrowSteps.divider-rtl.png +++ b/resources/jquery/images/jquery.arrowSteps.divider-rtl.png diff --git a/resources/jquery/images/jquery.arrowSteps.head-ltr.png b/resources/jquery/images/jquery.arrowSteps.head-ltr.png Binary files differindex dbcc71b9..3289617d 100644 --- a/resources/jquery/images/jquery.arrowSteps.head-ltr.png +++ b/resources/jquery/images/jquery.arrowSteps.head-ltr.png diff --git a/resources/jquery/images/jquery.arrowSteps.head-rtl.png b/resources/jquery/images/jquery.arrowSteps.head-rtl.png Binary files differindex 760798bf..3d9f70cb 100644 --- a/resources/jquery/images/jquery.arrowSteps.head-rtl.png +++ b/resources/jquery/images/jquery.arrowSteps.head-rtl.png diff --git a/resources/jquery/images/jquery.arrowSteps.tail-ltr.png b/resources/jquery/images/jquery.arrowSteps.tail-ltr.png Binary files differindex 61340fa8..92b872b2 100644 --- a/resources/jquery/images/jquery.arrowSteps.tail-ltr.png +++ b/resources/jquery/images/jquery.arrowSteps.tail-ltr.png diff --git a/resources/jquery/images/jquery.arrowSteps.tail-rtl.png b/resources/jquery/images/jquery.arrowSteps.tail-rtl.png Binary files differindex dd2d8e8a..1d3048ef 100644 --- a/resources/jquery/images/jquery.arrowSteps.tail-rtl.png +++ b/resources/jquery/images/jquery.arrowSteps.tail-rtl.png diff --git a/resources/jquery/images/spinner-large.gif b/resources/jquery/images/spinner-large.gif Binary files differnew file mode 100644 index 00000000..72203fdd --- /dev/null +++ b/resources/jquery/images/spinner-large.gif diff --git a/resources/jquery/images/spinner.gif b/resources/jquery/images/spinner.gif Binary files differindex 37d3a43d..6146be4e 100644 --- a/resources/jquery/images/spinner.gif +++ b/resources/jquery/images/spinner.gif diff --git a/resources/jquery/images/wheel.png b/resources/jquery/images/wheel.png Binary files differindex 97b343d9..7e53103e 100644 --- a/resources/jquery/images/wheel.png +++ b/resources/jquery/images/wheel.png diff --git a/resources/jquery/jquery.arrowSteps.css b/resources/jquery/jquery.arrowSteps.css index 60461032..f8f6e951 100644 --- a/resources/jquery/jquery.arrowSteps.css +++ b/resources/jquery/jquery.arrowSteps.css @@ -42,4 +42,4 @@ /* TODO: eliminate duplication of jquery.arrowSteps.head.png embedding */ /* @embed */ background: url(images/jquery.arrowSteps.head-ltr.png) no-repeat right center; -}
\ No newline at end of file +} diff --git a/resources/jquery/jquery.arrowSteps.js b/resources/jquery/jquery.arrowSteps.js index f9637545..488d1065 100644 --- a/resources/jquery/jquery.arrowSteps.js +++ b/resources/jquery/jquery.arrowSteps.js @@ -1,21 +1,21 @@ /** * jQuery arrowSteps plugin * Copyright Neil Kandalgaonkar, 2010 - * - * This work is licensed under the terms of the GNU General Public License, - * version 2 or later. - * (see http://www.fsf.org/licensing/licenses/gpl.html). - * Derivative works and later versions of the code must be free software + * + * This work is licensed under the terms of the GNU General Public License, + * version 2 or later. + * (see http://www.fsf.org/licensing/licenses/gpl.html). + * Derivative works and later versions of the code must be free software * licensed under the same or a compatible license. * * * DESCRIPTION * - * Show users their progress through a series of steps, via a row of items that fit + * Show users their progress through a series of steps, via a row of items that fit * together like arrows. One item can be highlighted at a time. * * - * SYNOPSIS + * SYNOPSIS * * <ul id="robin-hood-daffy"> * <li id="guard"><div>Guard!</div></li> @@ -27,45 +27,43 @@ * <li id="thrust"><div>Thrust!</div></li> * </ul> * - * <script language="javascript"><!-- + * <script> * $( '#robin-hood-daffy' ).arrowSteps(); * * $( '#robin-hood-daffy' ).arrowStepsHighlight( '#guard' ); * // 'Guard!' is highlighted. * * // ... user completes the 'guard' step ... - * + * * $( '#robin-hood-daffy' ).arrowStepsHighlight( '#turn' ); * // 'Turn!' is highlighted. - * - * //--> * </script> * */ - -( function( $j ) { - $j.fn.arrowSteps = function() { +( function ( $ ) { + $.fn.arrowSteps = function () { + var $steps, width, arrowWidth; this.addClass( 'arrowSteps' ); - var $steps = this.find( 'li' ); + $steps = this.find( 'li' ); - var width = parseInt( 100 / $steps.length, 10 ); + width = parseInt( 100 / $steps.length, 10 ); $steps.css( 'width', width + '%' ); - // every step except the last one has an arrow at the right hand side. Also add in the padding + // every step except the last one has an arrow at the right hand side. Also add in the padding // for the calculated arrow width. - var arrowWidth = parseInt( this.outerHeight(), 10 ); + arrowWidth = parseInt( this.outerHeight(), 10 ); $steps.filter( ':not(:last-child)' ).addClass( 'arrow' ) .find( 'div' ).css( 'padding-right', arrowWidth.toString() + 'px' ); this.data( 'arrowSteps', $steps ); return this; }; - - $j.fn.arrowStepsHighlight = function( selector ) { - var $steps = this.data( 'arrowSteps' ); - var $previous; - $j.each( $steps, function( i, step ) { - var $step = $j( step ); + + $.fn.arrowStepsHighlight = function ( selector ) { + var $previous, + $steps = this.data( 'arrowSteps' ); + $.each( $steps, function ( i, step ) { + var $step = $( step ); if ( $step.is( selector ) ) { if ($previous) { $previous.addClass( 'tail' ); @@ -75,7 +73,7 @@ $step.removeClass( 'head tail lasthead' ); } $previous = $step; - } ); + } ); }; -} )( jQuery ); +}( jQuery ) ); diff --git a/resources/jquery/jquery.autoEllipsis.js b/resources/jquery/jquery.autoEllipsis.js index 9a5fcc9c..49a932a1 100644 --- a/resources/jquery/jquery.autoEllipsis.js +++ b/resources/jquery/jquery.autoEllipsis.js @@ -1,53 +1,57 @@ /** - * Plugin that automatically truncates the plain text contents of an element and adds an ellipsis + * Plugin that automatically truncates the plain text contents of an element + * and adds an ellipsis. */ -( function( $ ) { +( function ( $ ) { -// Cache ellipsed substrings for every string-width-position combination -var cache = { }; -// Use a separate cache when match highlighting is enabled -var matchTextCache = { }; +var + // Cache ellipsed substrings for every string-width-position combination + cache = {}, -$.fn.autoEllipsis = function( options ) { + // Use a separate cache when match highlighting is enabled + matchTextCache = {}; + +$.fn.autoEllipsis = function ( options ) { options = $.extend( { - 'position': 'center', - 'tooltip': false, - 'restoreText': false, - 'hasSpan': false, - 'matchText': null + position: 'center', + tooltip: false, + restoreText: false, + hasSpan: false, + matchText: null }, options ); - $(this).each( function() { - var $el = $(this); + + return this.each( function () { + var $trimmableText, + text, trimmableText, w, pw, + l, r, i, side, m, + // container element - used for measuring against + $container = $(this); + if ( options.restoreText ) { - if ( !$el.data( 'autoEllipsis.originalText' ) ) { - $el.data( 'autoEllipsis.originalText', $el.text() ); + if ( !$container.data( 'autoEllipsis.originalText' ) ) { + $container.data( 'autoEllipsis.originalText', $container.text() ); } else { - $el.text( $el.data( 'autoEllipsis.originalText' ) ); + $container.text( $container.data( 'autoEllipsis.originalText' ) ); } } - // container element - used for measuring against - var $container = $el; // trimmable text element - only the text within this element will be trimmed - var $trimmableText = null; - // protected text element - the width of this element is counted, but next is never trimmed from it - var $protectedText = null; - if ( options.hasSpan ) { - $trimmableText = $el.children( options.selector ); + $trimmableText = $container.children( options.selector ); } else { - $trimmableText = $( '<span />' ) + $trimmableText = $( '<span>' ) .css( 'whiteSpace', 'nowrap' ) - .text( $el.text() ); - $el + .text( $container.text() ); + $container .empty() .append( $trimmableText ); } - var text = $container.text(); - var trimmableText = $trimmableText.text(); - var w = $container.width(); - var pw = $protectedText ? $protectedText.width() : 0; + text = $container.text(); + trimmableText = $trimmableText.text(); + w = $container.width(); + pw = 0; + // Try cache if ( options.matchText ) { if ( !( text in matchTextCache ) ) { @@ -86,9 +90,10 @@ $.fn.autoEllipsis = function( options ) { switch ( options.position ) { case 'right': // Use binary search-like technique for efficiency - var l = 0, r = trimmableText.length; + l = 0; + r = trimmableText.length; do { - var m = Math.ceil( ( l + r ) / 2 ); + m = Math.ceil( ( l + r ) / 2 ); $trimmableText.text( trimmableText.substr( 0, m ) + '...' ); if ( $trimmableText.width() + pw > w ) { // Text is too long @@ -101,9 +106,10 @@ $.fn.autoEllipsis = function( options ) { break; case 'center': // TODO: Use binary search like for 'right' - var i = [Math.round( trimmableText.length / 2 ), Math.round( trimmableText.length / 2 )]; - var side = 1; // Begin with making the end shorter - while ( $trimmableText.outerWidth() + pw > w && i[0] > 0 ) { + i = [Math.round( trimmableText.length / 2 ), Math.round( trimmableText.length / 2 )]; + // Begin with making the end shorter + side = 1; + while ( $trimmableText.outerWidth() + pw > w && i[0] > 0 ) { $trimmableText.text( trimmableText.substr( 0, i[0] ) + '...' + trimmableText.substr( i[1] ) ); // Alternate between trimming the end and begining if ( side === 0 ) { @@ -119,7 +125,7 @@ $.fn.autoEllipsis = function( options ) { break; case 'left': // TODO: Use binary search like for 'right' - var r = 0; + r = 0; while ( $trimmableText.outerWidth() + pw > w && r < trimmableText.length ) { $trimmableText.text( '...' + trimmableText.substr( r ) ); r++; @@ -140,4 +146,4 @@ $.fn.autoEllipsis = function( options ) { } ); }; -} )( jQuery );
\ No newline at end of file +}( jQuery ) );
\ No newline at end of file diff --git a/resources/jquery/jquery.badge.css b/resources/jquery/jquery.badge.css new file mode 100644 index 00000000..92e72555 --- /dev/null +++ b/resources/jquery/jquery.badge.css @@ -0,0 +1,39 @@ +.mw-badge { + min-width: 8px; + height: 14px; + border: 1px solid white; + -moz-border-radius: 8px; + -webkit-border-radius: 8px; + border-radius: 8px; + -moz-box-shadow: 0px 1px 4px #ccc; + -webkit-box-shadow: 0px 1px 4px #ccc; + box-shadow: 0px 1px 4px #ccc; + background-color: #b60a00; + background-image: -o-linear-gradient(bottom, #a70802 0%, #cf0e00 100%); + background-image: -moz-linear-gradient(bottom, #a70802 0%, #cf0e00 100%); + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #a70802), color-stop(1, #cf0e00)); + background-image: -webkit-linear-gradient(bottom, #a70802 0%, #cf0e00 100%); + background-image: -ms-linear-gradient(bottom, #a70802 0%, #cf0e00 100%); + background-image: linear-gradient(bottom, #a70802 0%, #cf0e00 100%); + padding: 0 3px; + text-align: center; +} + +.mw-badge-content { + font-size: 12px; + line-height: 14px; + color: white; + vertical-align: top; +} + +.mw-badge-inline { + display: inline-block; + margin-left: 3px; +} + +.mw-badge-overlay { + position: absolute; + bottom: -1px; + right: -3px; + z-index: 50; +} diff --git a/resources/jquery/jquery.badge.js b/resources/jquery/jquery.badge.js new file mode 100644 index 00000000..04495b71 --- /dev/null +++ b/resources/jquery/jquery.badge.js @@ -0,0 +1,117 @@ +/** + * jQuery Badge plugin + * + * Based on Badger plugin by Daniel Raftery (http://thrivingkings.com/badger). + * + * @license MIT + */ + +/** + * @author Ryan Kaldari <rkaldari@wikimedia.org>, 2012 + * @author Andrew Garrett <agarrett@wikimedia.org>, 2012 + * @author Marius Hoch <hoo@online.de>, 2012 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * This program is distributed WITHOUT ANY WARRANTY. + */ +( function ( $ ) { + + /** + * Allows you to put a numeric "badge" on an item on the page. + * See mediawiki.org/wiki/ResourceLoader/Default_modules#jQuery.badge + * + * @param {string|number} badgeCount An explicit number, or "+n"/ "-n" + * to modify the existing value. If the new value is equal or lower than 0, + * any existing badge will be removed. The badge container will be appended + * to the selected element(s). + * @param {Object} options Optional parameters specified below + * type: 'inline' or 'overlay' (default) + * callback: will be called with the number now shown on the badge as a parameter + */ + $.fn.badge = function ( badgeCount, options ) { + var $badge, + oldBadgeCount, + newBadgeCount, + $existingBadge = this.find( '.mw-badge' ); + + options = $.extend( { type : 'overlay' }, options ); + + // If there is no existing badge, this will give an empty string + oldBadgeCount = Number( $existingBadge.text() ); + if ( isNaN( oldBadgeCount ) ) { + oldBadgeCount = 0; + } + + // If badgeCount is a number, use that as the new badge + if ( typeof badgeCount === 'number' ) { + newBadgeCount = badgeCount; + } else if ( typeof badgeCount === 'string' ) { + // If badgeCount is "+x", add x to the old badge + if ( badgeCount.charAt(0) === '+' ) { + newBadgeCount = oldBadgeCount + Number( badgeCount.substr(1) ); + // If badgeCount is "-x", subtract x from the old badge + } else if ( badgeCount.charAt(0) === '-' ) { + newBadgeCount = oldBadgeCount - Number( badgeCount.substr(1) ); + // If badgeCount can be converted into a number, convert it + } else if ( !isNaN( Number( badgeCount ) ) ) { + newBadgeCount = Number( badgeCount ); + } else { + newBadgeCount = 0; + } + // Other types are not supported, fall back to 0. + } else { + newBadgeCount = 0; + } + + // Badge count must be a whole number + newBadgeCount = Math.round( newBadgeCount ); + + if ( newBadgeCount <= 0 ) { + // Badges should only exist for values > 0. + $existingBadge.remove(); + } else { + // Don't add duplicates + if ( $existingBadge.length ) { + $badge = $existingBadge; + // Insert the new count into the badge + this.find( '.mw-badge-content' ).text( newBadgeCount ); + } else { + // Contruct a new badge with the count + $badge = $( '<div>' ) + .addClass( 'mw-badge' ) + .append( + $( '<span>' ) + .addClass( 'mw-badge-content' ) + .text( newBadgeCount ) + ); + this.append( $badge ); + } + + if ( options.type === 'inline' ) { + $badge + .removeClass( 'mw-badge-overlay' ) + .addClass( 'mw-badge-inline' ); + // Default: overlay + } else { + $badge + .removeClass( 'mw-badge-inline' ) + .addClass( 'mw-badge-overlay' ); + + } + + // If a callback was specified, call it with the badge count + if ( $.isFunction( options.callback ) ) { + options.callback( newBadgeCount ); + } + } + }; +}( jQuery ) ); diff --git a/resources/jquery/jquery.byteLength.js b/resources/jquery/jquery.byteLength.js index 20fa5c8e..3d5b7206 100644 --- a/resources/jquery/jquery.byteLength.js +++ b/resources/jquery/jquery.byteLength.js @@ -3,9 +3,9 @@ * * Calculate the byte length of a string (accounting for UTF-8). * - * @author Jan Paul Posma + * @author Jan Paul Posma, 2011 */ -jQuery.byteLength = function( str ) { +jQuery.byteLength = function ( str ) { // This basically figures out how many bytes a UTF-16 string (which is what js sees) // will take in UTF-8 by replacing a 2 byte character with 2 *'s, etc, and counting that. @@ -16,4 +16,4 @@ jQuery.byteLength = function( str ) { .replace( /[\u0080-\u07FF\uD800-\uDFFF]/g, '**' ) .replace( /[\u0800-\uD7FF\uE000-\uFFFF]/g, '***' ) .length; -} +}; diff --git a/resources/jquery/jquery.byteLimit.js b/resources/jquery/jquery.byteLimit.js index 10411924..75dc2b90 100644 --- a/resources/jquery/jquery.byteLimit.js +++ b/resources/jquery/jquery.byteLimit.js @@ -1,87 +1,229 @@ /** - * jQuery byteLimit + * jQuery byteLimit plugin. * - * @author Jan Paul Posma + * @author Jan Paul Posma, 2011 + * @author Timo Tijhof, 2011-2012 */ -( function( $ ) { +( function ( $ ) { /** - * Enforces a byte limit to a textbox, so that UTF-8 entries are counted as well, when, for example, - * a databae field has a byte limit rather than a character limit. - * Plugin rationale: Browser has native maxlength for number of characters, this plugin exists to - * limit number of bytes instead. + * Utility function to trim down a string, based on byteLimit + * and given a safe start position. It supports insertion anywhere + * in the string, so "foo" to "fobaro" if limit is 4 will result in + * "fobo", not "foba". Basically emulating the native maxlength by + * reconstructing where the insertion occured. * - * Can be called with a custom limit (to use that limit instead of the maxlength attribute value), - * a filter function (in case the limit should apply to something other than the exact input value), - * or both. Order of arguments is important! + * @param {string} safeVal Known value that was previously returned by this + * function, if none, pass empty string. + * @param {string} newVal New value that may have to be trimmed down. + * @param {number} byteLimit Number of bytes the value may be in size. + * @param {Function} fn [optional] See $.fn.byteLimit. + * @return {Object} Object with: + * - {string} newVal + * - {boolean} trimmed + */ + function trimValForByteLength( safeVal, newVal, byteLimit, fn ) { + var startMatches, endMatches, matchesLen, inpParts, + oldVal = safeVal; + + // Run the hook if one was provided, but only on the length + // assessment. The value itself is not to be affected by the hook. + if ( $.byteLength( fn ? fn( newVal ) : newVal ) <= byteLimit ) { + // Limit was not reached, just remember the new value + // and let the user continue. + return { + newVal: newVal, + trimmed: false + }; + } + + // Current input is longer than the active limit. + // Figure out what was added and limit the addition. + startMatches = 0; + endMatches = 0; + + // It is important that we keep the search within the range of + // the shortest string's length. + // Imagine a user adds text that matches the end of the old value + // (e.g. "foo" -> "foofoo"). startMatches would be 3, but without + // limiting both searches to the shortest length, endMatches would + // also be 3. + matchesLen = Math.min( newVal.length, oldVal.length ); + + // Count same characters from the left, first. + // (if "foo" -> "foofoo", assume addition was at the end). + while ( + startMatches < matchesLen && + oldVal.charAt( startMatches ) === newVal.charAt( startMatches ) + ) { + startMatches += 1; + } + + while ( + endMatches < ( matchesLen - startMatches ) && + oldVal.charAt( oldVal.length - 1 - endMatches ) === newVal.charAt( newVal.length - 1 - endMatches ) + ) { + endMatches += 1; + } + + inpParts = [ + // Same start + newVal.substring( 0, startMatches ), + // Inserted content + newVal.substring( startMatches, newVal.length - endMatches ), + // Same end + newVal.substring( newVal.length - endMatches ) + ]; + + // Chop off characters from the end of the "inserted content" string + // until the limit is statisfied. + if ( fn ) { + while ( $.byteLength( fn( inpParts.join( '' ) ) ) > byteLimit ) { + inpParts[1] = inpParts[1].slice( 0, -1 ); + } + } else { + while ( $.byteLength( inpParts.join( '' ) ) > byteLimit ) { + inpParts[1] = inpParts[1].slice( 0, -1 ); + } + } + + newVal = inpParts.join( '' ); + + return { + newVal: newVal, + trimmed: true + }; + } + + var eventKeys = [ + 'keyup.byteLimit', + 'keydown.byteLimit', + 'change.byteLimit', + 'mouseup.byteLimit', + 'cut.byteLimit', + 'paste.byteLimit', + 'focus.byteLimit', + 'blur.byteLimit' + ].join( ' ' ); + + /** + * Enforces a byte limit on an input field, so that UTF-8 entries are counted as well, + * when, for example, a database field has a byte limit rather than a character limit. + * Plugin rationale: Browser has native maxlength for number of characters, this plugin + * exists to limit number of bytes instead. + * + * Can be called with a custom limit (to use that limit instead of the maxlength attribute + * value), a filter function (in case the limit should apply to something other than the + * exact input value), or both. Order of parameters is important! * * @context {jQuery} Instance of jQuery for one or more input elements - * @param limit {Number} (optional) Limit to enforce, fallsback to maxLength-attribute, - * called with fetched value as argument. - * @param fn {Function} (optional) Function to call on the input string before assessing the length + * @param {Number} limit [optional] Limit to enforce, fallsback to maxLength-attribute, + * called with fetched value as argument. + * @param {Function} fn [optional] Function to call on the string before assessing the length. * @return {jQuery} The context */ - $.fn.byteLimit = function( limit, fn ) { + $.fn.byteLimit = function ( limit, fn ) { // If the first argument is the function, // set fn to the first argument's value and ignore the second argument. if ( $.isFunction( limit ) ) { fn = limit; limit = undefined; + // Either way, verify it is a function so we don't have to call + // isFunction again after this. + } else if ( !fn || !$.isFunction( fn ) ) { + fn = undefined; } - // Default limit to current attribute value - if ( limit === undefined ) { - limit = this.prop( 'maxLength' ); - } + // The following is specific to each element in the collection. + return this.each( function ( i, el ) { + var $el, elLimit, prevSafeVal; - // Update/set attribute value, but only if there is no callback set. - // If there's a callback set, it's possible that the limit being enforced - // is too low (ie. if the callback would return "Foo" for "User:Foo"). - // Usually this isn't a problem since browsers ignore maxLength when setting - // the value property through JavaScript, but Safari 4 violates that rule, so - // we have to remove or not set the property if we have a callback. - if ( fn == undefined ) { - this.prop( 'maxLength', limit ); - } else { - this.removeProp( 'maxLength' ); - } + $el = $( el ); - // Nothing passed and/or empty attribute, return without binding an event. - if ( limit === undefined ) { - return this; - } + // If no limit was passed to byteLimit(), use the maxlength value. + // Can't re-use 'limit' variable because it's in the higher scope + // that would affect the next each() iteration as well. + // Note that we use attribute to read the value instead of property, + // because in Chrome the maxLength property by default returns the + // highest supported value (no indication that it is being enforced + // by choice). We don't want to bind all of this for some ridiculously + // high default number, unless it was explicitly set in the HTML. + // Also cast to a (primitive) number (most commonly because the maxlength + // attribute contains a string, but theoretically the limit parameter + // could be something else as well). + elLimit = Number( limit === undefined ? $el.attr( 'maxlength' ) : limit ); - // Save function for reference - this.data( 'byteLimit-callback', fn ); - - // We've got something, go for it: - return this.keypress( function( e ) { - // First check to see if this is actually a character key - // being pressed. - // Based on key-event info from http://unixpapa.com/js/key.html - // jQuery should also normalize e.which to be consistent cross-browser, - // however the same check is still needed regardless of jQuery. - - // Note: At the moment, for some older opera versions (~< 10.5) - // some special keys won't be recognized (aka left arrow key). - // Backspace will be, so not big issue. - - if ( e.which === 0 || e.charCode === 0 || e.which === 8 || - e.ctrlKey || e.altKey || e.metaKey ) - { - return true; //a special key (backspace, etc) so don't interfere. + // If there is no (valid) limit passed or found in the property, + // skip this. The < 0 check is required for Firefox, which returns + // -1 (instead of undefined) for maxLength if it is not set. + if ( !elLimit || elLimit < 0 ) { + return; } - var val = fn !== undefined ? fn( $( this ).val() ): $( this ).val(), - len = $.byteLength( val ), - // Note that keypress returns a character code point, not a keycode. - // However, this may not be super reliable depending on how keys come in... - charLen = $.byteLength( String.fromCharCode( e.which ) ); + if ( fn ) { + // Save function for reference + $el.data( 'byteLimit.callback', fn ); + } + + // Remove old event handlers (if there are any) + $el.off( '.byteLimit' ); - if ( ( len + charLen ) > limit ) { - e.preventDefault(); + if ( fn ) { + // Disable the native maxLength (if there is any), because it interferes + // with the (differently calculated) byte limit. + // Aside from being differently calculated (average chars with byteLimit + // is lower), we also support a callback which can make it to allow longer + // values (e.g. count "Foo" from "User:Foo"). + // maxLength is a strange property. Removing or setting the property to + // undefined directly doesn't work. Instead, it can only be unset internally + // by the browser when removing the associated attribute (Firefox/Chrome). + // http://code.google.com/p/chromium/issues/detail?id=136004 + $el.removeAttr( 'maxlength' ); + + } else { + // If we don't have a callback the bytelimit can only be lower than the charlimit + // (that is, there are no characters less than 1 byte in size). So lets (re-)enforce + // the native limit for efficiency when possible (it will make the while-loop below + // faster by there being less left to interate over). + $el.attr( 'maxlength', elLimit ); } - }); - }; -} )( jQuery ); + + // Safe base value, used to determine the path between the previous state + // and the state that triggered the event handler below - and enforce the + // limit approppiately (e.g. don't chop from the end if text was inserted + // at the beginning of the string). + prevSafeVal = ''; + + // We need to listen to after the change has already happened because we've + // learned that trying to guess the new value and canceling the event + // accordingly doesn't work because the new value is not always as simple as: + // oldValue + String.fromCharCode( e.which ); because of cut, paste, select-drag + // replacements, and custom input methods and what not. + // Even though we only trim input after it was changed (never prevent it), we do + // listen on events that input text, because there are cases where the text has + // changed while text is being entered and keyup/change will not be fired yet + // (such as holding down a single key, fires keydown, and after each keydown, + // we can trim the previous one). + // See http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order for + // the order and characteristics of the key events. + $el.on( eventKeys, function () { + var res = trimValForByteLength( + prevSafeVal, + this.value, + elLimit, + fn + ); + + // Only set value property if it was trimmed, because whenever the + // value property is set, the browser needs to re-initiate the text context, + // which moves the cursor at the end the input, moving it away from wherever it was. + // This is a side-effect of limiting after the fact. + if ( res.trimmed === true ) { + this.value = res.newVal; + prevSafeVal = res.newVal; + } + } ); + } ); + }; +}( jQuery ) ); diff --git a/resources/jquery/jquery.checkboxShiftClick.js b/resources/jquery/jquery.checkboxShiftClick.js index 0a1d7d7d..1990dc0d 100644 --- a/resources/jquery/jquery.checkboxShiftClick.js +++ b/resources/jquery/jquery.checkboxShiftClick.js @@ -6,23 +6,22 @@ * @author Krinkle <krinklemail@gmail.com> * @license GPL v2 */ -( function( $ ) { -$.fn.checkboxShiftClick = function( text ) { - var prevCheckbox = null; - var $box = this; - // When our boxes are clicked.. - $box.click( function( e ) { - // And one has been clicked before... - if ( prevCheckbox !== null && e.shiftKey ) { - // Check or uncheck this one and all in-between checkboxes - $box.slice( - Math.min( $box.index( prevCheckbox ), $box.index( e.target ) ), - Math.max( $box.index( prevCheckbox ), $box.index( e.target ) ) + 1 - ).prop( 'checked', e.target.checked ? true : false ); - } - // Either way, update the prevCheckbox variable to the one clicked now - prevCheckbox = e.target; - } ); - return $box; -}; -} )( jQuery );
\ No newline at end of file +( function ( $ ) { + $.fn.checkboxShiftClick = function ( text ) { + var prevCheckbox = null, $box = this; + // When our boxes are clicked.. + $box.click( function ( e ) { + // And one has been clicked before... + if ( prevCheckbox !== null && e.shiftKey ) { + // Check or uncheck this one and all in-between checkboxes + $box.slice( + Math.min( $box.index( prevCheckbox ), $box.index( e.target ) ), + Math.max( $box.index( prevCheckbox ), $box.index( e.target ) ) + 1 + ).prop( 'checked', !!e.target.checked ); + } + // Either way, update the prevCheckbox variable to the one clicked now + prevCheckbox = e.target; + } ); + return $box; + }; +}( jQuery ) ); diff --git a/resources/jquery/jquery.client.js b/resources/jquery/jquery.client.js index ae74a324..24f8959e 100644 --- a/resources/jquery/jquery.client.js +++ b/resources/jquery/jquery.client.js @@ -1,7 +1,7 @@ /** * User-agent detection */ -( function( $ ) { +( function ( $ ) { /* Private Members */ @@ -18,7 +18,7 @@ /** * Get an object containing information about the client. * - * @param nav {Object} An object with atleast a 'userAgent' and 'platform' key.= + * @param nav {Object} An object with atleast a 'userAgent' and 'platform' key. * Defaults to the global Navigator object. * @return {Object} The resulting client object will be in the following format: * { @@ -31,7 +31,9 @@ * 'versionNumber': 3.5, * } */ - profile: function( nav ) { + profile: function ( nav ) { + /*jshint boss: true */ + if ( nav === undefined ) { nav = window.navigator; } @@ -64,15 +66,15 @@ // Strings which precede a version number in a user agent string - combined and used as match 1 in // version detectection var versionPrefixes = [ - 'camino', 'chrome', 'firefox', 'netscape', 'netscape6', 'opera', 'version', 'konqueror', 'lynx', - 'msie', 'safari', 'ps3' + 'camino', 'chrome', 'firefox', 'netscape', 'netscape6', 'opera', 'version', 'konqueror', + 'lynx', 'msie', 'safari', 'ps3' ]; // Used as matches 2, 3 and 4 in version extraction - 3 is used as actual version number var versionSuffix = '(\\/|\\;?\\s|)([a-z0-9\\.\\+]*?)(\\;|dev|rel|\\)|\\s|$)'; // Names of known browsers var names = [ - 'camino', 'chrome', 'firefox', 'netscape', 'konqueror', 'lynx', 'msie', 'opera', 'safari', 'ipod', - 'iphone', 'blackberry', 'ps3' + 'camino', 'chrome', 'firefox', 'netscape', 'konqueror', 'lynx', 'msie', 'opera', + 'safari', 'ipod', 'iphone', 'blackberry', 'ps3', 'rekonq' ]; // Tanslations for conforming browser names var nameTranslations = []; @@ -89,9 +91,12 @@ /* Methods */ - // Performs multiple replacements on a string - var translate = function( source, translations ) { - for ( var i = 0; i < translations.length; i++ ) { + /** + * Performs multiple replacements on a string + */ + var translate = function ( source, translations ) { + var i; + for ( i = 0; i < translations.length; i++ ) { source = source.replace( translations[i][0], translations[i][1] ); } return source; @@ -147,13 +152,13 @@ /* Caching */ profileCache[nav.userAgent] = { - 'name': name, - 'layout': layout, - 'layoutVersion': layoutversion, - 'platform': platform, - 'version': version, - 'versionBase': ( version !== x ? Math.floor( versionNumber ).toString() : x ), - 'versionNumber': versionNumber + name: name, + layout: layout, + layoutVersion: layoutversion, + platform: platform, + version: version, + versionBase: ( version !== x ? Math.floor( versionNumber ).toString() : x ), + versionNumber: versionNumber }; } return profileCache[nav.userAgent]; @@ -185,26 +190,30 @@ * * @return Boolean true if browser known or assumed to be supported, false if blacklisted */ - test: function( map, profile ) { + test: function ( map, profile ) { + /*jshint evil:true */ + + var conditions, dir, i, op, val; profile = $.isPlainObject( profile ) ? profile : $.client.profile(); - var dir = $( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'; + dir = $( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'; // Check over each browser condition to determine if we are running in a compatible client - if ( typeof map[dir] !== 'object' || typeof map[dir][profile.name] === 'undefined' ) { + if ( typeof map[dir] !== 'object' || map[dir][profile.name] === undefined ) { // Unknown, so we assume it's working return true; } - var conditions = map[dir][profile.name]; - for ( var i = 0; i < conditions.length; i++ ) { - var op = conditions[i][0]; - var val = conditions[i][1]; + conditions = map[dir][profile.name]; + for ( i = 0; i < conditions.length; i++ ) { + op = conditions[i][0]; + val = conditions[i][1]; if ( val === false ) { return false; - } else if ( typeof val == 'string' ) { + } + if ( typeof val === 'string' ) { if ( !( eval( 'profile.version' + op + '"' + val + '"' ) ) ) { return false; } - } else if ( typeof val == 'number' ) { + } else if ( typeof val === 'number' ) { if ( !( eval( 'profile.versionNumber' + op + val ) ) ) { return false; } @@ -213,4 +222,4 @@ return true; } }; -} )( jQuery ); +}( jQuery ) ); diff --git a/resources/jquery/jquery.collapsibleTabs.js b/resources/jquery/jquery.collapsibleTabs.js index 1784f86a..cb25796f 100644 --- a/resources/jquery/jquery.collapsibleTabs.js +++ b/resources/jquery/jquery.collapsibleTabs.js @@ -1,30 +1,34 @@ -/* +/** * Collapsible tabs jQuery Plugin */ -( function( $ ) { - $.fn.collapsibleTabs = function( options ) { +( function ( $ ) { + $.fn.collapsibleTabs = function ( options ) { // return if the function is called on an empty jquery object - if( !this.length ) return this; - //merge options into the defaults + if ( !this.length ) { + return this; + } + // Merge options into the defaults var $settings = $.extend( {}, $.collapsibleTabs.defaults, options ); - this.each( function() { - var $this = $( this ); + this.each( function () { + var $el = $( this ); // add the element to our array of collapsible managers - $.collapsibleTabs.instances = ( $.collapsibleTabs.instances.length == 0 ? - $this : $.collapsibleTabs.instances.add( $this ) ); + $.collapsibleTabs.instances = ( $.collapsibleTabs.instances.length === 0 ? + $el : $.collapsibleTabs.instances.add( $el ) ); // attach the settings to the elements - $this.data( 'collapsibleTabsSettings', $settings ); + $el.data( 'collapsibleTabsSettings', $settings ); // attach data to our collapsible elements - $this.children( $settings.collapsible ).each( function() { + $el.children( $settings.collapsible ).each( function () { $.collapsibleTabs.addData( $( this ) ); } ); } ); // if we haven't already bound our resize hanlder, bind it now - if( !$.collapsibleTabs.boundEvent ) { + if ( !$.collapsibleTabs.boundEvent ) { $( window ) - .delayedBind( '500', 'resize', function( ) { $.collapsibleTabs.handleResize(); } ); + .delayedBind( '500', 'resize', function ( ) { + $.collapsibleTabs.handleResize(); + } ); } // call our resize handler to setup the page $.collapsibleTabs.handleResize(); @@ -38,63 +42,67 @@ collapsedContainer: '#p-cactions ul', collapsible: 'li.collapsible', shifting: false, - expandCondition: function( eleWidth ) { + expandCondition: function ( eleWidth ) { return ( $( '#left-navigation' ).position().left + $( '#left-navigation' ).width() ) < ( $( '#right-navigation' ).position().left - eleWidth ); }, - collapseCondition: function() { + collapseCondition: function () { return ( $( '#left-navigation' ).position().left + $( '#left-navigation' ).width() ) > $( '#right-navigation' ).position().left; } }, - addData: function( $collapsible ) { + addData: function ( $collapsible ) { var $settings = $collapsible.parent().data( 'collapsibleTabsSettings' ); - if ( $settings != null ) { + if ( $settings !== null ) { $collapsible.data( 'collapsibleTabsSettings', { - 'expandedContainer': $settings.expandedContainer, - 'collapsedContainer': $settings.collapsedContainer, - 'expandedWidth': $collapsible.width(), - 'prevElement': $collapsible.prev() + expandedContainer: $settings.expandedContainer, + collapsedContainer: $settings.collapsedContainer, + expandedWidth: $collapsible.width(), + prevElement: $collapsible.prev() } ); } }, - getSettings: function( $collapsible ) { + getSettings: function ( $collapsible ) { var $settings = $collapsible.data( 'collapsibleTabsSettings' ); - if ( typeof $settings == 'undefined' ) { + if ( $settings === undefined ) { $.collapsibleTabs.addData( $collapsible ); $settings = $collapsible.data( 'collapsibleTabsSettings' ); } return $settings; }, - handleResize: function( e ){ - $.collapsibleTabs.instances.each( function() { - var $this = $( this ), data = $.collapsibleTabs.getSettings( $this ); - if( data.shifting ) return; + handleResize: function ( e ) { + $.collapsibleTabs.instances.each( function () { + var $el = $( this ), + data = $.collapsibleTabs.getSettings( $el ); + + if ( data.shifting ) { + return; + } // if the two navigations are colliding - if( $this.children( data.collapsible ).length > 0 && data.collapseCondition() ) { + if ( $el.children( data.collapsible ).length > 0 && data.collapseCondition() ) { - $this.trigger( "beforeTabCollapse" ); + $el.trigger( 'beforeTabCollapse' ); // move the element to the dropdown menu - $.collapsibleTabs.moveToCollapsed( $this.children( data.collapsible + ':last' ) ); + $.collapsibleTabs.moveToCollapsed( $el.children( data.collapsible + ':last' ) ); } // if there are still moveable items in the dropdown menu, // and there is sufficient space to place them in the tab container - if( $( data.collapsedContainer + ' ' + data.collapsible ).length > 0 + if ( $( data.collapsedContainer + ' ' + data.collapsible ).length > 0 && data.expandCondition( $.collapsibleTabs.getSettings( $( data.collapsedContainer ).children( - data.collapsible+":first" ) ).expandedWidth ) ) { + data.collapsible + ':first' ) ).expandedWidth ) ) { //move the element from the dropdown to the tab - $this.trigger( "beforeTabExpand" ); + $el.trigger( 'beforeTabExpand' ); $.collapsibleTabs - .moveToExpanded( data.collapsedContainer + " " + data.collapsible + ':first' ); + .moveToExpanded( data.collapsedContainer + ' ' + data.collapsible + ':first' ); } }); }, - moveToCollapsed: function( ele ) { - var $moving = $( ele ); - var data = $.collapsibleTabs.getSettings( $moving ); - var dataExp = $.collapsibleTabs.getSettings( data.expandedContainer ); + moveToCollapsed: function ( ele ) { + var $moving = $( ele ), + data = $.collapsibleTabs.getSettings( $moving ), + dataExp = $.collapsibleTabs.getSettings( data.expandedContainer ); dataExp.shifting = true; $moving .detach() @@ -103,10 +111,10 @@ dataExp.shifting = false; $.collapsibleTabs.handleResize(); }, - moveToExpanded: function( ele ) { - var $moving = $( ele ); - var data = $.collapsibleTabs.getSettings( $moving ); - var dataExp = $.collapsibleTabs.getSettings( data.expandedContainer ); + moveToExpanded: function ( ele ) { + var $moving = $( ele ), + data = $.collapsibleTabs.getSettings( $moving ), + dataExp = $.collapsibleTabs.getSettings( data.expandedContainer ); dataExp.shifting = true; // remove this element from where it's at and put it in the dropdown menu $moving.detach().insertAfter( data.prevElement ).data( 'collapsibleTabsSettings', data ); @@ -114,4 +122,5 @@ $.collapsibleTabs.handleResize(); } }; -} )( jQuery ); + +}( jQuery ) ); diff --git a/resources/jquery/jquery.color.js b/resources/jquery/jquery.color.js index 8a619b5c..8bc45c97 100644 --- a/resources/jquery/jquery.color.js +++ b/resources/jquery/jquery.color.js @@ -1,44 +1,54 @@ /** * jQuery Color Animations - * Copyright 2007 John Resig + * + * @author John Resig, 2007 + * @author Krinkle, 2011 * Released under the MIT and GPL licenses. * - * - 2011-01-05: Modified by Krinkle to use the jQuery.colorUtil plugin (which has to be loaded first!) + * - 2011-01-05: Forked for MediaWiki. See also jQuery.colorUtil plugin */ -(function( $ ) { +( function ( $ ) { - // We override the animation for all of these color styles - $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], - function( i, attr ) { - $.fx.step[attr] = function( fx ) { - if ( fx.state == 0 ) { - fx.start = getColor( fx.elem, attr ); - fx.end = $.colorUtil.getRGB( fx.end ); - } - - fx.elem.style[attr] = 'rgb(' + [ - Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0), - Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0), - Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0) - ].join( ',' ) + ')'; - } - } - ); - - function getColor(elem, attr) { + function getColor( elem, attr ) { + /*jshint boss:true */ var color; do { - color = $.curCSS(elem, attr); + color = $.curCSS( elem, attr ); // Keep going until we find an element that has color, or we hit the body - if ( color != '' && color != 'transparent' || $.nodeName(elem, 'body') ) + if ( color !== '' && color !== 'transparent' || $.nodeName( elem, 'body' ) ) { break; + } attr = 'backgroundColor'; } while ( elem = elem.parentNode ); - return $.colorUtil.getRGB(color); - }; + return $.colorUtil.getRGB( color ); + } + + // We override the animation for all of these color styles + $.each([ + 'backgroundColor', + 'borderBottomColor', + 'borderLeftColor', + 'borderRightColor', + 'borderTopColor', + 'color', + 'outlineColor' + ], function ( i, attr ) { + $.fx.step[attr] = function ( fx ) { + if ( fx.state === 0 ) { + fx.start = getColor( fx.elem, attr ); + fx.end = $.colorUtil.getRGB( fx.end ); + } + + fx.elem.style[attr] = 'rgb(' + [ + Math.max( Math.min( parseInt( (fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10 ), 255 ), 0 ), + Math.max( Math.min( parseInt( (fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10 ), 255 ), 0 ), + Math.max( Math.min( parseInt( (fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10 ), 255 ), 0 ) + ].join( ',' ) + ')'; + }; + } ); -} )( jQuery ); +}( jQuery ) ); diff --git a/resources/jquery/jquery.colorUtil.js b/resources/jquery/jquery.colorUtil.js index 1116aec6..c1fe7fe3 100644 --- a/resources/jquery/jquery.colorUtil.js +++ b/resources/jquery/jquery.colorUtil.js @@ -2,192 +2,215 @@ * jQuery Color Utilities * Written by Krinkle in 2011 * Released under the MIT and GPL licenses. - * Mostly based on other plugins and functions (taken through JSLint and optimized a little). - * Sources cited locally. + * Mostly based on other plugins and functions (linted and optimized a little). + * Sources cited inline. */ -( function( $ ) { -$.colorUtil = { - - // Color Conversion function from highlightFade - // By Blair Mitchelmore - // http://jquery.offput.ca/highlightFade/ - // Parse strings looking for color tuples [255,255,255] - getRGB : function( color ) { - var result; - - // Check if we're already dealing with an array of colors - if ( color && color.constructor == Array && color.length == 3 ){ - return color; - } +( function ( $ ) { + $.colorUtil = { - // Look for rgb(num,num,num) - if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) { - return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)]; - } + // Color Conversion function from highlightFade + // By Blair Mitchelmore + // http://jquery.offput.ca/highlightFade/ + // Parse strings looking for color tuples [255,255,255] + getRGB : function ( color ) { + /*jshint boss:true */ + var result; - // Look for rgb(num%,num%,num%) - if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) { - return [parseFloat(result[1],10)*2.55, parseFloat(result[2],10)*2.55, parseFloat(result[3])*2.55]; - } + // Check if we're already dealing with an array of colors + if ( color && $.isArray( color ) && color.length === 3 ) { + return color; + } - // Look for #a0b1c2 - if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) { - return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)]; - } + // Look for rgb(num,num,num) + if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) { + return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)]; + } - // Look for #fff - if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) { - return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)]; - } + // Look for rgb(num%,num%,num%) + if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) { + return [parseFloat(result[1],10)*2.55, parseFloat(result[2],10)*2.55, parseFloat(result[3])*2.55]; + } - // Look for rgba(0, 0, 0, 0) == transparent in Safari 3 - if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) { - return $.colorUtil.colors.transparent; - } + // Look for #a0b1c2 + if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) { + return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)]; + } - // Otherwise, we're most likely dealing with a named color - return $.colorUtil.colors[$.trim(color).toLowerCase()]; - }, - - // Some named colors to work with - // From Interface by Stefan Petre - // http://interface.eyecon.ro/ - colors: { - aqua:[0,255,255], - azure:[240,255,255], - beige:[245,245,220], - black:[0,0,0], - blue:[0,0,255], - brown:[165,42,42], - cyan:[0,255,255], - darkblue:[0,0,139], - darkcyan:[0,139,139], - darkgrey:[169,169,169], - darkgreen:[0,100,0], - darkkhaki:[189,183,107], - darkmagenta:[139,0,139], - darkolivegreen:[85,107,47], - darkorange:[255,140,0], - darkorchid:[153,50,204], - darkred:[139,0,0], - darksalmon:[233,150,122], - darkviolet:[148,0,211], - fuchsia:[255,0,255], - gold:[255,215,0], - green:[0,128,0], - indigo:[75,0,130], - khaki:[240,230,140], - lightblue:[173,216,230], - lightcyan:[224,255,255], - lightgreen:[144,238,144], - lightgrey:[211,211,211], - lightpink:[255,182,193], - lightyellow:[255,255,224], - lime:[0,255,0], - magenta:[255,0,255], - maroon:[128,0,0], - navy:[0,0,128], - olive:[128,128,0], - orange:[255,165,0], - pink:[255,192,203], - purple:[128,0,128], - violet:[128,0,128], - red:[255,0,0], - silver:[192,192,192], - white:[255,255,255], - yellow:[255,255,0], - transparent: [255,255,255] - }, - /** - * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - * Converts an RGB color value to HSL. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSL_color_space. - * Assumes r, g, and b are contained in the set [0, 255] and - * returns h, s, and l in the set [0, 1]. - * - * @param Number R The red color value - * @param Number G The green color value - * @param Number B The blue color value - * @return Array The HSL representation - */ - rgbToHsl: function( R, G, B ) { - var r = R / 255, - g = G / 255, - b = B / 255; - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, l = (max + min) / 2; - - if(max == min){ - h = s = 0; // achromatic - }else{ - var d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch(max){ - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; + // Look for #fff + if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) { + return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)]; + } + + // Look for rgba(0, 0, 0, 0) == transparent in Safari 3 + if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) { + return $.colorUtil.colors.transparent; } - h /= 6; - } - return [h, s, l]; - }, - /** - * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - * Converts an HSL color value to RGB. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSL_color_space. - * Assumes h, s, and l are contained in the set [0, 1] and - * returns r, g, and b in the set [0, 255]. - * - * @param Number h The hue - * @param Number s The saturation - * @param Number l The lightness - * @return Array The RGB representation - */ - hslToRgb: function( h, s, l ) { - var r, g, b; - - if(s === 0){ - r = g = b = l; // achromatic - }else{ - var hue2rgb = function(p, q, t){ - if(t < 0){ t += 1; } - if(t > 1){ t -= 1; } - if(t < 1/6){ return p + (q - p) * 6 * t; } - if(t < 1/2){ return q; } - if(t < 2/3){ return p + (q - p) * (2/3 - t) * 6; } - return p; - }; - - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - r = hue2rgb(p, q, h + 1/3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1/3); + // Otherwise, we're most likely dealing with a named color + return $.colorUtil.colors[$.trim(color).toLowerCase()]; + }, + + // Some named colors to work with + // From Interface by Stefan Petre + // http://interface.eyecon.ro/ + colors: { + aqua: [0,255,255], + azure: [240,255,255], + beige: [245,245,220], + black: [0,0,0], + blue: [0,0,255], + brown: [165,42,42], + cyan: [0,255,255], + darkblue: [0,0,139], + darkcyan: [0,139,139], + darkgrey: [169,169,169], + darkgreen: [0,100,0], + darkkhaki: [189,183,107], + darkmagenta: [139,0,139], + darkolivegreen: [85,107,47], + darkorange: [255,140,0], + darkorchid: [153,50,204], + darkred: [139,0,0], + darksalmon: [233,150,122], + darkviolet: [148,0,211], + fuchsia: [255,0,255], + gold: [255,215,0], + green: [0,128,0], + indigo: [75,0,130], + khaki: [240,230,140], + lightblue: [173,216,230], + lightcyan: [224,255,255], + lightgreen: [144,238,144], + lightgrey: [211,211,211], + lightpink: [255,182,193], + lightyellow: [255,255,224], + lime: [0,255,0], + magenta: [255,0,255], + maroon: [128,0,0], + navy: [0,0,128], + olive: [128,128,0], + orange: [255,165,0], + pink: [255,192,203], + purple: [128,0,128], + violet: [128,0,128], + red: [255,0,0], + silver: [192,192,192], + white: [255,255,255], + yellow: [255,255,0], + transparent: [255,255,255] + }, + + /** + * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + * Converts an RGB color value to HSL. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_color_space. + * Assumes r, g, and b are contained in the set [0, 255] and + * returns h, s, and l in the set [0, 1]. + * + * @param Number R The red color value + * @param Number G The green color value + * @param Number B The blue color value + * @return Array The HSL representation + */ + rgbToHsl: function ( R, G, B ) { + var r = R / 255, + g = G / 255, + b = B / 255; + var max = Math.max( r, g, b ), min = Math.min( r, g, b ); + var h, s, l = (max + min) / 2; + + if ( max === min ) { + // achromatic + h = s = 0; + } else { + var d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch ( max ) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + + return [h, s, l]; + }, + + /** + * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + * Converts an HSL color value to RGB. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_color_space. + * Assumes h, s, and l are contained in the set [0, 1] and + * returns r, g, and b in the set [0, 255]. + * + * @param Number h The hue + * @param Number s The saturation + * @param Number l The lightness + * @return Array The RGB representation + */ + hslToRgb: function ( h, s, l ) { + var r, g, b; + + if ( s === 0 ) { + r = g = b = l; // achromatic + } else { + var hue2rgb = function ( p, q, t ) { + if ( t < 0 ) { + t += 1; + } + if ( t > 1 ) { + t -= 1; + } + if ( t < 1/6 ) { + return p + (q - p) * 6 * t; + } + if ( t < 1/2 ) { + return q; + } + if ( t < 2/3 ) { + return p + (q - p) * (2/3 - t) * 6; + } + return p; + }; + + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = hue2rgb( p, q, h + 1/3 ); + g = hue2rgb( p, q, h ); + b = hue2rgb( p, q, h - 1/3 ); + } + + return [r * 255, g * 255, b * 255]; + }, + + /** + * Get's a brighter or darker rgb() value string. + * + * @author Krinkle + * + * @example getCSSColorMod( 'red', +0.1 ) + * @example getCSSColorMod( 'rgb(200,50,50)', -0.2 ) + * + * @param Mixed currentColor current value in css + * @param Number mod wanted brightness modification between -1 and 1 + * @return String 'rgb(r,g,b)' + */ + getColorBrightness: function ( currentColor, mod ) { + var rgbArr = $.colorUtil.getRGB( currentColor ), + hslArr = $.colorUtil.rgbToHsl(rgbArr[0], rgbArr[1], rgbArr[2] ); + rgbArr = $.colorUtil.hslToRgb(hslArr[0], hslArr[1], hslArr[2]+mod); + + return 'rgb(' + + [parseInt( rgbArr[0], 10), parseInt( rgbArr[1], 10 ), parseInt( rgbArr[2], 10 )].join( ',' ) + + ')'; } - return [r * 255, g * 255, b * 255]; - }, - /** - * Get's a brighter or darker rgb() value string. - * - * @author Krinkle - * - * @example getCSSColorMod( 'red', +0.1 ) - * @example getCSSColorMod( 'rgb(200,50,50)', -0.2 ) - * - * @param Mixed currentColor current value in css - * @param Number mod wanted brightness modification between -1 and 1 - * @return String 'rgb(r,g,b)' - */ - getColorBrightness: function( currentColor, mod ) { - var rgbArr = $.colorUtil.getRGB( currentColor ), - hslArr = $.colorUtil.rgbToHsl(rgbArr[0], rgbArr[1], rgbArr[2] ); - rgbArr = $.colorUtil.hslToRgb(hslArr[0], hslArr[1], hslArr[2]+mod); - return 'rgb(' + - [parseInt( rgbArr[0], 10), parseInt( rgbArr[1], 10 ), parseInt( rgbArr[2], 10 )].join( ',' ) + - ')'; - } - -}; -} )( jQuery );
\ No newline at end of file + }; + +}( jQuery ) ); diff --git a/resources/jquery/jquery.cookie.js b/resources/jquery/jquery.cookie.js index 79317f74..6d5974a2 100644 --- a/resources/jquery/jquery.cookie.js +++ b/resources/jquery/jquery.cookie.js @@ -1,96 +1,47 @@ -/** - * Cookie plugin +/*! + * jQuery Cookie Plugin + * https://github.com/carhartl/jquery-cookie * - * Copyright (c) 2006 Klaus Hartl (stilbuero.de) - * Dual licensed under the MIT and GPL licenses: + * Copyright 2011, Klaus Hartl + * Dual licensed under the MIT or GPL Version 2 licenses. * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * + * http://www.opensource.org/licenses/GPL-2.0 */ +(function($) { + $.cookie = function(key, value, options) { -/** - * Create a cookie with the given name 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 name The name 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 - */ + // key and at least value given, set cookie... + if (arguments.length > 1 && (!/Object/.test(Object.prototype.toString.call(value)) || value === null || value === undefined)) { + options = $.extend({}, options); -/** - * Get the value of a cookie with the given name. - * - * @example $.cookie('the_cookie'); - * @desc Get the value of a cookie. - * - * @param String name The name 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(name, value, options) { - if (typeof value != 'undefined') { // name and value given, set cookie - options = options || {}; - if (value === null) { - value = ''; - options.expires = -1; - } - var expires = ''; - if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { - var date; - if (typeof options.expires == 'number') { - date = new Date(); - date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); - } else { - date = options.expires; + if (value === null || value === undefined) { + options.expires = -1; } - expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE - } - // CAUTION: Needed to parenthesize options.path and options.domain - // in the following expressions, otherwise they evaluate to undefined - // in the packed version for some reason... - var path = options.path ? '; path=' + (options.path) : ''; - var domain = options.domain ? '; domain=' + (options.domain) : ''; - var secure = options.secure ? '; secure' : ''; - document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); - } else { // only name given, get cookie - var cookieValue = null; - if (document.cookie && document.cookie != '') { - var cookies = document.cookie.split(';'); - for (var i = 0; i < cookies.length; i++) { - var cookie = jQuery.trim(cookies[i]); - // Does this cookie string begin with the name we want? - if (cookie.substring(0, name.length + 1) == (name + '=')) { - cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); - break; - } + + if (typeof options.expires === 'number') { + var days = options.expires, t = options.expires = new Date(); + t.setDate(t.getDate() + days); } + + value = String(value); + + return (document.cookie = [ + encodeURIComponent(key), '=', options.raw ? value : encodeURIComponent(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 decode = options.raw ? function(s) { return s; } : decodeURIComponent; + + var pairs = document.cookie.split('; '); + for (var i = 0, pair; pair = pairs[i] && pairs[i].split('='); i++) { + if (decode(pair[0]) === key) return decode(pair[1] || ''); // IE saves cookies with empty string as "c; ", e.g. without "=" as opposed to EOMB, thus pair[1] may be undefined } - return cookieValue; - } -}; + return null; + }; +})(jQuery); diff --git a/resources/jquery/jquery.delayedBind.js b/resources/jquery/jquery.delayedBind.js index d84ee267..5d32b6b0 100644 --- a/resources/jquery/jquery.delayedBind.js +++ b/resources/jquery/jquery.delayedBind.js @@ -1,4 +1,4 @@ -(function( $ ) { +( function ( $ ) { /** * Function that escapes spaces in event names. This is needed because * "_delayedBind-foo bar-1000" refers to two events @@ -18,25 +18,26 @@ $.fn.extend( { * @param data Data to pass to the event handler (optional) * @param callback Function to call */ - delayedBind: function( timeout, event, data, callback ) { - if ( arguments.length == 3 ) { + delayedBind: function ( timeout, event, data, callback ) { + if ( arguments.length === 3 ) { // Shift optional parameter down callback = data; data = undefined; } var encEvent = encodeEvent( event ); - return this.each( function() { + return this.each( function () { var that = this; // Bind the top half // Do this only once for every (event, timeout) pair if ( !( $(this).data( '_delayedBindBound-' + encEvent + '-' + timeout ) ) ) { $(this).data( '_delayedBindBound-' + encEvent + '-' + timeout, true ); - $(this).bind( event, function() { + $(this).bind( event, function () { var timerID = $(this).data( '_delayedBindTimerID-' + encEvent + '-' + timeout ); // Cancel the running timer - if ( typeof timerID != 'undefined' ) + if ( timerID !== null ) { clearTimeout( timerID ); - timerID = setTimeout( function() { + } + timerID = setTimeout( function () { $(that).trigger( '_delayedBind-' + encEvent + '-' + timeout ); }, timeout ); $(this).data( '_delayedBindTimerID-' + encEvent + '-' + timeout, timerID ); @@ -51,23 +52,25 @@ $.fn.extend( { /** * Cancel the timers for delayed events on the selected elements. */ - delayedBindCancel: function( timeout, event ) { + delayedBindCancel: function ( timeout, event ) { var encEvent = encodeEvent( event ); - return this.each( function() { + return this.each( function () { var timerID = $(this).data( '_delayedBindTimerID-' + encEvent + '-' + timeout ); - if ( typeof timerID != 'undefined' ) + if ( timerID !== null ) { clearTimeout( timerID ); + } } ); }, /** * Unbind an event bound with delayedBind() */ - delayedBindUnbind: function( timeout, event, callback ) { + delayedBindUnbind: function ( timeout, event, callback ) { var encEvent = encodeEvent( event ); - return this.each( function() { + return this.each( function () { $(this).unbind( '_delayedBind-' + encEvent + '-' + timeout, callback ); } ); } } ); -} )( jQuery );
\ No newline at end of file + +}( jQuery ) ); diff --git a/resources/jquery/jquery.expandableField.js b/resources/jquery/jquery.expandableField.js index 3c65d016..063f2609 100644 --- a/resources/jquery/jquery.expandableField.js +++ b/resources/jquery/jquery.expandableField.js @@ -14,116 +14,124 @@ * Options: * */ -( function( $ ) { - -$.expandableField = { - /** - * Expand the field, make the callback - */ - expandField: function( e, context ) { - context.config.beforeExpand.call( context.data.$field, context ); - context.data.$field - .animate( { 'width': context.data.expandedWidth }, 'fast', function() { - context.config.afterExpand.call( this, context ); - } ); - }, - /** - * Condense the field, make the callback - */ - condenseField: function( e, context ) { - context.config.beforeCondense.call( context.data.$field, context ); - context.data.$field - .animate( { 'width': context.data.condensedWidth }, 'fast', function() { - context.config.afterCondense.call( this, context ); - } ); - }, - /** - * Sets the value of a property, and updates the widget accordingly - * @param property String Name of property - * @param value Mixed Value to set property with - */ - configure: function( context, property, value ) { - // Validate creation using fallback values - switch( property ) { - default: - context.config[property] = value; - break; - } - } - -}; -$.fn.expandableField = function() { - - // Multi-context fields - var returnValue = null; - var args = arguments; - - $( this ).each( function() { - - /* Construction / Loading */ - - var context = $( this ).data( 'expandableField-context' ); - if ( context == null ) { - context = { - config: { - // callback function for before collapse - 'beforeCondense': function( context ) {}, - // callback function for before expand - 'beforeExpand': function( context ) {}, - // callback function for after collapse - 'afterCondense': function( context ) {}, - // callback function for after expand - 'afterExpand': function( context ) {}, - // Whether the field should expand to the left or the right -- defaults to left - 'expandToLeft': true - } - }; +( function ( $ ) { + + $.expandableField = { + /** + * Expand the field, make the callback + */ + expandField: function ( e, context ) { + context.config.beforeExpand.call( context.data.$field, context ); + context.data.$field + .animate( { 'width': context.data.expandedWidth }, 'fast', function () { + context.config.afterExpand.call( this, context ); + } ); + }, + /** + * Condense the field, make the callback + */ + condenseField: function ( e, context ) { + context.config.beforeCondense.call( context.data.$field, context ); + context.data.$field + .animate( { 'width': context.data.condensedWidth }, 'fast', function () { + context.config.afterCondense.call( this, context ); + } ); + }, + /** + * Sets the value of a property, and updates the widget accordingly + * @param property String Name of property + * @param value Mixed Value to set property with + */ + configure: function ( context, property, value ) { + // TODO: Validate creation using fallback values + context.config[property] = value; } - - /* API */ - // Handle various calling styles - if ( args.length > 0 ) { - if ( typeof args[0] == 'object' ) { - // Apply set of properties - for ( var key in args[0] ) { - $.expandableField.configure( context, key, args[0][key] ); - } - } else if ( typeof args[0] == 'string' ) { - if ( args.length > 1 ) { - // Set property values - $.expandableField.configure( context, args[0], args[1] ); - } else if ( returnValue == null ) { - // Get property values, but don't give access to internal data - returns only the first - returnValue = ( args[0] in context.config ? undefined : context.config[args[0]] ); + + }; + + $.fn.expandableField = function () { + + // Multi-context fields + var returnValue, + args = arguments; + + $( this ).each( function () { + var key, context; + + /* Construction / Loading */ + + context = $( this ).data( 'expandableField-context' ); + + // TODO: Do we need to check both null and undefined? + if ( context === undefined || context === null ) { + context = { + config: { + // callback function for before collapse + beforeCondense: function ( context ) {}, + + // callback function for before expand + beforeExpand: function ( context ) {}, + + // callback function for after collapse + afterCondense: function ( context ) {}, + + // callback function for after expand + afterExpand: function ( context ) {}, + + // Whether the field should expand to the left or the right -- defaults to left + expandToLeft: true + } + }; + } + + /* API */ + // Handle various calling styles + if ( args.length > 0 ) { + if ( typeof args[0] === 'object' ) { + // Apply set of properties + for ( key in args[0] ) { + $.expandableField.configure( context, key, args[0][key] ); + } + } else if ( typeof args[0] === 'string' ) { + if ( args.length > 1 ) { + // Set property values + $.expandableField.configure( context, args[0], args[1] ); + + // TODO: Do we need to check both null and undefined? + } else if ( returnValue === null || returnValue === undefined ) { + // Get property values, but don't give access to internal data - returns only the first + returnValue = ( args[0] in context.config ? undefined : context.config[args[0]] ); + } } } - } - - /* Initialization */ - - if ( typeof context.data == 'undefined' ) { - context.data = { - // The width of the field in it's condensed state - 'condensedWidth': $( this ).width(), - // The width of the field in it's expanded state - 'expandedWidth': $( this ).width() * 2, - // Reference to the field - '$field': $( this ) - }; - - $( this ) - .addClass( 'expandableField' ) - .focus( function( e ) { - $.expandableField.expandField( e, context ); - } ) - .delayedBind( 250, 'blur', function( e ) { - $.expandableField.condenseField( e, context ); - } ); - } - // Store the context for next time - $( this ).data( 'expandableField-context', context ); - } ); - return returnValue !== null ? returnValue : $(this); -}; -} )( jQuery ); + /* Initialization */ + + if ( context.data === undefined ) { + context.data = { + // The width of the field in it's condensed state + condensedWidth: $( this ).width(), + + // The width of the field in it's expanded state + expandedWidth: $( this ).width() * 2, + + // Reference to the field + $field: $( this ) + }; + + $( this ) + .addClass( 'expandableField' ) + .focus( function ( e ) { + $.expandableField.expandField( e, context ); + } ) + .delayedBind( 250, 'blur', function ( e ) { + $.expandableField.condenseField( e, context ); + } ); + } + // Store the context for next time + $( this ).data( 'expandableField-context', context ); + } ); + return returnValue !== undefined ? returnValue : $(this); + }; + +}( jQuery ) ); diff --git a/resources/jquery/jquery.form.js b/resources/jquery/jquery.form.js index fdcdd15a..13e9a55c 100644 --- a/resources/jquery/jquery.form.js +++ b/resources/jquery/jquery.form.js @@ -1,557 +1,677 @@ /*! * jQuery Form Plugin - * version: 2.84 (12-AUG-2011) + * version: 3.14 (30-JUL-2012) * @requires jQuery v1.3.2 or later * * Examples and documentation at: http://malsup.com/jquery/form/ + * Project repository: https://github.com/malsup/form * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html + * http://malsup.github.com/mit-license.txt + * http://malsup.github.com/gpl-license-v2.txt */ +/*global ActiveXObject alert */ ;(function($) { +"use strict"; /* - Usage Note: - ----------- - Do not use both ajaxSubmit and ajaxForm on the same form. These - functions are intended to be exclusive. Use ajaxSubmit if you want - to bind your own submit handler to the form. For example, - - $(document).ready(function() { - $('#myForm').bind('submit', function(e) { - e.preventDefault(); // <-- important - $(this).ajaxSubmit({ - target: '#output' - }); - }); - }); - - Use ajaxForm when you want the plugin to manage all the event binding - for you. For example, - - $(document).ready(function() { - $('#myForm').ajaxForm({ - target: '#output' - }); - }); - - When using ajaxForm, the ajaxSubmit function will be invoked for you - at the appropriate time. + Usage Note: + ----------- + Do not use both ajaxSubmit and ajaxForm on the same form. These + functions are mutually exclusive. Use ajaxSubmit if you want + to bind your own submit handler to the form. For example, + + $(document).ready(function() { + $('#myForm').on('submit', function(e) { + e.preventDefault(); // <-- important + $(this).ajaxSubmit({ + target: '#output' + }); + }); + }); + + Use ajaxForm when you want the plugin to manage all the event binding + for you. For example, + + $(document).ready(function() { + $('#myForm').ajaxForm({ + target: '#output' + }); + }); + + You can also use ajaxForm with delegation (requires jQuery v1.7+), so the + form does not have to exist when you invoke ajaxForm: + + $('#myForm').ajaxForm({ + delegation: true, + target: '#output' + }); + + When using ajaxForm, the ajaxSubmit function will be invoked for you + at the appropriate time. */ /** + * Feature detection + */ +var feature = {}; +feature.fileapi = $("<input type='file'/>").get(0).files !== undefined; +feature.formdata = window.FormData !== undefined; + +/** * ajaxSubmit() provides a mechanism for immediately submitting * an HTML form using AJAX. */ $.fn.ajaxSubmit = function(options) { - // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) - if (!this.length) { - log('ajaxSubmit: skipping submit process - no element selected'); - return this; - } - - var method, action, url, $form = this; - - if (typeof options == 'function') { - options = { success: options }; - } - - method = this.attr('method'); - action = this.attr('action'); - url = (typeof action === 'string') ? $.trim(action) : ''; - url = url || window.location.href || ''; - if (url) { - // clean url (don't include hash vaue) - url = (url.match(/^([^#]+)/)||[])[1]; - } - - options = $.extend(true, { - url: url, - success: $.ajaxSettings.success, - type: method || 'GET', - iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' - }, options); - - // hook for manipulating the form data before it is extracted; - // convenient for use with rich editors like tinyMCE or FCKEditor - var veto = {}; - this.trigger('form-pre-serialize', [this, options, veto]); - if (veto.veto) { - log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); - return this; - } - - // provide opportunity to alter form data before it is serialized - if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { - log('ajaxSubmit: submit aborted via beforeSerialize callback'); - return this; - } - - var n,v,a = this.formToArray(options.semantic); - if (options.data) { - options.extraData = options.data; - for (n in options.data) { - if( $.isArray(options.data[n]) ) { - for (var k in options.data[n]) { - a.push( { name: n, value: options.data[n][k] } ); - } - } - else { - v = options.data[n]; - v = $.isFunction(v) ? v() : v; // if value is fn, invoke it - a.push( { name: n, value: v } ); - } - } - } - - // give pre-submit callback an opportunity to abort the submit - if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { - log('ajaxSubmit: submit aborted via beforeSubmit callback'); - return this; - } - - // fire vetoable 'validate' event - this.trigger('form-submit-validate', [a, this, options, veto]); - if (veto.veto) { - log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); - return this; - } - - var q = $.param(a); - - if (options.type.toUpperCase() == 'GET') { - options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; - options.data = null; // data is null for 'get' - } - else { - options.data = q; // data is the query string for 'post' - } - - var callbacks = []; - if (options.resetForm) { - callbacks.push(function() { $form.resetForm(); }); - } - if (options.clearForm) { - callbacks.push(function() { $form.clearForm(); }); - } - - // perform a load on the target only if dataType is not provided - if (!options.dataType && options.target) { - var oldSuccess = options.success || function(){}; - callbacks.push(function(data) { - var fn = options.replaceTarget ? 'replaceWith' : 'html'; - $(options.target)[fn](data).each(oldSuccess, arguments); - }); - } - else if (options.success) { - callbacks.push(options.success); - } - - options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg - var context = options.context || options; // jQuery 1.4+ supports scope context - for (var i=0, max=callbacks.length; i < max; i++) { - callbacks[i].apply(context, [data, status, xhr || $form, $form]); - } - }; - - // are there files to upload? - var fileInputs = $('input:file', this).length > 0; - var mp = 'multipart/form-data'; - var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); - - // options.iframe allows user to force iframe mode - // 06-NOV-09: now defaulting to iframe mode if file input is detected - if (options.iframe !== false && (fileInputs || options.iframe || multipart)) { - // hack to fix Safari hang (thanks to Tim Molendijk for this) - // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d - if (options.closeKeepAlive) { - $.get(options.closeKeepAlive, function() { fileUpload(a); }); - } - else { - fileUpload(a); - } - } - else { - // IE7 massage (see issue 57) - if ($.browser.msie && method == 'get') { - var ieMeth = $form[0].getAttribute('method'); - if (typeof ieMeth === 'string') - options.type = ieMeth; - } - $.ajax(options); - } - - // fire 'notify' event - this.trigger('form-submit-notify', [this, options]); - return this; - - - // private function for handling file uploads (hat tip to YAHOO!) - function fileUpload(a) { - var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle; + /*jshint scripturl:true */ + + // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) + if (!this.length) { + log('ajaxSubmit: skipping submit process - no element selected'); + return this; + } + + var method, action, url, $form = this; + + if (typeof options == 'function') { + options = { success: options }; + } + + method = this.attr('method'); + action = this.attr('action'); + url = (typeof action === 'string') ? $.trim(action) : ''; + url = url || window.location.href || ''; + if (url) { + // clean url (don't include hash vaue) + url = (url.match(/^([^#]+)/)||[])[1]; + } + + options = $.extend(true, { + url: url, + success: $.ajaxSettings.success, + type: method || 'GET', + iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' + }, options); + + // hook for manipulating the form data before it is extracted; + // convenient for use with rich editors like tinyMCE or FCKEditor + var veto = {}; + this.trigger('form-pre-serialize', [this, options, veto]); + if (veto.veto) { + log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); + return this; + } + + // provide opportunity to alter form data before it is serialized + if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { + log('ajaxSubmit: submit aborted via beforeSerialize callback'); + return this; + } + + var traditional = options.traditional; + if ( traditional === undefined ) { + traditional = $.ajaxSettings.traditional; + } + + var elements = []; + var qx, a = this.formToArray(options.semantic, elements); + if (options.data) { + options.extraData = options.data; + qx = $.param(options.data, traditional); + } + + // give pre-submit callback an opportunity to abort the submit + if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { + log('ajaxSubmit: submit aborted via beforeSubmit callback'); + return this; + } + + // fire vetoable 'validate' event + this.trigger('form-submit-validate', [a, this, options, veto]); + if (veto.veto) { + log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); + return this; + } + + var q = $.param(a, traditional); + if (qx) { + q = ( q ? (q + '&' + qx) : qx ); + } + if (options.type.toUpperCase() == 'GET') { + options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; + options.data = null; // data is null for 'get' + } + else { + options.data = q; // data is the query string for 'post' + } + + var callbacks = []; + if (options.resetForm) { + callbacks.push(function() { $form.resetForm(); }); + } + if (options.clearForm) { + callbacks.push(function() { $form.clearForm(options.includeHidden); }); + } + + // perform a load on the target only if dataType is not provided + if (!options.dataType && options.target) { + var oldSuccess = options.success || function(){}; + callbacks.push(function(data) { + var fn = options.replaceTarget ? 'replaceWith' : 'html'; + $(options.target)[fn](data).each(oldSuccess, arguments); + }); + } + else if (options.success) { + callbacks.push(options.success); + } + + options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg + var context = options.context || this ; // jQuery 1.4+ supports scope context + for (var i=0, max=callbacks.length; i < max; i++) { + callbacks[i].apply(context, [data, status, xhr || $form, $form]); + } + }; + + // are there files to upload? + var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113) + var hasFileInputs = fileInputs.length > 0; + var mp = 'multipart/form-data'; + var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); + + var fileAPI = feature.fileapi && feature.formdata; + log("fileAPI :" + fileAPI); + var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI; + + // options.iframe allows user to force iframe mode + // 06-NOV-09: now defaulting to iframe mode if file input is detected + if (options.iframe !== false && (options.iframe || shouldUseFrame)) { + // hack to fix Safari hang (thanks to Tim Molendijk for this) + // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d + if (options.closeKeepAlive) { + $.get(options.closeKeepAlive, function() { + fileUploadIframe(a); + }); + } + else { + fileUploadIframe(a); + } + } + else if ((hasFileInputs || multipart) && fileAPI) { + fileUploadXhr(a); + } + else { + $.ajax(options); + } + + // clear element array + for (var k=0; k < elements.length; k++) + elements[k] = null; + + // fire 'notify' event + this.trigger('form-submit-notify', [this, options]); + return this; + + // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz) + function fileUploadXhr(a) { + var formdata = new FormData(); + + for (var i=0; i < a.length; i++) { + formdata.append(a[i].name, a[i].value); + } + + if (options.extraData) { + for (var p in options.extraData) + if (options.extraData.hasOwnProperty(p)) + formdata.append(p, options.extraData[p]); + } + + options.data = null; + + var s = $.extend(true, {}, $.ajaxSettings, options, { + contentType: false, + processData: false, + cache: false, + type: 'POST' + }); + + if (options.uploadProgress) { + // workaround because jqXHR does not expose upload property + s.xhr = function() { + var xhr = jQuery.ajaxSettings.xhr(); + if (xhr.upload) { + xhr.upload.onprogress = function(event) { + var percent = 0; + var position = event.loaded || event.position; /*event.position is deprecated*/ + var total = event.total; + if (event.lengthComputable) { + percent = Math.ceil(position / total * 100); + } + options.uploadProgress(event, position, total, percent); + }; + } + return xhr; + }; + } + + s.data = null; + var beforeSend = s.beforeSend; + s.beforeSend = function(xhr, o) { + o.data = formdata; + if(beforeSend) + beforeSend.call(this, xhr, o); + }; + $.ajax(s); + } + + // private function for handling file uploads (hat tip to YAHOO!) + function fileUploadIframe(a) { + var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle; var useProp = !!$.fn.prop; + if ($(':input[name=submit],:input[id=submit]', form).length) { + // if there is an input with a name or id of 'submit' then we won't be + // able to invoke the submit fn on the form (at least not x-browser) + alert('Error: Form elements must not have name or id of "submit".'); + return; + } + if (a) { - // ensure that every serialized input is still enabled - for (i=0; i < a.length; i++) { - el = $(form[a[i].name]); - el[ useProp ? 'prop' : 'attr' ]('disabled', false); - } - } - - if ($(':input[name=submit],:input[id=submit]', form).length) { - // if there is an input with a name or id of 'submit' then we won't be - // able to invoke the submit fn on the form (at least not x-browser) - alert('Error: Form elements must not have name or id of "submit".'); - return; - } - - s = $.extend(true, {}, $.ajaxSettings, options); - s.context = s.context || s; - id = 'jqFormIO' + (new Date().getTime()); - if (s.iframeTarget) { - $io = $(s.iframeTarget); - n = $io.attr('name'); - if (n == null) - $io.attr('name', id); - else - id = n; - } - else { - $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />'); - $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); - } - io = $io[0]; - - - xhr = { // mock object - aborted: 0, - responseText: null, - responseXML: null, - status: 0, - statusText: 'n/a', - getAllResponseHeaders: function() {}, - getResponseHeader: function() {}, - setRequestHeader: function() {}, - abort: function(status) { - var e = (status === 'timeout' ? 'timeout' : 'aborted'); - log('aborting upload... ' + e); - this.aborted = 1; - $io.attr('src', s.iframeSrc); // abort op in progress - xhr.error = e; - s.error && s.error.call(s.context, xhr, e, status); - g && $.event.trigger("ajaxError", [xhr, s, e]); - s.complete && s.complete.call(s.context, xhr, e); - } - }; - - g = s.global; - // trigger ajax global events so that activity/block indicators work like normal - if (g && ! $.active++) { - $.event.trigger("ajaxStart"); - } - if (g) { - $.event.trigger("ajaxSend", [xhr, s]); - } - - if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) { - if (s.global) { - $.active--; - } - return; - } - if (xhr.aborted) { - return; - } - - // add submitting element to data if we know it - sub = form.clk; - if (sub) { - n = sub.name; - if (n && !sub.disabled) { - s.extraData = s.extraData || {}; - s.extraData[n] = sub.value; - if (sub.type == "image") { - s.extraData[n+'.x'] = form.clk_x; - s.extraData[n+'.y'] = form.clk_y; - } - } - } - - var CLIENT_TIMEOUT_ABORT = 1; - var SERVER_ABORT = 2; - - function getDoc(frame) { - var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document; - return doc; - } - - // take a breath so that pending repaints get some cpu time before the upload starts - function doSubmit() { - // make sure form attrs are set - var t = $form.attr('target'), a = $form.attr('action'); - - // update form attrs in IE friendly way - form.setAttribute('target',id); - if (!method) { - form.setAttribute('method', 'POST'); - } - if (a != s.url) { - form.setAttribute('action', s.url); - } - - // ie borks in some cases when setting encoding - if (! s.skipEncodingOverride && (!method || /post/i.test(method))) { - $form.attr({ - encoding: 'multipart/form-data', - enctype: 'multipart/form-data' - }); - } - - // support timout - if (s.timeout) { - timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout); - } - - // look for server aborts - function checkState() { - try { - var state = getDoc(io).readyState; - log('state = ' + state); - if (state.toLowerCase() == 'uninitialized') - setTimeout(checkState,50); - } - catch(e) { - log('Server abort: ' , e, ' (', e.name, ')'); - cb(SERVER_ABORT); - timeoutHandle && clearTimeout(timeoutHandle); - timeoutHandle = undefined; - } - } - - // add "extra" data to form if provided in options - var extraInputs = []; - try { - if (s.extraData) { - for (var n in s.extraData) { - extraInputs.push( - $('<input type="hidden" name="'+n+'" />').attr('value',s.extraData[n]) - .appendTo(form)[0]); - } - } - - if (!s.iframeTarget) { - // add iframe to doc and submit the form - $io.appendTo('body'); - io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false); - } - setTimeout(checkState,15); - form.submit(); - } - finally { - // reset attrs and remove "extra" input elements - form.setAttribute('action',a); - if(t) { - form.setAttribute('target', t); - } else { - $form.removeAttr('target'); - } - $(extraInputs).remove(); - } - } - - if (s.forceSync) { - doSubmit(); - } - else { - setTimeout(doSubmit, 10); // this lets dom updates render - } - - var data, doc, domCheckCount = 50, callbackProcessed; - - function cb(e) { - if (xhr.aborted || callbackProcessed) { - return; - } - try { - doc = getDoc(io); - } - catch(ex) { - log('cannot access response document: ', ex); - e = SERVER_ABORT; - } - if (e === CLIENT_TIMEOUT_ABORT && xhr) { - xhr.abort('timeout'); - return; - } - else if (e == SERVER_ABORT && xhr) { - xhr.abort('server abort'); - return; - } - - if (!doc || doc.location.href == s.iframeSrc) { - // response not received yet - if (!timedOut) - return; - } - io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false); - - var status = 'success', errMsg; - try { - if (timedOut) { - throw 'timeout'; - } - - var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc); - log('isXml='+isXml); - if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) { - if (--domCheckCount) { - // in some browsers (Opera) the iframe DOM is not always traversable when - // the onload callback fires, so we loop a bit to accommodate - log('requeing onLoad callback, DOM not available'); - setTimeout(cb, 250); - return; - } - // let this fall through because server response could be an empty document - //log('Could not access iframe DOM after mutiple tries.'); - //throw 'DOMException: not available'; - } - - //log('response detected'); + // ensure that every serialized input is still enabled + for (i=0; i < elements.length; i++) { + el = $(elements[i]); + if ( useProp ) + el.prop('disabled', false); + else + el.removeAttr('disabled'); + } + } + + s = $.extend(true, {}, $.ajaxSettings, options); + s.context = s.context || s; + id = 'jqFormIO' + (new Date().getTime()); + if (s.iframeTarget) { + $io = $(s.iframeTarget); + n = $io.attr('name'); + if (!n) + $io.attr('name', id); + else + id = n; + } + else { + $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />'); + $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); + } + io = $io[0]; + + + xhr = { // mock object + aborted: 0, + responseText: null, + responseXML: null, + status: 0, + statusText: 'n/a', + getAllResponseHeaders: function() {}, + getResponseHeader: function() {}, + setRequestHeader: function() {}, + abort: function(status) { + var e = (status === 'timeout' ? 'timeout' : 'aborted'); + log('aborting upload... ' + e); + this.aborted = 1; + // #214 + if (io.contentWindow.document.execCommand) { + try { // #214 + io.contentWindow.document.execCommand('Stop'); + } catch(ignore) {} + } + $io.attr('src', s.iframeSrc); // abort op in progress + xhr.error = e; + if (s.error) + s.error.call(s.context, xhr, e, status); + if (g) + $.event.trigger("ajaxError", [xhr, s, e]); + if (s.complete) + s.complete.call(s.context, xhr, e); + } + }; + + g = s.global; + // trigger ajax global events so that activity/block indicators work like normal + if (g && 0 === $.active++) { + $.event.trigger("ajaxStart"); + } + if (g) { + $.event.trigger("ajaxSend", [xhr, s]); + } + + if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) { + if (s.global) { + $.active--; + } + return; + } + if (xhr.aborted) { + return; + } + + // add submitting element to data if we know it + sub = form.clk; + if (sub) { + n = sub.name; + if (n && !sub.disabled) { + s.extraData = s.extraData || {}; + s.extraData[n] = sub.value; + if (sub.type == "image") { + s.extraData[n+'.x'] = form.clk_x; + s.extraData[n+'.y'] = form.clk_y; + } + } + } + + var CLIENT_TIMEOUT_ABORT = 1; + var SERVER_ABORT = 2; + + function getDoc(frame) { + var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document; + return doc; + } + + // Rails CSRF hack (thanks to Yvan Barthelemy) + var csrf_token = $('meta[name=csrf-token]').attr('content'); + var csrf_param = $('meta[name=csrf-param]').attr('content'); + if (csrf_param && csrf_token) { + s.extraData = s.extraData || {}; + s.extraData[csrf_param] = csrf_token; + } + + // take a breath so that pending repaints get some cpu time before the upload starts + function doSubmit() { + // make sure form attrs are set + var t = $form.attr('target'), a = $form.attr('action'); + + // update form attrs in IE friendly way + form.setAttribute('target',id); + if (!method) { + form.setAttribute('method', 'POST'); + } + if (a != s.url) { + form.setAttribute('action', s.url); + } + + // ie borks in some cases when setting encoding + if (! s.skipEncodingOverride && (!method || /post/i.test(method))) { + $form.attr({ + encoding: 'multipart/form-data', + enctype: 'multipart/form-data' + }); + } + + // support timout + if (s.timeout) { + timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout); + } + + // look for server aborts + function checkState() { + try { + var state = getDoc(io).readyState; + log('state = ' + state); + if (state && state.toLowerCase() == 'uninitialized') + setTimeout(checkState,50); + } + catch(e) { + log('Server abort: ' , e, ' (', e.name, ')'); + cb(SERVER_ABORT); + if (timeoutHandle) + clearTimeout(timeoutHandle); + timeoutHandle = undefined; + } + } + + // add "extra" data to form if provided in options + var extraInputs = []; + try { + if (s.extraData) { + for (var n in s.extraData) { + if (s.extraData.hasOwnProperty(n)) { + // if using the $.param format that allows for multiple values with the same name + if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) { + extraInputs.push( + $('<input type="hidden" name="'+s.extraData[n].name+'">').attr('value',s.extraData[n].value) + .appendTo(form)[0]); + } else { + extraInputs.push( + $('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n]) + .appendTo(form)[0]); + } + } + } + } + + if (!s.iframeTarget) { + // add iframe to doc and submit the form + $io.appendTo('body'); + if (io.attachEvent) + io.attachEvent('onload', cb); + else + io.addEventListener('load', cb, false); + } + setTimeout(checkState,15); + form.submit(); + } + finally { + // reset attrs and remove "extra" input elements + form.setAttribute('action',a); + if(t) { + form.setAttribute('target', t); + } else { + $form.removeAttr('target'); + } + $(extraInputs).remove(); + } + } + + if (s.forceSync) { + doSubmit(); + } + else { + setTimeout(doSubmit, 10); // this lets dom updates render + } + + var data, doc, domCheckCount = 50, callbackProcessed; + + function cb(e) { + if (xhr.aborted || callbackProcessed) { + return; + } + try { + doc = getDoc(io); + } + catch(ex) { + log('cannot access response document: ', ex); + e = SERVER_ABORT; + } + if (e === CLIENT_TIMEOUT_ABORT && xhr) { + xhr.abort('timeout'); + return; + } + else if (e == SERVER_ABORT && xhr) { + xhr.abort('server abort'); + return; + } + + if (!doc || doc.location.href == s.iframeSrc) { + // response not received yet + if (!timedOut) + return; + } + if (io.detachEvent) + io.detachEvent('onload', cb); + else + io.removeEventListener('load', cb, false); + + var status = 'success', errMsg; + try { + if (timedOut) { + throw 'timeout'; + } + + var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc); + log('isXml='+isXml); + if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) { + if (--domCheckCount) { + // in some browsers (Opera) the iframe DOM is not always traversable when + // the onload callback fires, so we loop a bit to accommodate + log('requeing onLoad callback, DOM not available'); + setTimeout(cb, 250); + return; + } + // let this fall through because server response could be an empty document + //log('Could not access iframe DOM after mutiple tries.'); + //throw 'DOMException: not available'; + } + + //log('response detected'); var docRoot = doc.body ? doc.body : doc.documentElement; xhr.responseText = docRoot ? docRoot.innerHTML : null; - xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; - if (isXml) - s.dataType = 'xml'; - xhr.getResponseHeader = function(header){ - var headers = {'content-type': s.dataType}; - return headers[header]; - }; + xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; + if (isXml) + s.dataType = 'xml'; + xhr.getResponseHeader = function(header){ + var headers = {'content-type': s.dataType}; + return headers[header]; + }; // support for XHR 'status' & 'statusText' emulation : if (docRoot) { xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status; xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText; } - var dt = s.dataType || ''; - var scr = /(json|script|text)/.test(dt.toLowerCase()); - if (scr || s.textarea) { - // see if user embedded response in textarea - var ta = doc.getElementsByTagName('textarea')[0]; - if (ta) { - xhr.responseText = ta.value; + var dt = (s.dataType || '').toLowerCase(); + var scr = /(json|script|text)/.test(dt); + if (scr || s.textarea) { + // see if user embedded response in textarea + var ta = doc.getElementsByTagName('textarea')[0]; + if (ta) { + xhr.responseText = ta.value; // support for XHR 'status' & 'statusText' emulation : xhr.status = Number( ta.getAttribute('status') ) || xhr.status; xhr.statusText = ta.getAttribute('statusText') || xhr.statusText; - } - else if (scr) { - // account for browsers injecting pre around json response - var pre = doc.getElementsByTagName('pre')[0]; - var b = doc.getElementsByTagName('body')[0]; - if (pre) { - xhr.responseText = pre.textContent ? pre.textContent : pre.innerHTML; - } - else if (b) { - xhr.responseText = b.innerHTML; - } - } - } - else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) { - xhr.responseXML = toXml(xhr.responseText); - } + } + else if (scr) { + // account for browsers injecting pre around json response + var pre = doc.getElementsByTagName('pre')[0]; + var b = doc.getElementsByTagName('body')[0]; + if (pre) { + xhr.responseText = pre.textContent ? pre.textContent : pre.innerText; + } + else if (b) { + xhr.responseText = b.textContent ? b.textContent : b.innerText; + } + } + } + else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) { + xhr.responseXML = toXml(xhr.responseText); + } try { - data = httpData(xhr, s.dataType, s); + data = httpData(xhr, dt, s); } catch (e) { status = 'parsererror'; xhr.error = errMsg = (e || status); } - } - catch (e) { - log('error caught: ',e); - status = 'error'; + } + catch (e) { + log('error caught: ',e); + status = 'error'; xhr.error = errMsg = (e || status); - } + } - if (xhr.aborted) { - log('upload aborted'); - status = null; - } + if (xhr.aborted) { + log('upload aborted'); + status = null; + } if (xhr.status) { // we've set xhr.status status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error'; } - // ordering of these callbacks/triggers is odd, but that's how $.ajax does it - if (status === 'success') { - s.success && s.success.call(s.context, data, 'success', xhr); - g && $.event.trigger("ajaxSuccess", [xhr, s]); - } + // ordering of these callbacks/triggers is odd, but that's how $.ajax does it + if (status === 'success') { + if (s.success) + s.success.call(s.context, data, 'success', xhr); + if (g) + $.event.trigger("ajaxSuccess", [xhr, s]); + } else if (status) { - if (errMsg == undefined) - errMsg = xhr.statusText; - s.error && s.error.call(s.context, xhr, status, errMsg); - g && $.event.trigger("ajaxError", [xhr, s, errMsg]); - } - - g && $.event.trigger("ajaxComplete", [xhr, s]); - - if (g && ! --$.active) { - $.event.trigger("ajaxStop"); - } - - s.complete && s.complete.call(s.context, xhr, status); - - callbackProcessed = true; - if (s.timeout) - clearTimeout(timeoutHandle); - - // clean up - setTimeout(function() { - if (!s.iframeTarget) - $io.remove(); - xhr.responseXML = null; - }, 100); - } - - var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+) - if (window.ActiveXObject) { - doc = new ActiveXObject('Microsoft.XMLDOM'); - doc.async = 'false'; - doc.loadXML(s); - } - else { - doc = (new DOMParser()).parseFromString(s, 'text/xml'); - } - return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null; - }; - var parseJSON = $.parseJSON || function(s) { - return window['eval']('(' + s + ')'); - }; - - var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4 - - var ct = xhr.getResponseHeader('content-type') || '', - xml = type === 'xml' || !type && ct.indexOf('xml') >= 0, - data = xml ? xhr.responseXML : xhr.responseText; - - if (xml && data.documentElement.nodeName === 'parsererror') { - $.error && $.error('parsererror'); - } - if (s && s.dataFilter) { - data = s.dataFilter(data, type); - } - if (typeof data === 'string') { - if (type === 'json' || !type && ct.indexOf('json') >= 0) { - data = parseJSON(data); - } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) { - $.globalEval(data); - } - } - return data; - }; - } + if (errMsg === undefined) + errMsg = xhr.statusText; + if (s.error) + s.error.call(s.context, xhr, status, errMsg); + if (g) + $.event.trigger("ajaxError", [xhr, s, errMsg]); + } + + if (g) + $.event.trigger("ajaxComplete", [xhr, s]); + + if (g && ! --$.active) { + $.event.trigger("ajaxStop"); + } + + if (s.complete) + s.complete.call(s.context, xhr, status); + + callbackProcessed = true; + if (s.timeout) + clearTimeout(timeoutHandle); + + // clean up + setTimeout(function() { + if (!s.iframeTarget) + $io.remove(); + xhr.responseXML = null; + }, 100); + } + + var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+) + if (window.ActiveXObject) { + doc = new ActiveXObject('Microsoft.XMLDOM'); + doc.async = 'false'; + doc.loadXML(s); + } + else { + doc = (new DOMParser()).parseFromString(s, 'text/xml'); + } + return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null; + }; + var parseJSON = $.parseJSON || function(s) { + /*jslint evil:true */ + return window['eval']('(' + s + ')'); + }; + + var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4 + + var ct = xhr.getResponseHeader('content-type') || '', + xml = type === 'xml' || !type && ct.indexOf('xml') >= 0, + data = xml ? xhr.responseXML : xhr.responseText; + + if (xml && data.documentElement.nodeName === 'parsererror') { + if ($.error) + $.error('parsererror'); + } + if (s && s.dataFilter) { + data = s.dataFilter(data, type); + } + if (typeof data === 'string') { + if (type === 'json' || !type && ct.indexOf('json') >= 0) { + data = parseJSON(data); + } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) { + $.globalEval(data); + } + } + return data; + }; + } }; /** @@ -560,9 +680,9 @@ $.fn.ajaxSubmit = function(options) { * The advantages of using this method instead of ajaxSubmit() are: * * 1: This method will include coordinates for <input type="image" /> elements (if the element - * is used to submit the form). + * is used to submit the form). * 2. This method will include the submit element's name/value data (for the element that was - * used to submit the form). + * used to submit the form). * 3. This method binds the submit() method to the form for you. * * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely @@ -570,60 +690,83 @@ $.fn.ajaxSubmit = function(options) { * the form itself. */ $.fn.ajaxForm = function(options) { - // in jQuery 1.3+ we can fix mistakes with the ready state - if (this.length === 0) { - var o = { s: this.selector, c: this.context }; - if (!$.isReady && o.s) { - log('DOM not ready, queuing ajaxForm'); - $(function() { - $(o.s,o.c).ajaxForm(options); - }); - return this; - } - // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready() - log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)')); - return this; - } - - return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) { - if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed - e.preventDefault(); - $(this).ajaxSubmit(options); - } - }).bind('click.form-plugin', function(e) { - var target = e.target; - var $el = $(target); - if (!($el.is(":submit,input:image"))) { - // is this a child element of the submit el? (ex: a span within a button) - var t = $el.closest(':submit'); - if (t.length == 0) { - return; - } - target = t[0]; - } - var form = this; - form.clk = target; - if (target.type == 'image') { - if (e.offsetX != undefined) { - form.clk_x = e.offsetX; - form.clk_y = e.offsetY; - } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin - var offset = $el.offset(); - form.clk_x = e.pageX - offset.left; - form.clk_y = e.pageY - offset.top; - } else { - form.clk_x = e.pageX - target.offsetLeft; - form.clk_y = e.pageY - target.offsetTop; - } - } - // clear form vars - setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100); - }); + options = options || {}; + options.delegation = options.delegation && $.isFunction($.fn.on); + + // in jQuery 1.3+ we can fix mistakes with the ready state + if (!options.delegation && this.length === 0) { + var o = { s: this.selector, c: this.context }; + if (!$.isReady && o.s) { + log('DOM not ready, queuing ajaxForm'); + $(function() { + $(o.s,o.c).ajaxForm(options); + }); + return this; + } + // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready() + log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)')); + return this; + } + + if ( options.delegation ) { + $(document) + .off('submit.form-plugin', this.selector, doAjaxSubmit) + .off('click.form-plugin', this.selector, captureSubmittingElement) + .on('submit.form-plugin', this.selector, options, doAjaxSubmit) + .on('click.form-plugin', this.selector, options, captureSubmittingElement); + return this; + } + + return this.ajaxFormUnbind() + .bind('submit.form-plugin', options, doAjaxSubmit) + .bind('click.form-plugin', options, captureSubmittingElement); }; +// private event handlers +function doAjaxSubmit(e) { + /*jshint validthis:true */ + var options = e.data; + if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed + e.preventDefault(); + $(this).ajaxSubmit(options); + } +} + +function captureSubmittingElement(e) { + /*jshint validthis:true */ + var target = e.target; + var $el = $(target); + if (!($el.is(":submit,input:image"))) { + // is this a child element of the submit el? (ex: a span within a button) + var t = $el.closest(':submit'); + if (t.length === 0) { + return; + } + target = t[0]; + } + var form = this; + form.clk = target; + if (target.type == 'image') { + if (e.offsetX !== undefined) { + form.clk_x = e.offsetX; + form.clk_y = e.offsetY; + } else if (typeof $.fn.offset == 'function') { + var offset = $el.offset(); + form.clk_x = e.pageX - offset.left; + form.clk_y = e.pageY - offset.top; + } else { + form.clk_x = e.pageX - target.offsetLeft; + form.clk_y = e.pageY - target.offsetTop; + } + } + // clear form vars + setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100); +} + + // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm $.fn.ajaxFormUnbind = function() { - return this.unbind('submit.form-plugin click.form-plugin'); + return this.unbind('submit.form-plugin click.form-plugin'); }; /** @@ -637,56 +780,74 @@ $.fn.ajaxFormUnbind = function() { * It is this array that is passed to pre-submit callback functions provided to the * ajaxSubmit() and ajaxForm() methods. */ -$.fn.formToArray = function(semantic) { - var a = []; - if (this.length === 0) { - return a; - } - - var form = this[0]; - var els = semantic ? form.getElementsByTagName('*') : form.elements; - if (!els) { - return a; - } - - var i,j,n,v,el,max,jmax; - for(i=0, max=els.length; i < max; i++) { - el = els[i]; - n = el.name; - if (!n) { - continue; - } - - if (semantic && form.clk && el.type == "image") { - // handle image inputs on the fly when semantic == true - if(!el.disabled && form.clk == el) { - a.push({name: n, value: $(el).val()}); - a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); - } - continue; - } - - v = $.fieldValue(el, true); - if (v && v.constructor == Array) { - for(j=0, jmax=v.length; j < jmax; j++) { - a.push({name: n, value: v[j]}); - } - } - else if (v !== null && typeof v != 'undefined') { - a.push({name: n, value: v}); - } - } - - if (!semantic && form.clk) { - // input type=='image' are not found in elements array! handle it here - var $input = $(form.clk), input = $input[0]; - n = input.name; - if (n && !input.disabled && input.type == 'image') { - a.push({name: n, value: $input.val()}); - a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); - } - } - return a; +$.fn.formToArray = function(semantic, elements) { + var a = []; + if (this.length === 0) { + return a; + } + + var form = this[0]; + var els = semantic ? form.getElementsByTagName('*') : form.elements; + if (!els) { + return a; + } + + var i,j,n,v,el,max,jmax; + for(i=0, max=els.length; i < max; i++) { + el = els[i]; + n = el.name; + if (!n) { + continue; + } + + if (semantic && form.clk && el.type == "image") { + // handle image inputs on the fly when semantic == true + if(!el.disabled && form.clk == el) { + a.push({name: n, value: $(el).val(), type: el.type }); + a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); + } + continue; + } + + v = $.fieldValue(el, true); + if (v && v.constructor == Array) { + if (elements) + elements.push(el); + for(j=0, jmax=v.length; j < jmax; j++) { + a.push({name: n, value: v[j]}); + } + } + else if (feature.fileapi && el.type == 'file' && !el.disabled) { + if (elements) + elements.push(el); + var files = el.files; + if (files.length) { + for (j=0; j < files.length; j++) { + a.push({name: n, value: files[j], type: el.type}); + } + } + else { + // #180 + a.push({ name: n, value: '', type: el.type }); + } + } + else if (v !== null && typeof v != 'undefined') { + if (elements) + elements.push(el); + a.push({name: n, value: v, type: el.type, required: el.required}); + } + } + + if (!semantic && form.clk) { + // input type=='image' are not found in elements array! handle it here + var $input = $(form.clk), input = $input[0]; + n = input.name; + if (n && !input.disabled && input.type == 'image') { + a.push({name: n, value: $input.val()}); + a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); + } + } + return a; }; /** @@ -694,8 +855,8 @@ $.fn.formToArray = function(semantic) { * in the format: name1=value1&name2=value2 */ $.fn.formSerialize = function(semantic) { - //hand off to jQuery.param for proper encoding - return $.param(this.formToArray(semantic)); + //hand off to jQuery.param for proper encoding + return $.param(this.formToArray(semantic)); }; /** @@ -703,36 +864,36 @@ $.fn.formSerialize = function(semantic) { * This method will return a string in the format: name1=value1&name2=value2 */ $.fn.fieldSerialize = function(successful) { - var a = []; - this.each(function() { - var n = this.name; - if (!n) { - return; - } - var v = $.fieldValue(this, successful); - if (v && v.constructor == Array) { - for (var i=0,max=v.length; i < max; i++) { - a.push({name: n, value: v[i]}); - } - } - else if (v !== null && typeof v != 'undefined') { - a.push({name: this.name, value: v}); - } - }); - //hand off to jQuery.param for proper encoding - return $.param(a); + var a = []; + this.each(function() { + var n = this.name; + if (!n) { + return; + } + var v = $.fieldValue(this, successful); + if (v && v.constructor == Array) { + for (var i=0,max=v.length; i < max; i++) { + a.push({name: n, value: v[i]}); + } + } + else if (v !== null && typeof v != 'undefined') { + a.push({name: this.name, value: v}); + } + }); + //hand off to jQuery.param for proper encoding + return $.param(a); }; /** * Returns the value(s) of the element in the matched set. For example, consider the following form: * * <form><fieldset> - * <input name="A" type="text" /> - * <input name="A" type="text" /> - * <input name="B" type="checkbox" value="B1" /> - * <input name="B" type="checkbox" value="B2"/> - * <input name="C" type="radio" value="C1" /> - * <input name="C" type="radio" value="C2" /> + * <input name="A" type="text" /> + * <input name="A" type="text" /> + * <input name="B" type="checkbox" value="B1" /> + * <input name="B" type="checkbox" value="B2"/> + * <input name="C" type="radio" value="C1" /> + * <input name="C" type="radio" value="C2" /> * </fieldset></form> * * var v = $(':text').fieldValue(); @@ -759,60 +920,63 @@ $.fn.fieldSerialize = function(successful) { * for each element is returned. * * Note: This method *always* returns an array. If no valid value can be determined the - * array will be empty, otherwise it will contain one or more values. + * array will be empty, otherwise it will contain one or more values. */ $.fn.fieldValue = function(successful) { - for (var val=[], i=0, max=this.length; i < max; i++) { - var el = this[i]; - var v = $.fieldValue(el, successful); - if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) { - continue; - } - v.constructor == Array ? $.merge(val, v) : val.push(v); - } - return val; + for (var val=[], i=0, max=this.length; i < max; i++) { + var el = this[i]; + var v = $.fieldValue(el, successful); + if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) { + continue; + } + if (v.constructor == Array) + $.merge(val, v); + else + val.push(v); + } + return val; }; /** * Returns the value of the field element. */ $.fieldValue = function(el, successful) { - var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); - if (successful === undefined) { - successful = true; - } - - if (successful && (!n || el.disabled || t == 'reset' || t == 'button' || - (t == 'checkbox' || t == 'radio') && !el.checked || - (t == 'submit' || t == 'image') && el.form && el.form.clk != el || - tag == 'select' && el.selectedIndex == -1)) { - return null; - } - - if (tag == 'select') { - var index = el.selectedIndex; - if (index < 0) { - return null; - } - var a = [], ops = el.options; - var one = (t == 'select-one'); - var max = (one ? index+1 : ops.length); - for(var i=(one ? index : 0); i < max; i++) { - var op = ops[i]; - if (op.selected) { - var v = op.value; - if (!v) { // extra pain for IE... - v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value; - } - if (one) { - return v; - } - a.push(v); - } - } - return a; - } - return $(el).val(); + var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); + if (successful === undefined) { + successful = true; + } + + if (successful && (!n || el.disabled || t == 'reset' || t == 'button' || + (t == 'checkbox' || t == 'radio') && !el.checked || + (t == 'submit' || t == 'image') && el.form && el.form.clk != el || + tag == 'select' && el.selectedIndex == -1)) { + return null; + } + + if (tag == 'select') { + var index = el.selectedIndex; + if (index < 0) { + return null; + } + var a = [], ops = el.options; + var one = (t == 'select-one'); + var max = (one ? index+1 : ops.length); + for(var i=(one ? index : 0); i < max; i++) { + var op = ops[i]; + if (op.selected) { + var v = op.value; + if (!v) { // extra pain for IE... + v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value; + } + if (one) { + return v; + } + a.push(v); + } + } + return a; + } + return $(el).val(); }; /** @@ -823,54 +987,63 @@ $.fieldValue = function(el, successful) { * - inputs of type submit, button, reset, and hidden will *not* be effected * - button elements will *not* be effected */ -$.fn.clearForm = function() { - return this.each(function() { - $('input,select,textarea', this).clearFields(); - }); +$.fn.clearForm = function(includeHidden) { + return this.each(function() { + $('input,select,textarea', this).clearFields(includeHidden); + }); }; /** * Clears the selected form elements. */ -$.fn.clearFields = $.fn.clearInputs = function() { - var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list - return this.each(function() { - var t = this.type, tag = this.tagName.toLowerCase(); - if (re.test(t) || tag == 'textarea') { - this.value = ''; - } - else if (t == 'checkbox' || t == 'radio') { - this.checked = false; - } - else if (tag == 'select') { - this.selectedIndex = -1; - } - }); +$.fn.clearFields = $.fn.clearInputs = function(includeHidden) { + var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list + return this.each(function() { + var t = this.type, tag = this.tagName.toLowerCase(); + if (re.test(t) || tag == 'textarea') { + this.value = ''; + } + else if (t == 'checkbox' || t == 'radio') { + this.checked = false; + } + else if (tag == 'select') { + this.selectedIndex = -1; + } + else if (includeHidden) { + // includeHidden can be the value true, or it can be a selector string + // indicating a special test; for example: + // $('#myForm').clearForm('.special:hidden') + // the above would clean hidden inputs that have the class of 'special' + if ( (includeHidden === true && /hidden/.test(t)) || + (typeof includeHidden == 'string' && $(this).is(includeHidden)) ) + this.value = ''; + } + }); }; /** * Resets the form data. Causes all form elements to be reset to their original value. */ $.fn.resetForm = function() { - return this.each(function() { - // guard against an input with the name of 'reset' - // note that IE reports the reset function as an 'object' - if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) { - this.reset(); - } - }); + return this.each(function() { + // guard against an input with the name of 'reset' + // note that IE reports the reset function as an 'object' + if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) { + this.reset(); + } + }); }; /** * Enables or disables any matching elements. */ $.fn.enable = function(b) { - if (b === undefined) { - b = true; - } - return this.each(function() { - this.disabled = !b; - }); + if (b === undefined) { + b = true; + } + return this.each(function() { + this.disabled = !b; + }); }; /** @@ -878,34 +1051,39 @@ $.fn.enable = function(b) { * selects/deselects and matching option elements. */ $.fn.selected = function(select) { - if (select === undefined) { - select = true; - } - return this.each(function() { - var t = this.type; - if (t == 'checkbox' || t == 'radio') { - this.checked = select; - } - else if (this.tagName.toLowerCase() == 'option') { - var $sel = $(this).parent('select'); - if (select && $sel[0] && $sel[0].type == 'select-one') { - // deselect all other options - $sel.find('option').selected(false); - } - this.selected = select; - } - }); + if (select === undefined) { + select = true; + } + return this.each(function() { + var t = this.type; + if (t == 'checkbox' || t == 'radio') { + this.checked = select; + } + else if (this.tagName.toLowerCase() == 'option') { + var $sel = $(this).parent('select'); + if (select && $sel[0] && $sel[0].type == 'select-one') { + // deselect all other options + $sel.find('option').selected(false); + } + this.selected = select; + } + }); }; +// expose debug var +$.fn.ajaxSubmit.debug = false; + // helper fn for console logging function log() { - var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,''); - if (window.console && window.console.log) { - window.console.log(msg); - } - else if (window.opera && window.opera.postError) { - window.opera.postError(msg); - } -}; + if (!$.fn.ajaxSubmit.debug) + return; + var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,''); + if (window.console && window.console.log) { + window.console.log(msg); + } + else if (window.opera && window.opera.postError) { + window.opera.postError(msg); + } +} })(jQuery); diff --git a/resources/jquery/jquery.getAttrs.js b/resources/jquery/jquery.getAttrs.js index c05012d9..25b806b6 100644 --- a/resources/jquery/jquery.getAttrs.js +++ b/resources/jquery/jquery.getAttrs.js @@ -3,8 +3,8 @@ * * @author Timo Tijhof, 2011 */ -jQuery.fn.getAttrs = function( all ) { - var map = this[0].attributes, +jQuery.fn.getAttrs = function ( all ) { + var map = this[0].attributes, attrs = {}, len = map.length, i, v; diff --git a/resources/jquery/jquery.highlightText.js b/resources/jquery/jquery.highlightText.js index 44ac56e1..f720e07f 100644 --- a/resources/jquery/jquery.highlightText.js +++ b/resources/jquery/jquery.highlightText.js @@ -1,64 +1,69 @@ /** - * Plugin that highlights matched word partials in a given element - * TODO: add a function for restoring the previous text - * TODO: accept mappings for converting shortcuts like WP: to Wikipedia: + * Plugin that highlights matched word partials in a given element. + * TODO: Add a function for restoring the previous text. + * TODO: Accept mappings for converting shortcuts like WP: to Wikipedia:. */ -( function( $ ) { +( function ( $ ) { -$.highlightText = { - - // Split our pattern string at spaces and run our highlight function on the results - splitAndHighlight: function( node, pat ) { - var patArray = pat.split(" "); - for ( var i = 0; i < patArray.length; i++ ) { - if ( patArray[i].length == 0 ) continue; - $.highlightText.innerHighlight( node, patArray[i] ); - } - return node; - }, - // scans a node looking for the pattern and wraps a span around each match - innerHighlight: function( node, pat ) { - // if this is a text node - if ( node.nodeType == 3 ) { - // TODO - need to be smarter about the character matching here. - // non latin characters can make regex think a new word has begun: do not use \b - // http://stackoverflow.com/questions/3787072/regex-wordwrap-with-utf8-characters-in-js - // look for an occurence of our pattern and store the starting position - var match = node.data.match( new RegExp( "(^|\\s)" + $.escapeRE( pat ), "i" ) ); - if ( match ) { - var pos = match.index + match[1].length; // include length of any matched spaces - // create the span wrapper for the matched text - var spannode = document.createElement( 'span' ); - spannode.className = 'highlight'; - // shave off the characters preceding the matched text - var middlebit = node.splitText( pos ); - // shave off any unmatched text off the end - middlebit.splitText( pat.length ); - // clone for appending to our span - var middleclone = middlebit.cloneNode( true ); - // append the matched text node to the span - spannode.appendChild( middleclone ); - // replace the matched node, with our span-wrapped clone of the matched node - middlebit.parentNode.replaceChild( spannode, middlebit ); + $.highlightText = { + + // Split our pattern string at spaces and run our highlight function on the results + splitAndHighlight: function ( node, pat ) { + var i, + patArray = pat.split( ' ' ); + for ( i = 0; i < patArray.length; i++ ) { + if ( patArray[i].length === 0 ) { + continue; + } + $.highlightText.innerHighlight( node, patArray[i] ); } - // if this is an element with childnodes, and not a script, style or an element we created - } else if ( node.nodeType == 1 && node.childNodes && !/(script|style)/i.test( node.tagName ) - && !( node.tagName.toLowerCase() == 'span' && node.className.match( /\bhighlight/ ) ) ) { - for ( var i = 0; i < node.childNodes.length; ++i ) { - // call the highlight function for each child node - $.highlightText.innerHighlight( node.childNodes[i], pat ); + return node; + }, + + // scans a node looking for the pattern and wraps a span around each match + innerHighlight: function ( node, pat ) { + var i, match, pos, spannode, middlebit, middleclone; + // if this is a text node + if ( node.nodeType === 3 ) { + // TODO - need to be smarter about the character matching here. + // non latin characters can make regex think a new word has begun: do not use \b + // http://stackoverflow.com/questions/3787072/regex-wordwrap-with-utf8-characters-in-js + // look for an occurrence of our pattern and store the starting position + match = node.data.match( new RegExp( "(^|\\s)" + $.escapeRE( pat ), "i" ) ); + if ( match ) { + pos = match.index + match[1].length; // include length of any matched spaces + // create the span wrapper for the matched text + spannode = document.createElement( 'span' ); + spannode.className = 'highlight'; + // shave off the characters preceding the matched text + middlebit = node.splitText( pos ); + // shave off any unmatched text off the end + middlebit.splitText( pat.length ); + // clone for appending to our span + middleclone = middlebit.cloneNode( true ); + // append the matched text node to the span + spannode.appendChild( middleclone ); + // replace the matched node, with our span-wrapped clone of the matched node + middlebit.parentNode.replaceChild( spannode, middlebit ); + } + // if this is an element with childnodes, and not a script, style or an element we created + } else if ( node.nodeType === 1 && node.childNodes && !/(script|style)/i.test( node.tagName ) + && !( node.tagName.toLowerCase() === 'span' && node.className.match( /\bhighlight/ ) ) ) { + for ( i = 0; i < node.childNodes.length; ++i ) { + // call the highlight function for each child node + $.highlightText.innerHighlight( node.childNodes[i], pat ); + } } } - } -}; + }; -$.fn.highlightText = function( matchString ) { - return $( this ).each( function() { - var $this = $( this ); - $this.data( 'highlightText', { originalText: $this.text() } ); - $.highlightText.splitAndHighlight( this, matchString ); - } ); -}; + $.fn.highlightText = function ( matchString ) { + return this.each( function () { + var $el = $( this ); + $el.data( 'highlightText', { originalText: $el.text() } ); + $.highlightText.splitAndHighlight( this, matchString ); + } ); + }; -} )( jQuery ); +}( jQuery ) ); diff --git a/resources/jquery/jquery.jStorage.js b/resources/jquery/jquery.jStorage.js new file mode 100644 index 00000000..95959cf7 --- /dev/null +++ b/resources/jquery/jquery.jStorage.js @@ -0,0 +1,532 @@ +/* + * ----------------------------- JSTORAGE ------------------------------------- + * Simple local storage wrapper to save data on the browser side, supporting + * all major browsers - IE6+, Firefox2+, Safari4+, Chrome4+ and Opera 10.5+ + * + * Copyright (c) 2010 Andris Reinman, andris.reinman@gmail.com + * Project homepage: www.jstorage.info + * + * Taken from Github with slight modifications by Hoo man + * https://raw.github.com/andris9/jStorage/master/jstorage.js + * + * Licensed under MIT-style license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * $.jStorage + * + * USAGE: + * + * jStorage requires Prototype, MooTools or jQuery! If jQuery is used, then + * jQuery-JSON (http://code.google.com/p/jquery-json/) is also needed. + * (jQuery-JSON needs to be loaded BEFORE jStorage!) + * + * Methods: + * + * -set(key, value[, options]) + * $.jStorage.set(key, value) -> saves a value + * + * -get(key[, default]) + * value = $.jStorage.get(key [, default]) -> + * retrieves value if key exists, or default if it doesn't + * + * -deleteKey(key) + * $.jStorage.deleteKey(key) -> removes a key from the storage + * + * -flush() + * $.jStorage.flush() -> clears the cache + * + * -storageObj() + * $.jStorage.storageObj() -> returns a read-ony copy of the actual storage + * + * -storageSize() + * $.jStorage.storageSize() -> returns the size of the storage in bytes + * + * -index() + * $.jStorage.index() -> returns the used keys as an array + * + * -storageAvailable() + * $.jStorage.storageAvailable() -> returns true if storage is available + * + * -reInit() + * $.jStorage.reInit() -> reloads the data from browser storage + * + * <value> can be any JSON-able value, including objects and arrays. + * + **/ + +(function($){ + if(!$ || !($.toJSON || Object.toJSON || window.JSON)){ + throw new Error("jQuery, MooTools or Prototype needs to be loaded before jStorage!"); + } + + var + /* This is the object, that holds the cached values */ + _storage = {}, + + /* Actual browser storage (localStorage or globalStorage['domain']) */ + _storage_service = {jStorage:"{}"}, + + /* DOM element for older IE versions, holds userData behavior */ + _storage_elm = null, + + /* How much space does the storage take */ + _storage_size = 0, + + /* function to encode objects to JSON strings */ + json_encode = $.toJSON || Object.toJSON || (window.JSON && (JSON.encode || JSON.stringify)), + + /* function to decode objects from JSON strings */ + json_decode = $.evalJSON || (window.JSON && (JSON.decode || JSON.parse)) || function(str){ + return String(str).evalJSON(); + }, + + /* which backend is currently used */ + _backend = false, + + /* Next check for TTL */ + _ttl_timeout, + + /** + * XML encoding and decoding as XML nodes can't be JSON'ized + * XML nodes are encoded and decoded if the node is the value to be saved + * but not if it's as a property of another object + * Eg. - + * $.jStorage.set("key", xmlNode); // IS OK + * $.jStorage.set("key", {xml: xmlNode}); // NOT OK + */ + _XMLService = { + + /** + * Validates a XML node to be XML + * based on jQuery.isXML function + */ + isXML: function(elm){ + var documentElement = (elm ? elm.ownerDocument || elm : 0).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; + }, + + /** + * Encodes a XML node to string + * based on http://www.mercurytide.co.uk/news/article/issues-when-working-ajax/ + */ + encode: function(xmlNode) { + if(!this.isXML(xmlNode)){ + return false; + } + try{ // Mozilla, Webkit, Opera + return new XMLSerializer().serializeToString(xmlNode); + }catch(E1) { + try { // IE + return xmlNode.xml; + }catch(E2){} + } + return false; + }, + + /** + * Decodes a XML node from string + * loosely based on http://outwestmedia.com/jquery-plugins/xmldom/ + */ + decode: function(xmlString){ + var dom_parser = ("DOMParser" in window && (new DOMParser()).parseFromString) || + (window.ActiveXObject && function(_xmlString) { + var xml_doc = new ActiveXObject('Microsoft.XMLDOM'); + xml_doc.async = 'false'; + xml_doc.loadXML(_xmlString); + return xml_doc; + }), + resultXML; + if(!dom_parser){ + return false; + } + resultXML = dom_parser.call("DOMParser" in window && (new DOMParser()) || window, xmlString, 'text/xml'); + return this.isXML(resultXML)?resultXML:false; + } + }; + + ////////////////////////// PRIVATE METHODS //////////////////////// + + /** + * Initialization function. Detects if the browser supports DOM Storage + * or userData behavior and behaves accordingly. + * @returns undefined + */ + function _init(){ + /* Check if browser supports localStorage */ + var localStorageReallyWorks = false; + if("localStorage" in window){ + try { + window.localStorage.setItem('_tmptest', 'tmpval'); + localStorageReallyWorks = true; + window.localStorage.removeItem('_tmptest'); + } catch(BogusQuotaExceededErrorOnIos5) { + // Thanks be to iOS5 Private Browsing mode which throws + // QUOTA_EXCEEDED_ERRROR DOM Exception 22. + } + } + if(localStorageReallyWorks){ + try { + if(window.localStorage) { + _storage_service = window.localStorage; + _backend = "localStorage"; + } + } catch(E3) {/* Firefox fails when touching localStorage and cookies are disabled */} + } + /* Check if browser supports globalStorage */ + else if("globalStorage" in window){ + try { + if(window.globalStorage) { + _storage_service = window.globalStorage[window.location.hostname]; + _backend = "globalStorage"; + } + } catch(E4) {/* Firefox fails when touching localStorage and cookies are disabled */} + } + /* Check if browser supports userData behavior */ + else { + _storage_elm = document.createElement('link'); + if(_storage_elm.addBehavior){ + + /* Use a DOM element to act as userData storage */ + _storage_elm.style.behavior = 'url(#default#userData)'; + + /* userData element needs to be inserted into the DOM! */ + document.getElementsByTagName('head')[0].appendChild(_storage_elm); + + _storage_elm.load("jStorage"); + var data = "{}"; + try{ + data = _storage_elm.getAttribute("jStorage"); + }catch(E5){} + _storage_service.jStorage = data; + _backend = "userDataBehavior"; + }else{ + _storage_elm = null; + return; + } + } + + _load_storage(); + + // remove dead keys + _handleTTL(); + } + + /** + * Loads the data from the storage based on the supported mechanism + * @returns undefined + */ + function _load_storage(){ + /* if jStorage string is retrieved, then decode it */ + if(_storage_service.jStorage){ + try{ + _storage = json_decode(String(_storage_service.jStorage)); + }catch(E6){_storage_service.jStorage = "{}";} + }else{ + _storage_service.jStorage = "{}"; + } + _storage_size = _storage_service.jStorage?String(_storage_service.jStorage).length:0; + } + + /** + * This functions provides the "save" mechanism to store the jStorage object + * @returns undefined + */ + function _save(){ + try{ + _storage_service.jStorage = json_encode(_storage); + // If userData is used as the storage engine, additional + if(_storage_elm) { + _storage_elm.setAttribute("jStorage",_storage_service.jStorage); + _storage_elm.save("jStorage"); + } + _storage_size = _storage_service.jStorage?String(_storage_service.jStorage).length:0; + }catch(E7){/* probably cache is full, nothing is saved this way*/} + } + + /** + * Function checks if a key is set and is string or numberic + */ + function _checkKey(key){ + if(!key || (typeof key !== "string" && typeof key !== "number")){ + throw new TypeError('Key name must be string or numeric'); + } + if(key === "__jstorage_meta"){ + throw new TypeError('Reserved key name'); + } + return true; + } + + /** + * Removes expired keys + */ + function _handleTTL(){ + var curtime, i, TTL, nextExpire = Infinity, changed = false; + + clearTimeout(_ttl_timeout); + + if(!_storage.__jstorage_meta || typeof _storage.__jstorage_meta.TTL !== "object"){ + // nothing to do here + return; + } + + curtime = +new Date(); + TTL = _storage.__jstorage_meta.TTL; + for(i in TTL){ + if(TTL.hasOwnProperty(i)){ + if(TTL[i] <= curtime){ + delete TTL[i]; + delete _storage[i]; + changed = true; + }else if(TTL[i] < nextExpire){ + nextExpire = TTL[i]; + } + } + } + + // set next check + if(nextExpire != Infinity){ + _ttl_timeout = setTimeout(_handleTTL, nextExpire - curtime); + } + + // save changes + if(changed){ + _save(); + } + } + + ////////////////////////// PUBLIC INTERFACE ///////////////////////// + + $.jStorage = { + /* Version number */ + version: "0.1.7.0", + + /** + * Sets a key's value. + * + * @param {String} key - Key to set. If this value is not set or not + * a string an exception is raised. + * @param {Mixed} value - Value to set. This can be any value that is JSON + * compatible (Numbers, Strings, Objects etc.). + * @param {Object} [options] - possible options to use + * @param {Number} [options.TTL] - optional TTL value + * @returns the used value + */ + set: function(key, value, options){ + _checkKey(key); + + options = options || {}; + + if(_XMLService.isXML(value)){ + value = {_is_xml:true,xml:_XMLService.encode(value)}; + }else if(typeof value === "function"){ + value = null; // functions can't be saved! + }else if(value && typeof value === "object"){ + // clone the object before saving to _storage tree + value = json_decode(json_encode(value)); + } + _storage[key] = value; + + if(!isNaN(options.TTL)){ + this.setTTL(key, options.TTL); + // also handles saving + }else{ + _save(); + } + return value; + }, + + /** + * Looks up a key in cache + * + * @param {String} key - Key to look up. + * @param {mixed} def - Default value to return, if key didn't exist. + * @returns the key value, default value or <null> + */ + get: function(key, def){ + _checkKey(key); + if(key in _storage){ + if(_storage[key] && typeof _storage[key] === "object" && + _storage[key]._is_xml && + _storage[key]._is_xml){ + return _XMLService.decode(_storage[key].xml); + }else{ + return _storage[key]; + } + } + return typeof(def) === 'undefined' ? null : def; + }, + + /** + * Deletes a key from cache. + * + * @param {String} key - Key to delete. + * @returns true if key existed or false if it didn't + */ + deleteKey: function(key){ + _checkKey(key); + if(key in _storage){ + delete _storage[key]; + // remove from TTL list + if(_storage.__jstorage_meta && + typeof _storage.__jstorage_meta.TTL === "object" && + key in _storage.__jstorage_meta.TTL){ + delete _storage.__jstorage_meta.TTL[key]; + } + _save(); + return true; + } + return false; + }, + + /** + * Sets a TTL for a key, or remove it if ttl value is 0 or below + * + * @param {String} key - key to set the TTL for + * @param {Number} ttl - TTL timeout in milliseconds + * @returns true if key existed or false if it didn't + */ + setTTL: function(key, ttl){ + var curtime = +new Date(); + _checkKey(key); + ttl = Number(ttl) || 0; + if(key in _storage){ + + if(!_storage.__jstorage_meta){ + _storage.__jstorage_meta = {}; + } + if(!_storage.__jstorage_meta.TTL){ + _storage.__jstorage_meta.TTL = {}; + } + + // Set TTL value for the key + if(ttl>0){ + _storage.__jstorage_meta.TTL[key] = curtime + ttl; + }else{ + delete _storage.__jstorage_meta.TTL[key]; + } + + _save(); + + _handleTTL(); + return true; + } + return false; + }, + + /** + * Deletes everything in cache. + * + * @return true + */ + flush: function(){ + _storage = {}; + _save(); + return true; + }, + + /** + * Returns a read-only copy of _storage + * + * @returns Object + */ + storageObj: function(){ + function F() {} + F.prototype = _storage; + return new F(); + }, + + /** + * Returns an index of all used keys as an array + * ['key1', 'key2',..'keyN'] + * + * @returns Array + */ + index: function(){ + var index = [], i; + for(i in _storage){ + if(_storage.hasOwnProperty(i) && i !== "__jstorage_meta"){ + index.push(i); + } + } + return index; + }, + + /** + * How much space in bytes does the storage take? + * + * @returns Number + */ + storageSize: function(){ + return _storage_size; + }, + + /** + * Which backend is currently in use? + * + * @returns String + */ + currentBackend: function(){ + return _backend; + }, + + /** + * Test if storage is available + * + * @returns Boolean + */ + storageAvailable: function(){ + return !!_backend; + }, + + /** + * Reloads the data from browser storage + * + * @returns undefined + */ + reInit: function(){ + var new_storage_elm, data; + if(_storage_elm && _storage_elm.addBehavior){ + new_storage_elm = document.createElement('link'); + + _storage_elm.parentNode.replaceChild(new_storage_elm, _storage_elm); + _storage_elm = new_storage_elm; + + /* Use a DOM element to act as userData storage */ + _storage_elm.style.behavior = 'url(#default#userData)'; + + /* userData element needs to be inserted into the DOM! */ + document.getElementsByTagName('head')[0].appendChild(_storage_elm); + + _storage_elm.load("jStorage"); + data = "{}"; + try{ + data = _storage_elm.getAttribute("jStorage"); + }catch(E5){} + _storage_service.jStorage = data; + _backend = "userDataBehavior"; + } + + _load_storage(); + } + }; + + // Initialize jStorage + _init(); + +})(window.$ || window.jQuery); diff --git a/resources/jquery/jquery.js b/resources/jquery/jquery.js index 8ccd0ea7..d4f3bb38 100644 --- a/resources/jquery/jquery.js +++ b/resources/jquery/jquery.js @@ -1,31 +1,28 @@ /*! - * jQuery JavaScript Library v1.7.1 + * jQuery JavaScript Library v1.8.2 * http://jquery.com/ * - * Copyright 2011, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * * Includes Sizzle.js * http://sizzlejs.com/ - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. * - * Date: Mon Nov 21 21:11:03 2011 -0500 + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: Thu Sep 20 2012 21:13:05 GMT-0400 (Eastern Daylight Time) */ (function( window, undefined ) { +var + // A central reference to the root jQuery(document) + rootjQuery, -// Use the correct document accordingly with window argument (sandbox) -var document = window.document, - navigator = window.navigator, - location = window.location; -var jQuery = (function() { + // The deferred used on DOM ready + readyList, -// Define a local copy of jQuery -var jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context, rootjQuery ); - }, + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + location = window.location, + navigator = window.navigator, // Map over jQuery in case of overwrite _jQuery = window.jQuery, @@ -33,63 +30,64 @@ var jQuery = function( selector, context ) { // Map over the $ in case of overwrite _$ = window.$, - // A central reference to the root jQuery(document) - rootjQuery, + // Save a reference to some core methods + core_push = Array.prototype.push, + core_slice = Array.prototype.slice, + core_indexOf = Array.prototype.indexOf, + core_toString = Object.prototype.toString, + core_hasOwn = Object.prototype.hasOwnProperty, + core_trim = String.prototype.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, - // A simple way to check for HTML strings or ID strings - // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) - quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + // Used for matching numbers + core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source, + + // Used for detecting and trimming whitespace + core_rnotwhite = /\S/, + core_rspace = /\s+/, - // Check if a string has a non-whitespace character in it - rnotwhite = /\S/, + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - // Used for trimming whitespace - trimLeft = /^\s+/, - trimRight = /\s+$/, + // A simple way to check for HTML strings + // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) + rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, // Match a standalone tag - rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, // JSON RegExp rvalidchars = /^[\],:{}\s]*$/, - rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, - rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, - - // Useragent RegExp - rwebkit = /(webkit)[ \/]([\w.]+)/, - ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, - rmsie = /(msie) ([\w.]+)/, - rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, // Matches dashed string for camelizing - rdashAlpha = /-([a-z]|[0-9])/ig, rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, // Used by jQuery.camelCase as callback to replace() fcamelCase = function( all, letter ) { return ( letter + "" ).toUpperCase(); }, - // Keep a UserAgent string for use with jQuery.browser - userAgent = navigator.userAgent, - - // For matching the engine and version of the browser - browserMatch, - - // The deferred used on DOM ready - readyList, - - // The ready event handler - DOMContentLoaded, - - // Save a reference to some core methods - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - push = Array.prototype.push, - slice = Array.prototype.slice, - trim = String.prototype.trim, - indexOf = Array.prototype.indexOf, + // The ready event handler and self cleanup method + DOMContentLoaded = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + } else if ( document.readyState === "complete" ) { + // we're here because readyState === "complete" in oldIE + // which is good enough for us to call the dom ready! + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }, // [[Class]] -> type pairs class2type = {}; @@ -99,7 +97,7 @@ jQuery.fn = jQuery.prototype = { init: function( selector, context, rootjQuery ) { var match, elem, ret, doc; - // Handle $(""), $(null), or $(undefined) + // Handle $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; } @@ -111,55 +109,33 @@ jQuery.fn = jQuery.prototype = { return this; } - // The body element only exists once, optimize finding it - if ( selector === "body" && !context && document.body ) { - this.context = document; - this[0] = document.body; - this.selector = selector; - this.length = 1; - return this; - } - // Handle HTML strings if ( typeof selector === "string" ) { - // Are we dealing with HTML string or an ID? if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ]; } else { - match = quickExpr.exec( selector ); + match = rquickExpr.exec( selector ); } - // Verify a match, and that no context was specified for #id + // Match html or make sure no context is specified for #id if ( match && (match[1] || !context) ) { // HANDLE: $(html) -> $(array) if ( match[1] ) { context = context instanceof jQuery ? context[0] : context; - doc = ( context ? context.ownerDocument || context : document ); + doc = ( context && context.nodeType ? context.ownerDocument || context : document ); - // If a single string is passed in and it's a single tag - // just do a createElement and skip the rest - ret = rsingleTag.exec( selector ); - - if ( ret ) { - if ( jQuery.isPlainObject( context ) ) { - selector = [ document.createElement( ret[1] ) ]; - jQuery.fn.attr.call( selector, context, true ); - - } else { - selector = [ doc.createElement( ret[1] ) ]; - } - - } else { - ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); - selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + // scripts is true for back-compat + selector = jQuery.parseHTML( match[1], doc, true ); + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + this.attr.call( selector, context, true ); } return jQuery.merge( this, selector ); - // HANDLE: $("#id") + // HANDLE: $(#id) } else { elem = document.getElementById( match[2] ); @@ -210,7 +186,7 @@ jQuery.fn = jQuery.prototype = { selector: "", // The current version of jQuery being used - jquery: "1.7.1", + jquery: "1.8.2", // The default length of a jQuery object is 0 length: 0, @@ -221,7 +197,7 @@ jQuery.fn = jQuery.prototype = { }, toArray: function() { - return slice.call( this, 0 ); + return core_slice.call( this ); }, // Get the Nth element in the matched element set OR @@ -239,15 +215,9 @@ jQuery.fn = jQuery.prototype = { // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function( elems, name, selector ) { - // Build a new jQuery matched element set - var ret = this.constructor(); - - if ( jQuery.isArray( elems ) ) { - push.apply( ret, elems ); - } else { - jQuery.merge( ret, elems ); - } + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference) ret.prevObject = this; @@ -272,11 +242,8 @@ jQuery.fn = jQuery.prototype = { }, ready: function( fn ) { - // Attach the listeners - jQuery.bindReady(); - // Add the callback - readyList.add( fn ); + jQuery.ready.promise().done( fn ); return this; }, @@ -297,8 +264,8 @@ jQuery.fn = jQuery.prototype = { }, slice: function() { - return this.pushStack( slice.apply( this, arguments ), - "slice", slice.call(arguments).join(",") ); + return this.pushStack( core_slice.apply( this, arguments ), + "slice", core_slice.call(arguments).join(",") ); }, map: function( callback ) { @@ -313,7 +280,7 @@ jQuery.fn = jQuery.prototype = { // For internal use only. // Behaves like an Array's method, not like a jQuery method. - push: push, + push: core_push, sort: [].sort, splice: [].splice }; @@ -416,73 +383,31 @@ jQuery.extend({ // Handle when the DOM is ready ready: function( wait ) { - // Either a released hold or an DOMready/load event and not yet ready - if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready, 1 ); - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.fireWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.trigger ) { - jQuery( document ).trigger( "ready" ).off( "ready" ); - } - } - }, - bindReady: function() { - if ( readyList ) { + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } - readyList = jQuery.Callbacks( "once memory" ); - - // Catch cases where $(document).ready() is called after the - // browser event has already occurred. - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { return setTimeout( jQuery.ready, 1 ); } - // Mozilla, Opera and webkit nightlies currently support this event - if ( document.addEventListener ) { - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + // Remember that the DOM is ready + jQuery.isReady = true; - // A fallback to window.onload, that will always work - window.addEventListener( "load", jQuery.ready, false ); - - // If IE event model is used - } else if ( document.attachEvent ) { - // ensure firing before onload, - // maybe late but safe also for iframes - document.attachEvent( "onreadystatechange", DOMContentLoaded ); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", jQuery.ready ); - - // If IE and not a frame - // continually check to see if the document is ready - var toplevel = false; + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } - try { - toplevel = window.frameElement == null; - } catch(e) {} + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); - if ( document.documentElement.doScroll && toplevel ) { - doScrollCheck(); - } + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); } }, @@ -497,9 +422,8 @@ jQuery.extend({ return jQuery.type(obj) === "array"; }, - // A crude way of determining if an object is a window isWindow: function( obj ) { - return obj && typeof obj === "object" && "setInterval" in obj; + return obj != null && obj == obj.window; }, isNumeric: function( obj ) { @@ -509,7 +433,7 @@ jQuery.extend({ type: function( obj ) { return obj == null ? String( obj ) : - class2type[ toString.call(obj) ] || "object"; + class2type[ core_toString.call(obj) ] || "object"; }, isPlainObject: function( obj ) { @@ -523,8 +447,8 @@ jQuery.extend({ try { // Not own constructor property must be Object if ( obj.constructor && - !hasOwn.call(obj, "constructor") && - !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { return false; } } catch ( e ) { @@ -538,11 +462,12 @@ jQuery.extend({ var key; for ( key in obj ) {} - return key === undefined || hasOwn.call( obj, key ); + return key === undefined || core_hasOwn.call( obj, key ); }, isEmptyObject: function( obj ) { - for ( var name in obj ) { + var name; + for ( name in obj ) { return false; } return true; @@ -552,8 +477,32 @@ jQuery.extend({ throw new Error( msg ); }, + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // scripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, scripts ) { + var parsed; + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + scripts = context; + context = 0; + } + context = context || document; + + // Single tag + if ( (parsed = rsingleTag.exec( data )) ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] ); + return jQuery.merge( [], + (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes ); + }, + parseJSON: function( data ) { - if ( typeof data !== "string" || !data ) { + if ( !data || typeof data !== "string") { return null; } @@ -580,6 +529,9 @@ jQuery.extend({ // Cross-browser xml parsing parseXML: function( data ) { var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } try { if ( window.DOMParser ) { // Standard tmp = new DOMParser(); @@ -604,7 +556,7 @@ jQuery.extend({ // Workarounds based on findings by Jim Driscoll // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context globalEval: function( data ) { - if ( data && rnotwhite.test( data ) ) { + if ( data && core_rnotwhite.test( data ) ) { // We use execScript on Internet Explorer // We use an anonymous function so that context is window // rather than jQuery in Firefox @@ -621,25 +573,26 @@ jQuery.extend({ }, nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); }, // args is for internal usage only - each: function( object, callback, args ) { - var name, i = 0, - length = object.length, - isObj = length === undefined || jQuery.isFunction( object ); + each: function( obj, callback, args ) { + var name, + i = 0, + length = obj.length, + isObj = length === undefined || jQuery.isFunction( obj ); if ( args ) { if ( isObj ) { - for ( name in object ) { - if ( callback.apply( object[ name ], args ) === false ) { + for ( name in obj ) { + if ( callback.apply( obj[ name ], args ) === false ) { break; } } } else { for ( ; i < length; ) { - if ( callback.apply( object[ i++ ], args ) === false ) { + if ( callback.apply( obj[ i++ ], args ) === false ) { break; } } @@ -648,71 +601,72 @@ jQuery.extend({ // A special, fast, case for the most common use of each } else { if ( isObj ) { - for ( name in object ) { - if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + for ( name in obj ) { + if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) { break; } } } else { for ( ; i < length; ) { - if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) { break; } } } } - return object; + return obj; }, // Use native String.trim function wherever possible - trim: trim ? + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? function( text ) { return text == null ? "" : - trim.call( text ); + core_trim.call( text ); } : // Otherwise use our own trimming functionality function( text ) { return text == null ? "" : - text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + ( text + "" ).replace( rtrim, "" ); }, // results is for internal usage only - makeArray: function( array, results ) { - var ret = results || []; + makeArray: function( arr, results ) { + var type, + ret = results || []; - if ( array != null ) { + if ( arr != null ) { // The window, strings (and functions) also have 'length' // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 - var type = jQuery.type( array ); + type = jQuery.type( arr ); - if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { - push.call( ret, array ); + if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) { + core_push.call( ret, arr ); } else { - jQuery.merge( ret, array ); + jQuery.merge( ret, arr ); } } return ret; }, - inArray: function( elem, array, i ) { + inArray: function( elem, arr, i ) { var len; - if ( array ) { - if ( indexOf ) { - return indexOf.call( array, elem, i ); + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); } - len = array.length; + len = arr.length; i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; for ( ; i < len; i++ ) { // Skip accessing in sparse arrays - if ( i in array && array[ i ] === elem ) { + if ( i in arr && arr[ i ] === elem ) { return i; } } @@ -722,11 +676,12 @@ jQuery.extend({ }, merge: function( first, second ) { - var i = first.length, + var l = second.length, + i = first.length, j = 0; - if ( typeof second.length === "number" ) { - for ( var l = second.length; j < l; j++ ) { + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { first[ i++ ] = second[ j ]; } @@ -742,12 +697,15 @@ jQuery.extend({ }, grep: function( elems, callback, inv ) { - var ret = [], retVal; + var retVal, + ret = [], + i = 0, + length = elems.length; inv = !!inv; // Go through the array, only saving the items // that pass the validator function - for ( var i = 0, length = elems.length; i < length; i++ ) { + for ( ; i < length; i++ ) { retVal = !!callback( elems[ i ], i ); if ( inv !== retVal ) { ret.push( elems[ i ] ); @@ -759,7 +717,8 @@ jQuery.extend({ // arg is for internal usage only map: function( elems, callback, arg ) { - var value, key, ret = [], + var value, key, + ret = [], i = 0, length = elems.length, // jquery objects are treated as arrays @@ -796,8 +755,10 @@ jQuery.extend({ // Bind a function to a context, optionally partially applying any // arguments. proxy: function( fn, context ) { + var tmp, args, proxy; + if ( typeof context === "string" ) { - var tmp = fn[ context ]; + tmp = fn[ context ]; context = fn; fn = tmp; } @@ -809,178 +770,162 @@ jQuery.extend({ } // Simulated bind - var args = slice.call( arguments, 2 ), - proxy = function() { - return fn.apply( context, args.concat( slice.call( arguments ) ) ); - }; + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context, args.concat( core_slice.call( arguments ) ) ); + }; // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + proxy.guid = fn.guid = fn.guid || jQuery.guid++; return proxy; }, - // Mutifunctional method to get and set values to a collection + // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function - access: function( elems, key, value, exec, fn, pass ) { - var length = elems.length; + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; - // Setting many attributes - if ( typeof key === "object" ) { - for ( var k in key ) { - jQuery.access( elems, k, key[k], exec, fn, value ); + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); } - return elems; - } + chainable = 1; - // Setting one attribute - if ( value !== undefined ) { + // Sets one value + } else if ( value !== undefined ) { // Optionally, function values get executed if exec is true - exec = !pass && exec && jQuery.isFunction(value); + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } - for ( var i = 0; i < length; i++ ) { - fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } } - return elems; + chainable = 1; } - // Getting an attribute - return length ? fn( elems[0], key ) : undefined; + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; }, now: function() { return ( new Date() ).getTime(); - }, - - // Use of jQuery.browser is frowned upon. - // More details: http://docs.jquery.com/Utilities/jQuery.browser - uaMatch: function( ua ) { - ua = ua.toLowerCase(); + } +}); - var match = rwebkit.exec( ua ) || - ropera.exec( ua ) || - rmsie.exec( ua ) || - ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || - []; +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { - return { browser: match[1] || "", version: match[2] || "0" }; - }, + readyList = jQuery.Deferred(); - sub: function() { - function jQuerySub( selector, context ) { - return new jQuerySub.fn.init( selector, context ); - } - jQuery.extend( true, jQuerySub, this ); - jQuerySub.superclass = this; - jQuerySub.fn = jQuerySub.prototype = this(); - jQuerySub.fn.constructor = jQuerySub; - jQuerySub.sub = this.sub; - jQuerySub.fn.init = function init( selector, context ) { - if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { - context = jQuerySub( context ); - } + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready, 1 ); - return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); - }; - jQuerySub.fn.init.prototype = jQuerySub.fn; - var rootjQuerySub = jQuerySub(document); - return jQuerySub; - }, + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - browser: {} -}); + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); -browserMatch = jQuery.uaMatch( userAgent ); -if ( browserMatch.browser ) { - jQuery.browser[ browserMatch.browser ] = true; - jQuery.browser.version = browserMatch.version; -} + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); -// Deprecated, use jQuery.browser.webkit instead -if ( jQuery.browser.webkit ) { - jQuery.browser.safari = true; -} + // If IE and not a frame + // continually check to see if the document is ready + var top = false; -// IE doesn't match non-breaking spaces with \s -if ( rnotwhite.test( "\xA0" ) ) { - trimLeft = /^[\s\xA0]+/; - trimRight = /[\s\xA0]+$/; -} + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} -// All jQuery objects should point back to these -rootjQuery = jQuery(document); + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { -// Cleanup functions for the document ready method -if ( document.addEventListener ) { - DOMContentLoaded = function() { - document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - jQuery.ready(); - }; + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } -} else if ( document.attachEvent ) { - DOMContentLoaded = function() { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( document.readyState === "complete" ) { - document.detachEvent( "onreadystatechange", DOMContentLoaded ); - jQuery.ready(); + // and execute any waiting functions + jQuery.ready(); + } + })(); + } } - }; -} - -// The DOM ready check for Internet Explorer -function doScrollCheck() { - if ( jQuery.isReady ) { - return; } + return readyList.promise( obj ); +}; - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - document.documentElement.doScroll("left"); - } catch(e) { - setTimeout( doScrollCheck, 1 ); - return; - } - - // and execute any waiting functions - jQuery.ready(); -} - -return jQuery; - -})(); - - -// String to Object flags format cache -var flagsCache = {}; +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); -// Convert String-formatted flags into Object-formatted ones and store in cache -function createFlags( flags ) { - var object = flagsCache[ flags ] = {}, - i, length; - flags = flags.split( /\s+/ ); - for ( i = 0, length = flags.length; i < length; i++ ) { - object[ flags[i] ] = true; - } +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.split( core_rspace ), function( _, flag ) { + object[ flag ] = true; + }); return object; } /* * Create a callback list using the following parameters: * - * flags: an optional list of space-separated flags that will change how - * the callback list behaves + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * - * Possible flags: + * Possible options: * * once: will ensure the callback list can only be fired once (like a Deferred) * @@ -993,18 +938,18 @@ function createFlags( flags ) { * stopOnFalse: interrupt callings when a callback returns false * */ -jQuery.Callbacks = function( flags ) { +jQuery.Callbacks = function( options ) { - // Convert flags from String-formatted to Object-formatted + // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) - flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); - var // Actual callback list - list = [], - // Stack of fire calls for repeatable lists - stack = [], - // Last fire value (for non-forgettable lists) + var // Last fire value (for non-forgettable lists) memory, + // Flag to know if list was already fired + fired, // Flag to know if list is currently firing firing, // First callback to fire (used internally by add and fireWith) @@ -1013,52 +958,34 @@ jQuery.Callbacks = function( flags ) { firingLength, // Index of currently firing callback (modified by remove if needed) firingIndex, - // Add one or several callbacks to the list - add = function( args ) { - var i, - length, - elem, - type, - actual; - for ( i = 0, length = args.length; i < length; i++ ) { - elem = args[ i ]; - type = jQuery.type( elem ); - if ( type === "array" ) { - // Inspect recursively - add( elem ); - } else if ( type === "function" ) { - // Add if not in unique mode and callback is not in - if ( !flags.unique || !self.has( elem ) ) { - list.push( elem ); - } - } - } - }, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], // Fire callbacks - fire = function( context, args ) { - args = args || []; - memory = !flags.memory || [ context, args ]; - firing = true; + fire = function( data ) { + memory = options.memory && data; + fired = true; firingIndex = firingStart || 0; firingStart = 0; firingLength = list.length; + firing = true; for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { - memory = true; // Mark as halted + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add break; } } firing = false; if ( list ) { - if ( !flags.once ) { - if ( stack && stack.length ) { - memory = stack.shift(); - self.fireWith( memory[ 0 ], memory[ 1 ] ); + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); } - } else if ( memory === true ) { - self.disable(); - } else { + } else if ( memory ) { list = []; + } else { + self.disable(); } } }, @@ -1067,18 +994,28 @@ jQuery.Callbacks = function( flags ) { // Add a callback or a collection of callbacks to the list add: function() { if ( list ) { - var length = list.length; - add( arguments ); + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" && ( !options.unique || !self.has( arg ) ) ) { + list.push( arg ); + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); // Do we need to add the callbacks to the // current firing batch? if ( firing ) { firingLength = list.length; // With memory, if we're not firing then - // we should call right away, unless previous - // firing was halted (stopOnFalse) - } else if ( memory && memory !== true ) { - firingStart = length; - fire( memory[ 0 ], memory[ 1 ] ); + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); } } return this; @@ -1086,46 +1023,27 @@ jQuery.Callbacks = function( flags ) { // Remove a callback from the list remove: function() { if ( list ) { - var args = arguments, - argIndex = 0, - argLength = args.length; - for ( ; argIndex < argLength ; argIndex++ ) { - for ( var i = 0; i < list.length; i++ ) { - if ( args[ argIndex ] === list[ i ] ) { - // Handle firingIndex and firingLength - if ( firing ) { - if ( i <= firingLength ) { - firingLength--; - if ( i <= firingIndex ) { - firingIndex--; - } - } + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; } - // Remove the element - list.splice( i--, 1 ); - // If we have some unicity property then - // we only need to do this once - if ( flags.unique ) { - break; + if ( index <= firingIndex ) { + firingIndex--; } } } - } + }); } return this; }, // Control if a given callback is in the list has: function( fn ) { - if ( list ) { - var i = 0, - length = list.length; - for ( ; i < length; i++ ) { - if ( fn === list[ i ] ) { - return true; - } - } - } - return false; + return jQuery.inArray( fn, list ) > -1; }, // Remove all callbacks from the list empty: function() { @@ -1144,7 +1062,7 @@ jQuery.Callbacks = function( flags ) { // Lock the list in its current state lock: function() { stack = undefined; - if ( !memory || memory === true ) { + if ( !memory ) { self.disable(); } return this; @@ -1155,13 +1073,13 @@ jQuery.Callbacks = function( flags ) { }, // Call all callbacks with the given context and arguments fireWith: function( context, args ) { - if ( stack ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( list && ( !fired || stack ) ) { if ( firing ) { - if ( !flags.once ) { - stack.push( [ context, args ] ); - } - } else if ( !( flags.once && memory ) ) { - fire( context, args ); + stack.push( args ); + } else { + fire( args ); } } return this; @@ -1173,104 +1091,91 @@ jQuery.Callbacks = function( flags ) { }, // To know if the callbacks have already been called at least once fired: function() { - return !!memory; + return !!fired; } }; return self; }; - - - - -var // Static reference to slice - sliceDeferred = [].slice; - jQuery.extend({ Deferred: function( func ) { - var doneList = jQuery.Callbacks( "once memory" ), - failList = jQuery.Callbacks( "once memory" ), - progressList = jQuery.Callbacks( "memory" ), + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], state = "pending", - lists = { - resolve: doneList, - reject: failList, - notify: progressList - }, promise = { - done: doneList.add, - fail: failList.add, - progress: progressList.add, - state: function() { return state; }, - - // Deprecated - isResolved: doneList.fired, - isRejected: failList.fired, - - then: function( doneCallbacks, failCallbacks, progressCallbacks ) { - deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); - return this; - }, always: function() { - deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + deferred.done( arguments ).fail( arguments ); return this; }, - pipe: function( fnDone, fnFail, fnProgress ) { + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; return jQuery.Deferred(function( newDefer ) { - jQuery.each( { - done: [ fnDone, "resolve" ], - fail: [ fnFail, "reject" ], - progress: [ fnProgress, "notify" ] - }, function( handler, data ) { - var fn = data[ 0 ], - action = data[ 1 ], - returned; - if ( jQuery.isFunction( fn ) ) { - deferred[ handler ](function() { - returned = fn.apply( this, arguments ); + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? + function() { + var returned = fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); } else { newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); } - }); - } else { - deferred[ handler ]( newDefer[ action ] ); - } + } : + newDefer[ action ] + ); }); + fns = null; }).promise(); }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { - if ( obj == null ) { - obj = promise; - } else { - for ( var key in promise ) { - obj[ key ] = promise[ key ]; - } - } - return obj; + return obj != null ? jQuery.extend( obj, promise ) : promise; } }, - deferred = promise.promise({}), - key; + deferred = {}; - for ( key in lists ) { - deferred[ key ] = lists[ key ].fire; - deferred[ key + "With" ] = lists[ key ].fireWith; - } + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] = list.fire + deferred[ tuple[0] ] = list.fire; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); - // Handle state - deferred.done( function() { - state = "resolved"; - }, failList.disable, progressList.lock ).fail( function() { - state = "rejected"; - }, doneList.disable, progressList.lock ); + // Make the deferred a promise + promise.promise( deferred ); // Call given func if any if ( func ) { @@ -1282,52 +1187,57 @@ jQuery.extend({ }, // Deferred helper - when: function( firstParam ) { - var args = sliceDeferred.call( arguments, 0 ), - i = 0, - length = args.length, - pValues = new Array( length ), - count = length, - pCount = length, - deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? - firstParam : - jQuery.Deferred(), - promise = deferred.promise(); - function resolveFunc( i ) { - return function( value ) { - args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - if ( !( --count ) ) { - deferred.resolveWith( deferred, args ); - } - }; - } - function progressFunc( i ) { - return function( value ) { - pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - deferred.notifyWith( promise, pValues ); - }; - } + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); for ( ; i < length; i++ ) { - if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { - args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); } else { - --count; + --remaining; } } - if ( !count ) { - deferred.resolveWith( deferred, args ); - } - } else if ( deferred !== firstParam ) { - deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); } - return promise; - } -}); - - + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + return deferred.promise(); + } +}); jQuery.support = (function() { var support, @@ -1336,32 +1246,30 @@ jQuery.support = (function() { select, opt, input, - marginDiv, fragment, - tds, - events, eventName, i, isSupported, - div = document.createElement( "div" ), - documentElement = document.documentElement; + clickFn, + div = document.createElement("div"); // Preliminary tests - div.setAttribute("className", "t"); - div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>"; + div.setAttribute( "className", "t" ); + div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; - all = div.getElementsByTagName( "*" ); - a = div.getElementsByTagName( "a" )[ 0 ]; + all = div.getElementsByTagName("*"); + a = div.getElementsByTagName("a")[ 0 ]; + a.style.cssText = "top:1px;float:left;opacity:.5"; // Can't get basic test support - if ( !all || !all.length || !a ) { + if ( !all || !all.length ) { return {}; } // First batch of supports tests - select = document.createElement( "select" ); + select = document.createElement("select"); opt = select.appendChild( document.createElement("option") ); - input = div.getElementsByTagName( "input" )[ 0 ]; + input = div.getElementsByTagName("input")[ 0 ]; support = { // IE strips leading whitespace when .innerHTML is used @@ -1386,7 +1294,7 @@ jQuery.support = (function() { // Make sure that element opacity exists // (IE uses filter instead) // Use a regex to work around a WebKit issue. See #5145 - opacity: /^0.55/.test( a.style.opacity ), + opacity: /^0.5/.test( a.style.opacity ), // Verify style float existence // (IE uses styleFloat instead of cssFloat) @@ -1411,6 +1319,9 @@ jQuery.support = (function() { // Where outerHTML is undefined, this still works html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>", + // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode + boxModel: ( document.compatMode === "CSS1Compat" ), + // Will be defined later submitBubbles: true, changeBubbles: true, @@ -1419,7 +1330,9 @@ jQuery.support = (function() { noCloneEvent: true, inlineBlockNeedsLayout: false, shrinkWrapBlocks: false, - reliableMarginRight: true + reliableMarginRight: true, + boxSizingReliable: true, + pixelPosition: false }; // Make sure checked status is properly cloned @@ -1440,22 +1353,27 @@ jQuery.support = (function() { } if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { - div.attachEvent( "onclick", function() { + div.attachEvent( "onclick", clickFn = function() { // Cloning a node shouldn't copy over any // bound event handlers (IE does this) support.noCloneEvent = false; }); - div.cloneNode( true ).fireEvent( "onclick" ); + div.cloneNode( true ).fireEvent("onclick"); + div.detachEvent( "onclick", clickFn ); } // Check if a radio maintains its value // after being appended to the DOM input = document.createElement("input"); input.value = "t"; - input.setAttribute("type", "radio"); + input.setAttribute( "type", "radio" ); support.radioValue = input.value === "t"; - input.setAttribute("checked", "checked"); + input.setAttribute( "checked", "checked" ); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + div.appendChild( input ); fragment = document.createDocumentFragment(); fragment.appendChild( div.lastChild ); @@ -1470,23 +1388,6 @@ jQuery.support = (function() { fragment.removeChild( input ); fragment.appendChild( div ); - div.innerHTML = ""; - - // Check if div with explicit width and no margin-right incorrectly - // gets computed margin-right based on width of container. For more - // info see bug #3333 - // Fails in WebKit before Feb 2011 nightlies - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - if ( window.getComputedStyle ) { - marginDiv = document.createElement( "div" ); - marginDiv.style.width = "0"; - marginDiv.style.marginRight = "0"; - div.style.width = "2px"; - div.appendChild( marginDiv ); - support.reliableMarginRight = - ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; - } - // Technique from Juriy Zaytsev // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ // We only care about the case where non-standard event systems @@ -1494,10 +1395,10 @@ jQuery.support = (function() { // avoid an eval call (in setAttribute) which can cause CSP // to go haywire. See: https://developer.mozilla.org/en/Security/CSP if ( div.attachEvent ) { - for( i in { - submit: 1, - change: 1, - focusin: 1 + for ( i in { + submit: true, + change: true, + focusin: true }) { eventName = "on" + i; isSupported = ( eventName in div ); @@ -1509,15 +1410,10 @@ jQuery.support = (function() { } } - fragment.removeChild( div ); - - // Null elements to avoid leaks in IE - fragment = select = opt = marginDiv = div = input = null; - // Run tests that need a body at doc ready jQuery(function() { - var container, outer, inner, table, td, offsetSupport, - conMarginTop, ptlm, vb, style, html, + var container, div, tds, marginDiv, + divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;", body = document.getElementsByTagName("body")[0]; if ( !body ) { @@ -1525,16 +1421,8 @@ jQuery.support = (function() { return; } - conMarginTop = 1; - ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;"; - vb = "visibility:hidden;border:0;"; - style = "style='" + ptlm + "border:5px solid #000;padding:0;'"; - html = "<div " + style + "><div></div></div>" + - "<table " + style + " cellpadding='0' cellspacing='0'>" + - "<tr><td></td></tr></table>"; - container = document.createElement("div"); - container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px"; body.insertBefore( container, body.firstChild ); // Construct the test element @@ -1548,8 +1436,9 @@ jQuery.support = (function() { // display:none (it is still safe to use offsets if a parent element is // hidden; don safety goggles and see bug #4512 for more information). // (only IE 8 fails this test) - div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>"; - tds = div.getElementsByTagName( "td" ); + div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>"; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; isSupported = ( tds[ 0 ].offsetHeight === 0 ); tds[ 0 ].style.display = ""; @@ -1559,71 +1448,72 @@ jQuery.support = (function() { // (IE <= 8 fail this test) support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); - // Figure out if the W3C box model works as expected + // Check box-sizing and margin behavior div.innerHTML = ""; - div.style.width = div.style.paddingLeft = "1px"; - jQuery.boxModel = support.boxModel = div.offsetWidth === 2; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + support.boxSizing = ( div.offsetWidth === 4 ); + support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); + + // NOTE: To any future maintainer, we've window.getComputedStyle + // because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = document.createElement("div"); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } if ( typeof div.style.zoom !== "undefined" ) { // Check if natively block-level elements act like inline-block // elements when setting their display to 'inline' and giving // them layout // (IE < 8 does this) - div.style.display = "inline"; - div.style.zoom = 1; - support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); // Check if elements with layout shrink-wrap their children // (IE 6 does this) - div.style.display = ""; - div.innerHTML = "<div style='width:4px;'></div>"; - support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); - } - - div.style.cssText = ptlm + vb; - div.innerHTML = html; - - outer = div.firstChild; - inner = outer.firstChild; - td = outer.nextSibling.firstChild.firstChild; - - offsetSupport = { - doesNotAddBorder: ( inner.offsetTop !== 5 ), - doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) - }; - - inner.style.position = "fixed"; - inner.style.top = "20px"; - - // safari subtracts parent border width here which is 5px - offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); - inner.style.position = inner.style.top = ""; - - outer.style.overflow = "hidden"; - outer.style.position = "relative"; + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "<div></div>"; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); - offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); - offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + container.style.zoom = 1; + } + // Null elements to avoid leaks in IE body.removeChild( container ); - div = container = null; - - jQuery.extend( support, offsetSupport ); + container = div = tds = marginDiv = null; }); + // Null elements to avoid leaks in IE + fragment.removeChild( div ); + all = a = select = opt = input = fragment = div = null; + return support; })(); - - - - -var rbrace = /^(?:\{.*\}|\[.*\])$/, +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, rmultiDash = /([A-Z])/g; jQuery.extend({ cache: {}, - // Please use with caution + deletedIds: [], + + // Remove at next major release (1.9/2.0) uuid: 0, // Unique for each copy of jQuery on the page @@ -1649,7 +1539,7 @@ jQuery.extend({ return; } - var privateCache, thisCache, ret, + var thisCache, ret, internalKey = jQuery.expando, getByName = typeof name === "string", @@ -1663,12 +1553,11 @@ jQuery.extend({ // Only defining an ID for JS objects if its cache already exists allows // the code to shortcut on the same path as a DOM node with no cache - id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, - isEvents = name === "events"; + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; // Avoid doing any more work than we need to when trying to get data on an // object that has no data at all - if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { return; } @@ -1676,7 +1565,7 @@ jQuery.extend({ // Only DOM nodes need a new unique ID for each element since their data // ends up in the global cache if ( isNode ) { - elem[ internalKey ] = id = ++jQuery.uuid; + elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++; } else { id = internalKey; } @@ -1702,7 +1591,7 @@ jQuery.extend({ } } - privateCache = thisCache = cache[ id ]; + thisCache = cache[ id ]; // jQuery data() is stored in a separate object inside the object's internal data // cache in order to avoid key collisions between internal data and user-defined @@ -1719,12 +1608,6 @@ jQuery.extend({ thisCache[ jQuery.camelCase( name ) ] = data; } - // Users should not attempt to inspect the internal events object using jQuery.data, - // it is undocumented and subject to change. But does anyone listen? No. - if ( isEvents && !thisCache[ name ] ) { - return privateCache.events; - } - // Check for both converted-to-camel and non-converted data property names // If a data property was specified if ( getByName ) { @@ -1752,16 +1635,11 @@ jQuery.extend({ var thisCache, i, l, - // Reference to internal data cache key - internalKey = jQuery.expando, - isNode = elem.nodeType, // See jQuery.data for more information cache = isNode ? jQuery.cache : elem, - - // See jQuery.data for more information - id = isNode ? elem[ internalKey ] : internalKey; + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; // If there is already no cache entry for this object, there is no // purpose in continuing @@ -1788,7 +1666,7 @@ jQuery.extend({ if ( name in thisCache ) { name = [ name ]; } else { - name = name.split( " " ); + name = name.split(" "); } } } @@ -1811,35 +1689,23 @@ jQuery.extend({ // Don't destroy the parent cache unless the internal data object // had been the only thing left in it - if ( !isEmptyDataObject(cache[ id ]) ) { + if ( !isEmptyDataObject( cache[ id ] ) ) { return; } } - // Browsers that fail expando deletion also refuse to delete expandos on - // the window, but it will allow it on all other JS objects; other browsers - // don't care - // Ensure that `cache` is not a window object #10080 - if ( jQuery.support.deleteExpando || !cache.setInterval ) { + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { delete cache[ id ]; + + // When all else fails, null } else { cache[ id ] = null; } - - // We destroyed the cache and need to eliminate the expando on the node to avoid - // false lookups in the cache for entries that no longer exist - if ( isNode ) { - // IE does not allow us to delete expando properties from nodes, - // nor does it have a removeAttribute function on Document nodes; - // we must handle all of these cases - if ( jQuery.support.deleteExpando ) { - delete elem[ internalKey ]; - } else if ( elem.removeAttribute ) { - elem.removeAttribute( internalKey ); - } else { - elem[ internalKey ] = null; - } - } }, // For internal use only. @@ -1849,76 +1715,79 @@ jQuery.extend({ // A method for determining if a DOM node can handle the data expando acceptData: function( elem ) { - if ( elem.nodeName ) { - var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; - if ( match ) { - return !(match === true || elem.getAttribute("classid") !== match); - } - } - - return true; + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; } }); jQuery.fn.extend({ data: function( key, value ) { - var parts, attr, name, + var parts, part, attr, name, l, + elem = this[0], + i = 0, data = null; - if ( typeof key === "undefined" ) { + // Gets all values + if ( key === undefined ) { if ( this.length ) { - data = jQuery.data( this[0] ); + data = jQuery.data( elem ); - if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) { - attr = this[0].attributes; - for ( var i = 0, l = attr.length; i < l; i++ ) { + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { name = attr[i].name; - if ( name.indexOf( "data-" ) === 0 ) { + if ( !name.indexOf( "data-" ) ) { name = jQuery.camelCase( name.substring(5) ); - dataAttr( this[0], name, data[ name ] ); + dataAttr( elem, name, data[ name ] ); } } - jQuery._data( this[0], "parsedAttrs", true ); + jQuery._data( elem, "parsedAttrs", true ); } } return data; + } - } else if ( typeof key === "object" ) { + // Sets multiple values + if ( typeof key === "object" ) { return this.each(function() { jQuery.data( this, key ); }); } - parts = key.split("."); + parts = key.split( ".", 2 ); parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; - if ( value === undefined ) { - data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + return jQuery.access( this, function( value ) { - // Try to fetch any internally stored data first - if ( data === undefined && this.length ) { - data = jQuery.data( this[0], key ); - data = dataAttr( this[0], key, data ); - } + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); - return data === undefined && parts[1] ? - this.data( parts[0] ) : - data; + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } - } else { - return this.each(function() { - var self = jQuery( this ), - args = [ parts[0], value ]; + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); - self.triggerHandler( "setData" + parts[1] + "!", args ); + self.triggerHandler( "setData" + part, parts ); jQuery.data( this, key, value ); - self.triggerHandler( "changeData" + parts[1] + "!", args ); + self.triggerHandler( "changeData" + part, parts ); }); - } + }, null, value, arguments.length > 1, null, false ); }, removeData: function( key ) { @@ -1942,8 +1811,9 @@ function dataAttr( elem, key, data ) { data = data === "true" ? true : data === "false" ? false : data === "null" ? null : - jQuery.isNumeric( data ) ? parseFloat( data ) : - rbrace.test( data ) ? jQuery.parseJSON( data ) : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : data; } catch( e ) {} @@ -1960,7 +1830,8 @@ function dataAttr( elem, key, data ) { // checks a cache object for emptiness function isEmptyDataObject( obj ) { - for ( var name in obj ) { + var name; + for ( name in obj ) { // if the public data object is empty, the private is still empty if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { @@ -1973,73 +1844,23 @@ function isEmptyDataObject( obj ) { return true; } - - - - -function handleQueueMarkDefer( elem, type, src ) { - var deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - defer = jQuery._data( elem, deferDataKey ); - if ( defer && - ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && - ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { - // Give room for hard-coded callbacks to fire first - // and eventually mark/queue something else on the element - setTimeout( function() { - if ( !jQuery._data( elem, queueDataKey ) && - !jQuery._data( elem, markDataKey ) ) { - jQuery.removeData( elem, deferDataKey, true ); - defer.fire(); - } - }, 0 ); - } -} - jQuery.extend({ - - _mark: function( elem, type ) { - if ( elem ) { - type = ( type || "fx" ) + "mark"; - jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); - } - }, - - _unmark: function( force, elem, type ) { - if ( force !== true ) { - type = elem; - elem = force; - force = false; - } - if ( elem ) { - type = type || "fx"; - var key = type + "mark", - count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); - if ( count ) { - jQuery._data( elem, key, count ); - } else { - jQuery.removeData( elem, key, true ); - handleQueueMarkDefer( elem, type, "mark" ); - } - } - }, - queue: function( elem, type, data ) { - var q; + var queue; + if ( elem ) { type = ( type || "fx" ) + "queue"; - q = jQuery._data( elem, type ); + queue = jQuery._data( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { - if ( !q || jQuery.isArray(data) ) { - q = jQuery._data( elem, type, jQuery.makeArray(data) ); + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); } else { - q.push( data ); + queue.push( data ); } } - return q || []; + return queue || []; } }, @@ -2047,51 +1868,75 @@ jQuery.extend({ type = type || "fx"; var queue = jQuery.queue( elem, type ), + startLength = queue.length, fn = queue.shift(), - hooks = {}; + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { fn = queue.shift(); + startLength--; } if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if ( type === "fx" ) { queue.unshift( "inprogress" ); } - jQuery._data( elem, type + ".run", hooks ); - fn.call( elem, function() { - jQuery.dequeue( elem, type ); - }, hooks ); + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); } - if ( !queue.length ) { - jQuery.removeData( elem, type + "queue " + type + ".run", true ); - handleQueueMarkDefer( elem, type, "queue" ); + if ( !startLength && hooks ) { + hooks.empty.fire(); } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery.removeData( elem, type + "queue", true ); + jQuery.removeData( elem, key, true ); + }) + }); } }); jQuery.fn.extend({ queue: function( type, data ) { + var setter = 2; + if ( typeof type !== "string" ) { data = type; type = "fx"; + setter--; } - if ( data === undefined ) { + if ( arguments.length < setter ) { return jQuery.queue( this[0], type ); } - return this.each(function() { - var queue = jQuery.queue( this, type, data ); - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); }, dequeue: function( type ) { return this.each(function() { @@ -2116,55 +1961,47 @@ jQuery.fn.extend({ }, // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) - promise: function( type, object ) { + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + if ( typeof type !== "string" ) { - object = type; + obj = type; type = undefined; } type = type || "fx"; - var defer = jQuery.Deferred(), - elements = this, - i = elements.length, - count = 1, - deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - tmp; - function resolve() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - } + while( i-- ) { - if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || - ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || - jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && - jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { count++; - tmp.add( resolve ); + tmp.empty.add( resolve ); } } resolve(); - return defer.promise(); + return defer.promise( obj ); } }); - - - - -var rclass = /[\n\t\r]/g, - rspace = /\s+/, +var nodeHook, boolHook, fixSpecified, + rclass = /[\t\r\n]/g, rreturn = /\r/g, rtype = /^(?:button|input)$/i, rfocusable = /^(?:button|input|object|select|textarea)$/i, - rclickable = /^a(?:rea)?$/i, + rclickable = /^a(?:rea|)$/i, rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, - getSetAttribute = jQuery.support.getSetAttribute, - nodeHook, boolHook, fixSpecified; + getSetAttribute = jQuery.support.getSetAttribute; jQuery.fn.extend({ attr: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.attr ); + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); }, removeAttr: function( name ) { @@ -2174,7 +2011,7 @@ jQuery.fn.extend({ }, prop: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.prop ); + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); }, removeProp: function( name ) { @@ -2199,7 +2036,7 @@ jQuery.fn.extend({ } if ( value && typeof value === "string" ) { - classNames = value.split( rspace ); + classNames = value.split( core_rspace ); for ( i = 0, l = this.length; i < l; i++ ) { elem = this[ i ]; @@ -2212,7 +2049,7 @@ jQuery.fn.extend({ setClass = " " + elem.className + " "; for ( c = 0, cl = classNames.length; c < cl; c++ ) { - if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) { setClass += classNames[ c ] + " "; } } @@ -2226,31 +2063,30 @@ jQuery.fn.extend({ }, removeClass: function( value ) { - var classNames, i, l, elem, className, c, cl; + var removes, className, elem, c, cl, i, l; if ( jQuery.isFunction( value ) ) { return this.each(function( j ) { jQuery( this ).removeClass( value.call(this, j, this.className) ); }); } - if ( (value && typeof value === "string") || value === undefined ) { - classNames = ( value || "" ).split( rspace ); + removes = ( value || "" ).split( core_rspace ); for ( i = 0, l = this.length; i < l; i++ ) { elem = this[ i ]; - if ( elem.nodeType === 1 && elem.className ) { - if ( value ) { - className = (" " + elem.className + " ").replace( rclass, " " ); - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - className = className.replace(" " + classNames[ c ] + " ", " "); - } - elem.className = jQuery.trim( className ); - } else { - elem.className = ""; + className = (" " + elem.className + " ").replace( rclass, " " ); + + // loop over each item in the removal list + for ( c = 0, cl = removes.length; c < cl; c++ ) { + // Remove until there is nothing to remove, + while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) { + className = className.replace( " " + removes[ c ] + " " , " " ); + } } + elem.className = value ? jQuery.trim( className ) : ""; } } } @@ -2275,10 +2111,10 @@ jQuery.fn.extend({ i = 0, self = jQuery( this ), state = stateVal, - classNames = value.split( rspace ); + classNames = value.split( core_rspace ); while ( (className = classNames[ i++ ]) ) { - // check each className given, space seperated list + // check each className given, space separated list state = isBool ? state : !self.hasClass( className ); self[ state ? "addClass" : "removeClass" ]( className ); } @@ -2300,7 +2136,7 @@ jQuery.fn.extend({ i = 0, l = this.length; for ( ; i < l; i++ ) { - if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { return true; } } @@ -2314,7 +2150,7 @@ jQuery.fn.extend({ if ( !arguments.length ) { if ( elem ) { - hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { return ret; @@ -2335,7 +2171,8 @@ jQuery.fn.extend({ isFunction = jQuery.isFunction( value ); return this.each(function( i ) { - var self = jQuery(this), val; + var val, + self = jQuery(this); if ( this.nodeType !== 1 ) { return; @@ -2358,7 +2195,7 @@ jQuery.fn.extend({ }); } - hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; // If set returns undefined, fall back to normal setting if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { @@ -2437,16 +2274,8 @@ jQuery.extend({ } }, - attrFn: { - val: true, - css: true, - html: true, - text: true, - data: true, - width: true, - height: true, - offset: true - }, + // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9 + attrFn: {}, attr: function( elem, name, value, pass ) { var ret, hooks, notxml, @@ -2457,7 +2286,7 @@ jQuery.extend({ return; } - if ( pass && name in jQuery.attrFn ) { + if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { return jQuery( elem )[ name ]( value ); } @@ -2485,7 +2314,7 @@ jQuery.extend({ return ret; } else { - elem.setAttribute( name, "" + value ); + elem.setAttribute( name, value + "" ); return value; } @@ -2504,25 +2333,29 @@ jQuery.extend({ }, removeAttr: function( elem, value ) { - var propName, attrNames, name, l, + var propName, attrNames, name, isBool, i = 0; if ( value && elem.nodeType === 1 ) { - attrNames = value.toLowerCase().split( rspace ); - l = attrNames.length; - for ( ; i < l; i++ ) { + attrNames = value.split( core_rspace ); + + for ( ; i < attrNames.length; i++ ) { name = attrNames[ i ]; if ( name ) { propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); // See #9699 for explanation of this approach (setting first, then removal) - jQuery.attr( elem, name, "" ); + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } elem.removeAttribute( getSetAttribute ? name : propName ); // Set corresponding property to false for boolean attributes - if ( rboolean.test( name ) && propName in elem ) { + if ( isBool && propName in elem ) { elem[ propName ] = false; } } @@ -2637,9 +2470,6 @@ jQuery.extend({ } }); -// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) -jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; - // Hook for boolean attributes boolHook = { get: function( elem, name ) { @@ -2676,7 +2506,8 @@ if ( !getSetAttribute ) { fixSpecified = { name: true, - id: true + id: true, + coords: true }; // Use this for any attribute in IE6/7 @@ -2685,8 +2516,8 @@ if ( !getSetAttribute ) { get: function( elem, name ) { var ret; ret = elem.getAttributeNode( name ); - return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? - ret.nodeValue : + return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ? + ret.value : undefined; }, set: function( elem, value, name ) { @@ -2696,13 +2527,10 @@ if ( !getSetAttribute ) { ret = document.createAttribute( name ); elem.setAttributeNode( ret ); } - return ( ret.nodeValue = value + "" ); + return ( ret.value = value + "" ); } }; - // Apply the nodeHook to tabindex - jQuery.attrHooks.tabindex.set = nodeHook.set; - // Set width and height to auto instead of 0 on empty string( Bug #8150 ) // This is for removals jQuery.each([ "width", "height" ], function( i, name ) { @@ -2750,7 +2578,7 @@ if ( !jQuery.support.style ) { return elem.style.cssText.toLowerCase() || undefined; }, set: function( elem, value ) { - return ( elem.style.cssText = "" + value ); + return ( elem.style.cssText = value + "" ); } }; } @@ -2800,35 +2628,12 @@ jQuery.each([ "radio", "checkbox" ], function() { } }); }); - - - - var rformElems = /^(?:textarea|input|select)$/i, - rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, - rhoverHack = /\bhover(\.\S+)?\b/, + rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/, + rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|contextmenu)|click/, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, - quickParse = function( selector ) { - var quick = rquickIs.exec( selector ); - if ( quick ) { - // 0 1 2 3 - // [ _, tag, id, class ] - quick[1] = ( quick[1] || "" ).toLowerCase(); - quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); - } - return quick; - }, - quickIs = function( elem, m ) { - var attrs = elem.attributes || {}; - return ( - (!m[1] || elem.nodeName.toLowerCase() === m[1]) && - (!m[2] || (attrs.id || {}).value === m[2]) && - (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) - ); - }, hoverHack = function( events ) { return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); }; @@ -2843,7 +2648,7 @@ jQuery.event = { var elemData, eventHandle, events, t, tns, type, namespaces, handleObj, - handleObjIn, quick, handlers, special; + handleObjIn, handlers, special; // Don't attach events to noData or text/comment nodes (allow plain objects tho) if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { @@ -2854,6 +2659,7 @@ jQuery.event = { if ( handler.handler ) { handleObjIn = handler; handler = handleObjIn.handler; + selector = handleObjIn.selector; } // Make sure that the handler has a unique ID, used to find/remove it later @@ -2905,7 +2711,7 @@ jQuery.event = { handler: handler, guid: handler.guid, selector: selector, - quick: quickParse( selector ), + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), namespace: namespaces.join(".") }, handleObjIn ); @@ -2955,9 +2761,9 @@ jQuery.event = { // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { - var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), - t, tns, type, origType, namespaces, origCount, - j, events, special, handle, eventType, handleObj; + var t, tns, type, origType, namespaces, origCount, + j, events, special, eventType, handleObj, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); if ( !elemData || !(events = elemData.events) ) { return; @@ -2982,7 +2788,7 @@ jQuery.event = { type = ( selector? special.delegateType : special.bindType ) || type; eventType = events[ type ] || []; origCount = eventType.length; - namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; // Remove matching events for ( j = 0; j < eventType.length; j++ ) { @@ -3006,7 +2812,7 @@ jQuery.event = { // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if ( eventType.length === 0 && origCount !== eventType.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } @@ -3016,14 +2822,11 @@ jQuery.event = { // Remove the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { - handle = elemData.handle; - if ( handle ) { - handle.elem = null; - } + delete elemData.handle; // removeData also checks for emptiness and clears the expando if empty // so use it instead of delete - jQuery.removeData( elem, [ "events", "handle" ], true ); + jQuery.removeData( elem, "events", true ); } }, @@ -3042,9 +2845,9 @@ jQuery.event = { } // Event object or event type - var type = event.type || event, - namespaces = [], - cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType, + type = event.type || event, + namespaces = []; // focus/blur morphs to focusin/out; ensure we're not firing them right now if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { @@ -3082,7 +2885,7 @@ jQuery.event = { event.isTrigger = true; event.exclusive = exclusive; event.namespace = namespaces.join( "." ); - event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; // Handle a global trigger @@ -3121,14 +2924,13 @@ jQuery.event = { bubbleType = special.delegateType || type; cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; - old = null; - for ( ; cur; cur = cur.parentNode ) { + for ( old = elem; cur; cur = cur.parentNode ) { eventPath.push([ cur, bubbleType ]); old = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( old && old === elem.ownerDocument ) { + if ( old === (elem.ownerDocument || document) ) { eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); } } @@ -3145,7 +2947,7 @@ jQuery.event = { } // Note that this is a bare JS function and not a jQuery handler handle = ontype && cur[ ontype ]; - if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { event.preventDefault(); } } @@ -3190,45 +2992,50 @@ jQuery.event = { // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( event || window.event ); - var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related, + handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), delegateCount = handlers.delegateCount, - args = [].slice.call( arguments, 0 ), + args = core_slice.call( arguments ), run_all = !event.exclusive && !event.namespace, - handlerQueue = [], - i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = []; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[0] = event; event.delegateTarget = this; - // Determine handlers that should run if there are delegated events - // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861) - if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) { + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } - // Pregenerate a single jQuery object for reuse with .is() - jqcur = jQuery(this); - jqcur.context = this.ownerDocument || this; + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { - selMatch = {}; - matches = []; - jqcur[0] = cur; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - sel = handleObj.selector; - - if ( selMatch[ sel ] === undefined ) { - selMatch[ sel ] = ( - handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) - ); + + // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + selMatch = {}; + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } } - if ( selMatch[ sel ] ) { - matches.push( handleObj ); + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); } } - if ( matches.length ) { - handlerQueue.push({ elem: cur, matches: matches }); - } } } @@ -3266,6 +3073,11 @@ jQuery.event = { } } + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + return event.result; }, @@ -3348,20 +3160,13 @@ jQuery.event = { event.target = event.target.parentNode; } - // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) - if ( event.metaKey === undefined ) { - event.metaKey = event.ctrlKey; - } + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) + event.metaKey = !!event.metaKey; return fixHook.filter? fixHook.filter( event, originalEvent ) : event; }, special: { - ready: { - // Make sure the ready event is setup - setup: jQuery.bindReady - }, - load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true @@ -3424,8 +3229,17 @@ jQuery.removeEvent = document.removeEventListener ? } } : function( elem, type, handle ) { + var name = "on" + type; + if ( elem.detachEvent ) { - elem.detachEvent( "on" + type, handle ); + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 – + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === "undefined" ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); } }; @@ -3522,11 +3336,11 @@ jQuery.each({ bindType: fix, handle: function( event ) { - var target = this, + var ret, + target = this, related = event.relatedTarget, handleObj = event.handleObj, - selector = handleObj.selector, - ret; + selector = handleObj.selector; // For mousenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window @@ -3555,19 +3369,26 @@ if ( !jQuery.support.submitBubbles ) { // Node name check avoids a VML-related crash in IE (#9807) var elem = e.target, form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; - if ( form && !form._submit_attached ) { + if ( form && !jQuery._data( form, "_submit_attached" ) ) { jQuery.event.add( form, "submit._submit", function( event ) { - // If form was submitted by the user, bubble the event up the tree - if ( this.parentNode && !event.isTrigger ) { - jQuery.event.simulate( "submit", this.parentNode, event, true ); - } + event._submit_bubble = true; }); - form._submit_attached = true; + jQuery._data( form, "_submit_attached", true ); } }); // 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 ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + teardown: function() { // Only need this for delegated form submit events if ( jQuery.nodeName( this, "form" ) ) { @@ -3600,8 +3421,9 @@ if ( !jQuery.support.changeBubbles ) { jQuery.event.add( this, "click._change", function( event ) { if ( this._just_changed && !event.isTrigger ) { this._just_changed = false; - jQuery.event.simulate( "change", this, event, true ); } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); }); } return false; @@ -3610,13 +3432,13 @@ if ( !jQuery.support.changeBubbles ) { jQuery.event.add( this, "beforeactivate._change", function( e ) { var elem = e.target; - if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { jQuery.event.add( elem, "change._change", function( event ) { if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { jQuery.event.simulate( "change", this.parentNode, event, true ); } }); - elem._change_attached = true; + jQuery._data( elem, "_change_attached", true ); } }); }, @@ -3633,7 +3455,7 @@ if ( !jQuery.support.changeBubbles ) { teardown: function() { jQuery.event.remove( this, "._change" ); - return rformElems.test( this.nodeName ); + return !rformElems.test( this.nodeName ); } }; } @@ -3671,9 +3493,9 @@ jQuery.fn.extend({ // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { + if ( typeof selector !== "string" ) { // && selector != null // ( types-Object, data ) - data = selector; + data = data || selector; selector = undefined; } for ( type in types ) { @@ -3719,14 +3541,15 @@ jQuery.fn.extend({ }); }, one: function( types, selector, data, fn ) { - return this.on.call( this, types, selector, data, fn, 1 ); + return this.on( types, selector, data, fn, 1 ); }, off: function( types, selector, fn ) { + var handleObj, type; if ( types && types.preventDefault && types.handleObj ) { // ( event ) dispatched jQuery.Event - var handleObj = types.handleObj; + handleObj = types.handleObj; jQuery( types.delegateTarget ).off( - handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type, + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler ); @@ -3734,7 +3557,7 @@ jQuery.fn.extend({ } if ( typeof types === "object" ) { // ( types-object [, selector] ) - for ( var type in types ) { + for ( type in types ) { this.off( type, selector, types[ type ] ); } return this; @@ -3773,7 +3596,7 @@ jQuery.fn.extend({ }, undelegate: function( selector, types, fn ) { // ( namespace ) or ( selector, types [, fn] ) - return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); }, trigger: function( type, data ) { @@ -3834,10 +3657,6 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl this.trigger( name ); }; - if ( jQuery.attrFn ) { - jQuery.attrFn[ name ] = true; - } - if ( rkeyEvent.test( name ) ) { jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; } @@ -3846,1468 +3665,1683 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; } }); - - - -/*! - * Sizzle CSS Selector Engine - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - expando = "sizcache" + (Math.random() + '').replace('.', ''), - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true, - rBackslash = /\\/g, - rReturn = /\r\n/g, - rNonWord = /\W/; - -// Here we 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() { - baseHasDuplicate = false; - return 0; -}); - -var Sizzle = function( selector, context, results, seed ) { - results = results || []; - context = context || document; - - var origContext = context; - - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - var m, set, checkSet, extra, ret, cur, pop, i, - prune = true, - contextXML = Sizzle.isXML( context ), - parts = [], - soFar = selector; - - // Reset the position of the chunker regexp (start from head) - do { - chunker.exec( "" ); - m = chunker.exec( soFar ); - - if ( m ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - } while ( m ); - - if ( parts.length > 1 && origPOS.exec( selector ) ) { - - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context, seed ); - - } else { - set = Expr.relative[ parts[0] ] ? - [ context ] : - Sizzle( parts.shift(), context ); - - while ( parts.length ) { - selector = parts.shift(); - - if ( Expr.relative[ selector ] ) { - selector += parts.shift(); - } - - set = posProcess( selector, set, seed ); - } - } - - } else { - // Take a shortcut and set the context if the root selector is an ID - // (but not if it'll be faster if the inner selector is an ID) - if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && - Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { - - ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? - Sizzle.filter( ret.expr, ret.set )[0] : - ret.set[0]; - } - - if ( context ) { - ret = seed ? - { expr: parts.pop(), set: makeArray(seed) } : - Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); - - set = ret.expr ? - Sizzle.filter( ret.expr, ret.set ) : - ret.set; - - if ( parts.length > 0 ) { - checkSet = makeArray( set ); - - } else { - prune = false; - } - - while ( parts.length ) { - cur = parts.pop(); - pop = cur; - - if ( !Expr.relative[ cur ] ) { - cur = ""; - } else { - pop = parts.pop(); - } - - if ( pop == null ) { - pop = context; - } - - Expr.relative[ cur ]( checkSet, pop, contextXML ); - } - - } else { - checkSet = parts = []; - } - } - - if ( !checkSet ) { - checkSet = set; - } - - if ( !checkSet ) { - Sizzle.error( cur || selector ); - } - - if ( toString.call(checkSet) === "[object Array]" ) { - if ( !prune ) { - results.push.apply( results, checkSet ); - - } else if ( context && context.nodeType === 1 ) { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { - results.push( set[i] ); - } - } - - } else { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && checkSet[i].nodeType === 1 ) { - results.push( set[i] ); - } - } - } - - } else { - makeArray( checkSet, results ); - } - - if ( extra ) { - Sizzle( extra, origContext, results, seed ); - Sizzle.uniqueSort( results ); - } - - return results; -}; - -Sizzle.uniqueSort = function( results ) { - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort( sortOrder ); - - if ( hasDuplicate ) { - for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[ i - 1 ] ) { - results.splice( i--, 1 ); - } - } - } - } - - return results; -}; - -Sizzle.matches = function( expr, set ) { - return Sizzle( expr, null, null, set ); -}; - -Sizzle.matchesSelector = function( node, expr ) { - return Sizzle( expr, null, null, [node] ).length > 0; -}; - -Sizzle.find = function( expr, context, isXML ) { - var set, i, len, match, type, left; - - if ( !expr ) { - return []; - } - - 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 ); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace( rBackslash, "" ); - set = Expr.find[ type ]( match, context, isXML ); - - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } - - if ( !set ) { - set = typeof context.getElementsByTagName !== "undefined" ? - context.getElementsByTagName( "*" ) : - []; - } - - return { set: set, expr: expr }; -}; - -Sizzle.filter = function( expr, set, inplace, not ) { - var match, anyFound, - type, found, item, filter, left, - i, pass, - old = expr, - result = [], - curLoop = set, - isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); - - while ( expr && set.length ) { - for ( type in Expr.filter ) { - if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { - filter = Expr.filter[ type ]; - left = match[1]; - - anyFound = false; - - match.splice(1,1); - - if ( left.substr( left.length - 1 ) === "\\" ) { - continue; - } - - if ( curLoop === result ) { - result = []; - } - - if ( Expr.preFilter[ type ] ) { - match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); - - if ( !match ) { - anyFound = found = true; - - } else if ( match === true ) { - continue; - } - } - - if ( match ) { - for ( i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - pass = not ^ found; - - if ( inplace && found != null ) { - if ( pass ) { - anyFound = true; - - } else { - curLoop[i] = false; - } - - } else if ( pass ) { - result.push( item ); - anyFound = true; - } - } - } - } - - if ( found !== undefined ) { - if ( !inplace ) { - curLoop = result; - } - - expr = expr.replace( Expr.match[ type ], "" ); - - if ( !anyFound ) { - return []; - } - - break; - } - } - } - - // Improper expression - if ( expr === old ) { - if ( anyFound == null ) { - Sizzle.error( expr ); - - } else { - break; - } - } - - old = expr; - } - - return curLoop; -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Utility function for retreiving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -var getText = Sizzle.getText = function( elem ) { - var i, node, - nodeType = elem.nodeType, - ret = ""; - - if ( nodeType ) { - if ( nodeType === 1 || nodeType === 9 ) { - // Use textContent || innerText for elements - if ( typeof elem.textContent === 'string' ) { - return elem.textContent; - } else if ( typeof elem.innerText === 'string' ) { - // Replace IE's carriage returns - return elem.innerText.replace( rReturn, '' ); - } else { - // Traverse it's children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - } else { - - // If no nodeType, this is expected to be an array - for ( i = 0; (node = elem[i]); i++ ) { - // Do not traverse comment nodes - if ( node.nodeType !== 8 ) { - ret += getText( node ); - } - } - } - return ret; -}; - -var Expr = Sizzle.selectors = { - order: [ "ID", "NAME", "TAG" ], - - match: { - ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, - PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ - }, - - leftMatch: {}, - - attrMap: { - "class": "className", - "for": "htmlFor" - }, - - attrHandle: { - href: function( elem ) { - return elem.getAttribute( "href" ); - }, - type: function( elem ) { - return elem.getAttribute( "type" ); - } - }, - - relative: { - "+": function(checkSet, part){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !rNonWord.test( part ), - isPartStrNotTag = isPartStr && !isTag; - - if ( isTag ) { - part = part.toLowerCase(); - } - - for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { - if ( (elem = checkSet[i]) ) { - while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} - - checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? - elem || false : - elem === part; - } - } - - if ( isPartStrNotTag ) { - Sizzle.filter( part, checkSet, true ); - } - }, - - ">": function( checkSet, part ) { - var elem, - isPartStr = typeof part === "string", - i = 0, - l = checkSet.length; - - if ( isPartStr && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - var parent = elem.parentNode; - checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; - } - } - - } else { - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - checkSet[i] = isPartStr ? - elem.parentNode : - elem.parentNode === part; - } - } - - if ( isPartStr ) { - Sizzle.filter( part, checkSet, true ); - } - } - }, - - "": function(checkSet, part, isXML){ - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); - }, - - "~": function( checkSet, part, isXML ) { - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); - } - }, - - find: { - ID: function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [m] : []; - } - }, - - NAME: function( match, context ) { - if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], - results = context.getElementsByName( match[1] ); - - for ( var i = 0, l = results.length; i < l; i++ ) { - if ( results[i].getAttribute("name") === match[1] ) { - ret.push( results[i] ); - } - } - - return ret.length === 0 ? null : ret; - } - }, - - TAG: function( match, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( match[1] ); - } - } - }, - preFilter: { - CLASS: function( match, curLoop, inplace, result, not, isXML ) { - match = " " + match[1].replace( rBackslash, "" ) + " "; - - if ( isXML ) { - return match; - } - - for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { - if ( elem ) { - if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { - if ( !inplace ) { - result.push( elem ); - } - - } else if ( inplace ) { - curLoop[i] = false; - } - } - } - - return false; - }, - - ID: function( match ) { - return match[1].replace( rBackslash, "" ); - }, - - TAG: function( match, curLoop ) { - return match[1].replace( rBackslash, "" ).toLowerCase(); - }, - - CHILD: function( match ) { - if ( match[1] === "nth" ) { - if ( !match[2] ) { - Sizzle.error( match[0] ); - } - - match[2] = match[2].replace(/^\+|\s*/g, ''); - - // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' - var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( - match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || - !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); - - // calculate the numbers (first)n+(last) including if they are negative - match[2] = (test[1] + (test[2] || 1)) - 0; - match[3] = test[3] - 0; - } - else if ( match[2] ) { - Sizzle.error( match[0] ); - } - - // TODO: Move to normal caching system - match[0] = done++; - - return match; - }, - - 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]; - } - - // Handle if an un-quoted value was used - match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); - - if ( match[2] === "~=" ) { - match[4] = " " + match[4] + " "; - } - - return match; - }, - - PSEUDO: function( match, curLoop, inplace, result, not ) { - if ( match[1] === "not" ) { - // If we're dealing with a complex expression, or a simple one - if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { - match[3] = Sizzle(match[3], null, null, curLoop); - - } else { - var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); - - if ( !inplace ) { - result.push.apply( result, ret ); - } - - return false; - } - - } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { - return true; - } - - return match; - }, - - POS: function( match ) { - match.unshift( true ); - - return match; - } - }, - - filters: { - enabled: function( elem ) { - return elem.disabled === false && elem.type !== "hidden"; - }, - - disabled: function( elem ) { - return elem.disabled === true; - }, - - 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; - }, - - parent: function( elem ) { - return !!elem.firstChild; - }, - - empty: function( elem ) { - return !elem.firstChild; - }, - - has: function( elem, i, match ) { - return !!Sizzle( match[3], elem ).length; - }, - - header: function( elem ) { - return (/h\d/i).test( elem.nodeName ); - }, - - 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) - // use getAttribute instead to test this case - return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); - }, - - radio: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; - }, - - checkbox: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; - }, - - file: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; - }, - - password: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; - }, - - submit: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "submit" === elem.type; - }, - - image: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; - }, - - reset: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "reset" === elem.type; - }, - - button: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && "button" === elem.type || name === "button"; - }, - - input: function( elem ) { - return (/input|select|textarea|button/i).test( elem.nodeName ); - }, - - focus: function( elem ) { - return elem === elem.ownerDocument.activeElement; - } - }, - setFilters: { - first: function( elem, i ) { - return i === 0; - }, - - last: function( elem, i, match, array ) { - return i === array.length - 1; - }, - - even: function( elem, i ) { - return i % 2 === 0; - }, - - odd: function( elem, i ) { - return i % 2 === 1; - }, - - lt: function( elem, i, match ) { - return i < match[3] - 0; - }, - - gt: function( elem, i, match ) { - return i > match[3] - 0; - }, - - nth: function( elem, i, match ) { - return match[3] - 0 === i; - }, - - eq: function( elem, i, match ) { - return match[3] - 0 === i; - } - }, - filter: { - PSEUDO: function( elem, match, i, array ) { - var name = match[1], - filter = Expr.filters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - - } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; - - } else if ( name === "not" ) { - var not = match[3]; - - for ( var j = 0, l = not.length; j < l; j++ ) { - if ( not[j] === elem ) { - return false; - } - } - - return true; - - } else { - Sizzle.error( name ); - } - }, - - CHILD: function( elem, match ) { - var first, last, - doneName, parent, cache, - count, diff, - type = match[1], - 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; - - case "last": - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - - return true; - - case "nth": - first = match[2]; - last = match[3]; - - 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 ) { - return diff === 0; - - } else { - return ( diff % first === 0 && diff / first >= 0 ); - } - } - }, - - ID: function( elem, match ) { - return elem.nodeType === 1 && elem.getAttribute("id") === match; - }, - - 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; - }, - - ATTR: function( elem, match ) { - var name = match[1], - result = Sizzle.attr ? - Sizzle.attr( elem, name ) : - Expr.attrHandle[ name ] ? - Expr.attrHandle[ name ]( elem ) : - elem[ name ] != null ? - elem[ name ] : - elem.getAttribute( name ), - value = result + "", - type = match[2], - check = match[4]; - - return result == null ? - type === "!=" : - !type && Sizzle.attr ? - result != null : - type === "=" ? - value === check : - type === "*=" ? - value.indexOf(check) >= 0 : - type === "~=" ? - (" " + value + " ").indexOf(check) >= 0 : - !check ? - value && result !== false : - type === "!=" ? - value !== check : - type === "^=" ? - value.indexOf(check) === 0 : - type === "$=" ? - value.substr(value.length - check.length) === check : - type === "|=" ? - value === check || value.substr(0, check.length + 1) === check + "-" : - false; - }, - - POS: function( elem, match, i, array ) { - var name = match[2], - filter = Expr.setFilters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } - } - } -}; - -var origPOS = Expr.match.POS, - fescape = function(all, num){ - return "\\" + (num - 0 + 1); - }; - -for ( var type in Expr.match ) { - Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); - Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); -} - -var makeArray = function( array, results ) { - array = Array.prototype.slice.call( array, 0 ); - - if ( results ) { - results.push.apply( results, array ); - return results; - } - - return array; -}; - -// Perform a simple check to determine if the browser is capable of -// converting a NodeList to an array using builtin methods. -// Also verifies that the returned array holds DOM nodes -// (which is not the case in the Blackberry browser) -try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; - -// Provide a fallback method if it does not work -} catch( e ) { - makeArray = function( array, results ) { - var i = 0, - ret = results || []; - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - - } else { - if ( typeof array.length === "number" ) { - for ( var l = array.length; i < l; i++ ) { - ret.push( array[i] ); - } - - } else { - for ( ; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - return ret; - }; -} - -var sortOrder, siblingCheck; - -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - return a.compareDocumentPosition ? -1 : 1; - } - - return 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; - }; -} - -// Check to see if the browser returns elements by name when -// querying by getElementById (and provide a workaround) -(function(){ - // We're going to inject a fake input element with a specified name - var form = document.createElement("div"), - id = "script" + (new Date()).getTime(), - root = document.documentElement; - - form.innerHTML = "<a name='" + id + "'/>"; - - // Inject it into the root element, check its status, and remove it quickly - root.insertBefore( form, root.firstChild ); - - // The workaround has to do additional checks after a getElementById - // Which slows things down for other browsers (hence the branching) - if ( document.getElementById( id ) ) { - Expr.find.ID = function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - - return m ? - m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? - [m] : - undefined : - []; - } - }; - - Expr.filter.ID = function( elem, match ) { - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); - - return elem.nodeType === 1 && node && node.nodeValue === match; - }; - } - - root.removeChild( form ); - - // release memory in IE - root = form = null; -})(); - -(function(){ - // Check to see if the browser returns only elements - // when doing getElementsByTagName("*") - - // Create a fake element - var div = document.createElement("div"); - div.appendChild( document.createComment("") ); - - // Make sure no comments are found - if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function( match, context ) { - var results = context.getElementsByTagName( match[1] ); - - // Filter out possible comments - if ( match[1] === "*" ) { - var tmp = []; - - for ( var i = 0; results[i]; i++ ) { - if ( results[i].nodeType === 1 ) { - tmp.push( results[i] ); - } - } - - results = tmp; - } - - return results; - }; - } - - // Check to see if an attribute returns normalized href attributes - div.innerHTML = "<a href='#'></a>"; - - if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && - div.firstChild.getAttribute("href") !== "#" ) { - - Expr.attrHandle.href = function( elem ) { - return elem.getAttribute( "href", 2 ); - }; - } - - // release memory in IE - div = null; -})(); - -if ( document.querySelectorAll ) { - (function(){ - var oldSizzle = Sizzle, - div = document.createElement("div"), - id = "__sizzle__"; - - div.innerHTML = "<p class='TEST'></p>"; - - // Safari can't handle uppercase or unicode characters when - // in quirks mode. - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } - - Sizzle = function( query, context, extra, seed ) { - context = context || document; - - // Only use querySelectorAll on non-XML documents - // (ID selectors don't work in non-HTML documents) - 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] ); - - // 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 and Opera return items - // by name instead of ID - if ( elem.id === match[3] ) { - return makeArray( [ elem ], extra ); - } - - } else { - return makeArray( [], extra ); - } - } - - try { - return makeArray( context.querySelectorAll(query), extra ); - } 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 oldContext = context, - old = context.getAttribute( "id" ), - nid = old || id, - hasParent = context.parentNode, - relativeHierarchySelector = /^\s*[+~]/.test( query ); - - if ( !old ) { - context.setAttribute( "id", nid ); - } else { - nid = nid.replace( /'/g, "\\$&" ); - } - if ( relativeHierarchySelector && hasParent ) { - context = context.parentNode; - } - - try { - if ( !relativeHierarchySelector || hasParent ) { - return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); - } - - } catch(pseudoError) { - } finally { - if ( !old ) { - oldContext.removeAttribute( "id" ); - } - } - } - } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - // release memory in IE - div = null; - })(); -} - -(function(){ - var html = document.documentElement, - matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; - - if ( matches ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9 fails this) - var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), - pseudoWorks = false; - - try { - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( document.documentElement, "[test!='']:sizzle" ); - - } catch( pseudoError ) { - pseudoWorks = true; - } - - Sizzle.matchesSelector = function( node, expr ) { - // Make sure that attribute selectors are quoted - expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); - - if ( !Sizzle.isXML( node ) ) { - try { - if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { - var ret = matches.call( node, 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, so check for that - node.document && node.document.nodeType !== 11 ) { - return ret; - } - } - } catch(e) {} - } - - return Sizzle(expr, null, null, [node]).length > 0; - }; - } -})(); - -(function(){ - var div = document.createElement("div"); - - div.innerHTML = "<div class='test e'></div><div class='test'></div>"; - - // Opera can't find a second classname (in 9.6) - // Also, make sure that getElementsByClassName actually exists - if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { - return; - } - - // Safari caches class attributes, doesn't catch changes (in 3.2) - div.lastChild.className = "e"; - - 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 ) { - return context.getElementsByClassName(match[1]); - } - }; - - // release memory in IE - div = null; -})(); - -function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem[ expando ] === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 && !isXML ){ - elem[ expando ] = doneName; - elem.sizset = i; - } - - if ( elem.nodeName.toLowerCase() === cur ) { - match = elem; - break; - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem[ expando ] === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem[ expando ] = doneName; - elem.sizset = i; - } - - if ( typeof cur !== "string" ) { - if ( elem === cur ) { - match = true; - break; - } - - } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { - match = elem; - break; - } - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -if ( document.documentElement.contains ) { - Sizzle.contains = function( a, b ) { - return a !== b && (a.contains ? a.contains(b) : true); - }; - -} else if ( document.documentElement.compareDocumentPosition ) { - Sizzle.contains = function( a, b ) { - return !!(a.compareDocumentPosition(b) & 16); - }; - -} else { - Sizzle.contains = function() { - return false; - }; -} - -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 : 0).documentElement; - - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -var posProcess = function( selector, context, seed ) { - var match, - tmpSet = [], - later = "", - root = context.nodeType ? [context] : context; - - // Position selectors must be done after the filter - // And so must :not(positional) so we move all PSEUDOs to the end - while ( (match = Expr.match.PSEUDO.exec( selector )) ) { - later += match[0]; - selector = selector.replace( Expr.match.PSEUDO, "" ); - } - - selector = Expr.relative[selector] ? selector + "*" : selector; - - for ( var i = 0, l = root.length; i < l; i++ ) { - Sizzle( selector, root[i], tmpSet, seed ); - } - - return Sizzle.filter( later, tmpSet ); -}; - -// EXPOSE +/*!
+ * 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; -Sizzle.selectors.attrMap = {}; jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.filters; +jQuery.expr[":"] = jQuery.expr.pseudos; jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; - - -})(); - - +
+
+})( window );
var runtil = /Until$/, - rparentsprev = /^(?:parents|prevUntil|prevAll)/, - // Note: This RegExp should be improved, or likely pulled from Sizzle - rmultiselector = /,/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, isSimple = /^.[^:#\[\.,]*$/, - slice = Array.prototype.slice, - POS = jQuery.expr.match.POS, + rneedsContext = jQuery.expr.match.needsContext, // methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, @@ -5318,8 +5352,8 @@ var runtil = /Until$/, jQuery.fn.extend({ find: function( selector ) { - var self = this, - i, l; + var i, l, length, n, r, ret, + self = this; if ( typeof selector !== "string" ) { return jQuery( selector ).filter(function() { @@ -5331,8 +5365,7 @@ jQuery.fn.extend({ }); } - var ret = this.pushStack( "", "find", selector ), - length, n, r; + ret = this.pushStack( "", "find", selector ); for ( i = 0, l = this.length; i < l; i++ ) { length = ret.length; @@ -5355,9 +5388,12 @@ jQuery.fn.extend({ }, has: function( target ) { - var targets = jQuery( target ); + var i, + targets = jQuery( target, this ), + len = targets.length; + return this.filter(function() { - for ( var i = 0, l = targets.length; i < l; i++ ) { + for ( i = 0; i < len; i++ ) { if ( jQuery.contains( this, targets[i] ) ) { return true; } @@ -5374,57 +5410,34 @@ 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 + // If this is a positional/relative 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 ) ? + rneedsContext.test( selector ) ? jQuery( selector, this.context ).index( this[0] ) >= 0 : jQuery.filter( selector, this ).length > 0 : this.filter( selector ).length > 0 ); }, 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; - - while ( cur && cur.ownerDocument && cur !== context ) { - for ( i = 0; i < selectors.length; i++ ) { - - if ( jQuery( cur ).is( selectors[ i ] ) ) { - ret.push({ selector: selectors[ i ], elem: cur, level: level }); - } - } - - cur = cur.parentNode; - level++; - } - - return ret; - } - - // String - var pos = POS.test( selectors ) || typeof selectors !== "string" ? + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? jQuery( selectors, context || this.context ) : 0; - for ( i = 0, l = this.length; i < l; i++ ) { + for ( ; i < l; i++ ) { cur = this[i]; - while ( cur ) { + while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { ret.push( cur ); break; - - } else { - cur = cur.parentNode; - if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { - break; - } } + cur = cur.parentNode; } } @@ -5464,17 +5477,29 @@ jQuery.fn.extend({ jQuery.unique( all ) ); }, - andSelf: function() { - return this.add( this.prevObject ); + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); } }); +jQuery.fn.andSelf = jQuery.fn.addBack; + // A painfully simple check to see if an element is disconnected // from a document (should be improved, where feasible). function isDisconnected( node ) { return !node || !node.parentNode || node.parentNode.nodeType === 11; } +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + jQuery.each({ parent: function( elem ) { var parent = elem.parentNode; @@ -5487,10 +5512,10 @@ jQuery.each({ return jQuery.dir( elem, "parentNode", until ); }, next: function( elem ) { - return jQuery.nth( elem, 2, "nextSibling" ); + return sibling( elem, "nextSibling" ); }, prev: function( elem ) { - return jQuery.nth( elem, 2, "previousSibling" ); + return sibling( elem, "previousSibling" ); }, nextAll: function( elem ) { return jQuery.dir( elem, "nextSibling" ); @@ -5505,7 +5530,7 @@ jQuery.each({ return jQuery.dir( elem, "previousSibling", until ); }, siblings: function( elem ) { - return jQuery.sibling( elem.parentNode.firstChild, elem ); + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { return jQuery.sibling( elem.firstChild ); @@ -5513,7 +5538,7 @@ jQuery.each({ contents: function( elem ) { return jQuery.nodeName( elem, "iframe" ) ? elem.contentDocument || elem.contentWindow.document : - jQuery.makeArray( elem.childNodes ); + jQuery.merge( [], elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { @@ -5529,11 +5554,11 @@ jQuery.each({ ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + if ( this.length > 1 && rparentsprev.test( name ) ) { ret = ret.reverse(); } - return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + return this.pushStack( ret, name, core_slice.call( arguments ).join(",") ); }; }); @@ -5561,19 +5586,6 @@ jQuery.extend({ return matched; }, - nth: function( cur, result, dir, elem ) { - result = result || 1; - var num = 0; - - for ( ; cur; cur = cur[dir] ) { - if ( cur.nodeType === 1 && ++num === result ) { - break; - } - } - - return cur; - }, - sibling: function( n, elem ) { var r = []; @@ -5621,10 +5633,6 @@ function winnow( elements, qualifier, keep ) { return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; }); } - - - - function createSafeFragment( document ) { var list = nodeNames.split( "|" ), safeFrag = document.createDocumentFragment(); @@ -5639,21 +5647,22 @@ function createSafeFragment( document ) { return safeFrag; } -var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|" + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", - rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, rleadingWhitespace = /^\s+/, - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, rtagName = /<([\w:]+)/, rtbody = /<tbody/i, rhtml = /<|&#?\w+;/, - rnoInnerhtml = /<(?:script|style)/i, + rnoInnerhtml = /<(?:script|style|link)/i, rnocache = /<(?:script|object|embed|option|style)/i, - rnoshimcache = new RegExp("<(?:" + nodeNames + ")", "i"), + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rcheckableType = /^(?:checkbox|radio)$/, // checked="checked" or checked rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, rscriptType = /\/(java|ecma)script/i, - rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/, + rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g, wrapMap = { option: [ 1, "<select multiple='multiple'>", "</select>" ], legend: [ 1, "<fieldset>", "</fieldset>" ], @@ -5664,32 +5673,26 @@ var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|fig area: [ 1, "<map>", "</map>" ], _default: [ 0, "", "" ] }, - safeFragment = createSafeFragment( document ); + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; -// IE can't serialize <link> and <script> tags normally +// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, +// unless wrapped in a div with non-breaking characters in front of it. if ( !jQuery.support.htmlSerialize ) { - wrapMap._default = [ 1, "div<div>", "</div>" ]; + wrapMap._default = [ 1, "X<div>", "</div>" ]; } jQuery.fn.extend({ - text: function( text ) { - if ( jQuery.isFunction(text) ) { - return this.each(function(i) { - var self = jQuery( this ); - - self.text( text.call(this, i, self.text()) ); - }); - } - - if ( typeof text !== "object" && text !== undefined ) { - return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); - } - - return jQuery.text( this ); + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); }, wrapAll: function( html ) { @@ -5759,7 +5762,7 @@ jQuery.fn.extend({ append: function() { return this.domManip(arguments, true, function( elem ) { - if ( this.nodeType === 1 ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { this.appendChild( elem ); } }); @@ -5767,39 +5770,44 @@ jQuery.fn.extend({ prepend: function() { return this.domManip(arguments, true, function( elem ) { - if ( this.nodeType === 1 ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { this.insertBefore( elem, this.firstChild ); } }); }, before: function() { - if ( this[0] && this[0].parentNode ) { + if ( !isDisconnected( this[0] ) ) { return this.domManip(arguments, false, function( elem ) { this.parentNode.insertBefore( elem, this ); }); - } else if ( arguments.length ) { + } + + if ( arguments.length ) { var set = jQuery.clean( arguments ); - set.push.apply( set, this.toArray() ); - return this.pushStack( set, "before", arguments ); + return this.pushStack( jQuery.merge( set, this ), "before", this.selector ); } }, after: function() { - if ( this[0] && this[0].parentNode ) { + if ( !isDisconnected( this[0] ) ) { return this.domManip(arguments, false, function( elem ) { this.parentNode.insertBefore( elem, this.nextSibling ); }); - } else if ( arguments.length ) { - var set = this.pushStack( this, "after", arguments ); - set.push.apply( set, jQuery.clean(arguments) ); - return set; + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( this, set ), "after", this.selector ); } }, // keepData is for internal use only--do not document remove: function( selector, keepData ) { - for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { if ( !keepData && elem.nodeType === 1 ) { jQuery.cleanData( elem.getElementsByTagName("*") ); @@ -5816,7 +5824,10 @@ jQuery.fn.extend({ }, empty: function() { - for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { jQuery.cleanData( elem.getElementsByTagName("*") ); @@ -5841,48 +5852,49 @@ jQuery.fn.extend({ }, html: function( value ) { - if ( value === undefined ) { - return this[0] && this[0].nodeType === 1 ? - this[0].innerHTML.replace(rinlinejQuery, "") : - null; - - // See if we can take a shortcut and just use innerHTML - } else if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) && - !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; - value = value.replace(rxhtmlTag, "<$1></$2>"); + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } - try { - for ( var i = 0, l = this.length; i < l; i++ ) { - // Remove element nodes and prevent memory leaks - if ( this[i].nodeType === 1 ) { - jQuery.cleanData( this[i].getElementsByTagName("*") ); - this[i].innerHTML = value; - } - } + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { - // If using innerHTML throws an exception, use the fallback method - } catch(e) { - this.empty().append( value ); - } + value = value.replace( rxhtmlTag, "<$1></$2>" ); - } else if ( jQuery.isFunction( value ) ) { - this.each(function(i){ - var self = jQuery( this ); + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName( "*" ) ); + elem.innerHTML = value; + } + } - self.html( value.call(this, i, self.html()) ); - }); + elem = 0; - } else { - this.empty().append( value ); - } + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } - return this; + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); }, replaceWith: function( value ) { - if ( this[0] && this[0].parentNode ) { + if ( !isDisconnected( this[0] ) ) { // Make sure that the elements are removed from the DOM before they are inserted // this can help fix replacing a parent with child elements if ( jQuery.isFunction( value ) ) { @@ -5908,11 +5920,11 @@ jQuery.fn.extend({ jQuery(parent).append( value ); } }); - } else { - return this.length ? - this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : - this; } + + return this.length ? + this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : + this; }, detach: function( selector ) { @@ -5920,68 +5932,84 @@ jQuery.fn.extend({ }, domManip: function( args, table, callback ) { - var results, first, fragment, parent, + + // Flatten any nested arrays + args = [].concat.apply( [], args ); + + var results, first, fragment, iNoClone, + i = 0, value = args[0], - scripts = []; + scripts = [], + l = this.length; // We can't cloneNode fragments that contain checked, in WebKit - if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) { + if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) { return this.each(function() { - jQuery(this).domManip( args, table, callback, true ); + jQuery(this).domManip( args, table, callback ); }); } if ( jQuery.isFunction(value) ) { return this.each(function(i) { var self = jQuery(this); - args[0] = value.call(this, i, table ? self.html() : undefined); + args[0] = value.call( this, i, table ? self.html() : undefined ); self.domManip( args, table, callback ); }); } if ( this[0] ) { - parent = value && value.parentNode; - - // If we're in a fragment, just use that instead of building a new one - if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) { - results = { fragment: parent }; - - } else { - results = jQuery.buildFragment( args, this, scripts ); - } - + results = jQuery.buildFragment( args, this, scripts ); fragment = results.fragment; + first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { - first = fragment = fragment.firstChild; - } else { - first = fragment.firstChild; + fragment = first; } if ( first ) { table = table && jQuery.nodeName( first, "tr" ); - for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) { + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + // Fragments from the fragment cache must always be cloned and never used in place. + for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) { callback.call( - table ? - root(this[i], first) : + table && jQuery.nodeName( this[i], "table" ) ? + findOrAppend( this[i], "tbody" ) : this[i], - // Make sure that we do not leak memory by inadvertently discarding - // the original fragment (which might have attached data) instead of - // using it; in addition, use the original fragment object for the last - // item instead of first because it can end up being emptied incorrectly - // in certain situations (Bug #8070). - // Fragments from the fragment cache must always be cloned and never used - // in place. - results.cacheable || ( l > 1 && i < lastIndex ) ? - jQuery.clone( fragment, true, true ) : - fragment + i === iNoClone ? + fragment : + jQuery.clone( fragment, true, true ) ); } } + // Fix #11809: Avoid leaking memory + fragment = first = null; + if ( scripts.length ) { - jQuery.each( scripts, evalScript ); + jQuery.each( scripts, function( i, elem ) { + if ( elem.src ) { + if ( jQuery.ajax ) { + jQuery.ajax({ + url: elem.src, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } else { + jQuery.error("no ajax"); + } + } else { + jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + }); } } @@ -5989,11 +6017,8 @@ jQuery.fn.extend({ } }); -function root( elem, cur ) { - return jQuery.nodeName(elem, "table") ? - (elem.getElementsByTagName("tbody")[0] || - elem.appendChild(elem.ownerDocument.createElement("tbody"))) : - elem; +function findOrAppend( elem, tag ) { + return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); } function cloneCopyEvent( src, dest ) { @@ -6013,7 +6038,7 @@ function cloneCopyEvent( src, dest ) { for ( type in events ) { for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data ); + jQuery.event.add( dest, type, events[ type ][ i ] ); } } } @@ -6046,19 +6071,27 @@ function cloneFixAttributes( src, dest ) { nodeName = dest.nodeName.toLowerCase(); - // IE6-8 fail to clone children inside object elements that use - // the proprietary classid attribute value (rather than the type - // attribute) to identify the type of content to display if ( nodeName === "object" ) { - dest.outerHTML = src.outerHTML; + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } - } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) { + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { // IE6-8 fails to persist the checked state of a cloned checkbox // or radio button. Worse, IE6-7 fail to give the cloned element // a checked appearance if the defaultChecked value isn't also set - if ( src.checked ) { - dest.defaultChecked = dest.checked = src.checked; - } + + dest.defaultChecked = dest.checked = src.checked; // IE6-7 get confused and end up setting the value of a cloned // checkbox/radio button to an empty string instead of "on" @@ -6075,6 +6108,10 @@ function cloneFixAttributes( src, dest ) { // cloning other types of input fields } else if ( nodeName === "input" || nodeName === "textarea" ) { dest.defaultValue = src.defaultValue; + + // IE blanks contents when cloning scripts + } else if ( nodeName === "script" && dest.text !== src.text ) { + dest.text = src.text; } // Event data gets referenced instead of copied if the expando @@ -6082,49 +6119,42 @@ function cloneFixAttributes( src, dest ) { dest.removeAttribute( jQuery.expando ); } -jQuery.buildFragment = function( args, nodes, scripts ) { - var fragment, cacheable, cacheresults, doc, - first = args[ 0 ]; - - // nodes may contain either an explicit document object, - // a jQuery collection or context object. - // If nodes[0] contains a valid object to assign to doc - if ( nodes && nodes[0] ) { - doc = nodes[0].ownerDocument || nodes[0]; - } +jQuery.buildFragment = function( args, context, scripts ) { + var fragment, cacheable, cachehit, + first = args[ 0 ]; - // Ensure that an attr object doesn't incorrectly stand in as a document object - // Chrome and Firefox seem to allow this to occur and will throw exception - // Fixes #8950 - if ( !doc.createDocumentFragment ) { - doc = document; - } + // Set context from what may come in as undefined or a jQuery collection or a node + // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 & + // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception + context = context || document; + context = !context.nodeType && context[0] || context; + context = context.ownerDocument || context; // Only cache "small" (1/2 KB) HTML strings that are associated with the main document // Cloning options loses the selected state, so don't cache them // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 - if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document && + if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document && first.charAt(0) === "<" && !rnocache.test( first ) && (jQuery.support.checkClone || !rchecked.test( first )) && (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { + // Mark cacheable and look for a hit cacheable = true; - - cacheresults = jQuery.fragments[ first ]; - if ( cacheresults && cacheresults !== 1 ) { - fragment = cacheresults; - } + fragment = jQuery.fragments[ first ]; + cachehit = fragment !== undefined; } if ( !fragment ) { - fragment = doc.createDocumentFragment(); - jQuery.clean( args, doc, fragment, scripts ); - } + fragment = context.createDocumentFragment(); + jQuery.clean( args, context, fragment, scripts ); - if ( cacheable ) { - jQuery.fragments[ first ] = cacheresults ? fragment : 1; + // Update the cache, but only store false + // unless this is a second parsing of the same content + if ( cacheable ) { + jQuery.fragments[ first ] = cachehit && fragment; + } } return { fragment: fragment, cacheable: cacheable }; @@ -6140,17 +6170,19 @@ jQuery.each({ replaceAll: "replaceWith" }, function( name, original ) { jQuery.fn[ name ] = function( selector ) { - var ret = [], + var elems, + i = 0, + ret = [], insert = jQuery( selector ), + l = insert.length, parent = this.length === 1 && this[0].parentNode; - if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { + if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) { insert[ original ]( this[0] ); return this; - } else { - for ( var i = 0, l = insert.length; i < l; i++ ) { - var elems = ( i > 0 ? this.clone(true) : this ).get(); + for ( ; i < l; i++ ) { + elems = ( i > 0 ? this.clone(true) : this ).get(); jQuery( insert[i] )[ original ]( elems ); ret = ret.concat( elems ); } @@ -6174,39 +6206,26 @@ function getAll( elem ) { // Used in clean, fixes the defaultChecked property function fixDefaultChecked( elem ) { - if ( elem.type === "checkbox" || elem.type === "radio" ) { + if ( rcheckableType.test( elem.type ) ) { elem.defaultChecked = elem.checked; } } -// Finds all inputs and passes them to fixDefaultChecked -function findInputs( elem ) { - var nodeName = ( elem.nodeName || "" ).toLowerCase(); - if ( nodeName === "input" ) { - fixDefaultChecked( elem ); - // Skip scripts, get other children - } else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) { - jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); - } -} - -// Derived From: http://www.iecss.com/shimprove/javascript/shimprove.1-0-1.js -function shimCloneNode( elem ) { - var div = document.createElement( "div" ); - safeFragment.appendChild( div ); - - div.innerHTML = elem.outerHTML; - return div.firstChild; -} jQuery.extend({ clone: function( elem, dataAndEvents, deepDataAndEvents ) { var srcElements, destElements, i, - // IE<=8 does not properly clone detached, unknown element nodes - clone = jQuery.support.html5Clone || !rnoshimcache.test( "<" + elem.nodeName ) ? - elem.cloneNode( true ) : - shimCloneNode( elem ); + clone; + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { @@ -6254,18 +6273,17 @@ jQuery.extend({ }, clean: function( elems, context, fragment, scripts ) { - var checkScriptType; - - context = context || document; + var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, + safe = context === document && safeFragment, + ret = []; - // !context.createElement fails in IE with an error but returns typeof 'object' - if ( typeof context.createElement === "undefined" ) { - context = context.ownerDocument || context[0] && context[0].ownerDocument || document; + // Ensure that context is a document + if ( !context || typeof context.createDocumentFragment === "undefined" ) { + context = document; } - var ret = [], j; - - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + // Use the already-created safe fragment if context permits + for ( i = 0; (elem = elems[i]) != null; i++ ) { if ( typeof elem === "number" ) { elem += ""; } @@ -6279,25 +6297,18 @@ jQuery.extend({ if ( !rhtml.test( elem ) ) { elem = context.createTextNode( elem ); } else { + // Ensure a safe container in which to render the html + safe = safe || createSafeFragment( context ); + div = context.createElement("div"); + safe.appendChild( div ); + // Fix "XHTML"-style tags in all browsers elem = elem.replace(rxhtmlTag, "<$1></$2>"); - // Trim whitespace, otherwise indexOf won't work as expected - var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(), - wrap = wrapMap[ tag ] || wrapMap._default, - depth = wrap[0], - div = context.createElement("div"); - - // Append wrapper element to unknown element safe doc fragment - if ( context === document ) { - // Use the fragment we've already created for this document - safeFragment.appendChild( div ); - } else { - // Use a fragment created with the owner document - createSafeFragment( context ).appendChild( div ); - } - // Go to html and back, then peel off extra wrappers + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + depth = wrap[0]; div.innerHTML = wrap[1] + elem + wrap[2]; // Move to the right depth @@ -6309,7 +6320,7 @@ jQuery.extend({ if ( !jQuery.support.tbody ) { // String was a <table>, *may* have spurious <tbody> - var hasBody = rtbody.test(elem), + hasBody = rtbody.test(elem); tbody = tag === "table" && !hasBody ? div.firstChild && div.firstChild.childNodes : @@ -6331,44 +6342,63 @@ jQuery.extend({ } elem = div.childNodes; - } - } - // Resets defaultChecked for any radios and checkboxes - // about to be appended to the DOM in IE 6/7 (#8060) - var len; - if ( !jQuery.support.appendChecked ) { - if ( elem[0] && typeof (len = elem.length) === "number" ) { - for ( j = 0; j < len; j++ ) { - findInputs( elem[j] ); - } - } else { - findInputs( elem ); + // Take out of fragment container (we need a fresh div each time) + div.parentNode.removeChild( div ); } } if ( elem.nodeType ) { ret.push( elem ); } else { - ret = jQuery.merge( ret, elem ); + jQuery.merge( ret, elem ); + } + } + + // Fix #11356: Clear elements from safeFragment + if ( div ) { + elem = div = safe = null; + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + for ( i = 0; (elem = ret[i]) != null; i++ ) { + if ( jQuery.nodeName( elem, "input" ) ) { + fixDefaultChecked( elem ); + } else if ( typeof elem.getElementsByTagName !== "undefined" ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } } } + // Append elements to a provided document fragment if ( fragment ) { - checkScriptType = function( elem ) { - return !elem.type || rscriptType.test( elem.type ); + // Special handling of each script element + handleScript = function( elem ) { + // Check if we consider it executable + if ( !elem.type || rscriptType.test( elem.type ) ) { + // Detach the script and store it in the scripts array (if provided) or the fragment + // Return truthy to indicate that it has been handled + return scripts ? + scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : + fragment.appendChild( elem ); + } }; - for ( i = 0; ret[i]; i++ ) { - if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { - scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); - } else { - if ( ret[i].nodeType === 1 ) { - var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType ); + for ( i = 0; (elem = ret[i]) != null; i++ ) { + // Check if we're done after handling an executable script + if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { + // Append to fragment and handle embedded scripts + fragment.appendChild( elem ); + if ( typeof elem.getElementsByTagName !== "undefined" ) { + // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration + jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); + // Splice the scripts into ret after their former ancestor and advance our index beyond them ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + i += jsTags.length; } - fragment.appendChild( ret[i] ); } } } @@ -6376,99 +6406,253 @@ jQuery.extend({ return ret; }, - cleanData: function( elems ) { - var data, id, + cleanData: function( elems, /* internal */ acceptData ) { + var data, id, elem, type, + i = 0, + internalKey = jQuery.expando, cache = jQuery.cache, - special = jQuery.event.special, - deleteExpando = jQuery.support.deleteExpando; + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { - if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { - continue; - } + for ( ; (elem = elems[i]) != null; i++ ) { - id = elem[ jQuery.expando ]; + if ( acceptData || jQuery.acceptData( elem ) ) { - if ( id ) { - data = cache[ id ]; + id = elem[ internalKey ]; + data = id && cache[ id ]; - if ( data && data.events ) { - for ( var type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } } } - // Null the DOM reference to avoid IE6/7/8 leak (#7054) - if ( data.handle ) { - data.handle.elem = null; - } - } + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { - if ( deleteExpando ) { - delete elem[ jQuery.expando ]; + delete cache[ id ]; - } else if ( elem.removeAttribute ) { - elem.removeAttribute( jQuery.expando ); - } + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); - delete cache[ id ]; + } else { + elem[ internalKey ] = null; + } + + jQuery.deletedIds.push( id ); + } + } } } } }); +// Limit scope pollution from any deprecated API +(function() { + +var matched, browser; + +// Use of jQuery.browser is frowned upon. +// More details: http://api.jquery.com/jQuery.browser +// jQuery.uaMatch maintained for back-compat +jQuery.uaMatch = function( ua ) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; +}; -function evalScript( i, elem ) { - if ( elem.src ) { - jQuery.ajax({ - url: elem.src, - async: false, - dataType: "script" - }); - } else { - jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) ); - } +matched = jQuery.uaMatch( navigator.userAgent ); +browser = {}; - if ( elem.parentNode ) { - elem.parentNode.removeChild( elem ); - } +if ( matched.browser ) { + browser[ matched.browser ] = true; + browser.version = matched.version; } +// Chrome is Webkit, but Webkit is also Safari. +if ( browser.chrome ) { + browser.webkit = true; +} else if ( browser.webkit ) { + browser.safari = true; +} +jQuery.browser = browser; +jQuery.sub = function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; +}; -var ralpha = /alpha\([^)]*\)/i, +})(); +var curCSS, iframe, iframeDoc, + ralpha = /alpha\([^)]*\)/i, ropacity = /opacity=([^)]*)/, - // fixed for IE9, see #8346 - rupper = /([A-Z]|^ms)/g, - rnumpx = /^-?\d+(?:px)?$/i, - rnum = /^-?\d/, - rrelNum = /^([\-+])=([\-+.\de]+)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ), + elemdisplay = {}, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, - cssWidth = [ "Left", "Right" ], - cssHeight = [ "Top", "Bottom" ], - curCSS, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, - getComputedStyle, - currentStyle; + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], -jQuery.fn.css = function( name, value ) { - // Setting 'undefined' is a no-op - if ( arguments.length === 2 && value === undefined ) { - return this; + eventsToggle = jQuery.fn.toggle; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; } - return jQuery.access( this, name, value, true, function( elem, name, value ) { - return value !== undefined ? - jQuery.style( elem, name, value ) : - jQuery.css( elem, name ); - }); -}; + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var elem, display, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + values[ index ] = jQuery._data( elem, "olddisplay" ); + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && elem.style.display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + display = curCSS( elem, "display" ); + + if ( !values[ index ] && display !== "none" ) { + jQuery._data( elem, "olddisplay", display ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state, fn2 ) { + var bool = typeof state === "boolean"; + + if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) { + return eventsToggle.apply( this, arguments ); + } + + return this.each(function() { + if ( bool ? state : isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); jQuery.extend({ // Add in style property hooks for overriding the default @@ -6478,11 +6662,9 @@ jQuery.extend({ get: function( elem, computed ) { if ( computed ) { // We should always get a number back from opacity - var ret = curCSS( elem, "opacity", "opacity" ); + var ret = curCSS( elem, "opacity" ); return ret === "" ? "1" : ret; - } else { - return elem.style.opacity; } } } @@ -6515,10 +6697,15 @@ jQuery.extend({ } // Make sure that we're working with the right name - var ret, type, origName = jQuery.camelCase( name ), - style = elem.style, hooks = jQuery.cssHooks[ origName ]; + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; - name = jQuery.cssProps[ origName ] || origName; + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // Check if we're setting a value if ( value !== undefined ) { @@ -6526,7 +6713,7 @@ jQuery.extend({ // convert relative number strings (+= or -=) to relative numbers. #7345 if ( type === "string" && (ret = rrelNum.exec( value )) ) { - value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) ); + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); // Fixes bug #9237 type = "number"; } @@ -6542,7 +6729,7 @@ jQuery.extend({ } // If a hook was provided, use that value, otherwise just set the specified value - if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) { + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { // Wrapped to prevent IE from throwing errors when 'invalid' values are provided // Fixes bug #5509 try { @@ -6561,81 +6748,299 @@ jQuery.extend({ } }, - css: function( elem, name, extra ) { - var ret, hooks; + css: function( elem, name, numeric, extra ) { + var val, num, hooks, + origName = jQuery.camelCase( name ); // Make sure that we're working with the right name - name = jQuery.camelCase( name ); - hooks = jQuery.cssHooks[ name ]; - name = jQuery.cssProps[ name ] || name; + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); - // cssFloat needs a special treatment - if ( name === "cssFloat" ) { - name = "float"; - } + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // If a hook was provided get the computed value from there - if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { - return ret; + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } // Otherwise, if a way to get the computed value exists, use that - } else if ( curCSS ) { - return curCSS( elem, name ); + if ( val === undefined ) { + val = curCSS( elem, name ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( numeric || extra !== undefined ) { + num = parseFloat( val ); + return numeric || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; }, // A method for quickly swapping in/out CSS properties to get correct calculations swap: function( elem, options, callback ) { - var old = {}; + var ret, name, + old = {}; // Remember the old values, and insert the new ones - for ( var name in options ) { + for ( name in options ) { old[ name ] = elem.style[ name ]; elem.style[ name ] = options[ name ]; } - callback.call( elem ); + ret = callback.call( elem ); // Revert the old values for ( name in options ) { elem.style[ name ] = old[ name ]; } + + return ret; } }); -// DEPRECATED, Use jQuery.css() instead -jQuery.curCSS = jQuery.css; +// NOTE: To any future maintainer, we've window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + curCSS = function( elem, name ) { + var ret, width, minWidth, maxWidth, + computed = window.getComputedStyle( elem, null ), + style = elem.style; + + if ( computed ) { + + ret = computed[ name ]; + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + curCSS = function( elem, name ) { + var left, rsLeft, + ret = elem.currentStyle && elem.currentStyle[ name ], + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + elem.runtimeStyle.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + elem.runtimeStyle.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + // we use jQuery.css instead of curCSS here + // because of the reliableMarginRight CSS hook! + val += jQuery.css( elem, extra + cssExpand[ i ], true ); + } + + // From this point on we use curCSS for maximum performance (relevant in animations) + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } else { + // at this point, extra isn't content, so add padding + val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + valueIsBorderBox = true, + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); -jQuery.each(["height", "width"], function( i, name ) { + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox + ) + ) + "px"; +} + + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + if ( elemdisplay[ nodeName ] ) { + return elemdisplay[ nodeName ]; + } + + var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ), + display = elem.css("display"); + elem.remove(); + + // If the simple way fails, + // get element's real default display by attaching it to a temp iframe + if ( display === "none" || display === "" ) { + // Use the already-created iframe if possible + iframe = document.body.appendChild( + iframe || jQuery.extend( document.createElement("iframe"), { + frameBorder: 0, + width: 0, + height: 0 + }) + ); + + // Create a cacheable copy of the iframe document on first call. + // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML + // document to it; WebKit & Firefox won't allow reusing the iframe document. + if ( !iframeDoc || !iframe.createElement ) { + iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; + iframeDoc.write("<!doctype html><html><body>"); + iframeDoc.close(); + } + + elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) ); + + display = curCSS( elem, "display" ); + document.body.removeChild( iframe ); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + + return display; +} + +jQuery.each([ "height", "width" ], function( i, name ) { jQuery.cssHooks[ name ] = { get: function( elem, computed, extra ) { - var val; - if ( computed ) { - if ( elem.offsetWidth !== 0 ) { - return getWH( elem, name, extra ); - } else { - jQuery.swap( elem, cssShow, function() { - val = getWH( elem, name, extra ); + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) { + return jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); }); + } else { + return getWidthOrHeight( elem, name, extra ); } - - return val; } }, - set: function( elem, value ) { - if ( rnumpx.test( value ) ) { - // ignore negative width and height values #1599 - value = parseFloat( value ); - - if ( value >= 0 ) { - return value + "px"; - } - - } else { - return value; - } + set: function( elem, value, extra ) { + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" + ) : 0 + ); } }; }); @@ -6645,7 +7050,7 @@ if ( !jQuery.support.opacity ) { get: function( elem, computed ) { // IE uses filters for opacity return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? - ( parseFloat( RegExp.$1 ) / 100 ) + "" : + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : computed ? "1" : ""; }, @@ -6660,7 +7065,8 @@ if ( !jQuery.support.opacity ) { style.zoom = 1; // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 - if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) { + if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" && + style.removeAttribute ) { // Setting style.filter to null, "" & " " still leave "filter:" in the cssText // if "filter:" is present at all, clearType is disabled, we want to avoid this @@ -6681,170 +7087,195 @@ if ( !jQuery.support.opacity ) { }; } +// These hooks cannot be added until DOM ready because the support test +// for it is not run until after DOM ready jQuery(function() { - // This hook cannot be added until DOM ready because the support test - // for it is not run until after DOM ready if ( !jQuery.support.reliableMarginRight ) { jQuery.cssHooks.marginRight = { get: function( elem, computed ) { // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right // Work around by temporarily setting element display to inline-block - var ret; - jQuery.swap( elem, { "display": "inline-block" }, function() { + return jQuery.swap( elem, { "display": "inline-block" }, function() { if ( computed ) { - ret = curCSS( elem, "margin-right", "marginRight" ); - } else { - ret = elem.style.marginRight; + return curCSS( elem, "marginRight" ); } }); - return ret; } }; } -}); -if ( document.defaultView && document.defaultView.getComputedStyle ) { - getComputedStyle = function( elem, name ) { - var ret, defaultView, computedStyle; + // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 + // getComputedStyle returns percent when specified for top/left/bottom/right + // rather than make the css module depend on the offset module, we just check for it here + if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { + jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = { + get: function( elem, computed ) { + if ( computed ) { + var ret = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret; + } + } + }; + }); + } - name = name.replace( rupper, "-$1" ).toLowerCase(); +}); - if ( (defaultView = elem.ownerDocument.defaultView) && - (computedStyle = defaultView.getComputedStyle( elem, null )) ) { - ret = computedStyle.getPropertyValue( name ); - if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { - ret = jQuery.style( elem, name ); - } - } +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.hidden = function( elem ) { + return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none"); + }; - return ret; + jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); }; } -if ( document.documentElement.currentStyle ) { - currentStyle = function( elem, name ) { - var left, rsLeft, uncomputed, - ret = elem.currentStyle && elem.currentStyle[ name ], - style = elem.style; - - // Avoid setting ret to empty string here - // so we don't default to auto - if ( ret === null && style && (uncomputed = style[ name ]) ) { - ret = uncomputed; - } - - // From the awesome hack by Dean Edwards - // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 - - // If we're not dealing with a regular pixel number - // but a number that has a weird ending, we need to convert it to pixels - if ( !rnumpx.test( ret ) && rnum.test( ret ) ) { +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i, - // Remember the original values - left = style.left; - rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; + // assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ], + expanded = {}; - // Put in the new values to get a computed value out - if ( rsLeft ) { - elem.runtimeStyle.left = elem.currentStyle.left; + for ( i = 0; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; } - style.left = name === "fontSize" ? "1em" : ( ret || 0 ); - ret = style.pixelLeft + "px"; - // Revert the changed values - style.left = left; - if ( rsLeft ) { - elem.runtimeStyle.left = rsLeft; - } + return expanded; } - - return ret === "" ? "auto" : ret; }; -} -curCSS = getComputedStyle || currentStyle; + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + rselectTextarea = /^(?:select|textarea)/i; -function getWH( elem, name, extra ) { +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function(){ + return this.elements ? jQuery.makeArray( this.elements ) : this; + }) + .filter(function(){ + return this.name && !this.disabled && + ( this.checked || rselectTextarea.test( this.nodeName ) || + rinput.test( this.type ) ); + }) + .map(function( i, elem ){ + var val = jQuery( this ).val(); - // Start with offset property - var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, - which = name === "width" ? cssWidth : cssHeight, - i = 0, - len = which.length; + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val, i ){ + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); - if ( val > 0 ) { - if ( extra !== "border" ) { - for ( ; i < len; i++ ) { - if ( !extra ) { - val -= parseFloat( jQuery.css( elem, "padding" + which[ i ] ) ) || 0; - } - if ( extra === "margin" ) { - val += parseFloat( jQuery.css( elem, extra + which[ i ] ) ) || 0; - } else { - val -= parseFloat( jQuery.css( elem, "border" + which[ i ] + "Width" ) ) || 0; - } - } - } +//Serialize an array of form elements or a set of +//key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; - return val + "px"; + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; } - // Fall back to computed then uncomputed css if necessary - val = curCSS( elem, name, name ); - if ( val < 0 || val == null ) { - val = elem.style[ name ] || 0; - } - // Normalize "", auto, and prepare for extra - val = parseFloat( val ) || 0; + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); - // Add padding, border, margin - if ( extra ) { - for ( ; i < len; i++ ) { - val += parseFloat( jQuery.css( elem, "padding" + which[ i ] ) ) || 0; - if ( extra !== "padding" ) { - val += parseFloat( jQuery.css( elem, "border" + which[ i ] + "Width" ) ) || 0; - } - if ( extra === "margin" ) { - val += parseFloat( jQuery.css( elem, extra + which[ i ] ) ) || 0; - } + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); } } - return val + "px"; -} - -if ( jQuery.expr && jQuery.expr.filters ) { - jQuery.expr.filters.hidden = function( elem ) { - var width = elem.offsetWidth, - height = elem.offsetHeight; + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; - return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none"); - }; +function buildParams( prefix, obj, traditional, add ) { + var name; - jQuery.expr.filters.visible = function( elem ) { - return !jQuery.expr.filters.hidden( elem ); - }; -} + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + } else { + // If array item is non-scalar (array or object), encode its + // numeric index to resolve deserialization ambiguity issues. + // Note that rack (as of 1.0.0) can't currently deserialize + // nested arrays properly, and attempting to do so may cause + // a server error. Possible fixes are to modify rack's + // deserialization algorithm or to provide an option or flag + // to force array serialization to be shallow. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} +var + // Document location + ajaxLocParts, + ajaxLocation, -var r20 = /%20/g, - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, rhash = /#.*$/, rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL - rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, // #7653, #8125, #8152: local protocol detection rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, rquery = /\?/, rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, - rselectTextarea = /^(?:select|textarea)/i, - rspacesAjax = /\s+/, rts = /([?&])_=[^&]*/, - rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/, + rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, // Keep a copy of the old load method _load = jQuery.fn.load, @@ -6867,12 +7298,6 @@ var r20 = /%20/g, */ transports = {}, - // Document location - ajaxLocation, - - // Document location segments - ajaxLocParts, - // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression allTypes = ["*/"] + ["*"]; @@ -6902,14 +7327,12 @@ function addToPrefiltersOrTransports( structure ) { dataTypeExpression = "*"; } - if ( jQuery.isFunction( func ) ) { - var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ), - i = 0, - length = dataTypes.length, - dataType, - list, - placeBefore; + var dataType, list, placeBefore, + dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ), + i = 0, + length = dataTypes.length; + if ( jQuery.isFunction( func ) ) { // For each dataType in the dataTypeExpression for ( ; i < length; i++ ) { dataType = dataTypes[ i ]; @@ -6936,11 +7359,11 @@ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqX inspected[ dataType ] = true; - var list = structure[ dataType ], + var selection, + list = structure[ dataType ], i = 0, length = list ? list.length : 0, - executeOnly = ( structure === prefilters ), - selection; + executeOnly = ( structure === prefilters ); for ( ; i < length && ( executeOnly || !selection ); i++ ) { selection = list[ i ]( options, originalOptions, jqXHR ); @@ -6983,109 +7406,75 @@ function ajaxExtend( target, src ) { } } -jQuery.fn.extend({ - load: function( url, params, callback ) { - if ( typeof url !== "string" && _load ) { - return _load.apply( this, arguments ); +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } - // Don't do a request if no elements are being requested - } else if ( !this.length ) { - return this; - } + // Don't do a request if no elements are being requested + if ( !this.length ) { + return this; + } - var off = url.indexOf( " " ); - if ( off >= 0 ) { - var selector = url.slice( off, url.length ); - url = url.slice( 0, off ); - } + var selector, type, response, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = url.slice( off, url.length ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; - // Default to a GET request - var type = "GET"; + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { |