Merge remote-tracking branch 'origin/master' into translation-staging

This commit is contained in:
Ingo Schommer 2012-08-20 13:04:57 +02:00
commit 7cfae71b08
46 changed files with 4235 additions and 4089 deletions

16
.travis.yml Normal file
View File

@ -0,0 +1,16 @@
language: php
php:
- 5.3
before_script:
- ./tests/travis/before_script ~/builds/ss
- cd ~/builds/ss
script:
- phpunit -c phpunit.xml.dist
branches:
except:
- translation-staging
- 2.4

View File

@ -296,9 +296,9 @@ class LeftAndMain extends Controller implements PermissionProvider {
); );
// TODO Confuses jQuery.ondemand through document.write() // TODO Confuses jQuery.ondemand through document.write()
// if (Director::isDev()) { if (Director::isDev()) {
// Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/src/jquery.entwine.inspector.js'); Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/src/jquery.entwine.inspector.js');
// } }
Requirements::css(FRAMEWORK_ADMIN_DIR . '/thirdparty/jquery-notice/jquery.notice.css'); Requirements::css(FRAMEWORK_ADMIN_DIR . '/thirdparty/jquery-notice/jquery.notice.css');
Requirements::css(THIRDPARTY_DIR . '/jquery-ui-themes/smoothness/jquery-ui.css'); Requirements::css(THIRDPARTY_DIR . '/jquery-ui-themes/smoothness/jquery-ui.css');

View File

@ -20,18 +20,38 @@ jQuery.noConflict();
// apply an select element only when it is ready, ie. when it is rendered into a template // apply an select element only when it is ready, ie. when it is rendered into a template
// with css applied and got a width value. // with css applied and got a width value.
var applyChosen = function(el){ var applyChosen = function(el) {
if(el.outerWidth()){ if(el.is(':visible')) {
el.chosen({ el.addClass('has-chzn').chosen({
'disable_search_threshold' : 20, allow_single_deselect: true,
'allow_single_deselect': true disable_search_threshold: 20
}).addClass("has-chzn"); });
// Copy over title attribute if required
if(el.attr('title')) el.siblings('.chzn-container').attr('title', el.attr('title')); var title = el.prop('title')
if(title) {
el.siblings('.chzn-container').prop('title', title);
}
} else { } else {
setTimeout(function() {applyChosen(el);},500); setTimeout(function() { applyChosen(el); }, 500);
} }
}; };
/**
* Compare URLs, but normalize trailing slashes in
* URL to work around routing weirdnesses in SS_HTTPRequest.
* Also normalizes relative URLs by prefixing them with the <base>.
*/
var isSameUrl = function(url1, url2) {
var baseUrl = $('base').attr('href');
url1 = $.path.isAbsoluteUrl(url1) ? url1 : $.path.makeUrlAbsolute(url1, baseUrl),
url2 = $.path.isAbsoluteUrl(url2) ? url2 : $.path.makeUrlAbsolute(url2, baseUrl);
var url1parts = $.path.parseUrl(url1), url2parts = $.path.parseUrl(url2);
return (
url1parts.pathname.replace(/\/*$/, '') == url2parts.pathname.replace(/\/*$/, '') &&
url1parts.search == url2parts.search
);
};
$(window).bind('resize', positionLoadingSpinner).trigger('resize'); $(window).bind('resize', positionLoadingSpinner).trigger('resize');
@ -39,10 +59,12 @@ jQuery.noConflict();
$(document).ajaxComplete(function(e, xhr, settings) { $(document).ajaxComplete(function(e, xhr, settings) {
// Simulates a redirect on an ajax response. // Simulates a redirect on an ajax response.
if(window.History.enabled) { if(window.History.enabled) {
var url = xhr.getResponseHeader('X-ControllerURL'), opts, requestHeaders = settings.headers; var url = xhr.getResponseHeader('X-ControllerURL'),
// Normalize trailing slashes in URL to work around routing weirdnesses in SS_HTTPRequest. // TODO Replaces trailing slashes added by History after locale (e.g. admin/?locale=en/)
var isSame = (url && History.getPageUrl().replace(/\/+$/, '') == url.replace(/\/+$/, '')); origUrl = History.getPageUrl().replace(/\/$/, ''),
if(url && !isSame) { opts, requestHeaders = settings.headers;
if(url !== null && !isSameUrl(origUrl, url)) {
opts = {pjax: xhr.getResponseHeader('X-Pjax') ? xhr.getResponseHeader('X-Pjax') : settings.headers['X-Pjax']}; opts = {pjax: xhr.getResponseHeader('X-Pjax') ? xhr.getResponseHeader('X-Pjax') : settings.headers['X-Pjax']};
window.History.pushState(opts, '', url); window.History.pushState(opts, '', url);
} }
@ -144,8 +166,9 @@ jQuery.noConflict();
* - {String} url * - {String} url
* - {String} title New window title * - {String} title New window title
* - {Object} data Any additional data passed through to History.pushState() * - {Object} data Any additional data passed through to History.pushState()
* - {boolean} forceReload Forces the replacement of the current history state, even if the URL is the same, i.e. allows reloading.
*/ */
loadPanel: function(url, title, data) { loadPanel: function(url, title, data, forceReload) {
if(!data) data = {}; if(!data) data = {};
if(!title) title = ""; if(!title) title = "";
@ -169,12 +192,25 @@ jQuery.noConflict();
if(window.History.enabled) { if(window.History.enabled) {
// Active menu item is set based on X-Controller ajax header, // Active menu item is set based on X-Controller ajax header,
// which matches one class on the menu // which matches one class on the menu
window.History.pushState(data, title, url); if(forceReload) {
// Add a parameter to make sure the page gets reloaded even if the URL is the same.
$.extend(data, {__forceReload: Math.random()});
window.History.replaceState(data, title, url);
} else {
window.History.pushState(data, title, url);
}
} else { } else {
window.location = $.path.makeUrlAbsolute(url, $('base').attr('href')); window.location = $.path.makeUrlAbsolute(url, $('base').attr('href'));
} }
}, },
/**
* Nice wrapper for reloading current history state.
*/
reloadCurrentPanel: function() {
this.loadPanel(window.History.getState().url, null, null, true);
},
/** /**
* Function: submitForm * Function: submitForm
* *
@ -887,11 +923,9 @@ jQuery.noConflict();
ajaxOptions: { ajaxOptions: {
// Overwrite ajax loading to use CMS logic instead // Overwrite ajax loading to use CMS logic instead
beforeSend: function(xhr, settings) { beforeSend: function(xhr, settings) {
var makeAbs = $.path.makeUrlAbsolute, if(!isSameUrl(document.location.href, settings.url)) {
baseUrl = $('base').attr('href'), $('.cms-container').loadPanel(settings.url);
isSame = (makeAbs(settings.url, baseUrl) == makeAbs(document.location.href)); }
if(!isSame) $('.cms-container').loadPanel(settings.url);
return false; return false;
} }
}, },

View File

@ -14,8 +14,6 @@
SelectParser = (function() { SelectParser = (function() {
SelectParser.name = 'SelectParser';
function SelectParser() { function SelectParser() {
this.options_index = 0; this.options_index = 0;
this.parsed = []; this.parsed = [];
@ -109,8 +107,6 @@ Copyright (c) 2011 by Harvest
AbstractChosen = (function() { AbstractChosen = (function() {
AbstractChosen.name = 'AbstractChosen';
function AbstractChosen(form_field, options) { function AbstractChosen(form_field, options) {
this.form_field = form_field; this.form_field = form_field;
this.options = options != null ? options : {}; this.options = options != null ? options : {};
@ -280,7 +276,7 @@ Copyright (c) 2011 by Harvest
(function() { (function() {
var $, Chosen, get_side_border_padding, root, var $, Chosen, get_side_border_padding, root,
__hasProp = {}.hasOwnProperty, __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
root = this; root = this;
@ -305,8 +301,6 @@ Copyright (c) 2011 by Harvest
__extends(Chosen, _super); __extends(Chosen, _super);
Chosen.name = 'Chosen';
function Chosen() { function Chosen() {
return Chosen.__super__.constructor.apply(this, arguments); return Chosen.__super__.constructor.apply(this, arguments);
} }
@ -325,7 +319,6 @@ Copyright (c) 2011 by Harvest
this.container_id = this.form_field.id.length ? this.form_field.id.replace(/(:|\.)/g, '_') : this.generate_field_id(); this.container_id = this.form_field.id.length ? this.form_field.id.replace(/(:|\.)/g, '_') : this.generate_field_id();
this.container_id += "_chzn"; this.container_id += "_chzn";
this.f_width = this.form_field_jq.outerWidth(); this.f_width = this.form_field_jq.outerWidth();
if (this.f_width==0) this.f_width = this.form_field_jq.css("width");
this.default_text = this.form_field_jq.data('placeholder') ? this.form_field_jq.data('placeholder') : this.default_text_default; this.default_text = this.form_field_jq.data('placeholder') ? this.form_field_jq.data('placeholder') : this.default_text_default;
container_div = $("<div />", { container_div = $("<div />", {
id: this.container_id, id: this.container_id,
@ -348,7 +341,7 @@ Copyright (c) 2011 by Harvest
rise = this.rise_up(this.container, this.dropdown); rise = this.rise_up(this.container, this.dropdown);
dd_top = rise ? -this.container.find('.chzn-drop').height() : this.container.height(); dd_top = rise ? -this.container.find('.chzn-drop').height() : this.container.height();
dd_width = this.container.width - get_side_border_padding(this.dropdown); dd_width = this.container.width() - get_side_border_padding(this.dropdown);
this.dropdown.css({ this.dropdown.css({
"width": dd_width + "px", "width": dd_width + "px",
"top": dd_top + "px" "top": dd_top + "px"

View File

@ -9,4 +9,4 @@
// based on version 0.9.8, applied a very simple patch that fix percentaage width support on select tag // based on version 0.9.8, applied a very simple patch that fix percentaage width support on select tag
// This file is generated by `cake build`, do not edit it by hand. // This file is generated by `cake build`, do not edit it by hand.
(function(){var a;a=function(){function a(){this.options_index=0,this.parsed=[]}return a.name="SelectParser",a.prototype.add_node=function(a){return a.nodeName==="OPTGROUP"?this.add_group(a):this.add_option(a)},a.prototype.add_group=function(a){var b,c,d,e,f,g;b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:a.label,children:0,disabled:a.disabled}),f=a.childNodes,g=[];for(d=0,e=f.length;d<e;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},a.prototype.add_option=function(a,b,c){if(a.nodeName==="OPTION")return a.text!==""?(b!=null&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1},a}(),a.select_to_array=function(b){var c,d,e,f,g;d=new a,g=b.childNodes;for(e=0,f=g.length;e<f;e++)c=g[e],d.add_node(c);return d.parsed},this.SelectParser=a}).call(this),function(){var a,b;b=this,a=function(){function a(a,b){this.form_field=a,this.options=b!=null?b:{},this.set_default_values(),this.is_multiple=this.form_field.multiple,this.default_text_default=this.is_multiple?"Select Some Options":"Select an Option",this.setup(),this.set_up_html(),this.register_observers(),this.finish_setup()}return a.name="AbstractChosen",a.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.result_single_selected=null,this.allow_single_deselect=this.options.allow_single_deselect!=null&&this.form_field.options[0]!=null&&this.form_field.options[0].text===""?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.search_contains=this.options.search_contains||!1,this.choices=0,this.results_none_found=this.options.no_results_text||"No results match"},a.prototype.mouse_enter=function(){return this.mouse_on_container=!0},a.prototype.mouse_leave=function(){return this.mouse_on_container=!1},a.prototype.input_focus=function(a){var b=this;if(!this.active_field)return setTimeout(function(){return b.container_mousedown()},50)},a.prototype.input_blur=function(a){var b=this;if(!this.mouse_on_container)return this.active_field=!1,setTimeout(function(){return b.blur_test()},100)},a.prototype.result_add_option=function(a){var b,c;return a.disabled?"":(a.dom_id=this.container_id+"_o_"+a.array_index,b=a.selected&&this.is_multiple?[]:["active-result"],a.selected&&b.push("result-selected"),a.group_array_index!=null&&b.push("group-option"),a.classes!==""&&b.push(a.classes),c=a.style.cssText!==""?' style="'+a.style+'"':"",'<li id="'+a.dom_id+'" class="'+b.join(" ")+'"'+c+">"+a.html+"</li>")},a.prototype.results_update_field=function(){return this.result_clear_highlight(),this.result_single_selected=null,this.results_build()},a.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},a.prototype.results_search=function(a){return this.results_showing?this.winnow_results():this.results_show()},a.prototype.keyup_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale();switch(b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:a.preventDefault();if(this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},a.prototype.generate_field_id=function(){var a;return a=this.generate_random_id(),this.form_field.id=a,a},a.prototype.generate_random_char=function(){var a,b,c;return a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ",c=Math.floor(Math.random()*a.length),b=a.substring(c,c+1)},a}(),b.AbstractChosen=a}.call(this),function(){var a,b,c,d,e={}.hasOwnProperty,f=function(a,b){function d(){this.constructor=a}for(var c in b)e.call(b,c)&&(a[c]=b[c]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a};d=this,a=jQuery,a.fn.extend({chosen:function(c){return!a.browser.msie||a.browser.version!=="6.0"&&a.browser.version!=="7.0"?this.each(function(d){var e;e=a(this);if(!e.hasClass("chzn-done"))return e.data("chosen",new b(this,c))}):this}}),b=function(b){function e(){return e.__super__.constructor.apply(this,arguments)}return f(e,b),e.name="Chosen",e.prototype.setup=function(){return this.form_field_jq=a(this.form_field),this.is_rtl=this.form_field_jq.hasClass("chzn-rtl")},e.prototype.finish_setup=function(){return this.form_field_jq.addClass("chzn-done")},e.prototype.set_up_html=function(){var b,d,e,f,g;return this.container_id=this.form_field.id.length?this.form_field.id.replace(/(:|\.)/g,"_"):this.generate_field_id(),this.container_id+="_chzn",this.f_width=this.form_field_jq.outerWidth(),this.default_text=this.form_field_jq.data("placeholder")?this.form_field_jq.data("placeholder"):this.default_text_default,b=a("<div />",{id:this.container_id,"class":"chzn-container"+(this.is_rtl?" chzn-rtl":""),style:"width: "+(this.options.width||this.f_width)+"px;"}),this.is_multiple?b.html('<ul class="chzn-choices"><li class="search-field"><input type="text" value="'+this.default_text+'" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>'):b.html('<a href="javascript:void(0)" class="chzn-single chzn-default"><span>'+this.default_text+'</span><div><b></b></div></a><div class="chzn-drop" style="left:-9000px;"><div class="chzn-search"><input type="text" autocomplete="off" /></div><ul class="chzn-results"></ul></div>'),this.form_field_jq.hide().after(b),this.container=a("#"+this.container_id),this.container.addClass("chzn-container-"+(this.is_multiple?"multi":"single")),this.dropdown=this.container.find("div.chzn-drop").first(),f=this.rise_up(this.container,this.dropdown),d=f?-this.container.find(".chzn-drop").height():this.container.height(),e=this.container.width-c(this.dropdown),this.dropdown.css({width:e+"px",top:d+"px"}),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chzn-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chzn-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chzn-search").first(),this.selected_item=this.container.find(".chzn-single").first(),g=e-c(this.search_container)-c(this.search_field),this.search_field.css({width:g+"px"})),this.results_build(),this.set_tab_index(),this.form_field_jq.trigger("liszt:ready",{chosen:this})},e.prototype.register_observers=function(){var a=this;return this.container.mousedown(function(b){return a.container_mousedown(b)}),this.container.mouseup(function(b){return a.container_mouseup(b)}),this.container.mouseenter(function(b){return a.mouse_enter(b)}),this.container.mouseleave(function(b){return a.mouse_leave(b)}),this.search_results.mouseup(function(b){return a.search_results_mouseup(b)}),this.search_results.mouseover(function(b){return a.search_results_mouseover(b)}),this.search_results.mouseout(function(b){return a.search_results_mouseout(b)}),this.form_field_jq.bind("liszt:updated",function(b){return a.results_update_field(b)}),this.search_field.blur(function(b){return a.input_blur(b)}),this.search_field.keyup(function(b){return a.keyup_checker(b)}),this.search_field.keydown(function(b){return a.keydown_checker(b)}),this.is_multiple?(this.search_choices.click(function(b){return a.choices_click(b)}),this.search_field.focus(function(b){return a.input_focus(b)})):this.container.click(function(a){return a.preventDefault()})},e.prototype.search_field_disabled=function(){this.is_disabled=this.form_field_jq[0].disabled;if(this.is_disabled)return this.container.addClass("chzn-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus",this.activate_action),this.close_field();this.container.removeClass("chzn-disabled"),this.search_field[0].disabled=!1;if(!this.is_multiple)return this.selected_item.bind("focus",this.activate_action)},e.prototype.container_mousedown=function(b){var c;if(!this.is_disabled)return c=b!=null?a(b.target).hasClass("search-choice-close"):!1,b&&b.type==="mousedown"&&!this.results_showing&&b.stopPropagation(),!this.pending_destroy_click&&!c?(this.active_field?!this.is_multiple&&b&&(a(b.target)[0]===this.selected_item[0]||a(b.target).parents("a.chzn-single").length)&&(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(document).click(this.click_test_action),this.results_show()),this.activate_field()):this.pending_destroy_click=!1},e.prototype.container_mouseup=function(a){if(a.target.nodeName==="ABBR")return this.results_reset(a)},e.prototype.blur_test=function(a){if(!this.active_field&&this.container.hasClass("chzn-container-active"))return this.close_field()},e.prototype.close_field=function(){return a(document).unbind("click",this.click_test_action),this.is_multiple||(this.selected_item.attr("tabindex",this.search_field.attr("tabindex")),this.search_field.attr("tabindex",-1)),this.active_field=!1,this.results_hide(),this.container.removeClass("chzn-container-active"),this.winnow_results_clear(),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},e.prototype.activate_field=function(){return!this.is_multiple&&!this.active_field&&(this.search_field.attr("tabindex",this.selected_item.attr("tabindex")),this.selected_item.attr("tabindex",-1)),this.container.addClass("chzn-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},e.prototype.test_active_click=function(b){return a(b.target).parents("#"+this.container_id).length?this.active_field=!0:this.close_field()},e.prototype.results_build=function(){var a,b,c,e,f;this.parsing=!0,this.results_data=d.SelectParser.select_to_array(this.form_field),this.is_multiple&&this.choices>0?(this.search_choices.find("li.search-choice").remove(),this.choices=0):this.is_multiple||(this.selected_item.find("span").text(this.default_text),this.form_field.options.length<=this.disable_search_threshold?this.container.addClass("chzn-container-single-nosearch"):this.container.removeClass("chzn-container-single-nosearch")),a="",f=this.results_data;for(c=0,e=f.length;c<e;c++)b=f[c],b.group?a+=this.result_add_group(b):b.empty||(a+=this.result_add_option(b),b.selected&&this.is_multiple?this.choice_build(b):b.selected&&!this.is_multiple&&(this.selected_item.removeClass("chzn-default").find("span").text(b.text),this.allow_single_deselect&&this.single_deselect_control_build()));return this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.search_results.html(a),this.parsing=!1},e.prototype.result_add_group=function(b){return b.disabled?"":(b.dom_id=this.container_id+"_g_"+b.array_index,'<li id="'+b.dom_id+'" class="group-result">'+a("<div />").text(b.label).html()+"</li>")},e.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight();if(b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(c<f)return this.search_results.scrollTop(c)}},e.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},e.prototype.results_show=function(){var a,b,d;return this.is_multiple||(this.selected_item.addClass("chzn-single-with-drop"),this.result_single_selected&&this.result_do_highlight(this.result_single_selected)),d=this.rise_up(this.container,this.dropdown),a=d?-this.container.find(".chzn-drop").height():this.is_multiple?this.container.height():this.container.height()-1,b=this.container.width()-c(this.dropdown),this.dropdown.css({top:a+"px",left:0}),this.results_showing=!0,this.search_field.css("width",b-c(this.search_container)-c(this.search_field)+"px"),this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results()},e.prototype.results_hide=function(){return this.is_multiple||this.selected_item.removeClass("chzn-single-with-drop"),this.result_clear_highlight(),this.dropdown.css({left:"-9000px"}),this.results_showing=!1},e.prototype.set_tab_index=function(a){var b;if(this.form_field_jq.attr("tabindex"))return b=this.form_field_jq.attr("tabindex"),this.form_field_jq.attr("tabindex",-1),this.is_multiple?this.search_field.attr("tabindex",b):(this.selected_item.attr("tabindex",b),this.search_field.attr("tabindex",-1))},e.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},e.prototype.search_results_mouseup=function(b){var c;c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first();if(c.length)return this.result_highlight=c,this.result_select(b)},e.prototype.search_results_mouseover=function(b){var c;c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first();if(c)return this.result_do_highlight(c)},e.prototype.search_results_mouseout=function(b){if(a(b.target).hasClass("active-result"))return this.result_clear_highlight()},e.prototype.choices_click=function(b){b.preventDefault();if(this.active_field&&!a(b.target).hasClass("search-choice")&&!this.results_showing)return this.results_show()},e.prototype.choice_build=function(b){var c,d,e=this;return c=this.container_id+"_c_"+b.array_index,this.choices+=1,this.search_container.before('<li class="search-choice" id="'+c+'"><span>'+b.html+'</span><a href="javascript:void(0)" class="search-choice-close" rel="'+b.array_index+'"></a></li>'),d=a("#"+c).find("a").first(),d.click(function(a){return e.choice_destroy_link_click(a)})},e.prototype.choice_destroy_link_click=function(b){return b.preventDefault(),this.is_disabled?b.stopPropagation:(this.pending_destroy_click=!0,this.choice_destroy(a(b.target)))},e.prototype.choice_destroy=function(a){return this.choices-=1,this.show_search_field_default(),this.is_multiple&&this.choices>0&&this.search_field.val().length<1&&this.results_hide(),this.result_deselect(a.attr("rel")),a.parents("li").first().remove()},e.prototype.results_reset=function(b){this.form_field.options[0].selected=!0,this.selected_item.find("span").text(this.default_text),this.is_multiple||this.selected_item.addClass("chzn-default"),this.show_search_field_default(),a(b.target).remove(),this.form_field_jq.trigger("change");if(this.active_field)return this.results_hide()},e.prototype.result_select=function(a){var b,c,d,e;if(this.result_highlight)return b=this.result_highlight,c=b.attr("id"),this.result_clear_highlight(),this.is_multiple?this.result_deactivate(b):(this.search_results.find(".result-selected").removeClass("result-selected"),this.result_single_selected=b,this.selected_item.removeClass("chzn-default")),b.addClass("result-selected"),e=c.substr(c.lastIndexOf("_")+1),d=this.results_data[e],d.selected=!0,this.form_field.options[d.options_index].selected=!0,this.is_multiple?this.choice_build(d):(this.selected_item.find("span").first().text(d.text),this.allow_single_deselect&&this.single_deselect_control_build()),(!a.metaKey||!this.is_multiple)&&this.results_hide(),this.search_field.val(""),this.form_field_jq.trigger("change"),this.search_field_scale()},e.prototype.result_activate=function(a){return a.addClass("active-result")},e.prototype.result_deactivate=function(a){return a.removeClass("active-result")},e.prototype.result_deselect=function(b){var c,d;return d=this.results_data[b],d.selected=!1,this.form_field.options[d.options_index].selected=!1,c=a("#"+this.container_id+"_o_"+b),c.removeClass("result-selected").addClass("active-result").show(),this.result_clear_highlight(),this.winnow_results(),this.form_field_jq.trigger("change"),this.search_field_scale()},e.prototype.single_deselect_control_build=function(){if(this.allow_single_deselect&&this.selected_item.find("abbr").length<1)return this.selected_item.find("span").first().after('<abbr class="search-choice-close"></abbr>')},e.prototype.winnow_results=function(){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;this.no_results_clear(),j=0,k=this.search_field.val()===this.default_text?"":a("<div/>").text(a.trim(this.search_field.val())).html(),g=this.search_contains?"":"^",f=new RegExp(g+k.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),n=new RegExp(k.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),s=this.results_data;for(o=0,q=s.length;o<q;o++){c=s[o];if(!c.disabled&&!c.empty)if(c.group)a("#"+c.dom_id).css("display","none");else if(!this.is_multiple||!c.selected){b=!1,i=c.dom_id,h=a("#"+i);if(f.test(c.html))b=!0,j+=1;else if(c.html.indexOf(" ")>=0||c.html.indexOf("[")===0){e=c.html.replace(/\[|\]/g,"").split(" ");if(e.length)for(p=0,r=e.length;p<r;p++)d=e[p],f.test(d)&&(b=!0,j+=1)}b?(k.length?(l=c.html.search(n),m=c.html.substr(0,l+k.length)+"</em>"+c.html.substr(l+k.length),m=m.substr(0,l)+"<em>"+m.substr(l)):m=c.html,h.html(m),this.result_activate(h),c.group_array_index!=null&&a("#"+this.results_data[c.group_array_index].dom_id).css("display","list-item")):(this.result_highlight&&i===this.result_highlight.attr("id")&&this.result_clear_highlight(),this.result_deactivate(h))}}return j<1&&k.length?this.no_results(k):this.winnow_results_set_highlight()},e.prototype.winnow_results_clear=function(){var b,c,d,e,f;this.search_field.val(""),c=this.search_results.find("li"),f=[];for(d=0,e=c.length;d<e;d++)b=c[d],b=a(b),b.hasClass("group-result")?f.push(b.css("display","auto")):!this.is_multiple||!b.hasClass("result-selected")?f.push(this.result_activate(b)):f.push(void 0);return f},e.prototype.winnow_results_set_highlight=function(){var a,b;if(!this.result_highlight){b=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),a=b.length?b.first():this.search_results.find(".active-result").first();if(a!=null)return this.result_do_highlight(a)}},e.prototype.no_results=function(b){var c;return c=a('<li class="no-results">'+this.results_none_found+' "<span></span>"</li>'),c.find("span").first().html(b),this.search_results.append(c)},e.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},e.prototype.keydown_arrow=function(){var b,c;this.result_highlight?this.results_showing&&(c=this.result_highlight.nextAll("li.active-result").first(),c&&this.result_do_highlight(c)):(b=this.search_results.find("li.active-result").first(),b&&this.result_do_highlight(a(b)));if(!this.results_showing)return this.results_show()},e.prototype.keyup_arrow=function(){var a;if(!this.results_showing&&!this.is_multiple)return this.results_show();if(this.result_highlight)return a=this.result_highlight.prevAll("li.active-result"),a.length?this.result_do_highlight(a.first()):(this.choices>0&&this.results_hide(),this.result_clear_highlight())},e.prototype.keydown_backstroke=function(){return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(this.pending_backstroke=this.search_container.siblings("li.search-choice").last(),this.pending_backstroke.addClass("search-choice-focus"))},e.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},e.prototype.keydown_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale(),b!==8&&this.pending_backstroke&&this.clear_backstroke();switch(b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:this.keydown_arrow()}},e.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j,k;if(this.is_multiple){d=0,i=0,g="position:absolute; left: -1000px; top: -1000px; display:none;",h=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"];for(j=0,k=h.length;j<k;j++)f=h[j],g+=f+":"+this.search_field.css(f)+";";return c=a("<div />",{style:g}),c.text(this.search_field.val()),a("body").append(c),i=c.width()+25,c.remove(),i>this.f_width-10&&(i=this.f_width-10),this.search_field.css({width:i+"px"}),e=this.rise_up(this.container,this.dropdown),b=e?-this.container.find(".chzn-drop").height():this.container.height(),this.dropdown.css({top:b+"px"})}},e.prototype.generate_random_id=function(){var b;b="sel"+this.generate_random_char()+this.generate_random_char()+this.generate_random_char();while(a("#"+b).length>0)b+=this.generate_random_char();return b},e.prototype.rise_up=function(b,c){var d,e,f,g;return g=b.find("a.chzn-single"),g.length>0?(f=a(window).height()+a(document).scrollTop()-b.find("a").innerHeight(),e=g.offset().top,d=c.innerHeight(),e+d>f&&e-d>0?(b.addClass("chzn-with-rise"),!0):(b.removeClass("chzn-with-rise"),!1)):!1},e}(AbstractChosen),c=function(a){var b;return b=a.outerWidth()-a.width()},d.get_side_border_padding=c}.call(this); (function(){var e;e=function(){function e(){this.options_index=0,this.parsed=[]}return e.prototype.add_node=function(e){return e.nodeName==="OPTGROUP"?this.add_group(e):this.add_option(e)},e.prototype.add_group=function(e){var t,n,r,i,s,o;t=this.parsed.length,this.parsed.push({array_index:t,group:!0,label:e.label,children:0,disabled:e.disabled}),s=e.childNodes,o=[];for(r=0,i=s.length;r<i;r++)n=s[r],o.push(this.add_option(n,t,e.disabled));return o},e.prototype.add_option=function(e,t,n){if(e.nodeName==="OPTION")return e.text!==""?(t!=null&&(this.parsed[t].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:e.value,text:e.text,html:e.innerHTML,selected:e.selected,disabled:n===!0?n:e.disabled,group_array_index:t,classes:e.className,style:e.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1},e}(),e.select_to_array=function(t){var n,r,i,s,o;r=new e,o=t.childNodes;for(i=0,s=o.length;i<s;i++)n=o[i],r.add_node(n);return r.parsed},this.SelectParser=e}).call(this),function(){var e,t;t=this,e=function(){function e(e,t){this.form_field=e,this.options=t!=null?t:{},this.set_default_values(),this.is_multiple=this.form_field.multiple,this.default_text_default=this.is_multiple?"Select Some Options":"Select an Option",this.setup(),this.set_up_html(),this.register_observers(),this.finish_setup()}return e.prototype.set_default_values=function(){var e=this;return this.click_test_action=function(t){return e.test_active_click(t)},this.activate_action=function(t){return e.activate_field(t)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.result_single_selected=null,this.allow_single_deselect=this.options.allow_single_deselect!=null&&this.form_field.options[0]!=null&&this.form_field.options[0].text===""?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.search_contains=this.options.search_contains||!1,this.choices=0,this.results_none_found=this.options.no_results_text||"No results match"},e.prototype.mouse_enter=function(){return this.mouse_on_container=!0},e.prototype.mouse_leave=function(){return this.mouse_on_container=!1},e.prototype.input_focus=function(e){var t=this;if(!this.active_field)return setTimeout(function(){return t.container_mousedown()},50)},e.prototype.input_blur=function(e){var t=this;if(!this.mouse_on_container)return this.active_field=!1,setTimeout(function(){return t.blur_test()},100)},e.prototype.result_add_option=function(e){var t,n;return e.disabled?"":(e.dom_id=this.container_id+"_o_"+e.array_index,t=e.selected&&this.is_multiple?[]:["active-result"],e.selected&&t.push("result-selected"),e.group_array_index!=null&&t.push("group-option"),e.classes!==""&&t.push(e.classes),n=e.style.cssText!==""?' style="'+e.style+'"':"",'<li id="'+e.dom_id+'" class="'+t.join(" ")+'"'+n+">"+e.html+"</li>")},e.prototype.results_update_field=function(){return this.result_clear_highlight(),this.result_single_selected=null,this.results_build()},e.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},e.prototype.results_search=function(e){return this.results_showing?this.winnow_results():this.results_show()},e.prototype.keyup_checker=function(e){var t,n;t=(n=e.which)!=null?n:e.keyCode,this.search_field_scale();switch(t){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:e.preventDefault();if(this.results_showing)return this.result_select(e);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},e.prototype.generate_field_id=function(){var e;return e=this.generate_random_id(),this.form_field.id=e,e},e.prototype.generate_random_char=function(){var e,t,n;return e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ",n=Math.floor(Math.random()*e.length),t=e.substring(n,n+1)},e}(),t.AbstractChosen=e}.call(this),function(){var e,t,n,r,i={}.hasOwnProperty,s=function(e,t){function r(){this.constructor=e}for(var n in t)i.call(t,n)&&(e[n]=t[n]);return r.prototype=t.prototype,e.prototype=new r,e.__super__=t.prototype,e};r=this,e=jQuery,e.fn.extend({chosen:function(n){return!e.browser.msie||e.browser.version!=="6.0"&&e.browser.version!=="7.0"?this.each(function(r){var i;i=e(this);if(!i.hasClass("chzn-done"))return i.data("chosen",new t(this,n))}):this}}),t=function(t){function i(){return i.__super__.constructor.apply(this,arguments)}return s(i,t),i.prototype.setup=function(){return this.form_field_jq=e(this.form_field),this.is_rtl=this.form_field_jq.hasClass("chzn-rtl")},i.prototype.finish_setup=function(){return this.form_field_jq.addClass("chzn-done")},i.prototype.set_up_html=function(){var t,r,i,s,o;return this.container_id=this.form_field.id.length?this.form_field.id.replace(/(:|\.)/g,"_"):this.generate_field_id(),this.container_id+="_chzn",this.f_width=this.form_field_jq.outerWidth(),this.default_text=this.form_field_jq.data("placeholder")?this.form_field_jq.data("placeholder"):this.default_text_default,t=e("<div />",{id:this.container_id,"class":"chzn-container"+(this.is_rtl?" chzn-rtl":""),style:"width: "+(this.options.width||this.f_width)+"px;"}),this.is_multiple?t.html('<ul class="chzn-choices"><li class="search-field"><input type="text" value="'+this.default_text+'" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>'):t.html('<a href="javascript:void(0)" class="chzn-single chzn-default"><span>'+this.default_text+'</span><div><b></b></div></a><div class="chzn-drop" style="left:-9000px;"><div class="chzn-search"><input type="text" autocomplete="off" /></div><ul class="chzn-results"></ul></div>'),this.form_field_jq.hide().after(t),this.container=e("#"+this.container_id),this.container.addClass("chzn-container-"+(this.is_multiple?"multi":"single")),this.dropdown=this.container.find("div.chzn-drop").first(),s=this.rise_up(this.container,this.dropdown),r=s?-this.container.find(".chzn-drop").height():this.container.height(),i=this.container.width()-n(this.dropdown),this.dropdown.css({width:i+"px",top:r+"px"}),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chzn-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chzn-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chzn-search").first(),this.selected_item=this.container.find(".chzn-single").first(),o=i-n(this.search_container)-n(this.search_field),this.search_field.css({width:o+"px"})),this.results_build(),this.set_tab_index(),this.form_field_jq.trigger("liszt:ready",{chosen:this})},i.prototype.register_observers=function(){var e=this;return this.container.mousedown(function(t){return e.container_mousedown(t)}),this.container.mouseup(function(t){return e.container_mouseup(t)}),this.container.mouseenter(function(t){return e.mouse_enter(t)}),this.container.mouseleave(function(t){return e.mouse_leave(t)}),this.search_results.mouseup(function(t){return e.search_results_mouseup(t)}),this.search_results.mouseover(function(t){return e.search_results_mouseover(t)}),this.search_results.mouseout(function(t){return e.search_results_mouseout(t)}),this.form_field_jq.bind("liszt:updated",function(t){return e.results_update_field(t)}),this.search_field.blur(function(t){return e.input_blur(t)}),this.search_field.keyup(function(t){return e.keyup_checker(t)}),this.search_field.keydown(function(t){return e.keydown_checker(t)}),this.is_multiple?(this.search_choices.click(function(t){return e.choices_click(t)}),this.search_field.focus(function(t){return e.input_focus(t)})):this.container.click(function(e){return e.preventDefault()})},i.prototype.search_field_disabled=function(){this.is_disabled=this.form_field_jq[0].disabled;if(this.is_disabled)return this.container.addClass("chzn-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus",this.activate_action),this.close_field();this.container.removeClass("chzn-disabled"),this.search_field[0].disabled=!1;if(!this.is_multiple)return this.selected_item.bind("focus",this.activate_action)},i.prototype.container_mousedown=function(t){var n;if(!this.is_disabled)return n=t!=null?e(t.target).hasClass("search-choice-close"):!1,t&&t.type==="mousedown"&&!this.results_showing&&t.stopPropagation(),!this.pending_destroy_click&&!n?(this.active_field?!this.is_multiple&&t&&(e(t.target)[0]===this.selected_item[0]||e(t.target).parents("a.chzn-single").length)&&(t.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),e(document).click(this.click_test_action),this.results_show()),this.activate_field()):this.pending_destroy_click=!1},i.prototype.container_mouseup=function(e){if(e.target.nodeName==="ABBR")return this.results_reset(e)},i.prototype.blur_test=function(e){if(!this.active_field&&this.container.hasClass("chzn-container-active"))return this.close_field()},i.prototype.close_field=function(){return e(document).unbind("click",this.click_test_action),this.is_multiple||(this.selected_item.attr("tabindex",this.search_field.attr("tabindex")),this.search_field.attr("tabindex",-1)),this.active_field=!1,this.results_hide(),this.container.removeClass("chzn-container-active"),this.winnow_results_clear(),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},i.prototype.activate_field=function(){return!this.is_multiple&&!this.active_field&&(this.search_field.attr("tabindex",this.selected_item.attr("tabindex")),this.selected_item.attr("tabindex",-1)),this.container.addClass("chzn-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},i.prototype.test_active_click=function(t){return e(t.target).parents("#"+this.container_id).length?this.active_field=!0:this.close_field()},i.prototype.results_build=function(){var e,t,n,i,s;this.parsing=!0,this.results_data=r.SelectParser.select_to_array(this.form_field),this.is_multiple&&this.choices>0?(this.search_choices.find("li.search-choice").remove(),this.choices=0):this.is_multiple||(this.selected_item.find("span").text(this.default_text),this.form_field.options.length<=this.disable_search_threshold?this.container.addClass("chzn-container-single-nosearch"):this.container.removeClass("chzn-container-single-nosearch")),e="",s=this.results_data;for(n=0,i=s.length;n<i;n++)t=s[n],t.group?e+=this.result_add_group(t):t.empty||(e+=this.result_add_option(t),t.selected&&this.is_multiple?this.choice_build(t):t.selected&&!this.is_multiple&&(this.selected_item.removeClass("chzn-default").find("span").text(t.text),this.allow_single_deselect&&this.single_deselect_control_build()));return this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.search_results.html(e),this.parsing=!1},i.prototype.result_add_group=function(t){return t.disabled?"":(t.dom_id=this.container_id+"_g_"+t.array_index,'<li id="'+t.dom_id+'" class="group-result">'+e("<div />").text(t.label).html()+"</li>")},i.prototype.result_do_highlight=function(e){var t,n,r,i,s;if(e.length){this.result_clear_highlight(),this.result_highlight=e,this.result_highlight.addClass("highlighted"),r=parseInt(this.search_results.css("maxHeight"),10),s=this.search_results.scrollTop(),i=r+s,n=this.result_highlight.position().top+this.search_results.scrollTop(),t=n+this.result_highlight.outerHeight();if(t>=i)return this.search_results.scrollTop(t-r>0?t-r:0);if(n<s)return this.search_results.scrollTop(n)}},i.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},i.prototype.results_show=function(){var e,t,r;return this.is_multiple||(this.selected_item.addClass("chzn-single-with-drop"),this.result_single_selected&&this.result_do_highlight(this.result_single_selected)),r=this.rise_up(this.container,this.dropdown),e=r?-this.container.find(".chzn-drop").height():this.is_multiple?this.container.height():this.container.height()-1,t=this.container.width()-n(this.dropdown),this.dropdown.css({top:e+"px",left:0}),this.results_showing=!0,this.search_field.css("width",t-n(this.search_container)-n(this.search_field)+"px"),this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results()},i.prototype.results_hide=function(){return this.is_multiple||this.selected_item.removeClass("chzn-single-with-drop"),this.result_clear_highlight(),this.dropdown.css({left:"-9000px"}),this.results_showing=!1},i.prototype.set_tab_index=function(e){var t;if(this.form_field_jq.attr("tabindex"))return t=this.form_field_jq.attr("tabindex"),this.form_field_jq.attr("tabindex",-1),this.is_multiple?this.search_field.attr("tabindex",t):(this.selected_item.attr("tabindex",t),this.search_field.attr("tabindex",-1))},i.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},i.prototype.search_results_mouseup=function(t){var n;n=e(t.target).hasClass("active-result")?e(t.target):e(t.target).parents(".active-result").first();if(n.length)return this.result_highlight=n,this.result_select(t)},i.prototype.search_results_mouseover=function(t){var n;n=e(t.target).hasClass("active-result")?e(t.target):e(t.target).parents(".active-result").first();if(n)return this.result_do_highlight(n)},i.prototype.search_results_mouseout=function(t){if(e(t.target).hasClass("active-result"))return this.result_clear_highlight()},i.prototype.choices_click=function(t){t.preventDefault();if(this.active_field&&!e(t.target).hasClass("search-choice")&&!this.results_showing)return this.results_show()},i.prototype.choice_build=function(t){var n,r,i=this;return n=this.container_id+"_c_"+t.array_index,this.choices+=1,this.search_container.before('<li class="search-choice" id="'+n+'"><span>'+t.html+'</span><a href="javascript:void(0)" class="search-choice-close" rel="'+t.array_index+'"></a></li>'),r=e("#"+n).find("a").first(),r.click(function(e){return i.choice_destroy_link_click(e)})},i.prototype.choice_destroy_link_click=function(t){return t.preventDefault(),this.is_disabled?t.stopPropagation:(this.pending_destroy_click=!0,this.choice_destroy(e(t.target)))},i.prototype.choice_destroy=function(e){return this.choices-=1,this.show_search_field_default(),this.is_multiple&&this.choices>0&&this.search_field.val().length<1&&this.results_hide(),this.result_deselect(e.attr("rel")),e.parents("li").first().remove()},i.prototype.results_reset=function(t){this.form_field.options[0].selected=!0,this.selected_item.find("span").text(this.default_text),this.is_multiple||this.selected_item.addClass("chzn-default"),this.show_search_field_default(),e(t.target).remove(),this.form_field_jq.trigger("change");if(this.active_field)return this.results_hide()},i.prototype.result_select=function(e){var t,n,r,i;if(this.result_highlight)return t=this.result_highlight,n=t.attr("id"),this.result_clear_highlight(),this.is_multiple?this.result_deactivate(t):(this.search_results.find(".result-selected").removeClass("result-selected"),this.result_single_selected=t,this.selected_item.removeClass("chzn-default")),t.addClass("result-selected"),i=n.substr(n.lastIndexOf("_")+1),r=this.results_data[i],r.selected=!0,this.form_field.options[r.options_index].selected=!0,this.is_multiple?this.choice_build(r):(this.selected_item.find("span").first().text(r.text),this.allow_single_deselect&&this.single_deselect_control_build()),(!e.metaKey||!this.is_multiple)&&this.results_hide(),this.search_field.val(""),this.form_field_jq.trigger("change"),this.search_field_scale()},i.prototype.result_activate=function(e){return e.addClass("active-result")},i.prototype.result_deactivate=function(e){return e.removeClass("active-result")},i.prototype.result_deselect=function(t){var n,r;return r=this.results_data[t],r.selected=!1,this.form_field.options[r.options_index].selected=!1,n=e("#"+this.container_id+"_o_"+t),n.removeClass("result-selected").addClass("active-result").show(),this.result_clear_highlight(),this.winnow_results(),this.form_field_jq.trigger("change"),this.search_field_scale()},i.prototype.single_deselect_control_build=function(){if(this.allow_single_deselect&&this.selected_item.find("abbr").length<1)return this.selected_item.find("span").first().after('<abbr class="search-choice-close"></abbr>')},i.prototype.winnow_results=function(){var t,n,r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y;this.no_results_clear(),f=0,l=this.search_field.val()===this.default_text?"":e("<div/>").text(e.trim(this.search_field.val())).html(),o=this.search_contains?"":"^",s=new RegExp(o+l.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),p=new RegExp(l.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),y=this.results_data;for(d=0,m=y.length;d<m;d++){n=y[d];if(!n.disabled&&!n.empty)if(n.group)e("#"+n.dom_id).css("display","none");else if(!this.is_multiple||!n.selected){t=!1,a=n.dom_id,u=e("#"+a);if(s.test(n.html))t=!0,f+=1;else if(n.html.indexOf(" ")>=0||n.html.indexOf("[")===0){i=n.html.replace(/\[|\]/g,"").split(" ");if(i.length)for(v=0,g=i.length;v<g;v++)r=i[v],s.test(r)&&(t=!0,f+=1)}t?(l.length?(c=n.html.search(p),h=n.html.substr(0,c+l.length)+"</em>"+n.html.substr(c+l.length),h=h.substr(0,c)+"<em>"+h.substr(c)):h=n.html,u.html(h),this.result_activate(u),n.group_array_index!=null&&e("#"+this.results_data[n.group_array_index].dom_id).css("display","list-item")):(this.result_highlight&&a===this.result_highlight.attr("id")&&this.result_clear_highlight(),this.result_deactivate(u))}}return f<1&&l.length?this.no_results(l):this.winnow_results_set_highlight()},i.prototype.winnow_results_clear=function(){var t,n,r,i,s;this.search_field.val(""),n=this.search_results.find("li"),s=[];for(r=0,i=n.length;r<i;r++)t=n[r],t=e(t),t.hasClass("group-result")?s.push(t.css("display","auto")):!this.is_multiple||!t.hasClass("result-selected")?s.push(this.result_activate(t)):s.push(void 0);return s},i.prototype.winnow_results_set_highlight=function(){var e,t;if(!this.result_highlight){t=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),e=t.length?t.first():this.search_results.find(".active-result").first();if(e!=null)return this.result_do_highlight(e)}},i.prototype.no_results=function(t){var n;return n=e('<li class="no-results">'+this.results_none_found+' "<span></span>"</li>'),n.find("span").first().html(t),this.search_results.append(n)},i.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},i.prototype.keydown_arrow=function(){var t,n;this.result_highlight?this.results_showing&&(n=this.result_highlight.nextAll("li.active-result").first(),n&&this.result_do_highlight(n)):(t=this.search_results.find("li.active-result").first(),t&&this.result_do_highlight(e(t)));if(!this.results_showing)return this.results_show()},i.prototype.keyup_arrow=function(){var e;if(!this.results_showing&&!this.is_multiple)return this.results_show();if(this.result_highlight)return e=this.result_highlight.prevAll("li.active-result"),e.length?this.result_do_highlight(e.first()):(this.choices>0&&this.results_hide(),this.result_clear_highlight())},i.prototype.keydown_backstroke=function(){return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(this.pending_backstroke=this.search_container.siblings("li.search-choice").last(),this.pending_backstroke.addClass("search-choice-focus"))},i.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},i.prototype.keydown_checker=function(e){var t,n;t=(n=e.which)!=null?n:e.keyCode,this.search_field_scale(),t!==8&&this.pending_backstroke&&this.clear_backstroke();switch(t){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(e),this.mouse_on_container=!1;break;case 13:e.preventDefault();break;case 38:e.preventDefault(),this.keyup_arrow();break;case 40:this.keydown_arrow()}},i.prototype.search_field_scale=function(){var t,n,r,i,s,o,u,a,f,l;if(this.is_multiple){r=0,a=0,o="position:absolute; left: -1000px; top: -1000px; display:none;",u=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"];for(f=0,l=u.length;f<l;f++)s=u[f],o+=s+":"+this.search_field.css(s)+";";return n=e("<div />",{style:o}),n.text(this.search_field.val()),e("body").append(n),a=n.width()+25,n.remove(),a>this.f_width-10&&(a=this.f_width-10),this.search_field.css({width:a+"px"}),i=this.rise_up(this.container,this.dropdown),t=i?-this.container.find(".chzn-drop").height():this.container.height(),this.dropdown.css({top:t+"px"})}},i.prototype.generate_random_id=function(){var t;t="sel"+this.generate_random_char()+this.generate_random_char()+this.generate_random_char();while(e("#"+t).length>0)t+=this.generate_random_char();return t},i.prototype.rise_up=function(t,n){var r,i,s,o;return o=t.find("a.chzn-single"),o.length>0?(s=e(window).height()+e(document).scrollTop()-t.find("a").innerHeight(),i=o.offset().top,r=n.innerHeight(),i+r>s&&i-r>0?(t.addClass("chzn-with-rise"),!0):(t.removeClass("chzn-with-rise"),!1)):!1},i}(AbstractChosen),n=function(e){var t;return t=e.outerWidth()-e.width()},r.get_side_border_padding=n}.call(this);

View File

@ -14,8 +14,6 @@
SelectParser = (function() { SelectParser = (function() {
SelectParser.name = 'SelectParser';
function SelectParser() { function SelectParser() {
this.options_index = 0; this.options_index = 0;
this.parsed = []; this.parsed = [];
@ -109,8 +107,6 @@ Copyright (c) 2011 by Harvest
AbstractChosen = (function() { AbstractChosen = (function() {
AbstractChosen.name = 'AbstractChosen';
function AbstractChosen(form_field, options) { function AbstractChosen(form_field, options) {
this.form_field = form_field; this.form_field = form_field;
this.options = options != null ? options : {}; this.options = options != null ? options : {};
@ -280,7 +276,7 @@ Copyright (c) 2011 by Harvest
(function() { (function() {
var Chosen, get_side_border_padding, root, var Chosen, get_side_border_padding, root,
__hasProp = {}.hasOwnProperty, __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
root = this; root = this;
@ -288,8 +284,6 @@ Copyright (c) 2011 by Harvest
__extends(Chosen, _super); __extends(Chosen, _super);
Chosen.name = 'Chosen';
function Chosen() { function Chosen() {
return Chosen.__super__.constructor.apply(this, arguments); return Chosen.__super__.constructor.apply(this, arguments);
} }

View File

@ -9,4 +9,4 @@
// based on version 0.9.8, applied a very simple patch that fix percentaage width support on select tag // based on version 0.9.8, applied a very simple patch that fix percentaage width support on select tag
// This file is generated by `cake build`, do not edit it by hand. // This file is generated by `cake build`, do not edit it by hand.
(function(){var a;a=function(){function a(){this.options_index=0,this.parsed=[]}return a.name="SelectParser",a.prototype.add_node=function(a){return a.nodeName==="OPTGROUP"?this.add_group(a):this.add_option(a)},a.prototype.add_group=function(a){var b,c,d,e,f,g;b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:a.label,children:0,disabled:a.disabled}),f=a.childNodes,g=[];for(d=0,e=f.length;d<e;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},a.prototype.add_option=function(a,b,c){if(a.nodeName==="OPTION")return a.text!==""?(b!=null&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1},a}(),a.select_to_array=function(b){var c,d,e,f,g;d=new a,g=b.childNodes;for(e=0,f=g.length;e<f;e++)c=g[e],d.add_node(c);return d.parsed},this.SelectParser=a}).call(this),function(){var a,b;b=this,a=function(){function a(a,b){this.form_field=a,this.options=b!=null?b:{},this.set_default_values(),this.is_multiple=this.form_field.multiple,this.default_text_default=this.is_multiple?"Select Some Options":"Select an Option",this.setup(),this.set_up_html(),this.register_observers(),this.finish_setup()}return a.name="AbstractChosen",a.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.result_single_selected=null,this.allow_single_deselect=this.options.allow_single_deselect!=null&&this.form_field.options[0]!=null&&this.form_field.options[0].text===""?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.search_contains=this.options.search_contains||!1,this.choices=0,this.results_none_found=this.options.no_results_text||"No results match"},a.prototype.mouse_enter=function(){return this.mouse_on_container=!0},a.prototype.mouse_leave=function(){return this.mouse_on_container=!1},a.prototype.input_focus=function(a){var b=this;if(!this.active_field)return setTimeout(function(){return b.container_mousedown()},50)},a.prototype.input_blur=function(a){var b=this;if(!this.mouse_on_container)return this.active_field=!1,setTimeout(function(){return b.blur_test()},100)},a.prototype.result_add_option=function(a){var b,c;return a.disabled?"":(a.dom_id=this.container_id+"_o_"+a.array_index,b=a.selected&&this.is_multiple?[]:["active-result"],a.selected&&b.push("result-selected"),a.group_array_index!=null&&b.push("group-option"),a.classes!==""&&b.push(a.classes),c=a.style.cssText!==""?' style="'+a.style+'"':"",'<li id="'+a.dom_id+'" class="'+b.join(" ")+'"'+c+">"+a.html+"</li>")},a.prototype.results_update_field=function(){return this.result_clear_highlight(),this.result_single_selected=null,this.results_build()},a.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},a.prototype.results_search=function(a){return this.results_showing?this.winnow_results():this.results_show()},a.prototype.keyup_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale();switch(b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:a.preventDefault();if(this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},a.prototype.generate_field_id=function(){var a;return a=this.generate_random_id(),this.form_field.id=a,a},a.prototype.generate_random_char=function(){var a,b,c;return a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ",c=Math.floor(Math.random()*a.length),b=a.substring(c,c+1)},a}(),b.AbstractChosen=a}.call(this),function(){var a,b,c,d={}.hasOwnProperty,e=function(a,b){function e(){this.constructor=a}for(var c in b)d.call(b,c)&&(a[c]=b[c]);return e.prototype=b.prototype,a.prototype=new e,a.__super__=b.prototype,a};c=this,a=function(a){function d(){return d.__super__.constructor.apply(this,arguments)}return e(d,a),d.name="Chosen",d.prototype.setup=function(){return this.is_rtl=this.form_field.hasClassName("chzn-rtl")},d.prototype.finish_setup=function(){return this.form_field.addClassName("chzn-done")},d.prototype.set_default_values=function(){return d.__super__.set_default_values.call(this),this.single_temp=new Template('<a href="javascript:void(0)" class="chzn-single chzn-default"><span>#{default}</span><div><b></b></div></a><div class="chzn-drop" style="left:-9000px;"><div class="chzn-search"><input type="text" autocomplete="off" /></div><ul class="chzn-results"></ul></div>'),this.multi_temp=new Template('<ul class="chzn-choices"><li class="search-field"><input type="text" value="#{default}" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>'),this.choice_temp=new Template('<li class="search-choice" id="#{id}"><span>#{choice}</span><a href="javascript:void(0)" class="search-choice-close" rel="#{position}"></a></li>'),this.no_results_temp=new Template('<li class="no-results">'+this.results_none_found+' "<span>#{terms}</span>"</li>')},d.prototype.set_up_html=function(){var a,c,d,e,f;return this.container_id=this.form_field.identify().replace(/(:|\.)/g,"_")+"_chzn",this.f_width=this.form_field.getStyle("width")?parseInt(this.form_field.getStyle("width"),10):this.form_field.getWidth(),c={id:this.container_id,"class":"chzn-container"+(this.is_rtl?" chzn-rtl":""),style:"width: "+this.f_width+"px"},this.default_text=this.form_field.readAttribute("data-placeholder")?this.form_field.readAttribute("data-placeholder"):this.default_text_default,a=this.is_multiple?(new Element("div",c)).update(this.multi_temp.evaluate({"default":this.default_text})):(new Element("div",c)).update(this.single_temp.evaluate({"default":this.default_text})),this.form_field.hide().insert({after:a}),this.container=$(this.container_id),this.container.addClassName("chzn-container-"+(this.is_multiple?"multi":"single")),this.dropdown=this.container.down("div.chzn-drop"),d=this.container.getHeight(),e=this.f_width-b(this.dropdown),this.dropdown.setStyle({width:e+"px",top:d+"px"}),this.search_field=this.container.down("input"),this.search_results=this.container.down("ul.chzn-results"),this.search_field_scale(),this.search_no_results=this.container.down("li.no-results"),this.is_multiple?(this.search_choices=this.container.down("ul.chzn-choices"),this.search_container=this.container.down("li.search-field")):(this.search_container=this.container.down("div.chzn-search"),this.selected_item=this.container.down(".chzn-single"),f=e-b(this.search_container)-b(this.search_field),this.search_field.setStyle({width:f+"px"})),this.results_build(),this.set_tab_index(),this.form_field.fire("liszt:ready",{chosen:this})},d.prototype.register_observers=function(){var a=this;return this.container.observe("mousedown",function(b){return a.container_mousedown(b)}),this.container.observe("mouseup",function(b){return a.container_mouseup(b)}),this.container.observe("mouseenter",function(b){return a.mouse_enter(b)}),this.container.observe("mouseleave",function(b){return a.mouse_leave(b)}),this.search_results.observe("mouseup",function(b){return a.search_results_mouseup(b)}),this.search_results.observe("mouseover",function(b){return a.search_results_mouseover(b)}),this.search_results.observe("mouseout",function(b){return a.search_results_mouseout(b)}),this.form_field.observe("liszt:updated",function(b){return a.results_update_field(b)}),this.search_field.observe("blur",function(b){return a.input_blur(b)}),this.search_field.observe("keyup",function(b){return a.keyup_checker(b)}),this.search_field.observe("keydown",function(b){return a.keydown_checker(b)}),this.is_multiple?(this.search_choices.observe("click",function(b){return a.choices_click(b)}),this.search_field.observe("focus",function(b){return a.input_focus(b)})):this.container.observe("click",function(a){return a.preventDefault()})},d.prototype.search_field_disabled=function(){this.is_disabled=this.form_field.disabled;if(this.is_disabled)return this.container.addClassName("chzn-disabled"),this.search_field.disabled=!0,this.is_multiple||this.selected_item.stopObserving("focus",this.activate_action),this.close_field();this.container.removeClassName("chzn-disabled"),this.search_field.disabled=!1;if(!this.is_multiple)return this.selected_item.observe("focus",this.activate_action)},d.prototype.container_mousedown=function(a){var b;if(!this.is_disabled)return b=a!=null?a.target.hasClassName("search-choice-close"):!1,a&&a.type==="mousedown"&&!this.results_showing&&a.stop(),!this.pending_destroy_click&&!b?(this.active_field?!this.is_multiple&&a&&(a.target===this.selected_item||a.target.up("a.chzn-single"))&&this.results_toggle():(this.is_multiple&&this.search_field.clear(),document.observe("click",this.click_test_action),this.results_show()),this.activate_field()):this.pending_destroy_click=!1},d.prototype.container_mouseup=function(a){if(a.target.nodeName==="ABBR")return this.results_reset(a)},d.prototype.blur_test=function(a){if(!this.active_field&&this.container.hasClassName("chzn-container-active"))return this.close_field()},d.prototype.close_field=function(){return document.stopObserving("click",this.click_test_action),this.is_multiple||(this.selected_item.tabIndex=this.search_field.tabIndex,this.search_field.tabIndex=-1),this.active_field=!1,this.results_hide(),this.container.removeClassName("chzn-container-active"),this.winnow_results_clear(),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},d.prototype.activate_field=function(){return!this.is_multiple&&!this.active_field&&(this.search_field.tabIndex=this.selected_item.tabIndex,this.selected_item.tabIndex=-1),this.container.addClassName("chzn-container-active"),this.active_field=!0,this.search_field.value=this.search_field.value,this.search_field.focus()},d.prototype.test_active_click=function(a){return a.target.up("#"+this.container_id)?this.active_field=!0:this.close_field()},d.prototype.results_build=function(){var a,b,d,e,f;this.parsing=!0,this.results_data=c.SelectParser.select_to_array(this.form_field),this.is_multiple&&this.choices>0?(this.search_choices.select("li.search-choice").invoke("remove"),this.choices=0):this.is_multiple||(this.selected_item.down("span").update(this.default_text),this.form_field.options.length<=this.disable_search_threshold?this.container.addClassName("chzn-container-single-nosearch"):this.container.removeClassName("chzn-container-single-nosearch")),a="",f=this.results_data;for(d=0,e=f.length;d<e;d++)b=f[d],b.group?a+=this.result_add_group(b):b.empty||(a+=this.result_add_option(b),b.selected&&this.is_multiple?this.choice_build(b):b.selected&&!this.is_multiple&&(this.selected_item.removeClassName("chzn-default").down("span").update(b.html),this.allow_single_deselect&&this.single_deselect_control_build()));return this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.search_results.update(a),this.parsing=!1},d.prototype.result_add_group=function(a){return a.disabled?"":(a.dom_id=this.container_id+"_g_"+a.array_index,'<li id="'+a.dom_id+'" class="group-result">'+a.label.escapeHTML()+"</li>")},d.prototype.result_do_highlight=function(a){var b,c,d,e,f;this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClassName("highlighted"),d=parseInt(this.search_results.getStyle("maxHeight"),10),f=this.search_results.scrollTop,e=d+f,c=this.result_highlight.positionedOffset().top,b=c+this.result_highlight.getHeight();if(b>=e)return this.search_results.scrollTop=b-d>0?b-d:0;if(c<f)return this.search_results.scrollTop=c},d.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClassName("highlighted"),this.result_highlight=null},d.prototype.results_show=function(){var a;return this.is_multiple||(this.selected_item.addClassName("chzn-single-with-drop"),this.result_single_selected&&this.result_do_highlight(this.result_single_selected)),a=this.is_multiple?this.container.getHeight():this.container.getHeight()-1,this.dropdown.setStyle({top:a+"px",left:0}),this.results_showing=!0,this.search_field.focus(),this.search_field.value=this.search_field.value,this.winnow_results()},d.prototype.results_hide=function(){return this.is_multiple||this.selected_item.removeClassName("chzn-single-with-drop"),this.result_clear_highlight(),this.dropdown.setStyle({left:"-9000px"}),this.results_showing=!1},d.prototype.set_tab_index=function(a){var b;if(this.form_field.tabIndex)return b=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.is_multiple?this.search_field.tabIndex=b:(this.selected_item.tabIndex=b,this.search_field.tabIndex=-1)},d.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices<1&&!this.active_field?(this.search_field.value=this.default_text,this.search_field.addClassName("default")):(this.search_field.value="",this.search_field.removeClassName("default"))},d.prototype.search_results_mouseup=function(a){var b;b=a.target.hasClassName("active-result")?a.target:a.target.up(".active-result");if(b)return this.result_highlight=b,this.result_select(a)},d.prototype.search_results_mouseover=function(a){var b;b=a.target.hasClassName("active-result")?a.target:a.target.up(".active-result");if(b)return this.result_do_highlight(b)},d.prototype.search_results_mouseout=function(a){if(a.target.hasClassName("active-result")||a.target.up(".active-result"))return this.result_clear_highlight()},d.prototype.choices_click=function(a){a.preventDefault();if(this.active_field&&!a.target.hasClassName("search-choice")&&!a.target.up(".search-choice")&&!this.results_showing)return this.results_show()},d.prototype.choice_build=function(a){var b,c,d=this;return b=this.container_id+"_c_"+a.array_index,this.choices+=1,this.search_container.insert({before:this.choice_temp.evaluate({id:b,choice:a.html,position:a.array_index})}),c=$(b).down("a"),c.observe("click",function(a){return d.choice_destroy_link_click(a)})},d.prototype.choice_destroy_link_click=function(a){a.preventDefault();if(!this.is_disabled)return this.pending_destroy_click=!0,this.choice_destroy(a.target)},d.prototype.choice_destroy=function(a){return this.choices-=1,this.show_search_field_default(),this.is_multiple&&this.choices>0&&this.search_field.value.length<1&&this.results_hide(),this.result_deselect(a.readAttribute("rel")),a.up("li").remove()},d.prototype.results_reset=function(a){this.form_field.options[0].selected=!0,this.selected_item.down("span").update(this.default_text),this.is_multiple||this.selected_item.addClassName("chzn-default"),this.show_search_field_default(),a.target.remove(),typeof Event.simulate=="function"&&this.form_field.simulate("change");if(this.active_field)return this.results_hide()},d.prototype.result_select=function(a){var b,c,d;if(this.result_highlight)return b=this.result_highlight,this.result_clear_highlight(),this.is_multiple?this.result_deactivate(b):(this.search_results.descendants(".result-selected").invoke("removeClassName","result-selected"),this.selected_item.removeClassName("chzn-default"),this.result_single_selected=b),b.addClassName("result-selected"),d=b.id.substr(b.id.lastIndexOf("_")+1),c=this.results_data[d],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.is_multiple?this.choice_build(c):(this.selected_item.down("span").update(c.html),this.allow_single_deselect&&this.single_deselect_control_build()),(!a.metaKey||!this.is_multiple)&&this.results_hide(),this.search_field.value="",typeof Event.simulate=="function"&&this.form_field.simulate("change"),this.search_field_scale()},d.prototype.result_activate=function(a){return a.addClassName("active-result")},d.prototype.result_deactivate=function(a){return a.removeClassName("active-result")},d.prototype.result_deselect=function(a){var b,c;return c=this.results_data[a],c.selected=!1,this.form_field.options[c.options_index].selected=!1,b=$(this.container_id+"_o_"+a),b.removeClassName("result-selected").addClassName("active-result").show(),this.result_clear_highlight(),this.winnow_results(),typeof Event.simulate=="function"&&this.form_field.simulate("change"),this.search_field_scale()},d.prototype.single_deselect_control_build=function(){if(this.allow_single_deselect&&!this.selected_item.down("abbr"))return this.selected_item.down("span").insert({after:'<abbr class="search-choice-close"></abbr>'})},d.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;this.no_results_clear(),h=0,i=this.search_field.value===this.default_text?"":this.search_field.value.strip().escapeHTML(),f=this.search_contains?"":"^",e=new RegExp(f+i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),l=new RegExp(i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),q=this.results_data;for(m=0,o=q.length;m<o;m++){b=q[m];if(!b.disabled&&!b.empty)if(b.group)$(b.dom_id).hide();else if(!this.is_multiple||!b.selected){a=!1,g=b.dom_id;if(e.test(b.html))a=!0,h+=1;else if(b.html.indexOf(" ")>=0||b.html.indexOf("[")===0){d=b.html.replace(/\[|\]/g,"").split(" ");if(d.length)for(n=0,p=d.length;n<p;n++)c=d[n],e.test(c)&&(a=!0,h+=1)}a?(i.length?(j=b.html.search(l),k=b.html.substr(0,j+i.length)+"</em>"+b.html.substr(j+i.length),k=k.substr(0,j)+"<em>"+k.substr(j)):k=b.html,$(g).innerHTML!==k&&$(g).update(k),this.result_activate($(g)),b.group_array_index!=null&&$(this.results_data[b.group_array_index].dom_id).setStyle({display:"list-item"})):($(g)===this.result_highlight&&this.result_clear_highlight(),this.result_deactivate($(g)))}}return h<1&&i.length?this.no_results(i):this.winnow_results_set_highlight()},d.prototype.winnow_results_clear=function(){var a,b,c,d,e;this.search_field.clear(),b=this.search_results.select("li"),e=[];for(c=0,d=b.length;c<d;c++)a=b[c],a.hasClassName("group-result")?e.push(a.show()):!this.is_multiple||!a.hasClassName("result-selected")?e.push(this.result_activate(a)):e.push(void 0);return e},d.prototype.winnow_results_set_highlight=function(){var a;if(!this.result_highlight){this.is_multiple||(a=this.search_results.down(".result-selected.active-result")),a==null&&(a=this.search_results.down(".active-result"));if(a!=null)return this.result_do_highlight(a)}},d.prototype.no_results=function(a){return this.search_results.insert(this.no_results_temp.evaluate({terms:a}))},d.prototype.no_results_clear=function(){var a,b;a=null,b=[];while(a=this.search_results.down(".no-results"))b.push(a.remove());return b},d.prototype.keydown_arrow=function(){var a,b,c;a=this.search_results.select("li.active-result");if(a.length){this.result_highlight?this.results_showing&&(c=this.result_highlight.nextSiblings(),b=c.intersect(a),b.length&&this.result_do_highlight(b.first())):this.result_do_highlight(a.first());if(!this.results_showing)return this.results_show()}},d.prototype.keyup_arrow=function(){var a,b,c;if(!this.results_showing&&!this.is_multiple)return this.results_show();if(this.result_highlight)return c=this.result_highlight.previousSiblings(),a=this.search_results.select("li.active-result"),b=c.intersect(a),b.length?this.result_do_highlight(b.first()):(this.choices>0&&this.results_hide(),this.result_clear_highlight())},d.prototype.keydown_backstroke=function(){return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.down("a")),this.clear_backstroke()):(this.pending_backstroke=this.search_container.siblings("li.search-choice").last(),this.pending_backstroke.addClassName("search-choice-focus"))},d.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClassName("search-choice-focus"),this.pending_backstroke=null},d.prototype.keydown_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale(),b!==8&&this.pending_backstroke&&this.clear_backstroke();switch(b){case 8:this.backstroke_length=this.search_field.value.length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:this.keydown_arrow()}},d.prototype.search_field_scale=function(){var a,b,c,d,e,f,g,h,i;if(this.is_multiple){c=0,g=0,e="position:absolute; left: -1000px; top: -1000px; display:none;",f=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"];for(h=0,i=f.length;h<i;h++)d=f[h],e+=d+":"+this.search_field.getStyle(d)+";";return b=(new Element("div",{style:e})).update(this.search_field.value.escapeHTML()),document.body.appendChild(b),g=Element.measure(b,"width")+25,b.remove(),g>this.f_width-10&&(g=this.f_width-10),this.search_field.setStyle({width:g+"px"}),a=this.container.getHeight(),this.dropdown.setStyle({top:a+"px"})}},d}(AbstractChosen),c.Chosen=a,Prototype.Browser.IE&&/MSIE (\d+\.\d+);/.test(navigator.userAgent)&&(Prototype.BrowserFeatures.Version=new Number(RegExp.$1)),b=function(a){var b,c;return b=new Element.Layout(a),c=b.get("border-left")+b.get("border-right")+b.get("padding-left")+b.get("padding-right")},c.get_side_border_padding=b}.call(this); (function(){var e;e=function(){function e(){this.options_index=0,this.parsed=[]}return e.prototype.add_node=function(e){return e.nodeName==="OPTGROUP"?this.add_group(e):this.add_option(e)},e.prototype.add_group=function(e){var t,n,r,i,s,o;t=this.parsed.length,this.parsed.push({array_index:t,group:!0,label:e.label,children:0,disabled:e.disabled}),s=e.childNodes,o=[];for(r=0,i=s.length;r<i;r++)n=s[r],o.push(this.add_option(n,t,e.disabled));return o},e.prototype.add_option=function(e,t,n){if(e.nodeName==="OPTION")return e.text!==""?(t!=null&&(this.parsed[t].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:e.value,text:e.text,html:e.innerHTML,selected:e.selected,disabled:n===!0?n:e.disabled,group_array_index:t,classes:e.className,style:e.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1},e}(),e.select_to_array=function(t){var n,r,i,s,o;r=new e,o=t.childNodes;for(i=0,s=o.length;i<s;i++)n=o[i],r.add_node(n);return r.parsed},this.SelectParser=e}).call(this),function(){var e,t;t=this,e=function(){function e(e,t){this.form_field=e,this.options=t!=null?t:{},this.set_default_values(),this.is_multiple=this.form_field.multiple,this.default_text_default=this.is_multiple?"Select Some Options":"Select an Option",this.setup(),this.set_up_html(),this.register_observers(),this.finish_setup()}return e.prototype.set_default_values=function(){var e=this;return this.click_test_action=function(t){return e.test_active_click(t)},this.activate_action=function(t){return e.activate_field(t)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.result_single_selected=null,this.allow_single_deselect=this.options.allow_single_deselect!=null&&this.form_field.options[0]!=null&&this.form_field.options[0].text===""?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.search_contains=this.options.search_contains||!1,this.choices=0,this.results_none_found=this.options.no_results_text||"No results match"},e.prototype.mouse_enter=function(){return this.mouse_on_container=!0},e.prototype.mouse_leave=function(){return this.mouse_on_container=!1},e.prototype.input_focus=function(e){var t=this;if(!this.active_field)return setTimeout(function(){return t.container_mousedown()},50)},e.prototype.input_blur=function(e){var t=this;if(!this.mouse_on_container)return this.active_field=!1,setTimeout(function(){return t.blur_test()},100)},e.prototype.result_add_option=function(e){var t,n;return e.disabled?"":(e.dom_id=this.container_id+"_o_"+e.array_index,t=e.selected&&this.is_multiple?[]:["active-result"],e.selected&&t.push("result-selected"),e.group_array_index!=null&&t.push("group-option"),e.classes!==""&&t.push(e.classes),n=e.style.cssText!==""?' style="'+e.style+'"':"",'<li id="'+e.dom_id+'" class="'+t.join(" ")+'"'+n+">"+e.html+"</li>")},e.prototype.results_update_field=function(){return this.result_clear_highlight(),this.result_single_selected=null,this.results_build()},e.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},e.prototype.results_search=function(e){return this.results_showing?this.winnow_results():this.results_show()},e.prototype.keyup_checker=function(e){var t,n;t=(n=e.which)!=null?n:e.keyCode,this.search_field_scale();switch(t){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:e.preventDefault();if(this.results_showing)return this.result_select(e);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},e.prototype.generate_field_id=function(){var e;return e=this.generate_random_id(),this.form_field.id=e,e},e.prototype.generate_random_char=function(){var e,t,n;return e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ",n=Math.floor(Math.random()*e.length),t=e.substring(n,n+1)},e}(),t.AbstractChosen=e}.call(this),function(){var e,t,n,r={}.hasOwnProperty,i=function(e,t){function i(){this.constructor=e}for(var n in t)r.call(t,n)&&(e[n]=t[n]);return i.prototype=t.prototype,e.prototype=new i,e.__super__=t.prototype,e};n=this,e=function(e){function r(){return r.__super__.constructor.apply(this,arguments)}return i(r,e),r.prototype.setup=function(){return this.is_rtl=this.form_field.hasClassName("chzn-rtl")},r.prototype.finish_setup=function(){return this.form_field.addClassName("chzn-done")},r.prototype.set_default_values=function(){return r.__super__.set_default_values.call(this),this.single_temp=new Template('<a href="javascript:void(0)" class="chzn-single chzn-default"><span>#{default}</span><div><b></b></div></a><div class="chzn-drop" style="left:-9000px;"><div class="chzn-search"><input type="text" autocomplete="off" /></div><ul class="chzn-results"></ul></div>'),this.multi_temp=new Template('<ul class="chzn-choices"><li class="search-field"><input type="text" value="#{default}" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>'),this.choice_temp=new Template('<li class="search-choice" id="#{id}"><span>#{choice}</span><a href="javascript:void(0)" class="search-choice-close" rel="#{position}"></a></li>'),this.no_results_temp=new Template('<li class="no-results">'+this.results_none_found+' "<span>#{terms}</span>"</li>')},r.prototype.set_up_html=function(){var e,n,r,i,s;return this.container_id=this.form_field.identify().replace(/(:|\.)/g,"_")+"_chzn",this.f_width=this.form_field.getStyle("width")?parseInt(this.form_field.getStyle("width"),10):this.form_field.getWidth(),n={id:this.container_id,"class":"chzn-container"+(this.is_rtl?" chzn-rtl":""),style:"width: "+this.f_width+"px"},this.default_text=this.form_field.readAttribute("data-placeholder")?this.form_field.readAttribute("data-placeholder"):this.default_text_default,e=this.is_multiple?(new Element("div",n)).update(this.multi_temp.evaluate({"default":this.default_text})):(new Element("div",n)).update(this.single_temp.evaluate({"default":this.default_text})),this.form_field.hide().insert({after:e}),this.container=$(this.container_id),this.container.addClassName("chzn-container-"+(this.is_multiple?"multi":"single")),this.dropdown=this.container.down("div.chzn-drop"),r=this.container.getHeight(),i=this.f_width-t(this.dropdown),this.dropdown.setStyle({width:i+"px",top:r+"px"}),this.search_field=this.container.down("input"),this.search_results=this.container.down("ul.chzn-results"),this.search_field_scale(),this.search_no_results=this.container.down("li.no-results"),this.is_multiple?(this.search_choices=this.container.down("ul.chzn-choices"),this.search_container=this.container.down("li.search-field")):(this.search_container=this.container.down("div.chzn-search"),this.selected_item=this.container.down(".chzn-single"),s=i-t(this.search_container)-t(this.search_field),this.search_field.setStyle({width:s+"px"})),this.results_build(),this.set_tab_index(),this.form_field.fire("liszt:ready",{chosen:this})},r.prototype.register_observers=function(){var e=this;return this.container.observe("mousedown",function(t){return e.container_mousedown(t)}),this.container.observe("mouseup",function(t){return e.container_mouseup(t)}),this.container.observe("mouseenter",function(t){return e.mouse_enter(t)}),this.container.observe("mouseleave",function(t){return e.mouse_leave(t)}),this.search_results.observe("mouseup",function(t){return e.search_results_mouseup(t)}),this.search_results.observe("mouseover",function(t){return e.search_results_mouseover(t)}),this.search_results.observe("mouseout",function(t){return e.search_results_mouseout(t)}),this.form_field.observe("liszt:updated",function(t){return e.results_update_field(t)}),this.search_field.observe("blur",function(t){return e.input_blur(t)}),this.search_field.observe("keyup",function(t){return e.keyup_checker(t)}),this.search_field.observe("keydown",function(t){return e.keydown_checker(t)}),this.is_multiple?(this.search_choices.observe("click",function(t){return e.choices_click(t)}),this.search_field.observe("focus",function(t){return e.input_focus(t)})):this.container.observe("click",function(e){return e.preventDefault()})},r.prototype.search_field_disabled=function(){this.is_disabled=this.form_field.disabled;if(this.is_disabled)return this.container.addClassName("chzn-disabled"),this.search_field.disabled=!0,this.is_multiple||this.selected_item.stopObserving("focus",this.activate_action),this.close_field();this.container.removeClassName("chzn-disabled"),this.search_field.disabled=!1;if(!this.is_multiple)return this.selected_item.observe("focus",this.activate_action)},r.prototype.container_mousedown=function(e){var t;if(!this.is_disabled)return t=e!=null?e.target.hasClassName("search-choice-close"):!1,e&&e.type==="mousedown"&&!this.results_showing&&e.stop(),!this.pending_destroy_click&&!t?(this.active_field?!this.is_multiple&&e&&(e.target===this.selected_item||e.target.up("a.chzn-single"))&&this.results_toggle():(this.is_multiple&&this.search_field.clear(),document.observe("click",this.click_test_action),this.results_show()),this.activate_field()):this.pending_destroy_click=!1},r.prototype.container_mouseup=function(e){if(e.target.nodeName==="ABBR")return this.results_reset(e)},r.prototype.blur_test=function(e){if(!this.active_field&&this.container.hasClassName("chzn-container-active"))return this.close_field()},r.prototype.close_field=function(){return document.stopObserving("click",this.click_test_action),this.is_multiple||(this.selected_item.tabIndex=this.search_field.tabIndex,this.search_field.tabIndex=-1),this.active_field=!1,this.results_hide(),this.container.removeClassName("chzn-container-active"),this.winnow_results_clear(),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},r.prototype.activate_field=function(){return!this.is_multiple&&!this.active_field&&(this.search_field.tabIndex=this.selected_item.tabIndex,this.selected_item.tabIndex=-1),this.container.addClassName("chzn-container-active"),this.active_field=!0,this.search_field.value=this.search_field.value,this.search_field.focus()},r.prototype.test_active_click=function(e){return e.target.up("#"+this.container_id)?this.active_field=!0:this.close_field()},r.prototype.results_build=function(){var e,t,r,i,s;this.parsing=!0,this.results_data=n.SelectParser.select_to_array(this.form_field),this.is_multiple&&this.choices>0?(this.search_choices.select("li.search-choice").invoke("remove"),this.choices=0):this.is_multiple||(this.selected_item.down("span").update(this.default_text),this.form_field.options.length<=this.disable_search_threshold?this.container.addClassName("chzn-container-single-nosearch"):this.container.removeClassName("chzn-container-single-nosearch")),e="",s=this.results_data;for(r=0,i=s.length;r<i;r++)t=s[r],t.group?e+=this.result_add_group(t):t.empty||(e+=this.result_add_option(t),t.selected&&this.is_multiple?this.choice_build(t):t.selected&&!this.is_multiple&&(this.selected_item.removeClassName("chzn-default").down("span").update(t.html),this.allow_single_deselect&&this.single_deselect_control_build()));return this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.search_results.update(e),this.parsing=!1},r.prototype.result_add_group=function(e){return e.disabled?"":(e.dom_id=this.container_id+"_g_"+e.array_index,'<li id="'+e.dom_id+'" class="group-result">'+e.label.escapeHTML()+"</li>")},r.prototype.result_do_highlight=function(e){var t,n,r,i,s;this.result_clear_highlight(),this.result_highlight=e,this.result_highlight.addClassName("highlighted"),r=parseInt(this.search_results.getStyle("maxHeight"),10),s=this.search_results.scrollTop,i=r+s,n=this.result_highlight.positionedOffset().top,t=n+this.result_highlight.getHeight();if(t>=i)return this.search_results.scrollTop=t-r>0?t-r:0;if(n<s)return this.search_results.scrollTop=n},r.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClassName("highlighted"),this.result_highlight=null},r.prototype.results_show=function(){var e;return this.is_multiple||(this.selected_item.addClassName("chzn-single-with-drop"),this.result_single_selected&&this.result_do_highlight(this.result_single_selected)),e=this.is_multiple?this.container.getHeight():this.container.getHeight()-1,this.dropdown.setStyle({top:e+"px",left:0}),this.results_showing=!0,this.search_field.focus(),this.search_field.value=this.search_field.value,this.winnow_results()},r.prototype.results_hide=function(){return this.is_multiple||this.selected_item.removeClassName("chzn-single-with-drop"),this.result_clear_highlight(),this.dropdown.setStyle({left:"-9000px"}),this.results_showing=!1},r.prototype.set_tab_index=function(e){var t;if(this.form_field.tabIndex)return t=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.is_multiple?this.search_field.tabIndex=t:(this.selected_item.tabIndex=t,this.search_field.tabIndex=-1)},r.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices<1&&!this.active_field?(this.search_field.value=this.default_text,this.search_field.addClassName("default")):(this.search_field.value="",this.search_field.removeClassName("default"))},r.prototype.search_results_mouseup=function(e){var t;t=e.target.hasClassName("active-result")?e.target:e.target.up(".active-result");if(t)return this.result_highlight=t,this.result_select(e)},r.prototype.search_results_mouseover=function(e){var t;t=e.target.hasClassName("active-result")?e.target:e.target.up(".active-result");if(t)return this.result_do_highlight(t)},r.prototype.search_results_mouseout=function(e){if(e.target.hasClassName("active-result")||e.target.up(".active-result"))return this.result_clear_highlight()},r.prototype.choices_click=function(e){e.preventDefault();if(this.active_field&&!e.target.hasClassName("search-choice")&&!e.target.up(".search-choice")&&!this.results_showing)return this.results_show()},r.prototype.choice_build=function(e){var t,n,r=this;return t=this.container_id+"_c_"+e.array_index,this.choices+=1,this.search_container.insert({before:this.choice_temp.evaluate({id:t,choice:e.html,position:e.array_index})}),n=$(t).down("a"),n.observe("click",function(e){return r.choice_destroy_link_click(e)})},r.prototype.choice_destroy_link_click=function(e){e.preventDefault();if(!this.is_disabled)return this.pending_destroy_click=!0,this.choice_destroy(e.target)},r.prototype.choice_destroy=function(e){return this.choices-=1,this.show_search_field_default(),this.is_multiple&&this.choices>0&&this.search_field.value.length<1&&this.results_hide(),this.result_deselect(e.readAttribute("rel")),e.up("li").remove()},r.prototype.results_reset=function(e){this.form_field.options[0].selected=!0,this.selected_item.down("span").update(this.default_text),this.is_multiple||this.selected_item.addClassName("chzn-default"),this.show_search_field_default(),e.target.remove(),typeof Event.simulate=="function"&&this.form_field.simulate("change");if(this.active_field)return this.results_hide()},r.prototype.result_select=function(e){var t,n,r;if(this.result_highlight)return t=this.result_highlight,this.result_clear_highlight(),this.is_multiple?this.result_deactivate(t):(this.search_results.descendants(".result-selected").invoke("removeClassName","result-selected"),this.selected_item.removeClassName("chzn-default"),this.result_single_selected=t),t.addClassName("result-selected"),r=t.id.substr(t.id.lastIndexOf("_")+1),n=this.results_data[r],n.selected=!0,this.form_field.options[n.options_index].selected=!0,this.is_multiple?this.choice_build(n):(this.selected_item.down("span").update(n.html),this.allow_single_deselect&&this.single_deselect_control_build()),(!e.metaKey||!this.is_multiple)&&this.results_hide(),this.search_field.value="",typeof Event.simulate=="function"&&this.form_field.simulate("change"),this.search_field_scale()},r.prototype.result_activate=function(e){return e.addClassName("active-result")},r.prototype.result_deactivate=function(e){return e.removeClassName("active-result")},r.prototype.result_deselect=function(e){var t,n;return n=this.results_data[e],n.selected=!1,this.form_field.options[n.options_index].selected=!1,t=$(this.container_id+"_o_"+e),t.removeClassName("result-selected").addClassName("active-result").show(),this.result_clear_highlight(),this.winnow_results(),typeof Event.simulate=="function"&&this.form_field.simulate("change"),this.search_field_scale()},r.prototype.single_deselect_control_build=function(){if(this.allow_single_deselect&&!this.selected_item.down("abbr"))return this.selected_item.down("span").insert({after:'<abbr class="search-choice-close"></abbr>'})},r.prototype.winnow_results=function(){var e,t,n,r,i,s,o,u,a,f,l,c,h,p,d,v,m;this.no_results_clear(),u=0,a=this.search_field.value===this.default_text?"":this.search_field.value.strip().escapeHTML(),s=this.search_contains?"":"^",i=new RegExp(s+a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),c=new RegExp(a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),m=this.results_data;for(h=0,d=m.length;h<d;h++){t=m[h];if(!t.disabled&&!t.empty)if(t.group)$(t.dom_id).hide();else if(!this.is_multiple||!t.selected){e=!1,o=t.dom_id;if(i.test(t.html))e=!0,u+=1;else if(t.html.indexOf(" ")>=0||t.html.indexOf("[")===0){r=t.html.replace(/\[|\]/g,"").split(" ");if(r.length)for(p=0,v=r.length;p<v;p++)n=r[p],i.test(n)&&(e=!0,u+=1)}e?(a.length?(f=t.html.search(c),l=t.html.substr(0,f+a.length)+"</em>"+t.html.substr(f+a.length),l=l.substr(0,f)+"<em>"+l.substr(f)):l=t.html,$(o).innerHTML!==l&&$(o).update(l),this.result_activate($(o)),t.group_array_index!=null&&$(this.results_data[t.group_array_index].dom_id).setStyle({display:"list-item"})):($(o)===this.result_highlight&&this.result_clear_highlight(),this.result_deactivate($(o)))}}return u<1&&a.length?this.no_results(a):this.winnow_results_set_highlight()},r.prototype.winnow_results_clear=function(){var e,t,n,r,i;this.search_field.clear(),t=this.search_results.select("li"),i=[];for(n=0,r=t.length;n<r;n++)e=t[n],e.hasClassName("group-result")?i.push(e.show()):!this.is_multiple||!e.hasClassName("result-selected")?i.push(this.result_activate(e)):i.push(void 0);return i},r.prototype.winnow_results_set_highlight=function(){var e;if(!this.result_highlight){this.is_multiple||(e=this.search_results.down(".result-selected.active-result")),e==null&&(e=this.search_results.down(".active-result"));if(e!=null)return this.result_do_highlight(e)}},r.prototype.no_results=function(e){return this.search_results.insert(this.no_results_temp.evaluate({terms:e}))},r.prototype.no_results_clear=function(){var e,t;e=null,t=[];while(e=this.search_results.down(".no-results"))t.push(e.remove());return t},r.prototype.keydown_arrow=function(){var e,t,n;e=this.search_results.select("li.active-result");if(e.length){this.result_highlight?this.results_showing&&(n=this.result_highlight.nextSiblings(),t=n.intersect(e),t.length&&this.result_do_highlight(t.first())):this.result_do_highlight(e.first());if(!this.results_showing)return this.results_show()}},r.prototype.keyup_arrow=function(){var e,t,n;if(!this.results_showing&&!this.is_multiple)return this.results_show();if(this.result_highlight)return n=this.result_highlight.previousSiblings(),e=this.search_results.select("li.active-result"),t=n.intersect(e),t.length?this.result_do_highlight(t.first()):(this.choices>0&&this.results_hide(),this.result_clear_highlight())},r.prototype.keydown_backstroke=function(){return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.down("a")),this.clear_backstroke()):(this.pending_backstroke=this.search_container.siblings("li.search-choice").last(),this.pending_backstroke.addClassName("search-choice-focus"))},r.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClassName("search-choice-focus"),this.pending_backstroke=null},r.prototype.keydown_checker=function(e){var t,n;t=(n=e.which)!=null?n:e.keyCode,this.search_field_scale(),t!==8&&this.pending_backstroke&&this.clear_backstroke();switch(t){case 8:this.backstroke_length=this.search_field.value.length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(e),this.mouse_on_container=!1;break;case 13:e.preventDefault();break;case 38:e.preventDefault(),this.keyup_arrow();break;case 40:this.keydown_arrow()}},r.prototype.search_field_scale=function(){var e,t,n,r,i,s,o,u,a;if(this.is_multiple){n=0,o=0,i="position:absolute; left: -1000px; top: -1000px; display:none;",s=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"];for(u=0,a=s.length;u<a;u++)r=s[u],i+=r+":"+this.search_field.getStyle(r)+";";return t=(new Element("div",{style:i})).update(this.search_field.value.escapeHTML()),document.body.appendChild(t),o=Element.measure(t,"width")+25,t.remove(),o>this.f_width-10&&(o=this.f_width-10),this.search_field.setStyle({width:o+"px"}),e=this.container.getHeight(),this.dropdown.setStyle({top:e+"px"})}},r}(AbstractChosen),n.Chosen=e,Prototype.Browser.IE&&/MSIE (\d+\.\d+);/.test(navigator.userAgent)&&(Prototype.BrowserFeatures.Version=new Number(RegExp.$1)),t=function(e){var t,n;return t=new Element.Layout(e),n=t.get("border-left")+t.get("border-right")+t.get("padding-left")+t.get("padding-right")},n.get_side_border_padding=t}.call(this);

View File

@ -60,7 +60,7 @@ class Chosen extends AbstractChosen
dd_top = if rise then -this.container.find('.chzn-drop').height() else @container.height() dd_top = if rise then -this.container.find('.chzn-drop').height() else @container.height()
#patch applied: https://github.com/harvesthq/chosen/issues/300 #patch applied: https://github.com/harvesthq/chosen/issues/300
dd_width = (@container.width - get_side_border_padding(@dropdown)) dd_width = (@container.width() - get_side_border_padding(@dropdown))
@dropdown.css({"width": dd_width + "px", "top": dd_top + "px"}) @dropdown.css({"width": dd_width + "px", "top": dd_top + "px"})

View File

@ -144,6 +144,7 @@ class RSSFeed extends ViewableData {
*/ */
function Entries() { function Entries() {
$output = new ArrayList(); $output = new ArrayList();
if(isset($this->entries)) { if(isset($this->entries)) {
foreach($this->entries as $entry) { foreach($this->entries as $entry) {
$output->push(new RSSFeed_Entry($entry, $this->titleField, $this->descriptionField, $this->authorField)); $output->push(new RSSFeed_Entry($entry, $this->titleField, $this->descriptionField, $this->authorField));
@ -183,7 +184,10 @@ class RSSFeed extends ViewableData {
/** /**
* Output the feed to the browser * Output the feed to the browser
*/ */
function outputToBrowser() { public function outputToBrowser() {
$prevState = SSViewer::get_source_file_comments();
SSViewer::set_source_file_comments(false);
if(is_int($this->lastModified)) { if(is_int($this->lastModified)) {
HTTP::register_modification_timestamp($this->lastModified); HTTP::register_modification_timestamp($this->lastModified);
header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $this->lastModified) . ' GMT'); header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $this->lastModified) . ' GMT');
@ -192,26 +196,14 @@ class RSSFeed extends ViewableData {
HTTP::register_etag($this->etag); HTTP::register_etag($this->etag);
} }
$body = $this->feedContent(); if(!headers_sent()) {
HTTP::add_cache_headers(); HTTP::add_cache_headers();
header("Content-type: text/xml"); header("Content-type: text/xml");
echo $body; }
}
/**
* Return the content of the RSS feed.
*
* Also temporarily disabled source file comments, and restores
* to previous state once content has been rendered.
*
* @return string
*/
function feedContent() {
$prevState = SSViewer::get_source_file_comments();
SSViewer::set_source_file_comments(false);
$content = str_replace('&nbsp;', '&#160;', $this->renderWith($this->getTemplate()));
SSViewer::set_source_file_comments($prevState); SSViewer::set_source_file_comments($prevState);
return $content;
return $this->renderWith($this->getTemplate());
} }
/** /**

View File

@ -561,24 +561,29 @@ class Director implements TemplateGlobalProvider {
* @return boolean * @return boolean
*/ */
public static function is_absolute_url($url) { public static function is_absolute_url($url) {
// Strip off the query and fragment parts of the URL before checking
if(($queryPosition = strpos($url, '?')) !== false) {
$url = substr($url, 0, $queryPosition-1);
}
if(($hashPosition = strpos($url, '#')) !== false) {
$url = substr($url, 0, $hashPosition-1);
}
$colonPosition = strpos($url, ':'); $colonPosition = strpos($url, ':');
return ( $slashPosition = strpos($url, '/');
// Base check for existence of a host on a compliant URL return (
parse_url($url, PHP_URL_HOST) // Base check for existence of a host on a compliant URL
// Check for more than one leading slash without a protocol. parse_url($url, PHP_URL_HOST)
// Check for more than one leading slash without a protocol.
// While not a RFC compliant absolute URL, it is completed to a valid URL by some browsers, // While not a RFC compliant absolute URL, it is completed to a valid URL by some browsers,
// and hence a potential security risk. Single leading slashes are not an issue though. // and hence a potential security risk. Single leading slashes are not an issue though.
|| preg_match('/\s*[\/]{2,}/', $url) || preg_match('/\s*[\/]{2,}/', $url)
|| ( || (
// If a colon is found, check if it's part of a valid scheme definition // If a colon is found, check if it's part of a valid scheme definition
// (meaning its not preceded by a slash, hash or questionmark). // (meaning its not preceded by a slash).
// URLs in query parameters are assumed to be correctly urlencoded based on RFC3986, $colonPosition !== FALSE
// in which case no colon should be present in the parameters. && ($slashPosition === FALSE || $colonPosition < $slashPosition)
$colonPosition !== FALSE )
&& !preg_match('![/?#]!', substr($url, 0, $colonPosition)) );
)
);
} }
/** /**

View File

@ -22,6 +22,7 @@ body.cms.ss-uploadfield-edit-iframe .fieldholder-small label, .composite.ss-asse
.ss-assetuploadfield .ss-uploadfield-files .ss-uploadfield-item-preview { position: absolute; height: 30px; width: 40px; overflow: hidden; z-index: 1; } .ss-assetuploadfield .ss-uploadfield-files .ss-uploadfield-item-preview { position: absolute; height: 30px; width: 40px; overflow: hidden; z-index: 1; }
.ss-assetuploadfield .ss-uploadfield-files .ss-uploadfield-item-preview .no-preview { display: block; height: 100%; width: 100%; background: url("../images/icons/document.png") 2px 0px no-repeat; } .ss-assetuploadfield .ss-uploadfield-files .ss-uploadfield-item-preview .no-preview { display: block; height: 100%; width: 100%; background: url("../images/icons/document.png") 2px 0px no-repeat; }
.ss-assetuploadfield .ss-uploadfield-files .ss-uploadfield-item-info { position: relative; height: 30px; overflow: hidden; background-color: #5db4df; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #5db4df), color-stop(8%, #5db1dd), color-stop(50%, #439bcb), color-stop(54%, #3f99cd), color-stop(96%, #207db6), color-stop(100%, #1e7cba)); background-image: -webkit-linear-gradient(top, #5db4df 0%, #5db1dd 8%, #439bcb 50%, #3f99cd 54%, #207db6 96%, #1e7cba 100%); background-image: -moz-linear-gradient(top, #5db4df 0%, #5db1dd 8%, #439bcb 50%, #3f99cd 54%, #207db6 96%, #1e7cba 100%); background-image: -o-linear-gradient(top, #5db4df 0%, #5db1dd 8%, #439bcb 50%, #3f99cd 54%, #207db6 96%, #1e7cba 100%); background-image: -ms-linear-gradient(top, #5db4df 0%, #5db1dd 8%, #439bcb 50%, #3f99cd 54%, #207db6 96%, #1e7cba 100%); background-image: linear-gradient(top, #5db4df 0%, #5db1dd 8%, #439bcb 50%, #3f99cd 54%, #207db6 96%, #1e7cba 100%); } .ss-assetuploadfield .ss-uploadfield-files .ss-uploadfield-item-info { position: relative; height: 30px; overflow: hidden; background-color: #5db4df; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #5db4df), color-stop(8%, #5db1dd), color-stop(50%, #439bcb), color-stop(54%, #3f99cd), color-stop(96%, #207db6), color-stop(100%, #1e7cba)); background-image: -webkit-linear-gradient(top, #5db4df 0%, #5db1dd 8%, #439bcb 50%, #3f99cd 54%, #207db6 96%, #1e7cba 100%); background-image: -moz-linear-gradient(top, #5db4df 0%, #5db1dd 8%, #439bcb 50%, #3f99cd 54%, #207db6 96%, #1e7cba 100%); background-image: -o-linear-gradient(top, #5db4df 0%, #5db1dd 8%, #439bcb 50%, #3f99cd 54%, #207db6 96%, #1e7cba 100%); background-image: -ms-linear-gradient(top, #5db4df 0%, #5db1dd 8%, #439bcb 50%, #3f99cd 54%, #207db6 96%, #1e7cba 100%); background-image: linear-gradient(top, #5db4df 0%, #5db1dd 8%, #439bcb 50%, #3f99cd 54%, #207db6 96%, #1e7cba 100%); }
.ss-assetuploadfield .ss-uploadfield-files .ss-uploadfield-item .info { position: relative; padding: 7px; overflow: hidden; background-color: #FFBE66; border: 1px solid #FF9300; }
.ss-assetuploadfield .ss-uploadfield-files .ui-state-error .ss-uploadfield-item-info { background-color: #c11f1d; padding-right: 130px; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #c11f1d), color-stop(4%, #bf1d1b), color-stop(8%, #b71b1c), color-stop(15%, #b61e1d), color-stop(27%, #b11d1d), color-stop(31%, #ab1d1c), color-stop(42%, #a51b1b), color-stop(46%, #9f1b19), color-stop(50%, #9f1b19), color-stop(54%, #991c1a), color-stop(58%, #971a18), color-stop(62%, #911b1b), color-stop(65%, #911b1b), color-stop(88%, #7e1816), color-stop(92%, #771919), color-stop(100%, #731817)); background-image: -webkit-linear-gradient(top, #c11f1d 0%, #bf1d1b 4%, #b71b1c 8%, #b61e1d 15%, #b11d1d 27%, #ab1d1c 31%, #a51b1b 42%, #9f1b19 46%, #9f1b19 50%, #991c1a 54%, #971a18 58%, #911b1b 62%, #911b1b 65%, #7e1816 88%, #771919 92%, #731817 100%); background-image: -moz-linear-gradient(top, #c11f1d 0%, #bf1d1b 4%, #b71b1c 8%, #b61e1d 15%, #b11d1d 27%, #ab1d1c 31%, #a51b1b 42%, #9f1b19 46%, #9f1b19 50%, #991c1a 54%, #971a18 58%, #911b1b 62%, #911b1b 65%, #7e1816 88%, #771919 92%, #731817 100%); background-image: -o-linear-gradient(top, #c11f1d 0%, #bf1d1b 4%, #b71b1c 8%, #b61e1d 15%, #b11d1d 27%, #ab1d1c 31%, #a51b1b 42%, #9f1b19 46%, #9f1b19 50%, #991c1a 54%, #971a18 58%, #911b1b 62%, #911b1b 65%, #7e1816 88%, #771919 92%, #731817 100%); background-image: -ms-linear-gradient(top, #c11f1d 0%, #bf1d1b 4%, #b71b1c 8%, #b61e1d 15%, #b11d1d 27%, #ab1d1c 31%, #a51b1b 42%, #9f1b19 46%, #9f1b19 50%, #991c1a 54%, #971a18 58%, #911b1b 62%, #911b1b 65%, #7e1816 88%, #771919 92%, #731817 100%); background-image: linear-gradient(top, #c11f1d 0%, #bf1d1b 4%, #b71b1c 8%, #b61e1d 15%, #b11d1d 27%, #ab1d1c 31%, #a51b1b 42%, #9f1b19 46%, #9f1b19 50%, #991c1a 54%, #971a18 58%, #911b1b 62%, #911b1b 65%, #7e1816 88%, #771919 92%, #731817 100%); } .ss-assetuploadfield .ss-uploadfield-files .ui-state-error .ss-uploadfield-item-info { background-color: #c11f1d; padding-right: 130px; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #c11f1d), color-stop(4%, #bf1d1b), color-stop(8%, #b71b1c), color-stop(15%, #b61e1d), color-stop(27%, #b11d1d), color-stop(31%, #ab1d1c), color-stop(42%, #a51b1b), color-stop(46%, #9f1b19), color-stop(50%, #9f1b19), color-stop(54%, #991c1a), color-stop(58%, #971a18), color-stop(62%, #911b1b), color-stop(65%, #911b1b), color-stop(88%, #7e1816), color-stop(92%, #771919), color-stop(100%, #731817)); background-image: -webkit-linear-gradient(top, #c11f1d 0%, #bf1d1b 4%, #b71b1c 8%, #b61e1d 15%, #b11d1d 27%, #ab1d1c 31%, #a51b1b 42%, #9f1b19 46%, #9f1b19 50%, #991c1a 54%, #971a18 58%, #911b1b 62%, #911b1b 65%, #7e1816 88%, #771919 92%, #731817 100%); background-image: -moz-linear-gradient(top, #c11f1d 0%, #bf1d1b 4%, #b71b1c 8%, #b61e1d 15%, #b11d1d 27%, #ab1d1c 31%, #a51b1b 42%, #9f1b19 46%, #9f1b19 50%, #991c1a 54%, #971a18 58%, #911b1b 62%, #911b1b 65%, #7e1816 88%, #771919 92%, #731817 100%); background-image: -o-linear-gradient(top, #c11f1d 0%, #bf1d1b 4%, #b71b1c 8%, #b61e1d 15%, #b11d1d 27%, #ab1d1c 31%, #a51b1b 42%, #9f1b19 46%, #9f1b19 50%, #991c1a 54%, #971a18 58%, #911b1b 62%, #911b1b 65%, #7e1816 88%, #771919 92%, #731817 100%); background-image: -ms-linear-gradient(top, #c11f1d 0%, #bf1d1b 4%, #b71b1c 8%, #b61e1d 15%, #b11d1d 27%, #ab1d1c 31%, #a51b1b 42%, #9f1b19 46%, #9f1b19 50%, #991c1a 54%, #971a18 58%, #911b1b 62%, #911b1b 65%, #7e1816 88%, #771919 92%, #731817 100%); background-image: linear-gradient(top, #c11f1d 0%, #bf1d1b 4%, #b71b1c 8%, #b61e1d 15%, #b11d1d 27%, #ab1d1c 31%, #a51b1b 42%, #9f1b19 46%, #9f1b19 50%, #991c1a 54%, #971a18 58%, #911b1b 62%, #911b1b 65%, #7e1816 88%, #771919 92%, #731817 100%); }
.ss-assetuploadfield .ss-uploadfield-files .ui-state-error .ss-uploadfield-item-info .ss-uploadfield-item-name { width: 100%; cursor: default; background: #bcb9b9; background: rgba(201, 198, 198, 0.9); } .ss-assetuploadfield .ss-uploadfield-files .ui-state-error .ss-uploadfield-item-info .ss-uploadfield-item-name { width: 100%; cursor: default; background: #bcb9b9; background: rgba(201, 198, 198, 0.9); }
.ss-assetuploadfield .ss-uploadfield-files .ui-state-error .ss-uploadfield-item-info .ss-uploadfield-item-name .name { text-shadow: 0px 1px 0px rgba(255, 255, 255, 0.7); } .ss-assetuploadfield .ss-uploadfield-files .ui-state-error .ss-uploadfield-item-info .ss-uploadfield-item-name .name { text-shadow: 0px 1px 0px rgba(255, 255, 255, 0.7); }

View File

@ -4,7 +4,7 @@ div.TreeDropdownField .treedropdownfield-title { float: left; padding: 7px; widt
div.TreeDropdownField .treedropdownfield-panel { clear: left; position: absolute; overflow: auto; display: none; cursor: default; border: 1px solid #aaa; border-top: none; margin: 1px 0 0 -1px; /* account for border on container div */ max-height: 200px; background-color: #fff; z-index: 50; -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); -o-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); } div.TreeDropdownField .treedropdownfield-panel { clear: left; position: absolute; overflow: auto; display: none; cursor: default; border: 1px solid #aaa; border-top: none; margin: 1px 0 0 -1px; /* account for border on container div */ max-height: 200px; background-color: #fff; z-index: 50; -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); -o-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); }
div.TreeDropdownField .treedropdownfield-panel ul.tree { margin: 0; } div.TreeDropdownField .treedropdownfield-panel ul.tree { margin: 0; }
div.TreeDropdownField .treedropdownfield-panel ul.tree a { font-size: 12px; } div.TreeDropdownField .treedropdownfield-panel ul.tree a { font-size: 12px; }
div.TreeDropdownField .treedropdownfield-toggle-panel-link { border: none; margin: 0; z-index: 0; padding: 7px 3px; float: right; overflow: hidden; -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0; -moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box; background: #ccc; background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #cccccc), color-stop(0.6, #eeeeee)); background-image: -webkit-linear-gradient(center bottom, #cccccc 0%, #eeeeee 60%); background-image: -moz-linear-gradient(center bottom, #cccccc 0%, #eeeeee 60%); background-image: -o-linear-gradient(bottom, #cccccc 0%, #eeeeee 60%); background-image: -ms-linear-gradient(top, #cccccc 0%, #eeeeee 60%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#eeeeee',GradientType=0 ); background-image: linear-gradient(top, #cccccc 0%, #eeeeee 60%); border-left: 1px solid #aaa; } div.TreeDropdownField .treedropdownfield-toggle-panel-link { border: none; margin: 0; z-index: 0; padding: 7px 3px; overflow: hidden; -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0; -moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box; background: #ccc; background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #cccccc), color-stop(0.6, #eeeeee)); background-image: -webkit-linear-gradient(center bottom, #cccccc 0%, #eeeeee 60%); background-image: -moz-linear-gradient(center bottom, #cccccc 0%, #eeeeee 60%); background-image: -o-linear-gradient(bottom, #cccccc 0%, #eeeeee 60%); background-image: -ms-linear-gradient(top, #cccccc 0%, #eeeeee 60%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#eeeeee',GradientType=0 ); background-image: linear-gradient(top, #cccccc 0%, #eeeeee 60%); border-left: 1px solid #aaa; }
div.TreeDropdownField .treedropdownfield-toggle-panel-link.treedropdownfield-open-tree { background: transparent; border: none; } div.TreeDropdownField .treedropdownfield-toggle-panel-link.treedropdownfield-open-tree { background: transparent; border: none; }
div.TreeDropdownField .treedropdownfield-toggle-panel-link a { text-decoration: none; display: block; border: 0; margin: 0; opacity: 0.5; } div.TreeDropdownField .treedropdownfield-toggle-panel-link a { text-decoration: none; display: block; border: 0; margin: 0; opacity: 0.5; }
div.TreeDropdownField .loading, div.TreeDropdownField .jstree-themeroller a.jstree-loading .jstree-icon { background: white url("../images/network-save.gif") center center no-repeat !important; } div.TreeDropdownField .loading, div.TreeDropdownField .jstree-themeroller a.jstree-loading .jstree-icon { background: white url("../images/network-save.gif") center center no-repeat !important; }

View File

@ -416,7 +416,6 @@ class Debug {
} }
$reporter->writeTrace(($errcontext ? $errcontext : debug_backtrace())); $reporter->writeTrace(($errcontext ? $errcontext : debug_backtrace()));
$reporter->writeFooter(); $reporter->writeFooter();
exit(1);
} }
/** /**

View File

@ -984,6 +984,7 @@ class Installer extends InstallRequirements {
?> ?>
<html> <html>
<head> <head>
<meta charset="utf-8" />
<title>Installing SilverStripe...</title> <title>Installing SilverStripe...</title>
<link rel="stylesheet" type="text/css" href="<?php echo FRAMEWORK_NAME; ?>/dev/install/css/install.css" /> <link rel="stylesheet" type="text/css" href="<?php echo FRAMEWORK_NAME; ?>/dev/install/css/install.css" />
<script src="<?php echo FRAMEWORK_NAME; ?>/thirdparty/jquery/jquery.js"></script> <script src="<?php echo FRAMEWORK_NAME; ?>/thirdparty/jquery/jquery.js"></script>
@ -1352,7 +1353,8 @@ TEXT;
method: 'get', method: 'get',
url: 'InstallerTest/testrewrite', url: 'InstallerTest/testrewrite',
complete: function(response) { complete: function(response) {
if(response.responseText == 'OK') { var r = response.responseText.replace(/[^A-Z]?/g,"");
if(r === "OK") {
$('#ModRewriteResult').html("Friendly URLs set up successfully; I am now redirecting you to your SilverStripe site...") $('#ModRewriteResult').html("Friendly URLs set up successfully; I am now redirecting you to your SilverStripe site...")
setTimeout(function() { setTimeout(function() {
window.location = "$destinationURL"; window.location = "$destinationURL";

View File

@ -127,6 +127,10 @@ in jQuery.entwine, we're trying to reuse library code wherever possible.
The most prominent example of this is the usage of [jQuery UI](http://jqueryui.com) for The most prominent example of this is the usage of [jQuery UI](http://jqueryui.com) for
dialogs and buttons. dialogs and buttons.
The CMS includes the jQuery.entwine inspector. Press Ctrl+` to bring down the inspector.
You can then click on any element in the CMS to see which entwine methods are bound to
any particular element.
## JavaScript and CSS dependencies via Requirements and Ajax ## JavaScript and CSS dependencies via Requirements and Ajax
The JavaScript logic powering the CMS is divided into many files, The JavaScript logic powering the CMS is divided into many files,

View File

@ -222,6 +222,9 @@ This is a deliberately simple example, the strength of jQuery.entwine over simpl
properties, namespacing, as well as its inheritance based on CSS selectors. Please see the [project properties, namespacing, as well as its inheritance based on CSS selectors. Please see the [project
documentation](http://github.com/hafriedlander/jquery.entwine/tree/master) for more complete examples. documentation](http://github.com/hafriedlander/jquery.entwine/tree/master) for more complete examples.
When working in the CMS, the CMS includes the jQuery.entwine inspector. Press Ctrl+` to bring down the inspector.
You can then click on any element in the CMS to see which entwine methods are bound to any particular element.
## Architecture and Best Practices ## Architecture and Best Practices
### Keep things simple ### Keep things simple

View File

@ -57,5 +57,10 @@ class GroupedDropdownField extends DropdownField {
return $this->createTag('select', $this->getAttributes(), $options); return $this->createTag('select', $this->getAttributes(), $options);
} }
function Type() {
return 'groupeddropdown dropdown';
}
} }

View File

@ -761,7 +761,7 @@ class HtmlEditorField_Toolbar extends RequestHandler {
* @return Array All extensions which can be handled by the different views. * @return Array All extensions which can be handled by the different views.
*/ */
protected function getAllowedExtensions() { protected function getAllowedExtensions() {
$exts = array('jpg', 'gif', 'png', 'swf'); $exts = array('jpg', 'gif', 'png', 'swf','jpeg');
$this->extend('updateAllowedExtensions', $exts); $this->extend('updateAllowedExtensions', $exts);
return $exts; return $exts;
} }
@ -896,6 +896,10 @@ class HtmlEditorField_Embed extends HtmlEditorField_File {
public function appCategory() { public function appCategory() {
return 'embed'; return 'embed';
} }
public function getInfo() {
return $this->oembed->info;
}
} }
class HtmlEditorField_Image extends HtmlEditorField_File { class HtmlEditorField_Image extends HtmlEditorField_File {

View File

@ -925,6 +925,7 @@ class i18n extends Object implements TemplateGlobalProvider {
'ko_KP' => 'ko', 'ko_KP' => 'ko',
'ko_KR' => 'ko', 'ko_KR' => 'ko',
'ko_CN' => 'ko', 'ko_CN' => 'ko',
'mi_NZ' => 'mi_NZ',
'nb_NO' => 'nb', 'nb_NO' => 'nb',
'nb_SJ' => 'nb', 'nb_SJ' => 'nb',
'nl_AN' => 'nl', 'nl_AN' => 'nl',

View File

@ -193,11 +193,13 @@
'data': this.getPanel().find('.tree-holder').html(), 'data': this.getPanel().find('.tree-holder').html(),
'ajax': { 'ajax': {
'url': function(node) { 'url': function(node) {
return self.data('urlTree') + '/' + ($(node).data("id") ? $(node).data("id") : 0); var url = $.path.parseUrl(self.data('urlTree')).hrefNoSearch;
return url + '/' + ($(node).data("id") ? $(node).data("id") : 0);
}, },
'data': function(node) { 'data': function(node) {
var query = $.query.load(self.data('urlTree')).keys;
var params = self.getRequestParams(); var params = self.getRequestParams();
params = $.extend({}, params, {ajax: 1}); params = $.extend({}, query, params, {ajax: 1});
return params; return params;
} }
} }
@ -262,7 +264,7 @@
onadd: function() { onadd: function() {
this._super(); this._super();
var title = this.data('title'); var title = decodeURIComponent(this.data('title'));
this.find('.treedropdownfield-title').replaceWith( this.find('.treedropdownfield-title').replaceWith(
$('<input type="text" class="treedropdownfield-title search" />') $('<input type="text" class="treedropdownfield-title search" />')
); );

View File

@ -330,6 +330,7 @@ en:
BUTTONLOSTPASSWORD: 'I''ve lost my password' BUTTONLOSTPASSWORD: 'I''ve lost my password'
CONFIRMNEWPASSWORD: 'Confirm New Password' CONFIRMNEWPASSWORD: 'Confirm New Password'
CONFIRMPASSWORD: 'Confirm Password' CONFIRMPASSWORD: 'Confirm Password'
DATEFORMAT: 'Date format'
DefaultAdminFirstname: 'Default Admin' DefaultAdminFirstname: 'Default Admin'
DefaultDateTime: default DefaultDateTime: default
EMAIL: Email EMAIL: Email
@ -352,6 +353,7 @@ en:
SUBJECTPASSWORDCHANGED: 'Your password has been changed' SUBJECTPASSWORDCHANGED: 'Your password has been changed'
SUBJECTPASSWORDRESET: 'Your password reset link' SUBJECTPASSWORDRESET: 'Your password reset link'
SURNAME: Surname SURNAME: Surname
TIMEFORMAT: 'Time format'
VALIDATIONMEMBEREXISTS: 'A member already exists with the same %s' VALIDATIONMEMBEREXISTS: 'A member already exists with the same %s'
ValidationIdentifierFailed: 'Can''t overwrite existing member #{id} with identical identifier ({name} = {value}))' ValidationIdentifierFailed: 'Can''t overwrite existing member #{id} with identical identifier ({name} = {value}))'
WELCOMEBACK: 'Welcome Back, {firstname}' WELCOMEBACK: 'Welcome Back, {firstname}'
@ -546,5 +548,6 @@ en:
STARTALL: 'Start all' STARTALL: 'Start all'
STARTALLINFO: 'Start all uploads' STARTALLINFO: 'Start all uploads'
Saved: Saved Saved: Saved
HOTLINKINFO: Info: This image will be hotlinked. Please ensure you have permissions from the original site creator to do so.
Versioned: Versioned:
has_many_Versions: Versions has_many_Versions: Versions

View File

@ -545,5 +545,6 @@ en_GB:
STARTALL: 'Start all' STARTALL: 'Start all'
STARTALLINFO: 'Start all uploads' STARTALLINFO: 'Start all uploads'
Saved: Saved Saved: Saved
HOTLINKINFO: Info: This image will be hotlinked. Please ensure you have permissions from the original site creator to do so.
Versioned: Versioned:
has_many_Versions: Versions has_many_Versions: Versions

View File

@ -3177,14 +3177,23 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
*/ */
public function defaultSearchFilters() { public function defaultSearchFilters() {
$filters = array(); $filters = array();
foreach($this->searchableFields() as $name => $spec) { foreach($this->searchableFields() as $name => $spec) {
$filterClass = $spec['filter']; $filterClass = $spec['filter'];
// if $filterClass is not set a name of any subclass of SearchFilter than assing 'PartiailMatchFilter' to it
if (!is_subclass_of($filterClass, 'SearchFilter')) { if($spec['filter'] instanceof SearchFilter) {
$filterClass = 'PartialMatchFilter'; $filters[$name] = $spec['filter'];
} else {
$class = $spec['filter'];
if(!is_subclass_of($spec['filter'], 'SearchFilter')) {
$class = 'PartialMatchFilter';
}
$filters[$name] = new $class($name);
} }
$filters[$name] = new $filterClass($name);
} }
return $filters; return $filters;
} }

View File

@ -227,7 +227,7 @@ class DataQuery {
// TODO: Versioned, Translatable, SiteTreeSubsites, etc, could probably be better implemented as subclasses of DataQuery // TODO: Versioned, Translatable, SiteTreeSubsites, etc, could probably be better implemented as subclasses of DataQuery
$obj = Injector::inst()->get(ClassInfo::baseDataClass($this->dataClass)); $obj = Injector::inst()->get($this->dataClass);
$obj->extend('augmentSQL', $query, $this); $obj->extend('augmentSQL', $query, $this);
$this->ensureSelectContainsOrderbyColumns($query); $this->ensureSelectContainsOrderbyColumns($query);

View File

@ -145,7 +145,8 @@ class Versioned extends DataExtension {
$date = $dataQuery->getQueryParam('Versioned.date'); $date = $dataQuery->getQueryParam('Versioned.date');
foreach($query->getFrom() as $table => $dummy) { foreach($query->getFrom() as $table => $dummy) {
$query->renameTable($table, $table . '_versions'); $query->renameTable($table, $table . '_versions');
$query->replaceText("\"$table\".\"ID\"", "\"$table\".\"RecordID\""); $query->replaceText("\"{$table}_versions\".\"ID\"", "\"{$table}_versions\".\"RecordID\"");
$query->replaceText("`{$table}_versions`.`ID`", "`{$table}_versions`.`RecordID`");
// Add all <basetable>_versions columns // Add all <basetable>_versions columns
foreach(self::$db_for_versions_table as $name => $type) { foreach(self::$db_for_versions_table as $name => $type) {
@ -154,15 +155,24 @@ class Versioned extends DataExtension {
$query->selectField(sprintf('"%s_versions"."%s"', $baseTable, 'RecordID'), "ID"); $query->selectField(sprintf('"%s_versions"."%s"', $baseTable, 'RecordID'), "ID");
if($table != $baseTable) { if($table != $baseTable) {
$query->addFrom(array($table => " AND \"{$table}_versions\".\"Version\" = \"{$baseTable}_versions\".\"Version\"")); $query->addWhere("\"{$table}_versions\".\"Version\" = \"{$baseTable}_versions\".\"Version\"");
} }
} }
// Link to the version archived on that date // Link to the version archived on that date
$archiveTable = $this->requireArchiveTempTable($baseTable, $date); $safeDate = Convert::raw2sql($date);
$query->addFrom(array($archiveTable => "INNER JOIN \"$archiveTable\" $query->addWhere(
ON \"$archiveTable\".\"ID\" = \"{$baseTable}_versions\".\"RecordID\" "`{$baseTable}_versions`.`Version` IN
AND \"$archiveTable\".\"Version\" = \"{$baseTable}_versions\".\"Version\"")); (SELECT LatestVersion FROM
(SELECT
`{$baseTable}_versions`.`RecordID`,
MAX(`{$baseTable}_versions`.`Version`) AS LatestVersion
FROM `{$baseTable}_versions`
WHERE `{$baseTable}_versions`.`LastEdited` <= '$safeDate'
GROUP BY `{$baseTable}_versions`.`RecordID`
) AS `{$baseTable}_versions_latest`
WHERE `{$baseTable}_versions_latest`.`RecordID` = `{$baseTable}_versions`.`RecordID`
)");
break; break;
// Reading a specific stage (Stage or Live) // Reading a specific stage (Stage or Live)
@ -203,10 +213,18 @@ class Versioned extends DataExtension {
// Return latest version instances, regardless of whether they are on a particular stage // Return latest version instances, regardless of whether they are on a particular stage
// This provides "show all, including deleted" functonality // This provides "show all, including deleted" functonality
if($dataQuery->getQueryParam('Versioned.mode') == 'latest_versions') { if($dataQuery->getQueryParam('Versioned.mode') == 'latest_versions') {
$archiveTable = self::requireArchiveTempTable($baseTable); $query->addWhere(
$query->addInnerJoin($archiveTable, "\"$archiveTable\".\"ID\" = \"{$baseTable}_versions\".\"RecordID\" AND \"$archiveTable\".\"Version\" = \"{$baseTable}_versions\".\"Version\""); "`{$alias}_versions`.`Version` IN
(SELECT LatestVersion FROM
(SELECT
`{$alias}_versions`.`RecordID`,
MAX(`{$alias}_versions`.`Version`) AS LatestVersion
FROM `{$alias}_versions`
GROUP BY `{$alias}_versions`.`RecordID`
) AS `{$alias}_versions_latest`
WHERE `{$alias}_versions_latest`.`RecordID` = `{$alias}_versions`.`RecordID`
)");
} }
break; break;
default: default:
throw new InvalidArgumentException("Bad value for query parameter Versioned.mode: " . $dataQuery->getQueryParam('Versioned.mode')); throw new InvalidArgumentException("Bad value for query parameter Versioned.mode: " . $dataQuery->getQueryParam('Versioned.mode'));
@ -233,34 +251,6 @@ class Versioned extends DataExtension {
// Remove references to them // Remove references to them
self::$archive_tables = array(); self::$archive_tables = array();
} }
/**
* Create a temporary table mapping each database record to its version on the given date.
* This is used by the versioning system to return database content on that date.
* @param string $baseTable The base table.
* @param string $date The date. If omitted, then the latest version of each page will be returned.
* @todo Ensure that this is DB abstracted
*/
protected static function requireArchiveTempTable($baseTable, $date = null) {
if(!isset(self::$archive_tables[$baseTable])) {
self::$archive_tables[$baseTable] = DB::createTable("_Archive$baseTable", array(
"ID" => "INT NOT NULL",
"Version" => "INT NOT NULL",
), null, array('temporary' => true));
}
if(!DB::query("SELECT COUNT(*) FROM \"" . self::$archive_tables[$baseTable] . "\"")->value()) {
if($date) $dateClause = "WHERE \"LastEdited\" <= '$date'";
else $dateClause = "";
DB::query("INSERT INTO \"" . self::$archive_tables[$baseTable] . "\"
SELECT \"RecordID\", max(\"Version\") FROM \"{$baseTable}_versions\"
$dateClause
GROUP BY \"RecordID\"");
}
return self::$archive_tables[$baseTable];
}
/** /**
* An array of DataObject extensions that may require versioning for extra tables * An array of DataObject extensions that may require versioning for extra tables
@ -705,7 +695,7 @@ class Versioned extends DataExtension {
$oldMode = self::get_reading_mode(); $oldMode = self::get_reading_mode();
self::reading_stage('Stage'); self::reading_stage('Stage');
$list = DataObject::get(get_class($this->owner), $filter, $sort, $limit, $join); $list = DataObject::get(get_class($this->owner), $filter, $sort, $join, $limit);
if($having) $having = $list->having($having); if($having) $having = $list->having($having);
$query = $list->dataQuery()->query(); $query = $list->dataQuery()->query();

View File

@ -253,6 +253,7 @@ class Oembed_Result extends ViewableData {
$data['provider_url'] = $protocoll.$host; $data['provider_url'] = $protocoll.$host;
$data['width'] = imagesx($image); $data['width'] = imagesx($image);
$data['height'] = imagesy($image); $data['height'] = imagesy($image);
$data['info'] = _t('UploadField.HOTLINKINFO', 'Info: This image will be hotlinked. Please ensure you have permissions from the original site creator to do so.');
} }
} }

View File

@ -88,6 +88,13 @@ body.cms.ss-uploadfield-edit-iframe, .composite.ss-assetuploadfield .details fie
padding: 0; padding: 0;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
.info {
position: relative;
padding: 7px;
overflow: hidden;
background-color: #FFBE66;
border: 1px solid #FF9300;
}
} }
.ss-uploadfield-item-preview { .ss-uploadfield-item-preview {
position: absolute; position: absolute;

View File

@ -52,7 +52,6 @@ div.TreeDropdownField {
margin: 0; margin: 0;
z-index: 0; z-index: 0;
padding: 7px 3px; padding: 7px 3px;
float: right;
overflow: hidden; overflow: hidden;
-webkit-border-radius: 0 4px 4px 0; -webkit-border-radius: 0 4px 4px 0;
-moz-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0;

View File

@ -1238,6 +1238,8 @@ class Member extends DataObject implements TemplateGlobalProvider {
$labels['PasswordExpiry'] = _t('Member.db_PasswordExpiry', 'Password Expiry Date', 'Password expiry date'); $labels['PasswordExpiry'] = _t('Member.db_PasswordExpiry', 'Password Expiry Date', 'Password expiry date');
$labels['LockedOutUntil'] = _t('Member.db_LockedOutUntil', 'Locked out until', 'Security related date'); $labels['LockedOutUntil'] = _t('Member.db_LockedOutUntil', 'Locked out until', 'Security related date');
$labels['Locale'] = _t('Member.db_Locale', 'Interface Locale'); $labels['Locale'] = _t('Member.db_Locale', 'Interface Locale');
$labels['DateFormat'] = _t('Member.DATEFORMAT', 'Date format');
$labels['TimeFormat'] = _t('Member.TIMEFORMAT', 'Time format');
if($includerelations){ if($includerelations){
$labels['Groups'] = _t('Member.belongs_many_many_Groups', 'Groups', 'Security Groups this member belongs to'); $labels['Groups'] = _t('Member.belongs_many_many_Groups', 'Groups', 'Security Groups this member belongs to');
} }

View File

@ -38,11 +38,13 @@
</div> </div>
</div> </div>
</div> </div>
<div class="details ss-uploadfield-item-editform loading"> <% if Info %><div class="info">$Info</div><% end_if %>
<fieldset> <div class="details ss-uploadfield-item-editform loading">
<% loop Fields %> <fieldset>
$FieldHolder <% loop Fields %>
<% end_loop %> $FieldHolder
</fieldset> <% end_loop %>
</fieldset>
</div>
</div> </div>
</div> </div>

View File

@ -14,7 +14,7 @@ class RSSFeedTest extends SapphireTest {
$list->push(new RSSFeedTest_ItemC()); $list->push(new RSSFeedTest_ItemC());
$rssFeed = new RSSFeed($list, "http://www.example.com", "Test RSS Feed", "Test RSS Feed Description"); $rssFeed = new RSSFeed($list, "http://www.example.com", "Test RSS Feed", "Test RSS Feed Description");
$content = $rssFeed->feedContent(); $content = $rssFeed->outputToBrowser();
//Debug::message($content); //Debug::message($content);
$this->assertContains('<link>http://www.example.org/item-a/</link>', $content); $this->assertContains('<link>http://www.example.org/item-a/</link>', $content);
@ -32,7 +32,7 @@ class RSSFeedTest extends SapphireTest {
// Feed #2 - put Content() into <title> and AltContent() into <description> // Feed #2 - put Content() into <title> and AltContent() into <description>
$rssFeed = new RSSFeed($list, "http://www.example.com", "Test RSS Feed", "Test RSS Feed Description", "Content", "AltContent"); $rssFeed = new RSSFeed($list, "http://www.example.com", "Test RSS Feed", "Test RSS Feed Description", "Content", "AltContent");
$content = $rssFeed->feedContent(); $content = $rssFeed->outputToBrowser();
$this->assertContains('<title>ItemA Content</title>', $content); $this->assertContains('<title>ItemA Content</title>', $content);
$this->assertContains('<title>ItemB Content</title>', $content); $this->assertContains('<title>ItemB Content</title>', $content);
@ -47,13 +47,11 @@ class RSSFeedTest extends SapphireTest {
$rssFeed = new RSSFeed(new ArrayList(), "", "", ""); $rssFeed = new RSSFeed(new ArrayList(), "", "", "");
$rssFeed->setTemplate('RSSFeedTest'); $rssFeed->setTemplate('RSSFeedTest');
$content = $rssFeed->feedContent(); $content = $rssFeed->outputToBrowser();
$this->assertContains('<title>Test Custom Template</title>', $content); $this->assertContains('<title>Test Custom Template</title>', $content);
$rssFeed->setTemplate('RSSFeed'); $rssFeed->setTemplate('RSSFeed');
$content = $rssFeed->feedContent(); $content = $rssFeed->outputToBrowser();
$this->assertNotContains('<title>Test Custom Template</title>', $content); $this->assertNotContains('<title>Test Custom Template</title>', $content);
} }
@ -69,7 +67,6 @@ class RSSFeedTest extends SapphireTest {
Director::setBaseURL(null); Director::setBaseURL(null);
$_SERVER['HTTP_HOST'] = self::$original_host; $_SERVER['HTTP_HOST'] = self::$original_host;
} }
} }
class RSSFeedTest_ItemA extends ViewableData { class RSSFeedTest_ItemA extends ViewableData {
@ -83,9 +80,11 @@ class RSSFeedTest_ItemA extends ViewableData {
function getTitle() { function getTitle() {
return "ItemA"; return "ItemA";
} }
function getContent() { function getContent() {
return "ItemA Content"; return "ItemA Content";
} }
function getAltContent() { function getAltContent() {
return "ItemA AltContent"; return "ItemA AltContent";
} }
@ -101,12 +100,15 @@ class RSSFeedTest_ItemB extends ViewableData {
function Title() { function Title() {
return "ItemB"; return "ItemB";
} }
function AbsoluteLink() { function AbsoluteLink() {
return "http://www.example.com/item-b.html"; return "http://www.example.com/item-b.html";
} }
function Content() { function Content() {
return "ItemB Content"; return "ItemB Content";
} }
function AltContent() { function AltContent() {
return "ItemB AltContent"; return "ItemB AltContent";
} }
@ -114,7 +116,7 @@ class RSSFeedTest_ItemB extends ViewableData {
class RSSFeedTest_ItemC extends ViewableData { class RSSFeedTest_ItemC extends ViewableData {
// ItemC tests fields - Title has casting, Content doesn't. // ItemC tests fields - Title has casting, Content doesn't.
static $casting = array( public static $casting = array(
'Title' => 'Varchar', 'Title' => 'Varchar',
'AltContent' => 'Text', 'AltContent' => 'Text',
); );
@ -126,6 +128,7 @@ class RSSFeedTest_ItemC extends ViewableData {
function Link() { function Link() {
return "item-c.html"; return "item-c.html";
} }
function AbsoluteLink() { function AbsoluteLink() {
return "http://www.example.com/item-c.html"; return "http://www.example.com/item-c.html";
} }

View File

@ -98,6 +98,8 @@ class DirectorTest extends SapphireTest {
$this->assertFalse(Director::is_absolute_url('test.com/testpage')); $this->assertFalse(Director::is_absolute_url('test.com/testpage'));
$this->assertFalse(Director::is_absolute_url('/relative')); $this->assertFalse(Director::is_absolute_url('/relative'));
$this->assertFalse(Director::is_absolute_url('relative')); $this->assertFalse(Director::is_absolute_url('relative'));
$this->assertFalse(Director::is_absolute_url("/relative/?url=http://foo.com"));
$this->assertFalse(Director::is_absolute_url("/relative/#http://foo.com"));
$this->assertTrue(Director::is_absolute_url("https://test.com/?url=http://foo.com")); $this->assertTrue(Director::is_absolute_url("https://test.com/?url=http://foo.com"));
$this->assertTrue(Director::is_absolute_url("trickparseurl:http://test.com")); $this->assertTrue(Director::is_absolute_url("trickparseurl:http://test.com"));
$this->assertTrue(Director::is_absolute_url('//test.com')); $this->assertTrue(Director::is_absolute_url('//test.com'));
@ -116,7 +118,8 @@ class DirectorTest extends SapphireTest {
$this->assertFalse(Director::is_relative_url('ftp://test.com')); $this->assertFalse(Director::is_relative_url('ftp://test.com'));
$this->assertTrue(Director::is_relative_url('/relative')); $this->assertTrue(Director::is_relative_url('/relative'));
$this->assertTrue(Director::is_relative_url('relative')); $this->assertTrue(Director::is_relative_url('relative'));
// $this->assertTrue(Director::is_relative_url('/relative/?url=http://test.com')); $this->assertTrue(Director::is_relative_url('/relative/?url=http://test.com'));
$this->assertTrue(Director::is_relative_url('/relative/#=http://test.com'));
} }
public function testMakeRelative() { public function testMakeRelative() {

View File

@ -266,6 +266,109 @@ class VersionedTest extends SapphireTest {
$this->assertInstanceOf("VersionedTest_DataObject", $obj3); $this->assertInstanceOf("VersionedTest_DataObject", $obj3);
} }
public function testArchiveVersion() {
// In 2005 this file was created
SS_Datetime::set_mock_now('2005-01-01 00:00:00');
$testPage = new VersionedTest_Subclass();
$testPage->Title = 'Archived page';
$testPage->Content = 'This is the content from 2005';
$testPage->ExtraField = '2005';
$testPage->write();
// In 2007 we updated it
SS_Datetime::set_mock_now('2007-01-01 00:00:00');
$testPage->Content = "It's 2007 already!";
$testPage->ExtraField = '2007';
$testPage->write();
// In 2009 we updated it again
SS_Datetime::set_mock_now('2009-01-01 00:00:00');
$testPage->Content = "I'm enjoying 2009";
$testPage->ExtraField = '2009';
$testPage->write();
// End mock, back to the present day:)
SS_Datetime::clear_mock_now();
// Test 1 - 2006 Content
singleton('VersionedTest_Subclass')->flushCache(true);
Versioned::set_reading_mode('Archive.2006-01-01 00:00:00');
$testPage2006 = DataObject::get('VersionedTest_Subclass')->filter(array('Title' => 'Archived page'))->first();
$this->assertInstanceOf("VersionedTest_Subclass", $testPage2006);
$this->assertEquals("2005", $testPage2006->ExtraField);
$this->assertEquals("This is the content from 2005", $testPage2006->Content);
// Test 2 - 2008 Content
singleton('VersionedTest_Subclass')->flushCache(true);
Versioned::set_reading_mode('Archive.2008-01-01 00:00:00');
$testPage2008 = DataObject::get('VersionedTest_Subclass')->filter(array('Title' => 'Archived page'))->first();
$this->assertInstanceOf("VersionedTest_Subclass", $testPage2008);
$this->assertEquals("2007", $testPage2008->ExtraField);
$this->assertEquals("It's 2007 already!", $testPage2008->Content);
// Test 3 - Today
singleton('VersionedTest_Subclass')->flushCache(true);
Versioned::set_reading_mode('Stage.Stage');
$testPageCurrent = DataObject::get('VersionedTest_Subclass')->filter(array('Title' => 'Archived page'))->first();
$this->assertInstanceOf("VersionedTest_Subclass", $testPageCurrent);
$this->assertEquals("2009", $testPageCurrent->ExtraField);
$this->assertEquals("I'm enjoying 2009", $testPageCurrent->Content);
}
public function testAllVersions()
{
// In 2005 this file was created
SS_Datetime::set_mock_now('2005-01-01 00:00:00');
$testPage = new VersionedTest_Subclass();
$testPage->Title = 'Archived page';
$testPage->Content = 'This is the content from 2005';
$testPage->ExtraField = '2005';
$testPage->write();
// In 2007 we updated it
SS_Datetime::set_mock_now('2007-01-01 00:00:00');
$testPage->Content = "It's 2007 already!";
$testPage->ExtraField = '2007';
$testPage->write();
// Check both versions are returned
$versions = Versioned::get_all_versions('VersionedTest_Subclass', $testPage->ID);
$content = array();
$extraFields = array();
foreach($versions as $version)
{
$content[] = $version->Content;
$extraFields[] = $version->ExtraField;
}
$this->assertEquals($versions->Count(), 2, 'All versions returned');
$this->assertEquals($content, array('This is the content from 2005', "It's 2007 already!"), 'Version fields returned');
$this->assertEquals($extraFields, array('2005', '2007'), 'Version fields returned');
// In 2009 we updated it again
SS_Datetime::set_mock_now('2009-01-01 00:00:00');
$testPage->Content = "I'm enjoying 2009";
$testPage->ExtraField = '2009';
$testPage->write();
// End mock, back to the present day:)
SS_Datetime::clear_mock_now();
$versions = Versioned::get_all_versions('VersionedTest_Subclass', $testPage->ID);
$content = array();
$extraFields = array();
foreach($versions as $version)
{
$content[] = $version->Content;
$extraFields[] = $version->ExtraField;
}
$this->assertEquals($versions->Count(), 3, 'Additional all versions returned');
$this->assertEquals($content, array('This is the content from 2005', "It's 2007 already!", "I'm enjoying 2009"), 'Additional version fields returned');
$this->assertEquals($extraFields, array('2005', '2007', '2009'), 'Additional version fields returned');
}
} }
class VersionedTest_DataObject extends DataObject implements TestOnly { class VersionedTest_DataObject extends DataObject implements TestOnly {

22
tests/travis/_config.php Normal file
View File

@ -0,0 +1,22 @@
<?php
global $project;
$project = 'mysite';
global $database;
$database = '';
require_once('conf/ConfigureFromEnv.php');
global $databaseConfig;
$databaseConfig['memory'] = true;
$databaseConfig['path'] = dirname(dirname(__FILE__)) .'/assets/';
MySQLDatabase::set_connection_charset('utf8');
// Set the current theme. More themes can be downloaded from
// http://www.silverstripe.org/themes/
SSViewer::set_theme('simple');
// Enable nested URLs for this site (e.g. page/sub-page/)
if(class_exists('SiteTree')) SiteTree::enable_nested_urls();

View File

@ -0,0 +1,17 @@
<?php
ob_start();
define('SS_ENVIRONMENT_TYPE', 'dev');
/* Database connection */
define('SS_DATABASE_CLASS', 'SQLitePDODatabase');
define('SS_DATABASE_SERVER', 'localhost');
define('SS_DATABASE_USERNAME', 'root');
define('SS_DATABASE_PASSWORD', '');
define('SS_DATABASE_CHOOSE_NAME', true);
/* Configure a default username and password to access the CMS on all sites in this environment. */
define('SS_DEFAULT_ADMIN_USERNAME', 'username');
define('SS_DEFAULT_ADMIN_PASSWORD', 'password');
$_FILE_TO_URL_MAPPING[dirname(__FILE__)] = 'http://localhost';

9
tests/travis/before_script Executable file
View File

@ -0,0 +1,9 @@
BUILD_DIR=$1
git clone --depth=100 --quiet git://github.com/silverstripe/silverstripe-installer.git $BUILD_DIR
git clone --depth=100 --quiet git://github.com/silverstripe-labs/silverstripe-sqlite3.git $BUILD_DIR/sqlite3
cp ./tests/travis/_ss_environment.php $BUILD_DIR
cp ./tests/travis/_config.php $BUILD_DIR/mysite
cp -r . $BUILD_DIR/framework
cd $BUILD_DIR
./framework/sake dev/build "flush=1"

View File

@ -3,6 +3,6 @@ repository_url: https://github.com/hafriedlander/jquery.entwine.git
format: 1 format: 1
handler: handler:
branch: master branch: master
commit: ca22d2b88771cf3c65e65288c4991050a42883a3 commit: 21af92dbad424148af6dd7ea310ab7344fcf7015
repository_class: Piston::Git::Repository repository_class: Piston::Git::Repository
lock: false lock: false

View File

@ -12,7 +12,7 @@
<script type="text/javascript"> <script type="text/javascript">
versionarg = window.location.search.match(/version=([^&]+)/); versionarg = window.location.search.match(/version=([^&]+)/);
jQueryVersion = versionarg ? versionarg[1] : '1.7.2'; jQueryVersion = versionarg ? versionarg[1] : '1.8.0';
jQuerySource = 'local'; jQuerySource = 'local';
var jQuery; var jQuery;

View File

@ -94,12 +94,10 @@ describe('Entwine', function(){
$('#a,#b').entwine({ $('#a,#b').entwine({
onadd: function(){ onadd: function(){
console.debug('added', this);
added.push(this.attr('id')); added.push(this.attr('id'));
sequence.push(this.attr('id')); sequence.push(this.attr('id'));
}, },
onremove: function(){ onremove: function(){
console.debug('added', this);
removed.push(this.attr('id')); removed.push(this.attr('id'));
sequence.push(this.attr('id')); sequence.push(this.attr('id'));
} }

View File

@ -1,30 +1,39 @@
document.write([
'<style type="text/css">',
'#entwine-inspector { position: fixed; z-index: 1000001; left: 0; right: 0; height: 400px; background: white; -webkit-box-shadow: 0 5px 40px 0 black; -moz-box-shadow: 0 5px 40px 0 black; }',
'#entwine-inspector li { list-style: none; margin: 2px 0; padding: 2px 0; }',
'#entwine-inspector li:hover { background: #eee; }',
'#entwine-inspector li.selected { background: #ddd; }',
'#ei-columns { overflow: hidden; display: -webkit-box; display: -moz-box; width: 100%; height: 380px; }',
'.ei-column { height: 380px; width: 1px; -webkit-box-flex: 1; -moz-box-flex: 1; }',
'#entwine-inspector .ei-column h1 { display: block; margin: 0; padding: 5px 2px; height: 20px; text-align: center; background: #444; color: #eee; font-size: 14px; font-weight: bold; }',
'#entwine-inspector .ei-column ul { overflow-y: scroll; height: 350px; }',
'#ei-options { overflow: hidden; height: 20px; background: #444; color: #eee; }',
'#ei-options label { padding-right: 5px; border-right: 1px solid #eee; }',
'.ei-entwined:hover, .ei-selected { background: rgba(128,0,0,0.2); }',
'.ei-hovernode { position: absolute; z-index: 1000000; background: rgba(0,0,0,0.3); border: 1px solid white; outline: 1px solid white; }',
'#ei-selectors li { color: #aaa; display: none; }',
'#ei-selectors li.matching, #entwine-inspector.show-unmatched #ei-selectors li { display: block; }',
'#ei-selectors li.matching { color: black; }',
'</style>'
].join("\n"));
jQuery(function($){ jQuery(function($){
// Create a new style element
var styleEl = document.createElement('style');
styleEl.setAttribute('type', 'text/css');
(document.head || document.getElementsByTagName('head')[0]).appendChild(styleEl);
var inspectorCSS = [
'#entwine-inspector { position: fixed; z-index: 1000001; left: 0; right: 0; height: 400px; background: white; -webkit-box-shadow: 0 5px 40px 0 black; -moz-box-shadow: 0 5px 40px 0 black; }',
'#entwine-inspector li { list-style: none; margin: 2px 0; padding: 2px 0; }',
'#entwine-inspector li:hover { background: #eee; }',
'#entwine-inspector li.selected { background: #ddd; }',
'#ei-columns { overflow: hidden; display: -webkit-box; display: -moz-box; width: 100%; height: 380px; }',
'.ei-column { height: 380px; width: 1px; -webkit-box-flex: 1; -moz-box-flex: 1; }',
'#entwine-inspector .ei-column h1 { display: block; margin: 0; padding: 5px 2px; height: 20px; text-align: center; background: #444; color: #eee; font-size: 14px; font-weight: bold; }',
'#entwine-inspector .ei-column ul { overflow-y: scroll; height: 350px; }',
'#ei-options { overflow: hidden; height: 20px; background: #444; color: #eee; }',
'#ei-options label { padding-right: 5px; border-right: 1px solid #eee; }',
'.ei-entwined:hover, .ei-selected { background: rgba(128,0,0,0.2); }',
'.ei-hovernode { position: absolute; z-index: 1000000; background: rgba(0,0,0,0.3); border: 1px solid white; outline: 1px solid white; }',
'#ei-selectors li { color: #aaa; display: none; }',
'#ei-selectors li.matching, #entwine-inspector.show-unmatched #ei-selectors li { display: block; }',
'#ei-selectors li.matching { color: black; }'
].join("\n");
// Set the style element to style up the inspector panel
if(styleEl.styleSheet){
styleEl.styleSheet.cssText = inspectorCSS;
}else{
styleEl.appendChild(document.createTextNode(inspectorCSS));
}
var inspectorPanel = $('<div id="entwine-inspector" class="show-unmatched"></div>').appendTo('body'); var inspectorPanel = $('<div id="entwine-inspector" class="show-unmatched"></div>').appendTo('body');
var columnHolder = $('<div id="ei-columns"></div>').appendTo(inspectorPanel); var columnHolder = $('<div id="ei-columns"></div>').appendTo(inspectorPanel);
@ -79,6 +88,22 @@ jQuery(function($){
}); });
}; };
var dumpElement = function(el) {
var frag = document.createDocumentFragment();
var div = document.createElement('div'); frag.appendChild(div);
var clone = el.cloneNode(false); $(clone).removeClass('ei-entwined').removeAttr('style');
var i = clone.attributes.length;
while (i--) {
var attr = clone.attributes.item(i);
if (attr.name != 'class' && attr.name != 'id' && attr.value.length > 20) attr.value = attr.value.substr(0, 18)+'..'+attr.value.substr(-2);
}
div.appendChild(clone);
return div.innerHTML;
};
var displaydetails = function(e){ var displaydetails = function(e){
e.preventDefault(); e.stopPropagation(); e.preventDefault(); e.stopPropagation();
@ -99,18 +124,7 @@ jQuery(function($){
var target = $(this); var target = $(this);
var li = $('<li></li>'); var li = $('<li></li>');
var clone = $(this.cloneNode(false)); clone.removeClass('ei-entwined'); clone.removeAttr('style'); li.text(dumpElement(this)).attr('data-id', ++ctr).data('el', target).prependTo(lists.elements);
var i = clone[0].attributes.length;
while (i--) {
var attr = clone[0].attributes.item(i);
if (attr.name != 'class' && attr.name != 'id' && attr.value.length > 20) attr.value = attr.value.substr(0, 18)+'..'+attr.value.substr(-2);
}
li.append(clone);
li.text(li.html()).attr('data-id', ++ctr).data('el', target).prependTo(lists.elements);
var namespaces = $('<ul data-element="'+ctr+'"></ul>').appendTo(columns.namespaces); var namespaces = $('<ul data-element="'+ctr+'"></ul>').appendTo(columns.namespaces);
@ -206,21 +220,21 @@ jQuery(function($){
$('.ei-selected').removeClass('ei-selected'); $('.ei-selected').removeClass('ei-selected');
activatelist('#ei-namespaces ul[data-element='+id+']'); activatelist('#ei-namespaces ul[data-element="'+id+'"]');
}); });
$('#ei-namespaces > ul > li').live('click', function(e){ $('#ei-namespaces > ul > li').live('click', function(e){
var target = $(e.target), namespace = target.attr('data-namespace'); var target = $(e.target), namespace = target.attr('data-namespace');
target.addClass('selected').siblings().removeClass('selected'); target.addClass('selected').siblings().removeClass('selected');
activatelist('#ei-methods ul[data-namespace='+namespace+']'); activatelist('#ei-methods ul[data-namespace="'+namespace+'"]');
}); });
$('#ei-methods > ul > li').live('click', function(e){ $('#ei-methods > ul > li').live('click', function(e){
var target = $(e.target), method = target.attr('data-method'); var target = $(e.target), method = target.attr('data-method');
target.addClass('selected').siblings().removeClass('selected'); target.addClass('selected').siblings().removeClass('selected');
activatelist('#ei-selectors ul[data-method='+method+']'); activatelist('#ei-selectors ul[data-method="'+method+'"]');
}); });
}); });

View File

@ -1,31 +1,28 @@
/*! /*!
* jQuery JavaScript Library v1.7.2 * jQuery JavaScript Library v1.8.0
* http://jquery.com/ * http://jquery.com/
* *
* Copyright 2011, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js * Includes Sizzle.js
* http://sizzlejs.com/ * http://sizzlejs.com/
* Copyright 2011, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
* *
* Date: Wed Mar 21 12:46:34 2012 -0700 * Copyright 2012 jQuery Foundation and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: Thu Aug 09 2012 16:24:48 GMT-0400 (Eastern Daylight Time)
*/ */
(function( window, undefined ) { (function( window, undefined ) {
var
// A central reference to the root jQuery(document)
rootjQuery,
// Use the correct document accordingly with window argument (sandbox) // The deferred used on DOM ready
var document = window.document, readyList,
// Use the correct document accordingly with window argument (sandbox)
document = window.document,
location = window.location,
navigator = window.navigator, navigator = window.navigator,
location = window.location;
var jQuery = (function() {
// 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 );
},
// Map over jQuery in case of overwrite // Map over jQuery in case of overwrite
_jQuery = window.jQuery, _jQuery = window.jQuery,
@ -33,63 +30,64 @@ var jQuery = function( selector, context ) {
// Map over the $ in case of overwrite // Map over the $ in case of overwrite
_$ = window.$, _$ = window.$,
// A central reference to the root jQuery(document) // Save a reference to some core methods
rootjQuery, 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,
// A simple way to check for HTML strings or ID strings // 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 );
},
// Used for matching numbers
core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,
// Used for detecting and trimming whitespace
core_rnotwhite = /\S/,
core_rspace = /\s+/,
// IE doesn't match non-breaking spaces with \s
rtrim = core_rnotwhite.test("\xA0") ? (/^[\s\xA0]+|[\s\xA0]+$/g) : /^\s+|\s+$/g,
// A simple way to check for HTML strings
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521) // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
// Check if a string has a non-whitespace character in it
rnotwhite = /\S/,
// Used for trimming whitespace
trimLeft = /^\s+/,
trimRight = /\s+$/,
// Match a standalone tag // Match a standalone tag
rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
// JSON RegExp // JSON RegExp
rvalidchars = /^[\],:{}\s]*$/, 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, rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
// Useragent RegExp rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,
rwebkit = /(webkit)[ \/]([\w.]+)/,
ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
rmsie = /(msie) ([\w.]+)/,
rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
// Matches dashed string for camelizing // Matches dashed string for camelizing
rdashAlpha = /-([a-z]|[0-9])/ig,
rmsPrefix = /^-ms-/, rmsPrefix = /^-ms-/,
rdashAlpha = /-([\da-z])/gi,
// Used by jQuery.camelCase as callback to replace() // Used by jQuery.camelCase as callback to replace()
fcamelCase = function( all, letter ) { fcamelCase = function( all, letter ) {
return ( letter + "" ).toUpperCase(); return ( letter + "" ).toUpperCase();
}, },
// Keep a UserAgent string for use with jQuery.browser // The ready event handler and self cleanup method
userAgent = navigator.userAgent, DOMContentLoaded = function() {
if ( document.addEventListener ) {
// For matching the engine and version of the browser document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
browserMatch, jQuery.ready();
} else if ( document.readyState === "complete" ) {
// The deferred used on DOM ready // we're here because readyState === "complete" in oldIE
readyList, // which is good enough for us to call the dom ready!
document.detachEvent( "onreadystatechange", DOMContentLoaded );
// The ready event handler jQuery.ready();
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,
// [[Class]] -> type pairs // [[Class]] -> type pairs
class2type = {}; class2type = {};
@ -99,7 +97,7 @@ jQuery.fn = jQuery.prototype = {
init: function( selector, context, rootjQuery ) { init: function( selector, context, rootjQuery ) {
var match, elem, ret, doc; var match, elem, ret, doc;
// Handle $(""), $(null), or $(undefined) // Handle $(""), $(null), $(undefined), $(false)
if ( !selector ) { if ( !selector ) {
return this; return this;
} }
@ -111,55 +109,33 @@ jQuery.fn = jQuery.prototype = {
return this; 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 // Handle HTML strings
if ( typeof selector === "string" ) { 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 ) { 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 // Assume that strings that start and end with <> are HTML and skip the regex check
match = [ null, selector, null ]; match = [ null, selector, null ];
} else { } 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) ) { if ( match && (match[1] || !context) ) {
// HANDLE: $(html) -> $(array) // HANDLE: $(html) -> $(array)
if ( match[1] ) { if ( match[1] ) {
context = context instanceof jQuery ? context[0] : context; 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 // scripts is true for back-compat
// just do a createElement and skip the rest selector = jQuery.parseHTML( match[1], doc, true );
ret = rsingleTag.exec( selector ); if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
this.attr.call( selector, context, true );
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;
} }
return jQuery.merge( this, selector ); return jQuery.merge( this, selector );
// HANDLE: $("#id") // HANDLE: $(#id)
} else { } else {
elem = document.getElementById( match[2] ); elem = document.getElementById( match[2] );
@ -210,7 +186,7 @@ jQuery.fn = jQuery.prototype = {
selector: "", selector: "",
// The current version of jQuery being used // The current version of jQuery being used
jquery: "1.7.2", jquery: "1.8.0",
// The default length of a jQuery object is 0 // The default length of a jQuery object is 0
length: 0, length: 0,
@ -221,7 +197,7 @@ jQuery.fn = jQuery.prototype = {
}, },
toArray: function() { toArray: function() {
return slice.call( this, 0 ); return core_slice.call( this );
}, },
// Get the Nth element in the matched element set OR // 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 // Take an array of elements and push it onto the stack
// (returning the new matched element set) // (returning the new matched element set)
pushStack: function( elems, name, selector ) { pushStack: function( elems, name, selector ) {
// Build a new jQuery matched element set // Build a new jQuery matched element set
var ret = this.constructor(); var ret = jQuery.merge( this.constructor(), elems );
if ( jQuery.isArray( elems ) ) {
push.apply( ret, elems );
} else {
jQuery.merge( ret, elems );
}
// Add the old object onto the stack (as a reference) // Add the old object onto the stack (as a reference)
ret.prevObject = this; ret.prevObject = this;
@ -272,11 +242,8 @@ jQuery.fn = jQuery.prototype = {
}, },
ready: function( fn ) { ready: function( fn ) {
// Attach the listeners
jQuery.bindReady();
// Add the callback // Add the callback
readyList.add( fn ); jQuery.ready.promise().done( fn );
return this; return this;
}, },
@ -297,8 +264,8 @@ jQuery.fn = jQuery.prototype = {
}, },
slice: function() { slice: function() {
return this.pushStack( slice.apply( this, arguments ), return this.pushStack( core_slice.apply( this, arguments ),
"slice", slice.call(arguments).join(",") ); "slice", core_slice.call(arguments).join(",") );
}, },
map: function( callback ) { map: function( callback ) {
@ -313,7 +280,7 @@ jQuery.fn = jQuery.prototype = {
// For internal use only. // For internal use only.
// Behaves like an Array's method, not like a jQuery method. // Behaves like an Array's method, not like a jQuery method.
push: push, push: core_push,
sort: [].sort, sort: [].sort,
splice: [].splice splice: [].splice
}; };
@ -416,73 +383,31 @@ jQuery.extend({
// Handle when the DOM is ready // Handle when the DOM is ready
ready: function( wait ) { 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 // Abort if there are pending holds or we're already ready
jQuery.isReady = true; if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
// 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 ) {
return; return;
} }
readyList = jQuery.Callbacks( "once memory" ); // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
if ( !document.body ) {
// 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
return setTimeout( jQuery.ready, 1 ); return setTimeout( jQuery.ready, 1 );
} }
// Mozilla, Opera and webkit nightlies currently support this event // Remember that the DOM is ready
if ( document.addEventListener ) { jQuery.isReady = true;
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work // If a normal DOM Ready event fired, decrement, and wait if need be
window.addEventListener( "load", jQuery.ready, false ); if ( wait !== true && --jQuery.readyWait > 0 ) {
return;
}
// If IE event model is used // If there are functions bound, to execute
} else if ( document.attachEvent ) { readyList.resolveWith( document, [ jQuery ] );
// ensure firing before onload,
// maybe late but safe also for iframes
document.attachEvent( "onreadystatechange", DOMContentLoaded );
// A fallback to window.onload, that will always work // Trigger any bound ready events
window.attachEvent( "onload", jQuery.ready ); if ( jQuery.fn.trigger ) {
jQuery( document ).trigger("ready").off("ready");
// If IE and not a frame
// continually check to see if the document is ready
var toplevel = false;
try {
toplevel = window.frameElement == null;
} catch(e) {}
if ( document.documentElement.doScroll && toplevel ) {
doScrollCheck();
}
} }
}, },
@ -508,7 +433,7 @@ jQuery.extend({
type: function( obj ) { type: function( obj ) {
return obj == null ? return obj == null ?
String( obj ) : String( obj ) :
class2type[ toString.call(obj) ] || "object"; class2type[ core_toString.call(obj) ] || "object";
}, },
isPlainObject: function( obj ) { isPlainObject: function( obj ) {
@ -522,8 +447,8 @@ jQuery.extend({
try { try {
// Not own constructor property must be Object // Not own constructor property must be Object
if ( obj.constructor && if ( obj.constructor &&
!hasOwn.call(obj, "constructor") && !core_hasOwn.call(obj, "constructor") &&
!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
return false; return false;
} }
} catch ( e ) { } catch ( e ) {
@ -537,11 +462,12 @@ jQuery.extend({
var key; var key;
for ( key in obj ) {} for ( key in obj ) {}
return key === undefined || hasOwn.call( obj, key ); return key === undefined || core_hasOwn.call( obj, key );
}, },
isEmptyObject: function( obj ) { isEmptyObject: function( obj ) {
for ( var name in obj ) { var name;
for ( name in obj ) {
return false; return false;
} }
return true; return true;
@ -551,8 +477,32 @@ jQuery.extend({
throw new Error( msg ); 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 ) { parseJSON: function( data ) {
if ( typeof data !== "string" || !data ) { if ( !data || typeof data !== "string") {
return null; return null;
} }
@ -578,10 +528,10 @@ jQuery.extend({
// Cross-browser xml parsing // Cross-browser xml parsing
parseXML: function( data ) { parseXML: function( data ) {
if ( typeof data !== "string" || !data ) { var xml, tmp;
if ( !data || typeof data !== "string" ) {
return null; return null;
} }
var xml, tmp;
try { try {
if ( window.DOMParser ) { // Standard if ( window.DOMParser ) { // Standard
tmp = new DOMParser(); tmp = new DOMParser();
@ -606,7 +556,7 @@ jQuery.extend({
// Workarounds based on findings by Jim Driscoll // Workarounds based on findings by Jim Driscoll
// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
globalEval: function( data ) { globalEval: function( data ) {
if ( data && rnotwhite.test( data ) ) { if ( data && core_rnotwhite.test( data ) ) {
// We use execScript on Internet Explorer // We use execScript on Internet Explorer
// We use an anonymous function so that context is window // We use an anonymous function so that context is window
// rather than jQuery in Firefox // rather than jQuery in Firefox
@ -627,21 +577,22 @@ jQuery.extend({
}, },
// args is for internal usage only // args is for internal usage only
each: function( object, callback, args ) { each: function( obj, callback, args ) {
var name, i = 0, var name,
length = object.length, i = 0,
isObj = length === undefined || jQuery.isFunction( object ); length = obj.length,
isObj = length === undefined || jQuery.isFunction( obj );
if ( args ) { if ( args ) {
if ( isObj ) { if ( isObj ) {
for ( name in object ) { for ( name in obj ) {
if ( callback.apply( object[ name ], args ) === false ) { if ( callback.apply( obj[ name ], args ) === false ) {
break; break;
} }
} }
} else { } else {
for ( ; i < length; ) { for ( ; i < length; ) {
if ( callback.apply( object[ i++ ], args ) === false ) { if ( callback.apply( obj[ i++ ], args ) === false ) {
break; break;
} }
} }
@ -650,71 +601,72 @@ jQuery.extend({
// A special, fast, case for the most common use of each // A special, fast, case for the most common use of each
} else { } else {
if ( isObj ) { if ( isObj ) {
for ( name in object ) { for ( name in obj ) {
if ( callback.call( object[ name ], name, object[ name ] ) === false ) { if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) {
break; break;
} }
} }
} else { } else {
for ( ; i < length; ) { for ( ; i < length; ) {
if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) {
break; break;
} }
} }
} }
} }
return object; return obj;
}, },
// Use native String.trim function wherever possible // Use native String.trim function wherever possible
trim: trim ? trim: core_trim ?
function( text ) { function( text ) {
return text == null ? return text == null ?
"" : "" :
trim.call( text ); core_trim.call( text );
} : } :
// Otherwise use our own trimming functionality // Otherwise use our own trimming functionality
function( text ) { function( text ) {
return text == null ? return text == null ?
"" : "" :
text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); text.toString().replace( rtrim, "" );
}, },
// results is for internal usage only // results is for internal usage only
makeArray: function( array, results ) { makeArray: function( arr, results ) {
var ret = results || []; var type,
ret = results || [];
if ( array != null ) { if ( arr != null ) {
// The window, strings (and functions) also have 'length' // The window, strings (and functions) also have 'length'
// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 // 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 ) ) { if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) {
push.call( ret, array ); core_push.call( ret, arr );
} else { } else {
jQuery.merge( ret, array ); jQuery.merge( ret, arr );
} }
} }
return ret; return ret;
}, },
inArray: function( elem, array, i ) { inArray: function( elem, arr, i ) {
var len; var len;
if ( array ) { if ( arr ) {
if ( indexOf ) { if ( core_indexOf ) {
return indexOf.call( array, elem, i ); return core_indexOf.call( arr, elem, i );
} }
len = array.length; len = arr.length;
i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
for ( ; i < len; i++ ) { for ( ; i < len; i++ ) {
// Skip accessing in sparse arrays // Skip accessing in sparse arrays
if ( i in array && array[ i ] === elem ) { if ( i in arr && arr[ i ] === elem ) {
return i; return i;
} }
} }
@ -724,11 +676,12 @@ jQuery.extend({
}, },
merge: function( first, second ) { merge: function( first, second ) {
var i = first.length, var l = second.length,
i = first.length,
j = 0; j = 0;
if ( typeof second.length === "number" ) { if ( typeof l === "number" ) {
for ( var l = second.length; j < l; j++ ) { for ( ; j < l; j++ ) {
first[ i++ ] = second[ j ]; first[ i++ ] = second[ j ];
} }
@ -744,12 +697,15 @@ jQuery.extend({
}, },
grep: function( elems, callback, inv ) { grep: function( elems, callback, inv ) {
var ret = [], retVal; var retVal,
ret = [],
i = 0,
length = elems.length;
inv = !!inv; inv = !!inv;
// Go through the array, only saving the items // Go through the array, only saving the items
// that pass the validator function // that pass the validator function
for ( var i = 0, length = elems.length; i < length; i++ ) { for ( ; i < length; i++ ) {
retVal = !!callback( elems[ i ], i ); retVal = !!callback( elems[ i ], i );
if ( inv !== retVal ) { if ( inv !== retVal ) {
ret.push( elems[ i ] ); ret.push( elems[ i ] );
@ -761,7 +717,8 @@ jQuery.extend({
// arg is for internal usage only // arg is for internal usage only
map: function( elems, callback, arg ) { map: function( elems, callback, arg ) {
var value, key, ret = [], var value, key,
ret = [],
i = 0, i = 0,
length = elems.length, length = elems.length,
// jquery objects are treated as arrays // jquery objects are treated as arrays
@ -798,8 +755,10 @@ jQuery.extend({
// Bind a function to a context, optionally partially applying any // Bind a function to a context, optionally partially applying any
// arguments. // arguments.
proxy: function( fn, context ) { proxy: function( fn, context ) {
var tmp, args, proxy;
if ( typeof context === "string" ) { if ( typeof context === "string" ) {
var tmp = fn[ context ]; tmp = fn[ context ];
context = fn; context = fn;
fn = tmp; fn = tmp;
} }
@ -811,10 +770,10 @@ jQuery.extend({
} }
// Simulated bind // Simulated bind
var args = slice.call( arguments, 2 ), args = core_slice.call( arguments, 2 );
proxy = function() { proxy = function() {
return fn.apply( context, args.concat( slice.call( arguments ) ) ); 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 // 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 || proxy.guid || jQuery.guid++;
@ -822,7 +781,7 @@ jQuery.extend({
return proxy; 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 // The value/s can optionally be executed if it's a function
access: function( elems, fn, key, value, chainable, emptyGet, pass ) { access: function( elems, fn, key, value, chainable, emptyGet, pass ) {
var exec, var exec,
@ -877,136 +836,95 @@ jQuery.extend({
now: function() { now: function() {
return ( new Date() ).getTime(); 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 ) ||
[];
return { browser: match[1] || "", version: match[2] || "0" };
},
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;
},
browser: {}
}); });
jQuery.ready.promise = function( obj ) {
if ( !readyList ) {
readyList = jQuery.Deferred();
// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState === "complete" || ( document.readyState !== "loading" && document.addEventListener ) ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
setTimeout( jQuery.ready, 1 );
// Standards-based browsers support DOMContentLoaded
} else if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
window.addEventListener( "load", jQuery.ready, false );
// If IE event model is used
} else {
// 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 top = false;
try {
top = window.frameElement == null && document.documentElement;
} catch(e) {}
if ( top && top.doScroll ) {
(function doScrollCheck() {
if ( !jQuery.isReady ) {
try {
// Use the trick by Diego Perini
// http://javascript.nwbox.com/IEContentLoaded/
top.doScroll("left");
} catch(e) {
return setTimeout( doScrollCheck, 50 );
}
// and execute any waiting functions
jQuery.ready();
}
})();
}
}
}
return readyList.promise( obj );
};
// Populate the class2type map // Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase(); class2type[ "[object " + name + "]" ] = name.toLowerCase();
}); });
browserMatch = jQuery.uaMatch( userAgent );
if ( browserMatch.browser ) {
jQuery.browser[ browserMatch.browser ] = true;
jQuery.browser.version = browserMatch.version;
}
// Deprecated, use jQuery.browser.webkit instead
if ( jQuery.browser.webkit ) {
jQuery.browser.safari = true;
}
// IE doesn't match non-breaking spaces with \s
if ( rnotwhite.test( "\xA0" ) ) {
trimLeft = /^[\s\xA0]+/;
trimRight = /[\s\xA0]+$/;
}
// All jQuery objects should point back to these // All jQuery objects should point back to these
rootjQuery = jQuery(document); rootjQuery = jQuery(document);
// String to Object options format cache
var optionsCache = {};
// Cleanup functions for the document ready method // Convert String-formatted options into Object-formatted ones and store in cache
if ( document.addEventListener ) { function createOptions( options ) {
DOMContentLoaded = function() { var object = optionsCache[ options ] = {};
document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); jQuery.each( options.split( core_rspace ), function( _, flag ) {
jQuery.ready(); object[ flag ] = true;
}; });
} 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();
}
};
}
// The DOM ready check for Internet Explorer
function doScrollCheck() {
if ( jQuery.isReady ) {
return;
}
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 = {};
// 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;
}
return object; return object;
} }
/* /*
* Create a callback list using the following parameters: * Create a callback list using the following parameters:
* *
* flags: an optional list of space-separated flags that will change how * options: an optional list of space-separated options that will change how
* the callback list behaves * 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 * By default a callback list will act like an event callback list and can be
* "fired" multiple times. * "fired" multiple times.
* *
* Possible flags: * Possible options:
* *
* once: will ensure the callback list can only be fired once (like a Deferred) * once: will ensure the callback list can only be fired once (like a Deferred)
* *
@ -1019,17 +937,15 @@ function createFlags( flags ) {
* stopOnFalse: interrupt callings when a callback returns false * 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) // (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 var // Last fire value (for non-forgettable lists)
list = [],
// Stack of fire calls for repeatable lists
stack = [],
// Last fire value (for non-forgettable lists)
memory, memory,
// Flag to know if list was already fired // Flag to know if list was already fired
fired, fired,
@ -1041,53 +957,34 @@ jQuery.Callbacks = function( flags ) {
firingLength, firingLength,
// Index of currently firing callback (modified by remove if needed) // Index of currently firing callback (modified by remove if needed)
firingIndex, firingIndex,
// Add one or several callbacks to the list // Actual callback list
add = function( args ) { list = [],
var i, // Stack of fire calls for repeatable lists
length, stack = !options.once && [],
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 );
}
}
}
},
// Fire callbacks // Fire callbacks
fire = function( context, args ) { fire = function( data ) {
args = args || []; memory = options.memory && data;
memory = !flags.memory || [ context, args ];
fired = true; fired = true;
firing = true;
firingIndex = firingStart || 0; firingIndex = firingStart || 0;
firingStart = 0; firingStart = 0;
firingLength = list.length; firingLength = list.length;
firing = true;
for ( ; list && firingIndex < firingLength; firingIndex++ ) { for ( ; list && firingIndex < firingLength; firingIndex++ ) {
if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
memory = true; // Mark as halted memory = false; // To prevent further calls using add
break; break;
} }
} }
firing = false; firing = false;
if ( list ) { if ( list ) {
if ( !flags.once ) { if ( stack ) {
if ( stack && stack.length ) { if ( stack.length ) {
memory = stack.shift(); fire( stack.shift() );
self.fireWith( memory[ 0 ], memory[ 1 ] );
} }
} else if ( memory === true ) { } else if ( memory ) {
self.disable();
} else {
list = []; list = [];
} else {
self.disable();
} }
} }
}, },
@ -1096,18 +993,27 @@ jQuery.Callbacks = function( flags ) {
// Add a callback or a collection of callbacks to the list // Add a callback or a collection of callbacks to the list
add: function() { add: function() {
if ( list ) { if ( list ) {
var length = list.length; // First, we save the current length
add( arguments ); var start = list.length;
(function add( args ) {
jQuery.each( args, function( _, arg ) {
if ( jQuery.isFunction( arg ) && ( !options.unique || !self.has( arg ) ) ) {
list.push( arg );
} else if ( arg && arg.length ) {
// Inspect recursively
add( arg );
}
});
})( arguments );
// Do we need to add the callbacks to the // Do we need to add the callbacks to the
// current firing batch? // current firing batch?
if ( firing ) { if ( firing ) {
firingLength = list.length; firingLength = list.length;
// With memory, if we're not firing then // With memory, if we're not firing then
// we should call right away, unless previous // we should call right away
// firing was halted (stopOnFalse) } else if ( memory ) {
} else if ( memory && memory !== true ) { firingStart = start;
firingStart = length; fire( memory );
fire( memory[ 0 ], memory[ 1 ] );
} }
} }
return this; return this;
@ -1115,46 +1021,27 @@ jQuery.Callbacks = function( flags ) {
// Remove a callback from the list // Remove a callback from the list
remove: function() { remove: function() {
if ( list ) { if ( list ) {
var args = arguments, jQuery.each( arguments, function( _, arg ) {
argIndex = 0, var index;
argLength = args.length; while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
for ( ; argIndex < argLength ; argIndex++ ) { list.splice( index, 1 );
for ( var i = 0; i < list.length; i++ ) { // Handle firing indexes
if ( args[ argIndex ] === list[ i ] ) { if ( firing ) {
// Handle firingIndex and firingLength if ( index <= firingLength ) {
if ( firing ) { firingLength--;
if ( i <= firingLength ) {
firingLength--;
if ( i <= firingIndex ) {
firingIndex--;
}
}
} }
// Remove the element if ( index <= firingIndex ) {
list.splice( i--, 1 ); firingIndex--;
// If we have some unicity property then
// we only need to do this once
if ( flags.unique ) {
break;
} }
} }
} }
} });
} }
return this; return this;
}, },
// Control if a given callback is in the list // Control if a given callback is in the list
has: function( fn ) { has: function( fn ) {
if ( list ) { return jQuery.inArray( fn, list ) > -1;
var i = 0,
length = list.length;
for ( ; i < length; i++ ) {
if ( fn === list[ i ] ) {
return true;
}
}
}
return false;
}, },
// Remove all callbacks from the list // Remove all callbacks from the list
empty: function() { empty: function() {
@ -1173,7 +1060,7 @@ jQuery.Callbacks = function( flags ) {
// Lock the list in its current state // Lock the list in its current state
lock: function() { lock: function() {
stack = undefined; stack = undefined;
if ( !memory || memory === true ) { if ( !memory ) {
self.disable(); self.disable();
} }
return this; return this;
@ -1184,13 +1071,13 @@ jQuery.Callbacks = function( flags ) {
}, },
// Call all callbacks with the given context and arguments // Call all callbacks with the given context and arguments
fireWith: function( context, args ) { fireWith: function( context, args ) {
if ( stack ) { args = args || [];
args = [ context, args.slice ? args.slice() : args ];
if ( list && ( !fired || stack ) ) {
if ( firing ) { if ( firing ) {
if ( !flags.once ) { stack.push( args );
stack.push( [ context, args ] ); } else {
} fire( args );
} else if ( !( flags.once && memory ) ) {
fire( context, args );
} }
} }
return this; return this;
@ -1208,98 +1095,85 @@ jQuery.Callbacks = function( flags ) {
return self; return self;
}; };
var // Static reference to slice
sliceDeferred = [].slice;
jQuery.extend({ jQuery.extend({
Deferred: function( func ) { Deferred: function( func ) {
var doneList = jQuery.Callbacks( "once memory" ), var tuples = [
failList = jQuery.Callbacks( "once memory" ), // action, add listener, listener list, final state
progressList = jQuery.Callbacks( "memory" ), [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
[ "notify", "progress", jQuery.Callbacks("memory") ]
],
state = "pending", state = "pending",
lists = {
resolve: doneList,
reject: failList,
notify: progressList
},
promise = { promise = {
done: doneList.add,
fail: failList.add,
progress: progressList.add,
state: function() { state: function() {
return state; 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() { always: function() {
deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); deferred.done( arguments ).fail( arguments );
return this; return this;
}, },
pipe: function( fnDone, fnFail, fnProgress ) { then: function( /* fnDone, fnFail, fnProgress */ ) {
var fns = arguments;
return jQuery.Deferred(function( newDefer ) { return jQuery.Deferred(function( newDefer ) {
jQuery.each( { jQuery.each( tuples, function( i, tuple ) {
done: [ fnDone, "resolve" ], var action = tuple[ 0 ],
fail: [ fnFail, "reject" ], fn = fns[ i ];
progress: [ fnProgress, "notify" ] // deferred[ done | fail | progress ] for forwarding actions to newDefer
}, function( handler, data ) { deferred[ tuple[1] ]( jQuery.isFunction( fn ) ?
var fn = data[ 0 ], function() {
action = data[ 1 ], var returned = fn.apply( this, arguments );
returned;
if ( jQuery.isFunction( fn ) ) {
deferred[ handler ](function() {
returned = fn.apply( this, arguments );
if ( returned && jQuery.isFunction( returned.promise ) ) { 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 { } else {
newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
} }
}); } :
} else { newDefer[ action ]
deferred[ handler ]( newDefer[ action ] ); );
}
}); });
fns = null;
}).promise(); }).promise();
}, },
// Get a promise for this deferred // Get a promise for this deferred
// If obj is provided, the promise aspect is added to the object // If obj is provided, the promise aspect is added to the object
promise: function( obj ) { promise: function( obj ) {
if ( obj == null ) { return typeof obj === "object" ? jQuery.extend( obj, promise ) : promise;
obj = promise;
} else {
for ( var key in promise ) {
obj[ key ] = promise[ key ];
}
}
return obj;
} }
}, },
deferred = promise.promise({}), deferred = {};
key;
for ( key in lists ) { // Keep pipe for back-compat
deferred[ key ] = lists[ key ].fire; promise.pipe = promise.then;
deferred[ key + "With" ] = lists[ key ].fireWith;
}
// Handle state // Add list-specific methods
deferred.done( function() { jQuery.each( tuples, function( i, tuple ) {
state = "resolved"; var list = tuple[ 2 ],
}, failList.disable, progressList.lock ).fail( function() { stateString = tuple[ 3 ];
state = "rejected";
}, doneList.disable, progressList.lock ); // 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;
});
// Make the deferred a promise
promise.promise( deferred );
// Call given func if any // Call given func if any
if ( func ) { if ( func ) {
@ -1311,52 +1185,57 @@ jQuery.extend({
}, },
// Deferred helper // Deferred helper
when: function( firstParam ) { when: function( subordinate /* , ..., subordinateN */ ) {
var args = sliceDeferred.call( arguments, 0 ), var i = 0,
i = 0, resolveValues = core_slice.call( arguments ),
length = args.length, length = resolveValues.length,
pValues = new Array( length ),
count = length, // the count of uncompleted subordinates
pCount = length, remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
firstParam : // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
jQuery.Deferred(), deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
promise = deferred.promise();
function resolveFunc( i ) { // Update function for both resolve and progress values
return function( value ) { updateFunc = function( i, contexts, values ) {
args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; return function( value ) {
if ( !( --count ) ) { contexts[ i ] = this;
deferred.resolveWith( deferred, args ); values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
} if( values === progressValues ) {
}; deferred.notifyWith( contexts, values );
} } else if ( !( --remaining ) ) {
function progressFunc( i ) { deferred.resolveWith( contexts, values );
return function( value ) { }
pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; };
deferred.notifyWith( promise, pValues ); },
};
} progressValues, progressContexts, resolveContexts;
// add listeners to Deferred subordinates; treat others as resolved
if ( length > 1 ) { if ( length > 1 ) {
progressValues = new Array( length );
progressContexts = new Array( length );
resolveContexts = new Array( length );
for ( ; i < length; i++ ) { for ( ; i < length; i++ ) {
if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); resolveValues[ i ].promise()
.done( updateFunc( i, resolveContexts, resolveValues ) )
.fail( deferred.reject )
.progress( updateFunc( i, progressContexts, progressValues ) );
} else { } 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() { jQuery.support = (function() {
var support, var support,
@ -1366,20 +1245,19 @@ jQuery.support = (function() {
opt, opt,
input, input,
fragment, fragment,
tds,
events,
eventName, eventName,
i, i,
isSupported, isSupported,
div = document.createElement( "div" ), clickFn,
documentElement = document.documentElement; div = document.createElement("div");
// Preliminary tests // Preliminary tests
div.setAttribute("className", "t"); 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.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
all = div.getElementsByTagName( "*" ); all = div.getElementsByTagName("*");
a = div.getElementsByTagName( "a" )[ 0 ]; a = div.getElementsByTagName("a")[ 0 ];
a.style.cssText = "top:1px;float:left;opacity:.5";
// Can't get basic test support // Can't get basic test support
if ( !all || !all.length || !a ) { if ( !all || !all.length || !a ) {
@ -1387,9 +1265,9 @@ jQuery.support = (function() {
} }
// First batch of supports tests // First batch of supports tests
select = document.createElement( "select" ); select = document.createElement("select");
opt = select.appendChild( document.createElement("option") ); opt = select.appendChild( document.createElement("option") );
input = div.getElementsByTagName( "input" )[ 0 ]; input = div.getElementsByTagName("input")[ 0 ];
support = { support = {
// IE strips leading whitespace when .innerHTML is used // IE strips leading whitespace when .innerHTML is used
@ -1414,7 +1292,7 @@ jQuery.support = (function() {
// Make sure that element opacity exists // Make sure that element opacity exists
// (IE uses filter instead) // (IE uses filter instead)
// Use a regex to work around a WebKit issue. See #5145 // 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 // Verify style float existence
// (IE uses styleFloat instead of cssFloat) // (IE uses styleFloat instead of cssFloat)
@ -1439,6 +1317,9 @@ jQuery.support = (function() {
// Where outerHTML is undefined, this still works // Where outerHTML is undefined, this still works
html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>", 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 // Will be defined later
submitBubbles: true, submitBubbles: true,
changeBubbles: true, changeBubbles: true,
@ -1448,12 +1329,10 @@ jQuery.support = (function() {
inlineBlockNeedsLayout: false, inlineBlockNeedsLayout: false,
shrinkWrapBlocks: false, shrinkWrapBlocks: false,
reliableMarginRight: true, reliableMarginRight: true,
pixelMargin: true boxSizingReliable: true,
pixelPosition: false
}; };
// jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead
jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat");
// Make sure checked status is properly cloned // Make sure checked status is properly cloned
input.checked = true; input.checked = true;
support.noCloneChecked = input.cloneNode( true ).checked; support.noCloneChecked = input.cloneNode( true ).checked;
@ -1472,22 +1351,23 @@ jQuery.support = (function() {
} }
if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
div.attachEvent( "onclick", function() { div.attachEvent( "onclick", clickFn = function() {
// Cloning a node shouldn't copy over any // Cloning a node shouldn't copy over any
// bound event handlers (IE does this) // bound event handlers (IE does this)
support.noCloneEvent = false; support.noCloneEvent = false;
}); });
div.cloneNode( true ).fireEvent( "onclick" ); div.cloneNode( true ).fireEvent("onclick");
div.detachEvent( "onclick", clickFn );
} }
// Check if a radio maintains its value // Check if a radio maintains its value
// after being appended to the DOM // after being appended to the DOM
input = document.createElement("input"); input = document.createElement("input");
input.value = "t"; input.value = "t";
input.setAttribute("type", "radio"); input.setAttribute( "type", "radio" );
support.radioValue = input.value === "t"; 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 // #11217 - WebKit loses check when the name is after the checked attribute
input.setAttribute( "name", "t" ); input.setAttribute( "name", "t" );
@ -1514,9 +1394,9 @@ jQuery.support = (function() {
// to go haywire. See: https://developer.mozilla.org/en/Security/CSP // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
if ( div.attachEvent ) { if ( div.attachEvent ) {
for ( i in { for ( i in {
submit: 1, submit: true,
change: 1, change: true,
focusin: 1 focusin: true
}) { }) {
eventName = "on" + i; eventName = "on" + i;
isSupported = ( eventName in div ); isSupported = ( eventName in div );
@ -1528,16 +1408,10 @@ jQuery.support = (function() {
} }
} }
fragment.removeChild( div );
// Null elements to avoid leaks in IE
fragment = select = opt = div = input = null;
// Run tests that need a body at doc ready // Run tests that need a body at doc ready
jQuery(function() { jQuery(function() {
var container, outer, inner, table, td, offsetSupport, var container, div, tds, marginDiv,
marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;",
paddingMarginBorderVisibility, paddingMarginBorder,
body = document.getElementsByTagName("body")[0]; body = document.getElementsByTagName("body")[0];
if ( !body ) { if ( !body ) {
@ -1545,17 +1419,8 @@ jQuery.support = (function() {
return; return;
} }
conMarginTop = 1;
paddingMarginBorder = "padding:0;margin:0;border:";
positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;";
paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;";
style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;";
html = "<div " + style + "display:block;'><div style='" + paddingMarginBorder + "0;display:block;overflow:hidden;'></div></div>" +
"<table " + style + "' cellpadding='0' cellspacing='0'>" +
"<tr><td></td></tr></table>";
container = document.createElement("div"); container = document.createElement("div");
container.style.cssText = paddingMarginBorderVisibility + "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 ); body.insertBefore( container, body.firstChild );
// Construct the test element // Construct the test element
@ -1569,8 +1434,9 @@ jQuery.support = (function() {
// display:none (it is still safe to use offsets if a parent element is // 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). // hidden; don safety goggles and see bug #4512 for more information).
// (only IE 8 fails this test) // (only IE 8 fails this test)
div.innerHTML = "<table><tr><td style='" + paddingMarginBorder + "0;display:none'></td><td>t</td></tr></table>"; div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
tds = div.getElementsByTagName( "td" ); tds = div.getElementsByTagName("td");
tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
isSupported = ( tds[ 0 ].offsetHeight === 0 ); isSupported = ( tds[ 0 ].offsetHeight === 0 );
tds[ 0 ].style.display = ""; tds[ 0 ].style.display = "";
@ -1580,20 +1446,32 @@ jQuery.support = (function() {
// (IE <= 8 fail this test) // (IE <= 8 fail this test)
support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
// Check if div with explicit width and no margin-right incorrectly // Check box-sizing and margin behavior
// gets computed margin-right based on width of container. For more div.innerHTML = "";
// info see bug #3333 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%;";
// Fails in WebKit before Feb 2011 nightlies support.boxSizing = ( div.offsetWidth === 4 );
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
// NOTE: To any future maintainer, window.getComputedStyle was used here
// instead of getComputedStyle because it gave a better gzip size.
// The difference between window.getComputedStyle and getComputedStyle is
// 7 bytes
if ( window.getComputedStyle ) { if ( window.getComputedStyle ) {
div.innerHTML = ""; support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
marginDiv = document.createElement( "div" ); support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
marginDiv.style.width = "0";
marginDiv.style.marginRight = "0"; // Check if div with explicit width and no margin-right incorrectly
div.style.width = "2px"; // 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 ); div.appendChild( marginDiv );
support.reliableMarginRight = support.reliableMarginRight =
( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
} }
if ( typeof div.style.zoom !== "undefined" ) { if ( typeof div.style.zoom !== "undefined" ) {
@ -1602,73 +1480,39 @@ jQuery.support = (function() {
// them layout // them layout
// (IE < 8 does this) // (IE < 8 does this)
div.innerHTML = ""; div.innerHTML = "";
div.style.width = div.style.padding = "1px"; div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
div.style.border = 0;
div.style.overflow = "hidden";
div.style.display = "inline";
div.style.zoom = 1;
support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
// Check if elements with layout shrink-wrap their children // Check if elements with layout shrink-wrap their children
// (IE 6 does this) // (IE 6 does this)
div.style.display = "block"; div.style.display = "block";
div.style.overflow = "visible"; div.style.overflow = "visible";
div.innerHTML = "<div style='width:5px;'></div>"; div.innerHTML = "<div></div>";
div.firstChild.style.width = "5px";
support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
}
div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility;
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";
offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 );
offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );
if ( window.getComputedStyle ) {
div.style.marginTop = "1%";
support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%";
}
if ( typeof container.style.zoom !== "undefined" ) {
container.style.zoom = 1; container.style.zoom = 1;
} }
// Null elements to avoid leaks in IE
body.removeChild( container ); body.removeChild( container );
marginDiv = div = container = null; container = div = tds = marginDiv = null;
jQuery.extend( support, offsetSupport );
}); });
// Null elements to avoid leaks in IE
fragment.removeChild( div );
all = a = select = opt = input = fragment = div = null;
return support; return support;
})(); })();
var rbrace = /^(?:\{.*\}|\[.*\])$/, var rbrace = /^(?:\{.*\}|\[.*\])$/,
rmultiDash = /([A-Z])/g; rmultiDash = /([A-Z])/g;
jQuery.extend({ jQuery.extend({
cache: {}, cache: {},
deletedIds: [],
// Please use with caution // Please use with caution
uuid: 0, uuid: 0,
@ -1695,7 +1539,7 @@ jQuery.extend({
return; return;
} }
var privateCache, thisCache, ret, var thisCache, ret,
internalKey = jQuery.expando, internalKey = jQuery.expando,
getByName = typeof name === "string", getByName = typeof name === "string",
@ -1709,12 +1553,11 @@ jQuery.extend({
// Only defining an ID for JS objects if its cache already exists allows // 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 // the code to shortcut on the same path as a DOM node with no cache
id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
isEvents = name === "events";
// Avoid doing any more work than we need to when trying to get data on an // Avoid doing any more work than we need to when trying to get data on an
// object that has no data at all // 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; return;
} }
@ -1722,7 +1565,7 @@ jQuery.extend({
// Only DOM nodes need a new unique ID for each element since their data // Only DOM nodes need a new unique ID for each element since their data
// ends up in the global cache // ends up in the global cache
if ( isNode ) { if ( isNode ) {
elem[ internalKey ] = id = ++jQuery.uuid; elem[ internalKey ] = id = jQuery.deletedIds.pop() || ++jQuery.uuid;
} else { } else {
id = internalKey; id = internalKey;
} }
@ -1748,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 // 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 // cache in order to avoid key collisions between internal data and user-defined
@ -1765,12 +1608,6 @@ jQuery.extend({
thisCache[ jQuery.camelCase( name ) ] = data; 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 // Check for both converted-to-camel and non-converted data property names
// If a data property was specified // If a data property was specified
if ( getByName ) { if ( getByName ) {
@ -1798,16 +1635,11 @@ jQuery.extend({
var thisCache, i, l, var thisCache, i, l,
// Reference to internal data cache key
internalKey = jQuery.expando,
isNode = elem.nodeType, isNode = elem.nodeType,
// See jQuery.data for more information // See jQuery.data for more information
cache = isNode ? jQuery.cache : elem, cache = isNode ? jQuery.cache : elem,
id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
// See jQuery.data for more information
id = isNode ? elem[ internalKey ] : internalKey;
// If there is already no cache entry for this object, there is no // If there is already no cache entry for this object, there is no
// purpose in continuing // purpose in continuing
@ -1834,7 +1666,7 @@ jQuery.extend({
if ( name in thisCache ) { if ( name in thisCache ) {
name = [ name ]; name = [ name ];
} else { } else {
name = name.split( " " ); name = name.split(" ");
} }
} }
} }
@ -1857,35 +1689,23 @@ jQuery.extend({
// Don't destroy the parent cache unless the internal data object // Don't destroy the parent cache unless the internal data object
// had been the only thing left in it // had been the only thing left in it
if ( !isEmptyDataObject(cache[ id ]) ) { if ( !isEmptyDataObject( cache[ id ] ) ) {
return; return;
} }
} }
// Browsers that fail expando deletion also refuse to delete expandos on // Destroy the cache
// the window, but it will allow it on all other JS objects; other browsers if ( isNode ) {
// don't care jQuery.cleanData( [ elem ], true );
// Ensure that `cache` is not a window object #10080
if ( jQuery.support.deleteExpando || !cache.setInterval ) { // 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 ]; delete cache[ id ];
// When all else fails, null
} else { } else {
cache[ id ] = null; 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. // For internal use only.
@ -1895,15 +1715,10 @@ jQuery.extend({
// A method for determining if a DOM node can handle the data expando // A method for determining if a DOM node can handle the data expando
acceptData: function( elem ) { acceptData: function( elem ) {
if ( elem.nodeName ) { var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
if ( match ) { // nodes accept data unless otherwise specified; rejection can be conditional
return !(match === true || elem.getAttribute("classid") !== match); return !noData || noData !== true && elem.getAttribute("classid") === noData;
}
}
return true;
} }
}); });
@ -1996,8 +1811,9 @@ function dataAttr( elem, key, data ) {
data = data === "true" ? true : data = data === "true" ? true :
data === "false" ? false : data === "false" ? false :
data === "null" ? null : data === "null" ? null :
jQuery.isNumeric( data ) ? +data : // Only convert to a number if it doesn't change the string
rbrace.test( data ) ? jQuery.parseJSON( data ) : +data + "" === data ? +data :
rbrace.test( data ) ? jQuery.parseJSON( data ) :
data; data;
} catch( e ) {} } catch( e ) {}
@ -2014,7 +1830,8 @@ function dataAttr( elem, key, data ) {
// checks a cache object for emptiness // checks a cache object for emptiness
function isEmptyDataObject( obj ) { 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 the public data object is empty, the private is still empty
if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
@ -2027,73 +1844,23 @@ function isEmptyDataObject( obj ) {
return true; 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({ 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 ) { queue: function( elem, type, data ) {
var q; var queue;
if ( elem ) { if ( elem ) {
type = ( type || "fx" ) + "queue"; 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 // Speed up dequeue by getting out quickly if this is just a lookup
if ( data ) { if ( data ) {
if ( !q || jQuery.isArray(data) ) { if ( !queue || jQuery.isArray(data) ) {
q = jQuery._data( elem, type, jQuery.makeArray(data) ); queue = jQuery._data( elem, type, jQuery.makeArray(data) );
} else { } else {
q.push( data ); queue.push( data );
} }
} }
return q || []; return queue || [];
} }
}, },
@ -2102,7 +1869,10 @@ jQuery.extend({
var queue = jQuery.queue( elem, type ), var queue = jQuery.queue( elem, type ),
fn = queue.shift(), 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 the fx queue is dequeued, always remove the progress sentinel
if ( fn === "inprogress" ) { if ( fn === "inprogress" ) {
@ -2110,22 +1880,31 @@ jQuery.extend({
} }
if ( fn ) { if ( fn ) {
// Add a progress sentinel to prevent the fx queue from being // Add a progress sentinel to prevent the fx queue from being
// automatically dequeued // automatically dequeued
if ( type === "fx" ) { if ( type === "fx" ) {
queue.unshift( "inprogress" ); queue.unshift( "inprogress" );
} }
jQuery._data( elem, type + ".run", hooks ); // clear up the last queue stop function
fn.call( elem, function() { delete hooks.stop;
jQuery.dequeue( elem, type ); fn.call( elem, next, hooks );
}, hooks );
} }
if ( !queue.length && hooks ) {
hooks.empty.fire();
}
},
if ( !queue.length ) { // not intended for public consumption - generates a queueHooks object, or returns the current one
jQuery.removeData( elem, type + "queue " + type + ".run", true ); _queueHooks: function( elem, type ) {
handleQueueMarkDefer( elem, type, "queue" ); 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 );
})
});
} }
}); });
@ -2148,6 +1927,9 @@ jQuery.fn.extend({
this.each(function() { this.each(function() {
var queue = jQuery.queue( this, type, data ); var queue = jQuery.queue( this, type, data );
// ensure a hooks for this queue
jQuery._queueHooks( this, type );
if ( type === "fx" && queue[0] !== "inprogress" ) { if ( type === "fx" && queue[0] !== "inprogress" ) {
jQuery.dequeue( this, type ); jQuery.dequeue( this, type );
} }
@ -2176,51 +1958,42 @@ jQuery.fn.extend({
}, },
// Get a promise resolved when queues of a certain type // Get a promise resolved when queues of a certain type
// are emptied (fx is the type by default) // 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" ) { if ( typeof type !== "string" ) {
object = type; obj = type;
type = undefined; type = undefined;
} }
type = type || "fx"; 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-- ) { while( i-- ) {
if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || if ( (tmp = jQuery._data( elements[ i ], type + "queueHooks" )) && tmp.empty ) {
( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) {
count++; count++;
tmp.add( resolve ); tmp.empty.add( resolve );
} }
} }
resolve(); resolve();
return defer.promise( object ); return defer.promise( obj );
} }
}); });
var nodeHook, boolHook, fixSpecified,
rclass = /[\t\r\n]/g,
var rclass = /[\n\t\r]/g,
rspace = /\s+/,
rreturn = /\r/g, rreturn = /\r/g,
rtype = /^(?:button|input)$/i, rtype = /^(?:button|input)$/i,
rfocusable = /^(?:button|input|object|select|textarea)$/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, rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
getSetAttribute = jQuery.support.getSetAttribute, getSetAttribute = jQuery.support.getSetAttribute;
nodeHook, boolHook, fixSpecified;
jQuery.fn.extend({ jQuery.fn.extend({
attr: function( name, value ) { attr: function( name, value ) {
@ -2259,7 +2032,7 @@ jQuery.fn.extend({
} }
if ( value && typeof value === "string" ) { if ( value && typeof value === "string" ) {
classNames = value.split( rspace ); classNames = value.split( core_rspace );
for ( i = 0, l = this.length; i < l; i++ ) { for ( i = 0, l = this.length; i < l; i++ ) {
elem = this[ i ]; elem = this[ i ];
@ -2286,31 +2059,30 @@ jQuery.fn.extend({
}, },
removeClass: function( value ) { removeClass: function( value ) {
var classNames, i, l, elem, className, c, cl; var removes, className, elem, c, cl, i, l;
if ( jQuery.isFunction( value ) ) { if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) { return this.each(function( j ) {
jQuery( this ).removeClass( value.call(this, j, this.className) ); jQuery( this ).removeClass( value.call(this, j, this.className) );
}); });
} }
if ( (value && typeof value === "string") || value === undefined ) { 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++ ) { for ( i = 0, l = this.length; i < l; i++ ) {
elem = this[ i ]; elem = this[ i ];
if ( elem.nodeType === 1 && elem.className ) { 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 { className = (" " + elem.className + " ").replace( rclass, " " );
elem.className = "";
// 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 ] + " ") > -1 ) {
className = className.replace( " " + removes[ c ] + " " , " " );
}
} }
elem.className = value ? jQuery.trim( className ) : "";
} }
} }
} }
@ -2335,10 +2107,10 @@ jQuery.fn.extend({
i = 0, i = 0,
self = jQuery( this ), self = jQuery( this ),
state = stateVal, state = stateVal,
classNames = value.split( rspace ); classNames = value.split( core_rspace );
while ( (className = classNames[ i++ ]) ) { while ( (className = classNames[ i++ ]) ) {
// check each className given, space seperated list // check each className given, space separated list
state = isBool ? state : !self.hasClass( className ); state = isBool ? state : !self.hasClass( className );
self[ state ? "addClass" : "removeClass" ]( className ); self[ state ? "addClass" : "removeClass" ]( className );
} }
@ -2395,7 +2167,8 @@ jQuery.fn.extend({
isFunction = jQuery.isFunction( value ); isFunction = jQuery.isFunction( value );
return this.each(function( i ) { return this.each(function( i ) {
var self = jQuery(this), val; var val,
self = jQuery(this);
if ( this.nodeType !== 1 ) { if ( this.nodeType !== 1 ) {
return; return;
@ -2497,16 +2270,8 @@ jQuery.extend({
} }
}, },
attrFn: { // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9
val: true, attrFn: {},
css: true,
html: true,
text: true,
data: true,
width: true,
height: true,
offset: true
},
attr: function( elem, name, value, pass ) { attr: function( elem, name, value, pass ) {
var ret, hooks, notxml, var ret, hooks, notxml,
@ -2517,7 +2282,7 @@ jQuery.extend({
return; return;
} }
if ( pass && name in jQuery.attrFn ) { if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {
return jQuery( elem )[ name ]( value ); return jQuery( elem )[ name ]( value );
} }
@ -2564,14 +2329,14 @@ jQuery.extend({
}, },
removeAttr: function( elem, value ) { removeAttr: function( elem, value ) {
var propName, attrNames, name, l, isBool, var propName, attrNames, name, isBool,
i = 0; i = 0;
if ( value && elem.nodeType === 1 ) { 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 ]; name = attrNames[ i ];
if ( name ) { if ( name ) {
@ -2701,9 +2466,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 // Hook for boolean attributes
boolHook = { boolHook = {
get: function( elem, name ) { get: function( elem, name ) {
@ -2750,8 +2512,8 @@ if ( !getSetAttribute ) {
get: function( elem, name ) { get: function( elem, name ) {
var ret; var ret;
ret = elem.getAttributeNode( name ); ret = elem.getAttributeNode( name );
return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ?
ret.nodeValue : ret.value :
undefined; undefined;
}, },
set: function( elem, value, name ) { set: function( elem, value, name ) {
@ -2761,13 +2523,10 @@ if ( !getSetAttribute ) {
ret = document.createAttribute( name ); ret = document.createAttribute( name );
elem.setAttributeNode( ret ); 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 ) // Set width and height to auto instead of 0 on empty string( Bug #8150 )
// This is for removals // This is for removals
jQuery.each([ "width", "height" ], function( i, name ) { jQuery.each([ "width", "height" ], function( i, name ) {
@ -2865,35 +2624,12 @@ jQuery.each([ "radio", "checkbox" ], function() {
} }
}); });
}); });
var rformElems = /^(?:textarea|input|select)$/i, var rformElems = /^(?:textarea|input|select)$/i,
rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/,
rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
rkeyEvent = /^key/, rkeyEvent = /^key/,
rmouseEvent = /^(?:mouse|contextmenu)|click/, rmouseEvent = /^(?:mouse|contextmenu)|click/,
rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 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 ) { hoverHack = function( events ) {
return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
}; };
@ -2908,7 +2644,7 @@ jQuery.event = {
var elemData, eventHandle, events, var elemData, eventHandle, events,
t, tns, type, namespaces, handleObj, 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) // 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 )) ) { if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
@ -2971,7 +2707,6 @@ jQuery.event = {
handler: handler, handler: handler,
guid: handler.guid, guid: handler.guid,
selector: selector, selector: selector,
quick: selector && quickParse( selector ),
namespace: namespaces.join(".") namespace: namespaces.join(".")
}, handleObjIn ); }, handleObjIn );
@ -3021,9 +2756,9 @@ jQuery.event = {
// Detach an event or set of events from an element // Detach an event or set of events from an element
remove: function( elem, types, handler, selector, mappedTypes ) { remove: function( elem, types, handler, selector, mappedTypes ) {
var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), var t, tns, type, origType, namespaces, origCount,
t, tns, type, origType, namespaces, origCount, j, events, special, eventType, handleObj,
j, events, special, handle, eventType, handleObj; elemData = jQuery.hasData( elem ) && jQuery._data( elem );
if ( !elemData || !(events = elemData.events) ) { if ( !elemData || !(events = elemData.events) ) {
return; return;
@ -3048,7 +2783,7 @@ jQuery.event = {
type = ( selector? special.delegateType : special.bindType ) || type; type = ( selector? special.delegateType : special.bindType ) || type;
eventType = events[ type ] || []; eventType = events[ type ] || [];
origCount = eventType.length; origCount = eventType.length;
namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
// Remove matching events // Remove matching events
for ( j = 0; j < eventType.length; j++ ) { for ( j = 0; j < eventType.length; j++ ) {
@ -3072,7 +2807,7 @@ jQuery.event = {
// Remove generic event handler if we removed something and no more handlers exist // Remove generic event handler if we removed something and no more handlers exist
// (avoids potential for endless recursion during removal of special event handlers) // (avoids potential for endless recursion during removal of special event handlers)
if ( eventType.length === 0 && origCount !== eventType.length ) { 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 ); jQuery.removeEvent( elem, type, elemData.handle );
} }
@ -3082,14 +2817,11 @@ jQuery.event = {
// Remove the expando if it's no longer used // Remove the expando if it's no longer used
if ( jQuery.isEmptyObject( events ) ) { if ( jQuery.isEmptyObject( events ) ) {
handle = elemData.handle; delete elemData.handle;
if ( handle ) {
handle.elem = null;
}
// removeData also checks for emptiness and clears the expando if empty // removeData also checks for emptiness and clears the expando if empty
// so use it instead of delete // so use it instead of delete
jQuery.removeData( elem, [ "events", "handle" ], true ); jQuery.removeData( elem, "events", true );
} }
}, },
@ -3108,9 +2840,9 @@ jQuery.event = {
} }
// Event object or event type // Event object or event type
var type = event.type || event, var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType,
namespaces = [], type = event.type || event,
cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; namespaces = [];
// focus/blur morphs to focusin/out; ensure we're not firing them right now // focus/blur morphs to focusin/out; ensure we're not firing them right now
if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
@ -3148,7 +2880,7 @@ jQuery.event = {
event.isTrigger = true; event.isTrigger = true;
event.exclusive = exclusive; event.exclusive = exclusive;
event.namespace = namespaces.join( "." ); 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 : ""; ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
// Handle a global trigger // Handle a global trigger
@ -3187,14 +2919,13 @@ jQuery.event = {
bubbleType = special.delegateType || type; bubbleType = special.delegateType || type;
cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;
old = null; for ( old = elem; cur; cur = cur.parentNode ) {
for ( ; cur; cur = cur.parentNode ) {
eventPath.push([ cur, bubbleType ]); eventPath.push([ cur, bubbleType ]);
old = cur; old = cur;
} }
// Only add window if we got to document (e.g., not plain obj or detached DOM) // 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 ]); eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
} }
} }
@ -3256,13 +2987,13 @@ jQuery.event = {
// Make a writable jQuery.Event from the native event object // Make a writable jQuery.Event from the native event object
event = jQuery.event.fix( event || window.event ); event = jQuery.event.fix( event || window.event );
var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), var i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related,
handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
delegateCount = handlers.delegateCount, delegateCount = handlers.delegateCount,
args = [].slice.call( arguments, 0 ), args = [].slice.call( arguments ),
run_all = !event.exclusive && !event.namespace, run_all = !event.exclusive && !event.namespace,
special = jQuery.event.special[ event.type ] || {}, special = jQuery.event.special[ event.type ] || {},
handlerQueue = [], handlerQueue = [];
i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related;
// Use the fix-ed jQuery.Event rather than the (read-only) native event // Use the fix-ed jQuery.Event rather than the (read-only) native event
args[0] = event; args[0] = event;
@ -3279,12 +3010,12 @@ jQuery.event = {
// Pregenerate a single jQuery object for reuse with .is() // Pregenerate a single jQuery object for reuse with .is()
jqcur = jQuery(this); jqcur = jQuery(this);
jqcur.context = this.ownerDocument || this; jqcur.context = this;
for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
// Don't process events on disabled elements (#6911, #8165) // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #xxxx)
if ( cur.disabled !== true ) { if ( cur.disabled !== true || event.type !== "click" ) {
selMatch = {}; selMatch = {};
matches = []; matches = [];
jqcur[0] = cur; jqcur[0] = cur;
@ -3293,9 +3024,7 @@ jQuery.event = {
sel = handleObj.selector; sel = handleObj.selector;
if ( selMatch[ sel ] === undefined ) { if ( selMatch[ sel ] === undefined ) {
selMatch[ sel ] = ( selMatch[ sel ] = jqcur.is( sel );
handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel )
);
} }
if ( selMatch[ sel ] ) { if ( selMatch[ sel ] ) {
matches.push( handleObj ); matches.push( handleObj );
@ -3429,10 +3158,8 @@ jQuery.event = {
event.target = event.target.parentNode; event.target = event.target.parentNode;
} }
// For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8)
if ( event.metaKey === undefined ) { event.metaKey = !!event.metaKey;
event.metaKey = event.ctrlKey;
}
return fixHook.filter? fixHook.filter( event, originalEvent ) : event; return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
}, },
@ -3505,8 +3232,17 @@ jQuery.removeEvent = document.removeEventListener ?
} }
} : } :
function( elem, type, handle ) { function( elem, type, handle ) {
var name = "on" + type;
if ( elem.detachEvent ) { 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 );
} }
}; };
@ -3603,11 +3339,11 @@ jQuery.each({
bindType: fix, bindType: fix,
handle: function( event ) { handle: function( event ) {
var target = this, var ret,
target = this,
related = event.relatedTarget, related = event.relatedTarget,
handleObj = event.handleObj, handleObj = event.handleObj,
selector = handleObj.selector, selector = handleObj.selector;
ret;
// For mousenter/leave call the handler if related is outside the target. // For mousenter/leave call the handler if related is outside the target.
// NB: No relatedTarget if the mouse left/entered the browser window // NB: No relatedTarget if the mouse left/entered the browser window
@ -3636,16 +3372,16 @@ if ( !jQuery.support.submitBubbles ) {
// Node name check avoids a VML-related crash in IE (#9807) // Node name check avoids a VML-related crash in IE (#9807)
var elem = e.target, var elem = e.target,
form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; 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 ) { jQuery.event.add( form, "submit._submit", function( event ) {
event._submit_bubble = 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 // return undefined since we don't need an event listener
}, },
postDispatch: function( event ) { postDispatch: function( event ) {
// If form was submitted by the user, bubble the event up the tree // If form was submitted by the user, bubble the event up the tree
if ( event._submit_bubble ) { if ( event._submit_bubble ) {
@ -3688,8 +3424,9 @@ if ( !jQuery.support.changeBubbles ) {
jQuery.event.add( this, "click._change", function( event ) { jQuery.event.add( this, "click._change", function( event ) {
if ( this._just_changed && !event.isTrigger ) { if ( this._just_changed && !event.isTrigger ) {
this._just_changed = false; 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; return false;
@ -3698,13 +3435,13 @@ if ( !jQuery.support.changeBubbles ) {
jQuery.event.add( this, "beforeactivate._change", function( e ) { jQuery.event.add( this, "beforeactivate._change", function( e ) {
var elem = e.target; 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 ) { jQuery.event.add( elem, "change._change", function( event ) {
if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
jQuery.event.simulate( "change", this.parentNode, event, true ); jQuery.event.simulate( "change", this.parentNode, event, true );
} }
}); });
elem._change_attached = true; jQuery._data( elem, "_change_attached", true );
} }
}); });
}, },
@ -3810,9 +3547,10 @@ jQuery.fn.extend({
return this.on( types, selector, data, fn, 1 ); return this.on( types, selector, data, fn, 1 );
}, },
off: function( types, selector, fn ) { off: function( types, selector, fn ) {
var handleObj, type;
if ( types && types.preventDefault && types.handleObj ) { if ( types && types.preventDefault && types.handleObj ) {
// ( event ) dispatched jQuery.Event // ( event ) dispatched jQuery.Event
var handleObj = types.handleObj; handleObj = types.handleObj;
jQuery( types.delegateTarget ).off( jQuery( types.delegateTarget ).off(
handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
handleObj.selector, handleObj.selector,
@ -3822,7 +3560,7 @@ jQuery.fn.extend({
} }
if ( typeof types === "object" ) { if ( typeof types === "object" ) {
// ( types-object [, selector] ) // ( types-object [, selector] )
for ( var type in types ) { for ( type in types ) {
this.off( type, selector, types[ type ] ); this.off( type, selector, types[ type ] );
} }
return this; return this;
@ -3861,7 +3599,7 @@ jQuery.fn.extend({
}, },
undelegate: function( selector, types, fn ) { undelegate: function( selector, types, fn ) {
// ( namespace ) or ( 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 ) { trigger: function( type, data ) {
@ -3922,10 +3660,6 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
this.trigger( name ); this.trigger( name );
}; };
if ( jQuery.attrFn ) {
jQuery.attrFn[ name ] = true;
}
if ( rkeyEvent.test( name ) ) { if ( rkeyEvent.test( name ) ) {
jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
} }
@ -3934,1472 +3668,1479 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
} }
}); });
/*!
* Sizzle CSS Selector Engine
* Copyright 2012 jQuery Foundation and other contributors
/*! * Released under the MIT license
* Sizzle CSS Selector Engine * http://sizzlejs.com/
* Copyright 2011, The Dojo Foundation */
* Released under the MIT, BSD, and GPL Licenses. (function( window, undefined ) {
* More information: http://sizzlejs.com/
*/ var cachedruns,
(function(){ dirruns,
sortOrder,
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, siblingCheck,
expando = "sizcache" + (Math.random() + '').replace('.', ''), assertGetIdNotName,
done = 0,
toString = Object.prototype.toString, document = window.document,
hasDuplicate = false, docElem = document.documentElement,
baseHasDuplicate = true,
rBackslash = /\\/g, strundefined = "undefined",
rReturn = /\r\n/g, hasDuplicate = false,
rNonWord = /\W/; baseHasDuplicate = true,
done = 0,
// Here we check if the JavaScript engine is using some sort of slice = [].slice,
// optimization where it does not always call our comparision push = [].push,
// function. If that is the case, discard the hasDuplicate value.
// Thus far that includes Google Chrome. expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
[0, 0].sort(function() {
baseHasDuplicate = false; // Regex
return 0;
}); // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
whitespace = "[\\x20\\t\\r\\n\\f]",
var Sizzle = function( selector, context, results, seed ) { // http://www.w3.org/TR/css3-syntax/#characters
results = results || []; characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
context = context || document;
// Loosely modeled on CSS identifier characters
var origContext = context; // 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
if ( context.nodeType !== 1 && context.nodeType !== 9 ) { identifier = characterEncoding.replace( "w", "w#" ),
return [];
} // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
operators = "([*^$|!~]?=)",
if ( !selector || typeof selector !== "string" ) { attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
return results; "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
} pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",
pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",
var m, set, checkSet, extra, ret, cur, pop, i, combinators = whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*",
prune = true, groups = "(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|" + attributes + "|" + pseudos.replace( 2, 7 ) + "|[^\\\\(),])+",
contextXML = Sizzle.isXML( context ),
parts = [], // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
soFar = selector; rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
// Reset the position of the chunker regexp (start from head) rcombinators = new RegExp( "^" + combinators ),
do {
chunker.exec( "" ); // All simple (non-comma) selectors, excluding insignifant trailing whitespace
m = chunker.exec( soFar ); rgroups = new RegExp( groups + "?(?=" + whitespace + "*,|$)", "g" ),
if ( m ) { // A selector, or everything after leading whitespace
soFar = m[3]; // Optionally followed in either case by a ")" for terminating sub-selectors
rselector = new RegExp( "^(?:(?!,)(?:(?:^|,)" + whitespace + "*" + groups + ")*?|" + whitespace + "*(.*?))(\\)|$)" ),
parts.push( m[1] );
// All combinators and selector components (attribute test, tag, pseudo, etc.), the latter appearing together when consecutive
if ( m[2] ) { rtokens = new RegExp( groups.slice( 19, -6 ) + "\\x20\\t\\r\\n\\f>+~])+|" + combinators, "g" ),
extra = m[3];
break; // Easily-parseable/retrievable ID or TAG or CLASS selectors
} rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
}
} while ( m ); rsibling = /[\x20\t\r\n\f]*[+~]/,
rendsWithNot = /:not\($/,
if ( parts.length > 1 && origPOS.exec( selector ) ) {
rheader = /h\d/i,
if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { rinputs = /input|select|textarea|button/i,
set = posProcess( parts[0] + parts[1], context, seed );
rbackslash = /\\(?!\\)/g,
} else {
set = Expr.relative[ parts[0] ] ? matchExpr = {
[ context ] : "ID": new RegExp( "^#(" + characterEncoding + ")" ),
Sizzle( parts.shift(), context ); "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
"NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
while ( parts.length ) { "TAG": new RegExp( "^(" + characterEncoding.replace( "[-", "[-\\*" ) + ")" ),
selector = parts.shift(); "ATTR": new RegExp( "^" + attributes ),
"PSEUDO": new RegExp( "^" + pseudos ),
if ( Expr.relative[ selector ] ) { "CHILD": new RegExp( "^:(only|nth|last|first)-child(?:\\(" + whitespace +
selector += parts.shift(); "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
} "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
"POS": new RegExp( pos, "ig" ),
set = posProcess( selector, set, seed ); // For use in libraries implementing .is()
} "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
} },
} else { classCache = {},
// Take a shortcut and set the context if the root selector is an ID cachedClasses = [],
// (but not if it'll be faster if the inner selector is an ID) compilerCache = {},
if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && cachedSelectors = [],
Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
// Mark a function for use in filtering
ret = Sizzle.find( parts.shift(), context, contextXML ); markFunction = function( fn ) {
context = ret.expr ? fn.sizzleFilter = true;
Sizzle.filter( ret.expr, ret.set )[0] : return fn;
ret.set[0]; },
}
// Returns a function to use in pseudos for input types
if ( context ) { createInputFunction = function( type ) {
ret = seed ? return function( elem ) {
{ expr: parts.pop(), set: makeArray(seed) } : // Check the input's nodeName and type
Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); return elem.nodeName.toLowerCase() === "input" && elem.type === type;
};
set = ret.expr ? },
Sizzle.filter( ret.expr, ret.set ) :
ret.set; // Returns a function to use in pseudos for buttons
createButtonFunction = function( type ) {
if ( parts.length > 0 ) { return function( elem ) {
checkSet = makeArray( set ); var name = elem.nodeName.toLowerCase();
return (name === "input" || name === "button") && elem.type === type;
} else { };
prune = false; },
}
// Used for testing something on an element
while ( parts.length ) { assert = function( fn ) {
cur = parts.pop(); var pass = false,
pop = cur; div = document.createElement("div");
try {
if ( !Expr.relative[ cur ] ) { pass = fn( div );
cur = ""; } catch (e) {}
} else { // release memory in IE
pop = parts.pop(); div = null;
} return pass;
},
if ( pop == null ) {
pop = context; // Check if attributes should be retrieved by attribute nodes
} assertAttributes = assert(function( div ) {
div.innerHTML = "<select></select>";
Expr.relative[ cur ]( checkSet, pop, contextXML ); var type = typeof div.lastChild.getAttribute("multiple");
} // IE8 returns a string for some attributes even when not present
return type !== "boolean" && type !== "string";
} else { }),
checkSet = parts = [];
} // Check if getElementById returns elements by name
} // Check if getElementsByName privileges form controls or returns elements by ID
assertUsableName = assert(function( div ) {
if ( !checkSet ) { // Inject content
checkSet = set; div.id = expando + 0;
} div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
docElem.insertBefore( div, docElem.firstChild );
if ( !checkSet ) {
Sizzle.error( cur || selector ); // Test
} var pass = document.getElementsByName &&
// buggy browsers will return fewer than the correct 2
if ( toString.call(checkSet) === "[object Array]" ) { document.getElementsByName( expando ).length ===
if ( !prune ) { // buggy browsers will return more than the correct 0
results.push.apply( results, checkSet ); 2 + document.getElementsByName( expando + 0 ).length;
assertGetIdNotName = !document.getElementById( expando );
} else if ( context && context.nodeType === 1 ) {
for ( i = 0; checkSet[i] != null; i++ ) { // Cleanup
if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { docElem.removeChild( div );
results.push( set[i] );
} return pass;
} }),
} else { // Check if the browser returns only elements
for ( i = 0; checkSet[i] != null; i++ ) { // when doing getElementsByTagName("*")
if ( checkSet[i] && checkSet[i].nodeType === 1 ) { assertTagNameNoComments = assert(function( div ) {
results.push( set[i] ); div.appendChild( document.createComment("") );
} return div.getElementsByTagName("*").length === 0;
} }),
}
// Check if getAttribute returns normalized href attributes
} else { assertHrefNotNormalized = assert(function( div ) {
makeArray( checkSet, results ); div.innerHTML = "<a href='#'></a>";
} return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
div.firstChild.getAttribute("href") === "#";
if ( extra ) { }),
Sizzle( extra, origContext, results, seed );
Sizzle.uniqueSort( results ); // Check if getElementsByClassName can be trusted
} assertUsableClassName = assert(function( div ) {
// Opera can't find a second classname (in 9.6)
return results; div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
}; if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
return false;
Sizzle.uniqueSort = function( results ) { }
if ( sortOrder ) {
hasDuplicate = baseHasDuplicate; // Safari caches class attributes, doesn't catch changes (in 3.2)
results.sort( sortOrder ); div.lastChild.className = "e";
return div.getElementsByClassName("e").length !== 1;
if ( hasDuplicate ) { });
for ( var i = 1; i < results.length; i++ ) {
if ( results[i] === results[ i - 1 ] ) { var Sizzle = function( selector, context, results, seed ) {
results.splice( i--, 1 ); results = results || [];
} context = context || document;
} var match, elem, xml, m,
} nodeType = context.nodeType;
}
if ( nodeType !== 1 && nodeType !== 9 ) {
return results; return [];
}; }
Sizzle.matches = function( expr, set ) { if ( !selector || typeof selector !== "string" ) {
return Sizzle( expr, null, null, set ); return results;
}; }
Sizzle.matchesSelector = function( node, expr ) { xml = isXML( context );
return Sizzle( expr, null, null, [node] ).length > 0;
}; if ( !xml && !seed ) {
if ( (match = rquickExpr.exec( selector )) ) {
Sizzle.find = function( expr, context, isXML ) { // Speed-up: Sizzle("#ID")
var set, i, len, match, type, left; if ( (m = match[1]) ) {
if ( nodeType === 9 ) {
if ( !expr ) { elem = context.getElementById( m );
return []; // Check parentNode to catch when Blackberry 4.6 returns
} // nodes that are no longer in the document #6963
if ( elem && elem.parentNode ) {
for ( i = 0, len = Expr.order.length; i < len; i++ ) { // Handle the case where IE, Opera, and Webkit return items
type = Expr.order[i]; // by name instead of ID
if ( elem.id === m ) {
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { results.push( elem );
left = match[1]; return results;
match.splice( 1, 1 ); }
} else {
if ( left.substr( left.length - 1 ) !== "\\" ) { return results;
match[1] = (match[1] || "").replace( rBackslash, "" ); }
set = Expr.find[ type ]( match, context, isXML ); } else {
// Context is not a document
if ( set != null ) { if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
expr = expr.replace( Expr.match[ type ], "" ); contains( context, elem ) && elem.id === m ) {
break; results.push( elem );
} return results;
} }
} }
}
// Speed-up: Sizzle("TAG")
if ( !set ) { } else if ( match[2] ) {
set = typeof context.getElementsByTagName !== "undefined" ? push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
context.getElementsByTagName( "*" ) : return results;
[];
} // Speed-up: Sizzle(".CLASS")
} else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
return { set: set, expr: expr }; push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
}; return results;
}
Sizzle.filter = function( expr, set, inplace, not ) { }
var match, anyFound, }
type, found, item, filter, left,
i, pass, // All others
old = expr, return select( selector, context, results, seed, xml );
result = [], };
curLoop = set,
isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); var Expr = Sizzle.selectors = {
while ( expr && set.length ) { // Can be adjusted by the user
for ( type in Expr.filter ) { cacheLength: 50,
if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
filter = Expr.filter[ type ]; match: matchExpr,
left = match[1];
order: [ "ID", "TAG" ],
anyFound = false;
attrHandle: {},
match.splice(1,1);
createPseudo: markFunction,
if ( left.substr( left.length - 1 ) === "\\" ) {
continue; find: {
} "ID": assertGetIdNotName ?
function( id, context, xml ) {
if ( curLoop === result ) { if ( typeof context.getElementById !== strundefined && !xml ) {
result = []; var m = context.getElementById( id );
} // Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
if ( Expr.preFilter[ type ] ) { return m && m.parentNode ? [m] : [];
match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); }
} :
if ( !match ) { function( id, context, xml ) {
anyFound = found = true; if ( typeof context.getElementById !== strundefined && !xml ) {
var m = context.getElementById( id );
} else if ( match === true ) {
continue; return m ?
} m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
} [m] :
undefined :
if ( match ) { [];
for ( i = 0; (item = curLoop[i]) != null; i++ ) { }
if ( item ) { },
found = filter( item, match, i, curLoop );
pass = not ^ found; "TAG": assertTagNameNoComments ?
function( tag, context ) {
if ( inplace && found != null ) { if ( typeof context.getElementsByTagName !== strundefined ) {
if ( pass ) { return context.getElementsByTagName( tag );
anyFound = true; }
} :
} else { function( tag, context ) {
curLoop[i] = false; var results = context.getElementsByTagName( tag );
}
// Filter out possible comments
} else if ( pass ) { if ( tag === "*" ) {
result.push( item ); var elem,
anyFound = true; tmp = [],
} i = 0;
}
} for ( ; (elem = results[i]); i++ ) {
} if ( elem.nodeType === 1 ) {
tmp.push( elem );
if ( found !== undefined ) { }
if ( !inplace ) { }
curLoop = result;
} return tmp;
}
expr = expr.replace( Expr.match[ type ], "" ); return results;
}
if ( !anyFound ) { },
return [];
} relative: {
">": { dir: "parentNode", first: true },
break; " ": { dir: "parentNode" },
} "+": { dir: "previousSibling", first: true },
} "~": { dir: "previousSibling" }
} },
// Improper expression preFilter: {
if ( expr === old ) { "ATTR": function( match ) {
if ( anyFound == null ) { match[1] = match[1].replace( rbackslash, "" );
Sizzle.error( expr );
// Move the given value to match[3] whether quoted or unquoted
} else { match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
break;
} if ( match[2] === "~=" ) {
} match[3] = " " + match[3] + " ";
}
old = expr;
} return match.slice( 0, 4 );
},
return curLoop;
}; "CHILD": function( match ) {
/* matches from matchExpr.CHILD
Sizzle.error = function( msg ) { 1 type (only|nth|...)
throw new Error( "Syntax error, unrecognized expression: " + msg ); 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
* Utility function for retreiving the text value of an array of DOM nodes 6 sign of y-component
* @param {Array|Element} elem 7 y of y-component
*/ */
var getText = Sizzle.getText = function( elem ) { match[1] = match[1].toLowerCase();
var i, node,
nodeType = elem.nodeType, if ( match[1] === "nth" ) {
ret = ""; // nth-child requires argument
if ( !match[2] ) {
if ( nodeType ) { Sizzle.error( match[0] );
if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { }
// Use textContent || innerText for elements
if ( typeof elem.textContent === 'string' ) { // numeric x and y parameters for Expr.filter.CHILD
return elem.textContent; // remember that false/true cast respectively to 0/1
} else if ( typeof elem.innerText === 'string' ) { match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
// Replace IE's carriage returns match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
return elem.innerText.replace( rReturn, '' );
} else { // other types prohibit arguments
// Traverse it's children } else if ( match[2] ) {
for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { Sizzle.error( match[0] );
ret += getText( elem ); }
}
} return match;
} else if ( nodeType === 3 || nodeType === 4 ) { },
return elem.nodeValue;
} "PSEUDO": function( match ) {
} else { var argument,
unquoted = match[4];
// If no nodeType, this is expected to be an array
for ( i = 0; (node = elem[i]); i++ ) { if ( matchExpr["CHILD"].test( match[0] ) ) {
// Do not traverse comment nodes return null;
if ( node.nodeType !== 8 ) { }
ret += getText( node );
} // Relinquish our claim on characters in `unquoted` from a closing parenthesis on
} if ( unquoted && (argument = rselector.exec( unquoted )) && argument.pop() ) {
}
return ret; match[0] = match[0].slice( 0, argument[0].length - unquoted.length - 1 );
}; unquoted = argument[0].slice( 0, -1 );
}
var Expr = Sizzle.selectors = {
order: [ "ID", "NAME", "TAG" ], // Quoted or unquoted, we have the full argument
// Return only captures needed by the pseudo filter method (type and argument)
match: { match.splice( 2, 3, unquoted || match[3] );
ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, return match;
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\*\-]|\\.)+)/, filter: {
CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, "ID": assertGetIdNotName ?
POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, function( id ) {
PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ id = id.replace( rbackslash, "" );
}, return function( elem ) {
return elem.getAttribute("id") === id;
leftMatch: {}, };
} :
attrMap: { function( id ) {
"class": "className", id = id.replace( rbackslash, "" );
"for": "htmlFor" return function( elem ) {
}, var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
return node && node.value === id;
attrHandle: { };
href: function( elem ) { },
return elem.getAttribute( "href" );
}, "TAG": function( nodeName ) {
type: function( elem ) { if ( nodeName === "*" ) {
return elem.getAttribute( "type" ); return function() { return true; };
} }
}, nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
relative: { return function( elem ) {
"+": function(checkSet, part){ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
var isPartStr = typeof part === "string", };
isTag = isPartStr && !rNonWord.test( part ), },
isPartStrNotTag = isPartStr && !isTag;
"CLASS": function( className ) {
if ( isTag ) { var pattern = classCache[ className ];
part = part.toLowerCase(); if ( !pattern ) {
} pattern = classCache[ className ] = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" );
cachedClasses.push( className );
for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { // Avoid too large of a cache
if ( (elem = checkSet[i]) ) { if ( cachedClasses.length > Expr.cacheLength ) {
while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} delete classCache[ cachedClasses.shift() ];
}
checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? }
elem || false : return function( elem ) {
elem === part; return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
} };
} },
if ( isPartStrNotTag ) { "ATTR": function( name, operator, check ) {
Sizzle.filter( part, checkSet, true ); if ( !operator ) {
} return function( elem ) {
}, return Sizzle.attr( elem, name ) != null;
};
">": function( checkSet, part ) { }
var elem,
isPartStr = typeof part === "string", return function( elem ) {
i = 0, var result = Sizzle.attr( elem, name ),
l = checkSet.length; value = result + "";
if ( isPartStr && !rNonWord.test( part ) ) { if ( result == null ) {
part = part.toLowerCase(); return operator === "!=";
}
for ( ; i < l; i++ ) {
elem = checkSet[i]; switch ( operator ) {
case "=":
if ( elem ) { return value === check;
var parent = elem.parentNode; case "!=":
checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; return value !== check;
} case "^=":
} return check && value.indexOf( check ) === 0;
case "*=":
} else { return check && value.indexOf( check ) > -1;
for ( ; i < l; i++ ) { case "$=":
elem = checkSet[i]; return check && value.substr( value.length - check.length ) === check;
case "~=":
if ( elem ) { return ( " " + value + " " ).indexOf( check ) > -1;
checkSet[i] = isPartStr ? case "|=":
elem.parentNode : return value === check || value.substr( 0, check.length + 1 ) === check + "-";
elem.parentNode === part; }
} };
} },
if ( isPartStr ) { "CHILD": function( type, argument, first, last ) {
Sizzle.filter( part, checkSet, true );
} if ( type === "nth" ) {
} var doneName = done++;
},
return function( elem ) {
"": function(checkSet, part, isXML){ var parent, diff,
var nodeCheck, count = 0,
doneName = done++, node = elem;
checkFn = dirCheck;
if ( first === 1 && last === 0 ) {
if ( typeof part === "string" && !rNonWord.test( part ) ) { return true;
part = part.toLowerCase(); }
nodeCheck = part;
checkFn = dirNodeCheck; parent = elem.parentNode;
}
if ( parent && (parent[ expando ] !== doneName || !elem.sizset) ) {
checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); for ( node = parent.firstChild; node; node = node.nextSibling ) {
}, if ( node.nodeType === 1 ) {
node.sizset = ++count;
"~": function( checkSet, part, isXML ) { if ( node === elem ) {
var nodeCheck, break;
doneName = done++, }
checkFn = dirCheck; }
}
if ( typeof part === "string" && !rNonWord.test( part ) ) {
part = part.toLowerCase(); parent[ expando ] = doneName;
nodeCheck = part; }
checkFn = dirNodeCheck;
} diff = elem.sizset - last;
checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); if ( first === 0 ) {
} return diff === 0;
},
} else {
find: { return ( diff % first === 0 && diff / first >= 0 );
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 function( elem ) {
return m && m.parentNode ? [m] : []; var node = elem;
}
}, switch ( type ) {
case "only":
NAME: function( match, context ) { case "first":
if ( typeof context.getElementsByName !== "undefined" ) { while ( (node = node.previousSibling) ) {
var ret = [], if ( node.nodeType === 1 ) {
results = context.getElementsByName( match[1] ); return false;
}
for ( var i = 0, l = results.length; i < l; i++ ) { }
if ( results[i].getAttribute("name") === match[1] ) {
ret.push( results[i] ); if ( type === "first" ) {
} return true;
} }
return ret.length === 0 ? null : ret; node = elem;
}
}, /* falls through */
case "last":
TAG: function( match, context ) { while ( (node = node.nextSibling) ) {
if ( typeof context.getElementsByTagName !== "undefined" ) { if ( node.nodeType === 1 ) {
return context.getElementsByTagName( match[1] ); return false;
} }
} }
},
preFilter: { return true;
CLASS: function( match, curLoop, inplace, result, not, isXML ) { }
match = " " + match[1].replace( rBackslash, "" ) + " "; };
},
if ( isXML ) {
return match; "PSEUDO": function( pseudo, argument, context, xml ) {
} // pseudo-class names are case-insensitive
// http://www.w3.org/TR/selectors/#pseudo-classes
for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
if ( elem ) { var fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ];
if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
if ( !inplace ) { if ( !fn ) {
result.push( elem ); Sizzle.error( "unsupported pseudo: " + pseudo );
} }
} else if ( inplace ) { // The user may set fn.sizzleFilter to indicate
curLoop[i] = false; // that arguments are needed to create the filter function
} // just as Sizzle does
} if ( !fn.sizzleFilter ) {
} return fn;
}
return false;
}, return fn( argument, context, xml );
}
ID: function( match ) { },
return match[1].replace( rBackslash, "" );
}, pseudos: {
"not": markFunction(function( selector, context, xml ) {
TAG: function( match, curLoop ) { // Trim the selector passed to compile
return match[1].replace( rBackslash, "" ).toLowerCase(); // to avoid treating leading and trailing
}, // spaces as combinators
var matcher = compile( selector.replace( rtrim, "$1" ), context, xml );
CHILD: function( match ) { return function( elem ) {
if ( match[1] === "nth" ) { return !matcher( elem );
if ( !match[2] ) { };
Sizzle.error( match[0] ); }),
}
"enabled": function( elem ) {
match[2] = match[2].replace(/^\+|\s*/g, ''); return elem.disabled === false;
},
// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( "disabled": function( elem ) {
match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || return elem.disabled === true;
!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); },
// calculate the numbers (first)n+(last) including if they are negative "checked": function( elem ) {
match[2] = (test[1] + (test[2] || 1)) - 0; // In CSS3, :checked should return both checked and selected elements
match[3] = test[3] - 0; // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
} var nodeName = elem.nodeName.toLowerCase();
else if ( match[2] ) { return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
Sizzle.error( match[0] ); },
}
"selected": function( elem ) {
// TODO: Move to normal caching system // Accessing this property makes selected-by-default
match[0] = done++; // options in Safari work properly
if ( elem.parentNode ) {
return match; elem.parentNode.selectedIndex;
}, }
ATTR: function( match, curLoop, inplace, result, not, isXML ) { return elem.selected === true;
var name = match[1] = match[1].replace( rBackslash, "" ); },
if ( !isXML && Expr.attrMap[name] ) { "parent": function( elem ) {
match[1] = Expr.attrMap[name]; return !Expr.pseudos["empty"]( elem );
} },
// Handle if an un-quoted value was used "empty": function( elem ) {
match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); // http://www.w3.org/TR/selectors/#empty-pseudo
// :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
if ( match[2] === "~=" ) { // not comment, processing instructions, or others
match[4] = " " + match[4] + " "; // Thanks to Diego Perini for the nodeName shortcut
} // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
var nodeType;
return match; elem = elem.firstChild;
}, while ( elem ) {
if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
PSEUDO: function( match, curLoop, inplace, result, not ) { return false;
if ( match[1] === "not" ) { }
// If we're dealing with a complex expression, or a simple one elem = elem.nextSibling;
if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { }
match[3] = Sizzle(match[3], null, null, curLoop); return true;
},
} else {
var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); "contains": markFunction(function( text ) {
return function( elem ) {
if ( !inplace ) { return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
result.push.apply( result, ret ); };
} }),
return false; "has": markFunction(function( selector ) {
} return function( elem ) {
return Sizzle( selector, elem ).length > 0;
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { };
return true; }),
}
"header": function( elem ) {
return match; return rheader.test( elem.nodeName );
}, },
POS: function( match ) { "text": function( elem ) {
match.unshift( true ); var type, attr;
// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
return match; // use getAttribute instead to test this case
} return elem.nodeName.toLowerCase() === "input" &&
}, (type = elem.type) === "text" &&
( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
filters: { },
enabled: function( elem ) {
return elem.disabled === false && elem.type !== "hidden"; // Input types
}, "radio": createInputFunction("radio"),
"checkbox": createInputFunction("checkbox"),
disabled: function( elem ) { "file": createInputFunction("file"),
return elem.disabled === true; "password": createInputFunction("password"),
}, "image": createInputFunction("image"),
checked: function( elem ) { "submit": createButtonFunction("submit"),
return elem.checked === true; "reset": createButtonFunction("reset"),
},
"button": function( elem ) {
selected: function( elem ) { var name = elem.nodeName.toLowerCase();
// Accessing this property makes selected-by-default return name === "input" && elem.type === "button" || name === "button";
// options in Safari work properly },
if ( elem.parentNode ) {
elem.parentNode.selectedIndex; "input": function( elem ) {
} return rinputs.test( elem.nodeName );
},
return elem.selected === true;
}, "focus": function( elem ) {
var doc = elem.ownerDocument;
parent: function( elem ) { return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href);
return !!elem.firstChild; },
},
"active": function( elem ) {
empty: function( elem ) { return elem === elem.ownerDocument.activeElement;
return !elem.firstChild; }
}, },
has: function( elem, i, match ) { setFilters: {
return !!Sizzle( match[3], elem ).length; "first": function( elements, argument, not ) {
}, return not ? elements.slice( 1 ) : [ elements[0] ];
},
header: function( elem ) {
return (/h\d/i).test( elem.nodeName ); "last": function( elements, argument, not ) {
}, var elem = elements.pop();
return not ? elements : [ elem ];
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) "even": function( elements, argument, not ) {
// use getAttribute instead to test this case var results = [],
return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); i = not ? 1 : 0,
}, len = elements.length;
for ( ; i < len; i = i + 2 ) {
radio: function( elem ) { results.push( elements[i] );
return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; }
}, return results;
},
checkbox: function( elem ) {
return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; "odd": function( elements, argument, not ) {
}, var results = [],
i = not ? 0 : 1,
file: function( elem ) { len = elements.length;
return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; for ( ; i < len; i = i + 2 ) {
}, results.push( elements[i] );
}
password: function( elem ) { return results;
return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; },
},
"lt": function( elements, argument, not ) {
submit: function( elem ) { return not ? elements.slice( +argument ) : elements.slice( 0, +argument );
var name = elem.nodeName.toLowerCase(); },
return (name === "input" || name === "button") && "submit" === elem.type;
}, "gt": function( elements, argument, not ) {
return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 );
image: function( elem ) { },
return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
}, "eq": function( elements, argument, not ) {
var elem = elements.splice( +argument, 1 );
reset: function( elem ) { return not ? elements : elem;
var name = elem.nodeName.toLowerCase(); }
return (name === "input" || name === "button") && "reset" === elem.type; }
}, };
button: function( elem ) { // Deprecated
var name = elem.nodeName.toLowerCase(); Expr.setFilters["nth"] = Expr.setFilters["eq"];
return name === "input" && "button" === elem.type || name === "button";
}, // Back-compat
Expr.filters = Expr.pseudos;
input: function( elem ) {
return (/input|select|textarea|button/i).test( elem.nodeName ); // IE6/7 return a modified href
}, if ( !assertHrefNotNormalized ) {
Expr.attrHandle = {
focus: function( elem ) { "href": function( elem ) {
return elem === elem.ownerDocument.activeElement; return elem.getAttribute( "href", 2 );
} },
}, "type": function( elem ) {
setFilters: { return elem.getAttribute("type");
first: function( elem, i ) { }
return i === 0; };
}, }
last: function( elem, i, match, array ) { // Add getElementsByName if usable
return i === array.length - 1; if ( assertUsableName ) {
}, Expr.order.push("NAME");
Expr.find["NAME"] = function( name, context ) {
even: function( elem, i ) { if ( typeof context.getElementsByName !== strundefined ) {
return i % 2 === 0; return context.getElementsByName( name );
}, }
};
odd: function( elem, i ) { }
return i % 2 === 1;
}, // Add getElementsByClassName if usable
if ( assertUsableClassName ) {
lt: function( elem, i, match ) { Expr.order.splice( 1, 0, "CLASS" );
return i < match[3] - 0; Expr.find["CLASS"] = function( className, context, xml ) {
}, if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
return context.getElementsByClassName( className );
gt: function( elem, i, match ) { }
return i > match[3] - 0; };
}, }
nth: function( elem, i, match ) { // If slice is not available, provide a backup
return match[3] - 0 === i; try {
}, slice.call( docElem.childNodes, 0 )[0].nodeType;
} catch ( e ) {
eq: function( elem, i, match ) { slice = function( i ) {
return match[3] - 0 === i; var elem, results = [];
} for ( ; (elem = this[i]); i++ ) {
}, results.push( elem );
filter: { }
PSEUDO: function( elem, match, i, array ) { return results;
var name = match[1], };
filter = Expr.filters[ name ]; }
if ( filter ) { var isXML = Sizzle.isXML = function( elem ) {
return filter( elem, i, match, array ); // documentElement is verified for cases where it doesn't yet exist
// (such as loading iframes in IE - #4833)
} else if ( name === "contains" ) { var documentElement = elem && (elem.ownerDocument || elem).documentElement;
return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; return documentElement ? documentElement.nodeName !== "HTML" : false;
};
} else if ( name === "not" ) {
var not = match[3]; // Element contains another
var contains = Sizzle.contains = docElem.compareDocumentPosition ?
for ( var j = 0, l = not.length; j < l; j++ ) { function( a, b ) {
if ( not[j] === elem ) { return !!( a.compareDocumentPosition( b ) & 16 );
return false; } :
} docElem.contains ?
} function( a, b ) {
var adown = a.nodeType === 9 ? a.documentElement : a,
return true; bup = b.parentNode;
return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
} else { } :
Sizzle.error( name ); function( a, b ) {
} while ( (b = b.parentNode) ) {
}, if ( b === a ) {
return true;
CHILD: function( elem, match ) { }
var first, last, }
doneName, parent, cache, return false;
count, diff, };
type = match[1],
node = elem; /**
* Utility function for retrieving the text value of an array of DOM nodes
switch ( type ) { * @param {Array|Element} elem
case "only": */
case "first": var getText = Sizzle.getText = function( elem ) {
while ( (node = node.previousSibling) ) { var node,
if ( node.nodeType === 1 ) { ret = "",
return false; i = 0,
} nodeType = elem.nodeType;
}
if ( nodeType ) {
if ( type === "first" ) { if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
return true; // Use textContent for elements
} // innerText usage removed for consistency of new lines (see #11153)
if ( typeof elem.textContent === "string" ) {
node = elem; return elem.textContent;
} else {
/* falls through */ // Traverse its children
case "last": for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
while ( (node = node.nextSibling) ) { ret += getText( elem );
if ( node.nodeType === 1 ) { }
return false; }
} } else if ( nodeType === 3 || nodeType === 4 ) {
} return elem.nodeValue;
}
return true; // Do not include comment or processing instruction nodes
} else {
case "nth":
first = match[2]; // If no nodeType, this is expected to be an array
last = match[3]; for ( ; (node = elem[i]); i++ ) {
// Do not traverse comment nodes
if ( first === 1 && last === 0 ) { ret += getText( node );
return true; }
} }
return ret;
doneName = match[0]; };
parent = elem.parentNode;
Sizzle.attr = function( elem, name ) {
if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { var attr,
count = 0; xml = isXML( elem );
for ( node = parent.firstChild; node; node = node.nextSibling ) { if ( !xml ) {
if ( node.nodeType === 1 ) { name = name.toLowerCase();
node.nodeIndex = ++count; }
} if ( Expr.attrHandle[ name ] ) {
} return Expr.attrHandle[ name ]( elem );
}
parent[ expando ] = doneName; if ( assertAttributes || xml ) {
} return elem.getAttribute( name );
}
diff = elem.nodeIndex - last; attr = elem.getAttributeNode( name );
return attr ?
if ( first === 0 ) { typeof elem[ name ] === "boolean" ?
return diff === 0; elem[ name ] ? name : null :
attr.specified ? attr.value : null :
} else { null;
return ( diff % first === 0 && diff / first >= 0 ); };
}
} Sizzle.error = function( msg ) {
}, throw new Error( "Syntax error, unrecognized expression: " + msg );
};
ID: function( elem, match ) {
return elem.nodeType === 1 && elem.getAttribute("id") === match; // 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.
TAG: function( elem, match ) { // Thus far that includes Google Chrome.
return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; [0, 0].sort(function() {
}, return (baseHasDuplicate = 0);
});
CLASS: function( elem, match ) {
return (" " + (elem.className || elem.getAttribute("class")) + " ")
.indexOf( match ) > -1; if ( docElem.compareDocumentPosition ) {
}, sortOrder = function( a, b ) {
if ( a === b ) {
ATTR: function( elem, match ) { hasDuplicate = true;
var name = match[1], return 0;
result = Sizzle.attr ? }
Sizzle.attr( elem, name ) :
Expr.attrHandle[ name ] ? return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
Expr.attrHandle[ name ]( elem ) : a.compareDocumentPosition :
elem[ name ] != null ? a.compareDocumentPosition(b) & 4
elem[ name ] : ) ? -1 : 1;
elem.getAttribute( name ), };
value = result + "",
type = match[2], } else {
check = match[4]; sortOrder = function( a, b ) {
// The nodes are identical, we can exit early
return result == null ? if ( a === b ) {
type === "!=" : hasDuplicate = true;
!type && Sizzle.attr ? return 0;
result != null :
type === "=" ? // Fallback to using sourceIndex (in IE) if it's available on both nodes
value === check : } else if ( a.sourceIndex && b.sourceIndex ) {
type === "*=" ? return a.sourceIndex - b.sourceIndex;
value.indexOf(check) >= 0 : }
type === "~=" ?
(" " + value + " ").indexOf(check) >= 0 : var al, bl,
!check ? ap = [],
value && result !== false : bp = [],
type === "!=" ? aup = a.parentNode,
value !== check : bup = b.parentNode,
type === "^=" ? cur = aup;
value.indexOf(check) === 0 :
type === "$=" ? // If the nodes are siblings (or identical) we can do a quick check
value.substr(value.length - check.length) === check : if ( aup === bup ) {
type === "|=" ? return siblingCheck( a, b );
value === check || value.substr(0, check.length + 1) === check + "-" :
false; // If no parents were found then the nodes are disconnected
}, } else if ( !aup ) {
return -1;
POS: function( elem, match, i, array ) {
var name = match[2], } else if ( !bup ) {
filter = Expr.setFilters[ name ]; return 1;
}
if ( filter ) {
return filter( elem, i, match, array ); // 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;
}
var origPOS = Expr.match.POS,
fescape = function(all, num){ cur = bup;
return "\\" + (num - 0 + 1);
}; while ( cur ) {
bp.unshift( cur );
for ( var type in Expr.match ) { cur = cur.parentNode;
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) );
} al = ap.length;
// Expose origPOS bl = bp.length;
// "global" as in regardless of relation to brackets/parens
Expr.match.globalPOS = origPOS; // Start walking down the tree looking for a discrepancy
for ( var i = 0; i < al && i < bl; i++ ) {
var makeArray = function( array, results ) { if ( ap[i] !== bp[i] ) {
array = Array.prototype.slice.call( array, 0 ); return siblingCheck( ap[i], bp[i] );
}
if ( results ) { }
results.push.apply( results, array );
return results; // We ended someplace up the tree so do a sibling check
} return i === al ?
siblingCheck( a, bp[i], -1 ) :
return array; siblingCheck( ap[i], b, 1 );
}; };
// Perform a simple check to determine if the browser is capable of siblingCheck = function( a, b, ret ) {
// converting a NodeList to an array using builtin methods. if ( a === b ) {
// Also verifies that the returned array holds DOM nodes return ret;
// (which is not the case in the Blackberry browser) }
try {
Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; var cur = a.nextSibling;
// Provide a fallback method if it does not work while ( cur ) {
} catch( e ) { if ( cur === b ) {
makeArray = function( array, results ) { return -1;
var i = 0, }
ret = results || [];
cur = cur.nextSibling;
if ( toString.call(array) === "[object Array]" ) { }
Array.prototype.push.apply( ret, array );
return 1;
} else { };
if ( typeof array.length === "number" ) { }
for ( var l = array.length; i < l; i++ ) {
ret.push( array[i] ); // Document sorting and removing duplicates
} Sizzle.uniqueSort = function( results ) {
var elem,
} else { i = 1;
for ( ; array[i]; i++ ) {
ret.push( array[i] ); if ( sortOrder ) {
} hasDuplicate = baseHasDuplicate;
} results.sort( sortOrder );
}
if ( hasDuplicate ) {
return ret; for ( ; (elem = results[i]); i++ ) {
}; if ( elem === results[ i - 1 ] ) {
} results.splice( i--, 1 );
}
var sortOrder, siblingCheck; }
}
if ( document.documentElement.compareDocumentPosition ) { }
sortOrder = function( a, b ) {
if ( a === b ) { return results;
hasDuplicate = true; };
return 0;
} function multipleContexts( selector, contexts, results, seed ) {
var i = 0,
if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { len = contexts.length;
return a.compareDocumentPosition ? -1 : 1; for ( ; i < len; i++ ) {
} Sizzle( selector, contexts[i], results, seed );
}
return a.compareDocumentPosition(b) & 4 ? -1 : 1; }
};
function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) {
} else { var results,
sortOrder = function( a, b ) { fn = Expr.setFilters[ posfilter.toLowerCase() ];
// The nodes are identical, we can exit early
if ( a === b ) { if ( !fn ) {
hasDuplicate = true; Sizzle.error( posfilter );
return 0; }
// Fallback to using sourceIndex (in IE) if it's available on both nodes if ( selector || !(results = seed) ) {
} else if ( a.sourceIndex && b.sourceIndex ) { multipleContexts( selector || "*", contexts, (results = []), seed );
return a.sourceIndex - b.sourceIndex; }
}
return results.length > 0 ? fn( results, argument, not ) : [];
var al, bl, }
ap = [],
bp = [], function handlePOS( selector, context, results, seed, groups ) {
aup = a.parentNode, var match, not, anchor, ret, elements, currentContexts, part, lastIndex,
bup = b.parentNode, i = 0,
cur = aup; len = groups.length,
rpos = matchExpr["POS"],
// If the nodes are siblings (or identical) we can do a quick check // This is generated here in case matchExpr["POS"] is extended
if ( aup === bup ) { rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ),
return siblingCheck( a, b ); // This is for making sure non-participating
// matching groups are represented cross-browser (IE6-8)
// If no parents were found then the nodes are disconnected setUndefined = function() {
} else if ( !aup ) { var i = 1,
return -1; len = arguments.length - 2;
for ( ; i < len; i++ ) {
} else if ( !bup ) { if ( arguments[i] === undefined ) {
return 1; match[i] = undefined;
} }
}
// Otherwise they're somewhere else in the tree so we need };
// to build up a full list of the parentNodes for comparison
while ( cur ) { for ( ; i < len; i++ ) {
ap.unshift( cur ); // Reset regex index to 0
cur = cur.parentNode; rpos.exec("");
} selector = groups[i];
ret = [];
cur = bup; anchor = 0;
elements = seed;
while ( cur ) { while ( (match = rpos.exec( selector )) ) {
bp.unshift( cur ); lastIndex = rpos.lastIndex = match.index + match[0].length;
cur = cur.parentNode; if ( lastIndex > anchor ) {
} part = selector.slice( anchor, match.index );
anchor = lastIndex;
al = ap.length; currentContexts = [ context ];
bl = bp.length;
if ( rcombinators.test(part) ) {
// Start walking down the tree looking for a discrepancy if ( elements ) {
for ( var i = 0; i < al && i < bl; i++ ) { currentContexts = elements;
if ( ap[i] !== bp[i] ) { }
return siblingCheck( ap[i], bp[i] ); elements = seed;
} }
}
if ( (not = rendsWithNot.test( part )) ) {
// We ended someplace up the tree so do a sibling check part = part.slice( 0, -5 ).replace( rcombinators, "$&*" );
return i === al ? }
siblingCheck( a, bp[i], -1 ) :
siblingCheck( ap[i], b, 1 ); if ( match.length > 1 ) {
}; match[0].replace( rposgroups, setUndefined );
}
siblingCheck = function( a, b, ret ) { elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not );
if ( a === b ) { }
return ret; }
}
if ( elements ) {
var cur = a.nextSibling; ret = ret.concat( elements );
while ( cur ) { if ( (part = selector.slice( anchor )) && part !== ")" ) {
if ( cur === b ) { if ( rcombinators.test(part) ) {
return -1; multipleContexts( part, ret, results, seed );
} } else {
Sizzle( part, context, results, seed ? seed.concat(elements) : elements );
cur = cur.nextSibling; }
} } else {
push.apply( results, ret );
return 1; }
}; } else {
} Sizzle( selector, context, results, seed );
}
// Check to see if the browser returns elements by name when }
// querying by getElementById (and provide a workaround)
(function(){ // Do not sort if this is a single filter
// We're going to inject a fake input element with a specified name return len === 1 ? results : Sizzle.uniqueSort( results );
var form = document.createElement("div"), }
id = "script" + (new Date()).getTime(),
root = document.documentElement; function tokenize( selector, context, xml ) {
var tokens, soFar, type,
form.innerHTML = "<a name='" + id + "'/>"; groups = [],
i = 0,
// Inject it into the root element, check its status, and remove it quickly
root.insertBefore( form, root.firstChild ); // Catch obvious selector issues: terminal ")"; nonempty fallback match
// rselector never fails to match *something*
// The workaround has to do additional checks after a getElementById match = rselector.exec( selector ),
// Which slows things down for other browsers (hence the branching) matched = !match.pop() && !match.pop(),
if ( document.getElementById( id ) ) { selectorGroups = matched && selector.match( rgroups ) || [""],
Expr.find.ID = function( match, context, isXML ) {
if ( typeof context.getElementById !== "undefined" && !isXML ) { preFilters = Expr.preFilter,
var m = context.getElementById(match[1]); filters = Expr.filter,
checkContext = !xml && context !== document;
return m ?
m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? for ( ; (soFar = selectorGroups[i]) != null && matched; i++ ) {
[m] : groups.push( tokens = [] );
undefined :
[]; // Need to make sure we're within a narrower context if necessary
} // Adding a descendant combinator will generate what is needed
}; if ( checkContext ) {
soFar = " " + soFar;
Expr.filter.ID = function( elem, match ) { }
var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
while ( soFar ) {
return elem.nodeType === 1 && node && node.nodeValue === match; matched = false;
};
} // Combinators
if ( (match = rcombinators.exec( soFar )) ) {
root.removeChild( form ); soFar = soFar.slice( match[0].length );
// release memory in IE // Cast descendant combinators to space
root = form = null; matched = tokens.push({ part: match.pop().replace( rtrim, " " ), captures: match });
})(); }
(function(){ // Filters
// Check to see if the browser returns only elements for ( type in filters ) {
// when doing getElementsByTagName("*") if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
(match = preFilters[ type ]( match, context, xml )) ) ) {
// Create a fake element
var div = document.createElement("div"); soFar = soFar.slice( match.shift().length );
div.appendChild( document.createComment("") ); matched = tokens.push({ part: type, captures: match });
}
// Make sure no comments are found }
if ( div.getElementsByTagName("*").length > 0 ) {
Expr.find.TAG = function( match, context ) { if ( !matched ) {
var results = context.getElementsByTagName( match[1] ); break;
}
// Filter out possible comments }
if ( match[1] === "*" ) { }
var tmp = [];
if ( !matched ) {
for ( var i = 0; results[i]; i++ ) { Sizzle.error( selector );
if ( results[i].nodeType === 1 ) { }
tmp.push( results[i] );
} return groups;
} }
results = tmp; function addCombinator( matcher, combinator, context ) {
} var dir = combinator.dir,
doneName = done++;
return results;
}; if ( !matcher ) {
} // If there is no matcher to check, check against the context
matcher = function( elem ) {
// Check to see if an attribute returns normalized href attributes return elem === context;
div.innerHTML = "<a href='#'></a>"; };
}
if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && return combinator.first ?
div.firstChild.getAttribute("href") !== "#" ) { function( elem, context ) {
while ( (elem = elem[ dir ]) ) {
Expr.attrHandle.href = function( elem ) { if ( elem.nodeType === 1 ) {
return elem.getAttribute( "href", 2 ); return matcher( elem, context ) && elem;
}; }
} }
} :
// release memory in IE function( elem, context ) {
div = null; var cache,
})(); dirkey = doneName + "." + dirruns,
cachedkey = dirkey + "." + cachedruns;
if ( document.querySelectorAll ) { while ( (elem = elem[ dir ]) ) {
(function(){ if ( elem.nodeType === 1 ) {
var oldSizzle = Sizzle, if ( (cache = elem[ expando ]) === cachedkey ) {
div = document.createElement("div"), return elem.sizset;
id = "__sizzle__"; } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
if ( elem.sizset ) {
div.innerHTML = "<p class='TEST'></p>"; return elem;
}
// Safari can't handle uppercase or unicode characters when } else {
// in quirks mode. elem[ expando ] = cachedkey;
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { if ( matcher( elem, context ) ) {
return; elem.sizset = true;
} return elem;
}
Sizzle = function( query, context, extra, seed ) { elem.sizset = false;
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 ); function addMatcher( higher, deeper ) {
return higher ?
if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { function( elem, context ) {
// Speed-up: Sizzle("TAG") var result = deeper( elem, context );
if ( match[1] ) { return result && higher( result === true ? elem : result, context );
return makeArray( context.getElementsByTagName( query ), extra ); } :
deeper;
// Speed-up: Sizzle(".CLASS") }
} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
return makeArray( context.getElementsByClassName( match[2] ), extra ); // ["TAG", ">", "ID", " ", "CLASS"]
} function matcherFromTokens( tokens, context, xml ) {
} var token, matcher,
i = 0;
if ( context.nodeType === 9 ) {
// Speed-up: Sizzle("body") for ( ; (token = tokens[i]); i++ ) {
// The body element only exists once, optimize finding it if ( Expr.relative[ token.part ] ) {
if ( query === "body" && context.body ) { matcher = addCombinator( matcher, Expr.relative[ token.part ], context );
return makeArray( [ context.body ], extra ); } else {
token.captures.push( context, xml );
// Speed-up: Sizzle("#ID") matcher = addMatcher( matcher, Expr.filter[ token.part ].apply( null, token.captures ) );
} else if ( match && match[3] ) { }
var elem = context.getElementById( match[3] ); }
// Check parentNode to catch when Blackberry 4.6 returns return matcher;
// nodes that are no longer in the document #6963 }
if ( elem && elem.parentNode ) {
// Handle the case where IE and Opera return items function matcherFromGroupMatchers( matchers ) {
// by name instead of ID return function( elem, context ) {
if ( elem.id === match[3] ) { var matcher,
return makeArray( [ elem ], extra ); j = 0;
} for ( ; (matcher = matchers[j]); j++ ) {
if ( matcher(elem, context) ) {
} else { return true;
return makeArray( [], extra ); }
} }
} return false;
};
try { }
return makeArray( context.querySelectorAll(query), extra );
} catch(qsaError) {} var compile = Sizzle.compile = function( selector, context, xml ) {
var tokens, group, i,
// qSA works strangely on Element-rooted queries cached = compilerCache[ selector ];
// 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) // Return a cached group function if already generated (context dependent)
// IE 8 doesn't work on object elements if ( cached && cached.context === context ) {
} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { return cached;
var oldContext = context, }
old = context.getAttribute( "id" ),
nid = old || id, // Generate a function of recursive functions that can be used to check each element
hasParent = context.parentNode, group = tokenize( selector, context, xml );
relativeHierarchySelector = /^\s*[+~]/.test( query ); for ( i = 0; (tokens = group[i]); i++ ) {
group[i] = matcherFromTokens( tokens, context, xml );
if ( !old ) { }
context.setAttribute( "id", nid );
} else { // Cache the compiled function
nid = nid.replace( /'/g, "\\$&" ); cached = compilerCache[ selector ] = matcherFromGroupMatchers( group );
} cached.context = context;
if ( relativeHierarchySelector && hasParent ) { cached.runs = cached.dirruns = 0;
context = context.parentNode; cachedSelectors.push( selector );
} // Ensure only the most recent are cached
if ( cachedSelectors.length > Expr.cacheLength ) {
try { delete compilerCache[ cachedSelectors.shift() ];
if ( !relativeHierarchySelector || hasParent ) { }
return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); return cached;
} };
} catch(pseudoError) { Sizzle.matches = function( expr, elements ) {
} finally { return Sizzle( expr, null, null, elements );
if ( !old ) { };
oldContext.removeAttribute( "id" );
} Sizzle.matchesSelector = function( elem, expr ) {
} return Sizzle( expr, null, null, [ elem ] ).length > 0;
} };
}
var select = function( selector, context, results, seed, xml ) {
return oldSizzle(query, context, extra, seed); // Remove excessive whitespace
}; selector = selector.replace( rtrim, "$1" );
var elements, matcher, i, len, elem, token,
for ( var prop in oldSizzle ) { type, findContext, notTokens,
Sizzle[ prop ] = oldSizzle[ prop ]; match = selector.match( rgroups ),
} tokens = selector.match( rtokens ),
contextNodeType = context.nodeType;
// release memory in IE
div = null; // POS handling
})(); if ( matchExpr["POS"].test(selector) ) {
} return handlePOS( selector, context, results, seed, match );
}
(function(){
var html = document.documentElement, if ( seed ) {
matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; elements = slice.call( seed, 0 );
if ( matches ) { // To maintain document order, only narrow the
// Check to see if it's possible to do matchesSelector // set if there is one group
// on a disconnected node (IE 9 fails this) } else if ( match && match.length === 1 ) {
var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
pseudoWorks = false; // Take a shortcut and set the context if the root selector is an ID
if ( tokens.length > 1 && contextNodeType === 9 && !xml &&
try { (match = matchExpr["ID"].exec( tokens[0] )) ) {
// This should fail with an exception
// Gecko does not error, returns false instead context = Expr.find["ID"]( match[1], context, xml )[0];
matches.call( document.documentElement, "[test!='']:sizzle" ); if ( !context ) {
return results;
} catch( pseudoError ) { }
pseudoWorks = true;
} selector = selector.slice( tokens.shift().length );
}
Sizzle.matchesSelector = function( node, expr ) {
// Make sure that attribute selectors are quoted findContext = ( (match = rsibling.exec( tokens[0] )) && !match.index && context.parentNode ) || context;
expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
// Get the last token, excluding :not
if ( !Sizzle.isXML( node ) ) { notTokens = tokens.pop();
try { token = notTokens.split(":not")[0];
if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
var ret = matches.call( node, expr ); for ( i = 0, len = Expr.order.length; i < len; i++ ) {
type = Expr.order[i];
// IE 9's matchesSelector returns false on disconnected nodes
if ( ret || !disconnectedMatch || if ( (match = matchExpr[ type ].exec( token )) ) {
// As well, disconnected nodes are said to be in a document elements = Expr.find[ type ]( (match[1] || "").replace( rbackslash, "" ), findContext, xml );
// fragment in IE 9, so check for that
node.document && node.document.nodeType !== 11 ) { if ( elements == null ) {
return ret; continue;
} }
}
} catch(e) {} if ( token === notTokens ) {
} selector = selector.slice( 0, selector.length - notTokens.length ) +
token.replace( matchExpr[ type ], "" );
return Sizzle(expr, null, null, [node]).length > 0;
}; if ( !selector ) {
} push.apply( results, slice.call(elements, 0) );
})(); }
}
(function(){ break;
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) // Only loop over the given elements once
// Also, make sure that getElementsByClassName actually exists // If selector is empty, we're already done
if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { if ( selector ) {
return; matcher = compile( selector, context, xml );
} dirruns = matcher.dirruns++;
// Safari caches class attributes, doesn't catch changes (in 3.2) if ( elements == null ) {
div.lastChild.className = "e"; elements = Expr.find["TAG"]( "*", (rsibling.test( selector ) && context.parentNode) || context );
}
if ( div.getElementsByClassName("e").length === 1 ) { for ( i = 0; (elem = elements[i]); i++ ) {
return; cachedruns = matcher.runs++;
} if ( matcher(elem, context) ) {
results.push( elem );
Expr.order.splice(1, 0, "CLASS"); }
Expr.find.CLASS = function( match, context, isXML ) { }
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { }
return context.getElementsByClassName(match[1]);
} return results;
}; };
// release memory in IE if ( document.querySelectorAll ) {
div = null; (function() {
})(); var disconnectedMatch,
oldSelect = select,
function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { rescape = /'|\\/g,
for ( var i = 0, l = checkSet.length; i < l; i++ ) { rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
var elem = checkSet[i]; rbuggyQSA = [],
// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
if ( elem ) { // A support test would require too much code (would include document ready)
var match = false; // just skip matchesSelector for :active
rbuggyMatches = [":active"],
elem = elem[dir]; matches = docElem.matchesSelector ||
docElem.mozMatchesSelector ||
while ( elem ) { docElem.webkitMatchesSelector ||
if ( elem[ expando ] === doneName ) { docElem.oMatchesSelector ||
match = checkSet[elem.sizset]; docElem.msMatchesSelector;
break;
} // Build QSA regex
// Regex strategy adopted from Diego Perini
if ( elem.nodeType === 1 && !isXML ){ assert(function( div ) {
elem[ expando ] = doneName; div.innerHTML = "<select><option selected></option></select>";
elem.sizset = i;
} // IE8 - Some boolean attributes are not treated correctly
if ( !div.querySelectorAll("[selected]").length ) {
if ( elem.nodeName.toLowerCase() === cur ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
match = elem; }
break;
} // Webkit/Opera - :checked should return selected option elements
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
elem = elem[dir]; // IE8 throws error here (do not put tests after this one)
} if ( !div.querySelectorAll(":checked").length ) {
rbuggyQSA.push(":checked");
checkSet[i] = match; }
} });
}
} assert(function( div ) {
function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { // Opera 10-12/IE9 - ^= $= *= and empty values
for ( var i = 0, l = checkSet.length; i < l; i++ ) { // Should not select anything
var elem = checkSet[i]; div.innerHTML = "<p test=''></p>";
if ( div.querySelectorAll("[test^='']").length ) {
if ( elem ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
var match = false; }
elem = elem[dir]; // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
// IE8 throws error here (do not put tests after this one)
while ( elem ) { div.innerHTML = "<input type='hidden'>";
if ( elem[ expando ] === doneName ) { if ( !div.querySelectorAll(":enabled").length ) {
match = checkSet[elem.sizset]; rbuggyQSA.push(":enabled", ":disabled");
break; }
} });
if ( elem.nodeType === 1 ) { rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
if ( !isXML ) {
elem[ expando ] = doneName; select = function( selector, context, results, seed, xml ) {
elem.sizset = i; // Only use querySelectorAll when not filtering,
} // when this is not xml,
// and when no QSA bugs apply
if ( typeof cur !== "string" ) { if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
if ( elem === cur ) { if ( context.nodeType === 9 ) {
match = true; try {
break; push.apply( results, slice.call(context.querySelectorAll( selector ), 0) );
} return results;
} catch(qsaError) {}
} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { // qSA works strangely on Element-rooted queries
match = elem; // We can work around this by specifying an extra ID on the root
break; // and working up from there (Thanks to Andrew Dupont for the technique)
} // IE 8 doesn't work on object elements
} } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
var old = context.getAttribute("id"),
elem = elem[dir]; nid = old || expando,
} newContext = rsibling.test( selector ) && context.parentNode || context;
checkSet[i] = match; if ( old ) {
} nid = nid.replace( rescape, "\\$&" );
} } else {
} context.setAttribute( "id", nid );
}
if ( document.documentElement.contains ) {
Sizzle.contains = function( a, b ) { try {
return a !== b && (a.contains ? a.contains(b) : true); push.apply( results, slice.call( newContext.querySelectorAll(
}; selector.replace( rgroups, "[id='" + nid + "'] $&" )
), 0 ) );
} else if ( document.documentElement.compareDocumentPosition ) { return results;
Sizzle.contains = function( a, b ) { } catch(qsaError) {
return !!(a.compareDocumentPosition(b) & 16); } finally {
}; if ( !old ) {
context.removeAttribute("id");
} else { }
Sizzle.contains = function() { }
return false; }
}; }
}
return oldSelect( selector, context, results, seed, xml );
Sizzle.isXML = function( elem ) { };
// documentElement is verified for cases where it doesn't yet exist
// (such as loading iframes in IE - #4833) if ( matches ) {
var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; assert(function( div ) {
// Check to see if it's possible to do matchesSelector
return documentElement ? documentElement.nodeName !== "HTML" : false; // on a disconnected node (IE 9)
}; disconnectedMatch = matches.call( div, "div" );
var posProcess = function( selector, context, seed ) { // This should fail with an exception
var match, // Gecko does not error, returns false instead
tmpSet = [], try {
later = "", matches.call( div, "[test!='']:sizzle" );
root = context.nodeType ? [context] : context; rbuggyMatches.push( Expr.match.PSEUDO );
} catch ( e ) {}
// 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 )) ) { // rbuggyMatches always contains :active, so no need for a length check
later += match[0]; rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
selector = selector.replace( Expr.match.PSEUDO, "" );
} Sizzle.matchesSelector = function( elem, expr ) {
// Make sure that attribute selectors are quoted
selector = Expr.relative[selector] ? selector + "*" : selector; expr = expr.replace( rattributeQuotes, "='$1']" );
for ( var i = 0, l = root.length; i < l; i++ ) { // rbuggyMatches always contains :active, so no need for an existence check
Sizzle( selector, root[i], tmpSet, seed ); if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) {
} try {
var ret = matches.call( elem, expr );
return Sizzle.filter( later, tmpSet );
}; // IE 9's matchesSelector returns false on disconnected nodes
if ( ret || disconnectedMatch ||
// EXPOSE // As well, disconnected nodes are said to be in a document
// fragment in IE 9
elem.document && elem.document.nodeType !== 11 ) {
return ret;
}
} catch(e) {}
}
return Sizzle( expr, null, null, [ elem ] ).length > 0;
};
}
})();
}
// Override sizzle attribute retrieval // Override sizzle attribute retrieval
Sizzle.attr = jQuery.attr; Sizzle.attr = jQuery.attr;
Sizzle.selectors.attrMap = {};
jQuery.find = Sizzle; jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors; jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.filters; jQuery.expr[":"] = jQuery.expr.pseudos;
jQuery.unique = Sizzle.uniqueSort; jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText; jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML; jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains; jQuery.contains = Sizzle.contains;
})(); })( window );
var runtil = /Until$/, var runtil = /Until$/,
rparentsprev = /^(?:parents|prevUntil|prevAll)/, rparentsprev = /^(?:parents|prev(?:Until|All))/,
// Note: This RegExp should be improved, or likely pulled from Sizzle
rmultiselector = /,/,
isSimple = /^.[^:#\[\.,]*$/, isSimple = /^.[^:#\[\.,]*$/,
slice = Array.prototype.slice, rneedsContext = jQuery.expr.match.needsContext,
POS = jQuery.expr.match.globalPOS,
// methods guaranteed to produce a unique set when starting from a unique set // methods guaranteed to produce a unique set when starting from a unique set
guaranteedUnique = { guaranteedUnique = {
children: true, children: true,
@ -5410,8 +5151,8 @@ var runtil = /Until$/,
jQuery.fn.extend({ jQuery.fn.extend({
find: function( selector ) { find: function( selector ) {
var self = this, var i, l, length, n, r, ret,
i, l; self = this;
if ( typeof selector !== "string" ) { if ( typeof selector !== "string" ) {
return jQuery( selector ).filter(function() { return jQuery( selector ).filter(function() {
@ -5423,8 +5164,7 @@ jQuery.fn.extend({
}); });
} }
var ret = this.pushStack( "", "find", selector ), ret = this.pushStack( "", "find", selector );
length, n, r;
for ( i = 0, l = this.length; i < l; i++ ) { for ( i = 0, l = this.length; i < l; i++ ) {
length = ret.length; length = ret.length;
@ -5447,9 +5187,12 @@ jQuery.fn.extend({
}, },
has: function( target ) { has: function( target ) {
var targets = jQuery( target ); var i,
targets = jQuery( target, this ),
len = targets.length;
return this.filter(function() { 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] ) ) { if ( jQuery.contains( this, targets[i] ) ) {
return true; return true;
} }
@ -5468,55 +5211,32 @@ jQuery.fn.extend({
is: function( selector ) { is: function( selector ) {
return !!selector && ( return !!selector && (
typeof selector === "string" ? 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". // 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( selector, this.context ).index( this[0] ) >= 0 :
jQuery.filter( selector, this ).length > 0 : jQuery.filter( selector, this ).length > 0 :
this.filter( selector ).length > 0 ); this.filter( selector ).length > 0 );
}, },
closest: function( selectors, context ) { closest: function( selectors, context ) {
var ret = [], i, l, cur = this[0]; var cur,
i = 0,
// Array (deprecated as of jQuery 1.7) l = this.length,
if ( jQuery.isArray( selectors ) ) { ret = [],
var level = 1; pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
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" ?
jQuery( selectors, context || this.context ) : jQuery( selectors, context || this.context ) :
0; 0;
for ( i = 0, l = this.length; i < l; i++ ) { for ( ; i < l; i++ ) {
cur = this[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) ) { if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
ret.push( cur ); ret.push( cur );
break; break;
} else {
cur = cur.parentNode;
if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
break;
}
} }
cur = cur.parentNode;
} }
} }
@ -5556,17 +5276,29 @@ jQuery.fn.extend({
jQuery.unique( all ) ); jQuery.unique( all ) );
}, },
andSelf: function() { addBack: function( selector ) {
return this.add( this.prevObject ); 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 // A painfully simple check to see if an element is disconnected
// from a document (should be improved, where feasible). // from a document (should be improved, where feasible).
function isDisconnected( node ) { function isDisconnected( node ) {
return !node || !node.parentNode || node.parentNode.nodeType === 11; 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({ jQuery.each({
parent: function( elem ) { parent: function( elem ) {
var parent = elem.parentNode; var parent = elem.parentNode;
@ -5579,10 +5311,10 @@ jQuery.each({
return jQuery.dir( elem, "parentNode", until ); return jQuery.dir( elem, "parentNode", until );
}, },
next: function( elem ) { next: function( elem ) {
return jQuery.nth( elem, 2, "nextSibling" ); return sibling( elem, "nextSibling" );
}, },
prev: function( elem ) { prev: function( elem ) {
return jQuery.nth( elem, 2, "previousSibling" ); return sibling( elem, "previousSibling" );
}, },
nextAll: function( elem ) { nextAll: function( elem ) {
return jQuery.dir( elem, "nextSibling" ); return jQuery.dir( elem, "nextSibling" );
@ -5605,7 +5337,7 @@ jQuery.each({
contents: function( elem ) { contents: function( elem ) {
return jQuery.nodeName( elem, "iframe" ) ? return jQuery.nodeName( elem, "iframe" ) ?
elem.contentDocument || elem.contentWindow.document : elem.contentDocument || elem.contentWindow.document :
jQuery.makeArray( elem.childNodes ); jQuery.merge( [], elem.childNodes );
} }
}, function( name, fn ) { }, function( name, fn ) {
jQuery.fn[ name ] = function( until, selector ) { jQuery.fn[ name ] = function( until, selector ) {
@ -5621,11 +5353,11 @@ jQuery.each({
ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; 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(); ret = ret.reverse();
} }
return this.pushStack( ret, name, slice.call( arguments ).join(",") ); return this.pushStack( ret, name, core_slice.call( arguments ).join(",") );
}; };
}); });
@ -5653,19 +5385,6 @@ jQuery.extend({
return matched; 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 ) { sibling: function( n, elem ) {
var r = []; var r = [];
@ -5713,10 +5432,6 @@ function winnow( elements, qualifier, keep ) {
return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
}); });
} }
function createSafeFragment( document ) { function createSafeFragment( document ) {
var list = nodeNames.split( "|" ), var list = nodeNames.split( "|" ),
safeFrag = document.createDocumentFragment(); safeFrag = document.createDocumentFragment();
@ -5733,19 +5448,20 @@ function createSafeFragment( document ) {
var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|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", "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+/, 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:]+)/, rtagName = /<([\w:]+)/,
rtbody = /<tbody/i, rtbody = /<tbody/i,
rhtml = /<|&#?\w+;/, rhtml = /<|&#?\w+;/,
rnoInnerhtml = /<(?:script|style)/i, rnoInnerhtml = /<(?:script|style|link)/i,
rnocache = /<(?:script|object|embed|option|style)/i, rnocache = /<(?:script|object|embed|option|style)/i,
rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
rcheckableType = /^(?:checkbox|radio)$/,
// checked="checked" or checked // checked="checked" or checked
rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
rscriptType = /\/(java|ecma)script/i, rscriptType = /\/(java|ecma)script/i,
rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/, rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,
wrapMap = { wrapMap = {
option: [ 1, "<select multiple='multiple'>", "</select>" ], option: [ 1, "<select multiple='multiple'>", "</select>" ],
legend: [ 1, "<fieldset>", "</fieldset>" ], legend: [ 1, "<fieldset>", "</fieldset>" ],
@ -5756,15 +5472,17 @@ var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figca
area: [ 1, "<map>", "</map>" ], area: [ 1, "<map>", "</map>" ],
_default: [ 0, "", "" ] _default: [ 0, "", "" ]
}, },
safeFragment = createSafeFragment( document ); safeFragment = createSafeFragment( document ),
fragmentDiv = safeFragment.appendChild( document.createElement("div") );
wrapMap.optgroup = wrapMap.option; wrapMap.optgroup = wrapMap.option;
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
wrapMap.th = wrapMap.td; 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 ) { if ( !jQuery.support.htmlSerialize ) {
wrapMap._default = [ 1, "div<div>", "</div>" ]; wrapMap._default = [ 1, "X<div>", "</div>" ];
} }
jQuery.fn.extend({ jQuery.fn.extend({
@ -5843,7 +5561,7 @@ jQuery.fn.extend({
append: function() { append: function() {
return this.domManip(arguments, true, function( elem ) { return this.domManip(arguments, true, function( elem ) {
if ( this.nodeType === 1 ) { if ( this.nodeType === 1 || this.nodeType === 11 ) {
this.appendChild( elem ); this.appendChild( elem );
} }
}); });
@ -5851,39 +5569,44 @@ jQuery.fn.extend({
prepend: function() { prepend: function() {
return this.domManip(arguments, true, function( elem ) { return this.domManip(arguments, true, function( elem ) {
if ( this.nodeType === 1 ) { if ( this.nodeType === 1 || this.nodeType === 11 ) {
this.insertBefore( elem, this.firstChild ); this.insertBefore( elem, this.firstChild );
} }
}); });
}, },
before: function() { before: function() {
if ( this[0] && this[0].parentNode ) { if ( !isDisconnected( this[0] ) ) {
return this.domManip(arguments, false, function( elem ) { return this.domManip(arguments, false, function( elem ) {
this.parentNode.insertBefore( elem, this ); this.parentNode.insertBefore( elem, this );
}); });
} else if ( arguments.length ) { }
if ( arguments.length ) {
var set = jQuery.clean( arguments ); var set = jQuery.clean( arguments );
set.push.apply( set, this.toArray() ); return this.pushStack( jQuery.merge( set, this ), "before", this.selector );
return this.pushStack( set, "before", arguments );
} }
}, },
after: function() { after: function() {
if ( this[0] && this[0].parentNode ) { if ( !isDisconnected( this[0] ) ) {
return this.domManip(arguments, false, function( elem ) { return this.domManip(arguments, false, function( elem ) {
this.parentNode.insertBefore( elem, this.nextSibling ); this.parentNode.insertBefore( elem, this.nextSibling );
}); });
} else if ( arguments.length ) { }
var set = this.pushStack( this, "after", arguments );
set.push.apply( set, jQuery.clean(arguments) ); if ( arguments.length ) {
return set; var set = jQuery.clean( arguments );
return this.pushStack( jQuery.merge( this, set ), "after", this.selector );
} }
}, },
// keepData is for internal use only--do not document // keepData is for internal use only--do not document
remove: function( selector, keepData ) { 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 ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
if ( !keepData && elem.nodeType === 1 ) { if ( !keepData && elem.nodeType === 1 ) {
jQuery.cleanData( elem.getElementsByTagName("*") ); jQuery.cleanData( elem.getElementsByTagName("*") );
@ -5900,7 +5623,10 @@ jQuery.fn.extend({
}, },
empty: function() { 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 // Remove element nodes and prevent memory leaks
if ( elem.nodeType === 1 ) { if ( elem.nodeType === 1 ) {
jQuery.cleanData( elem.getElementsByTagName("*") ); jQuery.cleanData( elem.getElementsByTagName("*") );
@ -5933,11 +5659,12 @@ jQuery.fn.extend({
if ( value === undefined ) { if ( value === undefined ) {
return elem.nodeType === 1 ? return elem.nodeType === 1 ?
elem.innerHTML.replace( rinlinejQuery, "" ) : elem.innerHTML.replace( rinlinejQuery, "" ) :
null; undefined;
} }
// See if we can take a shortcut and just use innerHTML
if ( typeof value === "string" && !rnoInnerhtml.test( value ) && if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) &&
( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
!wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
@ -5966,7 +5693,7 @@ jQuery.fn.extend({
}, },
replaceWith: function( value ) { 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 // Make sure that the elements are removed from the DOM before they are inserted
// this can help fix replacing a parent with child elements // this can help fix replacing a parent with child elements
if ( jQuery.isFunction( value ) ) { if ( jQuery.isFunction( value ) ) {
@ -5992,11 +5719,11 @@ jQuery.fn.extend({
jQuery(parent).append( value ); 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 ) { detach: function( selector ) {
@ -6004,78 +5731,78 @@ jQuery.fn.extend({
}, },
domManip: function( args, table, callback ) { 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], value = args[0],
scripts = []; scripts = [],
l = this.length;
// We can't cloneNode fragments that contain checked, in WebKit // 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() { return this.each(function() {
jQuery(this).domManip( args, table, callback, true ); jQuery(this).domManip( args, table, callback );
}); });
} }
if ( jQuery.isFunction(value) ) { if ( jQuery.isFunction(value) ) {
return this.each(function(i) { return this.each(function(i) {
var self = jQuery(this); 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 ); self.domManip( args, table, callback );
}); });
} }
if ( this[0] ) { if ( this[0] ) {
parent = value && value.parentNode; results = jQuery.buildFragment( args, this, scripts );
// 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 );
}
fragment = results.fragment; fragment = results.fragment;
first = fragment.firstChild;
if ( fragment.childNodes.length === 1 ) { if ( fragment.childNodes.length === 1 ) {
first = fragment = fragment.firstChild; fragment = first;
} else {
first = fragment.firstChild;
} }
if ( first ) { if ( first ) {
table = table && jQuery.nodeName( first, "tr" ); 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( callback.call(
table ? table && jQuery.nodeName( this[i], "table" ) ?
root(this[i], first) : findOrAppend( this[i], "tbody" ) :
this[i], this[i],
// Make sure that we do not leak memory by inadvertently discarding i === iNoClone ?
// the original fragment (which might have attached data) instead of fragment :
// using it; in addition, use the original fragment object for the last jQuery.clone( fragment, true, true )
// 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
); );
} }
} }
// Fix #11809: Avoid leaking memory
fragment = first = null;
if ( scripts.length ) { if ( scripts.length ) {
jQuery.each( scripts, function( i, elem ) { jQuery.each( scripts, function( i, elem ) {
if ( elem.src ) { if ( elem.src ) {
jQuery.ajax({ if ( jQuery.ajax ) {
type: "GET", jQuery.ajax({
global: false, url: elem.src,
url: elem.src, type: "GET",
async: false, dataType: "script",
dataType: "script" async: false,
}); global: false,
"throws": true
});
} else {
jQuery.error("no ajax");
}
} else { } else {
jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) ); jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) );
} }
if ( elem.parentNode ) { if ( elem.parentNode ) {
@ -6089,11 +5816,8 @@ jQuery.fn.extend({
} }
}); });
function root( elem, cur ) { function findOrAppend( elem, tag ) {
return jQuery.nodeName(elem, "table") ? return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );
(elem.getElementsByTagName("tbody")[0] ||
elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
elem;
} }
function cloneCopyEvent( src, dest ) { function cloneCopyEvent( src, dest ) {
@ -6146,19 +5870,27 @@ function cloneFixAttributes( src, dest ) {
nodeName = dest.nodeName.toLowerCase(); 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" ) { 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 // IE6-8 fails to persist the checked state of a cloned checkbox
// or radio button. Worse, IE6-7 fail to give the cloned element // or radio button. Worse, IE6-7 fail to give the cloned element
// a checked appearance if the defaultChecked value isn't also set // 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 // IE6-7 get confused and end up setting the value of a cloned
// checkbox/radio button to an empty string instead of "on" // checkbox/radio button to an empty string instead of "on"
@ -6184,29 +5916,21 @@ function cloneFixAttributes( src, dest ) {
// Event data gets referenced instead of copied if the expando // Event data gets referenced instead of copied if the expando
// gets copied too // gets copied too
dest.removeAttribute( jQuery.expando ); dest.removeAttribute( jQuery.expando );
// Clear flags for bubbling special change/submit events, they must
// be reattached when the newly cloned events are first activated
dest.removeAttribute( "_submit_attached" );
dest.removeAttribute( "_change_attached" );
} }
jQuery.buildFragment = function( args, nodes, scripts ) { jQuery.buildFragment = function( args, context, scripts ) {
var fragment, cacheable, cacheresults, doc, var fragment, cacheable, cachehit,
first = args[ 0 ]; first = args[ 0 ];
// nodes may contain either an explicit document object, // Set context from what may come in as undefined or a jQuery collection or a node
// a jQuery collection or context object. context = context || document;
// If nodes[0] contains a valid object to assign to doc context = (context[0] || context).ownerDocument || context[0] || context;
if ( nodes && nodes[0] ) {
doc = nodes[0].ownerDocument || nodes[0];
}
// Ensure that an attr object doesn't incorrectly stand in as a document object // 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 // Chrome and Firefox seem to allow this to occur and will throw exception
// Fixes #8950 // Fixes #8950
if ( !doc.createDocumentFragment ) { if ( typeof context.createDocumentFragment === "undefined" ) {
doc = document; context = document;
} }
// Only cache "small" (1/2 KB) HTML strings that are associated with the main document // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
@ -6214,26 +5938,26 @@ jQuery.buildFragment = function( args, nodes, scripts ) {
// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment // 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 // 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 // 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 ) && first.charAt(0) === "<" && !rnocache.test( first ) &&
(jQuery.support.checkClone || !rchecked.test( first )) && (jQuery.support.checkClone || !rchecked.test( first )) &&
(jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {
// Mark cacheable and look for a hit
cacheable = true; cacheable = true;
fragment = jQuery.fragments[ first ];
cacheresults = jQuery.fragments[ first ]; cachehit = fragment !== undefined;
if ( cacheresults && cacheresults !== 1 ) {
fragment = cacheresults;
}
} }
if ( !fragment ) { if ( !fragment ) {
fragment = doc.createDocumentFragment(); fragment = context.createDocumentFragment();
jQuery.clean( args, doc, fragment, scripts ); jQuery.clean( args, context, fragment, scripts );
}
if ( cacheable ) { // Update the cache, but only store false
jQuery.fragments[ first ] = cacheresults ? fragment : 1; // unless this is a second parsing of the same content
if ( cacheable ) {
jQuery.fragments[ first ] = cachehit && fragment;
}
} }
return { fragment: fragment, cacheable: cacheable }; return { fragment: fragment, cacheable: cacheable };
@ -6249,17 +5973,19 @@ jQuery.each({
replaceAll: "replaceWith" replaceAll: "replaceWith"
}, function( name, original ) { }, function( name, original ) {
jQuery.fn[ name ] = function( selector ) { jQuery.fn[ name ] = function( selector ) {
var ret = [], var elems,
i = 0,
ret = [],
insert = jQuery( selector ), insert = jQuery( selector ),
l = insert.length,
parent = this.length === 1 && this[0].parentNode; 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] ); insert[ original ]( this[0] );
return this; return this;
} else { } else {
for ( var i = 0, l = insert.length; i < l; i++ ) { for ( ; i < l; i++ ) {
var elems = ( i > 0 ? this.clone(true) : this ).get(); elems = ( i > 0 ? this.clone(true) : this ).get();
jQuery( insert[i] )[ original ]( elems ); jQuery( insert[i] )[ original ]( elems );
ret = ret.concat( elems ); ret = ret.concat( elems );
} }
@ -6283,39 +6009,26 @@ function getAll( elem ) {
// Used in clean, fixes the defaultChecked property // Used in clean, fixes the defaultChecked property
function fixDefaultChecked( elem ) { function fixDefaultChecked( elem ) {
if ( elem.type === "checkbox" || elem.type === "radio" ) { if ( rcheckableType.test( elem.type ) ) {
elem.defaultChecked = elem.checked; 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({ jQuery.extend({
clone: function( elem, dataAndEvents, deepDataAndEvents ) { clone: function( elem, dataAndEvents, deepDataAndEvents ) {
var srcElements, var srcElements,
destElements, destElements,
i, i,
// IE<=8 does not properly clone detached, unknown element nodes clone;
clone = jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ?
elem.cloneNode( true ) : if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
shimCloneNode( elem ); 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) && if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
@ -6363,17 +6076,17 @@ jQuery.extend({
}, },
clean: function( elems, context, fragment, scripts ) { clean: function( elems, context, fragment, scripts ) {
var checkScriptType, script, j, var j, safe, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,
ret = []; i = 0,
ret = [];
context = context || document; // Ensure that context is a document
if ( !context || typeof context.createDocumentFragment === "undefined" ) {
// !context.createElement fails in IE with an error but returns typeof 'object' context = document;
if ( typeof context.createElement === "undefined" ) {
context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
} }
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { // Use the already-created safe fragment if context permits
for ( safe = context === document && safeFragment; (elem = elems[i]) != null; i++ ) {
if ( typeof elem === "number" ) { if ( typeof elem === "number" ) {
elem += ""; elem += "";
} }
@ -6387,27 +6100,17 @@ jQuery.extend({
if ( !rhtml.test( elem ) ) { if ( !rhtml.test( elem ) ) {
elem = context.createTextNode( elem ); elem = context.createTextNode( elem );
} else { } else {
// Ensure a safe container in which to render the html
safe = safe || createSafeFragment( context );
div = div || safe.appendChild( context.createElement("div") );
// Fix "XHTML"-style tags in all browsers // Fix "XHTML"-style tags in all browsers
elem = elem.replace(rxhtmlTag, "<$1></$2>"); 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"),
safeChildNodes = safeFragment.childNodes,
remove;
// 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 // 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]; div.innerHTML = wrap[1] + elem + wrap[2];
// Move to the right depth // Move to the right depth
@ -6419,7 +6122,7 @@ jQuery.extend({
if ( !jQuery.support.tbody ) { if ( !jQuery.support.tbody ) {
// String was a <table>, *may* have spurious <tbody> // String was a <table>, *may* have spurious <tbody>
var hasBody = rtbody.test(elem), hasBody = rtbody.test(elem);
tbody = tag === "table" && !hasBody ? tbody = tag === "table" && !hasBody ?
div.firstChild && div.firstChild.childNodes : div.firstChild && div.firstChild.childNodes :
@ -6442,33 +6145,8 @@ jQuery.extend({
elem = div.childNodes; elem = div.childNodes;
// Clear elements from DocumentFragment (safeFragment or otherwise) // Remember the top-level container for proper cleanup
// to avoid hoarding elements. Fixes #11356 div = safe.lastChild;
if ( div ) {
div.parentNode.removeChild( div );
// Guard against -1 index exceptions in FF3.6
if ( safeChildNodes.length > 0 ) {
remove = safeChildNodes[ safeChildNodes.length - 1 ];
if ( remove && remove.parentNode ) {
remove.parentNode.removeChild( remove );
}
}
}
}
}
// 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 );
} }
} }
@ -6479,22 +6157,51 @@ jQuery.extend({
} }
} }
// Fix #11356: Clear elements from safeFragment
if ( div ) {
safe.removeChild( 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 ) { if ( fragment ) {
checkScriptType = function( elem ) { // Special handling of each script element
return !elem.type || rscriptType.test( elem.type ); 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++ ) {
script = ret[i];
if ( scripts && jQuery.nodeName( script, "script" ) && (!script.type || rscriptType.test( script.type )) ) {
scripts.push( script.parentNode ? script.parentNode.removeChild( script ) : script );
} else { for ( i = 0; (elem = ret[i]) != null; i++ ) {
if ( script.nodeType === 1 ) { // Check if we're done after handling an executable script
var jsTags = jQuery.grep( script.getElementsByTagName( "script" ), checkScriptType ); 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 ) ); ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
i += jsTags.length;
} }
fragment.appendChild( script );
} }
} }
} }
@ -6502,81 +6209,250 @@ jQuery.extend({
return ret; return ret;
}, },
cleanData: function( elems ) { cleanData: function( elems, /* internal */ acceptData ) {
var data, id, var data, id, elem, type,
i = 0,
internalKey = jQuery.expando,
cache = jQuery.cache, 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++ ) { for ( ; (elem = elems[i]) != null; i++ ) {
if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
continue;
}
id = elem[ jQuery.expando ]; if ( acceptData || jQuery.acceptData( elem ) ) {
if ( id ) { id = elem[ internalKey ];
data = cache[ id ]; data = id && cache[ id ];
if ( data && data.events ) { if ( data ) {
for ( var type in data.events ) { if ( data.events ) {
if ( special[ type ] ) { for ( type in data.events ) {
jQuery.event.remove( elem, type ); if ( special[ type ] ) {
jQuery.event.remove( elem, type );
// This is a shortcut to avoid jQuery.event.remove's overhead // This is a shortcut to avoid jQuery.event.remove's overhead
} else { } else {
jQuery.removeEvent( elem, type, data.handle ); jQuery.removeEvent( elem, type, data.handle );
}
} }
} }
// Null the DOM reference to avoid IE6/7/8 leak (#7054) // Remove cache only if it was not already removed by jQuery.event.remove
if ( data.handle ) { if ( cache[ id ] ) {
data.handle.elem = null;
delete cache[ id ];
// 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 );
} else {
elem[ internalKey ] = null;
}
jQuery.deletedIds.push( id );
} }
} }
if ( deleteExpando ) {
delete elem[ jQuery.expando ];
} else if ( elem.removeAttribute ) {
elem.removeAttribute( jQuery.expando );
}
delete cache[ 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 ) ||
[];
var ralpha = /alpha\([^)]*\)/i, return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
matched = jQuery.uaMatch( navigator.userAgent );
browser = {};
if ( matched.browser ) {
browser[ matched.browser ] = true;
browser.version = matched.version;
}
// Deprecated, use jQuery.browser.webkit instead
// Maintained for back-compat only
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 curCSS, iframe, iframeDoc,
ralpha = /alpha\([^)]*\)/i,
ropacity = /opacity=([^)]*)/, ropacity = /opacity=([^)]*)/,
// fixed for IE9, see #8346 rposition = /^(top|right|bottom|left)$/,
rupper = /([A-Z]|^ms)/g,
rnum = /^[\-+]?(?:\d*\.)?\d+$/i,
rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,
rrelNum = /^([\-+])=([\-+.\de]+)/,
rmargin = /^margin/, 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" }, cssShow = { position: "absolute", visibility: "hidden", display: "block" },
cssNormalTransform = {
letterSpacing: 0,
fontWeight: 400,
lineHeight: 1
},
// order is important!
cssExpand = [ "Top", "Right", "Bottom", "Left" ], cssExpand = [ "Top", "Right", "Bottom", "Left" ],
cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
curCSS, eventsToggle = jQuery.fn.toggle;
getComputedStyle, // return a css property mapped to a potentially vendor prefixed property
currentStyle; function vendorPropName( style, name ) {
jQuery.fn.css = function( name, value ) { // shortcut for names that are not vendor prefixed
return jQuery.access( this, function( elem, name, value ) { if ( name in style ) {
return value !== undefined ? return name;
jQuery.style( elem, name, value ) : }
jQuery.css( elem, name );
}, name, value, arguments.length > 1 ); // 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({ jQuery.extend({
// Add in style property hooks for overriding the default // Add in style property hooks for overriding the default
@ -6589,8 +6465,6 @@ jQuery.extend({
var ret = curCSS( elem, "opacity" ); var ret = curCSS( elem, "opacity" );
return ret === "" ? "1" : ret; return ret === "" ? "1" : ret;
} else {
return elem.style.opacity;
} }
} }
} }
@ -6623,10 +6497,15 @@ jQuery.extend({
} }
// Make sure that we're working with the right name // Make sure that we're working with the right name
var ret, type, origName = jQuery.camelCase( name ), var ret, type, hooks,
style = elem.style, hooks = jQuery.cssHooks[ origName ]; 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 // Check if we're setting a value
if ( value !== undefined ) { if ( value !== undefined ) {
@ -6634,7 +6513,7 @@ jQuery.extend({
// convert relative number strings (+= or -=) to relative numbers. #7345 // convert relative number strings (+= or -=) to relative numbers. #7345
if ( type === "string" && (ret = rrelNum.exec( value )) ) { 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 // Fixes bug #9237
type = "number"; type = "number";
} }
@ -6650,7 +6529,7 @@ jQuery.extend({
} }
// If a hook was provided, use that value, otherwise just set the specified value // 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 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
// Fixes bug #5509 // Fixes bug #5509
try { try {
@ -6669,33 +6548,44 @@ jQuery.extend({
} }
}, },
css: function( elem, name, extra ) { css: function( elem, name, numeric, extra ) {
var ret, hooks; var val, num, hooks,
origName = jQuery.camelCase( name );
// Make sure that we're working with the right name // Make sure that we're working with the right name
name = jQuery.camelCase( name ); name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
hooks = jQuery.cssHooks[ name ];
name = jQuery.cssProps[ name ] || name;
// cssFloat needs a special treatment // gets hook for the prefixed version
if ( name === "cssFloat" ) { // followed by the unprefixed version
name = "float"; hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
}
// If a hook was provided get the computed value from there // If a hook was provided get the computed value from there
if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { if ( hooks && "get" in hooks ) {
return ret; val = hooks.get( elem, true, extra );
}
// Otherwise, if a way to get the computed value exists, use that // Otherwise, if a way to get the computed value exists, use that
} else if ( curCSS ) { if ( val === undefined ) {
return curCSS( elem, name ); 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 // A method for quickly swapping in/out CSS properties to get correct calculations
swap: function( elem, options, callback ) { swap: function( elem, options, callback ) {
var old = {}, var ret, name,
ret, name; old = {};
// Remember the old values, and insert the new ones // Remember the old values, and insert the new ones
for ( name in options ) { for ( name in options ) {
@ -6714,49 +6604,51 @@ jQuery.extend({
} }
}); });
// DEPRECATED in 1.3, Use jQuery.css() instead // NOTE: To any future maintainer, we've used both window.getComputedStyle
jQuery.curCSS = jQuery.css; // and getComputedStyle here to produce a better gzip size
if ( window.getComputedStyle ) {
if ( document.defaultView && document.defaultView.getComputedStyle ) { curCSS = function( elem, name ) {
getComputedStyle = function( elem, name ) { var ret, width, minWidth, maxWidth,
var ret, defaultView, computedStyle, width, computed = getComputedStyle( elem, null ),
style = elem.style; style = elem.style;
name = name.replace( rupper, "-$1" ).toLowerCase(); if ( computed ) {
if ( (defaultView = elem.ownerDocument.defaultView) && ret = computed[ name ];
(computedStyle = defaultView.getComputedStyle( elem, null )) ) {
ret = computedStyle.getPropertyValue( name );
if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
ret = jQuery.style( elem, name ); ret = jQuery.style( elem, name );
} }
}
// A tribute to the "awesome hack by Dean Edwards" // A tribute to the "awesome hack by Dean Edwards"
// WebKit uses "computed value (percentage if specified)" instead of "used value" for margins // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
// which is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
if ( !jQuery.support.pixelMargin && computedStyle && rmargin.test( name ) && rnumnonpx.test( ret ) ) { // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
width = style.width; if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
style.width = ret; width = style.width;
ret = computedStyle.width; minWidth = style.minWidth;
style.width = width; maxWidth = style.maxWidth;
style.minWidth = style.maxWidth = style.width = ret;
ret = computed.width;
style.width = width;
style.minWidth = minWidth;
style.maxWidth = maxWidth;
}
} }
return ret; return ret;
}; };
} } else if ( document.documentElement.currentStyle ) {
curCSS = function( elem, name ) {
if ( document.documentElement.currentStyle ) { var left, rsLeft,
currentStyle = function( elem, name ) {
var left, rsLeft, uncomputed,
ret = elem.currentStyle && elem.currentStyle[ name ], ret = elem.currentStyle && elem.currentStyle[ name ],
style = elem.style; style = elem.style;
// Avoid setting ret to empty string here // Avoid setting ret to empty string here
// so we don't default to auto // so we don't default to auto
if ( ret == null && style && (uncomputed = style[ name ]) ) { if ( ret == null && style && style[ name ] ) {
ret = uncomputed; ret = style[ name ];
} }
// From the awesome hack by Dean Edwards // From the awesome hack by Dean Edwards
@ -6764,7 +6656,9 @@ if ( document.documentElement.currentStyle ) {
// If we're not dealing with a regular pixel number // 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 a number that has a weird ending, we need to convert it to pixels
if ( rnumnonpx.test( ret ) ) { // 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 // Remember the original values
left = style.left; left = style.left;
@ -6788,67 +6682,142 @@ if ( document.documentElement.currentStyle ) {
}; };
} }
curCSS = getComputedStyle || currentStyle; 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 ) { function getWidthOrHeight( elem, name, extra ) {
// Start with offset property // Start with offset property, which is equivalent to the border-box value
var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
i = name === "width" ? 1 : 0, valueIsBorderBox = true,
len = 4; isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box";
if ( val > 0 ) { if ( val <= 0 ) {
if ( extra !== "border" ) { // Fall back to computed then uncomputed css if necessary
for ( ; i < len; i += 2 ) { val = curCSS( elem, name );
if ( !extra ) { if ( val < 0 || val == null ) {
val -= parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0; val = elem.style[ name ];
}
if ( extra === "margin" ) {
val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0;
} else {
val -= parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
}
}
} }
return val + "px"; // Computed unit is not pixels. Stop here and return.
} if ( rnumnonpx.test(val) ) {
return val;
// 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;
}
// Normalize "", auto, and prepare for extra
val = parseFloat( val ) || 0;
// Add padding, border, margin
if ( extra ) {
for ( ; i < len; i += 2 ) {
val += parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;
if ( extra !== "padding" ) {
val += parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
}
if ( extra === "margin" ) {
val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ]) ) || 0;
}
} }
// 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 ] );
// Normalize "", auto, and prepare for extra
val = parseFloat( val ) || 0;
} }
return val + "px"; // 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.each([ "height", "width" ], function( i, name ) {
jQuery.cssHooks[ name ] = { jQuery.cssHooks[ name ] = {
get: function( elem, computed, extra ) { get: function( elem, computed, extra ) {
if ( computed ) { if ( computed ) {
if ( elem.offsetWidth !== 0 ) { if ( elem.offsetWidth !== 0 || curCSS( elem, "display" ) !== "none" ) {
return getWidthOrHeight( elem, name, extra ); return getWidthOrHeight( elem, name, extra );
} else { } else {
return jQuery.swap( elem, cssShow, function() { return jQuery.swap( elem, cssShow, function() {
@ -6858,10 +6827,15 @@ jQuery.each([ "height", "width" ], function( i, name ) {
} }
}, },
set: function( elem, value ) { set: function( elem, value, extra ) {
return rnum.test( value ) ? return setPositiveNumber( elem, value, extra ?
value + "px" : augmentWidthOrHeight(
value; elem,
name,
extra,
jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"
) : 0
);
} }
}; };
}); });
@ -6871,7 +6845,7 @@ if ( !jQuery.support.opacity ) {
get: function( elem, computed ) { get: function( elem, computed ) {
// IE uses filters for opacity // IE uses filters for opacity
return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
( parseFloat( RegExp.$1 ) / 100 ) + "" : ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
computed ? "1" : ""; computed ? "1" : "";
}, },
@ -6886,7 +6860,8 @@ if ( !jQuery.support.opacity ) {
style.zoom = 1; style.zoom = 1;
// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 // 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 // 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 // if "filter:" is present at all, clearType is disabled, we want to avoid this
@ -6907,9 +6882,9 @@ 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() { 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 ) { if ( !jQuery.support.reliableMarginRight ) {
jQuery.cssHooks.marginRight = { jQuery.cssHooks.marginRight = {
get: function( elem, computed ) { get: function( elem, computed ) {
@ -6917,22 +6892,35 @@ jQuery(function() {
// Work around by temporarily setting element display to inline-block // Work around by temporarily setting element display to inline-block
return jQuery.swap( elem, { "display": "inline-block" }, function() { return jQuery.swap( elem, { "display": "inline-block" }, function() {
if ( computed ) { if ( computed ) {
return curCSS( elem, "margin-right" ); return curCSS( elem, "marginRight" );
} else {
return elem.style.marginRight;
} }
}); });
} }
}; };
} }
// 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;
}
}
};
});
}
}); });
if ( jQuery.expr && jQuery.expr.filters ) { if ( jQuery.expr && jQuery.expr.filters ) {
jQuery.expr.filters.hidden = function( elem ) { jQuery.expr.filters.hidden = function( elem ) {
var width = elem.offsetWidth, return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none");
height = elem.offsetHeight;
return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
}; };
jQuery.expr.filters.visible = function( elem ) { jQuery.expr.filters.visible = function( elem ) {
@ -6946,7 +6934,6 @@ jQuery.each({
padding: "", padding: "",
border: "Width" border: "Width"
}, function( prefix, suffix ) { }, function( prefix, suffix ) {
jQuery.cssHooks[ prefix + suffix ] = { jQuery.cssHooks[ prefix + suffix ] = {
expand: function( value ) { expand: function( value ) {
var i, var i,
@ -6963,27 +6950,127 @@ jQuery.each({
return expanded; return expanded;
} }
}; };
if ( !rmargin.test( prefix ) ) {
jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
}
}); });
var r20 = /%20/g, var r20 = /%20/g,
rbracket = /\[\]$/, rbracket = /\[\]$/,
rCRLF = /\r?\n/g, 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;
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();
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();
}
});
//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 );
};
// Set traditional to true for jQuery <= 1.3.2 behavior.
if ( traditional === undefined ) {
traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
}
// 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 );
});
} 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 the resulting serialization
return s.join( "&" ).replace( r20, "+" );
};
function buildParams( prefix, obj, traditional, add ) {
var name;
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
ajaxLocation,
// Document location segments
ajaxLocParts,
rhash = /#.*$/, rhash = /#.*$/,
rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL 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 // #7653, #8125, #8152: local protocol detection
rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
rnoContent = /^(?:GET|HEAD)$/, rnoContent = /^(?:GET|HEAD)$/,
rprotocol = /^\/\//, rprotocol = /^\/\//,
rquery = /\?/, rquery = /\?/,
rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
rselectTextarea = /^(?:select|textarea)/i,
rspacesAjax = /\s+/,
rts = /([?&])_=[^&]*/, rts = /([?&])_=[^&]*/,
rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/, rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
// Keep a copy of the old load method // Keep a copy of the old load method
_load = jQuery.fn.load, _load = jQuery.fn.load,
@ -7006,12 +7093,6 @@ var r20 = /%20/g,
*/ */
transports = {}, transports = {},
// Document location
ajaxLocation,
// Document location segments
ajaxLocParts,
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
allTypes = ["*/"] + ["*"]; allTypes = ["*/"] + ["*"];
@ -7041,14 +7122,12 @@ function addToPrefiltersOrTransports( structure ) {
dataTypeExpression = "*"; dataTypeExpression = "*";
} }
if ( jQuery.isFunction( func ) ) { var dataType, list, placeBefore,
var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ), dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ),
i = 0, i = 0,
length = dataTypes.length, length = dataTypes.length;
dataType,
list,
placeBefore;
if ( jQuery.isFunction( func ) ) {
// For each dataType in the dataTypeExpression // For each dataType in the dataTypeExpression
for ( ; i < length; i++ ) { for ( ; i < length; i++ ) {
dataType = dataTypes[ i ]; dataType = dataTypes[ i ];
@ -7075,11 +7154,11 @@ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqX
inspected[ dataType ] = true; inspected[ dataType ] = true;
var list = structure[ dataType ], var selection,
list = structure[ dataType ],
i = 0, i = 0,
length = list ? list.length : 0, length = list ? list.length : 0,
executeOnly = ( structure === prefilters ), executeOnly = ( structure === prefilters );
selection;
for ( ; i < length && ( executeOnly || !selection ); i++ ) { for ( ; i < length && ( executeOnly || !selection ); i++ ) {
selection = list[ i ]( options, originalOptions, jqXHR ); selection = list[ i ]( options, originalOptions, jqXHR );
@ -7122,109 +7201,75 @@ function ajaxExtend( target, src ) {
} }
} }
jQuery.fn.extend({ jQuery.fn.load = function( url, params, callback ) {
load: function( url, params, callback ) { if ( typeof url !== "string" && _load ) {
if ( typeof url !== "string" && _load ) { return _load.apply( this, arguments );
return _load.apply( this, arguments );
// Don't do a request if no elements are being requested
} else if ( !this.length ) {
return this;
}
var off = url.indexOf( " " );
if ( off >= 0 ) {
var selector = url.slice( off, url.length );
url = url.slice( 0, off );
}
// Default to a GET request
var type = "GET";
// If the second parameter was provided
if ( params ) {
// If it's a function
if ( jQuery.isFunction( params ) ) {
// We assume that it's the callback
callback = params;
params = undefined;
// Otherwise, build a param string
} else if ( typeof params === "object" ) {
params = jQuery.param( params, jQuery.ajaxSettings.traditional );
type = "POST";
}
}
var self = this;
// Request the remote document
jQuery.ajax({
url: url,
type: type,
dataType: "html",
data: params,
// Complete callback (responseText is used internally)
complete: function( jqXHR, status, responseText ) {
// Store the response as specified by the jqXHR object
responseText = jqXHR.responseText;
// If successful, inject the HTML into all the matched elements
if ( jqXHR.isResolved() ) {
// #4825: Get the actual response in case
// a dataFilter is present in ajaxSettings
jqXHR.done(function( r ) {
responseText = r;
});
// See if a selector was specified
self.html( selector ?
// Create a dummy div to hold the results
jQuery("<div>")
// inject the contents of the document in, removing the scripts
// to avoid any 'Permission Denied' errors in IE
.append(responseText.replace(rscript, ""))
// Locate the specified elements
.find(selector) :
// If not, just inject the full result
responseText );
}
if ( callback ) {
self.each( callback, [ responseText, status, jqXHR ] );
}
}
});
return this;
},
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();
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();
} }
});
// Don't do a request if no elements are being requested
if ( !this.length ) {
return this;
}
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;
// Otherwise, build a param string
} else if ( typeof params === "object" ) {
type = "POST";
}
// Request the remote document
jQuery.ajax({
url: url,
// if "type" variable is undefined, then "GET" method will be used
type: type,
dataType: "html",
data: params,
complete: function( jqXHR, status ) {
if ( callback ) {
self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
}
}
}).done(function( responseText ) {
// Save response for use in complete callback
response = arguments;
// See if a selector was specified
self.html( selector ?
// Create a dummy div to hold the results
jQuery("<div>")
// inject the contents of the document in, removing the scripts
// to avoid any 'Permission Denied' errors in IE
.append( responseText.replace( rscript, "" ) )
// Locate the specified elements
.find( selector ) :
// If not, just inject the full result
responseText );
});
return this;
};
// Attach a bunch of functions for handling common AJAX events // Attach a bunch of functions for handling common AJAX events
jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
@ -7293,6 +7338,7 @@ jQuery.extend({
username: null, username: null,
password: null, password: null,
cache: null, cache: null,
throws: false,
traditional: false, traditional: false,
headers: {}, headers: {},
*/ */
@ -7359,7 +7405,22 @@ jQuery.extend({
// Force options to be an object // Force options to be an object
options = options || {}; options = options || {};
var // Create the final options object var // ifModified key
ifModifiedKey,
// Response headers
responseHeadersString,
responseHeaders,
// transport
transport,
// timeout handle
timeoutTimer,
// Cross-domain detection vars
parts,
// To know if global events are to be dispatched
fireGlobals,
// Loop variable
i,
// Create the final options object
s = jQuery.ajaxSetup( {}, options ), s = jQuery.ajaxSetup( {}, options ),
// Callbacks context // Callbacks context
callbackContext = s.context || s, callbackContext = s.context || s,
@ -7374,26 +7435,13 @@ jQuery.extend({
completeDeferred = jQuery.Callbacks( "once memory" ), completeDeferred = jQuery.Callbacks( "once memory" ),
// Status-dependent callbacks // Status-dependent callbacks
statusCode = s.statusCode || {}, statusCode = s.statusCode || {},
// ifModified key
ifModifiedKey,
// Headers (they are sent all at once) // Headers (they are sent all at once)
requestHeaders = {}, requestHeaders = {},
requestHeadersNames = {}, requestHeadersNames = {},
// Response headers
responseHeadersString,
responseHeaders,
// transport
transport,
// timeout handle
timeoutTimer,
// Cross-domain detection vars
parts,
// The jqXHR state // The jqXHR state
state = 0, state = 0,
// To know if global events are to be dispatched // Default abort message
fireGlobals, strAbort = "canceled",
// Loop variable
i,
// Fake xhr // Fake xhr
jqXHR = { jqXHR = {
@ -7439,7 +7487,7 @@ jQuery.extend({
// Cancel the request // Cancel the request
abort: function( statusText ) { abort: function( statusText ) {
statusText = statusText || "abort"; statusText = statusText || strAbort;
if ( transport ) { if ( transport ) {
transport.abort( statusText ); transport.abort( statusText );
} }
@ -7452,6 +7500,8 @@ jQuery.extend({
// It is defined here because jslint complains if it is declared // It is defined here because jslint complains if it is declared
// at the end of the function (which would be more logical and readable) // at the end of the function (which would be more logical and readable)
function done( status, nativeStatusText, responses, headers ) { function done( status, nativeStatusText, responses, headers ) {
var isSuccess, success, error, response, modified,
statusText = nativeStatusText;
// Called once // Called once
if ( state === 2 ) { if ( state === 2 ) {
@ -7476,13 +7526,10 @@ jQuery.extend({
// Set readyState // Set readyState
jqXHR.readyState = status > 0 ? 4 : 0; jqXHR.readyState = status > 0 ? 4 : 0;
var isSuccess, // Get response data
success, if ( responses ) {
error, response = ajaxHandleResponses( s, jqXHR, responses );
statusText = nativeStatusText, }
response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
lastModified,
etag;
// If successful, handle type chaining // If successful, handle type chaining
if ( status >= 200 && status < 300 || status === 304 ) { if ( status >= 200 && status < 300 || status === 304 ) {
@ -7490,11 +7537,13 @@ jQuery.extend({
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
if ( s.ifModified ) { if ( s.ifModified ) {
if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) { modified = jqXHR.getResponseHeader("Last-Modified");
jQuery.lastModified[ ifModifiedKey ] = lastModified; if ( modified ) {
jQuery.lastModified[ ifModifiedKey ] = modified;
} }
if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) { modified = jqXHR.getResponseHeader("Etag");
jQuery.etag[ ifModifiedKey ] = etag; if ( modified ) {
jQuery.etag[ ifModifiedKey ] = modified;
} }
} }
@ -7507,15 +7556,11 @@ jQuery.extend({
// If we have data // If we have data
} else { } else {
try { isSuccess = ajaxConvert( s, response );
success = ajaxConvert( s, response ); statusText = isSuccess.state;
statusText = "success"; success = isSuccess.data;
isSuccess = true; error = isSuccess.error;
} catch(e) { isSuccess = !error;
// We have a parsererror
statusText = "parsererror";
error = e;
}
} }
} else { } else {
// We extract error from statusText // We extract error from statusText
@ -7577,7 +7622,7 @@ jQuery.extend({
} }
} else { } else {
tmp = map[ jqXHR.status ]; tmp = map[ jqXHR.status ];
jqXHR.then( tmp, tmp ); jqXHR.always( tmp );
} }
} }
return this; return this;
@ -7589,7 +7634,7 @@ jQuery.extend({
s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
// Extract dataTypes list // Extract dataTypes list
s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax ); s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace );
// Determine if a cross-domain request is in order // Determine if a cross-domain request is in order
if ( s.crossDomain == null ) { if ( s.crossDomain == null ) {
@ -7611,7 +7656,7 @@ jQuery.extend({
// If request was aborted inside a prefilter, stop there // If request was aborted inside a prefilter, stop there
if ( state === 2 ) { if ( state === 2 ) {
return false; return jqXHR;
} }
// We can fire global events as of now if asked to // We can fire global events as of now if asked to
@ -7684,12 +7729,14 @@ jQuery.extend({
// Allow custom headers/mimetypes and early abort // Allow custom headers/mimetypes and early abort
if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
// Abort if not done already // Abort if not done already and return
jqXHR.abort(); return jqXHR.abort();
return false;
} }
// aborting is no longer a cancellation
strAbort = "abort";
// Install callbacks on deferreds // Install callbacks on deferreds
for ( i in { success: 1, error: 1, complete: 1 } ) { for ( i in { success: 1, error: 1, complete: 1 } ) {
jqXHR[ i ]( s[ i ] ); jqXHR[ i ]( s[ i ] );
@ -7731,77 +7778,6 @@ jQuery.extend({
return jqXHR; return jqXHR;
}, },
// Serialize an array of form elements or a set of
// key/values into a query string
param: function( a, traditional ) {
var s = [],
add = function( key, value ) {
// If value is a function, invoke it and return its value
value = jQuery.isFunction( value ) ? value() : value;
s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
};
// Set traditional to true for jQuery <= 1.3.2 behavior.
if ( traditional === undefined ) {
traditional = jQuery.ajaxSettings.traditional;
}
// 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 );
});
} else {
// If traditional, encode the "old" way (the way 1.3.2 or older
// did it), otherwise encode params recursively.
for ( var prefix in a ) {
buildParams( prefix, a[ prefix ], traditional, add );
}
}
// Return the resulting serialization
return s.join( "&" ).replace( r20, "+" );
}
});
function buildParams( prefix, obj, traditional, add ) {
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 ( var name in obj ) {
buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
}
} else {
// Serialize scalar item.
add( prefix, obj );
}
}
// This is still on the jQuery object... for now
// Want to move this to jQuery.ajax some day
jQuery.extend({
// Counter for holding the number of active queries // Counter for holding the number of active queries
active: 0, active: 0,
@ -7818,13 +7794,10 @@ jQuery.extend({
*/ */
function ajaxHandleResponses( s, jqXHR, responses ) { function ajaxHandleResponses( s, jqXHR, responses ) {
var contents = s.contents, var ct, type, finalDataType, firstDataType,
contents = s.contents,
dataTypes = s.dataTypes, dataTypes = s.dataTypes,
responseFields = s.responseFields, responseFields = s.responseFields;
ct,
type,
finalDataType,
firstDataType;
// Fill responseXXX fields // Fill responseXXX fields
for ( type in responseFields ) { for ( type in responseFields ) {
@ -7883,154 +7856,137 @@ function ajaxHandleResponses( s, jqXHR, responses ) {
// Chain conversions given the request and the original response // Chain conversions given the request and the original response
function ajaxConvert( s, response ) { function ajaxConvert( s, response ) {
var conv, conv2, current, tmp,
// Work with a copy of dataTypes in case we need to modify it for conversion
dataTypes = s.dataTypes.slice(),
prev = dataTypes[ 0 ],
converters = {},
i = 0;
// Apply the dataFilter if provided // Apply the dataFilter if provided
if ( s.dataFilter ) { if ( s.dataFilter ) {
response = s.dataFilter( response, s.dataType ); response = s.dataFilter( response, s.dataType );
} }
var dataTypes = s.dataTypes, // Create converters map with lowercased keys
converters = {}, if ( dataTypes[ 1 ] ) {
i, for ( conv in s.converters ) {
key, converters[ conv.toLowerCase() ] = s.converters[ conv ];
length = dataTypes.length,
tmp,
// Current and previous dataTypes
current = dataTypes[ 0 ],
prev,
// Conversion expression
conversion,
// Conversion function
conv,
// Conversion functions (transitive conversion)
conv1,
conv2;
// For each dataType in the chain
for ( i = 1; i < length; i++ ) {
// Create converters map
// with lowercased keys
if ( i === 1 ) {
for ( key in s.converters ) {
if ( typeof key === "string" ) {
converters[ key.toLowerCase() ] = s.converters[ key ];
}
}
} }
}
// Get the dataTypes // Convert to each sequential dataType, tolerating list modification
prev = current; for ( ; (current = dataTypes[++i]); ) {
current = dataTypes[ i ];
// If current is auto dataType, update it to prev // There's only work to do if current dataType is non-auto
if ( current === "*" ) { if ( current !== "*" ) {
current = prev;
// If no auto and dataTypes are actually different
} else if ( prev !== "*" && prev !== current ) {
// Get the converter // Convert response if prev dataType is non-auto and differs from current
conversion = prev + " " + current; if ( prev !== "*" && prev !== current ) {
conv = converters[ conversion ] || converters[ "* " + current ];
// If there is no direct converter, search transitively // Seek a direct converter
if ( !conv ) { conv = converters[ prev + " " + current ] || converters[ "* " + current ];
conv2 = undefined;
for ( conv1 in converters ) { // If none found, seek a pair
tmp = conv1.split( " " ); if ( !conv ) {
if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) { for ( conv2 in converters ) {
conv2 = converters[ tmp[1] + " " + current ];
if ( conv2 ) { // If conv2 outputs current
conv1 = converters[ conv1 ]; tmp = conv2.split(" ");
if ( conv1 === true ) { if ( tmp[ 1 ] === current ) {
conv = conv2;
} else if ( conv2 === true ) { // If prev can be converted to accepted input
conv = conv1; conv = converters[ prev + " " + tmp[ 0 ] ] ||
converters[ "* " + tmp[ 0 ] ];
if ( conv ) {
// Condense equivalence converters
if ( conv === true ) {
conv = converters[ conv2 ];
// Otherwise, insert the intermediate dataType
} else if ( converters[ conv2 ] !== true ) {
current = tmp[ 0 ];
dataTypes.splice( i--, 0, current );
}
break;
} }
break; }
}
}
// Apply converter (if not an equivalence)
if ( conv !== true ) {
// Unless errors are allowed to bubble, catch and return them
if ( conv && s["throws"] ) {
response = conv( response );
} else {
try {
response = conv( response );
} catch ( e ) {
return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
} }
} }
} }
} }
// If we found no converter, dispatch an error
if ( !( conv || conv2 ) ) { // Update prev for next iteration
jQuery.error( "No conversion from " + conversion.replace(" "," to ") ); prev = current;
}
// If found converter is not an equivalence
if ( conv !== true ) {
// Convert with 1 or 2 converters accordingly
response = conv ? conv( response ) : conv2( conv1(response) );
}
} }
} }
return response;
return { state: "success", data: response };
} }
var oldCallbacks = [],
rquestion = /\?/,
rjsonp = /(=)\?(?=&|$)|\?\?/,
nonce = jQuery.now();
var jsc = jQuery.now(),
jsre = /(\=)\?(&|$)|\?\?/i;
// Default jsonp settings // Default jsonp settings
jQuery.ajaxSetup({ jQuery.ajaxSetup({
jsonp: "callback", jsonp: "callback",
jsonpCallback: function() { jsonpCallback: function() {
return jQuery.expando + "_" + ( jsc++ ); var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
this[ callback ] = true;
return callback;
} }
}); });
// Detect, normalize options and install callbacks for jsonp requests // Detect, normalize options and install callbacks for jsonp requests
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
var inspectData = ( typeof s.data === "string" ) && /^application\/x\-www\-form\-urlencoded/.test( s.contentType ); var callbackName, overwritten, responseContainer,
data = s.data,
url = s.url,
hasCallback = s.jsonp !== false,
replaceInUrl = hasCallback && rjsonp.test( url ),
replaceInData = hasCallback && !replaceInUrl && typeof data === "string" &&
!( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") &&
rjsonp.test( data );
if ( s.dataTypes[ 0 ] === "jsonp" || // Handle iff the expected data type is "jsonp" or we have a parameter to set
s.jsonp !== false && ( jsre.test( s.url ) || if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) {
inspectData && jsre.test( s.data ) ) ) {
var responseContainer, // Get callback name, remembering preexisting value associated with it
jsonpCallback = s.jsonpCallback = callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback, s.jsonpCallback() :
previous = window[ jsonpCallback ], s.jsonpCallback;
url = s.url, overwritten = window[ callbackName ];
data = s.data,
replace = "$1" + jsonpCallback + "$2";
if ( s.jsonp !== false ) { // Insert callback into url or form data
url = url.replace( jsre, replace ); if ( replaceInUrl ) {
if ( s.url === url ) { s.url = url.replace( rjsonp, "$1" + callbackName );
if ( inspectData ) { } else if ( replaceInData ) {
data = data.replace( jsre, replace ); s.data = data.replace( rjsonp, "$1" + callbackName );
} } else if ( hasCallback ) {
if ( s.data === data ) { s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
// Add callback manually
url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
}
}
} }
s.url = url;
s.data = data;
// Install callback
window[ jsonpCallback ] = function( response ) {
responseContainer = [ response ];
};
// Clean-up function
jqXHR.always(function() {
// Set callback back to previous value
window[ jsonpCallback ] = previous;
// Call if it was a function and we have a response
if ( responseContainer && jQuery.isFunction( previous ) ) {
window[ jsonpCallback ]( responseContainer[ 0 ] );
}
});
// Use data converter to retrieve json after script execution // Use data converter to retrieve json after script execution
s.converters["script json"] = function() { s.converters["script json"] = function() {
if ( !responseContainer ) { if ( !responseContainer ) {
jQuery.error( jsonpCallback + " was not called" ); jQuery.error( callbackName + " was not called" );
} }
return responseContainer[ 0 ]; return responseContainer[ 0 ];
}; };
@ -8038,14 +7994,37 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
// force json dataType // force json dataType
s.dataTypes[ 0 ] = "json"; s.dataTypes[ 0 ] = "json";
// Install callback
window[ callbackName ] = function() {
responseContainer = arguments;
};
// Clean-up function (fires after converters)
jqXHR.always(function() {
// Restore preexisting value
window[ callbackName ] = overwritten;
// Save back as free
if ( s[ callbackName ] ) {
// make sure that re-using the options doesn't screw things around
s.jsonpCallback = originalSettings.jsonpCallback;
// save the callback name for future use
oldCallbacks.push( callbackName );
}
// Call if it was a function and we have a response
if ( responseContainer && jQuery.isFunction( overwritten ) ) {
overwritten( responseContainer[ 0 ] );
}
responseContainer = overwritten = undefined;
});
// Delegate to script // Delegate to script
return "script"; return "script";
} }
}); });
// Install script dataType // Install script dataType
jQuery.ajaxSetup({ jQuery.ajaxSetup({
accepts: { accepts: {
@ -8131,19 +8110,15 @@ jQuery.ajaxTransport( "script", function(s) {
}; };
} }
}); });
var xhrCallbacks,
// #5280: Internet Explorer will keep connections alive if we don't abort on unload
var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
xhrOnUnloadAbort = window.ActiveXObject ? function() { xhrOnUnloadAbort = window.ActiveXObject ? function() {
// Abort all pending requests // Abort all pending requests
for ( var key in xhrCallbacks ) { for ( var key in xhrCallbacks ) {
xhrCallbacks[ key ]( 0, 1 ); xhrCallbacks[ key ]( 0, 1 );
} }
} : false, } : false,
xhrId = 0, xhrId = 0;
xhrCallbacks;
// Functions to create xhrs // Functions to create xhrs
function createStandardXHR() { function createStandardXHR() {
@ -8194,9 +8169,8 @@ if ( jQuery.support.ajax ) {
send: function( headers, complete ) { send: function( headers, complete ) {
// Get a new xhr // Get a new xhr
var xhr = s.xhr(), var handle, i,
handle, xhr = s.xhr();
i;
// Open the socket // Open the socket
// Passing null username, generates a login popup on Opera (#2865) // Passing null username, generates a login popup on Opera (#2865)
@ -8249,7 +8223,7 @@ if ( jQuery.support.ajax ) {
xml; xml;
// Firefox throws exceptions when accessing properties // Firefox throws exceptions when accessing properties
// of an xhr when a network error occured // of an xhr when a network error occurred
// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
try { try {
@ -8325,11 +8299,13 @@ if ( jQuery.support.ajax ) {
} }
}; };
// if we're in sync mode or it's in cache if ( !s.async ) {
// and has been retrieved directly (IE6 & IE7) // if we're in sync mode we fire the callback
// we need to manually fire the callback
if ( !s.async || xhr.readyState === 4 ) {
callback(); callback();
} else if ( xhr.readyState === 4 ) {
// (IE6 & IE7) if it's in cache and has been
// retrieved directly we need to fire the callback
setTimeout( callback, 0 );
} else { } else {
handle = ++xhrId; handle = ++xhrId;
if ( xhrOnUnloadAbort ) { if ( xhrOnUnloadAbort ) {
@ -8355,278 +8331,489 @@ if ( jQuery.support.ajax ) {
} }
}); });
} }
var fxNow, timerId,
var elemdisplay = {},
iframe, iframeDoc,
rfxtypes = /^(?:toggle|show|hide)$/, rfxtypes = /^(?:toggle|show|hide)$/,
rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
timerId, rrun = /queueHooks$/,
fxAttrs = [ animationPrefilters = [ defaultPrefilter ],
// height animations tweeners = {
[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ], "*": [function( prop, value ) {
// width animations var end, unit, prevScale,
[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], tween = this.createTween( prop, value ),
// opacity animations parts = rfxnum.exec( value ),
[ "opacity" ] target = tween.cur(),
], start = +target || 0,
fxNow; scale = 1;
if ( parts ) {
end = +parts[2];
unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" );
// We need to compute starting value
if ( unit !== "px" && start ) {
// Iteratively approximate from a nonzero starting point
// Prefer the current property, because this process will be trivial if it uses the same units
// Fallback to end or a simple constant
start = jQuery.css( tween.elem, prop, true ) || end || 1;
do {
// If previous iteration zeroed out, double until we get *something*
// Use a string for doubling factor so we don't accidentally see scale as unchanged below
prevScale = scale = scale || ".5";
// Adjust and apply
start = start / scale;
jQuery.style( tween.elem, prop, start + unit );
// Update scale, tolerating zeroes from tween.cur()
scale = tween.cur() / target;
// Stop looping if we've hit the mark or scale is unchanged
} while ( scale !== 1 && scale !== prevScale );
}
tween.unit = unit;
tween.start = start;
// If a +=/-= token was provided, we're doing a relative animation
tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;
}
return tween;
}]
};
// Animations created synchronously will run synchronously
function createFxNow() {
setTimeout(function() {
fxNow = undefined;
}, 0 );
return ( fxNow = jQuery.now() );
}
function createTweens( animation, props ) {
jQuery.each( props, function( prop, value ) {
var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
index = 0,
length = collection.length;
for ( ; index < length; index++ ) {
if ( collection[ index ].call( animation, prop, value ) ) {
// we're done with this property
return;
}
}
});
}
function Animation( elem, properties, options ) {
var result,
index = 0,
tweenerIndex = 0,
length = animationPrefilters.length,
deferred = jQuery.Deferred().always( function() {
// don't match elem in the :animated selector
delete tick.elem;
}),
tick = function() {
var currentTime = fxNow || createFxNow(),
remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
percent = 1 - ( remaining / animation.duration || 0 ),
index = 0,
length = animation.tweens.length;
for ( ; index < length ; index++ ) {
animation.tweens[ index ].run( percent );
}
deferred.notifyWith( elem, [ animation, percent, remaining ]);
if ( percent < 1 && length ) {
return remaining;
} else {
deferred.resolveWith( elem, [ animation ] );
return false;
}
},
animation = deferred.promise({
elem: elem,
props: jQuery.extend( {}, properties ),
opts: jQuery.extend( true, { specialEasing: {} }, options ),
originalProperties: properties,
originalOptions: options,
startTime: fxNow || createFxNow(),
duration: options.duration,
tweens: [],
createTween: function( prop, end, easing ) {
var tween = jQuery.Tween( elem, animation.opts, prop, end,
animation.opts.specialEasing[ prop ] || animation.opts.easing );
animation.tweens.push( tween );
return tween;
},
stop: function( gotoEnd ) {
var index = 0,
// if we are going to the end, we want to run all the tweens
// otherwise we skip this part
length = gotoEnd ? animation.tweens.length : 0;
for ( ; index < length ; index++ ) {
animation.tweens[ index ].run( 1 );
}
// resolve when we played the last frame
// otherwise, reject
if ( gotoEnd ) {
deferred.resolveWith( elem, [ animation, gotoEnd ] );
} else {
deferred.rejectWith( elem, [ animation, gotoEnd ] );
}
return this;
}
}),
props = animation.props;
propFilter( props, animation.opts.specialEasing );
for ( ; index < length ; index++ ) {
result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
if ( result ) {
return result;
}
}
createTweens( animation, props );
if ( jQuery.isFunction( animation.opts.start ) ) {
animation.opts.start.call( elem, animation );
}
jQuery.fx.timer(
jQuery.extend( tick, {
anim: animation,
queue: animation.opts.queue,
elem: elem
})
);
// attach callbacks from options
return animation.progress( animation.opts.progress )
.done( animation.opts.done, animation.opts.complete )
.fail( animation.opts.fail )
.always( animation.opts.always );
}
function propFilter( props, specialEasing ) {
var index, name, easing, value, hooks;
// camelCase, specialEasing and expand cssHook pass
for ( index in props ) {
name = jQuery.camelCase( index );
easing = specialEasing[ name ];
value = props[ index ];
if ( jQuery.isArray( value ) ) {
easing = value[ 1 ];
value = props[ index ] = value[ 0 ];
}
if ( index !== name ) {
props[ name ] = value;
delete props[ index ];
}
hooks = jQuery.cssHooks[ name ];
if ( hooks && "expand" in hooks ) {
value = hooks.expand( value );
delete props[ name ];
// not quite $.extend, this wont overwrite keys already present.
// also - reusing 'index' from above because we have the correct "name"
for ( index in value ) {
if ( !( index in props ) ) {
props[ index ] = value[ index ];
specialEasing[ index ] = easing;
}
}
} else {
specialEasing[ name ] = easing;
}
}
}
jQuery.Animation = jQuery.extend( Animation, {
tweener: function( props, callback ) {
if ( jQuery.isFunction( props ) ) {
callback = props;
props = [ "*" ];
} else {
props = props.split(" ");
}
var prop,
index = 0,
length = props.length;
for ( ; index < length ; index++ ) {
prop = props[ index ];
tweeners[ prop ] = tweeners[ prop ] || [];
tweeners[ prop ].unshift( callback );
}
},
prefilter: function( callback, prepend ) {
if ( prepend ) {
animationPrefilters.unshift( callback );
} else {
animationPrefilters.push( callback );
}
}
});
function defaultPrefilter( elem, props, opts ) {
var index, prop, value, length, dataShow, tween, hooks, oldfire,
anim = this,
style = elem.style,
orig = {},
handled = [],
hidden = elem.nodeType && isHidden( elem );
// handle queue: false promises
if ( !opts.queue ) {
hooks = jQuery._queueHooks( elem, "fx" );
if ( hooks.unqueued == null ) {
hooks.unqueued = 0;
oldfire = hooks.empty.fire;
hooks.empty.fire = function() {
if ( !hooks.unqueued ) {
oldfire();
}
};
}
hooks.unqueued++;
anim.always(function() {
// doing this makes sure that the complete handler will be called
// before this completes
anim.always(function() {
hooks.unqueued--;
if ( !jQuery.queue( elem, "fx" ).length ) {
hooks.empty.fire();
}
});
});
}
// height/width overflow pass
if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
// Make sure that nothing sneaks out
// Record all 3 overflow attributes because IE does not
// change the overflow attribute when overflowX and
// overflowY are set to the same value
opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
// Set display property to inline-block for height/width
// animations on inline elements that are having width/height animated
if ( jQuery.css( elem, "display" ) === "inline" &&
jQuery.css( elem, "float" ) === "none" ) {
// inline-level elements accept inline-block;
// block-level elements need to be inline with layout
if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
style.display = "inline-block";
} else {
style.zoom = 1;
}
}
}
if ( opts.overflow ) {
style.overflow = "hidden";
if ( !jQuery.support.shrinkWrapBlocks ) {
anim.done(function() {
style.overflow = opts.overflow[ 0 ];
style.overflowX = opts.overflow[ 1 ];
style.overflowY = opts.overflow[ 2 ];
});
}
}
// show/hide pass
for ( index in props ) {
value = props[ index ];
if ( rfxtypes.exec( value ) ) {
delete props[ index ];
if ( value === ( hidden ? "hide" : "show" ) ) {
continue;
}
handled.push( index );
}
}
length = handled.length;
if ( length ) {
dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} );
if ( hidden ) {
jQuery( elem ).show();
} else {
anim.done(function() {
jQuery( elem ).hide();
});
}
anim.done(function() {
var prop;
jQuery.removeData( elem, "fxshow", true );
for ( prop in orig ) {
jQuery.style( elem, prop, orig[ prop ] );
}
});
for ( index = 0 ; index < length ; index++ ) {
prop = handled[ index ];
tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );
orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );
if ( !( prop in dataShow ) ) {
dataShow[ prop ] = tween.start;
if ( hidden ) {
tween.end = tween.start;
tween.start = prop === "width" || prop === "height" ? 1 : 0;
}
}
}
}
}
function Tween( elem, options, prop, end, easing ) {
return new Tween.prototype.init( elem, options, prop, end, easing );
}
jQuery.Tween = Tween;
Tween.prototype = {
constructor: Tween,
init: function( elem, options, prop, end, easing, unit ) {
this.elem = elem;
this.prop = prop;
this.easing = easing || "swing";
this.options = options;
this.start = this.now = this.cur();
this.end = end;
this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
},
cur: function() {
var hooks = Tween.propHooks[ this.prop ];
return hooks && hooks.get ?
hooks.get( this ) :
Tween.propHooks._default.get( this );
},
run: function( percent ) {
var eased,
hooks = Tween.propHooks[ this.prop ];
this.pos = eased = jQuery.easing[ this.easing ]( percent, this.options.duration * percent, 0, 1, this.options.duration );
this.now = ( this.end - this.start ) * eased + this.start;
if ( this.options.step ) {
this.options.step.call( this.elem, this.now, this );
}
if ( hooks && hooks.set ) {
hooks.set( this );
} else {
Tween.propHooks._default.set( this );
}
return this;
}
};
Tween.prototype.init.prototype = Tween.prototype;
Tween.propHooks = {
_default: {
get: function( tween ) {
var result;
if ( tween.elem[ tween.prop ] != null &&
(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
return tween.elem[ tween.prop ];
}
// passing any value as a 4th parameter to .css will automatically
// attempt a parseFloat and fallback to a string if the parse fails
// so, simple values such as "10px" are parsed to Float.
// complex values such as "rotate(1rad)" are returned as is.
result = jQuery.css( tween.elem, tween.prop, false, "" );
// Empty strings, null, undefined and "auto" are converted to 0.
return !result || result === "auto" ? 0 : result;
},
set: function( tween ) {
// use step hook for back compat - use cssHook if its there - use .style if its
// available and use plain properties where available
if ( jQuery.fx.step[ tween.prop ] ) {
jQuery.fx.step[ tween.prop ]( tween );
} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
} else {
tween.elem[ tween.prop ] = tween.now;
}
}
}
};
// Remove in 2.0 - this supports IE8's panic based approach
// to setting things on disconnected nodes
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
set: function( tween ) {
if ( tween.elem.nodeType && tween.elem.parentNode ) {
tween.elem[ tween.prop ] = tween.now;
}
}
};
jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
var cssFn = jQuery.fn[ name ];
jQuery.fn[ name ] = function( speed, easing, callback ) {
return speed == null || typeof speed === "boolean" ||
// special check for .toggle( handler, handler, ... )
( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ?
cssFn.apply( this, arguments ) :
this.animate( genFx( name, true ), speed, easing, callback );
};
});
jQuery.fn.extend({ jQuery.fn.extend({
show: function( speed, easing, callback ) {
var elem, display;
if ( speed || speed === 0 ) {
return this.animate( genFx("show", 3), speed, easing, callback );
} else {
for ( var i = 0, j = this.length; i < j; i++ ) {
elem = this[ i ];
if ( elem.style ) {
display = elem.style.display;
// Reset the inline display of this element to learn if it is
// being hidden by cascaded rules or not
if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
display = 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 ( (display === "" && jQuery.css(elem, "display") === "none") ||
!jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
}
}
}
// Set the display of most of the elements in a second loop
// to avoid the constant reflow
for ( i = 0; i < j; i++ ) {
elem = this[ i ];
if ( elem.style ) {
display = elem.style.display;
if ( display === "" || display === "none" ) {
elem.style.display = jQuery._data( elem, "olddisplay" ) || "";
}
}
}
return this;
}
},
hide: function( speed, easing, callback ) {
if ( speed || speed === 0 ) {
return this.animate( genFx("hide", 3), speed, easing, callback);
} else {
var elem, display,
i = 0,
j = this.length;
for ( ; i < j; i++ ) {
elem = this[i];
if ( elem.style ) {
display = jQuery.css( elem, "display" );
if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) {
jQuery._data( elem, "olddisplay", display );
}
}
}
// Set the display of the elements in a second loop
// to avoid the constant reflow
for ( i = 0; i < j; i++ ) {
if ( this[i].style ) {
this[i].style.display = "none";
}
}
return this;
}
},
// Save the old toggle function
_toggle: jQuery.fn.toggle,
toggle: function( fn, fn2, callback ) {
var bool = typeof fn === "boolean";
if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
this._toggle.apply( this, arguments );
} else if ( fn == null || bool ) {
this.each(function() {
var state = bool ? fn : jQuery(this).is(":hidden");
jQuery(this)[ state ? "show" : "hide" ]();
});
} else {
this.animate(genFx("toggle", 3), fn, fn2, callback);
}
return this;
},
fadeTo: function( speed, to, easing, callback ) { fadeTo: function( speed, to, easing, callback ) {
return this.filter(":hidden").css("opacity", 0).show().end()
.animate({opacity: to}, speed, easing, callback); // show any hidden elements after setting opacity to 0
return this.filter( isHidden ).css( "opacity", 0 ).show()
// animate to the value specified
.end().animate({ opacity: to }, speed, easing, callback );
}, },
animate: function( prop, speed, easing, callback ) { animate: function( prop, speed, easing, callback ) {
var optall = jQuery.speed( speed, easing, callback ); var empty = jQuery.isEmptyObject( prop ),
optall = jQuery.speed( speed, easing, callback ),
doAnimation = function() {
// Operate on a copy of prop so per-property easing won't be lost
var anim = Animation( this, jQuery.extend( {}, prop ), optall );
if ( jQuery.isEmptyObject( prop ) ) { // Empty animations resolve immediately
return this.each( optall.complete, [ false ] ); if ( empty ) {
} anim.stop( true );
// Do not change referenced properties as per-property easing will be lost
prop = jQuery.extend( {}, prop );
function doAnimation() {
// XXX 'this' does not always have a nodeName when running the
// test suite
if ( optall.queue === false ) {
jQuery._mark( this );
}
var opt = jQuery.extend( {}, optall ),
isElement = this.nodeType === 1,
hidden = isElement && jQuery(this).is(":hidden"),
name, val, p, e, hooks, replace,
parts, start, end, unit,
method;
// will store per property easing and be used to determine when an animation is complete
opt.animatedProperties = {};
// first pass over propertys to expand / normalize
for ( p in prop ) {
name = jQuery.camelCase( p );
if ( p !== name ) {
prop[ name ] = prop[ p ];
delete prop[ p ];
} }
};
if ( ( hooks = jQuery.cssHooks[ name ] ) && "expand" in hooks ) { return empty || optall.queue === false ?
replace = hooks.expand( prop[ name ] );
delete prop[ name ];
// not quite $.extend, this wont overwrite keys already present.
// also - reusing 'p' from above because we have the correct "name"
for ( p in replace ) {
if ( ! ( p in prop ) ) {
prop[ p ] = replace[ p ];
}
}
}
}
for ( name in prop ) {
val = prop[ name ];
// easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
if ( jQuery.isArray( val ) ) {
opt.animatedProperties[ name ] = val[ 1 ];
val = prop[ name ] = val[ 0 ];
} else {
opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
}
if ( val === "hide" && hidden || val === "show" && !hidden ) {
return opt.complete.call( this );
}
if ( isElement && ( name === "height" || name === "width" ) ) {
// Make sure that nothing sneaks out
// Record all 3 overflow attributes because IE does not
// change the overflow attribute when overflowX and
// overflowY are set to the same value
opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
// Set display property to inline-block for height/width
// animations on inline elements that are having width/height animated
if ( jQuery.css( this, "display" ) === "inline" &&
jQuery.css( this, "float" ) === "none" ) {
// inline-level elements accept inline-block;
// block-level elements need to be inline with layout
if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) {
this.style.display = "inline-block";
} else {
this.style.zoom = 1;
}
}
}
}
if ( opt.overflow != null ) {
this.style.overflow = "hidden";
}
for ( p in prop ) {
e = new jQuery.fx( this, opt, p );
val = prop[ p ];
if ( rfxtypes.test( val ) ) {
// Tracks whether to show or hide based on private
// data attached to the element
method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 );
if ( method ) {
jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" );
e[ method ]();
} else {
e[ val ]();
}
} else {
parts = rfxnum.exec( val );
start = e.cur();
if ( parts ) {
end = parseFloat( parts[2] );
unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
// We need to compute starting value
if ( unit !== "px" ) {
jQuery.style( this, p, (end || 1) + unit);
start = ( (end || 1) / e.cur() ) * start;
jQuery.style( this, p, start + unit);
}
// If a +=/-= token was provided, we're doing a relative animation
if ( parts[1] ) {
end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
}
e.custom( start, end, unit );
} else {
e.custom( start, val, "" );
}
}
}
// For JS strict compliance
return true;
}
return optall.queue === false ?
this.each( doAnimation ) : this.each( doAnimation ) :
this.queue( optall.queue, doAnimation ); this.queue( optall.queue, doAnimation );
}, },
stop: function( type, clearQueue, gotoEnd ) { stop: function( type, clearQueue, gotoEnd ) {
var stopQueue = function( hooks ) {
var stop = hooks.stop;
delete hooks.stop;
stop( gotoEnd );
};
if ( typeof type !== "string" ) { if ( typeof type !== "string" ) {
gotoEnd = clearQueue; gotoEnd = clearQueue;
clearQueue = type; clearQueue = type;
@ -8637,42 +8824,27 @@ jQuery.fn.extend({
} }
return this.each(function() { return this.each(function() {
var index, var dequeue = true,
hadTimers = false, index = type != null && type + "queueHooks",
timers = jQuery.timers, timers = jQuery.timers,
data = jQuery._data( this ); data = jQuery._data( this );
// clear marker counters if we know they won't be if ( index ) {
if ( !gotoEnd ) { if ( data[ index ] && data[ index ].stop ) {
jQuery._unmark( true, this ); stopQueue( data[ index ] );
} }
} else {
function stopQueue( elem, data, index ) {
var hooks = data[ index ];
jQuery.removeData( elem, index, true );
hooks.stop( gotoEnd );
}
if ( type == null ) {
for ( index in data ) { for ( index in data ) {
if ( data[ index ] && data[ index ].stop && index.indexOf(".run") === index.length - 4 ) { if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
stopQueue( this, data, index ); stopQueue( data[ index ] );
} }
} }
} else if ( data[ index = type + ".run" ] && data[ index ].stop ){
stopQueue( this, data, index );
} }
for ( index = timers.length; index--; ) { for ( index = timers.length; index--; ) {
if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
if ( gotoEnd ) { timers[ index ].anim.stop( gotoEnd );
dequeue = false;
// force the next step to be the last
timers[ index ]( true );
} else {
timers[ index ].saveState();
}
hadTimers = true;
timers.splice( index, 1 ); timers.splice( index, 1 );
} }
} }
@ -8680,40 +8852,38 @@ jQuery.fn.extend({
// start the next in the queue if the last step wasn't forced // start the next in the queue if the last step wasn't forced
// timers currently will call their complete callbacks, which will dequeue // timers currently will call their complete callbacks, which will dequeue
// but only if they were gotoEnd // but only if they were gotoEnd
if ( !( gotoEnd && hadTimers ) ) { if ( dequeue || !gotoEnd ) {
jQuery.dequeue( this, type ); jQuery.dequeue( this, type );
} }
}); });
} }
}); });
// Animations created synchronously will run synchronously
function createFxNow() {
setTimeout( clearFxNow, 0 );
return ( fxNow = jQuery.now() );
}
function clearFxNow() {
fxNow = undefined;
}
// Generate parameters to create a standard animation // Generate parameters to create a standard animation
function genFx( type, num ) { function genFx( type, includeWidth ) {
var obj = {}; var which,
attrs = { height: type },
i = 0;
jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() { // if we include width, step value is 1 to do all cssExpand values,
obj[ this ] = type; // if we don't include width, step value is 2 to skip over Left and Right
}); for( ; i < 4 ; i += 2 - includeWidth ) {
which = cssExpand[ i ];
attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
}
return obj; if ( includeWidth ) {
attrs.opacity = attrs.width = type;
}
return attrs;
} }
// Generate shortcuts for custom animations // Generate shortcuts for custom animations
jQuery.each({ jQuery.each({
slideDown: genFx( "show", 1 ), slideDown: genFx("show"),
slideUp: genFx( "hide", 1 ), slideUp: genFx("hide"),
slideToggle: genFx( "toggle", 1 ), slideToggle: genFx("toggle"),
fadeIn: { opacity: "show" }, fadeIn: { opacity: "show" },
fadeOut: { opacity: "hide" }, fadeOut: { opacity: "hide" },
fadeToggle: { opacity: "toggle" } fadeToggle: { opacity: "toggle" }
@ -8723,285 +8893,89 @@ jQuery.each({
}; };
}); });
jQuery.extend({ jQuery.speed = function( speed, easing, fn ) {
speed: function( speed, easing, fn ) { var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { complete: fn || !fn && easing ||
complete: fn || !fn && easing || jQuery.isFunction( speed ) && speed,
jQuery.isFunction( speed ) && speed, duration: speed,
duration: speed, easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing };
};
opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
// normalize opt.queue - true/undefined/null -> "fx" // normalize opt.queue - true/undefined/null -> "fx"
if ( opt.queue == null || opt.queue === true ) { if ( opt.queue == null || opt.queue === true ) {
opt.queue = "fx"; opt.queue = "fx";
}
// Queueing
opt.old = opt.complete;
opt.complete = function( noUnmark ) {
if ( jQuery.isFunction( opt.old ) ) {
opt.old.call( this );
}
if ( opt.queue ) {
jQuery.dequeue( this, opt.queue );
} else if ( noUnmark !== false ) {
jQuery._unmark( this );
}
};
return opt;
},
easing: {
linear: function( p ) {
return p;
},
swing: function( p ) {
return ( -Math.cos( p*Math.PI ) / 2 ) + 0.5;
}
},
timers: [],
fx: function( elem, options, prop ) {
this.options = options;
this.elem = elem;
this.prop = prop;
options.orig = options.orig || {};
} }
}); // Queueing
opt.old = opt.complete;
jQuery.fx.prototype = { opt.complete = function() {
// Simple function for setting a style value if ( jQuery.isFunction( opt.old ) ) {
update: function() { opt.old.call( this );
if ( this.options.step ) {
this.options.step.call( this.elem, this.now, this );
} }
( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this ); if ( opt.queue ) {
jQuery.dequeue( this, opt.queue );
}
};
return opt;
};
jQuery.easing = {
linear: function( p ) {
return p;
}, },
swing: function( p ) {
// Get the current size return 0.5 - Math.cos( p*Math.PI ) / 2;
cur: function() {
if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) {
return this.elem[ this.prop ];
}
var parsed,
r = jQuery.css( this.elem, this.prop );
// Empty strings, null, undefined and "auto" are converted to 0,
// complex values such as "rotate(1rad)" are returned as is,
// simple values such as "10px" are parsed to Float.
return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
},
// Start an animation from one number to another
custom: function( from, to, unit ) {
var self = this,
fx = jQuery.fx;
this.startTime = fxNow || createFxNow();
this.end = to;
this.now = this.start = from;
this.pos = this.state = 0;
this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
function t( gotoEnd ) {
return self.step( gotoEnd );
}
t.queue = this.options.queue;
t.elem = this.elem;
t.saveState = function() {
if ( jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) {
if ( self.options.hide ) {
jQuery._data( self.elem, "fxshow" + self.prop, self.start );
} else if ( self.options.show ) {
jQuery._data( self.elem, "fxshow" + self.prop, self.end );
}
}
};
if ( t() && jQuery.timers.push(t) && !timerId ) {
timerId = setInterval( fx.tick, fx.interval );
}
},
// Simple 'show' function
show: function() {
var dataShow = jQuery._data( this.elem, "fxshow" + this.prop );
// Remember where we started, so that we can go back to it later
this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop );
this.options.show = true;
// Begin the animation
// Make sure that we start at a small width/height to avoid any flash of content
if ( dataShow !== undefined ) {
// This show is picking up where a previous hide or show left off
this.custom( this.cur(), dataShow );
} else {
this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() );
}
// Start by showing the element
jQuery( this.elem ).show();
},
// Simple 'hide' function
hide: function() {
// Remember where we started, so that we can go back to it later
this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop );
this.options.hide = true;
// Begin the animation
this.custom( this.cur(), 0 );
},
// Each step of an animation
step: function( gotoEnd ) {
var p, n, complete,
t = fxNow || createFxNow(),
done = true,
elem = this.elem,
options = this.options;
if ( gotoEnd || t >= options.duration + this.startTime ) {
this.now = this.end;
this.pos = this.state = 1;
this.update();
options.animatedProperties[ this.prop ] = true;
for ( p in options.animatedProperties ) {
if ( options.animatedProperties[ p ] !== true ) {
done = false;
}
}
if ( done ) {
// Reset the overflow
if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
jQuery.each( [ "", "X", "Y" ], function( index, value ) {
elem.style[ "overflow" + value ] = options.overflow[ index ];
});
}
// Hide the element if the "hide" operation was done
if ( options.hide ) {
jQuery( elem ).hide();
}
// Reset the properties, if the item has been hidden or shown
if ( options.hide || options.show ) {
for ( p in options.animatedProperties ) {
jQuery.style( elem, p, options.orig[ p ] );
jQuery.removeData( elem, "fxshow" + p, true );
// Toggle data is no longer needed
jQuery.removeData( elem, "toggle" + p, true );
}
}
// Execute the complete function
// in the event that the complete function throws an exception
// we must ensure it won't be called twice. #5684
complete = options.complete;
if ( complete ) {
options.complete = false;
complete.call( elem );
}
}
return false;
} else {
// classical easing cannot be used with an Infinity duration
if ( options.duration == Infinity ) {
this.now = t;
} else {
n = t - this.startTime;
this.state = n / options.duration;
// Perform the easing function, defaults to swing
this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration );
this.now = this.start + ( (this.end - this.start) * this.pos );
}
// Perform the next step of the animation
this.update();
}
return true;
} }
}; };
jQuery.extend( jQuery.fx, { jQuery.timers = [];
tick: function() { jQuery.fx = Tween.prototype.init;
var timer, jQuery.fx.tick = function() {
timers = jQuery.timers, var timer,
i = 0; timers = jQuery.timers,
i = 0;
for ( ; i < timers.length; i++ ) { for ( ; i < timers.length; i++ ) {
timer = timers[ i ]; timer = timers[ i ];
// Checks the timer has not already been removed // Checks the timer has not already been removed
if ( !timer() && timers[ i ] === timer ) { if ( !timer() && timers[ i ] === timer ) {
timers.splice( i--, 1 ); timers.splice( i--, 1 );
}
}
if ( !timers.length ) {
jQuery.fx.stop();
}
},
interval: 13,
stop: function() {
clearInterval( timerId );
timerId = null;
},
speeds: {
slow: 600,
fast: 200,
// Default speed
_default: 400
},
step: {
opacity: function( fx ) {
jQuery.style( fx.elem, "opacity", fx.now );
},
_default: function( fx ) {
if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
fx.elem.style[ fx.prop ] = fx.now + fx.unit;
} else {
fx.elem[ fx.prop ] = fx.now;
}
} }
} }
});
// Ensure props that can't be negative don't go there on undershoot easing if ( !timers.length ) {
jQuery.each( fxAttrs.concat.apply( [], fxAttrs ), function( i, prop ) { jQuery.fx.stop();
// exclude marginTop, marginLeft, marginBottom and marginRight from this list
if ( prop.indexOf( "margin" ) ) {
jQuery.fx.step[ prop ] = function( fx ) {
jQuery.style( fx.elem, prop, Math.max(0, fx.now) + fx.unit );
};
} }
}); };
jQuery.fx.timer = function( timer ) {
if ( timer() && jQuery.timers.push( timer ) && !timerId ) {
timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
}
};
jQuery.fx.interval = 13;
jQuery.fx.stop = function() {
clearInterval( timerId );
timerId = null;
};
jQuery.fx.speeds = {
slow: 600,
fast: 200,
// Default speed
_default: 400
};
// Back Compat <1.8 extension point
jQuery.fx.step = {};
if ( jQuery.expr && jQuery.expr.filters ) { if ( jQuery.expr && jQuery.expr.filters ) {
jQuery.expr.filters.animated = function( elem ) { jQuery.expr.filters.animated = function( elem ) {
@ -9010,136 +8984,7 @@ if ( jQuery.expr && jQuery.expr.filters ) {
}).length; }).length;
}; };
} }
var rroot = /^(?:body|html)$/i;
// Try to restore the default display value of an element
function defaultDisplay( nodeName ) {
if ( !elemdisplay[ nodeName ] ) {
var body = document.body,
elem = jQuery( "<" + nodeName + ">" ).appendTo( 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 === "" ) {
// No iframe to use yet, so create it
if ( !iframe ) {
iframe = document.createElement( "iframe" );
iframe.frameBorder = iframe.width = iframe.height = 0;
}
body.appendChild( iframe );
// 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( ( jQuery.support.boxModel ? "<!doctype html>" : "" ) + "<html><body>" );
iframeDoc.close();
}
elem = iframeDoc.createElement( nodeName );
iframeDoc.body.appendChild( elem );
display = jQuery.css( elem, "display" );
body.removeChild( iframe );
}
// Store the correct default display
elemdisplay[ nodeName ] = display;
}
return elemdisplay[ nodeName ];
}
var getOffset,
rtable = /^t(?:able|d|h)$/i,
rroot = /^(?:body|html)$/i;
if ( "getBoundingClientRect" in document.documentElement ) {
getOffset = function( elem, doc, docElem, box ) {
try {
box = elem.getBoundingClientRect();
} catch(e) {}
// Make sure we're not dealing with a disconnected DOM node
if ( !box || !jQuery.contains( docElem, elem ) ) {
return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
}
var body = doc.body,
win = getWindow( doc ),
clientTop = docElem.clientTop || body.clientTop || 0,
clientLeft = docElem.clientLeft || body.clientLeft || 0,
scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
top = box.top + scrollTop - clientTop,
left = box.left + scrollLeft - clientLeft;
return { top: top, left: left };
};
} else {
getOffset = function( elem, doc, docElem ) {
var computedStyle,
offsetParent = elem.offsetParent,
prevOffsetParent = elem,
body = doc.body,
defaultView = doc.defaultView,
prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
top = elem.offsetTop,
left = elem.offsetLeft;
while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
break;
}
computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
top -= elem.scrollTop;
left -= elem.scrollLeft;
if ( elem === offsetParent ) {
top += elem.offsetTop;
left += elem.offsetLeft;
if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
top += parseFloat( computedStyle.borderTopWidth ) || 0;
left += parseFloat( computedStyle.borderLeftWidth ) || 0;
}
prevOffsetParent = offsetParent;
offsetParent = elem.offsetParent;
}
if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
top += parseFloat( computedStyle.borderTopWidth ) || 0;
left += parseFloat( computedStyle.borderLeftWidth ) || 0;
}
prevComputedStyle = computedStyle;
}
if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
top += body.offsetTop;
left += body.offsetLeft;
}
if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
top += Math.max( docElem.scrollTop, body.scrollTop );
left += Math.max( docElem.scrollLeft, body.scrollLeft );
}
return { top: top, left: left };
};
}
jQuery.fn.offset = function( options ) { jQuery.fn.offset = function( options ) {
if ( arguments.length ) { if ( arguments.length ) {
@ -9150,18 +8995,35 @@ jQuery.fn.offset = function( options ) {
}); });
} }
var elem = this[0], var box, docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, top, left,
elem = this[ 0 ],
doc = elem && elem.ownerDocument; doc = elem && elem.ownerDocument;
if ( !doc ) { if ( !doc ) {
return null; return;
} }
if ( elem === doc.body ) { if ( (body = doc.body) === elem ) {
return jQuery.offset.bodyOffset( elem ); return jQuery.offset.bodyOffset( elem );
} }
return getOffset( elem, doc, doc.documentElement ); docElem = doc.documentElement;
// Make sure we're not dealing with a disconnected DOM node
if ( !jQuery.contains( docElem, elem ) ) {
return { top: 0, left: 0 };
}
box = elem.getBoundingClientRect();
win = getWindow( doc );
clientTop = docElem.clientTop || body.clientTop || 0;
clientLeft = docElem.clientLeft || body.clientLeft || 0;
scrollTop = win.pageYOffset || docElem.scrollTop;
scrollLeft = win.pageXOffset || docElem.scrollLeft;
top = box.top + scrollTop - clientTop;
left = box.left + scrollLeft - clientLeft;
return { top: top, left: left };
}; };
jQuery.offset = { jQuery.offset = {
@ -9227,7 +9089,7 @@ jQuery.fn.extend({
position: function() { position: function() {
if ( !this[0] ) { if ( !this[0] ) {
return null; return;
} }
var elem = this[0], var elem = this[0],
@ -9262,7 +9124,7 @@ jQuery.fn.extend({
while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
offsetParent = offsetParent.offsetParent; offsetParent = offsetParent.offsetParent;
} }
return offsetParent; return offsetParent || document.body;
}); });
} }
}); });
@ -9278,8 +9140,7 @@ jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( me
if ( val === undefined ) { if ( val === undefined ) {
return win ? (prop in win) ? win[ prop ] : return win ? (prop in win) ? win[ prop ] :
jQuery.support.boxModel && win.document.documentElement[ method ] || win.document.documentElement[ method ] :
win.document.body[ method ] :
elem[ method ]; elem[ method ];
} }
@ -9303,83 +9164,47 @@ function getWindow( elem ) {
elem.defaultView || elem.parentWindow : elem.defaultView || elem.parentWindow :
false; false;
} }
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
var clientProp = "client" + name, jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
scrollProp = "scroll" + name, // margin is only for outerHeight, outerWidth
offsetProp = "offset" + name; jQuery.fn[ funcName ] = function( margin, value ) {
var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
// innerHeight and innerWidth return jQuery.access( this, function( elem, type, value ) {
jQuery.fn[ "inner" + name ] = function() { var doc;
var elem = this[0];
return elem ?
elem.style ?
parseFloat( jQuery.css( elem, type, "padding" ) ) :
this[ type ]() :
null;
};
// outerHeight and outerWidth if ( jQuery.isWindow( elem ) ) {
jQuery.fn[ "outer" + name ] = function( margin ) { // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
var elem = this[0]; // isn't a whole lot we can do. See pull request at this URL for discussion:
return elem ? // https://github.com/jquery/jquery/pull/764
elem.style ? return elem.document.documentElement[ "client" + name ];
parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
this[ type ]() :
null;
};
jQuery.fn[ type ] = function( value ) {
return jQuery.access( this, function( elem, type, value ) {
var doc, docElemProp, orig, ret;
if ( jQuery.isWindow( elem ) ) {
// 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
doc = elem.document;
docElemProp = doc.documentElement[ clientProp ];
return jQuery.support.boxModel && docElemProp ||
doc.body && doc.body[ clientProp ] || docElemProp;
}
// Get document width or height
if ( elem.nodeType === 9 ) {
// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
doc = elem.documentElement;
// when a window > document, IE6 reports a offset[Width/Height] > client[Width/Height]
// so we can't use max, as it'll choose the incorrect offset[Width/Height]
// instead we use the correct client[Width/Height]
// support:IE6
if ( doc[ clientProp ] >= doc[ scrollProp ] ) {
return doc[ clientProp ];
} }
return Math.max( // Get document width or height
elem.body[ scrollProp ], doc[ scrollProp ], if ( elem.nodeType === 9 ) {
elem.body[ offsetProp ], doc[ offsetProp ] doc = elem.documentElement;
);
}
// Get width or height on the element // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
if ( value === undefined ) { // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
orig = jQuery.css( elem, type ); return Math.max(
ret = parseFloat( orig ); elem.body[ "scroll" + name ], doc[ "scroll" + name ],
return jQuery.isNumeric( ret ) ? ret : orig; elem.body[ "offset" + name ], doc[ "offset" + name ],
} doc[ "client" + name ]
);
}
// Set the width or height on the element return value === undefined ?
jQuery( elem ).css( type, value ); // Get width or height on the element, requesting but not forcing parseFloat
}, type, value, arguments.length, null ); jQuery.css( elem, type, value, extra ) :
};
// Set width or height on the element
jQuery.style( elem, type, value, extra );
}, type, chainable ? margin : undefined, chainable );
};
});
}); });
// Expose jQuery to the global object // Expose jQuery to the global object
window.jQuery = window.$ = jQuery; window.jQuery = window.$ = jQuery;
@ -9399,6 +9224,4 @@ if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
define( "jquery", [], function () { return jQuery; } ); define( "jquery", [], function () { return jQuery; } );
} }
})( window ); })( window );

0
thirdparty/tinymce/langs/mi_NZ.js vendored Normal file
View File

View File

@ -0,0 +1,76 @@
tinyMCE.addI18n('mi_NZ.advanced', {
"underline_desc": "Underline (Ctrl+U)",
"italic_desc": "Italic (Ctrl+I)",
"bold_desc": "Bold (Ctrl+B)",
dd: "Definition Description",
dt: "Definition Term ",
samp: "Code Sample",
code: "Code",
blockquote: "Block Quote",
h6: "Panek\u014Drero 6",
h5: "Panek\u014Drero 5",
h4: "Panek\u014Drero 4",
h3: "Panek\u014Drero 3",
h2: "Panek\u014Drero 2",
h1: "Panek\u014Drero 1",
pre: "Kua whakah\u014Dpututia i mua",
address: "W\u0101hitau",
div: "DIV",
paragraph: "K\u014Dwae",
block: "H\u014Dputu",
fontdefault: "Font Family",
"font_size": "Font Size",
"style_select": "Ng\u0101 K\u0101hua",
"anchor_delta_height": "",
"anchor_delta_width": "",
"charmap_delta_height": "",
"charmap_delta_width": "",
"colorpicker_delta_height": "",
"colorpicker_delta_width": "",
"link_delta_height": "",
"link_delta_width": "",
"image_delta_height": "",
"image_delta_width": "",
"more_colors": "More Colors...",
"toolbar_focus": "Jump to tool buttons - Alt+Q, Jump to editor - Alt-Z, Jump to element path - Alt-X",
newdocument: "Are you sure you want clear all contents?",
path: "Path",
"clipboard_msg": "Copy/Cut/Paste is not available in Mozilla and Firefox. Do you want more information about this issue?",
"blockquote_desc": "Block Quote",
"help_desc": "Help",
"newdocument_desc": "New Document",
"image_props_desc": "Image Properties",
"paste_desc": "Paste (Ctrl+V)",
"copy_desc": "Copy (Ctrl+C)",
"cut_desc": "Cut (Ctrl+X)",
"anchor_desc": "Insert/Edit Anchor",
"visualaid_desc": "show/Hide Guidelines/Invisible Elements",
"charmap_desc": "Insert Special Character",
"backcolor_desc": "Select Background Color",
"forecolor_desc": "Select Text Color",
"custom1_desc": "Your Custom Description Here",
"removeformat_desc": "Remove Formatting",
"hr_desc": "Insert Horizontal Line",
"sup_desc": "Superscript",
"sub_desc": "Subscript",
"code_desc": "Edit HTML Source",
"cleanup_desc": "Cleanup Messy Code",
"image_desc": "Insert/Edit Image",
"unlink_desc": "Unlink",
"link_desc": "Insert/Edit Link",
"redo_desc": "Redo (Ctrl+Y)",
"undo_desc": "Undo (Ctrl+Z)",
"indent_desc": "Increase Indent",
"outdent_desc": "Decrease Indent",
"numlist_desc": "Insert/Remove Numbered List",
"bullist_desc": "Insert/Remove Bulleted List",
"justifyfull_desc": "Align Full",
"justifyright_desc": "Align Right",
"justifycenter_desc": "Align Center",
"justifyleft_desc": "Align Left",
"striketrough_desc": "Strikethrough",
"help_shortcut": "Press ALT-F10 for toolbar. Press ALT-0 for help",
"rich_text_area": "Rich Text Area",
"shortcuts_desc": "Accessability Help",
toolbar: "Toolbar"
});

View File

@ -1,6 +1,13 @@
(function() { (function() {
var each = tinymce.each; var each = tinymce.each;
// TinyMCE will stop loading if it encounters non-existent external script file
// when included through tiny_mce_gzip.php. Only load the external lang package if it is available.
var availableLangs = ['en', 'mi_NZ'];
if(jQuery.inArray(tinymce.settings.language, availableLangs) != -1) {
tinymce.PluginManager.requireLangPack("ssmacron");
}
/** /**
* Load via: * Load via:
* HtmlEditorConfig::get('cms')->enablePlugins(array('ssmacron', '../tinymce_ssmacron')) * HtmlEditorConfig::get('cms')->enablePlugins(array('ssmacron', '../tinymce_ssmacron'))
@ -33,7 +40,7 @@
// Register buttons // Register buttons
ed.addButton('ssmacron', { ed.addButton('ssmacron', {
title : 'Insert a Macron', title : t.editor.translate('insertmacron'),
cmd : 'mceInsertMacron', cmd : 'mceInsertMacron',
image : url + '/img/macron.png' image : url + '/img/macron.png'
}); });

View File

@ -0,0 +1 @@
tinyMCE.addI18n('en.ssmacron',{'insertmacron': 'Insert a Macron'});

View File

@ -0,0 +1 @@
tinyMCE.addI18n('mi_NZ.ssmacron',{'insertmacron': 'T\u0101urua he tohut\u014D'});