diff options
author | Jörn Zaefferer <joern.zaefferer@gmail.com> | 2011-08-10 14:55:16 +0200 |
---|---|---|
committer | Jörn Zaefferer <joern.zaefferer@gmail.com> | 2011-08-10 14:55:16 +0200 |
commit | 56e9cd71190a65c73023d6a631f7fd37c40f4167 (patch) | |
tree | b589e868fa38a8ce622d378968bfcd488c0fe635 /external/jquery.global.js | |
parent | bb79b418717bbd4b2ae800fc8c6bbe39682a2283 (diff) | |
download | jquery-ui-56e9cd71190a65c73023d6a631f7fd37c40f4167.tar.gz jquery-ui-56e9cd71190a65c73023d6a631f7fd37c40f4167.zip |
Replace $.global with Globalize, update Spinner to use it. Related demos currently broken due to previous changes.
Diffstat (limited to 'external/jquery.global.js')
-rw-r--r-- | external/jquery.global.js | 1341 |
1 files changed, 0 insertions, 1341 deletions
diff --git a/external/jquery.global.js b/external/jquery.global.js deleted file mode 100644 index 29ae5c637..000000000 --- a/external/jquery.global.js +++ /dev/null @@ -1,1341 +0,0 @@ -/*! - * jQuery Globalization Plugin - * http://github.com/jquery/jquery-global - * - * Copyright Software Freedom Conservancy, Inc. - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - */ -(function() { - -var Globalization = {}, localized = { en: {} }; -localized["default"] = localized.en; - -Globalization.extend = function( deep ) { - var target = arguments[ 1 ] || {}; - for ( var i = 2, l = arguments.length; i < l; i++ ) { - var source = arguments[ i ]; - if ( source ) { - for ( var field in source ) { - var sourceVal = source[ field ]; - if ( typeof sourceVal !== "undefined" ) { - if ( deep && (isObject( sourceVal ) || isArray( sourceVal )) ) { - var targetVal = target[ field ]; - // extend onto the existing value, or create a new one - targetVal = targetVal && (isObject( targetVal ) || isArray( targetVal )) - ? targetVal - : (isArray( sourceVal ) ? [] : {}); - target[ field ] = this.extend( true, targetVal, sourceVal ); - } - else { - target[ field ] = sourceVal; - } - } - } - } - } - return target; -} - -Globalization.findClosestCulture = function(name) { - var match; - if ( !name ) { - return this.culture || this.cultures["default"]; - } - if ( isString( name ) ) { - name = name.split( ',' ); - } - if ( isArray( name ) ) { - var lang, - cultures = this.cultures, - list = name, - i, l = list.length, - prioritized = []; - for ( i = 0; i < l; i++ ) { - name = trim( list[ i ] ); - var pri, parts = name.split( ';' ); - lang = trim( parts[ 0 ] ); - if ( parts.length === 1 ) { - pri = 1; - } - else { - name = trim( parts[ 1 ] ); - if ( name.indexOf("q=") === 0 ) { - name = name.substr( 2 ); - pri = parseFloat( name, 10 ); - pri = isNaN( pri ) ? 0 : pri; - } - else { - pri = 1; - } - } - prioritized.push( { lang: lang, pri: pri } ); - } - prioritized.sort(function(a, b) { - return a.pri < b.pri ? 1 : -1; - }); - for ( i = 0; i < l; i++ ) { - lang = prioritized[ i ].lang; - match = cultures[ lang ]; - // exact match? - if ( match ) { - return match; - } - } - for ( i = 0; i < l; i++ ) { - lang = prioritized[ i ].lang; - // for each entry try its neutral language - do { - var index = lang.lastIndexOf( "-" ); - if ( index === -1 ) { - break; - } - // strip off the last part. e.g. en-US => en - lang = lang.substr( 0, index ); - match = cultures[ lang ]; - if ( match ) { - return match; - } - } - while ( 1 ); - } - } - else if ( typeof name === 'object' ) { - return name; - } - return match || null; -} -Globalization.preferCulture = function(name) { - this.culture = this.findClosestCulture( name ) || this.cultures["default"]; -} -Globalization.localize = function(key, culture, value) { - // usign default culture in case culture is not provided - if (typeof culture !== 'string') { - culture = this.culture.name || this.culture || "default"; - } - culture = this.cultures[ culture ] || { name: culture }; - - var local = localized[ culture.name ]; - if ( arguments.length === 3 ) { - if ( !local) { - local = localized[ culture.name ] = {}; - } - local[ key ] = value; - } - else { - if ( local ) { - value = local[ key ]; - } - if ( typeof value === 'undefined' ) { - var language = localized[ culture.language ]; - if ( language ) { - value = language[ key ]; - } - if ( typeof value === 'undefined' ) { - value = localized["default"][ key ]; - } - } - } - return typeof value === "undefined" ? null : value; -} -Globalization.format = function(value, format, culture) { - culture = this.findClosestCulture( culture ); - if ( typeof value === "number" ) { - value = formatNumber( value, format, culture ); - } - else if ( value instanceof Date ) { - value = formatDate( value, format, culture ); - } - return value; -} -Globalization.parseInt = function(value, radix, culture) { - return Math.floor( this.parseFloat( value, radix, culture ) ); -} -Globalization.parseFloat = function(value, radix, culture) { - // make radix optional - if (typeof radix === "string") { - culture = radix; - radix = 10; - } - - culture = this.findClosestCulture( culture ); - var ret = NaN, - nf = culture.numberFormat; - - if (value.indexOf(culture.numberFormat.currency.symbol) > -1) { - // remove currency symbol - value = value.replace(culture.numberFormat.currency.symbol, ""); - // replace decimal seperator - value = value.replace(culture.numberFormat.currency["."], culture.numberFormat["."]); - } - - // trim leading and trailing whitespace - value = trim( value ); - - // allow infinity or hexidecimal - if (regexInfinity.test(value)) { - ret = parseFloat(value, radix); - } - else if (!radix && regexHex.test(value)) { - ret = parseInt(value, 16); - } - else { - var signInfo = parseNegativePattern( value, nf, nf.pattern[0] ), - sign = signInfo[0], - num = signInfo[1]; - // determine sign and number - if ( sign === "" && nf.pattern[0] !== "-n" ) { - signInfo = parseNegativePattern( value, nf, "-n" ); - sign = signInfo[0]; - num = signInfo[1]; - } - sign = sign || "+"; - // determine exponent and number - var exponent, - intAndFraction, - exponentPos = num.indexOf( 'e' ); - if ( exponentPos < 0 ) exponentPos = num.indexOf( 'E' ); - if ( exponentPos < 0 ) { - intAndFraction = num; - exponent = null; - } - else { - intAndFraction = num.substr( 0, exponentPos ); - exponent = num.substr( exponentPos + 1 ); - } - // determine decimal position - var integer, - fraction, - decSep = nf['.'], - decimalPos = intAndFraction.indexOf( decSep ); - if ( decimalPos < 0 ) { - integer = intAndFraction; - fraction = null; - } - else { - integer = intAndFraction.substr( 0, decimalPos ); - fraction = intAndFraction.substr( decimalPos + decSep.length ); - } - // handle groups (e.g. 1,000,000) - var groupSep = nf[","]; - integer = integer.split(groupSep).join(''); - var altGroupSep = groupSep.replace(/\u00A0/g, " "); - if ( groupSep !== altGroupSep ) { - integer = integer.split(altGroupSep).join(''); - } - // build a natively parsable number string - var p = sign + integer; - if ( fraction !== null ) { - p += '.' + fraction; - } - if ( exponent !== null ) { - // exponent itself may have a number patternd - var expSignInfo = parseNegativePattern( exponent, nf, "-n" ); - p += 'e' + (expSignInfo[0] || "+") + expSignInfo[1]; - } - if ( regexParseFloat.test( p ) ) { - ret = parseFloat( p ); - } - } - return ret; -} -Globalization.parseDate = function(value, formats, culture) { - culture = this.findClosestCulture( culture ); - - var date, prop, patterns; - if ( formats ) { - if ( typeof formats === "string" ) { - formats = [ formats ]; - } - if ( formats.length ) { - for ( var i = 0, l = formats.length; i < l; i++ ) { - var format = formats[ i ]; - if ( format ) { - date = parseExact( value, format, culture ); - if ( date ) { - break; - } - } - } - } - } - else { - patterns = culture.calendar.patterns; - for ( prop in patterns ) { - date = parseExact( value, patterns[prop], culture ); - if ( date ) { - break; - } - } - } - return date || null; -} - -// 1. When defining a culture, all fields are required except the ones stated as optional. -// 2. You can use Globalization.extend to copy an existing culture and provide only the differing values, -// a good practice since most cultures do not differ too much from the 'default' culture. -// DO use the 'default' culture if you do this, as it is the only one that definitely -// exists. -// 3. Other plugins may add to the culture information provided by extending it. However, -// that plugin may extend it prior to the culture being defined, or after. Therefore, -// do not overwrite values that already exist when defining the baseline for a culture, -// by extending your culture object with the existing one. -// 4. Each culture should have a ".calendars" object with at least one calendar named "standard" -// which serves as the default calendar in use by that culture. -// 5. Each culture should have a ".calendar" object which is the current calendar being used, -// it may be dynamically changed at any time to one of the calendars in ".calendars". - -// To define a culture, use the following pattern, which handles defining the culture based -// on the 'default culture, extending it with the existing culture if it exists, and defining -// it if it does not exist. -// Globalization.cultures.foo = Globalization.extend(true, Globalization.extend(true, {}, Globalization.cultures['default'], fooCulture), Globalization.cultures.foo) - -var cultures = Globalization.cultures = Globalization.cultures || {}; -var en = cultures["default"] = cultures.en = Globalization.extend(true, { - // A unique name for the culture in the form <language code>-<country/region code> - name: "en", - // the name of the culture in the english language - englishName: "English", - // the name of the culture in its own language - nativeName: "English", - // whether the culture uses right-to-left text - isRTL: false, - // 'language' is used for so-called "specific" cultures. - // For example, the culture "es-CL" means "Spanish, in Chili". - // It represents the Spanish-speaking culture as it is in Chili, - // which might have different formatting rules or even translations - // than Spanish in Spain. A "neutral" culture is one that is not - // specific to a region. For example, the culture "es" is the generic - // Spanish culture, which may be a more generalized version of the language - // that may or may not be what a specific culture expects. - // For a specific culture like "es-CL", the 'language' field refers to the - // neutral, generic culture information for the language it is using. - // This is not always a simple matter of the string before the dash. - // For example, the "zh-Hans" culture is netural (Simplified Chinese). - // And the 'zh-SG' culture is Simplified Chinese in Singapore, whose lanugage - // field is "zh-CHS", not "zh". - // This field should be used to navigate from a specific culture to it's - // more general, neutral culture. If a culture is already as general as it - // can get, the language may refer to itself. - language: "en", - // numberFormat defines general number formatting rules, like the digits in - // each grouping, the group separator, and how negative numbers are displayed. - numberFormat: { - // [negativePattern] - // Note, numberFormat.pattern has no 'positivePattern' unlike percent and currency, - // but is still defined as an array for consistency with them. - // negativePattern: one of "(n)|-n|- n|n-|n -" - pattern: ["-n"], - // number of decimal places normally shown - decimals: 2, - // string that separates number groups, as in 1,000,000 - ',': ",", - // string that separates a number from the fractional portion, as in 1.99 - '.': ".", - // array of numbers indicating the size of each number group. - // TODO: more detailed description and example - groupSizes: [3], - // symbol used for positive numbers - '+': "+", - // symbol used for negative numbers - '-': "-", - percent: { - // [negativePattern, positivePattern] - // negativePattern: one of "-n %|-n%|-%n|%-n|%n-|n-%|n%-|-% n|n %-|% n-|% -n|n- %" - // positivePattern: one of "n %|n%|%n|% n" - pattern: ["-n %","n %"], - // number of decimal places normally shown - decimals: 2, - // array of numbers indicating the size of each number group. - // TODO: more detailed description and example - groupSizes: [3], - // string that separates number groups, as in 1,000,000 - ',': ",", - // string that separates a number from the fractional portion, as in 1.99 - '.': ".", - // symbol used to represent a percentage - symbol: "%" - }, - currency: { - // [negativePattern, positivePattern] - // negativePattern: one of "($n)|-$n|$-n|$n-|(n$)|-n$|n-$|n$-|-n $|-$ n|n $-|$ n-|$ -n|n- $|($ n)|(n $)" - // positivePattern: one of "$n|n$|$ n|n $" - pattern: ["($n)","$n"], - // number of decimal places normally shown - decimals: 2, - // array of numbers indicating the size of each number group. - // TODO: more detailed description and example - groupSizes: [3], - // string that separates number groups, as in 1,000,000 - ',': ",", - // string that separates a number from the fractional portion, as in 1.99 - '.': ".", - // symbol used to represent currency - symbol: "$" - } - }, - // calendars defines all the possible calendars used by this culture. - // There should be at least one defined with name 'standard', and is the default - // calendar used by the culture. - // A calendar contains information about how dates are formatted, information about - // the calendar's eras, a standard set of the date formats, - // translations for day and month names, and if the calendar is not based on the Gregorian - // calendar, conversion functions to and from the Gregorian calendar. - calendars: { - standard: { - // name that identifies the type of calendar this is - name: "Gregorian_USEnglish", - // separator of parts of a date (e.g. '/' in 11/05/1955) - '/': "/", - // separator of parts of a time (e.g. ':' in 05:44 PM) - ':': ":", - // the first day of the week (0 = Sunday, 1 = Monday, etc) - firstDay: 0, - days: { - // full day names - names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], - // abbreviated day names - namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], - // shortest day names - namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] - }, - months: { - // full month names (13 months for lunar calendards -- 13th month should be "" if not lunar) - names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], - // abbreviated month names - namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] - }, - // AM and PM designators in one of these forms: - // The usual view, and the upper and lower case versions - // [standard,lowercase,uppercase] - // The culture does not use AM or PM (likely all standard date formats use 24 hour time) - // null - AM: ["AM", "am", "AM"], - PM: ["PM", "pm", "PM"], - eras: [ - // eras in reverse chronological order. - // name: the name of the era in this culture (e.g. A.D., C.E.) - // start: when the era starts in ticks (gregorian, gmt), null if it is the earliest supported era. - // offset: offset in years from gregorian calendar - { "name": "A.D.", "start": null, "offset": 0 } - ], - // when a two digit year is given, it will never be parsed as a four digit - // year greater than this year (in the appropriate era for the culture) - // Set it as a full year (e.g. 2029) or use an offset format starting from - // the current year: "+19" would correspond to 2029 if the current year 2010. - twoDigitYearMax: 2029, - // set of predefined date and time patterns used by the culture - // these represent the format someone in this culture would expect - // to see given the portions of the date that are shown. - patterns: { - // short date pattern - d: "M/d/yyyy", - // long date pattern - D: "dddd, MMMM dd, yyyy", - // short time pattern - t: "h:mm tt", - // long time pattern - T: "h:mm:ss tt", - // long date, short time pattern - f: "dddd, MMMM dd, yyyy h:mm tt", - // long date, long time pattern - F: "dddd, MMMM dd, yyyy h:mm:ss tt", - // month/day pattern - M: "MMMM dd", - // month/year pattern - Y: "yyyy MMMM", - // S is a sortable format that does not vary by culture - S: "yyyy\u0027-\u0027MM\u0027-\u0027dd\u0027T\u0027HH\u0027:\u0027mm\u0027:\u0027ss" - } - // optional fields for each calendar: - /* - monthsGenitive: - Same as months but used when the day preceeds the month. - Omit if the culture has no genitive distinction in month names. - For an explaination of genitive months, see http://blogs.msdn.com/michkap/archive/2004/12/25/332259.aspx - convert: - Allows for the support of non-gregorian based calendars. This convert object is used to - to convert a date to and from a gregorian calendar date to handle parsing and formatting. - The two functions: - fromGregorian(date) - Given the date as a parameter, return an array with parts [year, month, day] - corresponding to the non-gregorian based year, month, and day for the calendar. - toGregorian(year, month, day) - Given the non-gregorian year, month, and day, return a new Date() object - set to the corresponding date in the gregorian calendar. - */ - } - } -}, cultures.en); -en.calendar = en.calendar || en.calendars.standard; - -var regexTrim = /^\s+|\s+$/g, - regexInfinity = /^[+-]?infinity$/i, - regexHex = /^0x[a-f0-9]+$/i, - regexParseFloat = /^[+-]?\d*\.?\d*(e[+-]?\d+)?$/, - toString = Object.prototype.toString; - -function startsWith(value, pattern) { - return value.indexOf( pattern ) === 0; -} - -function endsWith(value, pattern) { - return value.substr( value.length - pattern.length ) === pattern; -} - -function trim(value) { - return (value+"").replace( regexTrim, "" ); -} - -function zeroPad(str, count, left) { - for (var l=str.length; l < count; l++) { - str = (left ? ('0' + str) : (str + '0')); - } - return str; -} - -function isArray(obj) { - return toString.call(obj) === "[object Array]"; -} - -function isString(obj) { - return toString.call(obj) === "[object String]"; -} - -function isObject(obj) { - return toString.call(obj) === "[object Object]"; -} - -function arrayIndexOf( array, item ) { - if ( array.indexOf ) { - return array.indexOf( item ); - } - for ( var i = 0, length = array.length; i < length; i++ ) { - if ( array[ i ] === item ) { - return i; - } - } - return -1; -} - -// *************************************** Numbers *************************************** - -function expandNumber(number, precision, formatInfo) { - var groupSizes = formatInfo.groupSizes, - curSize = groupSizes[ 0 ], - curGroupIndex = 1, - factor = Math.pow( 10, precision ), - rounded = Math.round( number * factor ) / factor; - if ( !isFinite(rounded) ) { - rounded = number; - } - number = rounded; - - var numberString = number+"", - right = "", - split = numberString.split(/e/i), - exponent = split.length > 1 ? parseInt( split[ 1 ], 10 ) : 0; - numberString = split[ 0 ]; - split = numberString.split( "." ); - numberString = split[ 0 ]; - right = split.length > 1 ? split[ 1 ] : ""; - - var l; - if ( exponent > 0 ) { - right = zeroPad( right, exponent, false ); - numberString += right.slice( 0, exponent ); - right = right.substr( exponent ); - } - else if ( exponent < 0 ) { - exponent = -exponent; - numberString = zeroPad( numberString, exponent + 1 ); - right = numberString.slice( -exponent, numberString.length ) + right; - numberString = numberString.slice( 0, -exponent ); - } - - if ( precision > 0 ) { - right = formatInfo['.'] + - ((right.length > precision) ? right.slice( 0, precision ) : zeroPad( right, precision )); - } - else { - right = ""; - } - - var stringIndex = numberString.length - 1, - sep = formatInfo[","], - ret = ""; - - while ( stringIndex >= 0 ) { - if ( curSize === 0 || curSize > stringIndex ) { - return numberString.slice( 0, stringIndex + 1 ) + ( ret.length ? ( sep + ret + right ) : right ); - } - ret = numberString.slice( stringIndex - curSize + 1, stringIndex + 1 ) + ( ret.length ? ( sep + ret ) : "" ); - - stringIndex -= curSize; - - if ( curGroupIndex < groupSizes.length ) { - curSize = groupSizes[ curGroupIndex ]; - curGroupIndex++; - } - } - return numberString.slice( 0, stringIndex + 1 ) + sep + ret + right; -} - - -function parseNegativePattern(value, nf, negativePattern) { - var neg = nf["-"], - pos = nf["+"], - ret; - switch (negativePattern) { - case "n -": - neg = ' ' + neg; - pos = ' ' + pos; - // fall through - case "n-": - if ( endsWith( value, neg ) ) { - ret = [ '-', value.substr( 0, value.length - neg.length ) ]; - } - else if ( endsWith( value, pos ) ) { - ret = [ '+', value.substr( 0, value.length - pos.length ) ]; - } - break; - case "- n": - neg += ' '; - pos += ' '; - // fall through - case "-n": - if ( startsWith( value, neg ) ) { - ret = [ '-', value.substr( neg.length ) ]; - } - else if ( startsWith(value, pos) ) { - ret = [ '+', value.substr( pos.length ) ]; - } - break; - case "(n)": - if ( startsWith( value, '(' ) && endsWith( value, ')' ) ) { - ret = [ '-', value.substr( 1, value.length - 2 ) ]; - } - break; - } - return ret || [ '', value ]; -} - -function formatNumber(value, format, culture) { - if ( !format || format === 'i' ) { - return culture.name.length ? value.toLocaleString() : value.toString(); - } - format = format || "D"; - - var nf = culture.numberFormat, - number = Math.abs(value), - precision = -1, - pattern; - if (format.length > 1) precision = parseInt( format.slice( 1 ), 10 ); - - var current = format.charAt( 0 ).toUpperCase(), - formatInfo; - - switch (current) { - case "D": - pattern = 'n'; - if (precision !== -1) { - number = zeroPad( ""+number, precision, true ); - } - if (value < 0) number = -number; - break; - case "N": - formatInfo = nf; - // fall through - case "C": - formatInfo = formatInfo || nf.currency; - // fall through - case "P": - formatInfo = formatInfo || nf.percent; - pattern = value < 0 ? formatInfo.pattern[0] : (formatInfo.pattern[1] || "n"); - if (precision === -1) precision = formatInfo.decimals; - number = expandNumber( number * (current === "P" ? 100 : 1), precision, formatInfo ); - break; - default: - throw "Bad number format specifier: " + current; - } - - var patternParts = /n|\$|-|%/g, - ret = ""; - for (;;) { - var index = patternParts.lastIndex, - ar = patternParts.exec(pattern); - - ret += pattern.slice( index, ar ? ar.index : pattern.length ); - - if (!ar) { - break; - } - - switch (ar[0]) { - case "n": - ret += number; - break; - case "$": - ret += nf.currency.symbol; - break; - case "-": - // don't make 0 negative - if ( /[1-9]/.test( number ) ) { - ret += nf["-"]; - } - break; - case "%": - ret += nf.percent.symbol; - break; - } - } - - return ret; -} - -// *************************************** Dates *************************************** - -function outOfRange(value, low, high) { - return value < low || value > high; -} - -function expandYear(cal, year) { - // expands 2-digit year into 4 digits. - var now = new Date(), - era = getEra(now); - if ( year < 100 ) { - var twoDigitYearMax = cal.twoDigitYearMax; - twoDigitYearMax = typeof twoDigitYearMax === 'string' ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax; - var curr = getEraYear( now, cal, era ); - year += curr - ( curr % 100 ); - if ( year > twoDigitYearMax ) { - year -= 100; - } - } - return year; -} - -function getEra(date, eras) { - if ( !eras ) return 0; - var start, ticks = date.getTime(); - for ( var i = 0, l = eras.length; i < l; i++ ) { - start = eras[ i ].start; - if ( start === null || ticks >= start ) { - return i; - } - } - return 0; -} - -function toUpper(value) { - // 'he-IL' has non-breaking space in weekday names. - return value.split( "\u00A0" ).join(' ').toUpperCase(); -} - -function toUpperArray(arr) { - var results = []; - for ( var i = 0, l = arr.length; i < l; i++ ) { - results[i] = toUpper(arr[i]); - } - return results; -} - -function getEraYear(date, cal, era, sortable) { - var year = date.getFullYear(); - if ( !sortable && cal.eras ) { - // convert normal gregorian year to era-shifted gregorian - // year by subtracting the era offset - year -= cal.eras[ era ].offset; - } - return year; -} - -function getDayIndex(cal, value, abbr) { - var ret, - days = cal.days, - upperDays = cal._upperDays; - if ( !upperDays ) { - cal._upperDays = upperDays = [ - toUpperArray( days.names ), - toUpperArray( days.namesAbbr ), - toUpperArray( days.namesShort ) - ]; - } - value = toUpper( value ); - if ( abbr ) { - ret = arrayIndexOf( upperDays[ 1 ], value ); - if ( ret === -1 ) { - ret = arrayIndexOf( upperDays[ 2 ], value ); - } - } - else { - ret = arrayIndexOf( upperDays[ 0 ], value ); - } - return ret; -} - -function getMonthIndex(cal, value, abbr) { - var months = cal.months, - monthsGen = cal.monthsGenitive || cal.months, - upperMonths = cal._upperMonths, - upperMonthsGen = cal._upperMonthsGen; - if ( !upperMonths ) { - cal._upperMonths = upperMonths = [ - toUpperArray( months.names ), - toUpperArray( months.namesAbbr ) - ]; - cal._upperMonthsGen = upperMonthsGen = [ - toUpperArray( monthsGen.names ), - toUpperArray( monthsGen.namesAbbr ) - ]; - } - value = toUpper( value ); - var i = arrayIndexOf( abbr ? upperMonths[ 1 ] : upperMonths[ 0 ], value ); - if ( i < 0 ) { - i = arrayIndexOf( abbr ? upperMonthsGen[ 1 ] : upperMonthsGen[ 0 ], value ); - } - return i; -} - -function appendPreOrPostMatch(preMatch, strings) { - // appends pre- and post- token match strings while removing escaped characters. - // Returns a single quote count which is used to determine if the token occurs - // in a string literal. - var quoteCount = 0, - escaped = false; - for ( var i = 0, il = preMatch.length; i < il; i++ ) { - var c = preMatch.charAt( i ); - switch ( c ) { - case '\'': - if ( escaped ) { - strings.push( "'" ); - } - else { - quoteCount++; - } - escaped = false; - break; - case '\\': - if ( escaped ) { - strings.push( "\\" ); - } - escaped = !escaped; - break; - default: - strings.push( c ); - escaped = false; - break; - } - } - return quoteCount; -} - -function expandFormat(cal, format) { - // expands unspecified or single character date formats into the full pattern. - format = format || "F"; - var pattern, - patterns = cal.patterns, - len = format.length; - if ( len === 1 ) { - pattern = patterns[ format ]; - if ( !pattern ) { - throw "Invalid date format string '" + format + "'."; - } - format = pattern; - } - else if ( len === 2 && format.charAt(0) === "%" ) { - // %X escape format -- intended as a custom format string that is only one character, not a built-in format. - format = format.charAt( 1 ); - } - return format; -} - -function getParseRegExp(cal, format) { - // converts a format string into a regular expression with groups that - // can be used to extract date fields from a date string. - // check for a cached parse regex. - var re = cal._parseRegExp; - if ( !re ) { - cal._parseRegExp = re = {}; - } - else { - var reFormat = re[ format ]; - if ( reFormat ) { - return reFormat; - } - } - - // expand single digit formats, then escape regular expression characters. - var expFormat = expandFormat( cal, format ).replace( /([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g, "\\\\$1" ), - regexp = ["^"], - groups = [], - index = 0, - quoteCount = 0, - tokenRegExp = getTokenRegExp(), - match; - - // iterate through each date token found. - while ( (match = tokenRegExp.exec( expFormat )) !== null ) { - var preMatch = expFormat.slice( index, match.index ); - index = tokenRegExp.lastIndex; - - // don't replace any matches that occur inside a string literal. - quoteCount += appendPreOrPostMatch( preMatch, regexp ); - if ( quoteCount % 2 ) { - regexp.push( match[ 0 ] ); - continue; - } - - // add a regex group for the token. - var m = match[ 0 ], - len = m.length, - add; - switch ( m ) { - case 'dddd': case 'ddd': - case 'MMMM': case 'MMM': - case 'gg': case 'g': - add = "(\\D+)"; - break; - case 'tt': case 't': - add = "(\\D*)"; - break; - case 'yyyy': - case 'fff': - case 'ff': - case 'f': - add = "(\\d{" + len + "})"; - break; - case 'dd': case 'd': - case 'MM': case 'M': - case 'yy': case 'y': - case 'HH': case 'H': - case 'hh': case 'h': - case 'mm': case 'm': - case 'ss': case 's': - add = "(\\d\\d?)"; - break; - case 'zzz': - add = "([+-]?\\d\\d?:\\d{2})"; - break; - case 'zz': case 'z': - add = "([+-]?\\d\\d?)"; - break; - case '/': - add = "(\\" + cal["/"] + ")"; - break; - default: - throw "Invalid date format pattern '" + m + "'."; - break; - } - if ( add ) { - regexp.push( add ); - } - groups.push( match[ 0 ] ); - } - appendPreOrPostMatch( expFormat.slice( index ), regexp ); - regexp.push( "$" ); - - // allow whitespace to differ when matching formats. - var regexpStr = regexp.join( '' ).replace( /\s+/g, "\\s+" ), - parseRegExp = {'regExp': regexpStr, 'groups': groups}; - - // cache the regex for this format. - return re[ format ] = parseRegExp; -} - -function getTokenRegExp() { - // regular expression for matching date and time tokens in format strings. - return /\/|dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z|gg|g/g; -} - -function parseExact(value, format, culture) { - // try to parse the date string by matching against the format string - // while using the specified culture for date field names. - value = trim( value ); - var cal = culture.calendar, - // convert date formats into regular expressions with groupings. - // use the regexp to determine the input format and extract the date fields. - parseInfo = getParseRegExp(cal, format), - match = new RegExp(parseInfo.regExp).exec(value); - if (match === null) { - return null; - } - // found a date format that matches the input. - var groups = parseInfo.groups, - era = null, year = null, month = null, date = null, weekDay = null, - hour = 0, hourOffset, min = 0, sec = 0, msec = 0, tzMinOffset = null, - pmHour = false; - // iterate the format groups to extract and set the date fields. - for ( var j = 0, jl = groups.length; j < jl; j++ ) { - var matchGroup = match[ j + 1 ]; - if ( matchGroup ) { - var current = groups[ j ], - clength = current.length, - matchInt = parseInt( matchGroup, 10 ); - switch ( current ) { - case 'dd': case 'd': - // Day of month. - date = matchInt; - // check that date is generally in valid range, also checking overflow below. - if ( outOfRange( date, 1, 31 ) ) return null; - break; - case 'MMM': - case 'MMMM': - month = getMonthIndex( cal, matchGroup, clength === 3 ); - if ( outOfRange( month, 0, 11 ) ) return null; - break; - case 'M': case 'MM': - // Month. - month = matchInt - 1; - if ( outOfRange( month, 0, 11 ) ) return null; - break; - case 'y': case 'yy': - case 'yyyy': - year = clength < 4 ? expandYear( cal, matchInt ) : matchInt; - if ( outOfRange( year, 0, 9999 ) ) return null; - break; - case 'h': case 'hh': - // Hours (12-hour clock). - hour = matchInt; - if ( hour === 12 ) hour = 0; - if ( outOfRange( hour, 0, 11 ) ) return null; - break; - case 'H': case 'HH': - // Hours (24-hour clock). - hour = matchInt; - if ( outOfRange( hour, 0, 23 ) ) return null; - break; - case 'm': case 'mm': - // Minutes. - min = matchInt; - if ( outOfRange( min, 0, 59 ) ) return null; - break; - case 's': case 'ss': - // Seconds. - sec = matchInt; - if ( outOfRange( sec, 0, 59 ) ) return null; - break; - case 'tt': case 't': - // AM/PM designator. - // see if it is standard, upper, or lower case PM. If not, ensure it is at least one of - // the AM tokens. If not, fail the parse for this format. - pmHour = cal.PM && ( matchGroup === cal.PM[0] || matchGroup === cal.PM[1] || matchGroup === cal.PM[2] ); - if ( !pmHour && ( !cal.AM || (matchGroup !== cal.AM[0] && matchGroup !== cal.AM[1] && matchGroup !== cal.AM[2]) ) ) return null; - break; - case 'f': - // Deciseconds. - case 'ff': - // Centiseconds. - case 'fff': - // Milliseconds. - msec = matchInt * Math.pow( 10, 3-clength ); - if ( outOfRange( msec, 0, 999 ) ) return null; - break; - case 'ddd': - // Day of week. - case 'dddd': - // Day of week. - weekDay = getDayIndex( cal, matchGroup, clength === 3 ); - if ( outOfRange( weekDay, 0, 6 ) ) return null; - break; - case 'zzz': - // Time zone offset in +/- hours:min. - var offsets = matchGroup.split( /:/ ); - if ( offsets.length !== 2 ) return null; - hourOffset = parseInt( offsets[ 0 ], 10 ); - if ( outOfRange( hourOffset, -12, 13 ) ) return null; - var minOffset = parseInt( offsets[ 1 ], 10 ); - if ( outOfRange( minOffset, 0, 59 ) ) return null; - tzMinOffset = (hourOffset * 60) + (startsWith( matchGroup, '-' ) ? -minOffset : minOffset); - break; - case 'z': case 'zz': - // Time zone offset in +/- hours. - hourOffset = matchInt; - if ( outOfRange( hourOffset, -12, 13 ) ) return null; - tzMinOffset = hourOffset * 60; - break; - case 'g': case 'gg': - var eraName = matchGroup; - if ( !eraName || !cal.eras ) return null; - eraName = trim( eraName.toLowerCase() ); - for ( var i = 0, l = cal.eras.length; i < l; i++ ) { - if ( eraName === cal.eras[ i ].name.toLowerCase() ) { - era = i; - break; - } - } - // could not find an era with that name - if ( era === null ) return null; - break; - } - } - } - var result = new Date(), defaultYear, convert = cal.convert; - defaultYear = convert ? convert.fromGregorian( result )[ 0 ] : result.getFullYear(); - if ( year === null ) { - year = defaultYear; - } - else if ( cal.eras ) { - // year must be shifted to normal gregorian year - // but not if year was not specified, its already normal gregorian - // per the main if clause above. - year += cal.eras[ (era || 0) ].offset; - } - // set default day and month to 1 and January, so if unspecified, these are the defaults - // instead of the current day/month. - if ( month === null ) { - month = 0; - } - if ( date === null ) { - date = 1; - } - // now have year, month, and date, but in the culture's calendar. - // convert to gregorian if necessary - if ( convert ) { - result = convert.toGregorian( year, month, date ); - // conversion failed, must be an invalid match - if ( result === null ) return null; - } - else { - // have to set year, month and date together to avoid overflow based on current date. - result.setFullYear( year, month, date ); - // check to see if date overflowed for specified month (only checked 1-31 above). - if ( result.getDate() !== date ) return null; - // invalid day of week. - if ( weekDay !== null && result.getDay() !== weekDay ) { - return null; - } - } - // if pm designator token was found make sure the hours fit the 24-hour clock. - if ( pmHour && hour < 12 ) { - hour += 12; - } - result.setHours( hour, min, sec, msec ); - if ( tzMinOffset !== null ) { - // adjust timezone to utc before applying local offset. - var adjustedMin = result.getMinutes() - ( tzMinOffset + result.getTimezoneOffset() ); - // Safari limits hours and minutes to the range of -127 to 127. We need to use setHours - // to ensure both these fields will not exceed this range. adjustedMin will range - // somewhere between -1440 and 1500, so we only need to split this into hours. - result.setHours( result.getHours() + parseInt( adjustedMin / 60, 10 ), adjustedMin % 60 ); - } - return result; -} - -function formatDate(value, format, culture) { - var cal = culture.calendar, - convert = cal.convert; - if ( !format || !format.length || format === 'i' ) { - var ret; - if ( culture && culture.name.length ) { - if ( convert ) { - // non-gregorian calendar, so we cannot use built-in toLocaleString() - ret = formatDate( value, cal.patterns.F, culture ); - } - else { - var eraDate = new Date( value.getTime() ), - era = getEra( value, cal.eras ); - eraDate.setFullYear( getEraYear( value, cal, era ) ); - ret = eraDate.toLocaleString(); - } - } - else { - ret = value.toString(); - } - return ret; - } - - var eras = cal.eras, - sortable = format === "s"; - format = expandFormat( cal, format ); - - // Start with an empty string - ret = []; - var hour, - zeros = ['0','00','000'], - foundDay, - checkedDay, - dayPartRegExp = /([^d]|^)(d|dd)([^d]|$)/g, - quoteCount = 0, - tokenRegExp = getTokenRegExp(), - converted; - - function padZeros(num, c) { - var r, s = num+''; - if ( c > 1 && s.length < c ) { - r = ( zeros[ c - 2 ] + s); - return r.substr( r.length - c, c ); - } - else { - r = s; - } - return r; - } - - function hasDay() { - if ( foundDay || checkedDay ) { - return foundDay; - } - foundDay = dayPartRegExp.test( format ); - checkedDay = true; - return foundDay; - } - - function getPart( date, part ) { - if ( converted ) { - return converted[ part ]; - } - switch ( part ) { - case 0: return date.getFullYear(); - case 1: return date.getMonth(); - case 2: return date.getDate(); - } - } - - if ( !sortable && convert ) { - converted = convert.fromGregorian( value ); - } - - for (;;) { - // Save the current index - var index = tokenRegExp.lastIndex, - // Look for the next pattern - ar = tokenRegExp.exec( format ); - - // Append the text before the pattern (or the end of the string if not found) - var preMatch = format.slice( index, ar ? ar.index : format.length ); - quoteCount += appendPreOrPostMatch( preMatch, ret ); - - if ( !ar ) { - break; - } - - // do not replace any matches that occur inside a string literal. - if ( quoteCount % 2 ) { - ret.push( ar[ 0 ] ); - continue; - } - - var current = ar[ 0 ], - clength = current.length; - - switch ( current ) { - case "ddd": - //Day of the week, as a three-letter abbreviation - case "dddd": - // Day of the week, using the full name - names = (clength === 3) ? cal.days.namesAbbr : cal.days.names; - ret.push( names[ value.getDay() ] ); - break; - case "d": - // Day of month, without leading zero for single-digit days - case "dd": - // Day of month, with leading zero for single-digit days - foundDay = true; - ret.push( padZeros( getPart( value, 2 ), clength ) ); - break; - case "MMM": - // Month, as a three-letter abbreviation - case "MMMM": - // Month, using the full name - var part = getPart( value, 1 ); - ret.push( (cal.monthsGenitive && hasDay()) - ? cal.monthsGenitive[ clength === 3 ? "namesAbbr" : "names" ][ part ] - : cal.months[ clength === 3 ? "namesAbbr" : "names" ][ part ] ); - break; - case "M": - // Month, as digits, with no leading zero for single-digit months - case "MM": - // Month, as digits, with leading zero for single-digit months - ret.push( padZeros( getPart( value, 1 ) + 1, clength ) ); - break; - case "y": - // Year, as two digits, but with no leading zero for years less than 10 - case "yy": - // Year, as two digits, with leading zero for years less than 10 - case "yyyy": - // Year represented by four full digits - part = converted ? converted[ 0 ] : getEraYear( value, cal, getEra( value, eras ), sortable ); - if ( clength < 4 ) { - part = part % 100; - } - ret.push( padZeros( part, clength ) ); - break; - case "h": - // Hours with no leading zero for single-digit hours, using 12-hour clock - case "hh": - // Hours with leading zero for single-digit hours, using 12-hour clock - hour = value.getHours() % 12; - if ( hour === 0 ) hour = 12; - ret.push( padZeros( hour, clength ) ); - break; - case "H": - // Hours with no leading zero for single-digit hours, using 24-hour clock - case "HH": - // Hours with leading zero for single-digit hours, using 24-hour clock - ret.push( padZeros( value.getHours(), clength ) ); - break; - case "m": - // Minutes with no leading zero for single-digit minutes - case "mm": - // Minutes with leading zero for single-digit minutes - ret.push( padZeros( value.getMinutes(), clength ) ); - break; - case "s": - // Seconds with no leading zero for single-digit seconds - case "ss": - // Seconds with leading zero for single-digit seconds - ret.push( padZeros(value .getSeconds(), clength ) ); - break; - case "t": - // One character am/pm indicator ("a" or "p") - case "tt": - // Multicharacter am/pm indicator - part = value.getHours() < 12 ? (cal.AM ? cal.AM[0] : " ") : (cal.PM ? cal.PM[0] : " "); - ret.push( clength === 1 ? part.charAt( 0 ) : part ); - break; - case "f": - // Deciseconds - case "ff": - // Centiseconds - case "fff": - // Milliseconds - ret.push( padZeros( value.getMilliseconds(), 3 ).substr( 0, clength ) ); - break; - case "z": - // Time zone offset, no leading zero - case "zz": - // Time zone offset with leading zero - hour = value.getTimezoneOffset() / 60; - ret.push( (hour <= 0 ? '+' : '-') + padZeros( Math.floor( Math.abs( hour ) ), clength ) ); - break; - case "zzz": - // Time zone offset with leading zero - hour = value.getTimezoneOffset() / 60; - ret.push( (hour <= 0 ? '+' : '-') + padZeros( Math.floor( Math.abs( hour ) ), 2 ) + - // Hard coded ":" separator, rather than using cal.TimeSeparator - // Repeated here for consistency, plus ":" was already assumed in date parsing. - ":" + padZeros( Math.abs( value.getTimezoneOffset() % 60 ), 2 ) ); - break; - case "g": - case "gg": - if ( cal.eras ) { - ret.push( cal.eras[ getEra(value, eras) ].name ); - } - break; - case "/": - ret.push( cal["/"] ); - break; - default: - throw "Invalid date format pattern '" + current + "'."; - break; - } - } - return ret.join( '' ); -} - -// EXPORTS -jQuery.global = Globalization; - -})(); - |