aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gruntfile.js52
-rw-r--r--bower.json1
-rw-r--r--build/tasks/testswarm.js1
-rw-r--r--demos/bootstrap.js13
-rw-r--r--demos/calendar/buttonbar.html28
-rw-r--r--demos/calendar/default.html (renamed from demos/datepicker/inline.html)8
-rw-r--r--demos/calendar/dropdown-month-year.html (renamed from demos/datepicker/dropdown-month-year.html)6
-rw-r--r--demos/calendar/index.html22
-rw-r--r--demos/calendar/localization.html41
-rw-r--r--demos/calendar/min-max.html33
-rw-r--r--demos/calendar/multiple-months.html (renamed from demos/datepicker/multiple-calendars.html)11
-rw-r--r--demos/calendar/other-months.html (renamed from demos/datepicker/other-months.html)17
-rw-r--r--demos/calendar/show-week.html26
-rw-r--r--demos/datepicker/alt-field.html25
-rw-r--r--demos/datepicker/animation.html13
-rw-r--r--demos/datepicker/buttonbar.html24
-rw-r--r--demos/datepicker/date-formats.html21
-rw-r--r--demos/datepicker/date-range.html53
-rw-r--r--demos/datepicker/icon-trigger.html28
-rw-r--r--demos/datepicker/index.html13
-rw-r--r--demos/datepicker/localization.html30
-rw-r--r--demos/datepicker/min-max.html22
-rw-r--r--demos/datepicker/show-week.html28
-rw-r--r--demos/index.html1
-rw-r--r--demos/spinner/currency.html7
-rw-r--r--demos/spinner/decimal.html7
-rw-r--r--demos/spinner/time.html6
-rw-r--r--external/cldrjs/LICENSE-MIT/LICENSE-MIT22
-rw-r--r--external/cldrjs/cldr.js662
-rw-r--r--external/cldrjs/cldr/event.js585
-rw-r--r--external/cldrjs/cldr/supplemental.js101
-rw-r--r--external/globalize-old/LICENSE (renamed from external/globalize/LICENSE)0
-rw-r--r--external/globalize-old/globalize.culture.de-DE.js (renamed from external/globalize/globalize.culture.de-DE.js)0
-rw-r--r--external/globalize-old/globalize.culture.ja-JP.js (renamed from external/globalize/globalize.culture.ja-JP.js)0
-rw-r--r--external/globalize-old/globalize.js1585
-rw-r--r--external/globalize/LICENSE.txt43
-rw-r--r--external/globalize/globalize-runtime.js236
-rw-r--r--external/globalize/globalize-runtime/date.js1289
-rw-r--r--external/globalize/globalize-runtime/number.js682
-rw-r--r--external/globalize/globalize.js1726
-rw-r--r--external/localization.js115
-rw-r--r--package.json2
-rw-r--r--tests/lib/bootstrap.js15
-rw-r--r--tests/unit/all.html1
-rw-r--r--tests/unit/calendar/all.html26
-rw-r--r--tests/unit/calendar/calendar.html21
-rw-r--r--tests/unit/calendar/common.js33
-rw-r--r--tests/unit/calendar/core.js393
-rw-r--r--tests/unit/calendar/events.js0
-rw-r--r--tests/unit/calendar/helper.js31
-rw-r--r--tests/unit/calendar/methods.js145
-rw-r--r--tests/unit/calendar/options.js401
-rw-r--r--tests/unit/date/all.html26
-rw-r--r--tests/unit/date/core.js174
-rw-r--r--tests/unit/date/date.html16
-rw-r--r--tests/unit/date/helper.js31
-rw-r--r--tests/unit/datepicker/common.js45
-rw-r--r--tests/unit/datepicker/core.js641
-rw-r--r--tests/unit/datepicker/datepicker.html6
-rw-r--r--tests/unit/datepicker/events.js274
-rw-r--r--tests/unit/datepicker/helper.js16
-rw-r--r--tests/unit/datepicker/methods.js235
-rw-r--r--tests/unit/datepicker/options.js1233
-rw-r--r--tests/unit/index.html1
-rw-r--r--tests/unit/spinner/options.js4
-rw-r--r--themes/base/base.css1
-rw-r--r--themes/base/calendar.css158
-rw-r--r--themes/base/datepicker.css170
-rw-r--r--ui/date.js192
-rw-r--r--ui/i18n/datepicker-af.js37
-rw-r--r--ui/i18n/datepicker-ar-DZ.js37
-rw-r--r--ui/i18n/datepicker-ar.js38
-rw-r--r--ui/i18n/datepicker-az.js37
-rw-r--r--ui/i18n/datepicker-be.js37
-rw-r--r--ui/i18n/datepicker-bg.js38
-rw-r--r--ui/i18n/datepicker-bs.js37
-rw-r--r--ui/i18n/datepicker-ca.js37
-rw-r--r--ui/i18n/datepicker-cs.js37
-rw-r--r--ui/i18n/datepicker-cy-GB.js37
-rw-r--r--ui/i18n/datepicker-da.js37
-rw-r--r--ui/i18n/datepicker-de.js37
-rw-r--r--ui/i18n/datepicker-el.js37
-rw-r--r--ui/i18n/datepicker-en-AU.js37
-rw-r--r--ui/i18n/datepicker-en-GB.js37
-rw-r--r--ui/i18n/datepicker-en-NZ.js37
-rw-r--r--ui/i18n/datepicker-eo.js37
-rw-r--r--ui/i18n/datepicker-es.js37
-rw-r--r--ui/i18n/datepicker-et.js37
-rw-r--r--ui/i18n/datepicker-eu.js36
-rw-r--r--ui/i18n/datepicker-fa.js73
-rw-r--r--ui/i18n/datepicker-fi.js37
-rw-r--r--ui/i18n/datepicker-fo.js37
-rw-r--r--ui/i18n/datepicker-fr-CA.js37
-rw-r--r--ui/i18n/datepicker-fr-CH.js37
-rw-r--r--ui/i18n/datepicker-fr.js39
-rw-r--r--ui/i18n/datepicker-gl.js37
-rw-r--r--ui/i18n/datepicker-he.js37
-rw-r--r--ui/i18n/datepicker-hi.js37
-rw-r--r--ui/i18n/datepicker-hr.js37
-rw-r--r--ui/i18n/datepicker-hu.js36
-rw-r--r--ui/i18n/datepicker-hy.js37
-rw-r--r--ui/i18n/datepicker-id.js37
-rw-r--r--ui/i18n/datepicker-is.js37
-rw-r--r--ui/i18n/datepicker-it-CH.js37
-rw-r--r--ui/i18n/datepicker-it.js37
-rw-r--r--ui/i18n/datepicker-ja.js37
-rw-r--r--ui/i18n/datepicker-ka.js35
-rw-r--r--ui/i18n/datepicker-kk.js37
-rw-r--r--ui/i18n/datepicker-km.js37
-rw-r--r--ui/i18n/datepicker-ko.js37
-rw-r--r--ui/i18n/datepicker-ky.js38
-rw-r--r--ui/i18n/datepicker-lb.js37
-rw-r--r--ui/i18n/datepicker-lt.js37
-rw-r--r--ui/i18n/datepicker-lv.js37
-rw-r--r--ui/i18n/datepicker-mk.js37
-rw-r--r--ui/i18n/datepicker-ml.js37
-rw-r--r--ui/i18n/datepicker-ms.js37
-rw-r--r--ui/i18n/datepicker-nb.js36
-rw-r--r--ui/i18n/datepicker-nl-BE.js37
-rw-r--r--ui/i18n/datepicker-nl.js37
-rw-r--r--ui/i18n/datepicker-nn.js36
-rw-r--r--ui/i18n/datepicker-no.js37
-rw-r--r--ui/i18n/datepicker-pl.js37
-rw-r--r--ui/i18n/datepicker-pt-BR.js37
-rw-r--r--ui/i18n/datepicker-pt.js36
-rw-r--r--ui/i18n/datepicker-rm.js35
-rw-r--r--ui/i18n/datepicker-ro.js40
-rw-r--r--ui/i18n/datepicker-ru.js37
-rw-r--r--ui/i18n/datepicker-sk.js37
-rw-r--r--ui/i18n/datepicker-sl.js38
-rw-r--r--ui/i18n/datepicker-sq.js37
-rw-r--r--ui/i18n/datepicker-sr-SR.js37
-rw-r--r--ui/i18n/datepicker-sr.js37
-rw-r--r--ui/i18n/datepicker-sv.js37
-rw-r--r--ui/i18n/datepicker-ta.js37
-rw-r--r--ui/i18n/datepicker-th.js37
-rw-r--r--ui/i18n/datepicker-tj.js37
-rw-r--r--ui/i18n/datepicker-tr.js37
-rw-r--r--ui/i18n/datepicker-uk.js38
-rw-r--r--ui/i18n/datepicker-vi.js37
-rw-r--r--ui/i18n/datepicker-zh-CN.js37
-rw-r--r--ui/i18n/datepicker-zh-HK.js37
-rw-r--r--ui/i18n/datepicker-zh-TW.js37
-rw-r--r--ui/widgets/calendar.js689
-rw-r--r--ui/widgets/datepicker.js2222
145 files changed, 9011 insertions, 8549 deletions
diff --git a/Gruntfile.js b/Gruntfile.js
index 40c35b17f..b7ace6cfd 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -163,7 +163,12 @@ grunt.initConfig({
findNestedDependencies: true,
skipModuleInsertion: true,
exclude: [ "jquery" ],
- include: expandFiles( [ "ui/**/*.js", "!ui/core.js", "!ui/i18n/*" ] ),
+ include: expandFiles( [
+ "ui/**/*.js",
+ "!ui/widgets/calendar.js",
+ "!ui/widgets/datepicker.js",
+ "!ui/i18n/*"
+ ] ),
out: "dist/jquery-ui.js",
wrap: {
start: createBanner( uiFiles ),
@@ -261,6 +266,16 @@ grunt.initConfig({
destPrefix: "external"
},
files: {
+ "cldrjs/cldr.js": "cldrjs/dist/cldr.js",
+ "cldrjs/cldr/event.js": "cldrjs/dist/cldr/event.js",
+ "cldrjs/cldr/supplemental.js": "cldrjs/dist/cldr/supplemental.js",
+ "cldrjs/LICENSE-MIT": "cldrjs/LICENSE-MIT",
+
+ "globalize/globalize-runtime.js": "globalize/dist/globalize-runtime.js",
+ "globalize/globalize-runtime/number.js": "globalize/dist/globalize-runtime/number.js",
+ "globalize/globalize-runtime/date.js": "globalize/dist/globalize-runtime/date.js",
+ "globalize/LICENSE.txt": "globalize/LICENSE.txt",
+
"qunit/qunit.js": "qunit/qunit/qunit.js",
"qunit/qunit.css": "qunit/qunit/qunit.css",
"qunit/LICENSE.txt": "qunit/LICENSE.txt",
@@ -422,6 +437,41 @@ grunt.registerTask( "update-authors", function() {
});
});
+grunt.registerTask( "compile-globalize", function() {
+ var formatters,
+ Globalize = require( "globalize" ),
+ globalizeCompiler = require( "globalize-compiler" ),
+ cldrData = require( "cldr-data" ),
+ languages = [ "ar", "en", "de", "es", "zh" ];
+
+ Globalize.load( cldrData.entireMainFor.apply( this, languages ) );
+ Globalize.load( cldrData.entireSupplemental() );
+
+ formatters = languages.reduce( function( ret, language ) {
+ var globalize = new Globalize( language );
+
+ ret = ret.concat([
+ globalize.dateFormatter( { raw: "EEEEEE" } ),
+ globalize.dateFormatter( { raw: "EEEEE" } ),
+ globalize.dateFormatter( { raw: "EEEE" } ),
+ globalize.dateFormatter( { raw: "MMMM" } ),
+ globalize.dateFormatter( { raw: "w" } ),
+ globalize.dateFormatter( { raw: "c" } ),
+ globalize.dateFormatter( { date: "short" } ),
+ globalize.dateParser( { date: "short" } ),
+ globalize.dateFormatter( { date: "long" } ),
+ globalize.dateParser( { date: "long" } ),
+ globalize.dateFormatter( { date: "full" } ),
+ globalize.dateParser( { date: "full" } ),
+ globalize.numberParser()
+ ]);
+
+ return ret;
+ }, [] );
+
+ grunt.file.write( "external/localization.js", globalizeCompiler.compile( formatters ) );
+});
+
grunt.registerTask( "default", [ "lint", "requirejs", "test" ]);
grunt.registerTask( "jenkins", [ "default", "concat" ]);
grunt.registerTask( "lint", [ "asciilint", "jshint", "jscs", "csslint", "htmllint" ]);
diff --git a/bower.json b/bower.json
index 2c8b5a6ba..f7b44bb37 100644
--- a/bower.json
+++ b/bower.json
@@ -19,6 +19,7 @@
"qunit-assert-close": "JamesMGreene/qunit-assert-close#v1.1.1",
"qunit-composite": "JamesMGreene/qunit-composite#v1.1.0",
"requirejs": "2.1.14",
+ "globalize": "globalize#1.1.0-rc.6",
"jquery-1.7.0": "jquery#1.7.0",
"jquery-1.7.1": "jquery#1.7.1",
diff --git a/build/tasks/testswarm.js b/build/tasks/testswarm.js
index 60f2800c5..1ef2f0e92 100644
--- a/build/tasks/testswarm.js
+++ b/build/tasks/testswarm.js
@@ -14,6 +14,7 @@ var versions = {
"Accordion": "accordion/accordion.html",
"Autocomplete": "autocomplete/autocomplete.html",
"Button": "button/button.html",
+ "Calendar": "calendar/calendar.html",
"Core": "core/core.html",
"Datepicker": "datepicker/datepicker.html",
"Dialog": "dialog/dialog.html",
diff --git a/demos/bootstrap.js b/demos/bootstrap.js
index 9a82071c7..0a109ef9e 100644
--- a/demos/bootstrap.js
+++ b/demos/bootstrap.js
@@ -30,6 +30,7 @@ var widgets = [
"accordion",
"autocomplete",
"button",
+ "calendar",
"checkboxradio",
"controlgroup",
"datepicker",
@@ -80,12 +81,20 @@ document.documentElement.className = "demo-loading";
require.config( {
baseUrl: window.location.pathname.indexOf( "demos/" ) !== -1 ? "../../ui" : "../../../ui",
paths: {
+ cldr: "../external/cldrjs/cldr",
+ "globalize-runtime": "../external/globalize/globalize-runtime",
+ "globalize-locales": "../external/localization",
jquery: "../external/jquery/jquery",
external: "../external/"
},
+ map: {
+ "*": {
+ "globalize": "globalize-runtime"
+ }
+ },
shim: {
- "external/globalize/globalize.culture.de-DE": [ "external/globalize/globalize" ],
- "external/globalize/globalize.culture.ja-JP": [ "external/globalize/globalize" ]
+ "external/globalize-old/globalize.culture.de-DE": [ "external/globalize-old/globalize" ],
+ "external/globalize-old/globalize.culture.ja-JP": [ "external/globalize-old/globalize" ]
}
} );
diff --git a/demos/calendar/buttonbar.html b/demos/calendar/buttonbar.html
new file mode 100644
index 000000000..28ee693cc
--- /dev/null
+++ b/demos/calendar/buttonbar.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>jQuery UI Calendar - Display button bar</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js">
+ $( "#calendar" ).calendar({
+ buttons: {
+ Today: function() {
+ $( this ).calendar( "valueAsDate", new Date() );
+ }
+ }
+ });
+ </script>
+</head>
+<body>
+
+<div id="calendar"></div>
+
+<div class="demo-description">
+<p>Display a button for selecting Today's date with the <code>buttons</code> option.</p>
+</div>
+</body>
+</html>
diff --git a/demos/datepicker/inline.html b/demos/calendar/default.html
index 9e8026726..1a2cfdf77 100644
--- a/demos/datepicker/inline.html
+++ b/demos/calendar/default.html
@@ -3,20 +3,20 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery UI Datepicker - Display inline</title>
+ <title>jQuery UI Calendar - Default functionality</title>
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
<script src="../bootstrap.js">
- $( "#datepicker" ).datepicker();
+ $( "#calendar" ).calendar();
</script>
</head>
<body>
-Date: <div id="datepicker"></div>
+<div id="calendar"></div>
<div class="demo-description">
-<p>Display the datepicker embedded in the page instead of in an overlay. Simply call .datepicker() on a div instead of an input.</p>
+<p>The calendar is a widget for selecting a date using a visual calendar representation.</p>
</div>
</body>
</html>
diff --git a/demos/datepicker/dropdown-month-year.html b/demos/calendar/dropdown-month-year.html
index ab3da5d0a..92b7e24fb 100644
--- a/demos/datepicker/dropdown-month-year.html
+++ b/demos/calendar/dropdown-month-year.html
@@ -3,12 +3,12 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery UI Datepicker - Display month &amp; year menus</title>
+ <title>jQuery UI Calendar - Display month &amp; year menus</title>
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
<script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
+ $( "#calendar" ).calendar({
changeMonth: true,
changeYear: true
});
@@ -16,7 +16,7 @@
</head>
<body>
-<p>Date: <input type="text" id="datepicker"></p>
+<div id="calendar"></div>
<div class="demo-description">
<p>Show month and year dropdowns in place of the static month/year header to facilitate navigation through large timeframes. Add the boolean <code>changeMonth</code> and <code>changeYear</code> options.</p>
diff --git a/demos/calendar/index.html b/demos/calendar/index.html
new file mode 100644
index 000000000..751301a00
--- /dev/null
+++ b/demos/calendar/index.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>jQuery UI Calendar Demos</title>
+</head>
+<body>
+
+<ul>
+ <li><a href="default.html">Default functionality</a></li>
+ <li><a href="buttonbar.html">Display button bar</a></li>
+ <li><a href="dropdown-month-year.html">Display month &amp; year menus</a></li>
+ <li><a href="localization.html">Localize calendar</a></li>
+ <li><a href="min-max.html">Restrict date range</a></li>
+ <li><a href="multiple-months.html">Display multiple months</a></li>
+ <li><a href="other-months.html">Dates in other months</a></li>
+ <li><a href="show-week.html">Show week of the year</a></li>
+</ul>
+
+</body>
+</html>
diff --git a/demos/calendar/localization.html b/demos/calendar/localization.html
new file mode 100644
index 000000000..2c2cc2310
--- /dev/null
+++ b/demos/calendar/localization.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>jQuery UI Calendar - Localize calendar</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js">
+ var calendar = $( "#calendar" ),
+ select = $( "#locale" );
+
+ calendar.calendar({
+ locale: select.val()
+ });
+
+ select.change( function() {
+ calendar.calendar( "option", {
+ locale: select.val()
+ });
+ calendar.calendar( "valueAsDate", calendar.calendar( "valueAsDate" ) );
+ });
+ </script>
+</head>
+<body>
+
+<div id="calendar"></div>
+<select id="locale">
+ <option value="ar">Arabic</option>
+ <option value="de" selected>German</option>
+ <option value="en">English</option>
+ <option value="es">Spanish</option>
+ <option value="zh">Chinese Simplified</option>
+</select>
+
+<div class="demo-description">
+<p>Localize the calendar language and format (English / Western formatting is the default). The calendar includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.</p>
+</div>
+</body>
+</html>
diff --git a/demos/calendar/min-max.html b/demos/calendar/min-max.html
new file mode 100644
index 000000000..b3036b873
--- /dev/null
+++ b/demos/calendar/min-max.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Calendar - Restrict date range</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js">
+ var now = new Date(),
+ dateMin = new Date( now.getFullYear(), now.getMonth(), now.getDate() + 1 ),
+ dateMax = new Date( now.getFullYear(), now.getMonth(), now.getDate() + 8 );
+
+ dateMin = new Date( 2008, 2 - 1, 29 );
+ dateMax = new Date( 2008, 12 - 1, 7 );
+
+
+ $( "#calendar" ).calendar({
+ min: dateMin,
+ max: dateMax,
+ value: new Date( 2008, 1 - 1, 4 )
+ });
+ </script>
+</head>
+<body>
+
+<div id="calendar"></div>
+
+<div class="demo-description">
+<p>Restrict the range of selectable dates with the <code>min</code> and <code>max</code> options. Set the beginning and end dates as actual dates (<code>new Date(2009, 1 - 1, 26)</code>).</p>
+</div>
+</body>
+</html>
diff --git a/demos/datepicker/multiple-calendars.html b/demos/calendar/multiple-months.html
index 033b648a2..f83da1f82 100644
--- a/demos/datepicker/multiple-calendars.html
+++ b/demos/calendar/multiple-months.html
@@ -3,23 +3,22 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery UI Datepicker - Display multiple months</title>
+ <title>jQuery UI Calendar - Display multiple months</title>
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
<script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
- numberOfMonths: 3,
- showButtonPanel: true
+ $( "#calendar" ).calendar({
+ numberOfMonths: 3
});
</script>
</head>
<body>
-<p>Date: <input type="text" id="datepicker"></p>
+<div id="calendar"></div>
<div class="demo-description">
-<p>Set the <code>numberOfMonths</code> option to an integer of 2 or more to show multiple months in a single datepicker.</p>
+<p>Set the <code>numberOfMonths</code> option to an integer of 2 or more to show multiple months in a single calendar.</p>
</div>
</body>
</html>
diff --git a/demos/datepicker/other-months.html b/demos/calendar/other-months.html
index ff8600644..2fb4dacf8 100644
--- a/demos/datepicker/other-months.html
+++ b/demos/calendar/other-months.html
@@ -3,23 +3,28 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery UI Datepicker - Dates in other months</title>
+ <title>jQuery UI Calendar - Dates in other months</title>
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
<script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
- showOtherMonths: true,
- selectOtherMonths: true
+ $( "#calendar" ).calendar({
+ eachDay: function( day ) {
+ if ( day.lead ) {
+ day.render = true;
+ day.selectable = true;
+ day.extraClasses = "ui-priority-secondary";
+ }
+ }
});
</script>
</head>
<body>
-<p>Date: <input type="text" id="datepicker"></p>
+<div id="calendar"></div>
<div class="demo-description">
-<p>The datepicker can show dates that come from other than the main month
+<p>The calendar can show dates that come from other than the main month
being displayed. These other dates can also be made selectable.</p>
</div>
</body>
diff --git a/demos/calendar/show-week.html b/demos/calendar/show-week.html
new file mode 100644
index 000000000..e148b6570
--- /dev/null
+++ b/demos/calendar/show-week.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>jQuery UI Calendar - Show week of the year</title>
+ <link rel="stylesheet" href="../../themes/base/all.css">
+ <link rel="stylesheet" href="../demos.css">
+ <script src="../../external/requirejs/require.js"></script>
+ <script src="../bootstrap.js">
+ $( "#calendar" ).calendar({
+ showWeek: true
+ });
+ </script>
+</head>
+<body>
+
+<div id="calendar"></div>
+
+<div class="demo-description">
+<p>The calendar can show the week of the year. The calculation follows
+ <a href="http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table">Unicode CLDR specification</a>.
+ This means that some days from one year may be placed into weeks 'belonging' to another year.</p>
+</div>
+</body>
+</html>
diff --git a/demos/datepicker/alt-field.html b/demos/datepicker/alt-field.html
deleted file mode 100644
index 779325719..000000000
--- a/demos/datepicker/alt-field.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery UI Datepicker - Populate alternate field</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <link rel="stylesheet" href="../demos.css">
- <script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
- altField: "#alternate",
- altFormat: "DD, d MM, yy"
- });
- </script>
-</head>
-<body>
-
-<p>Date: <input type="text" id="datepicker">&nbsp;<input type="text" id="alternate" size="30"/></p>
-
-<div class="demo-description">
-<p>Populate an alternate field with its own date format whenever a date is selected using the <code>altField</code> and <code>altFormat</code> options. This feature could be used to present a human-friendly date for user selection, while passing a more computer-friendly date through for further processing.</p>
-</div>
-</body>
-</html>
diff --git a/demos/datepicker/animation.html b/demos/datepicker/animation.html
index 7daf4bc6c..d493fad53 100644
--- a/demos/datepicker/animation.html
+++ b/demos/datepicker/animation.html
@@ -10,7 +10,11 @@
<script src="../bootstrap.js" data-modules="effect effect-bounce effect-blind effect-bounce effect-clip effect-drop effect-fold effect-slide">
$( "#datepicker" ).datepicker();
$( "#anim" ).on( "change", function() {
- $( "#datepicker" ).datepicker( "option", "showAnim", $( this ).val() );
+ var value = $( this ).val(),
+ hideValue = $( this ).find( "option:selected" ).data( "hide" );
+ $( "#datepicker" )
+ .datepicker( "option", "show", value )
+ .datepicker( "option", "hide", hideValue || value );
});
</script>
</head>
@@ -20,16 +24,15 @@
<p>Animations:<br />
<select id="anim">
- <option value="show">Show (default)</option>
- <option value="slideDown">Slide down</option>
- <option value="fadeIn">Fade in</option>
+ <option value="show">Fade in/out (default)</option>
+ <option value="slideDown" data-hide="slideUp">Slide down/up</option>
<option value="blind">Blind (UI Effect)</option>
<option value="bounce">Bounce (UI Effect)</option>
<option value="clip">Clip (UI Effect)</option>
<option value="drop">Drop (UI Effect)</option>
<option value="fold">Fold (UI Effect)</option>
<option value="slide">Slide (UI Effect)</option>
- <option value="">None</option>
+ <option value="false">None</option>
</select>
</p>
diff --git a/demos/datepicker/buttonbar.html b/demos/datepicker/buttonbar.html
deleted file mode 100644
index 5b48179b4..000000000
--- a/demos/datepicker/buttonbar.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery UI Datepicker - Display button bar</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <link rel="stylesheet" href="../demos.css">
- <script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
- showButtonPanel: true
- });
- </script>
-</head>
-<body>
-
-<p>Date: <input type="text" id="datepicker"></p>
-
-<div class="demo-description">
-<p>Display a button for selecting Today's date and a Done button for closing the calendar with the boolean <code>showButtonPanel</code> option. Each button is enabled by default when the bar is displayed, but can be turned off with additional options. Button text is customizable.</p>
-</div>
-</body>
-</html>
diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html
index 5e738b4ab..a234e223b 100644
--- a/demos/datepicker/date-formats.html
+++ b/demos/datepicker/date-formats.html
@@ -8,9 +8,17 @@
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
<script src="../bootstrap.js">
- $( "#datepicker" ).datepicker();
+ var value,
+ datepicker = $( "#datepicker" ).datepicker();
+
$( "#format" ).on( "change", function() {
- $( "#datepicker" ).datepicker( "option", "dateFormat", $( this ).val() );
+ value = $( this ).val();
+
+ if ( value === "iso" ) {
+ datepicker.datepicker( "option", "dateFormat", { raw: "yyyy-MM-dd" } );
+ } else {
+ datepicker.datepicker( "option", "dateFormat", { date: value } );
+ }
});
</script>
</head>
@@ -20,12 +28,9 @@
<p>Format options:<br />
<select id="format">
- <option value="mm/dd/yy">Default - mm/dd/yy</option>
- <option value="yy-mm-dd">ISO 8601 - yy-mm-dd</option>
- <option value="d M, y">Short - d M, y</option>
- <option value="d MM, y">Medium - d MM, y</option>
- <option value="DD, d MM, yy">Full - DD, d MM, yy</option>
- <option value="'day' d 'of' MM 'in the year' yy">With text - 'day' d 'of' MM 'in the year' yy</option>
+ <option value="short">Short - M/d/yy in "en" locale</option>
+ <option value="long">Long - MMMM d, y in "en" locale</option>
+ <option value="iso">ISO 8601 - yyyy-MM-dd</option>
</select>
</p>
diff --git a/demos/datepicker/date-range.html b/demos/datepicker/date-range.html
deleted file mode 100644
index 17581e1eb..000000000
--- a/demos/datepicker/date-range.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery UI Datepicker - Select a Date Range</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <link rel="stylesheet" href="../demos.css">
- <script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js">
- var dateFormat = "mm/dd/yy",
- from = $( "#from" )
- .datepicker({
- defaultDate: "+1w",
- changeMonth: true,
- numberOfMonths: 3
- })
- .on( "change", function() {
- to.datepicker( "option", "minDate", getDate( this ) );
- }),
- to = $( "#to" ).datepicker({
- defaultDate: "+1w",
- changeMonth: true,
- numberOfMonths: 3
- })
- .on( "change", function() {
- from.datepicker( "option", "maxDate", getDate( this ) );
- });
-
- function getDate( element ) {
- var date;
- try {
- date = $.datepicker.parseDate( dateFormat, element.value );
- } catch( error ) {
- date = null;
- }
-
- return date;
- }
- </script>
-</head>
-<body>
-
-<label for="from">From</label>
-<input type="text" id="from" name="from"/>
-<label for="to">to</label>
-<input type="text" id="to" name="to"/>
-
-<div class="demo-description">
-<p>Select the date range to search for.</p>
-</div>
-</body>
-</html>
diff --git a/demos/datepicker/icon-trigger.html b/demos/datepicker/icon-trigger.html
index 71d0621d4..ef3362a11 100644
--- a/demos/datepicker/icon-trigger.html
+++ b/demos/datepicker/icon-trigger.html
@@ -8,12 +8,26 @@
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
<script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
- showOn: "button",
- buttonImage: "images/calendar.gif",
- buttonImageOnly: true,
- buttonText: "Select date"
- });
+ var allowOpen = false,
+ datepicker = $( "#datepicker" ).datepicker({
+ beforeOpen: function() {
+ return allowOpen;
+ },
+ open: function() {
+ allowOpen = false;
+ }
+ } ),
+ widget = datepicker.datepicker( "widget" );
+
+ $( "<button>" )
+ .append( "<img src='images/calendar.gif' alt='Open Datepicker'>" )
+ .insertAfter( datepicker )
+ .on( "click", function() {
+ allowOpen = true;
+ if ( widget.is( ":hidden" ) ) {
+ datepicker.focus();
+ }
+ });
</script>
</head>
<body>
@@ -21,7 +35,7 @@
<p>Date: <input type="text" id="datepicker"></p>
<div class="demo-description">
-<p>Click the icon next to the input field to show the datepicker. Set the datepicker to open on focus (default behavior), on icon click, or both.</p>
+<p>Click the icon next to the input field to show the datepicker. This demo will be removed soon since its promoting bad practice. Please see our migration guide.</p>
</div>
</body>
</html>
diff --git a/demos/datepicker/index.html b/demos/datepicker/index.html
index d9c8dfc10..a56df7bd6 100644
--- a/demos/datepicker/index.html
+++ b/demos/datepicker/index.html
@@ -9,19 +9,10 @@
<ul>
<li><a href="default.html">Default functionality</a></li>
+ <li><a href="animation.html">Animations</a></li>
<li><a href="date-formats.html">Format date</a></li>
- <li><a href="min-max.html">Restrict date range</a></li>
- <li><a href="localization.html">Localize calendar</a></li>
- <li><a href="alt-field.html">Populate alternate field</a></li>
- <li><a href="inline.html">Display inline</a></li>
- <li><a href="buttonbar.html">Display button bar</a></li>
- <li><a href="dropdown-month-year.html">Display month &amp; year menus</a></li>
- <li><a href="other-months.html">Dates in other months</a></li>
- <li><a href="show-week.html">Show week of the year</a></li>
- <li><a href="multiple-calendars.html">Display multiple months</a></li>
<li><a href="icon-trigger.html">Icon trigger</a></li>
- <li><a href="animation.html">Animations</a></li>
- <li><a href="date-range.html">Date Range</a></li>
+ <li><a href="localization.html">Localize calendar</a></li>
</ul>
</body>
diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html
index 69835931a..9537567f7 100644
--- a/demos/datepicker/localization.html
+++ b/demos/datepicker/localization.html
@@ -7,11 +7,19 @@
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js" data-modules="i18n/datepicker-ar i18n/datepicker-fr i18n/datepicker-he i18n/datepicker-zh-TW">
- $( "#datepicker" ).datepicker( $.datepicker.regional[ "fr" ] );
- $( "#locale" ).on( "change", function() {
- $( "#datepicker" ).datepicker( "option",
- $.datepicker.regional[ $( this ).val() ] );
+ <script src="../bootstrap.js" data-modules="external/localization">
+ var datepicker = $( "#datepicker" ),
+ select = $( "#locale" );
+
+ datepicker.datepicker({
+ locale: select.val()
+ });
+
+ select.on( "change", function() {
+ datepicker.datepicker( "option", {
+ locale: select.val()
+ });
+ datepicker.datepicker( "valueAsDate", datepicker.datepicker( "valueAsDate" ) );
});
</script>
</head>
@@ -19,15 +27,15 @@
<p>Date: <input type="text" id="datepicker"/>&nbsp;
<select id="locale">
- <option value="ar">Arabic (&#8235;(&#1575;&#1604;&#1593;&#1585;&#1576;&#1610;&#1577;</option>
- <option value="zh-TW">Chinese Traditional (&#32321;&#39636;&#20013;&#25991;)</option>
- <option value="">English</option>
- <option value="fr" selected="selected">French (Fran&ccedil;ais)</option>
- <option value="he">Hebrew (&#8235;(&#1506;&#1489;&#1512;&#1497;&#1514;</option>
+ <option value="ar">Arabic</option>
+ <option value="de" selected>German</option>
+ <option value="en">English</option>
+ <option value="es">Spanish</option>
+ <option value="zh">Chinese Simplified</option>
</select></p>
<div class="demo-description">
-<p>Localize the datepicker calendar language and format (English / Western formatting is the default). The datepicker includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.</p>
+<p>Localize the datepicker calendar language and format (English / Western formatting is the default). The datepicker includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.</p>
</div>
</body>
</html>
diff --git a/demos/datepicker/min-max.html b/demos/datepicker/min-max.html
deleted file mode 100644
index 13b1b569e..000000000
--- a/demos/datepicker/min-max.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery UI Datepicker - Restrict date range</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <link rel="stylesheet" href="../demos.css">
- <script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({ minDate: -20, maxDate: "+1M +10D" });
- </script>
-</head>
-<body>
-
-<p>Date: <input type="text" id="datepicker"></p>
-
-<div class="demo-description">
-<p>Restrict the range of selectable dates with the <code>minDate</code> and <code>maxDate</code> options. Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)), as a numeric offset from today (-20), or as a string of periods and units ('+1M +10D'). For the last, use 'D' for days, 'W' for weeks, 'M' for months, or 'Y' for years.</p>
-</div>
-</body>
-</html>
diff --git a/demos/datepicker/show-week.html b/demos/datepicker/show-week.html
deleted file mode 100644
index 022d0271c..000000000
--- a/demos/datepicker/show-week.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery UI Datepicker - Show week of the year</title>
- <link rel="stylesheet" href="../../themes/base/all.css">
- <link rel="stylesheet" href="../demos.css">
- <script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js">
- $( "#datepicker" ).datepicker({
- showWeek: true,
- firstDay: 1
- });
- </script>
-</head>
-<body>
-
-<p>Date: <input type="text" id="datepicker"></p>
-
-<div class="demo-description">
-<p>The datepicker can show the week of the year. The default calculation follows
- the ISO 8601 definition: the week starts on Monday, the first week of the year
- contains the first Thursday of the year. This means that some days from one
- year may be placed into weeks 'belonging' to another year.</p>
-</div>
-</body>
-</html>
diff --git a/demos/index.html b/demos/index.html
index 89375dde7..b9d2f4e79 100644
--- a/demos/index.html
+++ b/demos/index.html
@@ -11,6 +11,7 @@
<li><a href="accordion/">accordion</a></li>
<li><a href="autocomplete/">autocomplete</a></li>
<li><a href="button/">button</a></li>
+ <li><a href="calendar/">calendar</a></li>
<li><a href="checkboxradio/">checkboxradio</a></li>
<li><a href="controlgroup/">controlgroup</a></li>
<li><a href="datepicker/">datepicker</a></li>
diff --git a/demos/spinner/currency.html b/demos/spinner/currency.html
index 4180b12e1..ad25359df 100644
--- a/demos/spinner/currency.html
+++ b/demos/spinner/currency.html
@@ -7,7 +7,12 @@
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js" data-modules="external/globalize/globalize external/globalize/globalize.culture.de-DE external/globalize/globalize.culture.ja-JP external/jquery-mousewheel/jquery.mousewheel">
+ <script src="../bootstrap.js" data-modules="
+ external/globalize-old/globalize
+ external/globalize-old/globalize.culture.de-DE
+ external/globalize-old/globalize.culture.ja-JP
+ external/jquery-mousewheel/jquery.mousewheel
+ ">
$( "#currency" ).on( "change", function() {
$( "#spinner" ).spinner( "option", "culture", $( this ).val() );
});
diff --git a/demos/spinner/decimal.html b/demos/spinner/decimal.html
index 0b39f2bac..68a806a9c 100644
--- a/demos/spinner/decimal.html
+++ b/demos/spinner/decimal.html
@@ -7,7 +7,12 @@
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js" data-modules="external/globalize/globalize external/globalize/globalize.culture.de-DE external/globalize/globalize.culture.ja-JP external/jquery-mousewheel/jquery.mousewheel">
+ <script src="../bootstrap.js" data-modules="
+ external/globalize-old/globalize
+ external/globalize-old/globalize.culture.de-DE
+ external/globalize-old/globalize.culture.ja-JP
+ external/jquery-mousewheel/jquery.mousewheel
+ ">
$( "#spinner" ).spinner({
step: 0.01,
numberFormat: "n"
diff --git a/demos/spinner/time.html b/demos/spinner/time.html
index 5836784d1..6941cd646 100644
--- a/demos/spinner/time.html
+++ b/demos/spinner/time.html
@@ -7,7 +7,11 @@
<link rel="stylesheet" href="../../themes/base/all.css">
<link rel="stylesheet" href="../demos.css">
<script src="../../external/requirejs/require.js"></script>
- <script src="../bootstrap.js" data-modules="external/globalize/globalize external/globalize/globalize.culture.de-DE external/jquery-mousewheel/jquery.mousewheel">
+ <script src="../bootstrap.js" data-modules="
+ external/globalize-old/globalize
+ external/globalize-old/globalize.culture.de-DE
+ external/jquery-mousewheel/jquery.mousewheel
+ ">
$.widget( "ui.timespinner", $.ui.spinner, {
options: {
// seconds
diff --git a/external/cldrjs/LICENSE-MIT/LICENSE-MIT b/external/cldrjs/LICENSE-MIT/LICENSE-MIT
new file mode 100644
index 000000000..6123defa8
--- /dev/null
+++ b/external/cldrjs/LICENSE-MIT/LICENSE-MIT
@@ -0,0 +1,22 @@
+Copyright (c) Rafael Xavier de Souza http://rafael.xavier.blog.br
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/external/cldrjs/cldr.js b/external/cldrjs/cldr.js
new file mode 100644
index 000000000..23b6c96fe
--- /dev/null
+++ b/external/cldrjs/cldr.js
@@ -0,0 +1,662 @@
+/**
+ * CLDR JavaScript Library v0.4.3
+ * http://jquery.com/
+ *
+ * Copyright 2013 Rafael Xavier de Souza
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-08-24T01:00Z
+ */
+/*!
+ * CLDR JavaScript Library v0.4.3 2015-08-24T01:00Z MIT license © Rafael Xavier
+ * http://git.io/h4lmVg
+ */
+(function( root, factory ) {
+
+ if ( typeof define === "function" && define.amd ) {
+ // AMD.
+ define( factory );
+ } else if ( typeof module === "object" && typeof module.exports === "object" ) {
+ // Node. CommonJS.
+ module.exports = factory();
+ } else {
+ // Global
+ root.Cldr = factory();
+ }
+
+}( this, function() {
+
+
+ var arrayIsArray = Array.isArray || function( obj ) {
+ return Object.prototype.toString.call( obj ) === "[object Array]";
+ };
+
+
+
+
+ var pathNormalize = function( path, attributes ) {
+ if ( arrayIsArray( path ) ) {
+ path = path.join( "/" );
+ }
+ if ( typeof path !== "string" ) {
+ throw new Error( "invalid path \"" + path + "\"" );
+ }
+ // 1: Ignore leading slash `/`
+ // 2: Ignore leading `cldr/`
+ path = path
+ .replace( /^\// , "" ) /* 1 */
+ .replace( /^cldr\// , "" ); /* 2 */
+
+ // Replace {attribute}'s
+ path = path.replace( /{[a-zA-Z]+}/g, function( name ) {
+ name = name.replace( /^{([^}]*)}$/, "$1" );
+ return attributes[ name ];
+ });
+
+ return path.split( "/" );
+ };
+
+
+
+
+ var arraySome = function( array, callback ) {
+ var i, length;
+ if ( array.some ) {
+ return array.some( callback );
+ }
+ for ( i = 0, length = array.length; i < length; i++ ) {
+ if ( callback( array[ i ], i, array ) ) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+
+
+
+ /**
+ * Return the maximized language id as defined in
+ * http://www.unicode.org/reports/tr35/#Likely_Subtags
+ * 1. Canonicalize.
+ * 1.1 Make sure the input locale is in canonical form: uses the right
+ * separator, and has the right casing.
+ * TODO Right casing? What df? It seems languages are lowercase, scripts are
+ * Capitalized, territory is uppercase. I am leaving this as an exercise to
+ * the user.
+ *
+ * 1.2 Replace any deprecated subtags with their canonical values using the
+ * <alias> data in supplemental metadata. Use the first value in the
+ * replacement list, if it exists. Language tag replacements may have multiple
+ * parts, such as "sh" ➞ "sr_Latn" or mo" ➞ "ro_MD". In such a case, the
+ * original script and/or region are retained if there is one. Thus
+ * "sh_Arab_AQ" ➞ "sr_Arab_AQ", not "sr_Latn_AQ".
+ * TODO What <alias> data?
+ *
+ * 1.3 If the tag is grandfathered (see <variable id="$grandfathered"
+ * type="choice"> in the supplemental data), then return it.
+ * TODO grandfathered?
+ *
+ * 1.4 Remove the script code 'Zzzz' and the region code 'ZZ' if they occur.
+ * 1.5 Get the components of the cleaned-up source tag (languages, scripts,
+ * and regions), plus any variants and extensions.
+ * 2. Lookup. Lookup each of the following in order, and stop on the first
+ * match:
+ * 2.1 languages_scripts_regions
+ * 2.2 languages_regions
+ * 2.3 languages_scripts
+ * 2.4 languages
+ * 2.5 und_scripts
+ * 3. Return
+ * 3.1 If there is no match, either return an error value, or the match for
+ * "und" (in APIs where a valid language tag is required).
+ * 3.2 Otherwise there is a match = languagem_scriptm_regionm
+ * 3.3 Let xr = xs if xs is not empty, and xm otherwise.
+ * 3.4 Return the language tag composed of languager _ scriptr _ regionr +
+ * variants + extensions.
+ *
+ * @subtags [Array] normalized language id subtags tuple (see init.js).
+ */
+ var coreLikelySubtags = function( Cldr, cldr, subtags, options ) {
+ var match, matchFound,
+ language = subtags[ 0 ],
+ script = subtags[ 1 ],
+ sep = Cldr.localeSep,
+ territory = subtags[ 2 ];
+ options = options || {};
+
+ // Skip if (language, script, territory) is not empty [3.3]
+ if ( language !== "und" && script !== "Zzzz" && territory !== "ZZ" ) {
+ return [ language, script, territory ];
+ }
+
+ // Skip if no supplemental likelySubtags data is present
+ if ( typeof cldr.get( "supplemental/likelySubtags" ) === "undefined" ) {
+ return;
+ }
+
+ // [2]
+ matchFound = arraySome([
+ [ language, script, territory ],
+ [ language, territory ],
+ [ language, script ],
+ [ language ],
+ [ "und", script ]
+ ], function( test ) {
+ return match = !(/\b(Zzzz|ZZ)\b/).test( test.join( sep ) ) /* [1.4] */ && cldr.get( [ "supplemental/likelySubtags", test.join( sep ) ] );
+ });
+
+ // [3]
+ if ( matchFound ) {
+ // [3.2 .. 3.4]
+ match = match.split( sep );
+ return [
+ language !== "und" ? language : match[ 0 ],
+ script !== "Zzzz" ? script : match[ 1 ],
+ territory !== "ZZ" ? territory : match[ 2 ]
+ ];
+ } else if ( options.force ) {
+ // [3.1.2]
+ return cldr.get( "supplemental/likelySubtags/und" ).split( sep );
+ } else {
+ // [3.1.1]
+ return;
+ }
+ };
+
+
+
+ /**
+ * Given a locale, remove any fields that Add Likely Subtags would add.
+ * http://www.unicode.org/reports/tr35/#Likely_Subtags
+ * 1. First get max = AddLikelySubtags(inputLocale). If an error is signaled,
+ * return it.
+ * 2. Remove the variants from max.
+ * 3. Then for trial in {language, language _ region, language _ script}. If
+ * AddLikelySubtags(trial) = max, then return trial + variants.
+ * 4. If you do not get a match, return max + variants.
+ *
+ * @maxLanguageId [Array] maxLanguageId tuple (see init.js).
+ */
+ var coreRemoveLikelySubtags = function( Cldr, cldr, maxLanguageId ) {
+ var match, matchFound,
+ language = maxLanguageId[ 0 ],
+ script = maxLanguageId[ 1 ],
+ territory = maxLanguageId[ 2 ];
+
+ // [3]
+ matchFound = arraySome([
+ [ [ language, "Zzzz", "ZZ" ], [ language ] ],
+ [ [ language, "Zzzz", territory ], [ language, territory ] ],
+ [ [ language, script, "ZZ" ], [ language, script ] ]
+ ], function( test ) {
+ var result = coreLikelySubtags( Cldr, cldr, test[ 0 ] );
+ match = test[ 1 ];
+ return result && result[ 0 ] === maxLanguageId[ 0 ] &&
+ result[ 1 ] === maxLanguageId[ 1 ] &&
+ result[ 2 ] === maxLanguageId[ 2 ];
+ });
+
+ // [4]
+ return matchFound ? match : maxLanguageId;
+ };
+
+
+
+
+ /**
+ * subtags( locale )
+ *
+ * @locale [String]
+ */
+ var coreSubtags = function( locale ) {
+ var aux, unicodeLanguageId,
+ subtags = [];
+
+ locale = locale.replace( /_/, "-" );
+
+ // Unicode locale extensions.
+ aux = locale.split( "-u-" );
+ if ( aux[ 1 ] ) {
+ aux[ 1 ] = aux[ 1 ].split( "-t-" );
+ locale = aux[ 0 ] + ( aux[ 1 ][ 1 ] ? "-t-" + aux[ 1 ][ 1 ] : "");
+ subtags[ 4 /* unicodeLocaleExtensions */ ] = aux[ 1 ][ 0 ];
+ }
+
+ // TODO normalize transformed extensions. Currently, skipped.
+ // subtags[ x ] = locale.split( "-t-" )[ 1 ];
+ unicodeLanguageId = locale.split( "-t-" )[ 0 ];
+
+ // unicode_language_id = "root"
+ // | unicode_language_subtag
+ // (sep unicode_script_subtag)?
+ // (sep unicode_region_subtag)?
+ // (sep unicode_variant_subtag)* ;
+ //
+ // Although unicode_language_subtag = alpha{2,8}, I'm using alpha{2,3}. Because, there's no language on CLDR lengthier than 3.
+ aux = unicodeLanguageId.match( /^(([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?)(-[a-zA-Z0-9]{5,8}|[0-9][a-zA-Z0-9]{3})*$|^(root)$/ );
+ if ( aux === null ) {
+ return [ "und", "Zzzz", "ZZ" ];
+ }
+ subtags[ 0 /* language */ ] = aux[ 9 ] /* root */ || aux[ 2 ] || "und";
+ subtags[ 1 /* script */ ] = aux[ 4 ] || "Zzzz";
+ subtags[ 2 /* territory */ ] = aux[ 6 ] || "ZZ";
+ subtags[ 3 /* variant */ ] = aux[ 7 ];
+
+ // 0: language
+ // 1: script
+ // 2: territory (aka region)
+ // 3: variant
+ // 4: unicodeLocaleExtensions
+ return subtags;
+ };
+
+
+
+
+ var arrayForEach = function( array, callback ) {
+ var i, length;
+ if ( array.forEach ) {
+ return array.forEach( callback );
+ }
+ for ( i = 0, length = array.length; i < length; i++ ) {
+ callback( array[ i ], i, array );
+ }
+ };
+
+
+
+
+ /**
+ * bundleLookup( minLanguageId )
+ *
+ * @Cldr [Cldr class]
+ *
+ * @cldr [Cldr instance]
+ *
+ * @minLanguageId [String] requested languageId after applied remove likely subtags.
+ */
+ var bundleLookup = function( Cldr, cldr, minLanguageId ) {
+ var availableBundleMap = Cldr._availableBundleMap,
+ availableBundleMapQueue = Cldr._availableBundleMapQueue;
+
+ if ( availableBundleMapQueue.length ) {
+ arrayForEach( availableBundleMapQueue, function( bundle ) {
+ var existing, maxBundle, minBundle, subtags;
+ subtags = coreSubtags( bundle );
+ maxBundle = coreLikelySubtags( Cldr, cldr, subtags, { force: true } ) || subtags;
+ minBundle = coreRemoveLikelySubtags( Cldr, cldr, maxBundle );
+ minBundle = minBundle.join( Cldr.localeSep );
+ existing = availableBundleMapQueue[ minBundle ];
+ if ( existing && existing.length < bundle.length ) {
+ return;
+ }
+ availableBundleMap[ minBundle ] = bundle;
+ });
+ Cldr._availableBundleMapQueue = [];
+ }
+
+ return availableBundleMap[ minLanguageId ] || null;
+ };
+
+
+
+
+ var objectKeys = function( object ) {
+ var i,
+ result = [];
+
+ if ( Object.keys ) {
+ return Object.keys( object );
+ }
+
+ for ( i in object ) {
+ result.push( i );
+ }
+
+ return result;
+ };
+
+
+
+
+ var createError = function( code, attributes ) {
+ var error, message;
+
+ message = code + ( attributes && JSON ? ": " + JSON.stringify( attributes ) : "" );
+ error = new Error( message );
+ error.code = code;
+
+ // extend( error, attributes );
+ arrayForEach( objectKeys( attributes ), function( attribute ) {
+ error[ attribute ] = attributes[ attribute ];
+ });
+
+ return error;
+ };
+
+
+
+
+ var validate = function( code, check, attributes ) {
+ if ( !check ) {
+ throw createError( code, attributes );
+ }
+ };
+
+
+
+
+ var validatePresence = function( value, name ) {
+ validate( "E_MISSING_PARAMETER", typeof value !== "undefined", {
+ name: name
+ });
+ };
+
+
+
+
+ var validateType = function( value, name, check, expected ) {
+ validate( "E_INVALID_PAR_TYPE", check, {
+ expected: expected,
+ name: name,
+ value: value
+ });
+ };
+
+
+
+
+ var validateTypePath = function( value, name ) {
+ validateType( value, name, typeof value === "string" || arrayIsArray( value ), "String or Array" );
+ };
+
+
+
+
+ /**
+ * Function inspired by jQuery Core, but reduced to our use case.
+ */
+ var isPlainObject = function( obj ) {
+ return obj !== null && "" + obj === "[object Object]";
+ };
+
+
+
+
+ var validateTypePlainObject = function( value, name ) {
+ validateType( value, name, typeof value === "undefined" || isPlainObject( value ), "Plain Object" );
+ };
+
+
+
+
+ var validateTypeString = function( value, name ) {
+ validateType( value, name, typeof value === "string", "a string" );
+ };
+
+
+
+
+ // @path: normalized path
+ var resourceGet = function( data, path ) {
+ var i,
+ node = data,
+ length = path.length;
+
+ for ( i = 0; i < length - 1; i++ ) {
+ node = node[ path[ i ] ];
+ if ( !node ) {
+ return undefined;
+ }
+ }
+ return node[ path[ i ] ];
+ };
+
+
+
+
+ /**
+ * setAvailableBundles( Cldr, json )
+ *
+ * @Cldr [Cldr class]
+ *
+ * @json resolved/unresolved cldr data.
+ *
+ * Set available bundles queue based on passed json CLDR data. Considers a bundle as any String at /main/{bundle}.
+ */
+ var coreSetAvailableBundles = function( Cldr, json ) {
+ var bundle,
+ availableBundleMapQueue = Cldr._availableBundleMapQueue,
+ main = resourceGet( json, [ "main" ] );
+
+ if ( main ) {
+ for ( bundle in main ) {
+ if ( main.hasOwnProperty( bundle ) && bundle !== "root" ) {
+ availableBundleMapQueue.push( bundle );
+ }
+ }
+ }
+ };
+
+
+
+ var alwaysArray = function( somethingOrArray ) {
+ return arrayIsArray( somethingOrArray ) ? somethingOrArray : [ somethingOrArray ];
+ };
+
+
+ var jsonMerge = (function() {
+
+ // Returns new deeply merged JSON.
+ //
+ // Eg.
+ // merge( { a: { b: 1, c: 2 } }, { a: { b: 3, d: 4 } } )
+ // -> { a: { b: 3, c: 2, d: 4 } }
+ //
+ // @arguments JSON's
+ //
+ var merge = function() {
+ var destination = {},
+ sources = [].slice.call( arguments, 0 );
+ arrayForEach( sources, function( source ) {
+ var prop;
+ for ( prop in source ) {
+ if ( prop in destination && typeof destination[ prop ] === "object" && !arrayIsArray( destination[ prop ] ) ) {
+
+ // Merge Objects
+ destination[ prop ] = merge( destination[ prop ], source[ prop ] );
+
+ } else {
+
+ // Set new values
+ destination[ prop ] = source[ prop ];
+
+ }
+ }
+ });
+ return destination;
+ };
+
+ return merge;
+
+}());
+
+
+ /**
+ * load( Cldr, source, jsons )
+ *
+ * @Cldr [Cldr class]
+ *
+ * @source [Object]
+ *
+ * @jsons [arguments]
+ */
+ var coreLoad = function( Cldr, source, jsons ) {
+ var i, j, json;
+
+ validatePresence( jsons[ 0 ], "json" );
+
+ // Support arbitrary parameters, e.g., `Cldr.load({...}, {...})`.
+ for ( i = 0; i < jsons.length; i++ ) {
+
+ // Support array parameters, e.g., `Cldr.load([{...}, {...}])`.
+ json = alwaysArray( jsons[ i ] );
+
+ for ( j = 0; j < json.length; j++ ) {
+ validateTypePlainObject( json[ j ], "json" );
+ source = jsonMerge( source, json[ j ] );
+ coreSetAvailableBundles( Cldr, json[ j ] );
+ }
+ }
+
+ return source;
+ };
+
+
+
+ var itemGetResolved = function( Cldr, path, attributes ) {
+ // Resolve path
+ var normalizedPath = pathNormalize( path, attributes );
+
+ return resourceGet( Cldr._resolved, normalizedPath );
+ };
+
+
+
+
+ /**
+ * new Cldr()
+ */
+ var Cldr = function( locale ) {
+ this.init( locale );
+ };
+
+ // Build optimization hack to avoid duplicating functions across modules.
+ Cldr._alwaysArray = alwaysArray;
+ Cldr._coreLoad = coreLoad;
+ Cldr._createError = createError;
+ Cldr._itemGetResolved = itemGetResolved;
+ Cldr._jsonMerge = jsonMerge;
+ Cldr._pathNormalize = pathNormalize;
+ Cldr._resourceGet = resourceGet;
+ Cldr._validatePresence = validatePresence;
+ Cldr._validateType = validateType;
+ Cldr._validateTypePath = validateTypePath;
+ Cldr._validateTypePlainObject = validateTypePlainObject;
+
+ Cldr._availableBundleMap = {};
+ Cldr._availableBundleMapQueue = [];
+ Cldr._resolved = {};
+
+ // Allow user to override locale separator "-" (default) | "_". According to http://www.unicode.org/reports/tr35/#Unicode_language_identifier, both "-" and "_" are valid locale separators (eg. "en_GB", "en-GB"). According to http://unicode.org/cldr/trac/ticket/6786 its usage must be consistent throughout the data set.
+ Cldr.localeSep = "-";
+
+ /**
+ * Cldr.load( json [, json, ...] )
+ *
+ * @json [JSON] CLDR data or [Array] Array of @json's.
+ *
+ * Load resolved cldr data.
+ */
+ Cldr.load = function() {
+ Cldr._resolved = coreLoad( Cldr, Cldr._resolved, arguments );
+ };
+
+ /**
+ * .init() automatically run on instantiation/construction.
+ */
+ Cldr.prototype.init = function( locale ) {
+ var attributes, language, maxLanguageId, minLanguageId, script, subtags, territory, unicodeLocaleExtensions, variant,
+ sep = Cldr.localeSep;
+
+ validatePresence( locale, "locale" );
+ validateTypeString( locale, "locale" );
+
+ subtags = coreSubtags( locale );
+
+ unicodeLocaleExtensions = subtags[ 4 ];
+ variant = subtags[ 3 ];
+
+ // Normalize locale code.
+ // Get (or deduce) the "triple subtags": language, territory (also aliased as region), and script subtags.
+ // Get the variant subtags (calendar, collation, currency, etc).
+ // refs:
+ // - http://www.unicode.org/reports/tr35/#Field_Definitions
+ // - http://www.unicode.org/reports/tr35/#Language_and_Locale_IDs
+ // - http://www.unicode.org/reports/tr35/#Unicode_locale_identifier
+
+ // When a locale id does not specify a language, or territory (region), or script, they are obtained by Likely Subtags.
+ maxLanguageId = coreLikelySubtags( Cldr, this, subtags, { force: true } ) || subtags;
+ language = maxLanguageId[ 0 ];
+ script = maxLanguageId[ 1 ];
+ territory = maxLanguageId[ 2 ];
+
+ minLanguageId = coreRemoveLikelySubtags( Cldr, this, maxLanguageId ).join( sep );
+
+ // Set attributes
+ this.attributes = attributes = {
+ bundle: bundleLookup( Cldr, this, minLanguageId ),
+
+ // Unicode Language Id
+ minlanguageId: minLanguageId,
+ maxLanguageId: maxLanguageId.join( sep ),
+
+ // Unicode Language Id Subtabs
+ language: language,
+ script: script,
+ territory: territory,
+ region: territory, /* alias */
+ variant: variant
+ };
+
+ // Unicode locale extensions.
+ unicodeLocaleExtensions && ( "-" + unicodeLocaleExtensions ).replace( /-[a-z]{3,8}|(-[a-z]{2})-([a-z]{3,8})/g, function( attribute, key, type ) {
+
+ if ( key ) {
+
+ // Extension is in the `keyword` form.
+ attributes[ "u" + key ] = type;
+ } else {
+
+ // Extension is in the `attribute` form.
+ attributes[ "u" + attribute ] = true;
+ }
+ });
+
+ this.locale = locale;
+ };
+
+ /**
+ * .get()
+ */
+ Cldr.prototype.get = function( path ) {
+
+ validatePresence( path, "path" );
+ validateTypePath( path, "path" );
+
+ return itemGetResolved( Cldr, path, this.attributes );
+ };
+
+ /**
+ * .main()
+ */
+ Cldr.prototype.main = function( path ) {
+ validatePresence( path, "path" );
+ validateTypePath( path, "path" );
+
+ validate( "E_MISSING_BUNDLE", this.attributes.bundle !== null, {
+ locale: this.locale
+ });
+
+ path = alwaysArray( path );
+ return this.get( [ "main/{bundle}" ].concat( path ) );
+ };
+
+ return Cldr;
+
+
+
+
+}));
diff --git a/external/cldrjs/cldr/event.js b/external/cldrjs/cldr/event.js
new file mode 100644
index 000000000..ee36d3543
--- /dev/null
+++ b/external/cldrjs/cldr/event.js
@@ -0,0 +1,585 @@
+/**
+ * CLDR JavaScript Library v0.4.3
+ * http://jquery.com/
+ *
+ * Copyright 2013 Rafael Xavier de Souza
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-08-24T01:00Z
+ */
+/*!
+ * CLDR JavaScript Library v0.4.3 2015-08-24T01:00Z MIT license © Rafael Xavier
+ * http://git.io/h4lmVg
+ */
+(function( factory ) {
+
+ if ( typeof define === "function" && define.amd ) {
+ // AMD.
+ define( [ "../cldr" ], factory );
+ } else if ( typeof module === "object" && typeof module.exports === "object" ) {
+ // Node. CommonJS.
+ module.exports = factory( require( "cldrjs" ) );
+ } else {
+ // Global
+ factory( Cldr );
+ }
+
+}(function( Cldr ) {
+
+ // Build optimization hack to avoid duplicating functions across modules.
+ var pathNormalize = Cldr._pathNormalize,
+ validatePresence = Cldr._validatePresence,
+ validateType = Cldr._validateType;
+
+/*!
+ * EventEmitter v4.2.7 - git.io/ee
+ * Oliver Caldwell
+ * MIT license
+ * @preserve
+ */
+
+var EventEmitter;
+/* jshint ignore:start */
+EventEmitter = (function () {
+
+
+ /**
+ * Class for managing events.
+ * Can be extended to provide event functionality in other classes.
+ *
+ * @class EventEmitter Manages event registering and emitting.
+ */
+ function EventEmitter() {}
+
+ // Shortcuts to improve speed and size
+ var proto = EventEmitter.prototype;
+ var exports = this;
+ var originalGlobalValue = exports.EventEmitter;
+
+ /**
+ * Finds the index of the listener for the event in it's storage array.
+ *
+ * @param {Function[]} listeners Array of listeners to search through.
+ * @param {Function} listener Method to look for.
+ * @return {Number} Index of the specified listener, -1 if not found
+ * @api private
+ */
+ function indexOfListener(listeners, listener) {
+ var i = listeners.length;
+ while (i--) {
+ if (listeners[i].listener === listener) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Alias a method while keeping the context correct, to allow for overwriting of target method.
+ *
+ * @param {String} name The name of the target method.
+ * @return {Function} The aliased method
+ * @api private
+ */
+ function alias(name) {
+ return function aliasClosure() {
+ return this[name].apply(this, arguments);
+ };
+ }
+
+ /**
+ * Returns the listener array for the specified event.
+ * Will initialise the event object and listener arrays if required.
+ * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
+ * Each property in the object response is an array of listener functions.
+ *
+ * @param {String|RegExp} evt Name of the event to return the listeners from.
+ * @return {Function[]|Object} All listener functions for the event.
+ */
+ proto.getListeners = function getListeners(evt) {
+ var events = this._getEvents();
+ var response;
+ var key;
+
+ // Return a concatenated array of all matching events if
+ // the selector is a regular expression.
+ if (evt instanceof RegExp) {
+ response = {};
+ for (key in events) {
+ if (events.hasOwnProperty(key) && evt.test(key)) {
+ response[key] = events[key];
+ }
+ }
+ }
+ else {
+ response = events[evt] || (events[evt] = []);
+ }
+
+ return response;
+ };
+
+ /**
+ * Takes a list of listener objects and flattens it into a list of listener functions.
+ *
+ * @param {Object[]} listeners Raw listener objects.
+ * @return {Function[]} Just the listener functions.
+ */
+ proto.flattenListeners = function flattenListeners(listeners) {
+ var flatListeners = [];
+ var i;
+
+ for (i = 0; i < listeners.length; i += 1) {
+ flatListeners.push(listeners[i].listener);
+ }
+
+ return flatListeners;
+ };
+
+ /**
+ * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
+ *
+ * @param {String|RegExp} evt Name of the event to return the listeners from.
+ * @return {Object} All listener functions for an event in an object.
+ */
+ proto.getListenersAsObject = function getListenersAsObject(evt) {
+ var listeners = this.getListeners(evt);
+ var response;
+
+ if (listeners instanceof Array) {
+ response = {};
+ response[evt] = listeners;
+ }
+
+ return response || listeners;
+ };
+
+ /**
+ * Adds a listener function to the specified event.
+ * The listener will not be added if it is a duplicate.
+ * If the listener returns true then it will be removed after it is called.
+ * If you pass a regular expression as the event name then the listener will be added to all events that match it.
+ *
+ * @param {String|RegExp} evt Name of the event to attach the listener to.
+ * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.addListener = function addListener(evt, listener) {
+ var listeners = this.getListenersAsObject(evt);
+ var listenerIsWrapped = typeof listener === 'object';
+ var key;
+
+ for (key in listeners) {
+ if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
+ listeners[key].push(listenerIsWrapped ? listener : {
+ listener: listener,
+ once: false
+ });
+ }
+ }
+
+ return this;
+ };
+
+ /**
+ * Alias of addListener
+ */
+ proto.on = alias('addListener');
+
+ /**
+ * Semi-alias of addListener. It will add a listener that will be
+ * automatically removed after it's first execution.
+ *
+ * @param {String|RegExp} evt Name of the event to attach the listener to.
+ * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.addOnceListener = function addOnceListener(evt, listener) {
+ return this.addListener(evt, {
+ listener: listener,
+ once: true
+ });
+ };
+
+ /**
+ * Alias of addOnceListener.
+ */
+ proto.once = alias('addOnceListener');
+
+ /**
+ * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
+ * You need to tell it what event names should be matched by a regex.
+ *
+ * @param {String} evt Name of the event to create.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.defineEvent = function defineEvent(evt) {
+ this.getListeners(evt);
+ return this;
+ };
+
+ /**
+ * Uses defineEvent to define multiple events.
+ *
+ * @param {String[]} evts An array of event names to define.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.defineEvents = function defineEvents(evts) {
+ for (var i = 0; i < evts.length; i += 1) {
+ this.defineEvent(evts[i]);
+ }
+ return this;
+ };
+
+ /**
+ * Removes a listener function from the specified event.
+ * When passed a regular expression as the event name, it will remove the listener from all events that match it.
+ *
+ * @param {String|RegExp} evt Name of the event to remove the listener from.
+ * @param {Function} listener Method to remove from the event.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.removeListener = function removeListener(evt, listener) {
+ var listeners = this.getListenersAsObject(evt);
+ var index;
+ var key;
+
+ for (key in listeners) {
+ if (listeners.hasOwnProperty(key)) {
+ index = indexOfListener(listeners[key], listener);
+
+ if (index !== -1) {
+ listeners[key].splice(index, 1);
+ }
+ }
+ }
+
+ return this;
+ };
+
+ /**
+ * Alias of removeListener
+ */
+ proto.off = alias('removeListener');
+
+ /**
+ * Adds listeners in bulk using the manipulateListeners method.
+ * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
+ * You can also pass it a regular expression to add the array of listeners to all events that match it.
+ * Yeah, this function does quite a bit. That's probably a bad thing.
+ *
+ * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
+ * @param {Function[]} [listeners] An optional array of listener functions to add.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.addListeners = function addListeners(evt, listeners) {
+ // Pass through to manipulateListeners
+ return this.manipulateListeners(false, evt, listeners);
+ };
+
+ /**
+ * Removes listeners in bulk using the manipulateListeners method.
+ * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
+ * You can also pass it an event name and an array of listeners to be removed.
+ * You can also pass it a regular expression to remove the listeners from all events that match it.
+ *
+ * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
+ * @param {Function[]} [listeners] An optional array of listener functions to remove.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.removeListeners = function removeListeners(evt, listeners) {
+ // Pass through to manipulateListeners
+ return this.manipulateListeners(true, evt, listeners);
+ };
+
+ /**
+ * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
+ * The first argument will determine if the listeners are removed (true) or added (false).
+ * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
+ * You can also pass it an event name and an array of listeners to be added/removed.
+ * You can also pass it a regular expression to manipulate the listeners of all events that match it.
+ *
+ * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
+ * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
+ * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
+ var i;
+ var value;
+ var single = remove ? this.removeListener : this.addListener;
+ var multiple = remove ? this.removeListeners : this.addListeners;
+
+ // If evt is an object then pass each of it's properties to this method
+ if (typeof evt === 'object' && !(evt instanceof RegExp)) {
+ for (i in evt) {
+ if (evt.hasOwnProperty(i) && (value = evt[i])) {
+ // Pass the single listener straight through to the singular method
+ if (typeof value === 'function') {
+ single.call(this, i, value);
+ }
+ else {
+ // Otherwise pass back to the multiple function
+ multiple.call(this, i, value);
+ }
+ }
+ }
+ }
+ else {
+ // So evt must be a string
+ // And listeners must be an array of listeners
+ // Loop over it and pass each one to the multiple method
+ i = listeners.length;
+ while (i--) {
+ single.call(this, evt, listeners[i]);
+ }
+ }
+
+ return this;
+ };
+
+ /**
+ * Removes all listeners from a specified event.
+ * If you do not specify an event then all listeners will be removed.
+ * That means every event will be emptied.
+ * You can also pass a regex to remove all events that match it.
+ *
+ * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.removeEvent = function removeEvent(evt) {
+ var type = typeof evt;
+ var events = this._getEvents();
+ var key;
+
+ // Remove different things depending on the state of evt
+ if (type === 'string') {
+ // Remove all listeners for the specified event
+ delete events[evt];
+ }
+ else if (evt instanceof RegExp) {
+ // Remove all events matching the regex.
+ for (key in events) {
+ if (events.hasOwnProperty(key) && evt.test(key)) {
+ delete events[key];
+ }
+ }
+ }
+ else {
+ // Remove all listeners in all events
+ delete this._events;
+ }
+
+ return this;
+ };
+
+ /**
+ * Alias of removeEvent.
+ *
+ * Added to mirror the node API.
+ */
+ proto.removeAllListeners = alias('removeEvent');
+
+ /**
+ * Emits an event of your choice.
+ * When emitted, every listener attached to that event will be executed.
+ * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
+ * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
+ * So they will not arrive within the array on the other side, they will be separate.
+ * You can also pass a regular expression to emit to all events that match it.
+ *
+ * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
+ * @param {Array} [args] Optional array of arguments to be passed to each listener.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.emitEvent = function emitEvent(evt, args) {
+ var listeners = this.getListenersAsObject(evt);
+ var listener;
+ var i;
+ var key;
+ var response;
+
+ for (key in listeners) {
+ if (listeners.hasOwnProperty(key)) {
+ i = listeners[key].length;
+
+ while (i--) {
+ // If the listener returns true then it shall be removed from the event
+ // The function is executed either with a basic call or an apply if there is an args array
+ listener = listeners[key][i];
+
+ if (listener.once === true) {
+ this.removeListener(evt, listener.listener);
+ }
+
+ response = listener.listener.apply(this, args || []);
+
+ if (response === this._getOnceReturnValue()) {
+ this.removeListener(evt, listener.listener);
+ }
+ }
+ }
+ }
+
+ return this;
+ };
+
+ /**
+ * Alias of emitEvent
+ */
+ proto.trigger = alias('emitEvent');
+
+ /**
+ * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
+ * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
+ *
+ * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
+ * @param {...*} Optional additional arguments to be passed to each listener.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.emit = function emit(evt) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return this.emitEvent(evt, args);
+ };
+
+ /**
+ * Sets the current value to check against when executing listeners. If a
+ * listeners return value matches the one set here then it will be removed
+ * after execution. This value defaults to true.
+ *
+ * @param {*} value The new value to check for when executing listeners.
+ * @return {Object} Current instance of EventEmitter for chaining.
+ */
+ proto.setOnceReturnValue = function setOnceReturnValue(value) {
+ this._onceReturnValue = value;
+ return this;
+ };
+
+ /**
+ * Fetches the current value to check against when executing listeners. If
+ * the listeners return value matches this one then it should be removed
+ * automatically. It will return true by default.
+ *
+ * @return {*|Boolean} The current value to check for or the default, true.
+ * @api private
+ */
+ proto._getOnceReturnValue = function _getOnceReturnValue() {
+ if (this.hasOwnProperty('_onceReturnValue')) {
+ return this._onceReturnValue;
+ }
+ else {
+ return true;
+ }
+ };
+
+ /**
+ * Fetches the events object and creates one if required.
+ *
+ * @return {Object} The events storage object.
+ * @api private
+ */
+ proto._getEvents = function _getEvents() {
+ return this._events || (this._events = {});
+ };
+
+ /**
+ * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
+ *
+ * @return {Function} Non conflicting EventEmitter class.
+ */
+ EventEmitter.noConflict = function noConflict() {
+ exports.EventEmitter = originalGlobalValue;
+ return EventEmitter;
+ };
+
+ return EventEmitter;
+}());
+/* jshint ignore:end */
+
+
+
+ var validateTypeFunction = function( value, name ) {
+ validateType( value, name, typeof value === "undefined" || typeof value === "function", "Function" );
+ };
+
+
+
+
+ var superGet, superInit,
+ globalEe = new EventEmitter();
+
+ function validateTypeEvent( value, name ) {
+ validateType( value, name, typeof value === "string" || value instanceof RegExp, "String or RegExp" );
+ }
+
+ function validateThenCall( method, self ) {
+ return function( event, listener ) {
+ validatePresence( event, "event" );
+ validateTypeEvent( event, "event" );
+
+ validatePresence( listener, "listener" );
+ validateTypeFunction( listener, "listener" );
+
+ return self[ method ].apply( self, arguments );
+ };
+ }
+
+ function off( self ) {
+ return validateThenCall( "off", self );
+ }
+
+ function on( self ) {
+ return validateThenCall( "on", self );
+ }
+
+ function once( self ) {
+ return validateThenCall( "once", self );
+ }
+
+ Cldr.off = off( globalEe );
+ Cldr.on = on( globalEe );
+ Cldr.once = once( globalEe );
+
+ /**
+ * Overload Cldr.prototype.init().
+ */
+ superInit = Cldr.prototype.init;
+ Cldr.prototype.init = function() {
+ var ee;
+ this.ee = ee = new EventEmitter();
+ this.off = off( ee );
+ this.on = on( ee );
+ this.once = once( ee );
+ superInit.apply( this, arguments );
+ };
+
+ /**
+ * getOverload is encapsulated, because of cldr/unresolved. If it's loaded
+ * after cldr/event (and note it overwrites .get), it can trigger this
+ * overload again.
+ */
+ function getOverload() {
+
+ /**
+ * Overload Cldr.prototype.get().
+ */
+ superGet = Cldr.prototype.get;
+ Cldr.prototype.get = function( path ) {
+ var value = superGet.apply( this, arguments );
+ path = pathNormalize( path, this.attributes ).join( "/" );
+ globalEe.trigger( "get", [ path, value ] );
+ this.ee.trigger( "get", [ path, value ] );
+ return value;
+ };
+ }
+
+ Cldr._eventInit = getOverload;
+ getOverload();
+
+ return Cldr;
+
+
+
+
+}));
diff --git a/external/cldrjs/cldr/supplemental.js b/external/cldrjs/cldr/supplemental.js
new file mode 100644
index 000000000..821abc4bf
--- /dev/null
+++ b/external/cldrjs/cldr/supplemental.js
@@ -0,0 +1,101 @@
+/**
+ * CLDR JavaScript Library v0.4.3
+ * http://jquery.com/
+ *
+ * Copyright 2013 Rafael Xavier de Souza
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-08-24T01:00Z
+ */
+/*!
+ * CLDR JavaScript Library v0.4.3 2015-08-24T01:00Z MIT license © Rafael Xavier
+ * http://git.io/h4lmVg
+ */
+(function( factory ) {
+
+ if ( typeof define === "function" && define.amd ) {
+ // AMD.
+ define( [ "../cldr" ], factory );
+ } else if ( typeof module === "object" && typeof module.exports === "object" ) {
+ // Node. CommonJS.
+ module.exports = factory( require( "cldrjs" ) );
+ } else {
+ // Global
+ factory( Cldr );
+ }
+
+}(function( Cldr ) {
+
+ // Build optimization hack to avoid duplicating functions across modules.
+ var alwaysArray = Cldr._alwaysArray;
+
+
+
+ var supplementalMain = function( cldr ) {
+
+ var prepend, supplemental;
+
+ prepend = function( prepend ) {
+ return function( path ) {
+ path = alwaysArray( path );
+ return cldr.get( [ prepend ].concat( path ) );
+ };
+ };
+
+ supplemental = prepend( "supplemental" );
+
+ // Week Data
+ // http://www.unicode.org/reports/tr35/tr35-dates.html#Week_Data
+ supplemental.weekData = prepend( "supplemental/weekData" );
+
+ supplemental.weekData.firstDay = function() {
+ return cldr.get( "supplemental/weekData/firstDay/{territory}" ) ||
+ cldr.get( "supplemental/weekData/firstDay/001" );
+ };
+
+ supplemental.weekData.minDays = function() {
+ var minDays = cldr.get( "supplemental/weekData/minDays/{territory}" ) ||
+ cldr.get( "supplemental/weekData/minDays/001" );
+ return parseInt( minDays, 10 );
+ };
+
+ // Time Data
+ // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data
+ supplemental.timeData = prepend( "supplemental/timeData" );
+
+ supplemental.timeData.allowed = function() {
+ return cldr.get( "supplemental/timeData/{territory}/_allowed" ) ||
+ cldr.get( "supplemental/timeData/001/_allowed" );
+ };
+
+ supplemental.timeData.preferred = function() {
+ return cldr.get( "supplemental/timeData/{territory}/_preferred" ) ||
+ cldr.get( "supplemental/timeData/001/_preferred" );
+ };
+
+ return supplemental;
+
+ };
+
+
+
+
+ var initSuper = Cldr.prototype.init;
+
+ /**
+ * .init() automatically ran on construction.
+ *
+ * Overload .init().
+ */
+ Cldr.prototype.init = function() {
+ initSuper.apply( this, arguments );
+ this.supplemental = supplementalMain( this );
+ };
+
+ return Cldr;
+
+
+
+
+}));
diff --git a/external/globalize/LICENSE b/external/globalize-old/LICENSE
index 9c8b02240..9c8b02240 100644
--- a/external/globalize/LICENSE
+++ b/external/globalize-old/LICENSE
diff --git a/external/globalize/globalize.culture.de-DE.js b/external/globalize-old/globalize.culture.de-DE.js
index 5466bd75e..5466bd75e 100644
--- a/external/globalize/globalize.culture.de-DE.js
+++ b/external/globalize-old/globalize.culture.de-DE.js
diff --git a/external/globalize/globalize.culture.ja-JP.js b/external/globalize-old/globalize.culture.ja-JP.js
index a9469d709..a9469d709 100644
--- a/external/globalize/globalize.culture.ja-JP.js
+++ b/external/globalize-old/globalize.culture.ja-JP.js
diff --git a/external/globalize-old/globalize.js b/external/globalize-old/globalize.js
new file mode 100644
index 000000000..a38a32625
--- /dev/null
+++ b/external/globalize-old/globalize.js
@@ -0,0 +1,1585 @@
+/*!
+ * Globalize
+ *
+ * http://github.com/jquery/globalize
+ *
+ * Copyright Software Freedom Conservancy, Inc.
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ */
+
+(function( window, undefined ) {
+
+var Globalize,
+ // private variables
+ regexHex,
+ regexInfinity,
+ regexParseFloat,
+ regexTrim,
+ // private JavaScript utility functions
+ arrayIndexOf,
+ endsWith,
+ extend,
+ isArray,
+ isFunction,
+ isObject,
+ startsWith,
+ trim,
+ truncate,
+ zeroPad,
+ // private Globalization utility functions
+ appendPreOrPostMatch,
+ expandFormat,
+ formatDate,
+ formatNumber,
+ getTokenRegExp,
+ getEra,
+ getEraYear,
+ parseExact,
+ parseNegativePattern;
+
+// Global variable (Globalize) or CommonJS module (globalize)
+Globalize = function( cultureSelector ) {
+ return new Globalize.prototype.init( cultureSelector );
+};
+
+if ( typeof require !== "undefined" &&
+ typeof exports !== "undefined" &&
+ typeof module !== "undefined" ) {
+ // Assume CommonJS
+ module.exports = Globalize;
+} else {
+ // Export as global variable
+ window.Globalize = Globalize;
+}
+
+Globalize.cultures = {};
+
+Globalize.prototype = {
+ constructor: Globalize,
+ init: function( cultureSelector ) {
+ this.cultures = Globalize.cultures;
+ this.cultureSelector = cultureSelector;
+
+ return this;
+ }
+};
+Globalize.prototype.init.prototype = Globalize.prototype;
+
+// 1. When defining a culture, all fields are required except the ones stated as optional.
+// 2. 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.
+// 3. 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".
+Globalize.cultures[ "default" ] = {
+ // 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
+ "-": "-",
+ // symbol used for NaN (Not-A-Number)
+ "NaN": "NaN",
+ // symbol used for Negative Infinity
+ negativeInfinity: "-Infinity",
+ // symbol used for Positive Infinity
+ positiveInfinity: "Infinity",
+ 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.
+ */
+ }
+ },
+ // For localized strings
+ messages: {}
+};
+
+Globalize.cultures[ "default" ].calendar = Globalize.cultures[ "default" ].calendars.standard;
+
+Globalize.cultures.en = Globalize.cultures[ "default" ];
+
+Globalize.cultureSelector = "en";
+
+//
+// private variables
+//
+
+regexHex = /^0x[a-f0-9]+$/i;
+regexInfinity = /^[+\-]?infinity$/i;
+regexParseFloat = /^[+\-]?\d*\.?\d*(e[+\-]?\d+)?$/;
+regexTrim = /^\s+|\s+$/g;
+
+//
+// private JavaScript utility functions
+//
+
+arrayIndexOf = function( 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;
+};
+
+endsWith = function( value, pattern ) {
+ return value.substr( value.length - pattern.length ) === pattern;
+};
+
+extend = function() {
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[0] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !isFunction(target) ) {
+ target = {};
+ }
+
+ for ( ; i < length; i++ ) {
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( isObject(copy) || (copyIsArray = isArray(copy)) ) ) {
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && isArray(src) ? src : [];
+
+ } else {
+ clone = src && isObject(src) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[ name ] = extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+isArray = Array.isArray || function( obj ) {
+ return Object.prototype.toString.call( obj ) === "[object Array]";
+};
+
+isFunction = function( obj ) {
+ return Object.prototype.toString.call( obj ) === "[object Function]";
+};
+
+isObject = function( obj ) {
+ return Object.prototype.toString.call( obj ) === "[object Object]";
+};
+
+startsWith = function( value, pattern ) {
+ return value.indexOf( pattern ) === 0;
+};
+
+trim = function( value ) {
+ return ( value + "" ).replace( regexTrim, "" );
+};
+
+truncate = function( value ) {
+ if ( isNaN( value ) ) {
+ return NaN;
+ }
+ return Math[ value < 0 ? "ceil" : "floor" ]( value );
+};
+
+zeroPad = function( str, count, left ) {
+ var l;
+ for ( l = str.length; l < count; l += 1 ) {
+ str = ( left ? ("0" + str) : (str + "0") );
+ }
+ return str;
+};
+
+//
+// private Globalization utility functions
+//
+
+appendPreOrPostMatch = function( 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;
+};
+
+expandFormat = function( 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;
+};
+
+formatDate = function( value, format, culture ) {
+ var cal = culture.calendar,
+ convert = cal.convert,
+ ret;
+
+ if ( !format || !format.length || format === "i" ) {
+ 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();
+ default:
+ throw "Invalid part value " + part;
+ }
+ }
+
+ 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
+ var 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 + "\'.";
+ }
+ }
+ return ret.join( "" );
+};
+
+// formatNumber
+(function() {
+ var expandNumber;
+
+ expandNumber = function( 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 ] : "";
+
+ 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, true );
+ 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;
+ };
+
+ formatNumber = function( value, format, culture ) {
+ if ( !isFinite(value) ) {
+ if ( value === Infinity ) {
+ return culture.numberFormat.positiveInfinity;
+ }
+ if ( value === -Infinity ) {
+ return culture.numberFormat.negativeInfinity;
+ }
+ return culture.numberFormat.NaN;
+ }
+ 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";
+ number = truncate( number );
+ if ( precision !== -1 ) {
+ number = zeroPad( "" + number, precision, true );
+ }
+ if ( value < 0 ) number = "-" + number;
+ break;
+ case "N":
+ formatInfo = nf;
+ /* falls through */
+ case "C":
+ formatInfo = formatInfo || nf.currency;
+ /* falls 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;
+ };
+
+}());
+
+getTokenRegExp = function() {
+ // 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);
+};
+
+getEra = function( 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;
+};
+
+getEraYear = function( 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;
+};
+
+// parseExact
+(function() {
+ var expandYear,
+ getDayIndex,
+ getMonthIndex,
+ getParseRegExp,
+ outOfRange,
+ toUpper,
+ toUpperArray;
+
+ expandYear = function( cal, year ) {
+ // expands 2-digit year into 4 digits.
+ if ( year < 100 ) {
+ var now = new Date(),
+ era = getEra( now ),
+ curr = getEraYear( now, cal, era ),
+ twoDigitYearMax = cal.twoDigitYearMax;
+ twoDigitYearMax = typeof twoDigitYearMax === "string" ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax;
+ year += curr - ( curr % 100 );
+ if ( year > twoDigitYearMax ) {
+ year -= 100;
+ }
+ }
+ return year;
+ };
+
+ getDayIndex = function ( 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;
+ };
+
+ getMonthIndex = function( 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;
+ };
+
+ getParseRegExp = function( 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 = "(\\/)";
+ break;
+ default:
+ throw "Invalid date format pattern \'" + m + "\'.";
+ }
+ 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;
+ };
+
+ outOfRange = function( value, low, high ) {
+ return value < low || value > high;
+ };
+
+ toUpper = function( value ) {
+ // "he-IL" has non-breaking space in weekday names.
+ return value.split( "\u00A0" ).join( " " ).toUpperCase();
+ };
+
+ toUpperArray = function( arr ) {
+ var results = [];
+ for ( var i = 0, l = arr.length; i < l; i++ ) {
+ results[ i ] = toUpper( arr[i] );
+ }
+ return results;
+ };
+
+ parseExact = function( 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;
+ };
+}());
+
+parseNegativePattern = function( value, nf, negativePattern ) {
+ var neg = nf[ "-" ],
+ pos = nf[ "+" ],
+ ret;
+ switch ( negativePattern ) {
+ case "n -":
+ neg = " " + neg;
+ pos = " " + pos;
+ /* falls 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 += " ";
+ /* falls 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 ];
+};
+
+//
+// public instance functions
+//
+
+Globalize.prototype.findClosestCulture = function( cultureSelector ) {
+ return Globalize.findClosestCulture.call( this, cultureSelector );
+};
+
+Globalize.prototype.format = function( value, format, cultureSelector ) {
+ return Globalize.format.call( this, value, format, cultureSelector );
+};
+
+Globalize.prototype.localize = function( key, cultureSelector ) {
+ return Globalize.localize.call( this, key, cultureSelector );
+};
+
+Globalize.prototype.parseInt = function( value, radix, cultureSelector ) {
+ return Globalize.parseInt.call( this, value, radix, cultureSelector );
+};
+
+Globalize.prototype.parseFloat = function( value, radix, cultureSelector ) {
+ return Globalize.parseFloat.call( this, value, radix, cultureSelector );
+};
+
+Globalize.prototype.culture = function( cultureSelector ) {
+ return Globalize.culture.call( this, cultureSelector );
+};
+
+//
+// public singleton functions
+//
+
+Globalize.addCultureInfo = function( cultureName, baseCultureName, info ) {
+
+ var base = {},
+ isNew = false;
+
+ if ( typeof cultureName !== "string" ) {
+ // cultureName argument is optional string. If not specified, assume info is first
+ // and only argument. Specified info deep-extends current culture.
+ info = cultureName;
+ cultureName = this.culture().name;
+ base = this.cultures[ cultureName ];
+ } else if ( typeof baseCultureName !== "string" ) {
+ // baseCultureName argument is optional string. If not specified, assume info is second
+ // argument. Specified info deep-extends specified culture.
+ // If specified culture does not exist, create by deep-extending default
+ info = baseCultureName;
+ isNew = ( this.cultures[ cultureName ] == null );
+ base = this.cultures[ cultureName ] || this.cultures[ "default" ];
+ } else {
+ // cultureName and baseCultureName specified. Assume a new culture is being created
+ // by deep-extending an specified base culture
+ isNew = true;
+ base = this.cultures[ baseCultureName ];
+ }
+
+ this.cultures[ cultureName ] = extend(true, {},
+ base,
+ info
+ );
+ // Make the standard calendar the current culture if it's a new culture
+ if ( isNew ) {
+ this.cultures[ cultureName ].calendar = this.cultures[ cultureName ].calendars.standard;
+ }
+};
+
+Globalize.findClosestCulture = function( name ) {
+ var match;
+ if ( !name ) {
+ return this.findClosestCulture( this.cultureSelector ) || this.cultures[ "default" ];
+ }
+ if ( typeof name === "string" ) {
+ 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 );
+ pri = isNaN( pri ) ? 0 : pri;
+ }
+ else {
+ pri = 1;
+ }
+ }
+ prioritized.push({ lang: lang, pri: pri });
+ }
+ prioritized.sort(function( a, b ) {
+ if ( a.pri < b.pri ) {
+ return 1;
+ } else if ( a.pri > b.pri ) {
+ return -1;
+ }
+ return 0;
+ });
+ // exact match
+ for ( i = 0; i < l; i++ ) {
+ lang = prioritized[ i ].lang;
+ match = cultures[ lang ];
+ if ( match ) {
+ return match;
+ }
+ }
+
+ // neutral language match
+ for ( i = 0; i < l; i++ ) {
+ lang = prioritized[ i ].lang;
+ 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 );
+ }
+
+ // last resort: match first culture using that language
+ for ( i = 0; i < l; i++ ) {
+ lang = prioritized[ i ].lang;
+ for ( var cultureKey in cultures ) {
+ var culture = cultures[ cultureKey ];
+ if ( culture.language === lang ) {
+ return culture;
+ }
+ }
+ }
+ }
+ else if ( typeof name === "object" ) {
+ return name;
+ }
+ return match || null;
+};
+
+Globalize.format = function( value, format, cultureSelector ) {
+ var culture = this.findClosestCulture( cultureSelector );
+ if ( value instanceof Date ) {
+ value = formatDate( value, format, culture );
+ }
+ else if ( typeof value === "number" ) {
+ value = formatNumber( value, format, culture );
+ }
+ return value;
+};
+
+Globalize.localize = function( key, cultureSelector ) {
+ return this.findClosestCulture( cultureSelector ).messages[ key ] ||
+ this.cultures[ "default" ].messages[ key ];
+};
+
+Globalize.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;
+};
+
+Globalize.parseInt = function( value, radix, cultureSelector ) {
+ return truncate( Globalize.parseFloat(value, radix, cultureSelector) );
+};
+
+Globalize.parseFloat = function( value, radix, cultureSelector ) {
+ // radix argument is optional
+ if ( typeof radix !== "number" ) {
+ cultureSelector = radix;
+ radix = 10;
+ }
+
+ var culture = this.findClosestCulture( cultureSelector );
+ 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["."] );
+ }
+
+ //Remove percentage character from number string before parsing
+ if ( value.indexOf(culture.numberFormat.percent.symbol) > -1){
+ value = value.replace( culture.numberFormat.percent.symbol, "" );
+ }
+
+ // remove spaces: leading, trailing and between - and number. Used for negative currency pt-BR
+ value = value.replace( / /g, "" );
+
+ // allow infinity or hexidecimal
+ if ( regexInfinity.test(value) ) {
+ ret = parseFloat( value );
+ }
+ else if ( !radix && regexHex.test(value) ) {
+ ret = parseInt( value, 16 );
+ }
+ else {
+
+ // determine sign and number
+ var signInfo = parseNegativePattern( value, nf, nf.pattern[0] ),
+ sign = signInfo[ 0 ],
+ num = signInfo[ 1 ];
+
+ // #44 - try parsing as "(n)"
+ if ( sign === "" && nf.pattern[0] !== "(n)" ) {
+ signInfo = parseNegativePattern( value, nf, "(n)" );
+ sign = signInfo[ 0 ];
+ num = signInfo[ 1 ];
+ }
+
+ // try parsing as "-n"
+ 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;
+};
+
+Globalize.culture = function( cultureSelector ) {
+ // setter
+ if ( typeof cultureSelector !== "undefined" ) {
+ this.cultureSelector = cultureSelector;
+ }
+ // getter
+ return this.findClosestCulture( cultureSelector ) || this.cultures[ "default" ];
+};
+
+}( this )); \ No newline at end of file
diff --git a/external/globalize/LICENSE.txt b/external/globalize/LICENSE.txt
new file mode 100644
index 000000000..0f9f2e51c
--- /dev/null
+++ b/external/globalize/LICENSE.txt
@@ -0,0 +1,43 @@
+Copyright jQuery Foundation and other contributors, https://jquery.org/
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+available at https://github.com/jquery/globalize
+
+The following license applies to all parts of this software except as
+documented below:
+
+====
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====
+
+Copyright and related rights for sample code are waived via CC0. Sample
+code is defined as all source code contained within the doc directory.
+
+CC0: http://creativecommons.org/publicdomain/zero/1.0/
+
+====
+
+All files located in the node_modules and external directories are
+externally maintained libraries used by this software which have their
+own licenses; we recommend you read them, as their terms may differ from
+the terms above.
diff --git a/external/globalize/globalize-runtime.js b/external/globalize/globalize-runtime.js
new file mode 100644
index 000000000..1cee1297e
--- /dev/null
+++ b/external/globalize/globalize-runtime.js
@@ -0,0 +1,236 @@
+/**
+ * Globalize Runtime v1.1.0-rc.6
+ *
+ * http://github.com/jquery/globalize
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-11-18T10:38Z
+ */
+/*!
+ * Globalize Runtime v1.1.0-rc.6 2015-11-18T10:38Z Released under the MIT license
+ * http://git.io/TrdQbw
+ */
+(function( root, factory ) {
+
+ // UMD returnExports
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD
+ define( factory );
+ } else if ( typeof exports === "object" ) {
+
+ // Node, CommonJS
+ module.exports = factory();
+ } else {
+
+ // Globalize
+ root.Globalize = factory();
+ }
+}( this, function() {
+
+
+/**
+ * A toString method that outputs meaningful values for objects or arrays and
+ * still performs as fast as a plain string in case variable is string, or as
+ * fast as `"" + number` in case variable is a number.
+ * Ref: http://jsperf.com/my-stringify
+ */
+var toString = function( variable ) {
+ return typeof variable === "string" ? variable : ( typeof variable === "number" ? "" +
+ variable : JSON.stringify( variable ) );
+};
+
+
+
+
+/**
+ * formatMessage( message, data )
+ *
+ * @message [String] A message with optional {vars} to be replaced.
+ *
+ * @data [Array or JSON] Object with replacing-variables content.
+ *
+ * Return the formatted message. For example:
+ *
+ * - formatMessage( "{0} second", [ 1 ] ); // 1 second
+ *
+ * - formatMessage( "{0}/{1}", ["m", "s"] ); // m/s
+ *
+ * - formatMessage( "{name} <{email}>", {
+ * name: "Foo",
+ * email: "bar@baz.qux"
+ * }); // Foo <bar@baz.qux>
+ */
+var formatMessage = function( message, data ) {
+
+ // Replace {attribute}'s
+ message = message.replace( /{[0-9a-zA-Z-_. ]+}/g, function( name ) {
+ name = name.replace( /^{([^}]*)}$/, "$1" );
+ return toString( data[ name ] );
+ });
+
+ return message;
+};
+
+
+
+
+var objectExtend = function() {
+ var destination = arguments[ 0 ],
+ sources = [].slice.call( arguments, 1 );
+
+ sources.forEach(function( source ) {
+ var prop;
+ for ( prop in source ) {
+ destination[ prop ] = source[ prop ];
+ }
+ });
+
+ return destination;
+};
+
+
+
+
+var createError = function( code, message, attributes ) {
+ var error;
+
+ message = code + ( message ? ": " + formatMessage( message, attributes ) : "" );
+ error = new Error( message );
+ error.code = code;
+
+ objectExtend( error, attributes );
+
+ return error;
+};
+
+
+
+
+// Based on http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery
+var stringHash = function( str ) {
+ return [].reduce.call( str, function( hash, i ) {
+ var chr = i.charCodeAt( 0 );
+ hash = ( ( hash << 5 ) - hash ) + chr;
+ return hash | 0;
+ }, 0 );
+};
+
+
+
+
+var runtimeKey = function( fnName, locale, args, argsStr ) {
+ var hash;
+ argsStr = argsStr || JSON.stringify( args );
+ hash = stringHash( fnName + locale + argsStr );
+ return hash > 0 ? "a" + hash : "b" + Math.abs( hash );
+};
+
+
+
+
+var validate = function( code, message, check, attributes ) {
+ if ( !check ) {
+ throw createError( code, message, attributes );
+ }
+};
+
+
+
+
+var validateParameterPresence = function( value, name ) {
+ validate( "E_MISSING_PARAMETER", "Missing required parameter `{name}`.",
+ value !== undefined, { name: name });
+};
+
+
+
+
+var validateParameterType = function( value, name, check, expected ) {
+ validate(
+ "E_INVALID_PAR_TYPE",
+ "Invalid `{name}` parameter ({value}). {expected} expected.",
+ check,
+ {
+ expected: expected,
+ name: name,
+ value: value
+ }
+ );
+};
+
+
+
+
+var validateParameterTypeString = function( value, name ) {
+ validateParameterType(
+ value,
+ name,
+ value === undefined || typeof value === "string",
+ "a string"
+ );
+};
+
+
+
+
+// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FRegular_Expressions
+var regexpEscape = function( string ) {
+ return string.replace( /([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1" );
+};
+
+
+
+
+var stringPad = function( str, count, right ) {
+ var length;
+ if ( typeof str !== "string" ) {
+ str = String( str );
+ }
+ for ( length = str.length; length < count; length += 1 ) {
+ str = ( right ? ( str + "0" ) : ( "0" + str ) );
+ }
+ return str;
+};
+
+
+
+
+function Globalize( locale ) {
+ if ( !( this instanceof Globalize ) ) {
+ return new Globalize( locale );
+ }
+
+ validateParameterPresence( locale, "locale" );
+ validateParameterTypeString( locale, "locale" );
+
+ this._locale = locale;
+}
+
+Globalize.locale = function( locale ) {
+ validateParameterTypeString( locale, "locale" );
+
+ if ( arguments.length ) {
+ this._locale = locale;
+ }
+ return this._locale;
+};
+
+Globalize._createError = createError;
+Globalize._formatMessage = formatMessage;
+Globalize._regexpEscape = regexpEscape;
+Globalize._runtimeKey = runtimeKey;
+Globalize._stringPad = stringPad;
+Globalize._validateParameterPresence = validateParameterPresence;
+Globalize._validateParameterTypeString = validateParameterTypeString;
+Globalize._validateParameterType = validateParameterType;
+
+return Globalize;
+
+
+
+
+}));
diff --git a/external/globalize/globalize-runtime/date.js b/external/globalize/globalize-runtime/date.js
new file mode 100644
index 000000000..118a5da05
--- /dev/null
+++ b/external/globalize/globalize-runtime/date.js
@@ -0,0 +1,1289 @@
+/**
+ * Globalize Runtime v1.1.0-rc.6
+ *
+ * http://github.com/jquery/globalize
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-11-18T10:38Z
+ */
+/*!
+ * Globalize Runtime v1.1.0-rc.6 2015-11-18T10:38Z Released under the MIT license
+ * http://git.io/TrdQbw
+ */
+(function( root, factory ) {
+
+ // UMD returnExports
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD
+ define([
+ "../globalize-runtime",
+ "./number"
+ ], factory );
+ } else if ( typeof exports === "object" ) {
+
+ // Node, CommonJS
+ module.exports = factory(
+ require( "../globalize-runtime" ),
+ require( "./number" )
+ );
+ } else {
+
+ // Extend global
+ factory( root.Globalize );
+ }
+}(this, function( Globalize ) {
+
+var createErrorUnsupportedFeature = Globalize._createErrorUnsupportedFeature,
+ regexpEscape = Globalize._regexpEscape,
+ runtimeKey = Globalize._runtimeKey,
+ stringPad = Globalize._stringPad,
+ validateParameterPresence = Globalize._validateParameterPresence,
+ validateParameterType = Globalize._validateParameterType,
+ validateParameterTypeString = Globalize._validateParameterTypeString;
+
+
+var validateParameterTypeDate = function( value, name ) {
+ validateParameterType( value, name, value === undefined || value instanceof Date, "Date" );
+};
+
+
+
+
+/**
+ * dayOfWeek( date, firstDay )
+ *
+ * @date
+ *
+ * @firstDay the result of `dateFirstDayOfWeek( cldr )`
+ *
+ * Return the day of the week normalized by the territory's firstDay [0-6].
+ * Eg for "mon":
+ * - return 0 if territory is GB, or BR, or DE, or FR (week starts on "mon");
+ * - return 1 if territory is US (week starts on "sun");
+ * - return 2 if territory is EG (week starts on "sat");
+ */
+var dateDayOfWeek = function( date, firstDay ) {
+ return ( date.getDay() - firstDay + 7 ) % 7;
+};
+
+
+
+
+/**
+ * distanceInDays( from, to )
+ *
+ * Return the distance in days between from and to Dates.
+ */
+var dateDistanceInDays = function( from, to ) {
+ var inDays = 864e5;
+ return ( to.getTime() - from.getTime() ) / inDays;
+};
+
+
+
+
+/**
+ * startOf changes the input to the beginning of the given unit.
+ *
+ * For example, starting at the start of a day, resets hours, minutes
+ * seconds and milliseconds to 0. Starting at the month does the same, but
+ * also sets the date to 1.
+ *
+ * Returns the modified date
+ */
+var dateStartOf = function( date, unit ) {
+ date = new Date( date.getTime() );
+ switch ( unit ) {
+ case "year":
+ date.setMonth( 0 );
+ /* falls through */
+ case "month":
+ date.setDate( 1 );
+ /* falls through */
+ case "day":
+ date.setHours( 0 );
+ /* falls through */
+ case "hour":
+ date.setMinutes( 0 );
+ /* falls through */
+ case "minute":
+ date.setSeconds( 0 );
+ /* falls through */
+ case "second":
+ date.setMilliseconds( 0 );
+ }
+ return date;
+};
+
+
+
+
+/**
+ * dayOfYear
+ *
+ * Return the distance in days of the date to the begin of the year [0-d].
+ */
+var dateDayOfYear = function( date ) {
+ return Math.floor( dateDistanceInDays( dateStartOf( date, "year" ), date ) );
+};
+
+
+
+
+/**
+ * millisecondsInDay
+ */
+var dateMillisecondsInDay = function( date ) {
+
+ // TODO Handle daylight savings discontinuities
+ return date - dateStartOf( date, "day" );
+};
+
+
+
+
+var datePatternRe = ( /([a-z])\1*|'([^']|'')+'|''|./ig );
+
+
+
+
+/**
+ * hourFormat( date, format, timeSeparator, formatNumber )
+ *
+ * Return date's timezone offset according to the format passed.
+ * Eg for format when timezone offset is 180:
+ * - "+H;-H": -3
+ * - "+HHmm;-HHmm": -0300
+ * - "+HH:mm;-HH:mm": -03:00
+ */
+var dateTimezoneHourFormat = function( date, format, timeSeparator, formatNumber ) {
+ var absOffset,
+ offset = date.getTimezoneOffset();
+
+ absOffset = Math.abs( offset );
+ formatNumber = formatNumber || {
+ 1: function( value ) {
+ return stringPad( value, 1 );
+ },
+ 2: function( value ) {
+ return stringPad( value, 2 );
+ }
+ };
+
+ return format
+
+ // Pick the correct sign side (+ or -).
+ .split( ";" )[ offset > 0 ? 1 : 0 ]
+
+ // Localize time separator
+ .replace( ":", timeSeparator )
+
+ // Update hours offset.
+ .replace( /HH?/, function( match ) {
+ return formatNumber[ match.length ]( Math.floor( absOffset / 60 ) );
+ })
+
+ // Update minutes offset and return.
+ .replace( /mm/, function() {
+ return formatNumber[ 2 ]( absOffset % 60 );
+ });
+};
+
+
+
+
+var dateWeekDays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ];
+
+
+
+
+/**
+ * format( date, properties )
+ *
+ * @date [Date instance].
+ *
+ * @properties
+ *
+ * TODO Support other calendar types.
+ *
+ * Disclosure: this function borrows excerpts of dojo/date/locale.
+ */
+var dateFormat = function( date, numberFormatters, properties ) {
+ var timeSeparator = properties.timeSeparator;
+
+ return properties.pattern.replace( datePatternRe, function( current ) {
+ var ret,
+ chr = current.charAt( 0 ),
+ length = current.length;
+
+ if ( chr === "j" ) {
+
+ // Locale preferred hHKk.
+ // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data
+ chr = properties.preferredTime;
+ }
+
+ if ( chr === "Z" ) {
+
+ // Z..ZZZ: same as "xxxx".
+ if ( length < 4 ) {
+ chr = "x";
+ length = 4;
+
+ // ZZZZ: same as "OOOO".
+ } else if ( length < 5 ) {
+ chr = "O";
+ length = 4;
+
+ // ZZZZZ: same as "XXXXX"
+ } else {
+ chr = "X";
+ length = 5;
+ }
+ }
+
+ switch ( chr ) {
+
+ // Era
+ case "G":
+ ret = properties.eras[ date.getFullYear() < 0 ? 0 : 1 ];
+ break;
+
+ // Year
+ case "y":
+
+ // Plain year.
+ // The length specifies the padding, but for two letters it also specifies the
+ // maximum length.
+ ret = date.getFullYear();
+ if ( length === 2 ) {
+ ret = String( ret );
+ ret = +ret.substr( ret.length - 2 );
+ }
+ break;
+
+ case "Y":
+
+ // Year in "Week of Year"
+ // The length specifies the padding, but for two letters it also specifies the
+ // maximum length.
+ // yearInWeekofYear = date + DaysInAWeek - (dayOfWeek - firstDay) - minDays
+ ret = new Date( date.getTime() );
+ ret.setDate(
+ ret.getDate() + 7 -
+ dateDayOfWeek( date, properties.firstDay ) -
+ properties.firstDay -
+ properties.minDays
+ );
+ ret = ret.getFullYear();
+ if ( length === 2 ) {
+ ret = String( ret );
+ ret = +ret.substr( ret.length - 2 );
+ }
+ break;
+
+ // Quarter
+ case "Q":
+ case "q":
+ ret = Math.ceil( ( date.getMonth() + 1 ) / 3 );
+ if ( length > 2 ) {
+ ret = properties.quarters[ chr ][ length ][ ret ];
+ }
+ break;
+
+ // Month
+ case "M":
+ case "L":
+ ret = date.getMonth() + 1;
+ if ( length > 2 ) {
+ ret = properties.months[ chr ][ length ][ ret ];
+ }
+ break;
+
+ // Week
+ case "w":
+
+ // Week of Year.
+ // woy = ceil( ( doy + dow of 1/1 ) / 7 ) - minDaysStuff ? 1 : 0.
+ // TODO should pad on ww? Not documented, but I guess so.
+ ret = dateDayOfWeek( dateStartOf( date, "year" ), properties.firstDay );
+ ret = Math.ceil( ( dateDayOfYear( date ) + ret ) / 7 ) -
+ ( 7 - ret >= properties.minDays ? 0 : 1 );
+ break;
+
+ case "W":
+
+ // Week of Month.
+ // wom = ceil( ( dom + dow of `1/month` ) / 7 ) - minDaysStuff ? 1 : 0.
+ ret = dateDayOfWeek( dateStartOf( date, "month" ), properties.firstDay );
+ ret = Math.ceil( ( date.getDate() + ret ) / 7 ) -
+ ( 7 - ret >= properties.minDays ? 0 : 1 );
+ break;
+
+ // Day
+ case "d":
+ ret = date.getDate();
+ break;
+
+ case "D":
+ ret = dateDayOfYear( date ) + 1;
+ break;
+
+ case "F":
+
+ // Day of Week in month. eg. 2nd Wed in July.
+ ret = Math.floor( date.getDate() / 7 ) + 1;
+ break;
+
+ // Week day
+ case "e":
+ case "c":
+ if ( length <= 2 ) {
+
+ // Range is [1-7] (deduced by example provided on documentation)
+ // TODO Should pad with zeros (not specified in the docs)?
+ ret = dateDayOfWeek( date, properties.firstDay ) + 1;
+ break;
+ }
+
+ /* falls through */
+ case "E":
+ ret = dateWeekDays[ date.getDay() ];
+ ret = properties.days[ chr ][ length ][ ret ];
+ break;
+
+ // Period (AM or PM)
+ case "a":
+ ret = properties.dayPeriods[ date.getHours() < 12 ? "am" : "pm" ];
+ break;
+
+ // Hour
+ case "h": // 1-12
+ ret = ( date.getHours() % 12 ) || 12;
+ break;
+
+ case "H": // 0-23
+ ret = date.getHours();
+ break;
+
+ case "K": // 0-11
+ ret = date.getHours() % 12;
+ break;
+
+ case "k": // 1-24
+ ret = date.getHours() || 24;
+ break;
+
+ // Minute
+ case "m":
+ ret = date.getMinutes();
+ break;
+
+ // Second
+ case "s":
+ ret = date.getSeconds();
+ break;
+
+ case "S":
+ ret = Math.round( date.getMilliseconds() * Math.pow( 10, length - 3 ) );
+ break;
+
+ case "A":
+ ret = Math.round( dateMillisecondsInDay( date ) * Math.pow( 10, length - 3 ) );
+ break;
+
+ // Zone
+ case "z":
+ case "O":
+
+ // O: "{gmtFormat}+H;{gmtFormat}-H" or "{gmtZeroFormat}", eg. "GMT-8" or "GMT".
+ // OOOO: "{gmtFormat}{hourFormat}" or "{gmtZeroFormat}", eg. "GMT-08:00" or "GMT".
+ if ( date.getTimezoneOffset() === 0 ) {
+ ret = properties.gmtZeroFormat;
+ } else {
+ ret = dateTimezoneHourFormat(
+ date,
+ length < 4 ? "+H;-H" : properties.tzLongHourFormat,
+ timeSeparator,
+ numberFormatters
+ );
+ ret = properties.gmtFormat.replace( /\{0\}/, ret );
+ }
+ break;
+
+ case "X":
+
+ // Same as x*, except it uses "Z" for zero offset.
+ if ( date.getTimezoneOffset() === 0 ) {
+ ret = "Z";
+ break;
+ }
+
+ /* falls through */
+ case "x":
+
+ // x: hourFormat("+HH;-HH")
+ // xx or xxxx: hourFormat("+HHmm;-HHmm")
+ // xxx or xxxxx: hourFormat("+HH:mm;-HH:mm")
+ ret = length === 1 ? "+HH;-HH" : ( length % 2 ? "+HH:mm;-HH:mm" : "+HHmm;-HHmm" );
+ ret = dateTimezoneHourFormat( date, ret, ":" );
+ break;
+
+ // timeSeparator
+ case ":":
+ ret = timeSeparator;
+ break;
+
+ // ' literals.
+ case "'":
+ current = current.replace( /''/, "'" );
+ if ( length > 2 ) {
+ current = current.slice( 1, -1 );
+ }
+ ret = current;
+ break;
+
+ // Anything else is considered a literal, including [ ,:/.@#], chinese, japonese, and
+ // arabic characters.
+ default:
+ ret = current;
+ }
+ if ( typeof ret === "number" ) {
+ ret = numberFormatters[ length ]( ret );
+ }
+ return ret;
+ });
+};
+
+
+
+
+var dateFormatterFn = function( numberFormatters, properties ) {
+ return function dateFormatter( value ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeDate( value, "value" );
+
+ return dateFormat( value, numberFormatters, properties );
+ };
+
+};
+
+
+
+
+/**
+ * isLeapYear( year )
+ *
+ * @year [Number]
+ *
+ * Returns an indication whether the specified year is a leap year.
+ */
+var dateIsLeapYear = function( year ) {
+ return new Date( year, 1, 29 ).getMonth() === 1;
+};
+
+
+
+
+/**
+ * lastDayOfMonth( date )
+ *
+ * @date [Date]
+ *
+ * Return the last day of the given date's month
+ */
+var dateLastDayOfMonth = function( date ) {
+ return new Date( date.getFullYear(), date.getMonth() + 1, 0 ).getDate();
+};
+
+
+
+
+/**
+ * Differently from native date.setDate(), this function returns a date whose
+ * day remains inside the month boundaries. For example:
+ *
+ * setDate( FebDate, 31 ): a "Feb 28" date.
+ * setDate( SepDate, 31 ): a "Sep 30" date.
+ */
+var dateSetDate = function( date, day ) {
+ var lastDay = new Date( date.getFullYear(), date.getMonth() + 1, 0 ).getDate();
+
+ date.setDate( day < 1 ? 1 : day < lastDay ? day : lastDay );
+};
+
+
+
+
+/**
+ * Differently from native date.setMonth(), this function adjusts date if
+ * needed, so final month is always the one set.
+ *
+ * setMonth( Jan31Date, 1 ): a "Feb 28" date.
+ * setDate( Jan31Date, 8 ): a "Sep 30" date.
+ */
+var dateSetMonth = function( date, month ) {
+ var originalDate = date.getDate();
+
+ date.setDate( 1 );
+ date.setMonth( month );
+ dateSetDate( date, originalDate );
+};
+
+
+
+
+var outOfRange = function( value, low, high ) {
+ return value < low || value > high;
+};
+
+
+
+
+/**
+ * parse( value, tokens, properties )
+ *
+ * @value [String] string date.
+ *
+ * @tokens [Object] tokens returned by date/tokenizer.
+ *
+ * @properties [Object] output returned by date/tokenizer-properties.
+ *
+ * ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
+ */
+var dateParse = function( value, tokens, properties ) {
+ var amPm, day, daysOfYear, era, hour, hour12, timezoneOffset, valid,
+ YEAR = 0,
+ MONTH = 1,
+ DAY = 2,
+ HOUR = 3,
+ MINUTE = 4,
+ SECOND = 5,
+ MILLISECONDS = 6,
+ date = new Date(),
+ truncateAt = [],
+ units = [ "year", "month", "day", "hour", "minute", "second", "milliseconds" ];
+
+ if ( !tokens.length ) {
+ return null;
+ }
+
+ valid = tokens.every(function( token ) {
+ var century, chr, value, length;
+
+ if ( token.type === "literal" ) {
+
+ // continue
+ return true;
+ }
+
+ chr = token.type.charAt( 0 );
+ length = token.type.length;
+
+ if ( chr === "j" ) {
+
+ // Locale preferred hHKk.
+ // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data
+ chr = properties.preferredTimeData;
+ }
+
+ switch ( chr ) {
+
+ // Era
+ case "G":
+ truncateAt.push( YEAR );
+ era = +token.value;
+ break;
+
+ // Year
+ case "y":
+ value = token.value;
+ if ( length === 2 ) {
+ if ( outOfRange( value, 0, 99 ) ) {
+ return false;
+ }
+
+ // mimic dojo/date/locale: choose century to apply, according to a sliding
+ // window of 80 years before and 20 years after present year.
+ century = Math.floor( date.getFullYear() / 100 ) * 100;
+ value += century;
+ if ( value > date.getFullYear() + 20 ) {
+ value -= 100;
+ }
+ }
+ date.setFullYear( value );
+ truncateAt.push( YEAR );
+ break;
+
+ case "Y": // Year in "Week of Year"
+ throw createErrorUnsupportedFeature({
+ feature: "year pattern `" + chr + "`"
+ });
+
+ // Quarter (skip)
+ case "Q":
+ case "q":
+ break;
+
+ // Month
+ case "M":
+ case "L":
+ if ( length <= 2 ) {
+ value = token.value;
+ } else {
+ value = +token.value;
+ }
+ if ( outOfRange( value, 1, 12 ) ) {
+ return false;
+ }
+ dateSetMonth( date, value - 1 );
+ truncateAt.push( MONTH );
+ break;
+
+ // Week (skip)
+ case "w": // Week of Year.
+ case "W": // Week of Month.
+ break;
+
+ // Day
+ case "d":
+ day = token.value;
+ truncateAt.push( DAY );
+ break;
+
+ case "D":
+ daysOfYear = token.value;
+ truncateAt.push( DAY );
+ break;
+
+ case "F":
+
+ // Day of Week in month. eg. 2nd Wed in July.
+ // Skip
+ break;
+
+ // Week day
+ case "e":
+ case "c":
+ case "E":
+
+ // Skip.
+ // value = arrayIndexOf( dateWeekDays, token.value );
+ break;
+
+ // Period (AM or PM)
+ case "a":
+ amPm = token.value;
+ break;
+
+ // Hour
+ case "h": // 1-12
+ value = token.value;
+ if ( outOfRange( value, 1, 12 ) ) {
+ return false;
+ }
+ hour = hour12 = true;
+ date.setHours( value === 12 ? 0 : value );
+ truncateAt.push( HOUR );
+ break;
+
+ case "K": // 0-11
+ value = token.value;
+ if ( outOfRange( value, 0, 11 ) ) {
+ return false;
+ }
+ hour = hour12 = true;
+ date.setHours( value );
+ truncateAt.push( HOUR );
+ break;
+
+ case "k": // 1-24
+ value = token.value;
+ if ( outOfRange( value, 1, 24 ) ) {
+ return false;
+ }
+ hour = true;
+ date.setHours( value === 24 ? 0 : value );
+ truncateAt.push( HOUR );
+ break;
+
+ case "H": // 0-23
+ value = token.value;
+ if ( outOfRange( value, 0, 23 ) ) {
+ return false;
+ }
+ hour = true;
+ date.setHours( value );
+ truncateAt.push( HOUR );
+ break;
+
+ // Minute
+ case "m":
+ value = token.value;
+ if ( outOfRange( value, 0, 59 ) ) {
+ return false;
+ }
+ date.setMinutes( value );
+ truncateAt.push( MINUTE );
+ break;
+
+ // Second
+ case "s":
+ value = token.value;
+ if ( outOfRange( value, 0, 59 ) ) {
+ return false;
+ }
+ date.setSeconds( value );
+ truncateAt.push( SECOND );
+ break;
+
+ case "A":
+ date.setHours( 0 );
+ date.setMinutes( 0 );
+ date.setSeconds( 0 );
+
+ /* falls through */
+ case "S":
+ value = Math.round( token.value * Math.pow( 10, 3 - length ) );
+ date.setMilliseconds( value );
+ truncateAt.push( MILLISECONDS );
+ break;
+
+ // Zone
+ case "Z":
+ case "z":
+ case "O":
+ case "X":
+ case "x":
+ timezoneOffset = token.value - date.getTimezoneOffset();
+ break;
+ }
+
+ return true;
+ });
+
+ if ( !valid ) {
+ return null;
+ }
+
+ // 12-hour format needs AM or PM, 24-hour format doesn't, ie. return null
+ // if amPm && !hour12 || !amPm && hour12.
+ if ( hour && !( !amPm ^ hour12 ) ) {
+ return null;
+ }
+
+ if ( era === 0 ) {
+
+ // 1 BC = year 0
+ date.setFullYear( date.getFullYear() * -1 + 1 );
+ }
+
+ if ( day !== undefined ) {
+ if ( outOfRange( day, 1, dateLastDayOfMonth( date ) ) ) {
+ return null;
+ }
+ date.setDate( day );
+ } else if ( daysOfYear !== undefined ) {
+ if ( outOfRange( daysOfYear, 1, dateIsLeapYear( date.getFullYear() ) ? 366 : 365 ) ) {
+ return null;
+ }
+ date.setMonth( 0 );
+ date.setDate( daysOfYear );
+ }
+
+ if ( hour12 && amPm === "pm" ) {
+ date.setHours( date.getHours() + 12 );
+ }
+
+ if ( timezoneOffset ) {
+ date.setMinutes( date.getMinutes() + timezoneOffset );
+ }
+
+ // Truncate date at the most precise unit defined. Eg.
+ // If value is "12/31", and pattern is "MM/dd":
+ // => new Date( <current Year>, 12, 31, 0, 0, 0, 0 );
+ truncateAt = Math.max.apply( null, truncateAt );
+ date = dateStartOf( date, units[ truncateAt ] );
+
+ return date;
+};
+
+
+
+
+/**
+ * Generated by:
+ *
+ * regenerate().add( require( "unicode-7.0.0/categories/N/symbols" ) ).toString();
+ *
+ * https://github.com/mathiasbynens/regenerate
+ * https://github.com/mathiasbynens/unicode-7.0.0
+ */
+var regexpN = /[0-9\xB2\xB3\xB9\xBC-\xBE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19]|\uD800[\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDEE1-\uDEFB\uDF20-\uDF23\uDF41\uDF4A\uDFD1-\uDFD5]|\uD801[\uDCA0-\uDCA9]|\uD802[\uDC58-\uDC5F\uDC79-\uDC7F\uDCA7-\uDCAF\uDD16-\uDD1B\uDE40-\uDE47\uDE7D\uDE7E\uDE9D-\uDE9F\uDEEB-\uDEEF\uDF58-\uDF5F\uDF78-\uDF7F\uDFA9-\uDFAF]|\uD803[\uDE60-\uDE7E]|\uD804[\uDC52-\uDC6F\uDCF0-\uDCF9\uDD36-\uDD3F\uDDD0-\uDDD9\uDDE1-\uDDF4\uDEF0-\uDEF9]|\uD805[\uDCD0-\uDCD9\uDE50-\uDE59\uDEC0-\uDEC9]|\uD806[\uDCE0-\uDCF2]|\uD809[\uDC00-\uDC6E]|\uD81A[\uDE60-\uDE69\uDF50-\uDF59\uDF5B-\uDF61]|\uD834[\uDF60-\uDF71]|\uD835[\uDFCE-\uDFFF]|\uD83A[\uDCC7-\uDCCF]|\uD83C[\uDD00-\uDD0C]/;
+
+
+
+
+/**
+ * tokenizer( value, pattern, properties )
+ *
+ * @value [String] string date.
+ *
+ * @properties [Object] output returned by date/tokenizer-properties.
+ *
+ * Returns an Array of tokens, eg. value "5 o'clock PM", pattern "h 'o''clock' a":
+ * [{
+ * type: "h",
+ * lexeme: "5"
+ * }, {
+ * type: "literal",
+ * lexeme: " "
+ * }, {
+ * type: "literal",
+ * lexeme: "o'clock"
+ * }, {
+ * type: "literal",
+ * lexeme: " "
+ * }, {
+ * type: "a",
+ * lexeme: "PM",
+ * value: "pm"
+ * }]
+ *
+ * OBS: lexeme's are always String and may return invalid ranges depending of the token type.
+ * Eg. "99" for month number.
+ *
+ * Return an empty Array when not successfully parsed.
+ */
+var dateTokenizer = function( value, numberParser, properties ) {
+ var valid,
+ timeSeparator = properties.timeSeparator,
+ tokens = [],
+ widths = [ "abbreviated", "wide", "narrow" ];
+
+ valid = properties.pattern.match( datePatternRe ).every(function( current ) {
+ var chr, length, numeric, tokenRe,
+ token = {};
+
+ function hourFormatParse( tokenRe, numberParser ) {
+ var aux = value.match( tokenRe );
+ numberParser = numberParser || function( value ) {
+ return +value;
+ };
+
+ if ( !aux ) {
+ return false;
+ }
+
+ // hourFormat containing H only, e.g., `+H;-H`
+ if ( aux.length < 8 ) {
+ token.value =
+ ( aux[ 1 ] ? -numberParser( aux[ 1 ] ) : numberParser( aux[ 4 ] ) ) * 60;
+
+ // hourFormat containing H and m, e.g., `+HHmm;-HHmm`
+ } else {
+ token.value =
+ ( aux[ 1 ] ? -numberParser( aux[ 1 ] ) : numberParser( aux[ 7 ] ) ) * 60 +
+ ( aux[ 1 ] ? -numberParser( aux[ 4 ] ) : numberParser( aux[ 10 ] ) );
+ }
+
+ return true;
+ }
+
+ // Transform:
+ // - "+H;-H" -> /\+(\d\d?)|-(\d\d?)/
+ // - "+HH;-HH" -> /\+(\d\d)|-(\d\d)/
+ // - "+HHmm;-HHmm" -> /\+(\d\d)(\d\d)|-(\d\d)(\d\d)/
+ // - "+HH:mm;-HH:mm" -> /\+(\d\d):(\d\d)|-(\d\d):(\d\d)/
+ //
+ // If gmtFormat is GMT{0}, the regexp must fill {0} in each side, e.g.:
+ // - "+H;-H" -> /GMT\+(\d\d?)|GMT-(\d\d?)/
+ function hourFormatRe( hourFormat, gmtFormat, timeSeparator ) {
+ var re;
+
+ if ( !gmtFormat ) {
+ gmtFormat = "{0}";
+ }
+
+ re = hourFormat
+ .replace( "+", "\\+" )
+
+ // Unicode equivalent to (\\d\\d)
+ .replace( /HH|mm/g, "((" + regexpN.source + ")(" + regexpN.source + "))" )
+
+ // Unicode equivalent to (\\d\\d?)
+ .replace( /H|m/g, "((" + regexpN.source + ")(" + regexpN.source + ")?)" );
+
+ if ( timeSeparator ) {
+ re = re.replace( /:/g, timeSeparator );
+ }
+
+ re = re.split( ";" ).map(function( part ) {
+ return gmtFormat.replace( "{0}", part );
+ }).join( "|" );
+
+ return new RegExp( re );
+ }
+
+ function oneDigitIfLengthOne() {
+ if ( length === 1 ) {
+
+ // Unicode equivalent to /\d/
+ numeric = true;
+ return tokenRe = regexpN;
+ }
+ }
+
+ function oneOrTwoDigitsIfLengthOne() {
+ if ( length === 1 ) {
+
+ // Unicode equivalent to /\d\d?/
+ numeric = true;
+ return tokenRe = new RegExp( "(" + regexpN.source + ")(" + regexpN.source + ")?" );
+ }
+ }
+
+ function twoDigitsIfLengthTwo() {
+ if ( length === 2 ) {
+
+ // Unicode equivalent to /\d\d/
+ numeric = true;
+ return tokenRe = new RegExp( "(" + regexpN.source + ")(" + regexpN.source + ")" );
+ }
+ }
+
+ // Brute-force test every locale entry in an attempt to match the given value.
+ // Return the first found one (and set token accordingly), or null.
+ function lookup( path ) {
+ var i, re,
+ data = properties[ path.join( "/" ) ];
+
+ for ( i in data ) {
+ re = new RegExp( "^" + data[ i ] );
+ if ( re.test( value ) ) {
+ token.value = i;
+ return tokenRe = new RegExp( data[ i ] );
+ }
+ }
+ return null;
+ }
+
+ token.type = current;
+ chr = current.charAt( 0 ),
+ length = current.length;
+
+ if ( chr === "Z" ) {
+
+ // Z..ZZZ: same as "xxxx".
+ if ( length < 4 ) {
+ chr = "x";
+ length = 4;
+
+ // ZZZZ: same as "OOOO".
+ } else if ( length < 5 ) {
+ chr = "O";
+ length = 4;
+
+ // ZZZZZ: same as "XXXXX"
+ } else {
+ chr = "X";
+ length = 5;
+ }
+ }
+
+ switch ( chr ) {
+
+ // Era
+ case "G":
+ lookup([
+ "gregorian/eras",
+ length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" )
+ ]);
+ break;
+
+ // Year
+ case "y":
+ case "Y":
+ numeric = true;
+
+ // number l=1:+, l=2:{2}, l=3:{3,}, l=4:{4,}, ...
+ if ( length === 1 ) {
+
+ // Unicode equivalent to /\d+/.
+ tokenRe = new RegExp( "(" + regexpN.source + ")+" );
+ } else if ( length === 2 ) {
+
+ // Unicode equivalent to /\d\d/
+ tokenRe = new RegExp( "(" + regexpN.source + ")(" + regexpN.source + ")" );
+ } else {
+
+ // Unicode equivalent to /\d{length,}/
+ tokenRe = new RegExp( "(" + regexpN.source + "){" + length + ",}" );
+ }
+ break;
+
+ // Quarter
+ case "Q":
+ case "q":
+
+ // number l=1:{1}, l=2:{2}.
+ // lookup l=3...
+ oneDigitIfLengthOne() || twoDigitsIfLengthTwo() || lookup([
+ "gregorian/quarters",
+ chr === "Q" ? "format" : "stand-alone",
+ widths[ length - 3 ]
+ ]);
+ break;
+
+ // Month
+ case "M":
+ case "L":
+
+ // number l=1:{1,2}, l=2:{2}.
+ // lookup l=3...
+ oneOrTwoDigitsIfLengthOne() || twoDigitsIfLengthTwo() || lookup([
+ "gregorian/months",
+ chr === "M" ? "format" : "stand-alone",
+ widths[ length - 3 ]
+ ]);
+ break;
+
+ // Day
+ case "D":
+
+ // number {l,3}.
+ if ( length <= 3 ) {
+
+ // Unicode equivalent to /\d{length,3}/
+ numeric = true;
+ tokenRe = new RegExp( "(" + regexpN.source + "){" + length + ",3}" );
+ }
+ break;
+
+ case "W":
+ case "F":
+
+ // number l=1:{1}.
+ oneDigitIfLengthOne();
+ break;
+
+ // Week day
+ case "e":
+ case "c":
+
+ // number l=1:{1}, l=2:{2}.
+ // lookup for length >=3.
+ if ( length <= 2 ) {
+ oneDigitIfLengthOne() || twoDigitsIfLengthTwo();
+ break;
+ }
+
+ /* falls through */
+ case "E":
+ if ( length === 6 ) {
+
+ // Note: if short day names are not explicitly specified, abbreviated day
+ // names are used instead http://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras
+ lookup([
+ "gregorian/days",
+ [ chr === "c" ? "stand-alone" : "format" ],
+ "short"
+ ]) || lookup([
+ "gregorian/days",
+ [ chr === "c" ? "stand-alone" : "format" ],
+ "abbreviated"
+ ]);
+ } else {
+ lookup([
+ "gregorian/days",
+ [ chr === "c" ? "stand-alone" : "format" ],
+ widths[ length < 3 ? 0 : length - 3 ]
+ ]);
+ }
+ break;
+
+ // Period (AM or PM)
+ case "a":
+ lookup([
+ "gregorian/dayPeriods/format/wide"
+ ]);
+ break;
+
+ // Week, Day, Hour, Minute, or Second
+ case "w":
+ case "d":
+ case "h":
+ case "H":
+ case "K":
+ case "k":
+ case "j":
+ case "m":
+ case "s":
+
+ // number l1:{1,2}, l2:{2}.
+ oneOrTwoDigitsIfLengthOne() || twoDigitsIfLengthTwo();
+ break;
+
+ case "S":
+
+ // number {l}.
+
+ // Unicode equivalent to /\d{length}/
+ numeric = true;
+ tokenRe = new RegExp( "(" + regexpN.source + "){" + length + "}" );
+ break;
+
+ case "A":
+
+ // number {l+5}.
+
+ // Unicode equivalent to /\d{length+5}/
+ numeric = true;
+ tokenRe = new RegExp( "(" + regexpN.source + "){" + ( length + 5 ) + "}" );
+ break;
+
+ // Zone
+ case "z":
+ case "O":
+
+ // O: "{gmtFormat}+H;{gmtFormat}-H" or "{gmtZeroFormat}", eg. "GMT-8" or "GMT".
+ // OOOO: "{gmtFormat}{hourFormat}" or "{gmtZeroFormat}", eg. "GMT-08:00" or "GMT".
+ if ( value === properties[ "timeZoneNames/gmtZeroFormat" ] ) {
+ token.value = 0;
+ tokenRe = new RegExp( properties[ "timeZoneNames/gmtZeroFormat" ] );
+ } else {
+ tokenRe = hourFormatRe(
+ length < 4 ? "+H;-H" : properties[ "timeZoneNames/hourFormat" ],
+ properties[ "timeZoneNames/gmtFormat" ],
+ timeSeparator
+ );
+ if ( !hourFormatParse( tokenRe, numberParser ) ) {
+ return null;
+ }
+ }
+ break;
+
+ case "X":
+
+ // Same as x*, except it uses "Z" for zero offset.
+ if ( value === "Z" ) {
+ token.value = 0;
+ tokenRe = /Z/;
+ break;
+ }
+
+ /* falls through */
+ case "x":
+
+ // x: hourFormat("+HH;-HH")
+ // xx or xxxx: hourFormat("+HHmm;-HHmm")
+ // xxx or xxxxx: hourFormat("+HH:mm;-HH:mm")
+ tokenRe = hourFormatRe(
+ length === 1 ? "+HH;-HH" : ( length % 2 ? "+HH:mm;-HH:mm" : "+HHmm;-HHmm" )
+ );
+ if ( !hourFormatParse( tokenRe ) ) {
+ return null;
+ }
+ break;
+
+ case "'":
+ token.type = "literal";
+ current = current.replace( /''/, "'" );
+ if ( length > 2 ) {
+ current = current.slice( 1, -1 );
+ }
+ tokenRe = new RegExp( regexpEscape( current ) );
+ break;
+
+ default:
+ token.type = "literal";
+ tokenRe = /./;
+ }
+
+ if ( !tokenRe ) {
+ return false;
+ }
+
+ // Get lexeme and consume it.
+ value = value.replace( new RegExp( "^" + tokenRe.source ), function( lexeme ) {
+ token.lexeme = lexeme;
+ if ( numeric ) {
+ token.value = numberParser( lexeme );
+ }
+ return "";
+ });
+
+ if ( !token.lexeme ) {
+ return false;
+ }
+
+ tokens.push( token );
+ return true;
+ });
+
+ return valid ? tokens : [];
+};
+
+
+
+
+var dateParserFn = function( numberParser, parseProperties, tokenizerProperties ) {
+ return function dateParser( value ) {
+ var tokens;
+
+ validateParameterPresence( value, "value" );
+ validateParameterTypeString( value, "value" );
+
+ tokens = dateTokenizer( value, numberParser, tokenizerProperties );
+ return dateParse( value, tokens, parseProperties ) || null;
+ };
+};
+
+
+
+
+Globalize._dateFormatterFn = dateFormatterFn;
+Globalize._dateParserFn = dateParserFn;
+Globalize._dateFormat = dateFormat;
+Globalize._dateParser = dateParse;
+Globalize._dateTokenizer = dateTokenizer;
+Globalize._validateParameterTypeDate = validateParameterTypeDate;
+
+Globalize.dateFormatter =
+Globalize.prototype.dateFormatter = function( options ) {
+ options = options || { skeleton: "yMd" };
+ return Globalize[ runtimeKey( "dateFormatter", this._locale, [ options ] ) ];
+};
+
+Globalize.dateParser =
+Globalize.prototype.dateParser = function( options ) {
+ options = options || { skeleton: "yMd" };
+ return Globalize[ runtimeKey( "dateParser", this._locale, [ options ] ) ];
+};
+
+Globalize.formatDate =
+Globalize.prototype.formatDate = function( value, options ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeDate( value, "value" );
+
+ return this.dateFormatter( options )( value );
+};
+
+Globalize.parseDate =
+Globalize.prototype.parseDate = function( value, options ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeString( value, "value" );
+
+ return this.dateParser( options )( value );
+};
+
+return Globalize;
+
+
+
+
+}));
diff --git a/external/globalize/globalize-runtime/number.js b/external/globalize/globalize-runtime/number.js
new file mode 100644
index 000000000..b3031471a
--- /dev/null
+++ b/external/globalize/globalize-runtime/number.js
@@ -0,0 +1,682 @@
+/**
+ * Globalize Runtime v1.1.0-rc.6
+ *
+ * http://github.com/jquery/globalize
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-11-18T10:38Z
+ */
+/*!
+ * Globalize Runtime v1.1.0-rc.6 2015-11-18T10:38Z Released under the MIT license
+ * http://git.io/TrdQbw
+ */
+(function( root, factory ) {
+
+ // UMD returnExports
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD
+ define([
+ "../globalize-runtime"
+ ], factory );
+ } else if ( typeof exports === "object" ) {
+
+ // Node, CommonJS
+ module.exports = factory( require( "../globalize-runtime" ) );
+ } else {
+
+ // Extend global
+ factory( root.Globalize );
+ }
+}(this, function( Globalize ) {
+
+var createError = Globalize._createError,
+ regexpEscape = Globalize._regexpEscape,
+ runtimeKey = Globalize._runtimeKey,
+ stringPad = Globalize._stringPad,
+ validateParameterType = Globalize._validateParameterType,
+ validateParameterPresence = Globalize._validateParameterPresence,
+ validateParameterTypeString = Globalize._validateParameterTypeString;
+
+
+var createErrorUnsupportedFeature = function( feature ) {
+ return createError( "E_UNSUPPORTED", "Unsupported {feature}.", {
+ feature: feature
+ });
+};
+
+
+
+
+var validateParameterTypeNumber = function( value, name ) {
+ validateParameterType(
+ value,
+ name,
+ value === undefined || typeof value === "number",
+ "Number"
+ );
+};
+
+
+
+
+/**
+ * goupingSeparator( number, primaryGroupingSize, secondaryGroupingSize )
+ *
+ * @number [Number].
+ *
+ * @primaryGroupingSize [Number]
+ *
+ * @secondaryGroupingSize [Number]
+ *
+ * Return the formatted number with group separator.
+ */
+var numberFormatGroupingSeparator = function( number, primaryGroupingSize, secondaryGroupingSize ) {
+ var index,
+ currentGroupingSize = primaryGroupingSize,
+ ret = "",
+ sep = ",",
+ switchToSecondary = secondaryGroupingSize ? true : false;
+
+ number = String( number ).split( "." );
+ index = number[ 0 ].length;
+
+ while ( index > currentGroupingSize ) {
+ ret = number[ 0 ].slice( index - currentGroupingSize, index ) +
+ ( ret.length ? sep : "" ) + ret;
+ index -= currentGroupingSize;
+ if ( switchToSecondary ) {
+ currentGroupingSize = secondaryGroupingSize;
+ switchToSecondary = false;
+ }
+ }
+
+ number[ 0 ] = number[ 0 ].slice( 0, index ) + ( ret.length ? sep : "" ) + ret;
+ return number.join( "." );
+};
+
+
+
+
+/**
+ * integerFractionDigits( number, minimumIntegerDigits, minimumFractionDigits,
+ * maximumFractionDigits, round, roundIncrement )
+ *
+ * @number [Number]
+ *
+ * @minimumIntegerDigits [Number]
+ *
+ * @minimumFractionDigits [Number]
+ *
+ * @maximumFractionDigits [Number]
+ *
+ * @round [Function]
+ *
+ * @roundIncrement [Function]
+ *
+ * Return the formatted integer and fraction digits.
+ */
+var numberFormatIntegerFractionDigits = function( number, minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, round,
+ roundIncrement ) {
+
+ // Fraction
+ if ( maximumFractionDigits ) {
+
+ // Rounding
+ if ( roundIncrement ) {
+ number = round( number, roundIncrement );
+
+ // Maximum fraction digits
+ } else {
+ number = round( number, { exponent: -maximumFractionDigits } );
+ }
+
+ // Minimum fraction digits
+ if ( minimumFractionDigits ) {
+ number = String( number ).split( "." );
+ number[ 1 ] = stringPad( number[ 1 ] || "", minimumFractionDigits, true );
+ number = number.join( "." );
+ }
+ } else {
+ number = round( number );
+ }
+
+ number = String( number );
+
+ // Minimum integer digits
+ if ( minimumIntegerDigits ) {
+ number = number.split( "." );
+ number[ 0 ] = stringPad( number[ 0 ], minimumIntegerDigits );
+ number = number.join( "." );
+ }
+
+ return number;
+};
+
+
+
+
+/**
+ * toPrecision( number, precision, round )
+ *
+ * @number (Number)
+ *
+ * @precision (Number) significant figures precision (not decimal precision).
+ *
+ * @round (Function)
+ *
+ * Return number.toPrecision( precision ) using the given round function.
+ */
+var numberToPrecision = function( number, precision, round ) {
+ var roundOrder;
+
+ // Get number at two extra significant figure precision.
+ number = number.toPrecision( precision + 2 );
+
+ // Then, round it to the required significant figure precision.
+ roundOrder = Math.ceil( Math.log( Math.abs( number ) ) / Math.log( 10 ) );
+ roundOrder -= precision;
+
+ return round( number, { exponent: roundOrder } );
+};
+
+
+
+
+/**
+ * toPrecision( number, minimumSignificantDigits, maximumSignificantDigits, round )
+ *
+ * @number [Number]
+ *
+ * @minimumSignificantDigits [Number]
+ *
+ * @maximumSignificantDigits [Number]
+ *
+ * @round [Function]
+ *
+ * Return the formatted significant digits number.
+ */
+var numberFormatSignificantDigits = function( number, minimumSignificantDigits, maximumSignificantDigits, round ) {
+ var atMinimum, atMaximum;
+
+ // Sanity check.
+ if ( minimumSignificantDigits > maximumSignificantDigits ) {
+ maximumSignificantDigits = minimumSignificantDigits;
+ }
+
+ atMinimum = numberToPrecision( number, minimumSignificantDigits, round );
+ atMaximum = numberToPrecision( number, maximumSignificantDigits, round );
+
+ // Use atMaximum only if it has more significant digits than atMinimum.
+ number = +atMinimum === +atMaximum ? atMinimum : atMaximum;
+
+ // Expand integer numbers, eg. 123e5 to 12300.
+ number = ( +number ).toString( 10 );
+
+ if ( ( /e/ ).test( number ) ) {
+ throw createErrorUnsupportedFeature({
+ feature: "integers out of (1e21, 1e-7)"
+ });
+ }
+
+ // Add trailing zeros if necessary.
+ if ( minimumSignificantDigits - number.replace( /^0+|\./g, "" ).length > 0 ) {
+ number = number.split( "." );
+ number[ 1 ] = stringPad( number[ 1 ] || "", minimumSignificantDigits - number[ 0 ].replace( /^0+/, "" ).length, true );
+ number = number.join( "." );
+ }
+
+ return number;
+};
+
+
+
+
+/**
+ * format( number, properties )
+ *
+ * @number [Number].
+ *
+ * @properties [Object] Output of number/format-properties.
+ *
+ * Return the formatted number.
+ * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html
+ */
+var numberFormat = function( number, properties ) {
+ var infinitySymbol, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits,
+ minimumIntegerDigits, minimumSignificantDigits, nanSymbol, nuDigitsMap, padding, prefix,
+ primaryGroupingSize, pattern, ret, round, roundIncrement, secondaryGroupingSize, suffix,
+ symbolMap;
+
+ padding = properties[ 1 ];
+ minimumIntegerDigits = properties[ 2 ];
+ minimumFractionDigits = properties[ 3 ];
+ maximumFractionDigits = properties[ 4 ];
+ minimumSignificantDigits = properties[ 5 ];
+ maximumSignificantDigits = properties[ 6 ];
+ roundIncrement = properties[ 7 ];
+ primaryGroupingSize = properties[ 8 ];
+ secondaryGroupingSize = properties[ 9 ];
+ round = properties[ 15 ];
+ infinitySymbol = properties[ 16 ];
+ nanSymbol = properties[ 17 ];
+ symbolMap = properties[ 18 ];
+ nuDigitsMap = properties[ 19 ];
+
+ // NaN
+ if ( isNaN( number ) ) {
+ return nanSymbol;
+ }
+
+ if ( number < 0 ) {
+ pattern = properties[ 12 ];
+ prefix = properties[ 13 ];
+ suffix = properties[ 14 ];
+ } else {
+ pattern = properties[ 11 ];
+ prefix = properties[ 0 ];
+ suffix = properties[ 10 ];
+ }
+
+ // Infinity
+ if ( !isFinite( number ) ) {
+ return prefix + infinitySymbol + suffix;
+ }
+
+ ret = prefix;
+
+ // Percent
+ if ( pattern.indexOf( "%" ) !== -1 ) {
+ number *= 100;
+
+ // Per mille
+ } else if ( pattern.indexOf( "\u2030" ) !== -1 ) {
+ number *= 1000;
+ }
+
+ // Significant digit format
+ if ( !isNaN( minimumSignificantDigits * maximumSignificantDigits ) ) {
+ number = numberFormatSignificantDigits( number, minimumSignificantDigits,
+ maximumSignificantDigits, round );
+
+ // Integer and fractional format
+ } else {
+ number = numberFormatIntegerFractionDigits( number, minimumIntegerDigits,
+ minimumFractionDigits, maximumFractionDigits, round, roundIncrement );
+ }
+
+ // Remove the possible number minus sign
+ number = number.replace( /^-/, "" );
+
+ // Grouping separators
+ if ( primaryGroupingSize ) {
+ number = numberFormatGroupingSeparator( number, primaryGroupingSize,
+ secondaryGroupingSize );
+ }
+
+ ret += number;
+
+ // Scientific notation
+ // TODO implement here
+
+ // Padding/'([^']|'')+'|''|[.,\-+E%\u2030]/g
+ // TODO implement here
+
+ ret += suffix;
+
+ return ret.replace( /('([^']|'')+'|'')|./g, function( character, literal ) {
+
+ // Literals
+ if ( literal ) {
+ literal = literal.replace( /''/, "'" );
+ if ( literal.length > 2 ) {
+ literal = literal.slice( 1, -1 );
+ }
+ return literal;
+ }
+
+ // Symbols
+ character = character.replace( /[.,\-+E%\u2030]/, function( symbol ) {
+ return symbolMap[ symbol ];
+ });
+
+ // Numbering system
+ if ( nuDigitsMap ) {
+ character = character.replace( /[0-9]/, function( digit ) {
+ return nuDigitsMap[ +digit ];
+ });
+ }
+
+ return character;
+ });
+};
+
+
+
+
+var numberFormatterFn = function( properties ) {
+ return function numberFormatter( value ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeNumber( value, "value" );
+
+ return numberFormat( value, properties );
+ };
+};
+
+
+
+
+/**
+ * EBNF representation:
+ *
+ * number_pattern_re = prefix_including_padding?
+ * number
+ * scientific_notation?
+ * suffix?
+ *
+ * number = integer_including_group_separator fraction_including_decimal_separator
+ *
+ * integer_including_group_separator =
+ * regexp([0-9,]*[0-9]+)
+ *
+ * fraction_including_decimal_separator =
+ * regexp((\.[0-9]+)?)
+
+ * prefix_including_padding = non_number_stuff
+ *
+ * scientific_notation = regexp(E[+-]?[0-9]+)
+ *
+ * suffix = non_number_stuff
+ *
+ * non_number_stuff = regexp([^0-9]*)
+ *
+ *
+ * Regexp groups:
+ *
+ * 0: number_pattern_re
+ * 1: prefix
+ * 2: integer_including_group_separator fraction_including_decimal_separator
+ * 3: integer_including_group_separator
+ * 4: fraction_including_decimal_separator
+ * 5: scientific_notation
+ * 6: suffix
+ */
+var numberNumberRe = ( /^([^0-9]*)(([0-9,]*[0-9]+)(\.[0-9]+)?)(E[+-]?[0-9]+)?([^0-9]*)$/ );
+
+
+
+
+/**
+ * parse( value, properties )
+ *
+ * @value [String].
+ *
+ * @properties [Object] Parser properties is a reduced pre-processed cldr
+ * data set returned by numberParserProperties().
+ *
+ * Return the parsed Number (including Infinity) or NaN when value is invalid.
+ * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html
+ */
+var numberParse = function( value, properties ) {
+ var aux, infinitySymbol, invertedNuDigitsMap, invertedSymbolMap, localizedDigitRe,
+ localizedSymbolsRe, negativePrefix, negativeSuffix, number, prefix, suffix;
+
+ infinitySymbol = properties[ 0 ];
+ invertedSymbolMap = properties[ 1 ];
+ negativePrefix = properties[ 2 ];
+ negativeSuffix = properties[ 3 ];
+ invertedNuDigitsMap = properties[ 4 ];
+
+ // Infinite number.
+ if ( aux = value.match( infinitySymbol ) ) {
+
+ number = Infinity;
+ prefix = value.slice( 0, aux.length );
+ suffix = value.slice( aux.length + 1 );
+
+ // Finite number.
+ } else {
+
+ // TODO: Create it during setup, i.e., make it a property.
+ localizedSymbolsRe = new RegExp(
+ Object.keys( invertedSymbolMap ).map(function( localizedSymbol ) {
+ return regexpEscape( localizedSymbol );
+ }).join( "|" ),
+ "g"
+ );
+
+ // Reverse localized symbols.
+ value = value.replace( localizedSymbolsRe, function( localizedSymbol ) {
+ return invertedSymbolMap[ localizedSymbol ];
+ });
+
+ // Reverse localized numbering system.
+ if ( invertedNuDigitsMap ) {
+
+ // TODO: Create it during setup, i.e., make it a property.
+ localizedDigitRe = new RegExp(
+ Object.keys( invertedNuDigitsMap ).map(function( localizedDigit ) {
+ return regexpEscape( localizedDigit );
+ }).join( "|" ),
+ "g"
+ );
+ value = value.replace( localizedDigitRe, function( localizedDigit ) {
+ return invertedNuDigitsMap[ localizedDigit ];
+ });
+ }
+
+ // Add padding zero to leading decimal.
+ if ( value.charAt( 0 ) === "." ) {
+ value = "0" + value;
+ }
+
+ // Is it a valid number?
+ value = value.match( numberNumberRe );
+ if ( !value ) {
+
+ // Invalid number.
+ return NaN;
+ }
+
+ prefix = value[ 1 ];
+ suffix = value[ 6 ];
+
+ // Remove grouping separators.
+ number = value[ 2 ].replace( /,/g, "" );
+
+ // Scientific notation
+ if ( value[ 5 ] ) {
+ number += value[ 5 ];
+ }
+
+ number = +number;
+
+ // Is it a valid number?
+ if ( isNaN( number ) ) {
+
+ // Invalid number.
+ return NaN;
+ }
+
+ // Percent
+ if ( value[ 0 ].indexOf( "%" ) !== -1 ) {
+ number /= 100;
+ suffix = suffix.replace( "%", "" );
+
+ // Per mille
+ } else if ( value[ 0 ].indexOf( "\u2030" ) !== -1 ) {
+ number /= 1000;
+ suffix = suffix.replace( "\u2030", "" );
+ }
+ }
+
+ // Negative number
+ // "If there is an explicit negative subpattern, it serves only to specify the negative prefix
+ // and suffix. If there is no explicit negative subpattern, the negative subpattern is the
+ // localized minus sign prefixed to the positive subpattern" UTS#35
+ if ( prefix === negativePrefix && suffix === negativeSuffix ) {
+ number *= -1;
+ }
+
+ return number;
+};
+
+
+
+
+var numberParserFn = function( properties ) {
+ return function numberParser( value ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeString( value, "value" );
+
+ return numberParse( value, properties );
+ };
+
+};
+
+
+
+
+var numberTruncate = function( value ) {
+ if ( isNaN( value ) ) {
+ return NaN;
+ }
+ return Math[ value < 0 ? "ceil" : "floor" ]( value );
+};
+
+
+
+
+/**
+ * round( method )
+ *
+ * @method [String] with either "round", "ceil", "floor", or "truncate".
+ *
+ * Return function( value, incrementOrExp ):
+ *
+ * @value [Number] eg. 123.45.
+ *
+ * @incrementOrExp [Number] optional, eg. 0.1; or
+ * [Object] Either { increment: <value> } or { exponent: <value> }
+ *
+ * Return the rounded number, eg:
+ * - round( "round" )( 123.45 ): 123;
+ * - round( "ceil" )( 123.45 ): 124;
+ * - round( "floor" )( 123.45 ): 123;
+ * - round( "truncate" )( 123.45 ): 123;
+ * - round( "round" )( 123.45, 0.1 ): 123.5;
+ * - round( "round" )( 123.45, 10 ): 120;
+ *
+ * Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
+ * Ref: #376
+ */
+var numberRound = function( method ) {
+ method = method || "round";
+ method = method === "truncate" ? numberTruncate : Math[ method ];
+
+ return function( value, incrementOrExp ) {
+ var exp, increment;
+
+ value = +value;
+
+ // If the value is not a number, return NaN.
+ if ( isNaN( value ) ) {
+ return NaN;
+ }
+
+ // Exponent given.
+ if ( typeof incrementOrExp === "object" && incrementOrExp.exponent ) {
+ exp = +incrementOrExp.exponent;
+ increment = 1;
+
+ if ( exp === 0 ) {
+ return method( value );
+ }
+
+ // If the exp is not an integer, return NaN.
+ if ( !( typeof exp === "number" && exp % 1 === 0 ) ) {
+ return NaN;
+ }
+
+ // Increment given.
+ } else {
+ increment = +incrementOrExp || 1;
+
+ if ( increment === 1 ) {
+ return method( value );
+ }
+
+ // If the increment is not a number, return NaN.
+ if ( isNaN( increment ) ) {
+ return NaN;
+ }
+
+ increment = increment.toExponential().split( "e" );
+ exp = +increment[ 1 ];
+ increment = +increment[ 0 ];
+ }
+
+ // Shift & Round
+ value = value.toString().split( "e" );
+ value[ 0 ] = +value[ 0 ] / increment;
+ value[ 1 ] = value[ 1 ] ? ( +value[ 1 ] - exp ) : -exp;
+ value = method( +( value[ 0 ] + "e" + value[ 1 ] ) );
+
+ // Shift back
+ value = value.toString().split( "e" );
+ value[ 0 ] = +value[ 0 ] * increment;
+ value[ 1 ] = value[ 1 ] ? ( +value[ 1 ] + exp ) : exp;
+ return +( value[ 0 ] + "e" + value[ 1 ] );
+ };
+};
+
+
+
+
+Globalize._createErrorUnsupportedFeature = createErrorUnsupportedFeature;
+Globalize._numberFormat = numberFormat;
+Globalize._numberFormatterFn = numberFormatterFn;
+Globalize._numberParse = numberParse;
+Globalize._numberParserFn = numberParserFn;
+Globalize._numberRound = numberRound;
+Globalize._validateParameterPresence = validateParameterPresence;
+Globalize._validateParameterTypeNumber = validateParameterTypeNumber;
+Globalize._validateParameterTypeString = validateParameterTypeString;
+
+Globalize.numberFormatter =
+Globalize.prototype.numberFormatter = function( options ) {
+ options = options || {};
+ return Globalize[ runtimeKey( "numberFormatter", this._locale, [ options ] ) ];
+};
+
+Globalize.numberParser =
+Globalize.prototype.numberParser = function( options ) {
+ options = options || {};
+ return Globalize[ runtimeKey( "numberParser", this._locale, [ options ] ) ];
+};
+
+Globalize.formatNumber =
+Globalize.prototype.formatNumber = function( value, options ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeNumber( value, "value" );
+
+ return this.numberFormatter( options )( value );
+};
+
+Globalize.parseNumber =
+Globalize.prototype.parseNumber = function( value, options ) {
+ validateParameterPresence( value, "value" );
+ validateParameterTypeString( value, "value" );
+
+ return this.numberParser( options )( value );
+};
+
+return Globalize;
+
+
+
+
+}));
diff --git a/external/globalize/globalize.js b/external/globalize/globalize.js
index a38a32625..2f744ac64 100644
--- a/external/globalize/globalize.js
+++ b/external/globalize/globalize.js
@@ -1,1585 +1,355 @@
-/*!
- * Globalize
+/**
+ * Globalize v1.0.0
*
* http://github.com/jquery/globalize
*
- * Copyright Software Freedom Conservancy, Inc.
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
* http://jquery.org/license
+ *
+ * Date: 2015-04-23T12:02Z
*/
+/*!
+ * Globalize v1.0.0 2015-04-23T12:02Z Released under the MIT license
+ * http://git.io/TrdQbw
+ */
+(function( root, factory ) {
-(function( window, undefined ) {
-
-var Globalize,
- // private variables
- regexHex,
- regexInfinity,
- regexParseFloat,
- regexTrim,
- // private JavaScript utility functions
- arrayIndexOf,
- endsWith,
- extend,
- isArray,
- isFunction,
- isObject,
- startsWith,
- trim,
- truncate,
- zeroPad,
- // private Globalization utility functions
- appendPreOrPostMatch,
- expandFormat,
- formatDate,
- formatNumber,
- getTokenRegExp,
- getEra,
- getEraYear,
- parseExact,
- parseNegativePattern;
-
-// Global variable (Globalize) or CommonJS module (globalize)
-Globalize = function( cultureSelector ) {
- return new Globalize.prototype.init( cultureSelector );
-};
-
-if ( typeof require !== "undefined" &&
- typeof exports !== "undefined" &&
- typeof module !== "undefined" ) {
- // Assume CommonJS
- module.exports = Globalize;
-} else {
- // Export as global variable
- window.Globalize = Globalize;
-}
+ // UMD returnExports
+ if ( typeof define === "function" && define.amd ) {
-Globalize.cultures = {};
+ // AMD
+ define([
+ "cldr",
+ "cldr/event"
+ ], factory );
+ } else if ( typeof exports === "object" ) {
-Globalize.prototype = {
- constructor: Globalize,
- init: function( cultureSelector ) {
- this.cultures = Globalize.cultures;
- this.cultureSelector = cultureSelector;
+ // Node, CommonJS
+ module.exports = factory( require( "cldrjs" ) );
+ } else {
- return this;
+ // Global
+ root.Globalize = factory( root.Cldr );
}
-};
-Globalize.prototype.init.prototype = Globalize.prototype;
-
-// 1. When defining a culture, all fields are required except the ones stated as optional.
-// 2. 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.
-// 3. 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".
-Globalize.cultures[ "default" ] = {
- // 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
- "-": "-",
- // symbol used for NaN (Not-A-Number)
- "NaN": "NaN",
- // symbol used for Negative Infinity
- negativeInfinity: "-Infinity",
- // symbol used for Positive Infinity
- positiveInfinity: "Infinity",
- 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.
- */
- }
- },
- // For localized strings
- messages: {}
-};
+}( this, function( Cldr ) {
-Globalize.cultures[ "default" ].calendar = Globalize.cultures[ "default" ].calendars.standard;
-Globalize.cultures.en = Globalize.cultures[ "default" ];
+/**
+ * A toString method that outputs meaningful values for objects or arrays and
+ * still performs as fast as a plain string in case variable is string, or as
+ * fast as `"" + number` in case variable is a number.
+ * Ref: http://jsperf.com/my-stringify
+ */
+var toString = function( variable ) {
+ return typeof variable === "string" ? variable : ( typeof variable === "number" ? "" +
+ variable : JSON.stringify( variable ) );
+};
-Globalize.cultureSelector = "en";
-//
-// private variables
-//
-regexHex = /^0x[a-f0-9]+$/i;
-regexInfinity = /^[+\-]?infinity$/i;
-regexParseFloat = /^[+\-]?\d*\.?\d*(e[+\-]?\d+)?$/;
-regexTrim = /^\s+|\s+$/g;
-//
-// private JavaScript utility functions
-//
+/**
+ * formatMessage( message, data )
+ *
+ * @message [String] A message with optional {vars} to be replaced.
+ *
+ * @data [Array or JSON] Object with replacing-variables content.
+ *
+ * Return the formatted message. For example:
+ *
+ * - formatMessage( "{0} second", [ 1 ] ); // 1 second
+ *
+ * - formatMessage( "{0}/{1}", ["m", "s"] ); // m/s
+ *
+ * - formatMessage( "{name} <{email}>", {
+ * name: "Foo",
+ * email: "bar@baz.qux"
+ * }); // Foo <bar@baz.qux>
+ */
+var formatMessage = function( message, data ) {
-arrayIndexOf = function( 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;
-};
+ // Replace {attribute}'s
+ message = message.replace( /{[0-9a-zA-Z-_. ]+}/g, function( name ) {
+ name = name.replace( /^{([^}]*)}$/, "$1" );
+ return toString( data[ name ] );
+ });
-endsWith = function( value, pattern ) {
- return value.substr( value.length - pattern.length ) === pattern;
+ return message;
};
-extend = function() {
- var options, name, src, copy, copyIsArray, clone,
- target = arguments[0] || {},
- i = 1,
- length = arguments.length,
- deep = false;
-
- // Handle a deep copy situation
- if ( typeof target === "boolean" ) {
- deep = target;
- target = arguments[1] || {};
- // skip the boolean and the target
- i = 2;
- }
- // Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !isFunction(target) ) {
- target = {};
- }
- for ( ; i < length; i++ ) {
- // Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null ) {
- // Extend the base object
- for ( name in options ) {
- src = target[ name ];
- copy = options[ name ];
-
- // Prevent never-ending loop
- if ( target === copy ) {
- continue;
- }
-
- // Recurse if we're merging plain objects or arrays
- if ( deep && copy && ( isObject(copy) || (copyIsArray = isArray(copy)) ) ) {
- if ( copyIsArray ) {
- copyIsArray = false;
- clone = src && isArray(src) ? src : [];
-
- } else {
- clone = src && isObject(src) ? src : {};
- }
-
- // Never move original objects, clone them
- target[ name ] = extend( deep, clone, copy );
-
- // Don't bring in undefined values
- } else if ( copy !== undefined ) {
- target[ name ] = copy;
- }
- }
+
+var objectExtend = function() {
+ var destination = arguments[ 0 ],
+ sources = [].slice.call( arguments, 1 );
+
+ sources.forEach(function( source ) {
+ var prop;
+ for ( prop in source ) {
+ destination[ prop ] = source[ prop ];
}
- }
+ });
- // Return the modified object
- return target;
+ return destination;
};
-isArray = Array.isArray || function( obj ) {
- return Object.prototype.toString.call( obj ) === "[object Array]";
-};
-isFunction = function( obj ) {
- return Object.prototype.toString.call( obj ) === "[object Function]";
-};
-isObject = function( obj ) {
- return Object.prototype.toString.call( obj ) === "[object Object]";
-};
-startsWith = function( value, pattern ) {
- return value.indexOf( pattern ) === 0;
-};
+var createError = function( code, message, attributes ) {
+ var error;
-trim = function( value ) {
- return ( value + "" ).replace( regexTrim, "" );
-};
+ message = code + ( message ? ": " + formatMessage( message, attributes ) : "" );
+ error = new Error( message );
+ error.code = code;
-truncate = function( value ) {
- if ( isNaN( value ) ) {
- return NaN;
- }
- return Math[ value < 0 ? "ceil" : "floor" ]( value );
-};
+ objectExtend( error, attributes );
-zeroPad = function( str, count, left ) {
- var l;
- for ( l = str.length; l < count; l += 1 ) {
- str = ( left ? ("0" + str) : (str + "0") );
- }
- return str;
+ return error;
};
-//
-// private Globalization utility functions
-//
-
-appendPreOrPostMatch = function( 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;
-};
-expandFormat = function( 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;
-};
-formatDate = function( value, format, culture ) {
- var cal = culture.calendar,
- convert = cal.convert,
- ret;
-
- if ( !format || !format.length || format === "i" ) {
- 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;
+var validate = function( code, message, check, attributes ) {
+ if ( !check ) {
+ throw createError( code, message, attributes );
}
+};
- 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();
- default:
- throw "Invalid part value " + part;
- }
- }
- 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 );
+var alwaysArray = function( stringOrArray ) {
+ return Array.isArray( stringOrArray ) ? stringOrArray : stringOrArray ? [ stringOrArray ] : [];
+};
- // 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
- var 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 + "\'.";
- }
- }
- return ret.join( "" );
-};
+var validateCldr = function( path, value, options ) {
+ var skipBoolean;
+ options = options || {};
-// formatNumber
-(function() {
- var expandNumber;
+ skipBoolean = alwaysArray( options.skip ).some(function( pathRe ) {
+ return pathRe.test( path );
+ });
- expandNumber = function( number, precision, formatInfo ) {
- var groupSizes = formatInfo.groupSizes,
- curSize = groupSizes[ 0 ],
- curGroupIndex = 1,
- factor = Math.pow( 10, precision ),
- rounded = Math.round( number * factor ) / factor;
+ validate( "E_MISSING_CLDR", "Missing required CLDR content `{path}`.", value || skipBoolean, {
+ path: path
+ });
+};
- 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 ] : "";
-
- 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, true );
- 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) : "" );
+var validateDefaultLocale = function( value ) {
+ validate( "E_DEFAULT_LOCALE_NOT_DEFINED", "Default locale has not been defined.",
+ value !== undefined, {} );
+};
- stringIndex -= curSize;
- if ( curGroupIndex < groupSizes.length ) {
- curSize = groupSizes[ curGroupIndex ];
- curGroupIndex++;
- }
- }
- return numberString.slice( 0, stringIndex + 1 ) + sep + ret + right;
- };
-
- formatNumber = function( value, format, culture ) {
- if ( !isFinite(value) ) {
- if ( value === Infinity ) {
- return culture.numberFormat.positiveInfinity;
- }
- if ( value === -Infinity ) {
- return culture.numberFormat.negativeInfinity;
- }
- return culture.numberFormat.NaN;
- }
- 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";
- number = truncate( number );
- if ( precision !== -1 ) {
- number = zeroPad( "" + number, precision, true );
- }
- if ( value < 0 ) number = "-" + number;
- break;
- case "N":
- formatInfo = nf;
- /* falls through */
- case "C":
- formatInfo = formatInfo || nf.currency;
- /* falls 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;
- }
- }
+var validateParameterPresence = function( value, name ) {
+ validate( "E_MISSING_PARAMETER", "Missing required parameter `{name}`.",
+ value !== undefined, { name: name });
+};
- return ret;
- };
-}());
-getTokenRegExp = function() {
- // 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);
-};
-getEra = function( 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;
+/**
+ * range( value, name, minimum, maximum )
+ *
+ * @value [Number].
+ *
+ * @name [String] name of variable.
+ *
+ * @minimum [Number]. The lowest valid value, inclusive.
+ *
+ * @maximum [Number]. The greatest valid value, inclusive.
+ */
+var validateParameterRange = function( value, name, minimum, maximum ) {
+ validate(
+ "E_PAR_OUT_OF_RANGE",
+ "Parameter `{name}` has value `{value}` out of range [{minimum}, {maximum}].",
+ value === undefined || value >= minimum && value <= maximum,
+ {
+ maximum: maximum,
+ minimum: minimum,
+ name: name,
+ value: value
}
- }
- return 0;
+ );
};
-getEraYear = function( 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;
-};
-// parseExact
-(function() {
- var expandYear,
- getDayIndex,
- getMonthIndex,
- getParseRegExp,
- outOfRange,
- toUpper,
- toUpperArray;
-
- expandYear = function( cal, year ) {
- // expands 2-digit year into 4 digits.
- if ( year < 100 ) {
- var now = new Date(),
- era = getEra( now ),
- curr = getEraYear( now, cal, era ),
- twoDigitYearMax = cal.twoDigitYearMax;
- twoDigitYearMax = typeof twoDigitYearMax === "string" ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax;
- year += curr - ( curr % 100 );
- if ( year > twoDigitYearMax ) {
- year -= 100;
- }
- }
- return year;
- };
-
- getDayIndex = function ( 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;
- };
-
- getMonthIndex = function( 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;
- };
-
- getParseRegExp = function( 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 = "(\\/)";
- break;
- default:
- throw "Invalid date format pattern \'" + m + "\'.";
- }
- 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;
- };
-
- outOfRange = function( value, low, high ) {
- return value < low || value > high;
- };
-
- toUpper = function( value ) {
- // "he-IL" has non-breaking space in weekday names.
- return value.split( "\u00A0" ).join( " " ).toUpperCase();
- };
-
- toUpperArray = function( arr ) {
- var results = [];
- for ( var i = 0, l = arr.length; i < l; i++ ) {
- results[ i ] = toUpper( arr[i] );
- }
- return results;
- };
-
- parseExact = function( 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 );
+
+var validateParameterType = function( value, name, check, expected ) {
+ validate(
+ "E_INVALID_PAR_TYPE",
+ "Invalid `{name}` parameter ({value}). {expected} expected.",
+ check,
+ {
+ expected: expected,
+ name: name,
+ value: value
}
- return result;
- };
-}());
-
-parseNegativePattern = function( value, nf, negativePattern ) {
- var neg = nf[ "-" ],
- pos = nf[ "+" ],
- ret;
- switch ( negativePattern ) {
- case "n -":
- neg = " " + neg;
- pos = " " + pos;
- /* falls 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 += " ";
- /* falls 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 ];
+ );
};
-//
-// public instance functions
-//
-Globalize.prototype.findClosestCulture = function( cultureSelector ) {
- return Globalize.findClosestCulture.call( this, cultureSelector );
-};
-Globalize.prototype.format = function( value, format, cultureSelector ) {
- return Globalize.format.call( this, value, format, cultureSelector );
-};
-Globalize.prototype.localize = function( key, cultureSelector ) {
- return Globalize.localize.call( this, key, cultureSelector );
+var validateParameterTypeLocale = function( value, name ) {
+ validateParameterType(
+ value,
+ name,
+ value === undefined || typeof value === "string" || value instanceof Cldr,
+ "String or Cldr instance"
+ );
};
-Globalize.prototype.parseInt = function( value, radix, cultureSelector ) {
- return Globalize.parseInt.call( this, value, radix, cultureSelector );
-};
-Globalize.prototype.parseFloat = function( value, radix, cultureSelector ) {
- return Globalize.parseFloat.call( this, value, radix, cultureSelector );
-};
-Globalize.prototype.culture = function( cultureSelector ) {
- return Globalize.culture.call( this, cultureSelector );
+
+/**
+ * Function inspired by jQuery Core, but reduced to our use case.
+ */
+var isPlainObject = function( obj ) {
+ return obj !== null && "" + obj === "[object Object]";
};
-//
-// public singleton functions
-//
-
-Globalize.addCultureInfo = function( cultureName, baseCultureName, info ) {
-
- var base = {},
- isNew = false;
-
- if ( typeof cultureName !== "string" ) {
- // cultureName argument is optional string. If not specified, assume info is first
- // and only argument. Specified info deep-extends current culture.
- info = cultureName;
- cultureName = this.culture().name;
- base = this.cultures[ cultureName ];
- } else if ( typeof baseCultureName !== "string" ) {
- // baseCultureName argument is optional string. If not specified, assume info is second
- // argument. Specified info deep-extends specified culture.
- // If specified culture does not exist, create by deep-extending default
- info = baseCultureName;
- isNew = ( this.cultures[ cultureName ] == null );
- base = this.cultures[ cultureName ] || this.cultures[ "default" ];
- } else {
- // cultureName and baseCultureName specified. Assume a new culture is being created
- // by deep-extending an specified base culture
- isNew = true;
- base = this.cultures[ baseCultureName ];
- }
- this.cultures[ cultureName ] = extend(true, {},
- base,
- info
+
+
+var validateParameterTypePlainObject = function( value, name ) {
+ validateParameterType(
+ value,
+ name,
+ value === undefined || isPlainObject( value ),
+ "Plain Object"
);
- // Make the standard calendar the current culture if it's a new culture
- if ( isNew ) {
- this.cultures[ cultureName ].calendar = this.cultures[ cultureName ].calendars.standard;
- }
};
-Globalize.findClosestCulture = function( name ) {
- var match;
- if ( !name ) {
- return this.findClosestCulture( this.cultureSelector ) || this.cultures[ "default" ];
- }
- if ( typeof name === "string" ) {
- 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 );
- pri = isNaN( pri ) ? 0 : pri;
- }
- else {
- pri = 1;
- }
- }
- prioritized.push({ lang: lang, pri: pri });
- }
- prioritized.sort(function( a, b ) {
- if ( a.pri < b.pri ) {
- return 1;
- } else if ( a.pri > b.pri ) {
- return -1;
- }
- return 0;
- });
- // exact match
- for ( i = 0; i < l; i++ ) {
- lang = prioritized[ i ].lang;
- match = cultures[ lang ];
- if ( match ) {
- return match;
- }
- }
- // neutral language match
- for ( i = 0; i < l; i++ ) {
- lang = prioritized[ i ].lang;
- 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 );
- }
- // last resort: match first culture using that language
- for ( i = 0; i < l; i++ ) {
- lang = prioritized[ i ].lang;
- for ( var cultureKey in cultures ) {
- var culture = cultures[ cultureKey ];
- if ( culture.language === lang ) {
- return culture;
- }
- }
- }
- }
- else if ( typeof name === "object" ) {
- return name;
- }
- return match || null;
-};
-Globalize.format = function( value, format, cultureSelector ) {
- var culture = this.findClosestCulture( cultureSelector );
- if ( value instanceof Date ) {
- value = formatDate( value, format, culture );
- }
- else if ( typeof value === "number" ) {
- value = formatNumber( value, format, culture );
- }
- return value;
+var alwaysCldr = function( localeOrCldr ) {
+ return localeOrCldr instanceof Cldr ? localeOrCldr : new Cldr( localeOrCldr );
};
-Globalize.localize = function( key, cultureSelector ) {
- return this.findClosestCulture( cultureSelector ).messages[ key ] ||
- this.cultures[ "default" ].messages[ key ];
-};
-Globalize.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;
+// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FRegular_Expressions
+var regexpEscape = function( string ) {
+ return string.replace( /([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1" );
};
-Globalize.parseInt = function( value, radix, cultureSelector ) {
- return truncate( Globalize.parseFloat(value, radix, cultureSelector) );
-};
-Globalize.parseFloat = function( value, radix, cultureSelector ) {
- // radix argument is optional
- if ( typeof radix !== "number" ) {
- cultureSelector = radix;
- radix = 10;
- }
- var culture = this.findClosestCulture( cultureSelector );
- 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["."] );
+var stringPad = function( str, count, right ) {
+ var length;
+ if ( typeof str !== "string" ) {
+ str = String( str );
}
-
- //Remove percentage character from number string before parsing
- if ( value.indexOf(culture.numberFormat.percent.symbol) > -1){
- value = value.replace( culture.numberFormat.percent.symbol, "" );
+ for ( length = str.length; length < count; length += 1 ) {
+ str = ( right ? ( str + "0" ) : ( "0" + str ) );
}
+ return str;
+};
- // remove spaces: leading, trailing and between - and number. Used for negative currency pt-BR
- value = value.replace( / /g, "" );
- // allow infinity or hexidecimal
- if ( regexInfinity.test(value) ) {
- ret = parseFloat( value );
- }
- else if ( !radix && regexHex.test(value) ) {
- ret = parseInt( value, 16 );
- }
- else {
-
- // determine sign and number
- var signInfo = parseNegativePattern( value, nf, nf.pattern[0] ),
- sign = signInfo[ 0 ],
- num = signInfo[ 1 ];
-
- // #44 - try parsing as "(n)"
- if ( sign === "" && nf.pattern[0] !== "(n)" ) {
- signInfo = parseNegativePattern( value, nf, "(n)" );
- sign = signInfo[ 0 ];
- num = signInfo[ 1 ];
- }
- // try parsing as "-n"
- if ( sign === "" && nf.pattern[0] !== "-n" ) {
- signInfo = parseNegativePattern( value, nf, "-n" );
- sign = signInfo[ 0 ];
- num = signInfo[ 1 ];
- }
- sign = sign || "+";
+function validateLikelySubtags( cldr ) {
+ cldr.once( "get", validateCldr );
+ cldr.get( "supplemental/likelySubtags" );
+}
- // 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 );
- }
+/**
+ * [new] Globalize( locale|cldr )
+ *
+ * @locale [String]
+ *
+ * @cldr [Cldr instance]
+ *
+ * Create a Globalize instance.
+ */
+function Globalize( locale ) {
+ if ( !( this instanceof Globalize ) ) {
+ return new Globalize( locale );
}
- return ret;
+
+ validateParameterPresence( locale, "locale" );
+ validateParameterTypeLocale( locale, "locale" );
+
+ this.cldr = alwaysCldr( locale );
+
+ validateLikelySubtags( this.cldr );
+}
+
+/**
+ * Globalize.load( json, ... )
+ *
+ * @json [JSON]
+ *
+ * Load resolved or unresolved cldr data.
+ * Somewhat equivalent to previous Globalize.addCultureInfo(...).
+ */
+Globalize.load = function() {
+ // validations are delegated to Cldr.load().
+ Cldr.load.apply( Cldr, arguments );
};
-Globalize.culture = function( cultureSelector ) {
- // setter
- if ( typeof cultureSelector !== "undefined" ) {
- this.cultureSelector = cultureSelector;
+/**
+ * Globalize.locale( [locale|cldr] )
+ *
+ * @locale [String]
+ *
+ * @cldr [Cldr instance]
+ *
+ * Set default Cldr instance if locale or cldr argument is passed.
+ *
+ * Return the default Cldr instance.
+ */
+Globalize.locale = function( locale ) {
+ validateParameterTypeLocale( locale, "locale" );
+
+ if ( arguments.length ) {
+ this.cldr = alwaysCldr( locale );
+ validateLikelySubtags( this.cldr );
}
- // getter
- return this.findClosestCulture( cultureSelector ) || this.cultures[ "default" ];
+ return this.cldr;
};
-}( this )); \ No newline at end of file
+/**
+ * Optimization to avoid duplicating some internal functions across modules.
+ */
+Globalize._alwaysArray = alwaysArray;
+Globalize._createError = createError;
+Globalize._formatMessage = formatMessage;
+Globalize._isPlainObject = isPlainObject;
+Globalize._objectExtend = objectExtend;
+Globalize._regexpEscape = regexpEscape;
+Globalize._stringPad = stringPad;
+Globalize._validate = validate;
+Globalize._validateCldr = validateCldr;
+Globalize._validateDefaultLocale = validateDefaultLocale;
+Globalize._validateParameterPresence = validateParameterPresence;
+Globalize._validateParameterRange = validateParameterRange;
+Globalize._validateParameterTypePlainObject = validateParameterTypePlainObject;
+Globalize._validateParameterType = validateParameterType;
+
+return Globalize;
+
+
+
+
+}));
diff --git a/external/localization.js b/external/localization.js
new file mode 100644
index 000000000..95bb3bafe
--- /dev/null
+++ b/external/localization.js
@@ -0,0 +1,115 @@
+(function( root, factory ) {
+
+ // UMD returnExports
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD
+ define( ["globalize-runtime/number","globalize-runtime/date"], factory );
+ } else if ( typeof exports === "object" ) {
+
+ // Node, CommonJS
+ module.exports = factory( require("globalize/dist/globalize-runtime/number"), require("globalize/dist/globalize-runtime/date") );
+ } else {
+
+ // Global
+ factory( root.Globalize );
+ }
+}( this, function( Globalize ) {
+
+var validateParameterTypeNumber = Globalize._validateParameterTypeNumber;
+var validateParameterPresence = Globalize._validateParameterPresence;
+var numberRound = Globalize._numberRound;
+var numberFormat = Globalize._numberFormat;
+var numberFormatterFn = Globalize._numberFormatterFn;
+var validateParameterTypeString = Globalize._validateParameterTypeString;
+var numberParse = Globalize._numberParse;
+var numberParserFn = Globalize._numberParserFn;
+var validateParameterTypeDate = Globalize._validateParameterTypeDate;
+var dateFormat = Globalize._dateFormat;
+var dateFormatterFn = Globalize._dateFormatterFn;
+var dateTokenizer = Globalize._dateTokenizer;
+var dateParse = Globalize._dateParse;
+var dateParserFn = Globalize._dateParserFn;
+
+Globalize.b376385760 = numberFormatterFn(["",,2,,,,,,,,"","00","-00","-","",numberRound(),"∞","NaN",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]);
+Globalize.a1711088039 = numberFormatterFn(["",,1,,,,,,,,"","0","-0","-","",numberRound(),"∞","NaN",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]);
+Globalize.a1916379524 = numberFormatterFn(["",,1,,,,,,,,"","0","-0","-","",numberRound(),"∞","ليس رقم",{".":"٫",",":"٬","%":"٪","+":"‏+","-":"‏-","E":"اس","‰":"؉"},"٠١٢٣٤٥٦٧٨٩"]);
+Globalize.b1256031091 = numberFormatterFn(["",,2,,,,,,,,"","00","-00","-","",numberRound(),"∞","NaN",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]);
+Globalize.b1148906457 = numberFormatterFn(["",,1,,,,,,,,"","0","-0","-","",numberRound(),"∞","NaN",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]);
+Globalize.a126395188 = numberFormatterFn(["",,1,,,,,,,,"","0","-0","-","",numberRound(),"∞","NaN",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]);
+Globalize.b203855544 = numberFormatterFn(["",,2,,,,,,,,"","00","-00","-","",numberRound(),"∞","NaN",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]);
+Globalize.a1378886668 = numberFormatterFn(["",,1,,,,,,,,"","0","-0","-","",numberRound(),"∞","NaN",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]);
+Globalize.b1961282698 = numberParserFn(["∞",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]);
+Globalize.b755631779 = numberParserFn(["∞",{".":"decimal",",":"group","%":"percentSign","+":"plusSign","-":"minusSign","E":"exponential","‰":"perMille","٫":".","٬":",","٪":"%","‏+":"+","‏-":"-","اس":"E","؉":"‰"},"-","",{"0":"invalid","1":"invalid","2":"invalid","3":"invalid","4":"invalid","5":"invalid","6":"invalid","7":"invalid","8":"invalid","9":"invalid","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9"}]);
+Globalize.b2002841143 = numberParserFn(["∞",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]);
+Globalize.a1749351181 = numberParserFn(["∞",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]);
+Globalize.b960923264 = numberParserFn(["∞",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]);
+Globalize.b1965900303 = numberParserFn(["∞",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]);
+Globalize.b2076722823 = numberParserFn(["∞",{".":"decimal",",":"group","%":"percentSign","+":"plusSign","-":"minusSign","E":"exponential","‰":"perMille","٫":".","٬":",","٪":"%","‏+":"+","‏-":"-","اس":"E","؉":"‰"},"-","",{"0":"invalid","1":"invalid","2":"invalid","3":"invalid","4":"invalid","5":"invalid","6":"invalid","7":"invalid","8":"invalid","9":"invalid","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9"}]);
+Globalize.b1293124635 = numberParserFn(["∞",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]);
+Globalize.a474049536 = numberParserFn(["∞",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]);
+Globalize.b1370229258 = numberParserFn(["∞",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]);
+Globalize.a946274711 = dateFormatterFn({}, {"pattern":"EEEEE","timeSeparator":":","days":{"E":{"5":{"sun":"D","mon":"L","tue":"M","wed":"X","thu":"J","fri":"V","sat":"S"}}}});
+Globalize.b1200480509 = dateFormatterFn({}, {"pattern":"MMMM","timeSeparator":":","months":{"M":{"4":{"1":"January","2":"February","3":"March","4":"April","5":"May","6":"June","7":"July","8":"August","9":"September","10":"October","11":"November","12":"December"}}}});
+Globalize.a52764931 = dateFormatterFn({}, {"pattern":"EEEE","timeSeparator":":","days":{"E":{"4":{"sun":"Sunday","mon":"Monday","tue":"Tuesday","wed":"Wednesday","thu":"Thursday","fri":"Friday","sat":"Saturday"}}}});
+Globalize.b617625506 = dateFormatterFn({"1":Globalize("en").numberFormatter({"raw":"0"})}, {"pattern":"c","timeSeparator":":","firstDay":0});
+Globalize.b93641787 = dateFormatterFn({"1":Globalize("en").numberFormatter({"raw":"0"}),"2":Globalize("en").numberFormatter({"raw":"00"})}, {"pattern":"M/d/yy","timeSeparator":":"});
+Globalize.a1636669180 = dateFormatterFn({}, {"pattern":"EEEEE","timeSeparator":":","days":{"E":{"5":{"sun":"S","mon":"M","tue":"T","wed":"W","thu":"T","fri":"F","sat":"S"}}}});
+Globalize.a491609039 = dateFormatterFn({"1":Globalize("zh").numberFormatter({"raw":"0"})}, {"pattern":"y年M月d日EEEE","timeSeparator":":","days":{"E":{"4":{"sun":"星期日","mon":"星期一","tue":"星期二","wed":"星期三","thu":"星期四","fri":"星期五","sat":"星期六"}}}});
+Globalize.b801906653 = dateFormatterFn({}, {"pattern":"EEEEEE","timeSeparator":":","days":{"E":{"6":{"sun":"Su","mon":"Mo","tue":"Tu","wed":"We","thu":"Th","fri":"Fr","sat":"Sa"}}}});
+Globalize.a218160295 = dateFormatterFn({"1":Globalize("en").numberFormatter({"raw":"0"})}, {"pattern":"MMMM d, y","timeSeparator":":","months":{"M":{"4":{"1":"January","2":"February","3":"March","4":"April","5":"May","6":"June","7":"July","8":"August","9":"September","10":"October","11":"November","12":"December"}}}});
+Globalize.a1351587010 = dateFormatterFn({"1":Globalize("zh").numberFormatter({"raw":"0"})}, {"pattern":"y年M月d日","timeSeparator":":"});
+Globalize.b641817676 = dateFormatterFn({"1":Globalize("en").numberFormatter({"raw":"0"})}, {"pattern":"EEEE, MMMM d, y","timeSeparator":":","days":{"E":{"4":{"sun":"Sunday","mon":"Monday","tue":"Tuesday","wed":"Wednesday","thu":"Thursday","fri":"Friday","sat":"Saturday"}}},"months":{"M":{"4":{"1":"January","2":"February","3":"March","4":"April","5":"May","6":"June","7":"July","8":"August","9":"September","10":"October","11":"November","12":"December"}}}});
+Globalize.a864358539 = dateFormatterFn({}, {"pattern":"EEEE","timeSeparator":":","days":{"E":{"4":{"sun":"الأحد","mon":"الاثنين","tue":"الثلاثاء","wed":"الأربعاء","thu":"الخميس","fri":"الجمعة","sat":"السبت"}}}});
+Globalize.a682848010 = dateFormatterFn({"1":Globalize("zh").numberFormatter({"raw":"0"})}, {"pattern":"y/M/d","timeSeparator":":"});
+Globalize.b1382770181 = dateFormatterFn({}, {"pattern":"EEEEEE","timeSeparator":":","days":{"E":{"6":{"sun":"So.","mon":"Mo.","tue":"Di.","wed":"Mi.","thu":"Do.","fri":"Fr.","sat":"Sa."}}}});
+Globalize.b1430109660 = dateFormatterFn({}, {"pattern":"EEEEE","timeSeparator":":","days":{"E":{"5":{"sun":"S","mon":"M","tue":"D","wed":"M","thu":"D","fri":"F","sat":"S"}}}});
+Globalize.a1754951899 = dateFormatterFn({}, {"pattern":"EEEE","timeSeparator":":","days":{"E":{"4":{"sun":"Sonntag","mon":"Montag","tue":"Dienstag","wed":"Mittwoch","thu":"Donnerstag","fri":"Freitag","sat":"Samstag"}}}});
+Globalize.a501706459 = dateFormatterFn({}, {"pattern":"MMMM","timeSeparator":":","months":{"M":{"4":{"1":"Januar","2":"Februar","3":"März","4":"April","5":"Mai","6":"Juni","7":"Juli","8":"August","9":"September","10":"Oktober","11":"November","12":"Dezember"}}}});
+Globalize.b1869521166 = dateFormatterFn({"1":Globalize("de").numberFormatter({"raw":"0"})}, {"pattern":"w","timeSeparator":":","firstDay":1,"minDays":4});
+Globalize.b1252219604 = dateFormatterFn({"1":Globalize("ar").numberFormatter({"raw":"0"})}, {"pattern":"EEEE، d MMMM، y","timeSeparator":":","days":{"E":{"4":{"sun":"الأحد","mon":"الاثنين","tue":"الثلاثاء","wed":"الأربعاء","thu":"الخميس","fri":"الجمعة","sat":"السبت"}}},"months":{"M":{"4":{"1":"يناير","2":"فبراير","3":"مارس","4":"أبريل","5":"مايو","6":"يونيو","7":"يوليو","8":"أغسطس","9":"سبتمبر","10":"أكتوبر","11":"نوفمبر","12":"ديسمبر"}}}});
+Globalize.b1870116986 = dateFormatterFn({"1":Globalize("de").numberFormatter({"raw":"0"})}, {"pattern":"c","timeSeparator":":","firstDay":1});
+Globalize.b674505315 = dateFormatterFn({"2":Globalize("de").numberFormatter({"raw":"00"})}, {"pattern":"dd.MM.yy","timeSeparator":":"});
+Globalize.a1026267252 = dateFormatterFn({}, {"pattern":"EEEEE","timeSeparator":":","days":{"E":{"5":{"sun":"ح","mon":"ن","tue":"ث","wed":"ر","thu":"خ","fri":"ج","sat":"س"}}}});
+Globalize.b285424135 = dateFormatterFn({"1":Globalize("zh").numberFormatter({"raw":"0"})}, {"pattern":"c","timeSeparator":":","firstDay":0});
+Globalize.b388886901 = dateFormatterFn({}, {"pattern":"MMMM","timeSeparator":":","months":{"M":{"4":{"1":"يناير","2":"فبراير","3":"مارس","4":"أبريل","5":"مايو","6":"يونيو","7":"يوليو","8":"أغسطس","9":"سبتمبر","10":"أكتوبر","11":"نوفمبر","12":"ديسمبر"}}}});
+Globalize.a1446348751 = dateFormatterFn({"1":Globalize("de").numberFormatter({"raw":"0"})}, {"pattern":"d. MMMM y","timeSeparator":":","months":{"M":{"4":{"1":"Januar","2":"Februar","3":"März","4":"April","5":"Mai","6":"Juni","7":"Juli","8":"August","9":"September","10":"Oktober","11":"November","12":"Dezember"}}}});
+Globalize.b284828315 = dateFormatterFn({"1":Globalize("zh").numberFormatter({"raw":"0"})}, {"pattern":"w","timeSeparator":":","firstDay":0,"minDays":1});
+Globalize.a586370780 = dateFormatterFn({"1":Globalize("de").numberFormatter({"raw":"0"})}, {"pattern":"EEEE, d. MMMM y","timeSeparator":":","days":{"E":{"4":{"sun":"Sonntag","mon":"Montag","tue":"Dienstag","wed":"Mittwoch","thu":"Donnerstag","fri":"Freitag","sat":"Samstag"}}},"months":{"M":{"4":{"1":"Januar","2":"Februar","3":"März","4":"April","5":"Mai","6":"Juni","7":"Juli","8":"August","9":"September","10":"Oktober","11":"November","12":"Dezember"}}}});
+Globalize.b194087032 = dateFormatterFn({}, {"pattern":"MMMM","timeSeparator":":","months":{"M":{"4":{"1":"一月","2":"二月","3":"三月","4":"四月","5":"五月","6":"六月","7":"七月","8":"八月","9":"九月","10":"十月","11":"十一月","12":"十二月"}}}});
+Globalize.b392241633 = dateFormatterFn({"1":Globalize("ar").numberFormatter({"raw":"0"})}, {"pattern":"d MMMM، y","timeSeparator":":","months":{"M":{"4":{"1":"يناير","2":"فبراير","3":"مارس","4":"أبريل","5":"مايو","6":"يونيو","7":"يوليو","8":"أغسطس","9":"سبتمبر","10":"أكتوبر","11":"نوفمبر","12":"ديسمبر"}}}});
+Globalize.b729298712 = dateFormatterFn({}, {"pattern":"EEEEEE","timeSeparator":":","days":{"E":{"6":{"sun":"DO","mon":"LU","tue":"MA","wed":"MI","thu":"JU","fri":"VI","sat":"SA"}}}});
+Globalize.b617029686 = dateFormatterFn({"1":Globalize("en").numberFormatter({"raw":"0"})}, {"pattern":"w","timeSeparator":":","firstDay":0,"minDays":1});
+Globalize.b1770621176 = dateFormatterFn({}, {"pattern":"EEEE","timeSeparator":":","days":{"E":{"4":{"sun":"domingo","mon":"lunes","tue":"martes","wed":"miércoles","thu":"jueves","fri":"viernes","sat":"sábado"}}}});
+Globalize.a1271100680 = dateFormatterFn({}, {"pattern":"MMMM","timeSeparator":":","months":{"M":{"4":{"1":"enero","2":"febrero","3":"marzo","4":"abril","5":"mayo","6":"junio","7":"julio","8":"agosto","9":"septiembre","10":"octubre","11":"noviembre","12":"diciembre"}}}});
+Globalize.a1150144485 = dateFormatterFn({"1":Globalize("es").numberFormatter({"raw":"0"})}, {"pattern":"w","timeSeparator":":","firstDay":1,"minDays":4});
+Globalize.a1059158408 = dateFormatterFn({}, {"pattern":"EEEE","timeSeparator":":","days":{"E":{"4":{"sun":"星期日","mon":"星期一","tue":"星期二","wed":"星期三","thu":"星期四","fri":"星期五","sat":"星期六"}}}});
+Globalize.a1149548665 = dateFormatterFn({"1":Globalize("es").numberFormatter({"raw":"0"})}, {"pattern":"c","timeSeparator":":","firstDay":1});
+Globalize.b21033846 = dateFormatterFn({"1":Globalize("es").numberFormatter({"raw":"0"}),"2":Globalize("es").numberFormatter({"raw":"00"})}, {"pattern":"d/M/yy","timeSeparator":":"});
+Globalize.b1836232371 = dateFormatterFn({"1":Globalize("ar").numberFormatter({"raw":"0"})}, {"pattern":"d‏/M‏/y","timeSeparator":":"});
+Globalize.b1524871401 = dateFormatterFn({}, {"pattern":"EEEEE","timeSeparator":":","days":{"E":{"5":{"sun":"日","mon":"一","tue":"二","wed":"三","thu":"四","fri":"五","sat":"六"}}}});
+Globalize.b80132650 = dateFormatterFn({"1":Globalize("ar").numberFormatter({"raw":"0"})}, {"pattern":"c","timeSeparator":":","firstDay":6});
+Globalize.b472234174 = dateFormatterFn({"1":Globalize("es").numberFormatter({"raw":"0"})}, {"pattern":"d 'de' MMMM 'de' y","timeSeparator":":","months":{"M":{"4":{"1":"enero","2":"febrero","3":"marzo","4":"abril","5":"mayo","6":"junio","7":"julio","8":"agosto","9":"septiembre","10":"octubre","11":"noviembre","12":"diciembre"}}}});
+Globalize.b25416856 = dateFormatterFn({}, {"pattern":"EEEEEE","timeSeparator":":","days":{"E":{"6":{"sun":"周日","mon":"周一","tue":"周二","wed":"周三","thu":"周四","fri":"周五","sat":"周六"}}}});
+Globalize.b1332212145 = dateFormatterFn({"1":Globalize("es").numberFormatter({"raw":"0"})}, {"pattern":"EEEE, d 'de' MMMM 'de' y","timeSeparator":":","days":{"E":{"4":{"sun":"domingo","mon":"lunes","tue":"martes","wed":"miércoles","thu":"jueves","fri":"viernes","sat":"sábado"}}},"months":{"M":{"4":{"1":"enero","2":"febrero","3":"marzo","4":"abril","5":"mayo","6":"junio","7":"julio","8":"agosto","9":"septiembre","10":"octubre","11":"noviembre","12":"diciembre"}}}});
+Globalize.b79536830 = dateFormatterFn({"1":Globalize("ar").numberFormatter({"raw":"0"})}, {"pattern":"w","timeSeparator":":","firstDay":6,"minDays":1});
+Globalize.a1750470059 = dateFormatterFn({}, {"pattern":"EEEEEE","timeSeparator":":","days":{"E":{"6":{"sun":"الأحد","mon":"الاثنين","tue":"الثلاثاء","wed":"الأربعاء","thu":"الخميس","fri":"الجمعة","sat":"السبت"}}}});
+Globalize.a1915997694 = dateParserFn(Globalize("es").numberParser({"raw":"0"}), {"preferredTimeData":"H"}, {"pattern":"EEEE, d 'de' MMMM 'de' y","timeSeparator":":","gregorian/days/format/wide":{"sun":"domingo","mon":"lunes","tue":"martes","wed":"miércoles","thu":"jueves","fri":"viernes","sat":"sábado"},"gregorian/months/format/wide":{"1":"enero","2":"febrero","3":"marzo","4":"abril","5":"mayo","6":"junio","7":"julio","8":"agosto","9":"septiembre","10":"octubre","11":"noviembre","12":"diciembre"}});
+Globalize.a1889223355 = dateParserFn(Globalize("es").numberParser({"raw":"0"}), {"preferredTimeData":"H"}, {"pattern":"d/M/yy","timeSeparator":":"});
+Globalize.a74024830 = dateParserFn(Globalize("ar").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"d‏/M‏/y","timeSeparator":":"});
+Globalize.b460386677 = dateParserFn(Globalize("de").numberParser({"raw":"0"}), {"preferredTimeData":"H"}, {"pattern":"EEEE, d. MMMM y","timeSeparator":":","gregorian/days/format/wide":{"sun":"Sonntag","mon":"Montag","tue":"Dienstag","wed":"Mittwoch","thu":"Donnerstag","fri":"Freitag","sat":"Samstag"},"gregorian/months/format/wide":{"1":"Januar","2":"Februar","3":"März","4":"April","5":"Mai","6":"Juni","7":"Juli","8":"August","9":"September","10":"Oktober","11":"November","12":"Dezember"}});
+Globalize.a399591294 = dateParserFn(Globalize("de").numberParser({"raw":"0"}), {"preferredTimeData":"H"}, {"pattern":"d. MMMM y","timeSeparator":":","gregorian/months/format/wide":{"1":"Januar","2":"Februar","3":"März","4":"April","5":"Mai","6":"Juni","7":"Juli","8":"August","9":"September","10":"Oktober","11":"November","12":"Dezember"}});
+Globalize.b1438999090 = dateParserFn(Globalize("ar").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"d MMMM، y","timeSeparator":":","gregorian/months/format/wide":{"1":"يناير","2":"فبراير","3":"مارس","4":"أبريل","5":"مايو","6":"يونيو","7":"يوليو","8":"أغسطس","9":"سبتمبر","10":"أكتوبر","11":"نوفمبر","12":"ديسمبر"}});
+Globalize.a1235751886 = dateParserFn(Globalize("de").numberParser({"raw":"0"}), {"preferredTimeData":"H"}, {"pattern":"dd.MM.yy","timeSeparator":":"});
+Globalize.b1518991631 = dateParserFn(Globalize("es").numberParser({"raw":"0"}), {"preferredTimeData":"H"}, {"pattern":"d 'de' MMMM 'de' y","timeSeparator":":","gregorian/months/format/wide":{"1":"enero","2":"febrero","3":"marzo","4":"abril","5":"mayo","6":"junio","7":"julio","8":"agosto","9":"septiembre","10":"octubre","11":"noviembre","12":"diciembre"}});
+Globalize.b1701862085 = dateParserFn(Globalize("zh").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"y/M/d","timeSeparator":":"});
+Globalize.b1688575133 = dateParserFn(Globalize("en").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"EEEE, MMMM d, y","timeSeparator":":","gregorian/days/format/wide":{"sun":"Sunday","mon":"Monday","tue":"Tuesday","wed":"Wednesday","thu":"Thursday","fri":"Friday","sat":"Saturday"},"gregorian/months/format/wide":{"1":"January","2":"February","3":"March","4":"April","5":"May","6":"June","7":"July","8":"August","9":"September","10":"October","11":"November","12":"December"}});
+Globalize.b828597162 = dateParserFn(Globalize("en").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"MMMM d, y","timeSeparator":":","gregorian/months/format/wide":{"1":"January","2":"February","3":"March","4":"April","5":"May","6":"June","7":"July","8":"August","9":"September","10":"October","11":"November","12":"December"}});
+Globalize.a304829553 = dateParserFn(Globalize("zh").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"y年M月d日","timeSeparator":":"});
+Globalize.a1816615414 = dateParserFn(Globalize("en").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"M/d/yy","timeSeparator":":"});
+Globalize.b555148418 = dateParserFn(Globalize("zh").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"y年M月d日EEEE","timeSeparator":":","gregorian/days/format/wide":{"sun":"星期日","mon":"星期一","tue":"星期二","wed":"星期三","thu":"星期四","fri":"星期五","sat":"星期六"}});
+Globalize.a1995990235 = dateParserFn(Globalize("ar").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"EEEE، d MMMM، y","timeSeparator":":","gregorian/days/format/wide":{"sun":"الأحد","mon":"الاثنين","tue":"الثلاثاء","wed":"الأربعاء","thu":"الخميس","fri":"الجمعة","sat":"السبت"},"gregorian/months/format/wide":{"1":"يناير","2":"فبراير","3":"مارس","4":"أبريل","5":"مايو","6":"يونيو","7":"يوليو","8":"أغسطس","9":"سبتمبر","10":"أكتوبر","11":"نوفمبر","12":"ديسمبر"}});
+
+return Globalize;
+
+}));
diff --git a/package.json b/package.json
index 61fbf13f8..7bd301b61 100644
--- a/package.json
+++ b/package.json
@@ -52,7 +52,9 @@
},
"dependencies": {},
"devDependencies": {
+ "cldr-data": ">=26",
"commitplease": "2.0.0",
+ "globalize-compiler": "0.1.1",
"grunt": "0.4.2",
"grunt-bowercopy": "1.1.0",
"grunt-compare-size": "0.4.0",
diff --git a/tests/lib/bootstrap.js b/tests/lib/bootstrap.js
index 4e374ac27..96b707f96 100644
--- a/tests/lib/bootstrap.js
+++ b/tests/lib/bootstrap.js
@@ -2,8 +2,11 @@
requirejs.config( {
paths: {
- "globalize": "../../../external/globalize/globalize",
- "globalize/ja-JP": "../../../external/globalize/globalize.culture.ja-JP",
+ "cldr": "../../../external/cldrjs/cldr",
+ "globalize-runtime": "../../../external/globalize/globalize-runtime",
+ "globalize-locales": "../../../external/localization",
+ "globalize-old": "../../../external/globalize-old/globalize",
+ "globalize-old/ja-JP": "../../../external/globalize-old/globalize.culture.ja-JP",
"jquery": jqueryUrl(),
"jquery-simulate": "../../../external/jquery-simulate/jquery.simulate",
"jshint": "../../../external/jshint/jshint",
@@ -15,8 +18,14 @@ requirejs.config( {
"testswarm": "http://swarm.jquery.org/js/inject.js?" + ( new Date() ).getTime(),
"ui": "../../../ui"
},
+ map: {
+ "*": {
+ "globalize": "globalize-runtime"
+ }
+ },
shim: {
- "globalize/ja-JP": [ "globalize" ],
+ "ui/date": [ "globalize-locales" ],
+ "globalize-old/ja-JP": [ "globalize-old" ],
"jquery-simulate": [ "jquery" ],
"qunit-assert-close": [ "qunit" ],
"testswarm": [ "qunit" ]
diff --git a/tests/unit/all.html b/tests/unit/all.html
index c8352615a..f06dad6d9 100644
--- a/tests/unit/all.html
+++ b/tests/unit/all.html
@@ -20,6 +20,7 @@
"autocomplete/autocomplete.html",
"button/button.html",
"core/core.html",
+ "calendar/calendar.html",
"datepicker/datepicker.html",
"dialog/dialog.html",
"draggable/draggable.html",
diff --git a/tests/unit/calendar/all.html b/tests/unit/calendar/all.html
new file mode 100644
index 000000000..65f71988b
--- /dev/null
+++ b/tests/unit/calendar/all.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Calendar Test Suite</title>
+
+ <script src="../../../external/jquery/jquery.js"></script>
+
+ <link rel="stylesheet" href="../../../external/qunit/qunit.css">
+ <link rel="stylesheet" href="../../../external/qunit-composite/qunit-composite.css">
+ <script src="../../../external/qunit/qunit.js"></script>
+ <script src="../../../external/qunit-composite/qunit-composite.js"></script>
+ <script src="../subsuite.js"></script>
+
+ <script>
+ testAllVersions( "calendar" );
+ </script>
+</head>
+<body>
+
+<div id="qunit"></div>
+<div id="qunit-fixture">
+
+</div>
+</body>
+</html>
diff --git a/tests/unit/calendar/calendar.html b/tests/unit/calendar/calendar.html
new file mode 100644
index 000000000..1cd3e8051
--- /dev/null
+++ b/tests/unit/calendar/calendar.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Calendar Test Suite</title>
+
+ <script src="../../../external/requirejs/require.js"></script>
+ <script src="../../lib/css.js" data-modules="core calendar"></script>
+ <script src="../../lib/bootstrap.js" data-widget="calendar"></script>
+</head>
+<body>
+
+<div id="qunit"></div>
+<div id="qunit-fixture">
+
+<div id="calendar"></div>
+<div id="calendar2"></div>
+
+</div>
+</body>
+</html>
diff --git a/tests/unit/calendar/common.js b/tests/unit/calendar/common.js
new file mode 100644
index 000000000..8b8f40f73
--- /dev/null
+++ b/tests/unit/calendar/common.js
@@ -0,0 +1,33 @@
+define( [
+ "lib/common",
+ "ui/widgets/calendar",
+ "globalize-locales"
+], function( common ) {
+
+common.testWidget( "calendar", {
+ defaults: {
+ buttons: [],
+ classes: {},
+ disabled: false,
+ dateFormat: { date: "short" },
+ eachDay: $.noop,
+ labels: {
+ "datePickerRole": "date picker",
+ "nextText": "Next",
+ "prevText": "Prev",
+ "weekHeader": "Wk"
+ },
+ locale: "en",
+ max: null,
+ min: null,
+ numberOfMonths: 1,
+ showWeek: false,
+ value: null,
+
+ // callbacks
+ create: null,
+ select: null
+ }
+} );
+
+} );
diff --git a/tests/unit/calendar/core.js b/tests/unit/calendar/core.js
new file mode 100644
index 000000000..b9c5836a1
--- /dev/null
+++ b/tests/unit/calendar/core.js
@@ -0,0 +1,393 @@
+define( [
+ "jquery",
+ "./helper",
+ "ui/widgets/calendar"
+], function( $, testHelper ) {
+
+module( "calendar: core" );
+
+test( "base structure", function() {
+ expect( 26 );
+
+ var header, title, table, thead, week, child, buttonpane,
+ element = $( "#calendar" ).calendar(),
+ dp = element.calendar( "widget" );
+
+ function step1() {
+ ok( !dp.is( ".ui-calendar-rtl" ), "Structure - not right-to-left" );
+ ok( !dp.is( ".ui-calendar-multi" ), "Structure - not multi-month" );
+ equal( dp.children().length, 2, "Structure - child count (header, calendar)" );
+
+ header = dp.children( ":first" );
+ ok( header.is( "div.ui-calendar-header" ), "Structure - header division" );
+ equal( header.children().length, 3, "Structure - header child count" );
+ ok( header.children( ":first" ).is( ".ui-calendar-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" );
+ ok( header.children( ":eq(1)" ).is( ".ui-calendar-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" );
+
+ title = header.children( ":last" ).children( ":first" );
+ ok( title.is( "div.ui-calendar-title" ) && title.html() !== "", "Structure - title division" );
+ equal( title.children().length, 2, "Structure - title child count" );
+ ok( title.children( ":first" ).is( "span.ui-calendar-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" );
+ ok( title.children( ":last" ).is( "span.ui-calendar-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" );
+
+ table = dp.children( ":eq(1)" );
+ ok( table.is( "table.ui-calendar-calendar" ), "Structure - month table" );
+ ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" );
+
+ thead = table.children( ":first" ).children( ":first" );
+ ok( thead.is( "tr" ), "Structure - month table title row" );
+ equal( thead.find( "th" ).length, 7, "Structure - month table title cells" );
+ ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" );
+ ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" );
+
+ week = table.children( ":eq(1)" ).children( ":first" );
+ ok( week.is( "tr" ), "Structure - month table week row" );
+ equal( week.children().length, 7, "Structure - week child count" );
+
+ step2();
+ }
+
+ function step2() {
+ element.calendar( "option", "buttons", {
+ "test": function() {},
+ "test button": function() {}
+ } );
+
+ equal( dp.children().length, 3, "Structure buttons - child count (header, calendar, buttonpane)" );
+
+ buttonpane = dp.children( ".ui-calendar-buttonpane" );
+ equal( buttonpane.children( "div.ui-calendar-buttonset" ).length, 1, "Structure buttons - buttonset" );
+ equal( buttonpane.find( "button.ui-button:first" ).text(), "test", "Structure buttons - buttonset" );
+ equal( buttonpane.find( "button.ui-button:eq(1)" ).text(), "test button", "Structure buttons - buttonset" );
+
+ element.calendar( "destroy" );
+ step3();
+ }
+
+ function step3() {
+
+ // Multi-month 2
+ element = $( "#calendar" ).calendar( { numberOfMonths: 2 } );
+ dp = element.calendar( "widget" );
+
+ ok( dp.is( ".ui-calendar-multi" ), "Structure multi [2] - multi-month" );
+ equal( dp.children().length, 3, "Structure multi [2] - child count" );
+
+ child = dp.children( ":eq(2)" );
+ ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2] - row break" );
+
+ element.calendar( "destroy" );
+ }
+
+ step1();
+} );
+
+test( "Localization", function() {
+ expect( 10 );
+
+ var element = $( "#calendar" ),
+ date = new Date( 2014, 0, 1 ),
+ optionsDe = {
+ locale: "de",
+ labels: {
+ "nextText": "Vor",
+ "prevText": "Zurück"
+ }
+ },
+ initCalendar = function( options ) {
+ element
+ .calendar( options )
+ .calendar( "valueAsDate", date );
+ },
+ testLocalization = function( message ) {
+ equal(
+ element.find( ".ui-calendar-month" ).text(),
+ "Januar", message + "titlebar year"
+ );
+ equal(
+ element.find( "thead th:first" ).text(),
+ "Mo.", message + "teader first day"
+ );
+ equal(
+ element.find( "thead th:last" ).text(),
+ "So.", message + "header last day"
+ );
+ equal(
+ element.find( ".ui-calendar-prev" ).text(),
+ "Zurück", message + "header prev"
+ );
+ equal(
+ element.find( ".ui-calendar-next" ).text(),
+ "Vor", message + "header next"
+ );
+ };
+
+ initCalendar( optionsDe );
+ testLocalization( "Init: " );
+ element.calendar( "destroy" );
+
+ initCalendar( {} );
+ element
+ .calendar( "option", optionsDe )
+ .calendar( "refresh" );
+ testLocalization( "After init: " );
+} );
+
+asyncTest( "keyboard handling", function() {
+ expect( 10 );
+
+ var element = $( "#calendar" );
+
+ function step1() {
+ element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } );
+
+ testHelper
+ .focusGrid( element )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
+ setTimeout( function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2013, 12 - 1, 31 ),
+ "Keystroke left to switch to previous day"
+ );
+ element.calendar( "destroy" );
+ step2();
+ }, 50 );
+ }
+
+ function step2() {
+ element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } );
+
+ testHelper.focusGrid( element )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2014, 1 - 1, 2 ),
+ "Keystroke right to switch to next day"
+ );
+ step3();
+ }
+
+ function step3() {
+ element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } );
+
+ testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
+ setTimeout( function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2013, 12 - 1, 25 ),
+ "Keystroke up to move to the previous week"
+ );
+ element.calendar( "destroy" );
+ step4();
+ }, 50 );
+ }
+
+ function step4() {
+ element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } );
+
+ testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+ setTimeout( function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2014, 1 - 1, 8 ),
+ "Keystroke down to move to the next week"
+ );
+ element.calendar( "destroy" );
+ step5();
+ }, 50 );
+ }
+
+ function step5() {
+ element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } );
+
+ testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
+ setTimeout( function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2013, 12 - 1, 1 ),
+ "Keystroke Page Up moves date to previous month"
+ );
+ element.calendar( "destroy" );
+ step6();
+ }, 50 );
+ }
+
+ function step6() {
+ element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } );
+
+ testHelper.focusGrid( element )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } );
+ setTimeout( function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2013, 1 - 1, 1 ),
+ "Keystroke Page Up + ALT moves date to previous year"
+ );
+ element.calendar( "destroy" );
+ step7();
+ }, 50 );
+ }
+
+ function step7() {
+ element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } );
+
+ testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
+ setTimeout( function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2014, 2 - 1, 1 ),
+ "Keystroke Page Down moves date to next month"
+ );
+ element.calendar( "destroy" );
+ step8();
+ }, 50 );
+ }
+
+ function step8() {
+ element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } );
+
+ testHelper.focusGrid( element )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } );
+ setTimeout( function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2015, 1 - 1, 1 ),
+ "Keystroke Page Down + ALT moves date to next year"
+ );
+ element.calendar( "destroy" );
+ step9();
+ }, 50 );
+ }
+
+ // Check for moving to short months
+ function step9() {
+ element.calendar( { value: new Date( 2014, 3 - 1, 31 ) } );
+
+ testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
+ setTimeout( function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2014, 2 - 1, 28 ),
+ "Keystroke Page Up and short months"
+ );
+ element.calendar( "destroy" );
+ step10();
+ }, 50 );
+ }
+
+ function step10() {
+ element.calendar( { value: new Date( 2016, 1 - 1, 30 ) } );
+
+ testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
+ setTimeout( function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2016, 2 - 1, 29 ),
+ "Keystroke Page Down and leap years"
+ );
+ element.calendar( "destroy" );
+ start();
+ }, 50 );
+ }
+
+ step1();
+} );
+
+asyncTest( "mouse", function() {
+ expect( 6 );
+
+ var element = $( "#calendar" ).calendar(),
+ date = new Date();
+
+ function step1() {
+ $( "tbody button:contains(10)", element ).simulate( "mousedown" );
+ date.setDate( 10 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date,
+ "Mouse click"
+ );
+
+ element.calendar( "option", "value", new Date( 2008, 2 - 1, 4 ) );
+ $( ".ui-calendar-calendar tbody button:contains(12)", element ).simulate( "mousedown" );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2008, 2 - 1, 12 ),
+ "Mouse click - preset"
+ );
+
+ // Previous/next
+ element.calendar( "option", "value", new Date( 2008, 2 - 1, 4 ) );
+ $( ".ui-calendar-prev", element ).simulate( "click" );
+ $( ".ui-calendar-calendar tbody button:contains(16)", element ).simulate( "mousedown" );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2008, 1 - 1, 16 ),
+ "Mouse click - previous"
+ );
+
+ element.calendar( "option", "value", new Date( 2008, 2 - 1, 4 ) );
+ $( ".ui-calendar-next", element ).simulate( "click" );
+ $( ".ui-calendar-calendar tbody button:contains(18)", element ).simulate( "mousedown" );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2008, 3 - 1, 18 ),
+ "Mouse click - next"
+ );
+
+ step2();
+ }
+
+ // Previous/next with minimum/maximum
+ function step2() {
+ element.calendar( "destroy" );
+ element.calendar( {
+ value: new Date( 2008, 3 - 1, 4 ),
+ min: new Date( 2008, 2 - 1, 2 ),
+ max: new Date( 2008, 2 - 1, 26 )
+ } );
+
+ $( ".ui-calendar-prev", element ).simulate( "click" );
+ $( "tbody button:contains(16)", element ).simulate( "mousedown" );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2008, 2 - 1, 16 ),
+ "Mouse click - previous + min/max"
+ );
+ step3();
+ }
+
+ function step3() {
+ element.calendar( "destroy" );
+ element.calendar( {
+ value: new Date( 2008, 1 - 1, 4 ),
+ min: new Date( 2008, 2 - 1, 2 ),
+ max: new Date( 2008, 2 - 1, 26 )
+ } );
+
+ $( ".ui-calendar-next", element ).simulate( "click" );
+ $( "tbody button:contains(18)", element ).simulate( "mousedown" );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ new Date( 2008, 2 - 1, 18 ),
+ "Mouse click - next + min/max"
+ );
+ start();
+ }
+
+ step1();
+} );
+
+} );
diff --git a/tests/unit/calendar/events.js b/tests/unit/calendar/events.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/unit/calendar/events.js
diff --git a/tests/unit/calendar/helper.js b/tests/unit/calendar/helper.js
new file mode 100644
index 000000000..a82e96705
--- /dev/null
+++ b/tests/unit/calendar/helper.js
@@ -0,0 +1,31 @@
+define( [
+ "jquery",
+ "lib/helper"
+], function( $, helper ) {
+
+return $.extend( helper, {
+ addMonths: function( date, offset ) {
+ var maxDay = 32 - new Date( date.getFullYear(), date.getMonth() + offset, 32 ).getDate();
+ date.setDate( Math.min( date.getDate(), maxDay ) );
+ date.setMonth( date.getMonth() + offset );
+ return date;
+ },
+ equalsDate: function( d1, d2, message ) {
+ if ( !d1 || !d2 ) {
+ ok( false, message + " - missing date" );
+ return;
+ }
+ d1 = new Date( d1.getFullYear(), d1.getMonth(), d1.getDate() );
+ d2 = new Date( d2.getFullYear(), d2.getMonth(), d2.getDate() );
+ equal( d1.toString(), d2.toString(), message );
+ },
+ focusGrid: function( element ) {
+ element.find( ":tabbable" ).last().simulate( "focus" );
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } );
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } );
+
+ return $( document.activeElement );
+ }
+} );
+
+} );
diff --git a/tests/unit/calendar/methods.js b/tests/unit/calendar/methods.js
new file mode 100644
index 000000000..84e265710
--- /dev/null
+++ b/tests/unit/calendar/methods.js
@@ -0,0 +1,145 @@
+define( [
+ "jquery",
+ "./helper",
+ "ui/widgets/calendar"
+], function( $, testHelper ) {
+
+module( "calendar: methods" );
+
+test( "destroy", function( assert ) {
+ expect( 1 );
+
+ assert.domEqual( "#calendar", function() {
+ $( "#calendar" ).calendar().calendar( "destroy" );
+ } );
+} );
+
+test( "enable / disable", function() {
+ expect( 8 );
+
+ var element = $( "#calendar" ).calendar();
+
+ element.calendar( "disable" );
+ ok( element.calendar( "option", "disabled" ), "disabled option is set" );
+ ok( element.hasClass( "ui-calendar-disabled" ), "has disabled widget class name" );
+ ok( element.hasClass( "ui-state-disabled" ), "has disabled state class name" );
+ equal( element.attr( "aria-disabled" ), "true", "has ARIA disabled" );
+
+ element.calendar( "enable" );
+ ok( !element.calendar( "option", "disabled" ), "enabled after enable() call" );
+ ok( !element.hasClass( "ui-calendar-disabled" ), "no longer has disabled widget class name" );
+ ok( !element.hasClass( "ui-state-disabled" ), "no longer has disabled state class name" );
+ equal( element.attr( "aria-disabled" ), "false", "no longer has ARIA disabled" );
+} );
+
+test( "widget", function() {
+ expect( 1 );
+
+ var element = $( "#calendar" ).calendar(),
+ widget = element.calendar( "widget" );
+
+ strictEqual( widget[ 0 ], element[ 0 ] );
+} );
+
+test( "value", function() {
+ expect( 3 );
+ var element = $( "#calendar" ).calendar();
+
+ element.calendar( "value", "1/1/14" );
+ ok( element.find( "button[data-timestamp]:first" )
+ .hasClass( "ui-state-active" ),
+ "first day marked as selected"
+ );
+ equal( element.calendar( "value" ), "1/1/14", "getter" );
+
+ element.calendar( "value", "abc" );
+ equal( element.calendar( "value" ), "1/1/14", "Setting invalid values should be ignored." );
+} );
+
+test( "valueAsDate", function() {
+ expect( 11 );
+
+ var minDate, maxDate, dateAndTimeToSet, dateAndTimeClone,
+ element = $( "#calendar" ).calendar(),
+ date1 = new Date( 2008, 6 - 1, 4 ),
+ date2;
+
+ element.calendar( "valueAsDate", new Date( 2014, 0, 1 ) );
+ ok( element.find( "button[data-timestamp]:first" )
+ .hasClass( "ui-state-active" ),
+ "First day marked as selected"
+ );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" );
+
+ element.calendar( "destroy" );
+
+ element.calendar();
+ equal( element.calendar( "valueAsDate" ), null, "Set date - default" );
+
+ element.calendar( "valueAsDate", date1 );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), date1, "Set date - 2008-06-04" );
+
+ // With minimum/maximum
+ element = $( "#calendar" ).calendar();
+ date1 = new Date( 2008, 1 - 1, 4 );
+ date2 = new Date( 2008, 6 - 1, 4 );
+ minDate = new Date( 2008, 2 - 1, 29 );
+ maxDate = new Date( 2008, 3 - 1, 28 );
+
+ element
+ .calendar( "option", { min: minDate } )
+ .calendar( "valueAsDate", date2 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date2, "Set date min/max - value > min"
+ );
+
+ element.calendar( "valueAsDate", date1 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date2,
+ "Set date min/max - value < min"
+ );
+
+ element
+ .calendar( "option", { max: maxDate, min: null } )
+ .calendar( "valueAsDate", date1 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date1,
+ "Set date min/max - value < max"
+ );
+
+ element.calendar( "valueAsDate", date2 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date1,
+ "Set date min/max - value > max"
+ );
+
+ element
+ .calendar( "option", { min: minDate } )
+ .calendar( "valueAsDate", date1 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date1,
+ "Set date min/max - value < min"
+ );
+
+ element.calendar( "valueAsDate", date2 );
+ testHelper.equalsDate(
+ element.calendar( "valueAsDate" ),
+ date1, "Set date min/max - value > max"
+ );
+
+ dateAndTimeToSet = new Date( 2008, 3 - 1, 28, 1, 11, 0 );
+ dateAndTimeClone = new Date( 2008, 3 - 1, 28, 1, 11, 0 );
+ element.calendar( "valueAsDate", dateAndTimeToSet );
+ equal(
+ dateAndTimeToSet.getTime(),
+ dateAndTimeClone.getTime(),
+ "Date object passed should not be changed by valueAsDate"
+ );
+} );
+
+} );
diff --git a/tests/unit/calendar/options.js b/tests/unit/calendar/options.js
new file mode 100644
index 000000000..4c9c1f15d
--- /dev/null
+++ b/tests/unit/calendar/options.js
@@ -0,0 +1,401 @@
+define( [
+ "jquery",
+ "./helper",
+ "ui/widgets/calendar"
+], function( $, testHelper ) {
+
+module( "calendar: options" );
+
+test( "buttons", function() {
+ expect( 21 );
+
+ var button, i, newButtons,
+ buttons = {
+ "Ok": function( event ) {
+ ok( true, "button click fires callback" );
+ equal( this, element[ 0 ], "context of callback" );
+ equal( event.target, button[ 0 ], "event target" );
+ },
+ "Cancel": function( event ) {
+ ok( true, "button click fires callback" );
+ equal( this, element[ 0 ], "context of callback" );
+ equal( event.target, button[ 1 ], "event target" );
+ }
+ },
+ element = $( "#calendar" ).calendar( { buttons: buttons } );
+
+ button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" );
+ equal( button.length, 2, "number of buttons" );
+
+ i = 0;
+ $.each( buttons, function( key ) {
+ equal( button.eq( i ).text(), key, "text of button " + ( i + 1 ) );
+ i++;
+ } );
+
+ ok( button.parent().hasClass( "ui-calendar-buttonset" ), "buttons in container" );
+ ok(
+ element.calendar( "widget" ).hasClass( "ui-calendar-buttons" ),
+ "calendar wrapper adds class about having buttons"
+ );
+
+ button.trigger( "click" );
+
+ newButtons = {
+ "Close": function( event ) {
+ ok( true, "button click fires callback" );
+ equal( this, element[ 0 ], "context of callback" );
+ equal( event.target, button[ 0 ], "event target" );
+ }
+ };
+
+ deepEqual(
+ element.calendar( "option", "buttons" ),
+ buttons,
+ ".calendar('option', 'buttons') getter"
+ );
+ element.calendar( "option", "buttons", newButtons );
+ deepEqual(
+ element.calendar( "option", "buttons" ),
+ newButtons,
+ ".calendar('option', 'buttons', ...) setter"
+ );
+
+ button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" );
+ equal( button.length, 1, "number of buttons after setter" );
+ button.trigger( "click" );
+
+ i = 0;
+ $.each( newButtons, function( key ) {
+ equal( button.eq( i ).text(), key, "text of button " + ( i + 1 ) );
+ i += 1;
+ } );
+
+ element.calendar( "option", "buttons", null );
+ button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" );
+ equal( button.length, 0, "all buttons have been removed" );
+ equal( element.find( ".ui-calendar-buttonset" ).length, 0, "buttonset has been removed" );
+ equal( element.hasClass( "ui-calendar-buttons" ), false, "calendar element removes class about having buttons" );
+
+ element.remove();
+} );
+
+test( "buttons - advanced", function() {
+ expect( 7 );
+
+ var buttons,
+ element = $( "#calendar" ).calendar( {
+ buttons: [ {
+ text: "a button",
+ "class": "additional-class",
+ id: "my-button-id",
+ click: function() {
+ equal( this, element[ 0 ], "correct context" );
+ },
+ icons: {
+ primary: "ui-icon-cancel"
+ },
+ showText: false
+ } ]
+ } );
+
+ buttons = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" );
+ equal( buttons.length, 1, "correct number of buttons" );
+ equal( buttons.attr( "id" ), "my-button-id", "correct id" );
+ equal ( buttons.text(), "a button", "correct label" );
+ ok( buttons.hasClass( "additional-class" ), "additional classes added" );
+ deepEqual( buttons.button( "option", "icons" ), { primary: "ui-icon-cancel", secondary: null } );
+ equal( buttons.button( "option", "text" ), false );
+ buttons.click();
+
+ element.remove();
+} );
+
+test( "dateFormat", function() {
+ expect( 2 );
+ var element = $( "#calendar" ).calendar();
+
+ element.calendar( "value", "1/1/14" );
+
+ element.calendar( "widget" ).find( "td[id]:first button" ).trigger( "mousedown" );
+ equal( element.calendar( "value" ), "1/1/14", "default formatting" );
+
+ element.calendar( "option", "dateFormat", { date: "full" } );
+ equal( element.calendar( "value" ), "Wednesday, January 1, 2014", "updated formatting" );
+} );
+
+test( "eachDay", function() {
+ expect( 5 );
+ var timestamp,
+ input = $( "#calendar" ).calendar(),
+ picker = input.calendar( "widget" ),
+ firstCell = picker.find( "td[id]:first" );
+
+ equal( firstCell.find( "button" ).length, 1, "days are selectable by default" );
+ timestamp = parseInt( firstCell.find( "button" ).attr( "data-timestamp" ), 10 );
+ equal( new Date( timestamp ).getDate(), 1, "first available day is the 1st by default" );
+
+ // Do not render the 1st of the month
+ input.calendar( "option", "eachDay", function( day ) {
+ if ( day.date === 1 ) {
+ day.render = false;
+ }
+ } );
+ firstCell = picker.find( "td[id]:first" );
+ timestamp = parseInt( firstCell.find( "button" ).attr( "data-timestamp" ), 10 );
+ equal( new Date( timestamp ).getDate(), 2, "first available day is the 2nd" );
+
+ // Display the 1st of the month but make it not selectable.
+ input.calendar( "option", "eachDay", function( day ) {
+ if ( day.date === 1 ) {
+ day.selectable = false;
+ }
+ } );
+ firstCell = picker.find( "td[id]:first" );
+ ok( firstCell.find( "button" ).prop( "disabled" ), "the 1st is not selectable" );
+
+ input.calendar( "option", "eachDay", function( day ) {
+ if ( day.date === 1 ) {
+ day.extraClasses = "ui-custom";
+ }
+ } );
+ ok( picker.find( "td[id]:first button" ).hasClass( "ui-custom" ), "extraClasses applied" );
+
+ input.calendar( "destroy" );
+} );
+
+test( "showWeek", function() {
+ expect( 7 );
+ var input = $( "#calendar" ).calendar(),
+ container = input.calendar( "widget" );
+
+ equal( container.find( "thead th" ).length, 7, "just 7 days, no column cell" );
+ equal( container.find( ".ui-calendar-week-col" ).length, 0,
+ "no week column cells present" );
+ input.calendar( "destroy" );
+
+ input = $( "#calendar" ).calendar( { showWeek: true } );
+ container = input.calendar( "widget" );
+ equal( container.find( "thead th" ).length, 8, "7 days + a column cell" );
+ ok( container.find( "thead th:first" ).is( ".ui-calendar-week-col" ),
+ "first cell should have ui-datepicker-week-col class name" );
+ equal( container.find( ".ui-calendar-week-col" ).length,
+ container.find( "tr" ).length, "one week cell for each week" );
+ input.calendar( "destroy" );
+
+ input = $( "#calendar" ).calendar();
+ container = input.calendar( "widget" );
+ equal( container.find( "thead th" ).length, 7, "no week column" );
+ input.calendar( "option", "showWeek", true );
+ equal( container.find( "thead th" ).length, 8, "supports changing option after init" );
+} );
+
+test( "min / max", function() {
+ expect( 17 );
+
+ // With existing date
+ var element = $( "#calendar" ).calendar(),
+ container = element.calendar( "widget" ),
+ prevButton = container.find( ".ui-calendar-prev" ),
+ nextButton = container.find( ".ui-calendar-next" ),
+ minDate = new Date( 2008, 2 - 1, 29 ),
+ maxDate = new Date( 2008, 12 - 1, 7 );
+
+ element
+ .calendar( "option", { min: minDate } )
+ .calendar( "value", "6/4/08" );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min" );
+
+ element
+ .calendar( "option", { min: minDate } )
+ .calendar( "value", "1/4/08" );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < min" );
+
+ element
+ .calendar( "option", { min: null } )
+ .calendar( "value", "6/4/08" )
+ .calendar( "option", { max: maxDate } );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < max" );
+
+ element
+ .calendar( "option", { max: maxDate } )
+ .calendar( "value", "1/4/09" );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - setDate > max" );
+
+ element
+ .calendar( "option", { min: minDate, max: maxDate } )
+ .calendar( "value", "1/4/08" );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < min" );
+
+ element
+ .calendar( "option", { min: minDate, max: maxDate } )
+ .calendar( "value", "6/4/08" );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min, < max" );
+
+ element
+ .calendar( "option", { min: minDate, max: maxDate } )
+ .calendar( "value", "1/4/09" );
+ testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > max" );
+
+ element
+ .calendar( "option", { min: minDate, max: maxDate } )
+ .calendar( "value", "3/4/08" );
+ ok( !prevButton.hasClass( "ui-state-disabled" ), "Prev button enabled" );
+ prevButton.simulate( "click" );
+ ok( prevButton.hasClass( "ui-state-disabled" ), "Prev button disabled" );
+
+ element.calendar( "value", "11/4/08" );
+ ok( !nextButton.hasClass( "ui-state-disabled" ), "Next button enabled" );
+ nextButton.simulate( "click" );
+ ok( nextButton.hasClass( "ui-state-disabled" ), "Next button disabled" );
+
+ element
+ .calendar( "option", { max: null } )
+ .calendar( "value", "1/4/09" )
+ .calendar( "option", { min: minDate, max: maxDate } );
+ ok( nextButton.hasClass( "ui-state-disabled" ), "Other year above max: Next button disabled" );
+ prevButton.simulate( "click" );
+ ok( nextButton.hasClass( "ui-state-disabled" ), "Other year above max: Next button disabled after click" );
+ prevButton.simulate( "click" );
+ ok( !nextButton.hasClass( "ui-state-disabled" ), "Other year above max: Next button enabled after click" );
+
+ element
+ .calendar( "option", { min: null } )
+ .calendar( "value", "1/4/08" )
+ .calendar( "option", { min: minDate, max: maxDate } );
+ ok( prevButton.hasClass( "ui-state-disabled" ), "Other year below min: Prev button disabled" );
+ nextButton.simulate( "click" );
+ ok( prevButton.hasClass( "ui-state-disabled" ), "Other year below min: Prev button disabled after click" );
+ nextButton.simulate( "click" );
+ ok( !prevButton.hasClass( "ui-state-disabled" ), "Other year below min: Prev button enabled after click" );
+} );
+
+test( "numberOfMonths", function() {
+ expect( 6 );
+ var date = new Date( 2015, 8 - 1, 1 ),
+ input = $( "#calendar" ).calendar( {
+ numberOfMonths: 3,
+ value: date
+ } ),
+ container = input.calendar( "widget" );
+
+ equal( container.find( ".ui-calendar-group" ).length, 3, "3 calendar grids" );
+ equal(
+ container.find( "tbody:first td[id]:first" ).attr( "id" ),
+ "calendar-2015-7-1",
+ "Correct id set for first day of first grid"
+ );
+ equal(
+ container.find( "tbody:last td[id]:last" ).attr( "id" ),
+ "calendar-2015-9-31",
+ "Correct id set for last day of third grid"
+ );
+
+ // Test for jumping in weekday rendering after click on last day of last grid
+ container.find( "tbody:last td[id]:last button" ).trigger( "mousedown" );
+ equal( container.find( "thead:last th:last" ).text(), "Sa",
+ "After mousedown last month: Last day is Saturday"
+ );
+
+ // Test if using cursor to go to the next / prev month advances three month
+ // Focus doesn't work here so we use an additional mouse down event
+ container.find( "tbody:first td[id]:first button" ).trigger( "mousedown" );
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
+ equal( container.find( ".ui-calendar-month:first" ).text(), "May",
+ "After move to previous month: First month is May"
+ );
+
+ container.find( "tbody:last td[id]:last button" ).trigger( "mousedown" );
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
+ equal( container.find( ".ui-calendar-month:last" ).text(), "October",
+ "After move to next month: Last month is October"
+ );
+} );
+
+/*
+// TODO: Move this to $.date, Globalize or calendar widget
+test( "daylightSaving", function() {
+ expect( 25 );
+ var inp = testHelper.init( "#inp" ),
+ dp = $( "#ui-datepicker-div" );
+ ok(true, "Daylight saving - " + new Date());
+ // Australia, Sydney - AM change, southern hemisphere
+ inp.val( "04/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(6) a", dp).simulate( "click" );
+ equal(inp.val(), "04/05/2008", "Daylight saving - Australia 04/05/2008" );
+ inp.val( "04/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(7) a", dp).simulate( "click" );
+ equal(inp.val(), "04/06/2008", "Daylight saving - Australia 04/06/2008" );
+ inp.val( "04/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(8) a", dp).simulate( "click" );
+ equal(inp.val(), "04/07/2008", "Daylight saving - Australia 04/07/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(6) a", dp).simulate( "click" );
+ equal(inp.val(), "10/04/2008", "Daylight saving - Australia 10/04/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(7) a", dp).simulate( "click" );
+ equal(inp.val(), "10/05/2008", "Daylight saving - Australia 10/05/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(8) a", dp).simulate( "click" );
+ equal(inp.val(), "10/06/2008", "Daylight saving - Australia 10/06/2008" );
+ // Brasil, Brasilia - midnight change, southern hemisphere
+ inp.val( "02/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(20) a", dp).simulate( "click" );
+ equal(inp.val(), "02/16/2008", "Daylight saving - Brasil 02/16/2008" );
+ inp.val( "02/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(21) a", dp).simulate( "click" );
+ equal(inp.val(), "02/17/2008", "Daylight saving - Brasil 02/17/2008" );
+ inp.val( "02/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(22) a", dp).simulate( "click" );
+ equal(inp.val(), "02/18/2008", "Daylight saving - Brasil 02/18/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(13) a", dp).simulate( "click" );
+ equal(inp.val(), "10/11/2008", "Daylight saving - Brasil 10/11/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(14) a", dp).simulate( "click" );
+ equal(inp.val(), "10/12/2008", "Daylight saving - Brasil 10/12/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(15) a", dp).simulate( "click" );
+ equal(inp.val(), "10/13/2008", "Daylight saving - Brasil 10/13/2008" );
+ // Lebanon, Beirut - midnight change, northern hemisphere
+ inp.val( "03/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(34) a", dp).simulate( "click" );
+ equal(inp.val(), "03/29/2008", "Daylight saving - Lebanon 03/29/2008" );
+ inp.val( "03/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(35) a", dp).simulate( "click" );
+ equal(inp.val(), "03/30/2008", "Daylight saving - Lebanon 03/30/2008" );
+ inp.val( "03/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(36) a", dp).simulate( "click" );
+ equal(inp.val(), "03/31/2008", "Daylight saving - Lebanon 03/31/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(27) a", dp).simulate( "click" );
+ equal(inp.val(), "10/25/2008", "Daylight saving - Lebanon 10/25/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(28) a", dp).simulate( "click" );
+ equal(inp.val(), "10/26/2008", "Daylight saving - Lebanon 10/26/2008" );
+ inp.val( "10/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(29) a", dp).simulate( "click" );
+ equal(inp.val(), "10/27/2008", "Daylight saving - Lebanon 10/27/2008" );
+ // US, Eastern - AM change, northern hemisphere
+ inp.val( "03/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(13) a", dp).simulate( "click" );
+ equal(inp.val(), "03/08/2008", "Daylight saving - US 03/08/2008" );
+ inp.val( "03/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(14) a", dp).simulate( "click" );
+ equal(inp.val(), "03/09/2008", "Daylight saving - US 03/09/2008" );
+ inp.val( "03/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(15) a", dp).simulate( "click" );
+ equal(inp.val(), "03/10/2008", "Daylight saving - US 03/10/2008" );
+ inp.val( "11/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(6) a", dp).simulate( "click" );
+ equal(inp.val(), "11/01/2008", "Daylight saving - US 11/01/2008" );
+ inp.val( "11/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(7) a", dp).simulate( "click" );
+ equal(inp.val(), "11/02/2008", "Daylight saving - US 11/02/2008" );
+ inp.val( "11/01/2008" ).calendar( "show" );
+ $( ".ui-calendar-calendar td:eq(8) a", dp).simulate( "click" );
+ equal(inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008" );
+ });
+ */
+
+} );
diff --git a/tests/unit/date/all.html b/tests/unit/date/all.html
new file mode 100644
index 000000000..5248d7ace
--- /dev/null
+++ b/tests/unit/date/all.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Date Test Suite</title>
+
+ <script src="../../../external/jquery/jquery.js"></script>
+
+ <link rel="stylesheet" href="../../../external/qunit/qunit.css">
+ <link rel="stylesheet" href="../../../external/qunit-composite/qunit-composite.css">
+ <script src="../../../external/qunit/qunit.js"></script>
+ <script src="../../../external/qunit-composite/qunit-composite.js"></script>
+ <script src="../subsuite.js"></script>
+
+ <script>
+ testAllVersions( "date" );
+ </script>
+</head>
+<body>
+
+<div id="qunit"></div>
+<div id="qunit-fixture">
+
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/tests/unit/date/core.js b/tests/unit/date/core.js
new file mode 100644
index 000000000..2c32c70d2
--- /dev/null
+++ b/tests/unit/date/core.js
@@ -0,0 +1,174 @@
+define( [
+ "jquery",
+ "./helper",
+ "ui/date"
+], function( $, testHelper ) {
+
+module( "date: core" );
+
+var attributes = testHelper.getAttributes( "en" );
+
+test( "Instantiation", function() {
+ expect( 2 );
+ ok( new $.ui.date( null, attributes ) instanceof $.ui.date, "constructor function" );
+ ok( $.ui.date( null, attributes ) instanceof $.ui.date, "instantiation without new" );
+} );
+
+test( "Check Sets and Gets", 4, function() {
+ var date = $.ui.date( null, attributes );
+ equal( date.setDay( 15 ).day(), 15, "Set day and retrieve" );
+ equal( date.setFullDate( 2012, 9, 15 ).year(), 2012, "Set full date and retrieve year" );
+ equal( date.month(), 9, "Set full date and retrieve month" );
+ equal( date.day(), 15, "Set full date and retrieve day" );
+
+ // TODO Add setTime test
+} );
+
+test( "Date Adjustments - Normal Use Cases", 10, function() {
+ var date = $.ui.date( null, attributes );
+
+ // Use October 15, 2012
+ date.setFullDate( 2012, 9, 15 );
+ equal( date.adjust( "D", 1 ).day(), 16, "Add 1 day" );
+ equal( date.adjust( "D", -1 ).day(), 15, "Subtract 1 day" );
+ equal( date.adjust( "M", 1 ).month(), 10, "Add 1 month" );
+ equal( date.adjust( "M", -1 ).month(), 9, "Subtract 1 month" );
+ equal( date.adjust( "Y", 1 ).year(), 2013, "Add 1 year" );
+ equal( date.adjust( "Y", -1 ).year(), 2012, "Subtract 1 year" );
+
+ // Check changing one value impact another. Ex: Day impacts month
+ // Use April 30th 2012
+ date.setFullDate( 2012, 3, 30 );
+ equal( date.adjust( "D", 1 ).month(), 4, "Add 1 day to change month from April to May" );
+ equal( date.adjust( "D", -1 ).month(), 3, "Subtract 1 day to change month from May to April" );
+
+ // Use December 31st 2012
+ date.setFullDate( 2012, 11, 31 );
+ equal( date.adjust( "D", 1 ).year(), 2013, "Add 1 day to change year from 2012 to 2013" );
+ equal( date.adjust( "D", -1 ).year(), 2012,
+ "Subtract 1 day to change month from 2013 to 2012" );
+} );
+
+test( "Date Adjustments - Month Overflow Edge Cases", 2, function() {
+ var date = $.ui.date( null, attributes );
+
+ // Use May 31 2012
+ date.setFullDate( 2012, 4, 31 );
+ equal( date.adjust( "M", 1 ).day(), 30,
+ "Add 1 month from May to June sets days to 30, last day in June (prevent Overflow)" );
+ equal( date.adjust( "M", -1 ).day(), 30,
+ "Subtract 1 month from June to May sets days to 30 in May" );
+} );
+
+test( "Date Adjustments - Leap Year Edge Cases", 1, function() {
+ var date = $.ui.date( null, attributes );
+
+ // Use February 29 2012 a Leap year
+ date.setFullDate( 2012, 1, 29 );
+ equal( date.adjust( "Y", 1 ).day(), 28,
+ "Feb 29 2012, add a year to convert to Feb 28, 2013" );
+} );
+
+test( "List days of Week", 2, function() {
+ var date = $.ui.date( null, attributes ),
+ offset0 = [
+ { "fullname": "Sunday", "shortname": "Su" },
+ { "fullname": "Monday", "shortname": "Mo" },
+ { "fullname": "Tuesday", "shortname": "Tu" },
+ { "fullname": "Wednesday", "shortname": "We" },
+ { "fullname": "Thursday", "shortname": "Th" },
+ { "fullname": "Friday", "shortname": "Fr" },
+ { "fullname": "Saturday", "shortname": "Sa" }
+ ],
+ offset1 = [
+ { "fullname": "Montag", "shortname": "Mo." },
+ { "fullname": "Dienstag", "shortname": "Di." },
+ { "fullname": "Mittwoch", "shortname": "Mi." },
+ { "fullname": "Donnerstag", "shortname": "Do." },
+ { "fullname": "Freitag", "shortname": "Fr." },
+ { "fullname": "Samstag", "shortname": "Sa." },
+ { "fullname": "Sonntag", "shortname": "So." }
+ ];
+
+ deepEqual( date.weekdays(), offset0, "Get weekdays with start of day on 0 (English)" );
+ date = $.ui.date( null, testHelper.getAttributes( "de" ) );
+ deepEqual( date.weekdays(), offset1, "Get weekdays with start of day on 1 (Germany)" );
+} );
+
+test( "Days in Month", 3, function() {
+ var date = $.ui.date( null, attributes );
+ date.setFullDate( 2012, 1, 1 );
+ equal( date.daysInMonth(), 29, "Leap Year implicit check for 29 days" );
+ equal( date.daysInMonth( 2012, 1 ), 29, "Leap Year explicit check for 29 days" );
+ equal( date.daysInMonth( 2011, 3 ), 30, "April has 30 days" );
+} );
+
+test( "Month Name", 2, function() {
+ var date = $.ui.date( null, attributes );
+ equal( date.setFullDate( 2012, 3, 1 ).monthName(), "April", "Month name return April (English)" );
+ date = $.ui.date( null, testHelper.getAttributes( "de" ) );
+ equal( date.setFullDate( 2012, 2, 1 ).monthName(), "März", "Month name return March (German)" );
+} );
+
+test( "Clone", 2, function() {
+ var date = $.ui.date( null, attributes ),
+ date2 = date.clone();
+ ok( date2, "Created cloned object" );
+ notEqual( date.adjust( "Y", 1 ).year(), date2.year(), "Object manipulated independently" );
+} );
+
+test( "Days", 1, function() {
+
+ // TODO Needs work
+ var date = $.ui.date( null, attributes );
+ date.eachDay = function( day ) {
+ if ( day.lead && day.date > 20 ) {
+ day.selectable = false;
+ day.render = true;
+ day.title = "These are the days of last month";
+ day.extraClasses = "ui-state-disabled";
+ }
+ if ( day.lead && day.date < 3 ) {
+ day.selectable = true;
+ day.render = true;
+ day.extraClasses = "ui-state-disabled";
+ }
+ if ( day.date === 1 ) {
+ day.extraClasses = "ui-state-error";
+ day.title = "Something bad explaining the error highlight";
+ }
+ if ( day.today ) {
+ day.title = "A good day!";
+ }
+ };
+ ok( date.days(), "Date days() returns" );
+} );
+
+test( "Months", 5, function() {
+ var date = $.ui.date( null, attributes ),
+ firstMonth = date.months( 1 )[ 0 ],
+ lastMonth = date.months( 1 )[ 1 ];
+
+ ok( firstMonth.first );
+ ok( !lastMonth.first );
+ ok( lastMonth.last );
+ ok( !lastMonth.first );
+
+ equal( firstMonth.month(), lastMonth.month() - 1 );
+} );
+
+test( "Equal", 4, function() {
+ var date = $.ui.date( null, attributes );
+ date.setFullDate( 2012, 9, 16 );
+ ok( date.equal( new Date( 2012, 9, 16 ) ), "Does date equal provide date" );
+ ok( !date.equal( new Date( 2011, 9, 16 ) ), "Does date year not equal provide date" );
+ ok( !date.equal( new Date( 2012, 8, 16 ) ), "Does date month not equal provide date" );
+ ok( !date.equal( new Date( 2012, 9, 15 ) ), "Does date day not equal provide date" );
+} );
+
+test( "Date", 1, function() {
+ var date = $.ui.date( null, attributes );
+ ok( date.date() instanceof Date, "Date returned" );
+} );
+
+} );
diff --git a/tests/unit/date/date.html b/tests/unit/date/date.html
new file mode 100644
index 000000000..3c11f519b
--- /dev/null
+++ b/tests/unit/date/date.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>jQuery UI Date Test Suite</title>
+
+ <script src="../../../external/requirejs/require.js"></script>
+ <script src="../../lib/css.js"></script>
+ <script src="../../lib/bootstrap.js" data-modules="core"></script>
+</head>
+<body>
+
+<div id="qunit"></div>
+<div id="qunit-fixture"></div>
+</body>
+</html>
diff --git a/tests/unit/date/helper.js b/tests/unit/date/helper.js
new file mode 100644
index 000000000..2f6f51fd9
--- /dev/null
+++ b/tests/unit/date/helper.js
@@ -0,0 +1,31 @@
+define( [
+ "jquery",
+ "globalize",
+ "lib/helper",
+ "globalize/date"
+], function( $, Globalize, helper ) {
+
+return $.extend( helper, {
+ getAttributes: function( locale ) {
+ var globalize = new Globalize( locale ),
+ weekdayShortFormatter = globalize.dateFormatter( { raw: "EEEEEE" } ),
+ weekdayNarrowFormatter = globalize.dateFormatter( { raw: "EEEEE" } ),
+ firstDayRaw = globalize.dateFormatter( { raw: "c" } )( new Date( 1970, 0, 3 ) );
+
+ return {
+ firstDay: ( 7 - globalize.parseNumber( firstDayRaw ) ),
+ formatWeekdayShort: function( date ) {
+
+ // Return the short weekday if its length is < 3. Otherwise, its narrow form.
+ var shortWeekday = weekdayShortFormatter( date );
+
+ return shortWeekday.length > 3 ? weekdayNarrowFormatter( date ) : shortWeekday;
+ },
+ formatWeekdayFull: globalize.dateFormatter( { raw: "EEEE" } ),
+ formatMonth: globalize.dateFormatter( { raw: "MMMM" } ),
+ formatWeekOfYear: globalize.dateFormatter( { raw: "w" } )
+ };
+ }
+} );
+
+} );
diff --git a/tests/unit/datepicker/common.js b/tests/unit/datepicker/common.js
index 1eecc85cb..bc06a8992 100644
--- a/tests/unit/datepicker/common.js
+++ b/tests/unit/datepicker/common.js
@@ -1,7 +1,42 @@
-/*
-TestHelpers.commonWidgetTests( "datepicker", {
+define( [
+ "lib/common",
+ "ui/widgets/datepicker",
+ "globalize-locales"
+], function( common ) {
+
+common.testWidget( "datepicker", {
defaults: {
- disabled: false
+ appendTo: null,
+ buttons: [],
+ classes: {},
+ disabled: false,
+ dateFormat: { date: "short" },
+ eachDay: $.noop,
+ labels: {
+ "datePickerRole": "date picker",
+ "nextText": "Next",
+ "prevText": "Prev",
+ "weekHeader": "Wk"
+ },
+ locale: "en",
+ max: null,
+ min: null,
+ numberOfMonths: 1,
+ position: {
+ my: "left top",
+ at: "left bottom"
+ },
+ show: true,
+ showWeek: false,
+ hide: true,
+
+ // callbacks
+ beforeOpen: null,
+ close: null,
+ create: null,
+ open: null,
+ select: null
}
-});
-*/
+} );
+
+} );
diff --git a/tests/unit/datepicker/core.js b/tests/unit/datepicker/core.js
index ec4c0efed..83882ef7a 100644
--- a/tests/unit/datepicker/core.js
+++ b/tests/unit/datepicker/core.js
@@ -1,542 +1,173 @@
define( [
"jquery",
- "lib/common",
"./helper",
- "ui/widgets/datepicker",
- "ui/i18n/datepicker-he"
-], function( $, common, testHelper ) {
+ "ui/widgets/datepicker"
+], function( $, testHelper ) {
-module( "datepicker: core", {
- setup: function() {
- $( "body" ).trigger( "focus" );
- }
-} );
-
-common.testJshint( "widgets/datepicker" );
-
-test( "initialization - Reinitialization after body had been emptied.", function() {
- expect( 1 );
- var bodyContent = $( "body" ).children(), inp = $( "#inp" );
- $( "#inp" ).datepicker();
- $( "body" ).empty().append( inp );
- $( "#inp" ).datepicker();
- ok( $( "#" + $.datepicker._mainDivId ).length === 1, "Datepicker container added" );
- $( "body" ).empty().append( bodyContent ); // Returning to initial state for later tests
-} );
-
-test( "widget method - empty collection", function() {
- expect( 1 );
- $( "#nonExist" ).datepicker(); // should create nothing
- ok( !$( "#ui-datepicker-div" ).length, "Non init on empty collection" );
-} );
-
-test( "widget method", function() {
- expect( 1 );
- var actual = $( "#inp" ).datepicker().datepicker( "widget" )[ 0 ];
- deepEqual( $( "body > #ui-datepicker-div:last-child" )[ 0 ], actual );
-} );
-
-asyncTest( "baseStructure", function() {
- expect( 58 );
- var header, title, table, thead, week, panel, inl, child,
- inp = testHelper.initNewInput(),
- dp = $( "#ui-datepicker-div" );
-
- function step1() {
- testHelper.onFocus( inp, function() {
- ok( dp.is( ":visible" ), "Structure - datepicker visible" );
- ok( !dp.is( ".ui-datepicker-rtl" ), "Structure - not right-to-left" );
- ok( !dp.is( ".ui-datepicker-multi" ), "Structure - not multi-month" );
- equal( dp.children().length, 2, "Structure - child count" );
-
- header = dp.children( ":first" );
- ok( header.is( "div.ui-datepicker-header" ), "Structure - header division" );
- equal( header.children().length, 3, "Structure - header child count" );
- ok( header.children( ":first" ).is( "a.ui-datepicker-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" );
- ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" );
-
- title = header.children( ":last" );
- ok( title.is( "div.ui-datepicker-title" ) && title.html() !== "", "Structure - title division" );
- equal( title.children().length, 2, "Structure - title child count" );
- ok( title.children( ":first" ).is( "span.ui-datepicker-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" );
- ok( title.children( ":last" ).is( "span.ui-datepicker-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" );
-
- table = dp.children( ":eq(1)" );
- ok( table.is( "table.ui-datepicker-calendar" ), "Structure - month table" );
- ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" );
-
- thead = table.children( ":first" ).children( ":first" );
- ok( thead.is( "tr" ), "Structure - month table title row" );
- equal( thead.find( "th" ).length, 7, "Structure - month table title cells" );
- ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" );
- ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" );
-
- week = table.children( ":eq(1)" ).children( ":first" );
- ok( week.is( "tr" ), "Structure - month table week row" );
- equal( week.children().length, 7, "Structure - week child count" );
- ok( week.children( ":first" ).is( "td.ui-datepicker-week-end" ), "Structure - month table first day cell" );
- ok( week.children( ":last" ).is( "td.ui-datepicker-week-end" ), "Structure - month table second day cell" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step2();
- } );
- }
-
- function step2() {
-
- // Editable month/year and button panel
- inp = testHelper.initNewInput( {
- changeMonth: true,
- changeYear: true,
- showButtonPanel: true
- } );
- testHelper.onFocus( inp, function() {
- title = dp.find( "div.ui-datepicker-title" );
- ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure - month selector" );
- ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure - year selector" );
-
- panel = dp.children( ":last" );
- ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure - button panel division" );
- equal( panel.children().length, 2, "Structure - button panel child count" );
- ok( panel.children( ":first" ).is( "button.ui-datepicker-current" ), "Structure - today button" );
- ok( panel.children( ":last" ).is( "button.ui-datepicker-close" ), "Structure - close button" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step3();
- } );
- }
-
- function step3() {
-
- // Multi-month 2
- inp = testHelper.initNewInput( { numberOfMonths: 2 } );
- testHelper.onFocus( inp, function() {
- ok( dp.is( ".ui-datepicker-multi" ), "Structure multi [2] - multi-month" );
- equal( dp.children().length, 3, "Structure multi [2] - child count" );
-
- child = dp.children( ":first" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2] - first month division" );
-
- child = dp.children( ":eq(1)" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2] - second month division" );
-
- child = dp.children( ":eq(2)" );
- ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2] - row break" );
- ok( dp.is( ".ui-datepicker-multi-2" ), "Structure multi [2] - multi-2" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step4();
- } );
- }
-
- function step4() {
-
- // Multi-month 3
- inp = testHelper.initNewInput( { numberOfMonths: 3 } );
- testHelper.onFocus( inp, function() {
- ok( dp.is( ".ui-datepicker-multi-3" ), "Structure multi [3] - multi-3" );
- ok( !dp.is( ".ui-datepicker-multi-2" ), "Structure multi [3] - Trac #6704" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step5();
- } );
- }
-
- function step5() {
-
- // Multi-month [2, 2]
- inp = testHelper.initNewInput( { numberOfMonths: [ 2, 2 ] } );
- testHelper.onFocus( inp, function() {
- ok( dp.is( ".ui-datepicker-multi" ), "Structure multi - multi-month" );
- equal( dp.children().length, 6, "Structure multi [2,2] - child count" );
-
- child = dp.children( ":first" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - first month division" );
-
- child = dp.children( ":eq(1)" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - second month division" );
-
- child = dp.children( ":eq(2)" );
- ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" );
-
- child = dp.children( ":eq(3)" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - third month division" );
-
- child = dp.children( ":eq(4)" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - fourth month division" );
+module( "datepicker: core" );
- child = dp.children( ":eq(5)" );
- ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" );
+test( "input's value determines starting date", function() {
+ expect( 3 );
- inp.datepicker( "hide" ).datepicker( "destroy" );
+ var input = $( "#datepicker" ).val( "1/1/14" ).datepicker(),
+ picker = input.datepicker( "widget" );
- // Inline
- inl = testHelper.init( "#inl" );
- dp = inl.children();
+ input.datepicker( "open" );
- ok( dp.is( ".ui-datepicker-inline" ), "Structure inline - main div" );
- ok( !dp.is( ".ui-datepicker-rtl" ), "Structure inline - not right-to-left" );
- ok( !dp.is( ".ui-datepicker-multi" ), "Structure inline - not multi-month" );
- equal( dp.children().length, 2, "Structure inline - child count" );
+ equal( picker.find( ".ui-calendar-month" ).html(), "January", "correct month displayed" );
+ equal( picker.find( ".ui-calendar-year" ).html(), "2014", "correct year displayed" );
+ equal( picker.find( ".ui-state-active" ).html(), "1", "correct day highlighted" );
- header = dp.children( ":first" );
- ok( header.is( "div.ui-datepicker-header" ), "Structure inline - header division" );
- equal( header.children().length, 3, "Structure inline - header child count" );
-
- table = dp.children( ":eq(1)" );
- ok( table.is( "table.ui-datepicker-calendar" ), "Structure inline - month table" );
- ok( table.children( ":first" ).is( "thead" ), "Structure inline - month table thead" );
- ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure inline - month table body" );
-
- inl.datepicker( "destroy" );
-
- // Inline multi-month
- inl = testHelper.init( "#inl", { numberOfMonths: 2 } );
- dp = inl.children();
-
- ok( dp.is( ".ui-datepicker-inline" ) && dp.is( ".ui-datepicker-multi" ), "Structure inline multi - main div" );
- equal( dp.children().length, 3, "Structure inline multi - child count" );
+ input.val( "" ).datepicker( "destroy" );
+} );
- child = dp.children( ":first" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure inline multi - first month division" );
+asyncTest( "base structure", function() {
+ expect( 5 );
- child = dp.children( ":eq(1)" );
- ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure inline multi - second month division" );
+ var input = testHelper.initNewInput(),
+ widget = input.datepicker( "widget" );
- child = dp.children( ":eq(2)" );
- ok( child.is( "div.ui-datepicker-row-break" ), "Structure inline multi - row break" );
+ input.focus();
- inl.datepicker( "destroy" );
- start();
- } );
- }
+ setTimeout( function() {
+ ok( widget.is( ":visible" ), "Datepicker visible" );
+ equal( widget.children().length, 2, "Child count" );
+ ok( widget.is( ".ui-calendar" ), "Class ui-calendar" );
+ ok( widget.is( ".ui-datepicker" ), "Class ui-datepicker" );
+ ok( widget.is( ".ui-front" ), "Class ui-front" );
- step1();
+ input.datepicker( "close" );
+ start();
+ }, 50 );
} );
-asyncTest( "customStructure", function() {
- expect( 20 );
- var header, panel, title, thead,
- inp = testHelper.initNewInput( $.datepicker.regional.he ),
- dp = $( "#ui-datepicker-div" );
+asyncTest( "Keyboard handling: input", function() {
+ expect( 10 );
+ var picker, instance,
+ input = $( "#datepicker" ).datepicker();
function step1() {
- inp.datepicker( "option", "showButtonPanel", true );
+ testHelper.init( input );
+ picker = input.datepicker( "widget" );
- testHelper.onFocus( inp, function() {
- ok( dp.is( ".ui-datepicker-rtl" ), "Structure RTL - right-to-left" );
+ ok( !picker.is( ":visible" ), "datepicker closed" );
- header = dp.children( ":first" );
- ok( header.is( "div.ui-datepicker-header" ), "Structure RTL - header division" );
- equal( header.children().length, 3, "Structure RTL - header child count" );
- ok( header.children( ":first" ).is( "a.ui-datepicker-next" ), "Structure RTL - prev link" );
- ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-prev" ), "Structure RTL - next link" );
-
- panel = dp.children( ":last" );
- ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure RTL - button division" );
- equal( panel.children().length, 2, "Structure RTL - button panel child count" );
- ok( panel.children( ":first" ).is( "button.ui-datepicker-close" ), "Structure RTL - close button" );
- ok( panel.children( ":last" ).is( "button.ui-datepicker-current" ), "Structure RTL - today button" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
+ input.val( "" ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+ setTimeout( function() {
+ ok( picker.is( ":visible" ), "Keystroke down opens datepicker" );
+ input.datepicker( "destroy" );
step2();
- } );
+ }, 100 );
}
- // Hide prev/next
function step2() {
- inp = testHelper.initNewInput( {
- hideIfNoPrevNext: true,
- minDate: new Date( 2008, 2 - 1, 4 ),
- maxDate: new Date( 2008, 2 - 1, 14 )
- } );
- inp.val( "02/10/2008" );
-
- testHelper.onFocus( inp, function() {
- header = dp.children( ":first" );
- ok( header.is( "div.ui-datepicker-header" ), "Structure hide prev/next - header division" );
- equal( header.children().length, 1, "Structure hide prev/next - links child count" );
- ok( header.children( ":first" ).is( "div.ui-datepicker-title" ), "Structure hide prev/next - title division" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step3();
- } );
- }
+ testHelper.init( input );
+ picker = input.datepicker( "widget" );
- // Changeable Month with read-only year
- function step3() {
- inp = testHelper.initNewInput( { changeMonth: true } );
-
- testHelper.onFocus( inp, function() {
- title = dp.children( ":first" ).children( ":last" );
- equal( title.children().length, 2, "Structure changeable month - title child count" );
- ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure changeable month - month selector" );
- ok( title.children( ":last" ).is( "span.ui-datepicker-year" ), "Structure changeable month - read-only year" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step4();
- } );
- }
+ ok( !picker.is( ":visible" ), "datepicker closed" );
- // Changeable year with read-only month
- function step4() {
- inp = testHelper.initNewInput( { changeYear: true } );
-
- testHelper.onFocus( inp, function() {
- title = dp.children( ":first" ).children( ":last" );
- equal( title.children().length, 2, "Structure changeable year - title child count" );
- ok( title.children( ":first" ).is( "span.ui-datepicker-month" ), "Structure changeable year - read-only month" );
- ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure changeable year - year selector" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- step5();
- } );
+ input.val( "" ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
+ setTimeout( function() {
+ ok( picker.is( ":visible" ), "Keystroke up opens datepicker" );
+ input.datepicker( "destroy" );
+ step3();
+ }, 100 );
}
- // Read-only first day of week
- function step5() {
- inp = testHelper.initNewInput( { changeFirstDay: false } );
-
- testHelper.onFocus( inp, function() {
- thead = dp.find( ".ui-datepicker-calendar thead tr" );
- equal( thead.children().length, 7, "Structure read-only first day - thead child count" );
- equal( thead.find( "a" ).length, 0, "Structure read-only first day - thead links count" );
-
- inp.datepicker( "hide" ).datepicker( "destroy" );
- start();
- } );
+ function step3() {
+ testHelper.init( input );
+ instance = input.datepicker( "instance" );
+
+ // Enter = Select preset date
+ input
+ .val( "1/1/14" )
+ .datepicker( "refresh" )
+ .datepicker( "open" )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ),
+ "Keystroke enter - preset" );
+
+ input
+ .val( "" )
+ .datepicker( "open" );
+ ok( instance.isOpen, "datepicker is open before escape" );
+
+ input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+ ok( !instance.isOpen, "escape closes the datepicker" );
+
+ input
+ .val( "1/1/14" )
+ .datepicker( "open" )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+ testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ),
+ "Keystroke esc - preset" );
+
+ input
+ .val( "1/1/14" )
+ .datepicker( "open" )
+ .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+ testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ),
+ "Keystroke esc - abandoned" );
+
+ input
+ .val( "1/2/14" )
+ .simulate( "keyup" );
+ testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 2 ),
+ "Picker updated as user types into input" );
+
+ input.datepicker( "destroy" );
+ start();
}
- // TODO: figure out why this setTimeout is needed in IE,
- // it only is necessary when the previous baseStructure tests runs first
- // Support: IE
- setTimeout( step1 );
+ step1();
} );
-test( "keystrokes", function() {
- expect( 26 );
- var inp = testHelper.init( "#inp" ),
- date = new Date();
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke enter" );
- inp.val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ),
- "Keystroke enter - preset" );
- inp.val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke ctrl+home" );
- inp.val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } );
- ok( inp.datepicker( "getDate" ) == null, "Keystroke ctrl+end" );
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
- ok( inp.datepicker( "getDate" ) == null, "Keystroke esc" );
- inp.val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ),
- "Keystroke esc - preset" );
- inp.val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ),
- "Keystroke esc - abandoned" );
-
- // Moving by day or week
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.LEFT } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() - 1 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke ctrl+left" );
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() + 1 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke left" );
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.RIGHT } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() + 1 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke ctrl+right" );
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() - 1 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke right" );
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.UP } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() - 7 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke ctrl+up" );
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.UP } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() + 7 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke up" );
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() + 7 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke ctrl+down" );
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() - 7 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke down" );
-
- // Moving by month or year
- inp.val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 1 - 1, 4 ),
- "Keystroke pgup" );
- inp.val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 3 - 1, 4 ),
- "Keystroke pgdn" );
- inp.val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2007, 2 - 1, 4 ),
- "Keystroke ctrl+pgup" );
- inp.val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2009, 2 - 1, 4 ),
- "Keystroke ctrl+pgdn" );
-
- // Check for moving to short months
- inp.val( "03/31/2008" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 29 ),
- "Keystroke pgup - Feb" );
- inp.val( "01/30/2008" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 29 ),
- "Keystroke pgdn - Feb" );
- inp.val( "02/29/2008" ).datepicker( "show" ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2007, 2 - 1, 28 ),
- "Keystroke ctrl+pgup - Feb" );
- inp.val( "02/29/2008" ).datepicker( "show" ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2009, 2 - 1, 28 ),
- "Keystroke ctrl+pgdn - Feb" );
-
- // Goto current
- inp.datepicker( "option", { gotoCurrent: true } ).
- datepicker( "hide" ).val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ),
- "Keystroke ctrl+home" );
-
- // Change steps
- inp.datepicker( "option", { stepMonths: 2, gotoCurrent: false } ).
- datepicker( "hide" ).val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2007, 12 - 1, 4 ),
- "Keystroke pgup step 2" );
- inp.val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 4 - 1, 4 ),
- "Keystroke pgdn step 2" );
+// TODO: implement
+test( "ARIA", function() {
+ expect( 0 );
} );
-test( "mouse", function() {
- expect( 15 );
- var inl,
- inp = testHelper.init( "#inp" ),
- dp = $( "#ui-datepicker-div" ),
- date = new Date();
- inp.val( "" ).datepicker( "show" );
- $( ".ui-datepicker-calendar tbody a:contains(10)", dp ).simulate( "click", {} );
- date.setDate( 10 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Mouse click" );
- inp.val( "02/04/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar tbody a:contains(12)", dp ).simulate( "click", {} );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 12 ),
- "Mouse click - preset" );
- inp.val( "02/04/2008" ).datepicker( "show" );
- inp.val( "" ).datepicker( "show" );
- $( "button.ui-datepicker-close", dp ).simulate( "click", {} );
- ok( inp.datepicker( "getDate" ) == null, "Mouse click - close" );
- inp.val( "02/04/2008" ).datepicker( "show" );
- $( "button.ui-datepicker-close", dp ).simulate( "click", {} );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ),
- "Mouse click - close + preset" );
- inp.val( "02/04/2008" ).datepicker( "show" );
- $( "a.ui-datepicker-prev", dp ).simulate( "click", {} );
- $( "button.ui-datepicker-close", dp ).simulate( "click", {} );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ),
- "Mouse click - abandoned" );
-
- // Current/previous/next
- inp.val( "02/04/2008" ).datepicker( "option", { showButtonPanel: true } ).datepicker( "show" );
- $( ".ui-datepicker-current", dp ).simulate( "click", {} );
- $( ".ui-datepicker-calendar tbody a:contains(14)", dp ).simulate( "click", {} );
- date.setDate( 14 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Mouse click - current" );
- inp.val( "02/04/2008" ).datepicker( "show" );
- $( ".ui-datepicker-prev", dp ).simulate( "click" );
- $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 1 - 1, 16 ),
- "Mouse click - previous" );
- inp.val( "02/04/2008" ).datepicker( "show" );
- $( ".ui-datepicker-next", dp ).simulate( "click" );
- $( ".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 3 - 1, 18 ),
- "Mouse click - next" );
-
- // Previous/next with minimum/maximum
- inp.datepicker( "option", { minDate: new Date( 2008, 2 - 1, 2 ),
- maxDate: new Date( 2008, 2 - 1, 26 ) } ).val( "02/04/2008" ).datepicker( "show" );
- $( ".ui-datepicker-prev", dp ).simulate( "click" );
- $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 16 ),
- "Mouse click - previous + min/max" );
- inp.val( "02/04/2008" ).datepicker( "show" );
- $( ".ui-datepicker-next", dp ).simulate( "click" );
- $( ".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 18 ),
- "Mouse click - next + min/max" );
-
- // Inline
- inl = testHelper.init( "#inl" );
- dp = $( ".ui-datepicker-inline", inl );
- date = new Date();
- inl.datepicker( "setDate", date );
- $( ".ui-datepicker-calendar tbody a:contains(10)", dp ).simulate( "click", {} );
- date.setDate( 10 );
- testHelper.equalsDate( inl.datepicker( "getDate" ), date, "Mouse click inline" );
- inl.datepicker( "option", { showButtonPanel: true } ).datepicker( "setDate", new Date( 2008, 2 - 1, 4 ) );
- $( ".ui-datepicker-calendar tbody a:contains(12)", dp ).simulate( "click", {} );
- testHelper.equalsDate( inl.datepicker( "getDate" ), new Date( 2008, 2 - 1, 12 ), "Mouse click inline - preset" );
- inl.datepicker( "option", { showButtonPanel: true } );
- $( ".ui-datepicker-current", dp ).simulate( "click", {} );
- $( ".ui-datepicker-calendar tbody a:contains(14)", dp ).simulate( "click", {} );
- date.setDate( 14 );
- testHelper.equalsDate( inl.datepicker( "getDate" ), date, "Mouse click inline - current" );
- inl.datepicker( "setDate", new Date( 2008, 2 - 1, 4 ) );
- $( ".ui-datepicker-prev", dp ).simulate( "click" );
- $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" );
- testHelper.equalsDate( inl.datepicker( "getDate" ), new Date( 2008, 1 - 1, 16 ),
- "Mouse click inline - previous" );
- inl.datepicker( "setDate", new Date( 2008, 2 - 1, 4 ) );
- $( ".ui-datepicker-next", dp ).simulate( "click" );
- $( ".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" );
- testHelper.equalsDate( inl.datepicker( "getDate" ), new Date( 2008, 3 - 1, 18 ),
- "Mouse click inline - next" );
+asyncTest( "mouse", function() {
+ expect( 4 );
+
+ var input = testHelper.init( $( "#datepicker" ).val( "" ) ),
+ picker = input.datepicker( "widget" );
+
+ input.datepicker( "open" );
+
+ setTimeout( function() {
+ input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" );
+ $( ".ui-calendar-calendar tbody button:contains(12)", picker ).simulate( "mousedown", {} );
+ testHelper.equalsDate(
+ input.datepicker( "valueAsDate" ),
+ new Date( 2008, 4 - 1, 12 ),
+ "Mouse click - preset"
+ );
+
+ input.val( "" ).datepicker( "refresh" );
+ input.simulate( "click" );
+ strictEqual( input.datepicker( "valueAsDate" ), null, "Mouse click - close" );
+
+ input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" );
+ input.simulate( "click" );
+ testHelper.equalsDate(
+ input.datepicker( "valueAsDate" ),
+ new Date( 2008, 4 - 1, 4 ),
+ "Mouse click - close + preset"
+ );
+
+ input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" );
+ picker.find( "a.ui-calendar-prev" ).simulate( "click" );
+ input.simulate( "click" );
+ testHelper.equalsDate(
+ input.datepicker( "valueAsDate" ),
+ new Date( 2008, 4 - 1, 4 ),
+ "Mouse click - abandoned"
+ );
+
+ start();
+ }, 100 );
} );
} );
diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html
index 26d8de3e0..3b20272b1 100644
--- a/tests/unit/datepicker/datepicker.html
+++ b/tests/unit/datepicker/datepicker.html
@@ -5,7 +5,7 @@
<title>jQuery UI Datepicker Test Suite</title>
<script src="../../../external/requirejs/require.js"></script>
- <script src="../../lib/css.js" data-modules="core datepicker"></script>
+ <script src="../../lib/css.js" data-modules="core calendar datepicker"></script>
<script src="../../lib/bootstrap.js" data-widget="datepicker"></script>
</head>
<body>
@@ -13,8 +13,8 @@
<div id="qunit"></div>
<div id="qunit-fixture">
-<div><input type="text" id="inp"><input type="text" id="alt"><div id="inl"></div></div>
-<p><input type="text" id="inp2"></p>
+<input type="text" id="datepicker">
+<input type="text" id="datepicker2">
</div>
</body>
diff --git a/tests/unit/datepicker/events.js b/tests/unit/datepicker/events.js
index 4a5654d09..902896f2a 100644
--- a/tests/unit/datepicker/events.js
+++ b/tests/unit/datepicker/events.js
@@ -6,157 +6,133 @@ define( [
module( "datepicker: events" );
-var selectedThis = null,
-selectedDate = null,
-selectedInst = null;
-
-function callback( date, inst ) {
- selectedThis = this;
- selectedDate = date;
- selectedInst = inst;
-}
-
-function callback2( year, month, inst ) {
- selectedThis = this;
- selectedDate = year + "/" + month;
- selectedInst = inst;
-}
-
-test( "events", function() {
- expect( 26 );
- var dateStr, newMonthYear, inp2,
- inp = testHelper.init( "#inp", { onSelect: callback } ),
- date = new Date();
-
- // onSelect
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- equal( selectedThis, inp[ 0 ], "Callback selected this" );
- equal( selectedInst, $.data( inp[ 0 ], testHelper.PROP_NAME ), "Callback selected inst" );
- equal( selectedDate, $.datepicker.formatDate( "mm/dd/yy", date ),
- "Callback selected date" );
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() + 7 );
- equal( selectedDate, $.datepicker.formatDate( "mm/dd/yy", date ),
- "Callback selected date - ctrl+down" );
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
- equal( selectedDate, $.datepicker.formatDate( "mm/dd/yy", date ),
- "Callback selected date - esc" );
- dateStr = "02/04/2008";
- inp.val( dateStr ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- equal( dateStr, selectedDate,
- "onSelect is called after enter keydown" );
-
- // onChangeMonthYear
- inp.datepicker( "option", { onChangeMonthYear: callback2, onSelect: null } ).
- val( "" ).datepicker( "show" );
- newMonthYear = function( date ) {
- return date.getFullYear() + "/" + ( date.getMonth() + 1 );
- };
- date = new Date();
- date.setDate( 1 );
- inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
- date.setMonth( date.getMonth() - 1 );
- equal( selectedThis, inp[ 0 ], "Callback change month/year this" );
- equal( selectedInst, $.data( inp[ 0 ], testHelper.PROP_NAME ), "Callback change month/year inst" );
- equal( selectedDate, newMonthYear( date ),
- "Callback change month/year date - pgup" );
- inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
- date.setMonth( date.getMonth() + 1 );
- equal( selectedDate, newMonthYear( date ),
- "Callback change month/year date - pgdn" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } );
- date.setFullYear( date.getFullYear() - 1 );
- equal( selectedDate, newMonthYear( date ),
- "Callback change month/year date - ctrl+pgup" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } );
- date.setFullYear( date.getFullYear() + 1 );
- equal( selectedDate, newMonthYear( date ),
- "Callback change month/year date - ctrl+home" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } );
- date.setFullYear( date.getFullYear() + 1 );
- equal( selectedDate, newMonthYear( date ),
- "Callback change month/year date - ctrl+pgdn" );
- inp.datepicker( "setDate", new Date( 2007, 1 - 1, 26 ) );
- equal( selectedDate, "2007/1", "Callback change month/year date - setDate" );
- selectedDate = null;
- inp.datepicker( "setDate", new Date( 2007, 1 - 1, 12 ) );
- ok( selectedDate == null, "Callback change month/year date - setDate no change" );
-
- // onChangeMonthYear step by 2
- inp.datepicker( "option", { stepMonths: 2 } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
- date.setMonth( date.getMonth() - 14 );
- equal( selectedDate, newMonthYear( date ),
- "Callback change month/year by 2 date - pgup" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } );
- date.setMonth( date.getMonth() - 12 );
- equal( selectedDate, newMonthYear( date ),
- "Callback change month/year by 2 date - ctrl+pgup" );
- inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
- date.setMonth( date.getMonth() + 2 );
- equal( selectedDate, newMonthYear( date ),
- "Callback change month/year by 2 date - pgdn" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } );
- date.setMonth( date.getMonth() + 12 );
- equal( selectedDate, newMonthYear( date ),
- "Callback change month/year by 2 date - ctrl+pgdn" );
-
- // onClose
- inp.datepicker( "option", { onClose: callback, onChangeMonthYear: null, stepMonths: 1 } ).
- val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
- equal( selectedThis, inp[ 0 ], "Callback close this" );
- equal( selectedInst, $.data( inp[ 0 ], testHelper.PROP_NAME ), "Callback close inst" );
- equal( selectedDate, "", "Callback close date - esc" );
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- equal( selectedDate, $.datepicker.formatDate( "mm/dd/yy", new Date() ),
- "Callback close date - enter" );
- inp.val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
- equal( selectedDate, "02/04/2008", "Callback close date - preset" );
- inp.val( "02/04/2008" ).datepicker( "show" ).
- simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } );
- equal( selectedDate, "", "Callback close date - ctrl+end" );
-
- inp2 = testHelper.init( "#inp2" );
- inp2.datepicker().datepicker( "option", { onClose: callback } ).datepicker( "show" );
- inp.datepicker( "show" );
- equal( selectedThis, inp2[ 0 ], "Callback close this" );
+test( "beforeOpen", function() {
+ expect( 3 );
+
+ var input = testHelper.init( "#datepicker", {
+ beforeOpen: function() {
+ ok( true, "beforeOpen event fired before open" );
+ ok( input.datepicker( "widget" ).is( ":hidden" ), "calendar hidden on beforeOpen" );
+ },
+ open: function() {
+ ok( input.datepicker( "widget" ).is( ":visible" ), "calendar open on open" );
+ }
+ } );
+
+ input
+ .datepicker( "open" )
+ .datepicker( "close" )
+ .datepicker( "option", {
+ beforeOpen: function() {
+ return false;
+ },
+ open: function() {
+ ok( false, "calendar should not open when openBefore is canceled" );
+ }
+ } )
+ .datepicker( "open" );
} );
-test( "beforeShowDay-getDate", function() {
- expect( 3 );
- var inp = testHelper.init( "#inp", { beforeShowDay: function() { inp.datepicker( "getDate" ); return [ true, "" ]; } } ),
- dp = $( "#ui-datepicker-div" );
- inp.val( "01/01/2010" ).datepicker( "show" );
-
- // contains non-breaking space
- equal( $( "div.ui-datepicker-title" ).text(),
-
- // Support: IE <9, jQuery <1.8
- // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways
- $( "<span>January&#xa0;2010</span>" ).text(), "Initial month" );
- $( "a.ui-datepicker-next", dp ).trigger( "click" );
- $( "a.ui-datepicker-next", dp ).trigger( "click" );
-
- // contains non-breaking space
- equal( $( "div.ui-datepicker-title" ).text(),
- $( "<span>March&#xa0;2010</span>" ).text(), "After next clicks" );
- inp.datepicker( "hide" ).datepicker( "show" );
- $( "a.ui-datepicker-prev", dp ).trigger( "click" );
- $( "a.ui-datepicker-prev", dp ).trigger( "click" );
-
- // contains non-breaking space
- equal( $( "div.ui-datepicker-title" ).text(),
- $( "<span>November&#xa0;2009</span>" ).text(), "After prev clicks" );
- inp.datepicker( "hide" );
+test( "close", function() {
+ expect( 4 );
+
+ var shouldFire,
+ input = testHelper.init( "#datepicker", {
+ close: function() {
+ ok( shouldFire, "close event fired" );
+ }
+ } );
+
+ shouldFire = false;
+ input.datepicker( "open" );
+ shouldFire = true;
+ input.datepicker( "close" );
+
+ shouldFire = false;
+ input.datepicker( "open" );
+ shouldFire = true;
+ $( "body" ).trigger( "mousedown" );
+
+ shouldFire = false;
+ input.datepicker( "open" );
+ shouldFire = true;
+ input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+
+ shouldFire = false;
+ input.datepicker( "open" );
+ shouldFire = true;
+ input.datepicker( "widget" ).find( "tbody tr:first button:first" ).simulate( "mousedown" );
+} );
+
+test( "open", function() {
+ expect( 2 );
+
+ var input = testHelper.init( "#datepicker", {
+ open: function() {
+ ok( true, "open event fired on open" );
+ ok( widget.is( ":visible" ), "calendar open on open" );
+ }
+ } ),
+ widget = input.datepicker( "widget" );
+
+ input.datepicker( "open" );
+} );
+
+asyncTest( "select", function() {
+ expect( 4 );
+
+ var input = testHelper.init( "#datepicker", {
+ select: function( event ) {
+ ok( true, "select event fired " + message );
+ equal(
+ event.originalEvent.type,
+ "calendarselect",
+ "select originalEvent " + message
+ );
+ }
+ } ),
+ widget = input.datepicker( "widget" ),
+ message = "";
+
+ function step1() {
+ message = "on calendar cell click";
+ input
+ .simulate( "focus" )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+ setTimeout( function() {
+ widget.find( "tbody tr:first button:first" ).simulate( "mousedown" );
+ input.datepicker( "close" );
+ step2();
+ }, 100 );
+ }
+
+ function step2() {
+ message = "on calendar cell enter";
+ input
+ .simulate( "focus" )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+ setTimeout( function() {
+ $( document.activeElement )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+ input.datepicker( "close" );
+ step3();
+ }, 100 );
+ }
+
+ function step3() {
+ message = "on calendar escape (not expected)";
+ input
+ .simulate( "focus" )
+ .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+ setTimeout( function() {
+ $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+ input.datepicker( "close" );
+ start();
+ }, 100 );
+ }
+
+ step1();
} );
} );
diff --git a/tests/unit/datepicker/helper.js b/tests/unit/datepicker/helper.js
index 4712a08da..81fdd9d00 100644
--- a/tests/unit/datepicker/helper.js
+++ b/tests/unit/datepicker/helper.js
@@ -11,7 +11,6 @@ return $.extend( helper, {
date.setMonth( date.getMonth() + offset );
return date;
},
-
equalsDate: function( d1, d2, message ) {
if ( !d1 || !d2 ) {
ok( false, message + " - missing date" );
@@ -21,18 +20,15 @@ return $.extend( helper, {
d2 = new Date( d2.getFullYear(), d2.getMonth(), d2.getDate() );
equal( d1.toString(), d2.toString(), message );
},
-
init: function( id, options ) {
- $.datepicker.setDefaults( $.datepicker.regional[ "" ] );
- return $( id ).datepicker( $.extend( { showAnim: "" }, options || {} ) );
+ options = $.extend( { show: false, hide: false }, options || {} );
+ return $( id ).datepicker( options );
},
-
initNewInput: function( options ) {
- var id = $( "<input>" ).appendTo( "#qunit-fixture" );
- return this.init( id, options );
- },
-
- PROP_NAME: "datepicker"
+ options = $.extend( { show: false, hide: false }, options || {} );
+ return $( "<input>" ).datepicker( options )
+ .appendTo( "#qunit-fixture" );
+ }
} );
} );
diff --git a/tests/unit/datepicker/methods.js b/tests/unit/datepicker/methods.js
index fcf8c2104..2cf835698 100644
--- a/tests/unit/datepicker/methods.js
+++ b/tests/unit/datepicker/methods.js
@@ -6,128 +6,123 @@ define( [
module( "datepicker: methods" );
-test( "destroy", function() {
- expect( 33 );
- var inl,
- inp = testHelper.init( "#inp" );
- ok( inp.is( ".hasDatepicker" ), "Default - marker class set" );
- ok( $.data( inp[ 0 ], testHelper.PROP_NAME ), "Default - instance present" );
- ok( inp.next().is( "#alt" ), "Default - button absent" );
- inp.datepicker( "destroy" );
- inp = $( "#inp" );
- ok( !inp.is( ".hasDatepicker" ), "Default - marker class cleared" );
- ok( !$.data( inp[ 0 ], testHelper.PROP_NAME ), "Default - instance absent" );
- ok( inp.next().is( "#alt" ), "Default - button absent" );
-
- // With button
- inp = testHelper.init( "#inp", { showOn: "both" } );
- ok( inp.is( ".hasDatepicker" ), "Button - marker class set" );
- ok( $.data( inp[ 0 ], testHelper.PROP_NAME ), "Button - instance present" );
- ok( inp.next().text() === "...", "Button - button added" );
- inp.datepicker( "destroy" );
- inp = $( "#inp" );
- ok( !inp.is( ".hasDatepicker" ), "Button - marker class cleared" );
- ok( !$.data( inp[ 0 ], testHelper.PROP_NAME ), "Button - instance absent" );
- ok( inp.next().is( "#alt" ), "Button - button removed" );
-
- // With append text
- inp = testHelper.init( "#inp", { appendText: "Testing" } );
- ok( inp.is( ".hasDatepicker" ), "Append - marker class set" );
- ok( $.data( inp[ 0 ], testHelper.PROP_NAME ), "Append - instance present" );
- ok( inp.next().text() === "Testing", "Append - append text added" );
- inp.datepicker( "destroy" );
- inp = $( "#inp" );
- ok( !inp.is( ".hasDatepicker" ), "Append - marker class cleared" );
- ok( !$.data( inp[ 0 ], testHelper.PROP_NAME ), "Append - instance absent" );
- ok( inp.next().is( "#alt" ), "Append - append text removed" );
-
- // With both
- inp = testHelper.init( "#inp", { showOn: "both", buttonImageOnly: true,
- buttonImage: "images/calendar.gif", appendText: "Testing" } );
- ok( inp.is( ".hasDatepicker" ), "Both - marker class set" );
- ok( $.data( inp[ 0 ], testHelper.PROP_NAME ), "Both - instance present" );
- ok( inp.next()[ 0 ].nodeName.toLowerCase() === "img", "Both - button added" );
- ok( inp.next().next().text() === "Testing", "Both - append text added" );
- inp.datepicker( "destroy" );
- inp = $( "#inp" );
- ok( !inp.is( ".hasDatepicker" ), "Both - marker class cleared" );
- ok( !$.data( inp[ 0 ], testHelper.PROP_NAME ), "Both - instance absent" );
- ok( inp.next().is( "#alt" ), "Both - button and append text absent" );
-
- // Inline
- inl = testHelper.init( "#inl" );
- ok( inl.is( ".hasDatepicker" ), "Inline - marker class set" );
- ok( inl.html() !== "", "Inline - datepicker present" );
- ok( $.data( inl[ 0 ], testHelper.PROP_NAME ), "Inline - instance present" );
- ok( inl.next().length === 0 || inl.next().is( "p" ), "Inline - button absent" );
- inl.datepicker( "destroy" );
- inl = $( "#inl" );
- ok( !inl.is( ".hasDatepicker" ), "Inline - marker class cleared" );
- ok( inl.html() === "", "Inline - datepicker absent" );
- ok( !$.data( inl[ 0 ], testHelper.PROP_NAME ), "Inline - instance absent" );
- ok( inl.next().length === 0 || inl.next().is( "p" ), "Inline - button absent" );
+test( "destroy", function( assert ) {
+ expect( 3 );
+
+ var input = $( "#datepicker" );
+ assert.domEqual( input, function() {
+ input.datepicker();
+ ok( input.attr( "aria-owns" ), "aria-owns attribute added" );
+ ok( input.attr( "aria-haspopup" ), "aria-haspopup attribute added" );
+ input.datepicker( "destroy" );
+ } );
+} );
+
+test( "enable / disable", function() {
+ expect( 10 );
+
+ var input = testHelper.init( "#datepicker" ),
+ calendar = input.datepicker( "widget" );
+
+ input.datepicker( "disable" );
+ ok( input.datepicker( "option", "disabled" ), "disabled option is set" );
+ ok( calendar.hasClass( "ui-datepicker-disabled" ), "has disabled widget class name" );
+ ok( input.hasClass( "ui-state-disabled" ), "has disabled state class name" );
+ equal( input.attr( "aria-disabled" ), "true", "has ARIA disabled" );
+ equal( input.attr( "disabled" ), "disabled", "input disabled" );
+
+ input.datepicker( "enable" );
+ ok( !input.datepicker( "option", "disabled" ), "enabled after enable() call" );
+ ok( !calendar.hasClass( "ui-datepicker-disabled" ), "no longer has disabled widget class name" );
+ ok( !input.hasClass( "ui-state-disabled" ), "no longer has disabled state class name" );
+ equal( input.attr( "aria-disabled" ), "false", "no longer has ARIA disabled" );
+ equal( input.attr( "disabled" ), undefined, "input no longer disabled" );
+} );
+
+test( "widget", function() {
+ expect( 1 );
+
+ var actual = $( "#datepicker" ).datepicker().datepicker( "widget" );
+ deepEqual( $( "body > .ui-front" )[ 0 ], actual[ 0 ] );
+ actual.remove();
+} );
+
+test( "open / close", function() {
+ expect( 7 );
+
+ var input = testHelper.initNewInput( { show: false, hide: false } ),
+ calendar = input.datepicker( "widget" );
+
+ ok( calendar.is( ":hidden" ), "calendar hidden on init" );
+
+ input.datepicker( "open" );
+ ok( calendar.is( ":visible" ), "open: calendar visible" );
+ equal( calendar.attr( "aria-hidden" ), "false", "open: calendar aria-hidden" );
+ equal( calendar.attr( "aria-expanded" ), "true", "close: calendar aria-expanded" );
+
+ input.datepicker( "close" );
+ ok( !calendar.is( ":visible" ), "close: calendar hidden" );
+ equal( calendar.attr( "aria-hidden" ), "true", "close: calendar aria-hidden" );
+ equal( calendar.attr( "aria-expanded" ), "false", "close: calendar aria-expanded" );
} );
-test( "enableDisable", function() {
- expect( 33 );
- var inl, dp,
- inp = testHelper.init( "#inp" );
- ok( !inp.datepicker( "isDisabled" ), "Enable/disable - initially marked as enabled" );
- ok( !inp[ 0 ].disabled, "Enable/disable - field initially enabled" );
- inp.datepicker( "disable" );
- ok( inp.datepicker( "isDisabled" ), "Enable/disable - now marked as disabled" );
- ok( inp[ 0 ].disabled, "Enable/disable - field now disabled" );
- inp.datepicker( "enable" );
- ok( !inp.datepicker( "isDisabled" ), "Enable/disable - now marked as enabled" );
- ok( !inp[ 0 ].disabled, "Enable/disable - field now enabled" );
- inp.datepicker( "destroy" );
-
- // With a button
- inp = testHelper.init( "#inp", { showOn: "button" } );
- ok( !inp.datepicker( "isDisabled" ), "Enable/disable button - initially marked as enabled" );
- ok( !inp[ 0 ].disabled, "Enable/disable button - field initially enabled" );
- ok( !inp.next( "button" )[ 0 ].disabled, "Enable/disable button - button initially enabled" );
- inp.datepicker( "disable" );
- ok( inp.datepicker( "isDisabled" ), "Enable/disable button - now marked as disabled" );
- ok( inp[ 0 ].disabled, "Enable/disable button - field now disabled" );
- ok( inp.next( "button" )[ 0 ].disabled, "Enable/disable button - button now disabled" );
- inp.datepicker( "enable" );
- ok( !inp.datepicker( "isDisabled" ), "Enable/disable button - now marked as enabled" );
- ok( !inp[ 0 ].disabled, "Enable/disable button - field now enabled" );
- ok( !inp.next( "button" )[ 0 ].disabled, "Enable/disable button - button now enabled" );
- inp.datepicker( "destroy" );
-
- // With an image button
- inp = testHelper.init( "#inp", { showOn: "button", buttonImageOnly: true,
- buttonImage: "images/calendar.gif" } );
- ok( !inp.datepicker( "isDisabled" ), "Enable/disable image - initially marked as enabled" );
- ok( !inp[ 0 ].disabled, "Enable/disable image - field initially enabled" );
- ok( parseFloat( inp.next( "img" ).css( "opacity" ) ) === 1, "Enable/disable image - image initially enabled" );
- inp.datepicker( "disable" );
- ok( inp.datepicker( "isDisabled" ), "Enable/disable image - now marked as disabled" );
- ok( inp[ 0 ].disabled, "Enable/disable image - field now disabled" );
- ok( parseFloat( inp.next( "img" ).css( "opacity" ) ) !== 1, "Enable/disable image - image now disabled" );
- inp.datepicker( "enable" );
- ok( !inp.datepicker( "isDisabled" ), "Enable/disable image - now marked as enabled" );
- ok( !inp[ 0 ].disabled, "Enable/disable image - field now enabled" );
- ok( parseFloat( inp.next( "img" ).css( "opacity" ) ) === 1, "Enable/disable image - image now enabled" );
- inp.datepicker( "destroy" );
-
- // Inline
- inl = testHelper.init( "#inl", { changeYear: true } );
- dp = $( ".ui-datepicker-inline", inl );
- ok( !inl.datepicker( "isDisabled" ), "Enable/disable inline - initially marked as enabled" );
- ok( !dp.children().is( ".ui-state-disabled" ), "Enable/disable inline - not visually disabled initially" );
- ok( !dp.find( "select" ).prop( "disabled" ), "Enable/disable inline - form element enabled initially" );
- inl.datepicker( "disable" );
- ok( inl.datepicker( "isDisabled" ), "Enable/disable inline - now marked as disabled" );
- ok( dp.children().is( ".ui-state-disabled" ), "Enable/disable inline - visually disabled" );
- ok( dp.find( "select" ).prop( "disabled" ), "Enable/disable inline - form element disabled" );
- inl.datepicker( "enable" );
- ok( !inl.datepicker( "isDisabled" ), "Enable/disable inline - now marked as enabled" );
- ok( !dp.children().is( ".ui-state-disabled" ), "Enable/disable inline - not visiually disabled" );
- ok( !dp.find( "select" ).prop( "disabled" ), "Enable/disable inline - form element enabled" );
- inl.datepicker( "destroy" );
+test( "value", function() {
+ expect( 4 );
+
+ var input = $( "#datepicker" ).datepicker(),
+ picker = input.datepicker( "widget" );
+
+ input.datepicker( "value", "1/1/14" );
+ equal( input.val(), "1/1/14", "input's value set" );
+
+ input.datepicker( "open" );
+ ok(
+ picker.find( "button[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ),
+ "first day marked as selected"
+ );
+ equal( input.datepicker( "value" ), "1/1/14", "getter" );
+
+ input.val( "abc" );
+ strictEqual( input.datepicker( "value" ), null, "Invalid values should return null." );
+} );
+
+test( "valueAsDate", function() {
+ expect( 6 );
+
+ var input = testHelper.init( "#datepicker" ),
+ picker = input.datepicker( "widget" ),
+ date1 = new Date( 2008, 6 - 1, 4 );
+
+ input.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) );
+ equal( input.val(), "1/1/14", "Input's value set" );
+ ok(
+ picker.find( "button[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ),
+ "First day marked as selected"
+ );
+ testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" );
+
+ input.val( "a/b/c" );
+ equal( input.datepicker( "valueAsDate" ), null, "Invalid dates return null" );
+
+ input.val( "" ).datepicker( "destroy" );
+ input = testHelper.init( "#datepicker" );
+
+ strictEqual( input.datepicker( "valueAsDate" ), null, "Set date - default" );
+ input.datepicker( "valueAsDate", date1 );
+ testHelper.equalsDate( input.datepicker( "valueAsDate" ), date1, "Set date - 2008-06-04" );
+} );
+
+test( "isValid", function() {
+ expect( 2 );
+ var input = $( "#datepicker" ).datepicker();
+
+ input.val( "1/1/14" );
+ ok( input.datepicker( "isValid" ) );
+
+ input.val( "1/1/abc" );
+ ok( !input.datepicker( "isValid" ) );
+
+ input.datepicker( "destroy" );
} );
} );
diff --git a/tests/unit/datepicker/options.js b/tests/unit/datepicker/options.js
index 794487f72..6021f1b7e 100644
--- a/tests/unit/datepicker/options.js
+++ b/tests/unit/datepicker/options.js
@@ -1,1152 +1,141 @@
define( [
"jquery",
"./helper",
- "ui/widgets/datepicker",
- "ui/i18n/datepicker-fr",
- "ui/i18n/datepicker-he",
- "ui/i18n/datepicker-zh-CN",
- "ui/ie"
+ "ui/widgets/datepicker"
], function( $, testHelper ) {
module( "datepicker: options" );
-test( "setDefaults", function() {
- expect( 3 );
- testHelper.init( "#inp" );
- equal( $.datepicker._defaults.showOn, "focus", "Initial showOn" );
- $.datepicker.setDefaults( { showOn: "button" } );
- equal( $.datepicker._defaults.showOn, "button", "Change default showOn" );
- $.datepicker.setDefaults( { showOn: "focus" } );
- equal( $.datepicker._defaults.showOn, "focus", "Restore showOn" );
-} );
-
-test( "option", function() {
- expect( 17 );
- var inp = testHelper.init( "#inp" ),
- inst = $.data( inp[ 0 ], testHelper.PROP_NAME );
-
- // Set option
- equal( inst.settings.showOn, null, "Initial setting showOn" );
- equal( $.datepicker._get( inst, "showOn" ), "focus", "Initial instance showOn" );
- equal( $.datepicker._defaults.showOn, "focus", "Initial default showOn" );
- inp.datepicker( "option", "showOn", "button" );
- equal( inst.settings.showOn, "button", "Change setting showOn" );
- equal( $.datepicker._get( inst, "showOn" ), "button", "Change instance showOn" );
- equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" );
- inp.datepicker( "option", { showOn: "both" } );
- equal( inst.settings.showOn, "both", "Change setting showOn" );
- equal( $.datepicker._get( inst, "showOn" ), "both", "Change instance showOn" );
- equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" );
- inp.datepicker( "option", "showOn", undefined );
- equal( inst.settings.showOn, null, "Clear setting showOn" );
- equal( $.datepicker._get( inst, "showOn" ), "focus", "Restore instance showOn" );
- equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" );
-
- // Get option
- inp = testHelper.init( "#inp" );
- equal( inp.datepicker( "option", "showOn" ), "focus", "Initial setting showOn" );
- inp.datepicker( "option", "showOn", "button" );
- equal( inp.datepicker( "option", "showOn" ), "button", "Change instance showOn" );
- inp.datepicker( "option", "showOn", undefined );
- equal( inp.datepicker( "option", "showOn" ), "focus", "Reset instance showOn" );
- deepEqual( inp.datepicker( "option", "all" ), { showAnim: "" }, "Get instance settings" );
- deepEqual( inp.datepicker( "option", "defaults" ), $.datepicker._defaults,
- "Get default settings" );
-} );
-
-test( "disabled", function() {
- expect( 8 );
- var inp = testHelper.init( "#inp" );
- ok( !inp.datepicker( "isDisabled" ), "Initially marked as enabled" );
- ok( !inp[ 0 ].disabled, "Field initially enabled" );
- inp.datepicker( "option", "disabled", true );
- ok( inp.datepicker( "isDisabled" ), "Marked as disabled" );
- ok( inp[ 0 ].disabled, "Field now disabled" );
- inp.datepicker( "option", "disabled", false );
- ok( !inp.datepicker( "isDisabled" ), "Marked as enabled" );
- ok( !inp[ 0 ].disabled, "Field now enabled" );
- inp.datepicker( "destroy" );
-
- inp = testHelper.init( "#inp", { disabled: true } );
- ok( inp.datepicker( "isDisabled" ), "Initially marked as disabled" );
- ok( inp[ 0 ].disabled, "Field initially disabled" );
-} );
-
-test( "change", function() {
- expect( 12 );
- var inp = testHelper.init( "#inp" ),
- inst = $.data( inp[ 0 ], testHelper.PROP_NAME );
- equal( inst.settings.showOn, null, "Initial setting showOn" );
- equal( $.datepicker._get( inst, "showOn" ), "focus", "Initial instance showOn" );
- equal( $.datepicker._defaults.showOn, "focus", "Initial default showOn" );
- inp.datepicker( "change", "showOn", "button" );
- equal( inst.settings.showOn, "button", "Change setting showOn" );
- equal( $.datepicker._get( inst, "showOn" ), "button", "Change instance showOn" );
- equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" );
- inp.datepicker( "change", { showOn: "both" } );
- equal( inst.settings.showOn, "both", "Change setting showOn" );
- equal( $.datepicker._get( inst, "showOn" ), "both", "Change instance showOn" );
- equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" );
- inp.datepicker( "change", "showOn", undefined );
- equal( inst.settings.showOn, null, "Clear setting showOn" );
- equal( $.datepicker._get( inst, "showOn" ), "focus", "Restore instance showOn" );
- equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" );
-} );
-
-( function() {
- var url = window.location.search;
- url = decodeURIComponent( url.slice( url.indexOf( "swarmURL=" ) + 9 ) );
-
- // TODO: This test occassionally fails in IE in TestSwarm
- if ( $.ui.ie && url && url.indexOf( "http" ) === 0 ) {
- return;
- }
-
- asyncTest( "invocation", function() {
- var button, image,
- isOldIE = $.ui.ie && ( !document.documentMode || document.documentMode < 9 ),
- body = $( "body" );
-
- expect( isOldIE ? 25 : 29 );
-
- function step0() {
- var inp = testHelper.initNewInput(),
- dp = $( "#ui-datepicker-div" );
-
- button = inp.siblings( "button" );
- ok( button.length === 0, "Focus - button absent" );
- image = inp.siblings( "img" );
- ok( image.length === 0, "Focus - image absent" );
-
- testHelper.onFocus( inp, function() {
- ok( dp.is( ":visible" ), "Focus - rendered on focus" );
- inp.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
- ok( !dp.is( ":visible" ), "Focus - hidden on exit" );
- step1();
- } );
- }
-
- function step1() {
-
- var inp = testHelper.initNewInput(),
- dp = $( "#ui-datepicker-div" );
-
- testHelper.onFocus( inp, function() {
- ok( dp.is( ":visible" ), "Focus - rendered on focus" );
- body.simulate( "mousedown", {} );
- ok( !dp.is( ":visible" ), "Focus - hidden on external click" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
-
- step2();
- } );
+test( "appendTo", function() {
+ expect( 6 );
+ var container,
+ detached = $( "<div>" ),
+ input = $( "#datepicker" );
+
+ input.datepicker();
+ container = input.datepicker( "widget" ).parent()[ 0 ];
+ equal( container, document.body, "defaults to body" );
+ input.datepicker( "destroy" );
+
+ input.datepicker( { appendTo: "#qunit-fixture" } );
+ container = input.datepicker( "widget" ).parent()[ 0 ];
+ equal( container, $( "#qunit-fixture" )[ 0 ], "child of specified element" );
+ input.datepicker( "destroy" );
+
+ input.datepicker( { appendTo: "#does-not-exist" } );
+ container = input.datepicker( "widget" ).parent()[ 0 ];
+ equal( container, document.body, "set to body if element does not exist" );
+ input.datepicker( "destroy" );
+
+ input.datepicker()
+ .datepicker( "option", "appendTo", "#qunit-fixture" );
+ container = input.datepicker( "widget" ).parent()[ 0 ];
+ equal( container, $( "#qunit-fixture" )[ 0 ], "modified after init" );
+ input.datepicker( "destroy" );
+
+ input.datepicker( { appendTo: detached } );
+ container = input.datepicker( "widget" ).parent()[ 0 ];
+ equal( container, detached[ 0 ], "detached jQuery object" );
+ input.datepicker( "destroy" );
+
+ input.datepicker( { appendTo: detached[ 0 ] } );
+ container = input.datepicker( "widget" ).parent()[ 0 ];
+ equal( container, detached[ 0 ], "detached DOM element" );
+ input.datepicker( "destroy" );
+} );
+
+test( "Pass-through options", function() {
+ expect( 11 );
+
+ var options = {
+ buttons: { "Test": $.noop },
+ dateFormat: { date: "full" },
+ disabled: true,
+ eachDay: function( day ) { day; },
+ locale: "de",
+ max: new Date( 2000, 0, 1 ),
+ min: new Date( 2000, 0, 2 ),
+ numberOfMonths: 3,
+ showWeek: true
+ },
+ input = $( "#datepicker" ).val( "1/1/14" ).datepicker(),
+ datepickerInstance = input.datepicker( "instance" );
+
+ $.each( options, function( key, value ) {
+ input.datepicker( "option", key, value );
+
+ deepEqual(
+ datepickerInstance.calendar.calendar( "option", key ),
+ value,
+ "option " + key + ": correct value"
+ );
+
+ if ( key === "dateFormat" ) {
+ equal( input.val(), "Wednesday, January 1, 2014", "option " + key + ": updated format" );
}
- function step2() {
- var inp = testHelper.initNewInput( {
- showOn: "button",
- buttonText: "Popup"
- } ),
- dp = $( "#ui-datepicker-div" );
-
- ok( !dp.is( ":visible" ), "Button - initially hidden" );
- button = inp.siblings( "button" );
- image = inp.siblings( "img" );
- ok( button.length === 1, "Button - button present" );
- ok( image.length === 0, "Button - image absent" );
- equal( button.text(), "Popup", "Button - button text" );
-
- testHelper.onFocus( inp, function() {
- ok( !dp.is( ":visible" ), "Button - not rendered on focus" );
- button.trigger( "click" );
- ok( dp.is( ":visible" ), "Button - rendered on button click" );
- button.trigger( "click" );
- ok( !dp.is( ":visible" ), "Button - hidden on second button click" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
-
- step3();
- } );
- }
-
- function step3() {
- var inp = testHelper.initNewInput( {
- showOn: "button",
- buttonImageOnly: true,
- buttonImage: "images/calendar.gif",
- buttonText: "Cal"
- } ),
- dp = $( "#ui-datepicker-div" );
-
- ok( !dp.is( ":visible" ), "Image button - initially hidden" );
- button = inp.siblings( "button" );
- ok( button.length === 0, "Image button - button absent" );
- image = inp.siblings( "img" );
- ok( image.length === 1, "Image button - image present" );
- ok( /images\/calendar\.gif$/.test( image.attr( "src" ) ), "Image button - image source" );
- equal( image.attr( "title" ), "Cal", "Image button - image text" );
-
- testHelper.onFocus( inp, function() {
- ok( !dp.is( ":visible" ), "Image button - not rendered on focus" );
- image.trigger( "click" );
- ok( dp.is( ":visible" ), "Image button - rendered on image click" );
- image.trigger( "click" );
- ok( !dp.is( ":visible" ), "Image button - hidden on second image click" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
-
- step4();
- } );
- }
-
- function step4() {
- var inp = testHelper.initNewInput( {
- showOn: "both",
- buttonImage: "images/calendar.gif"
- } ),
- dp = $( "#ui-datepicker-div" );
-
- ok( !dp.is( ":visible" ), "Both - initially hidden" );
- button = inp.siblings( "button" );
- ok( button.length === 1, "Both - button present" );
- image = inp.siblings( "img" );
- ok( image.length === 0, "Both - image absent" );
- image = button.children( "img" );
- ok( image.length === 1, "Both - button image present" );
-
- // TODO: This test occasionally fails to focus in IE8 in BrowserStack
- if ( !isOldIE ) {
- testHelper.onFocus( inp, function() {
- ok( dp.is( ":visible" ), "Both - rendered on focus" );
- body.simulate( "mousedown", {} );
- ok( !dp.is( ":visible" ), "Both - hidden on external click" );
- button.trigger( "click" );
- ok( dp.is( ":visible" ), "Both - rendered on button click" );
- button.trigger( "click" );
- ok( !dp.is( ":visible" ), "Both - hidden on second button click" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
-
- start();
- } );
- } else {
- start();
- }
- }
-
- step0();
- } );
-} )();
-
-test( "otherMonths", function() {
- expect( 8 );
- var inp = testHelper.init( "#inp" ),
- pop = $( "#ui-datepicker-div" );
- inp.val( "06/01/2009" ).datepicker( "show" );
- equal( pop.find( "tbody" ).text(),
-
- // support: IE <9, jQuery <1.8
- // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways
- $( "<span>\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0</span>" ).text(),
- "Other months - none" );
- ok( pop.find( "td:last *" ).length === 0, "Other months - no content" );
- inp.datepicker( "hide" ).datepicker( "option", "showOtherMonths", true ).datepicker( "show" );
- equal( pop.find( "tbody" ).text(), "311234567891011121314151617181920212223242526272829301234",
- "Other months - show" );
- ok( pop.find( "td:last span" ).length === 1, "Other months - span content" );
- inp.datepicker( "hide" ).datepicker( "option", "selectOtherMonths", true ).datepicker( "show" );
- equal( pop.find( "tbody" ).text(), "311234567891011121314151617181920212223242526272829301234",
- "Other months - select" );
- ok( pop.find( "td:last a" ).length === 1, "Other months - link content" );
- inp.datepicker( "hide" ).datepicker( "option", "showOtherMonths", false ).datepicker( "show" );
- equal( pop.find( "tbody" ).text(),
-
- // support: IE <9, jQuery <1.8
- // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways
- $( "<span>\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0</span>" ).text(),
- "Other months - none" );
- ok( pop.find( "td:last *" ).length === 0, "Other months - no content" );
-} );
-
-test( "defaultDate", function() {
- expect( 16 );
- var inp = testHelper.init( "#inp" ),
- date = new Date();
- inp.val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date null" );
-
- // Numeric values
- inp.datepicker( "option", { defaultDate: -2 } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() - 2 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date -2" );
-
- date = new Date();
- inp.datepicker( "option", { defaultDate: 3 } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() + 3 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date 3" );
-
- date = new Date();
- inp.datepicker( "option", { defaultDate: 1 / "a" } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date NaN" );
-
- // String offset values
- inp.datepicker( "option", { defaultDate: "-1d" } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() - 1 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date -1d" );
- inp.datepicker( "option", { defaultDate: "+3D" } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() + 4 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date +3D" );
- inp.datepicker( "option", { defaultDate: " -2 w " } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date = new Date();
- date.setDate( date.getDate() - 14 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date -2 w" );
- inp.datepicker( "option", { defaultDate: "+1 W" } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setDate( date.getDate() + 21 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date +1 W" );
- inp.datepicker( "option", { defaultDate: " -1 m " } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date = testHelper.addMonths( new Date(), -1 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date -1 m" );
- inp.datepicker( "option", { defaultDate: "+2M" } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date = testHelper.addMonths( new Date(), 2 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date +2M" );
- inp.datepicker( "option", { defaultDate: "-2y" } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date = new Date();
- date.setFullYear( date.getFullYear() - 2 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date -2y" );
- inp.datepicker( "option", { defaultDate: "+1 Y " } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date.setFullYear( date.getFullYear() + 3 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date +1 Y" );
- inp.datepicker( "option", { defaultDate: "+1M +10d" } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date = testHelper.addMonths( new Date(), 1 );
- date.setDate( date.getDate() + 10 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date +1M +10d" );
-
- // String date values
- inp.datepicker( "option", { defaultDate: "07/04/2007" } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date = new Date( 2007, 7 - 1, 4 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date 07/04/2007" );
- inp.datepicker( "option", { dateFormat: "yy-mm-dd", defaultDate: "2007-04-02" } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date = new Date( 2007, 4 - 1, 2 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date 2007-04-02" );
-
- // Date value
- date = new Date( 2007, 1 - 1, 26 );
- inp.datepicker( "option", { dateFormat: "mm/dd/yy", defaultDate: date } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date, "Default date 01/26/2007" );
-} );
-
-test( "miscellaneous", function() {
- expect( 19 );
- var curYear, longNames, shortNames, date,
- dp = $( "#ui-datepicker-div" ),
- inp = testHelper.init( "#inp" );
-
- // Year range
- function genRange( start, offset ) {
- var i = start,
- range = "";
- for ( ; i < start + offset; i++ ) {
- range += i;
- }
- return range;
- }
- curYear = new Date().getFullYear();
- inp.val( "02/04/2008" ).datepicker( "show" );
- equal( dp.find( ".ui-datepicker-year" ).text(), "2008", "Year range - read-only default" );
- inp.datepicker( "hide" ).datepicker( "option", { changeYear: true } ).datepicker( "show" );
- equal( dp.find( ".ui-datepicker-year" ).text(), genRange( 2008 - 10, 21 ), "Year range - changeable default" );
- inp.datepicker( "hide" ).datepicker( "option", { yearRange: "c-6:c+2", changeYear: true } ).datepicker( "show" );
- equal( dp.find( ".ui-datepicker-year" ).text(), genRange( 2008 - 6, 9 ), "Year range - c-6:c+2" );
- inp.datepicker( "hide" ).datepicker( "option", { yearRange: "2000:2010", changeYear: true } ).datepicker( "show" );
- equal( dp.find( ".ui-datepicker-year" ).text(), genRange( 2000, 11 ), "Year range - 2000:2010" );
- inp.datepicker( "hide" ).datepicker( "option", { yearRange: "-5:+3", changeYear: true } ).datepicker( "show" );
- equal( dp.find( ".ui-datepicker-year" ).text(), genRange( curYear - 5, 9 ), "Year range - -5:+3" );
- inp.datepicker( "hide" ).datepicker( "option", { yearRange: "2000:-5", changeYear: true } ).datepicker( "show" );
- equal( dp.find( ".ui-datepicker-year" ).text(), genRange( 2000, curYear - 2004 ), "Year range - 2000:-5" );
- inp.datepicker( "hide" ).datepicker( "option", { yearRange: "", changeYear: true } ).datepicker( "show" );
- equal( dp.find( ".ui-datepicker-year" ).text(), genRange( curYear, 1 ), "Year range - -6:+2" );
-
- // Navigation as date format
- inp.datepicker( "option", { showButtonPanel: true } );
- equal( dp.find( ".ui-datepicker-prev" ).text(), "Prev", "Navigation prev - default" );
- equal( dp.find( ".ui-datepicker-current" ).text(), "Today", "Navigation current - default" );
- equal( dp.find( ".ui-datepicker-next" ).text(), "Next", "Navigation next - default" );
- inp.datepicker( "hide" ).datepicker( "option", { navigationAsDateFormat: true, prevText: "< M", currentText: "MM", nextText: "M >" } ).
- val( "02/04/2008" ).datepicker( "show" );
- longNames = $.datepicker.regional[ "" ].monthNames;
- shortNames = $.datepicker.regional[ "" ].monthNamesShort;
- date = new Date();
- equal( dp.find( ".ui-datepicker-prev" ).text(), "< " + shortNames[ 0 ], "Navigation prev - as date format" );
- equal( dp.find( ".ui-datepicker-current" ).text(),
- longNames[ date.getMonth() ], "Navigation current - as date format" );
- equal( dp.find( ".ui-datepicker-next" ).text(),
- shortNames[ 2 ] + " >", "Navigation next - as date format" );
- inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
- equal( dp.find( ".ui-datepicker-prev" ).text(),
- "< " + shortNames[ 1 ], "Navigation prev - as date format + pgdn" );
- equal( dp.find( ".ui-datepicker-current" ).text(),
- longNames[ date.getMonth() ], "Navigation current - as date format + pgdn" );
- equal( dp.find( ".ui-datepicker-next" ).text(),
- shortNames[ 3 ] + " >", "Navigation next - as date format + pgdn" );
- inp.datepicker( "hide" ).datepicker( "option", { gotoCurrent: true } ).
- val( "02/04/2008" ).datepicker( "show" );
- equal( dp.find( ".ui-datepicker-prev" ).text(),
- "< " + shortNames[ 0 ], "Navigation prev - as date format + goto current" );
- equal( dp.find( ".ui-datepicker-current" ).text(),
- longNames[ 1 ], "Navigation current - as date format + goto current" );
- equal( dp.find( ".ui-datepicker-next" ).text(),
- shortNames[ 2 ] + " >", "Navigation next - as date format + goto current" );
-} );
-
-test( "minMax", function() {
- expect( 23 );
- var date,
- inp = testHelper.init( "#inp" ),
- dp = $( "#ui-datepicker-div" ),
- lastYear = new Date( 2007, 6 - 1, 4 ),
- nextYear = new Date( 2009, 6 - 1, 4 ),
- minDate = new Date( 2008, 2 - 1, 29 ),
- maxDate = new Date( 2008, 12 - 1, 7 );
- inp.val( "06/04/2008" ).datepicker( "show" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), lastYear,
- "Min/max - null, null - ctrl+pgup" );
- inp.val( "06/04/2008" ).datepicker( "show" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), nextYear,
- "Min/max - null, null - ctrl+pgdn" );
- inp.datepicker( "option", { minDate: minDate } ).
- datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), minDate,
- "Min/max - 02/29/2008, null - ctrl+pgup" );
- inp.val( "06/04/2008" ).datepicker( "show" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), nextYear,
- "Min/max - 02/29/2008, null - ctrl+pgdn" );
- inp.datepicker( "option", { maxDate: maxDate } ).
- datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), minDate,
- "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgup" );
- inp.val( "06/04/2008" ).datepicker( "show" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), maxDate,
- "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgdn" );
- inp.datepicker( "option", { minDate: null } ).
- datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), lastYear,
- "Min/max - null, 12/07/2008 - ctrl+pgup" );
- inp.val( "06/04/2008" ).datepicker( "show" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), maxDate,
- "Min/max - null, 12/07/2008 - ctrl+pgdn" );
-
- // Relative dates
- date = new Date();
- date.setDate( date.getDate() - 7 );
- inp.datepicker( "option", { minDate: "-1w", maxDate: "+1 M +10 D " } ).
- datepicker( "hide" ).val( "" ).datepicker( "show" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date,
- "Min/max - -1w, +1 M +10 D - ctrl+pgup" );
- date = testHelper.addMonths( new Date(), 1 );
- date.setDate( date.getDate() + 10 );
- inp.val( "" ).datepicker( "show" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date,
- "Min/max - -1w, +1 M +10 D - ctrl+pgdn" );
-
- // With existing date
- inp = testHelper.init( "#inp" );
- inp.val( "06/04/2008" ).datepicker( "option", { minDate: minDate } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - setDate > min" );
- inp.datepicker( "option", { minDate: null } ).val( "01/04/2008" ).datepicker( "option", { minDate: minDate } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), minDate, "Min/max - setDate < min" );
- inp.datepicker( "option", { minDate: null } ).val( "06/04/2008" ).datepicker( "option", { maxDate: maxDate } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - setDate < max" );
- inp.datepicker( "option", { maxDate: null } ).val( "01/04/2009" ).datepicker( "option", { maxDate: maxDate } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), maxDate, "Min/max - setDate > max" );
- inp.datepicker( "option", { maxDate: null } ).val( "01/04/2008" ).datepicker( "option", { minDate: minDate, maxDate: maxDate } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), minDate, "Min/max - setDate < min" );
- inp.datepicker( "option", { maxDate: null } ).val( "06/04/2008" ).datepicker( "option", { minDate: minDate, maxDate: maxDate } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - setDate > min, < max" );
- inp.datepicker( "option", { maxDate: null } ).val( "01/04/2009" ).datepicker( "option", { minDate: minDate, maxDate: maxDate } );
- testHelper.equalsDate( inp.datepicker( "getDate" ), maxDate, "Min/max - setDate > max" );
-
- inp.datepicker( "option", { yearRange: "-0:+1" } ).val( "01/01/" + new Date().getFullYear() );
- ok( dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - previous button disabled at 1/1/minYear" );
- inp.datepicker( "setDate", "12/30/" + new Date().getFullYear() );
- ok( dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - next button disabled at 12/30/maxYear" );
-
- inp.datepicker( "option", {
- minDate: new Date( 1900, 0, 1 ),
- maxDate: "-7Y",
- yearRange: "1900:-7"
- } ).val( "" );
- ok( dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - relative - next button disabled" );
- ok( !dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - relative - prev button enabled" );
-
- inp.datepicker( "option", {
- minDate: new Date( 1900, 0, 1 ),
- maxDate: "1/25/2007",
- yearRange: "1900:2007"
- } ).val( "" );
- ok( dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - absolute - next button disabled" );
- ok( !dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - absolute - prev button enabled" );
-} );
-
-test( "setDate", function() {
- expect( 24 );
- var inl, alt, minDate, maxDate, dateAndTimeToSet, dateAndTimeClone,
- inp = testHelper.init( "#inp" ),
- date1 = new Date( 2008, 6 - 1, 4 ),
- date2 = new Date();
- ok( inp.datepicker( "getDate" ) == null, "Set date - default" );
- inp.datepicker( "setDate", date1 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date1, "Set date - 2008-06-04" );
- date1 = new Date();
- date1.setDate( date1.getDate() + 7 );
- inp.datepicker( "setDate", +7 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date1, "Set date - +7" );
- date2.setFullYear( date2.getFullYear() + 2 );
- inp.datepicker( "setDate", "+2y" );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date2, "Set date - +2y" );
- inp.datepicker( "setDate", date1, date2 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date1, "Set date - two dates" );
- inp.datepicker( "setDate" );
- ok( inp.datepicker( "getDate" ) == null, "Set date - null" );
-
- // Relative to current date
- date1 = new Date();
- date1.setDate( date1.getDate() + 7 );
- inp.datepicker( "setDate", "c +7" );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date1, "Set date - c +7" );
- date1.setDate( date1.getDate() + 7 );
- inp.datepicker( "setDate", "c+7" );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date1, "Set date - c+7" );
- date1.setDate( date1.getDate() - 21 );
- inp.datepicker( "setDate", "c -3 w" );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date1, "Set date - c -3 w" );
-
- // Inline
- inl = testHelper.init( "#inl" );
- date1 = new Date( 2008, 6 - 1, 4 );
- date2 = new Date();
- testHelper.equalsDate( inl.datepicker( "getDate" ), date2, "Set date inline - default" );
- inl.datepicker( "setDate", date1 );
- testHelper.equalsDate( inl.datepicker( "getDate" ), date1, "Set date inline - 2008-06-04" );
- date1 = new Date();
- date1.setDate( date1.getDate() + 7 );
- inl.datepicker( "setDate", +7 );
- testHelper.equalsDate( inl.datepicker( "getDate" ), date1, "Set date inline - +7" );
- date2.setFullYear( date2.getFullYear() + 2 );
- inl.datepicker( "setDate", "+2y" );
- testHelper.equalsDate( inl.datepicker( "getDate" ), date2, "Set date inline - +2y" );
- inl.datepicker( "setDate", date1, date2 );
- testHelper.equalsDate( inl.datepicker( "getDate" ), date1, "Set date inline - two dates" );
- inl.datepicker( "setDate" );
- ok( inl.datepicker( "getDate" ) == null, "Set date inline - null" );
-
- // Alternate field
- alt = $( "#alt" );
- inp.datepicker( "option", { altField: "#alt", altFormat: "yy-mm-dd" } );
- date1 = new Date( 2008, 6 - 1, 4 );
- inp.datepicker( "setDate", date1 );
- equal( inp.val(), "06/04/2008", "Set date alternate - 06/04/2008" );
- equal( alt.val(), "2008-06-04", "Set date alternate - 2008-06-04" );
-
- // With minimum/maximum
- inp = testHelper.init( "#inp" );
- date1 = new Date( 2008, 1 - 1, 4 );
- date2 = new Date( 2008, 6 - 1, 4 );
- minDate = new Date( 2008, 2 - 1, 29 );
- maxDate = new Date( 2008, 3 - 1, 28 );
- inp.val( "" ).datepicker( "option", { minDate: minDate } ).datepicker( "setDate", date2 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date2, "Set date min/max - setDate > min" );
- inp.datepicker( "setDate", date1 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), minDate, "Set date min/max - setDate < min" );
- inp.val( "" ).datepicker( "option", { maxDate: maxDate, minDate: null } ).datepicker( "setDate", date1 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), date1, "Set date min/max - setDate < max" );
- inp.datepicker( "setDate", date2 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), maxDate, "Set date min/max - setDate > max" );
- inp.val( "" ).datepicker( "option", { minDate: minDate } ).datepicker( "setDate", date1 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), minDate, "Set date min/max - setDate < min" );
- inp.datepicker( "setDate", date2 );
- testHelper.equalsDate( inp.datepicker( "getDate" ), maxDate, "Set date min/max - setDate > max" );
- dateAndTimeToSet = new Date( 2008, 3 - 1, 28, 1, 11, 0 );
- dateAndTimeClone = new Date( 2008, 3 - 1, 28, 1, 11, 0 );
- inp.datepicker( "setDate", dateAndTimeToSet );
- equal( dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), "Date object passed should not be changed by setDate" );
-} );
-
-test( "altField", function() {
- expect( 10 );
- var inp = testHelper.init( "#inp" ),
- alt = $( "#alt" );
-
- // No alternate field set
- alt.val( "" );
- inp.val( "06/04/2008" ).datepicker( "show" );
- inp.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- equal( inp.val(), "06/04/2008", "Alt field - dp - enter" );
- equal( alt.val(), "", "Alt field - alt not set" );
-
- // Alternate field set
- alt.val( "" );
- inp.datepicker( "option", { altField: "#alt", altFormat: "yy-mm-dd" } ).
- val( "06/04/2008" ).datepicker( "show" );
- inp.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- equal( inp.val(), "06/04/2008", "Alt field - dp - enter" );
- equal( alt.val(), "2008-06-04", "Alt field - alt - enter" );
-
- // Move from initial date
- alt.val( "" );
- inp.val( "06/04/2008" ).datepicker( "show" );
- inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- equal( inp.val(), "07/04/2008", "Alt field - dp - pgdn" );
- equal( alt.val(), "2008-07-04", "Alt field - alt - pgdn" );
-
- // Alternate field set - closed
- alt.val( "" );
- inp.val( "06/04/2008" ).datepicker( "show" );
- inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ).
- simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
- equal( inp.val(), "06/04/2008", "Alt field - dp - pgdn/esc" );
- equal( alt.val(), "", "Alt field - alt - pgdn/esc" );
-
- // Clear date and alternate
- alt.val( "" );
- inp.val( "06/04/2008" ).datepicker( "show" );
- inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } );
- equal( inp.val(), "", "Alt field - dp - ctrl+end" );
- equal( alt.val(), "", "Alt field - alt - ctrl+end" );
-} );
-
-test( "autoSize", function() {
- expect( 15 );
- var inp = testHelper.init( "#inp" );
- equal( inp.prop( "size" ), 20, "Auto size - default" );
- inp.datepicker( "option", "autoSize", true );
- equal( inp.prop( "size" ), 10, "Auto size - mm/dd/yy" );
- inp.datepicker( "option", "dateFormat", "m/d/yy" );
- equal( inp.prop( "size" ), 10, "Auto size - m/d/yy" );
- inp.datepicker( "option", "dateFormat", "D M d yy" );
- equal( inp.prop( "size" ), 15, "Auto size - D M d yy" );
- inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" );
- equal( inp.prop( "size" ), 29, "Auto size - DD, MM dd, yy" );
-
- // French
- inp.datepicker( "option", $.extend( { autoSize: false }, $.datepicker.regional.fr ) );
- equal( inp.prop( "size" ), 29, "Auto size - fr - default" );
- inp.datepicker( "option", "autoSize", true );
- equal( inp.prop( "size" ), 10, "Auto size - fr - dd/mm/yy" );
- inp.datepicker( "option", "dateFormat", "m/d/yy" );
- equal( inp.prop( "size" ), 10, "Auto size - fr - m/d/yy" );
- inp.datepicker( "option", "dateFormat", "D M d yy" );
- equal( inp.prop( "size" ), 18, "Auto size - fr - D M d yy" );
- inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" );
- equal( inp.prop( "size" ), 28, "Auto size - fr - DD, MM dd, yy" );
-
- // Hebrew
- inp.datepicker( "option", $.extend( { autoSize: false }, $.datepicker.regional.he ) );
- equal( inp.prop( "size" ), 28, "Auto size - he - default" );
- inp.datepicker( "option", "autoSize", true );
- equal( inp.prop( "size" ), 10, "Auto size - he - dd/mm/yy" );
- inp.datepicker( "option", "dateFormat", "m/d/yy" );
- equal( inp.prop( "size" ), 10, "Auto size - he - m/d/yy" );
- inp.datepicker( "option", "dateFormat", "D M d yy" );
- equal( inp.prop( "size" ), 16, "Auto size - he - D M d yy" );
- inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" );
- equal( inp.prop( "size" ), 23, "Auto size - he - DD, MM dd, yy" );
-} );
-
-test( "daylightSaving", function() {
- expect( 25 );
- var inp = testHelper.init( "#inp" ),
- dp = $( "#ui-datepicker-div" );
- ok( true, "Daylight saving - " + new Date() );
-
- // Australia, Sydney - AM change, southern hemisphere
- inp.val( "04/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(6) a", dp ).simulate( "click" );
- equal( inp.val(), "04/05/2008", "Daylight saving - Australia 04/05/2008" );
- inp.val( "04/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(7) a", dp ).simulate( "click" );
- equal( inp.val(), "04/06/2008", "Daylight saving - Australia 04/06/2008" );
- inp.val( "04/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(8) a", dp ).simulate( "click" );
- equal( inp.val(), "04/07/2008", "Daylight saving - Australia 04/07/2008" );
- inp.val( "10/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(6) a", dp ).simulate( "click" );
- equal( inp.val(), "10/04/2008", "Daylight saving - Australia 10/04/2008" );
- inp.val( "10/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(7) a", dp ).simulate( "click" );
- equal( inp.val(), "10/05/2008", "Daylight saving - Australia 10/05/2008" );
- inp.val( "10/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(8) a", dp ).simulate( "click" );
- equal( inp.val(), "10/06/2008", "Daylight saving - Australia 10/06/2008" );
-
- // Brasil, Brasilia - midnight change, southern hemisphere
- inp.val( "02/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(20) a", dp ).simulate( "click" );
- equal( inp.val(), "02/16/2008", "Daylight saving - Brasil 02/16/2008" );
- inp.val( "02/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(21) a", dp ).simulate( "click" );
- equal( inp.val(), "02/17/2008", "Daylight saving - Brasil 02/17/2008" );
- inp.val( "02/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(22) a", dp ).simulate( "click" );
- equal( inp.val(), "02/18/2008", "Daylight saving - Brasil 02/18/2008" );
- inp.val( "10/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(13) a", dp ).simulate( "click" );
- equal( inp.val(), "10/11/2008", "Daylight saving - Brasil 10/11/2008" );
- inp.val( "10/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(14) a", dp ).simulate( "click" );
- equal( inp.val(), "10/12/2008", "Daylight saving - Brasil 10/12/2008" );
- inp.val( "10/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(15) a", dp ).simulate( "click" );
- equal( inp.val(), "10/13/2008", "Daylight saving - Brasil 10/13/2008" );
-
- // Lebanon, Beirut - midnight change, northern hemisphere
- inp.val( "03/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(34) a", dp ).simulate( "click" );
- equal( inp.val(), "03/29/2008", "Daylight saving - Lebanon 03/29/2008" );
- inp.val( "03/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(35) a", dp ).simulate( "click" );
- equal( inp.val(), "03/30/2008", "Daylight saving - Lebanon 03/30/2008" );
- inp.val( "03/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(36) a", dp ).simulate( "click" );
- equal( inp.val(), "03/31/2008", "Daylight saving - Lebanon 03/31/2008" );
- inp.val( "10/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(27) a", dp ).simulate( "click" );
- equal( inp.val(), "10/25/2008", "Daylight saving - Lebanon 10/25/2008" );
- inp.val( "10/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(28) a", dp ).simulate( "click" );
- equal( inp.val(), "10/26/2008", "Daylight saving - Lebanon 10/26/2008" );
- inp.val( "10/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(29) a", dp ).simulate( "click" );
- equal( inp.val(), "10/27/2008", "Daylight saving - Lebanon 10/27/2008" );
-
- // US, Eastern - AM change, northern hemisphere
- inp.val( "03/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(13) a", dp ).simulate( "click" );
- equal( inp.val(), "03/08/2008", "Daylight saving - US 03/08/2008" );
- inp.val( "03/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(14) a", dp ).simulate( "click" );
- equal( inp.val(), "03/09/2008", "Daylight saving - US 03/09/2008" );
- inp.val( "03/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(15) a", dp ).simulate( "click" );
- equal( inp.val(), "03/10/2008", "Daylight saving - US 03/10/2008" );
- inp.val( "11/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(6) a", dp ).simulate( "click" );
- equal( inp.val(), "11/01/2008", "Daylight saving - US 11/01/2008" );
- inp.val( "11/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(7) a", dp ).simulate( "click" );
- equal( inp.val(), "11/02/2008", "Daylight saving - US 11/02/2008" );
- inp.val( "11/01/2008" ).datepicker( "show" );
- $( ".ui-datepicker-calendar td:eq(8) a", dp ).simulate( "click" );
- equal( inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008" );
-} );
-
-var beforeShowThis = null,
- beforeShowInput = null,
- beforeShowInst = null,
- beforeShowDayThis = null,
- beforeShowDayOK = true;
-
-function beforeAll( input, inst ) {
- beforeShowThis = this;
- beforeShowInput = input;
- beforeShowInst = inst;
- return { currentText: "Current" };
-}
-
-function beforeDay( date ) {
- beforeShowDayThis = this;
- beforeShowDayOK &= ( date > new Date( 2008, 1 - 1, 26 ) &&
- date < new Date( 2008, 3 - 1, 6 ) );
- return [ ( date.getDate() % 2 === 0 ), ( date.getDate() % 10 === 0 ? "day10" : "" ),
- ( date.getDate() % 3 === 0 ? "Divisble by 3" : "" ) ];
-}
-
-test( "callbacks", function() {
- expect( 13 );
-
- // Before show
- var dp, day20, day21,
- inp = testHelper.init( "#inp", { beforeShow: beforeAll } ),
- inst = $.data( inp[ 0 ], "datepicker" );
- equal( $.datepicker._get( inst, "currentText" ), "Today", "Before show - initial" );
- inp.val( "02/04/2008" ).datepicker( "show" );
- equal( $.datepicker._get( inst, "currentText" ), "Current", "Before show - changed" );
- ok( beforeShowThis.id === inp[ 0 ].id, "Before show - this OK" );
- ok( beforeShowInput.id === inp[ 0 ].id, "Before show - input OK" );
- deepEqual( beforeShowInst, inst, "Before show - inst OK" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
-
- // Before show day
- inp = testHelper.init( "#inp", { beforeShowDay: beforeDay } );
- dp = $( "#ui-datepicker-div" );
- inp.val( "02/04/2008" ).datepicker( "show" );
- ok( beforeShowDayThis.id === inp[ 0 ].id, "Before show day - this OK" );
- ok( beforeShowDayOK, "Before show day - dates OK" );
- day20 = dp.find( ".ui-datepicker-calendar td:contains('20')" );
- day21 = dp.find( ".ui-datepicker-calendar td:contains('21')" );
- ok( !day20.is( ".ui-datepicker-unselectable" ), "Before show day - unselectable 20" );
- ok( day21.is( ".ui-datepicker-unselectable" ), "Before show day - unselectable 21" );
- ok( day20.is( ".day10" ), "Before show day - CSS 20" );
- ok( !day21.is( ".day10" ), "Before show day - CSS 21" );
- ok( !day20.attr( "title" ), "Before show day - title 20" );
- ok( day21.attr( "title" ) === "Divisble by 3", "Before show day - title 21" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
-} );
-
-test( "beforeShowDay - tooltips with quotes", function() {
- expect( 1 );
- var inp, dp;
- inp = testHelper.init( "#inp", {
- beforeShowDay: function() {
- return [ true, "", "'" ];
+ if ( key === "locale" ) {
+ equal( input.val(), "Mittwoch, 1. Januar 2014", "option " + key + ": updated locale" );
}
} );
- dp = $( "#ui-datepicker-div" );
-
- inp.datepicker( "show" );
- equal( dp.find( ".ui-datepicker-calendar td:contains('9')" ).attr( "title" ), "'" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
} );
-test( "localisation", function() {
- expect( 24 );
- var dp, month, day, date,
- inp = testHelper.init( "#inp", $.datepicker.regional.fr );
- inp.datepicker( "option", { dateFormat: "DD, d MM yy", showButtonPanel:true, changeMonth:true, changeYear:true } ).val( "" ).datepicker( "show" );
- dp = $( "#ui-datepicker-div" );
- equal( $( ".ui-datepicker-close", dp ).text(), "Fermer", "Localisation - close" );
- $( ".ui-datepicker-close", dp ).simulate( "mouseover" );
- equal( $( ".ui-datepicker-prev", dp ).text(), "Précédent", "Localisation - previous" );
- equal( $( ".ui-datepicker-current", dp ).text(), "Aujourd'hui", "Localisation - current" );
- equal( $( ".ui-datepicker-next", dp ).text(), "Suivant", "Localisation - next" );
- month = 0;
- $( ".ui-datepicker-month option", dp ).each( function() {
- equal( $( this ).text(), $.datepicker.regional.fr.monthNamesShort[ month ],
- "Localisation - month " + month );
- month++;
- } );
- day = 1;
- $( ".ui-datepicker-calendar th", dp ).each( function() {
- equal( $( this ).text(), $.datepicker.regional.fr.dayNamesMin[ day ],
- "Localisation - day " + day );
- day = ( day + 1 ) % 7;
+asyncTest( "position", function( assert ) {
+ expect( 3 );
+ var input = $( "<input>" ).datepicker().appendTo( "body" ).css( {
+ position: "absolute",
+ top: 0,
+ left: 0
+ } ),
+ container = input.datepicker( "widget" );
+
+ input.datepicker( "open" );
+ setTimeout( function() {
+ assert.close( input.offset().left, container.offset().left, 1, "left sides line up by default" );
+ assert.close( container.offset().top, input.offset().top + input.outerHeight(), 1,
+ "datepicker directly under input by default" );
+
+ // Change the position option using option()
+ input.datepicker( "option", "position", {
+ my: "left top",
+ at: "right bottom"
+ } );
+ assert.close( container.offset().left, input.offset().left + input.outerWidth(), 1,
+ "datepicker on right hand side of input after position change" );
+
+ input.remove();
+ start();
} );
- inp.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
- date = new Date();
- equal( inp.val(), $.datepicker.regional.fr.dayNames[ date.getDay() ] + ", " +
- date.getDate() + " " + $.datepicker.regional.fr.monthNames[ date.getMonth() ] +
- " " + date.getFullYear(), "Localisation - formatting" );
} );
-test( "noWeekends", function() {
- expect( 31 );
- var i, date;
- for ( i = 1; i <= 31; i++ ) {
- date = new Date( 2001, 1 - 1, i );
- deepEqual( $.datepicker.noWeekends( date ), [ ( i + 1 ) % 7 >= 2, "" ],
- "No weekends " + date );
- }
-} );
-
-test( "iso8601Week", function() {
- expect( 12 );
- var date = new Date( 2000, 12 - 1, 31 );
- equal( $.datepicker.iso8601Week( date ), 52, "ISO 8601 week " + date );
- date = new Date( 2001, 1 - 1, 1 );
- equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date );
- date = new Date( 2001, 1 - 1, 7 );
- equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date );
- date = new Date( 2001, 1 - 1, 8 );
- equal( $.datepicker.iso8601Week( date ), 2, "ISO 8601 week " + date );
- date = new Date( 2003, 12 - 1, 28 );
- equal( $.datepicker.iso8601Week( date ), 52, "ISO 8601 week " + date );
- date = new Date( 2003, 12 - 1, 29 );
- equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date );
- date = new Date( 2004, 1 - 1, 4 );
- equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date );
- date = new Date( 2004, 1 - 1, 5 );
- equal( $.datepicker.iso8601Week( date ), 2, "ISO 8601 week " + date );
- date = new Date( 2009, 12 - 1, 28 );
- equal( $.datepicker.iso8601Week( date ), 53, "ISO 8601 week " + date );
- date = new Date( 2010, 1 - 1, 3 );
- equal( $.datepicker.iso8601Week( date ), 53, "ISO 8601 week " + date );
- date = new Date( 2010, 1 - 1, 4 );
- equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date );
- date = new Date( 2010, 1 - 1, 10 );
- equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date );
-} );
-
-test( "parseDate", function() {
- expect( 26 );
- testHelper.init( "#inp" );
- var currentYear, gmtDate, fr, settings, zh;
- ok( $.datepicker.parseDate( "d m y", "" ) == null, "Parse date empty" );
- testHelper.equalsDate( $.datepicker.parseDate( "d m y", "3 2 01" ),
- new Date( 2001, 2 - 1, 3 ), "Parse date d m y" );
- testHelper.equalsDate( $.datepicker.parseDate( "dd mm yy", "03 02 2001" ),
- new Date( 2001, 2 - 1, 3 ), "Parse date dd mm yy" );
- testHelper.equalsDate( $.datepicker.parseDate( "d m y", "13 12 01" ),
- new Date( 2001, 12 - 1, 13 ), "Parse date d m y" );
- testHelper.equalsDate( $.datepicker.parseDate( "dd mm yy", "13 12 2001" ),
- new Date( 2001, 12 - 1, 13 ), "Parse date dd mm yy" );
- testHelper.equalsDate( $.datepicker.parseDate( "y-o", "01-34" ),
- new Date( 2001, 2 - 1, 3 ), "Parse date y-o" );
- testHelper.equalsDate( $.datepicker.parseDate( "yy-oo", "2001-347" ),
- new Date( 2001, 12 - 1, 13 ), "Parse date yy-oo" );
- testHelper.equalsDate( $.datepicker.parseDate( "oo yy", "348 2004" ),
- new Date( 2004, 12 - 1, 13 ), "Parse date oo yy" );
- testHelper.equalsDate( $.datepicker.parseDate( "D d M y", "Sat 3 Feb 01" ),
- new Date( 2001, 2 - 1, 3 ), "Parse date D d M y" );
- testHelper.equalsDate( $.datepicker.parseDate( "d MM DD yy", "3 February Saturday 2001" ),
- new Date( 2001, 2 - 1, 3 ), "Parse date dd MM DD yy" );
- testHelper.equalsDate( $.datepicker.parseDate( "DD, MM d, yy", "Saturday, February 3, 2001" ),
- new Date( 2001, 2 - 1, 3 ), "Parse date DD, MM d, yy" );
- testHelper.equalsDate( $.datepicker.parseDate( "'day' d 'of' MM (''DD''), yy",
- "day 3 of February ('Saturday'), 2001" ), new Date( 2001, 2 - 1, 3 ),
- "Parse date 'day' d 'of' MM (''DD''), yy" );
- currentYear = new Date().getFullYear();
- testHelper.equalsDate( $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 ) + "-02-03" ),
- new Date( currentYear, 2 - 1, 3 ), "Parse date y-m-d - default cutuff" );
- testHelper.equalsDate( $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 + 10 ) + "-02-03" ),
- new Date( currentYear + 10, 2 - 1, 3 ), "Parse date y-m-d - default cutuff" );
- testHelper.equalsDate( $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 + 11 ) + "-02-03" ),
- new Date( currentYear - 89, 2 - 1, 3 ), "Parse date y-m-d - default cutuff" );
- testHelper.equalsDate( $.datepicker.parseDate( "y-m-d", "80-02-03", { shortYearCutoff: 80 } ),
- new Date( 2080, 2 - 1, 3 ), "Parse date y-m-d - cutoff 80" );
- testHelper.equalsDate( $.datepicker.parseDate( "y-m-d", "81-02-03", { shortYearCutoff: 80 } ),
- new Date( 1981, 2 - 1, 3 ), "Parse date y-m-d - cutoff 80" );
- testHelper.equalsDate( $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 + 60 ) + "-02-03", { shortYearCutoff: "+60" } ),
- new Date( currentYear + 60, 2 - 1, 3 ), "Parse date y-m-d - cutoff +60" );
- testHelper.equalsDate( $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 + 61 ) + "-02-03", { shortYearCutoff: "+60" } ),
- new Date( currentYear - 39, 2 - 1, 3 ), "Parse date y-m-d - cutoff +60" );
- gmtDate = new Date( 2001, 2 - 1, 3 );
- gmtDate.setMinutes( gmtDate.getMinutes() - gmtDate.getTimezoneOffset() );
- testHelper.equalsDate( $.datepicker.parseDate( "@", "981158400000" ), gmtDate, "Parse date @" );
- testHelper.equalsDate( $.datepicker.parseDate( "!", "631167552000000000" ), gmtDate, "Parse date !" );
-
- fr = $.datepicker.regional.fr;
- settings = { dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames,
- monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames };
- testHelper.equalsDate( $.datepicker.parseDate( "D d M y", "Lun. 9 avr. 01", settings ),
- new Date( 2001, 4 - 1, 9 ), "Parse date D M y with settings" );
- testHelper.equalsDate( $.datepicker.parseDate( "d MM DD yy", "9 Avril Lundi 2001", settings ),
- new Date( 2001, 4 - 1, 9 ), "Parse date d MM DD yy with settings" );
- testHelper.equalsDate( $.datepicker.parseDate( "DD, MM d, yy", "Lundi, Avril 9, 2001", settings ),
- new Date( 2001, 4 - 1, 9 ), "Parse date DD, MM d, yy with settings" );
- testHelper.equalsDate( $.datepicker.parseDate( "'jour' d 'de' MM (''DD''), yy", "jour 9 de Avril ('Lundi'), 2001", settings ),
- new Date( 2001, 4 - 1, 9 ), "Parse date 'jour' d 'de' MM (''DD''), yy with settings" );
-
- zh = $.datepicker.regional[ "zh-CN" ];
- testHelper.equalsDate( $.datepicker.parseDate( "yy M d", "2011 十一月 22", zh ),
- new Date( 2011, 11 - 1, 22 ), "Parse date yy M d with zh-CN" );
-} );
-
-test( "parseDateErrors", function() {
- expect( 18 );
- testHelper.init( "#inp" );
- var fr, settings;
- function expectError( expr, value, error ) {
- try {
- expr();
- ok( false, "Parsed error " + value );
- }
- catch ( e ) {
- equal( e, error, "Parsed error " + value );
- }
- }
- expectError( function() { $.datepicker.parseDate( null, "Sat 2 01" ); },
- "Sat 2 01", "Invalid arguments" );
- expectError( function() { $.datepicker.parseDate( "d m y", null ); },
- "null", "Invalid arguments" );
- expectError( function() { $.datepicker.parseDate( "d m y", "Sat 2 01" ); },
- "Sat 2 01 - d m y", "Missing number at position 0" );
- expectError( function() { $.datepicker.parseDate( "dd mm yy", "Sat 2 01" ); },
- "Sat 2 01 - dd mm yy", "Missing number at position 0" );
- expectError( function() { $.datepicker.parseDate( "d m y", "3 Feb 01" ); },
- "3 Feb 01 - d m y", "Missing number at position 2" );
- expectError( function() { $.datepicker.parseDate( "dd mm yy", "3 Feb 01" ); },
- "3 Feb 01 - dd mm yy", "Missing number at position 2" );
- expectError( function() { $.datepicker.parseDate( "mm dd yy", "2 1 01" ); },
- "2 1 01 - dd mm yy", "Missing number at position 4" );
- expectError( function() { $.datepicker.parseDate( "d m y", "3 2 AD01" ); },
- "3 2 AD01 - d m y", "Missing number at position 4" );
- expectError( function() { $.datepicker.parseDate( "d m yy", "3 2 AD01" ); },
- "3 2 AD01 - dd mm yy", "Missing number at position 4" );
- expectError( function() { $.datepicker.parseDate( "y-o", "01-D01" ); },
- "2001-D01 - y-o", "Missing number at position 3" );
- expectError( function() { $.datepicker.parseDate( "yy-oo", "2001-D01" ); },
- "2001-D01 - yy-oo", "Missing number at position 5" );
- expectError( function() { $.datepicker.parseDate( "D d M y", "D7 3 Feb 01" ); },
- "D7 3 Feb 01 - D d M y", "Unknown name at position 0" );
- expectError( function() { $.datepicker.parseDate( "D d M y", "Sat 3 M2 01" ); },
- "Sat 3 M2 01 - D d M y", "Unknown name at position 6" );
- expectError( function() { $.datepicker.parseDate( "DD, MM d, yy", "Saturday- Feb 3, 2001" ); },
- "Saturday- Feb 3, 2001 - DD, MM d, yy", "Unexpected literal at position 8" );
- expectError( function() { $.datepicker.parseDate( "'day' d 'of' MM (''DD''), yy",
- "day 3 of February (\"Saturday\"), 2001" ); },
- "day 3 of Mon2 ('Day7'), 2001", "Unexpected literal at position 19" );
- expectError( function() { $.datepicker.parseDate( "d m y", "29 2 01" ); },
- "29 2 01 - d m y", "Invalid date" );
- fr = $.datepicker.regional.fr;
- settings = { dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames,
- monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames };
- expectError( function() { $.datepicker.parseDate( "D d M y", "Mon 9 Avr 01", settings ); },
- "Mon 9 Avr 01 - D d M y", "Unknown name at position 0" );
- expectError( function() { $.datepicker.parseDate( "D d M y", "Lun. 9 Apr 01", settings ); },
- "Lun. 9 Apr 01 - D d M y", "Unknown name at position 7" );
-} );
-
-test( "Ticket #7244: date parser does not fail when too many numbers are passed into the date function", function() {
- expect( 4 );
- var date;
- try {
- date = $.datepicker.parseDate( "dd/mm/yy", "18/04/19881" );
- ok( false, "Did not properly detect an invalid date" );
- }catch ( e ) {
- ok( "invalid date detected" );
- }
-
- try {
- date = $.datepicker.parseDate( "dd/mm/yy", "18/04/1988 @ 2:43 pm" );
- equal( date.getDate(), 18 );
- equal( date.getMonth(), 3 );
- equal( date.getFullYear(), 1988 );
- } catch ( e ) {
- ok( false, "Did not properly parse date with extra text separated by whitespace" );
- }
-} );
-
-test( "formatDate", function() {
- expect( 16 );
- testHelper.init( "#inp" );
- var gmtDate, fr, settings;
- equal( $.datepicker.formatDate( "d m y", new Date( 2001, 2 - 1, 3 ) ),
- "3 2 01", "Format date d m y" );
- equal( $.datepicker.formatDate( "dd mm yy", new Date( 2001, 2 - 1, 3 ) ),
- "03 02 2001", "Format date dd mm yy" );
- equal( $.datepicker.formatDate( "d m y", new Date( 2001, 12 - 1, 13 ) ),
- "13 12 01", "Format date d m y" );
- equal( $.datepicker.formatDate( "dd mm yy", new Date( 2001, 12 - 1, 13 ) ),
- "13 12 2001", "Format date dd mm yy" );
- equal( $.datepicker.formatDate( "yy-o", new Date( 2001, 2 - 1, 3 ) ),
- "2001-34", "Format date yy-o" );
- equal( $.datepicker.formatDate( "yy-oo", new Date( 2001, 2 - 1, 3 ) ),
- "2001-034", "Format date yy-oo" );
- equal( $.datepicker.formatDate( "D M y", new Date( 2001, 2 - 1, 3 ) ),
- "Sat Feb 01", "Format date D M y" );
- equal( $.datepicker.formatDate( "DD MM yy", new Date( 2001, 2 - 1, 3 ) ),
- "Saturday February 2001", "Format date DD MM yy" );
- equal( $.datepicker.formatDate( "DD, MM d, yy", new Date( 2001, 2 - 1, 3 ) ),
- "Saturday, February 3, 2001", "Format date DD, MM d, yy" );
- equal( $.datepicker.formatDate( "'day' d 'of' MM (''DD''), yy",
- new Date( 2001, 2 - 1, 3 ) ), "day 3 of February ('Saturday'), 2001",
- "Format date 'day' d 'of' MM ('DD'), yy" );
- gmtDate = new Date( 2001, 2 - 1, 3 );
- gmtDate.setMinutes( gmtDate.getMinutes() - gmtDate.getTimezoneOffset() );
- equal( $.datepicker.formatDate( "@", gmtDate ), "981158400000", "Format date @" );
- equal( $.datepicker.formatDate( "!", gmtDate ), "631167552000000000", "Format date !" );
- fr = $.datepicker.regional.fr;
- settings = { dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames,
- monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames };
- equal( $.datepicker.formatDate( "D M y", new Date( 2001, 4 - 1, 9 ), settings ),
- "lun. avr. 01", "Format date D M y with settings" );
- equal( $.datepicker.formatDate( "DD MM yy", new Date( 2001, 4 - 1, 9 ), settings ),
- "lundi avril 2001", "Format date DD MM yy with settings" );
- equal( $.datepicker.formatDate( "DD, MM d, yy", new Date( 2001, 4 - 1, 9 ), settings ),
- "lundi, avril 9, 2001", "Format date DD, MM d, yy with settings" );
- equal( $.datepicker.formatDate( "'jour' d 'de' MM (''DD''), yy",
- new Date( 2001, 4 - 1, 9 ), settings ), "jour 9 de avril ('lundi'), 2001",
- "Format date 'jour' d 'de' MM (''DD''), yy with settings" );
-} );
-
-// TODO: Fix this test so it isn't mysteriously flaky in Browserstack on certain OS/Browser combos
-// test("Ticket 6827: formatDate day of year calculation is wrong during day lights savings time", function(){
-// expect( 1 );
-// var time = $.datepicker.formatDate("oo", new Date("2010/03/30 12:00:00 CDT"));
-// equal(time, "089");
-// });
-
-test( "Ticket 7602: Stop datepicker from appearing with beforeShow event handler", function() {
+test( "Stop datepicker from appearing with beforeOpen event handler", function() {
expect( 3 );
- var inp, dp;
-
- inp = testHelper.init( "#inp", {
- beforeShow: function() {
- }
+ var input = testHelper.init( "#datepicker", {
+ beforeOpen: function() {}
} );
- dp = $( "#ui-datepicker-div" );
- inp.datepicker( "show" );
- equal( dp.css( "display" ), "block", "beforeShow returns nothing" );
- inp.datepicker( "hide" ).datepicker( "destroy" );
- inp = testHelper.init( "#inp", {
- beforeShow: function() {
+ input.datepicker( "open" );
+ ok( input.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns nothing" );
+ input.datepicker( "close" ).datepicker( "destroy" );
+
+ input = testHelper.init( "#datepicker", {
+ beforeOpen: function() {
return true;
}
} );
- dp = $( "#ui-datepicker-div" );
- inp.datepicker( "show" );
- equal( dp.css( "display" ), "block", "beforeShow returns true" );
- inp.datepicker( "hide" );
- inp.datepicker( "destroy" );
+ input.datepicker( "open" );
+ ok( input.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns true" );
+ input.datepicker( "close" ).datepicker( "destroy" );
- inp = testHelper.init( "#inp", {
- beforeShow: function() {
+ input = testHelper.init( "#datepicker", {
+ beforeOpen: function() {
return false;
}
} );
- dp = $( "#ui-datepicker-div" );
- inp.datepicker( "show" );
- equal( dp.css( "display" ), "none", "beforeShow returns false" );
- inp.datepicker( "destroy" );
+ input.datepicker( "open" );
+ ok( !input.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns false" );
+ input.datepicker( "destroy" );
} );
} );
diff --git a/tests/unit/index.html b/tests/unit/index.html
index 091e39c41..9f793141e 100644
--- a/tests/unit/index.html
+++ b/tests/unit/index.html
@@ -39,6 +39,7 @@
<ul>
<li><a href="accordion/accordion.html">Accordion</a></li>
<li><a href="autocomplete/autocomplete.html">Autocomplete</a></li>
+ <li><a href="calendar/calendar.html">Calendar</a></li>
<li><a href="button/button.html">Button</a></li>
<li><a href="checkboxradio/checkboxradio.html">Checkboxradio</a></li>
<li><a href="controlgroup/controlgroup.html">Controlgroup</a></li>
diff --git a/tests/unit/spinner/options.js b/tests/unit/spinner/options.js
index 8ad5caeaa..61d609bc7 100644
--- a/tests/unit/spinner/options.js
+++ b/tests/unit/spinner/options.js
@@ -1,8 +1,8 @@
define( [
"jquery",
"ui/widgets/spinner",
- "globalize",
- "globalize/ja-JP"
+ "globalize-old",
+ "globalize-old/ja-JP"
], function( $ ) {
module( "spinner: options" );
diff --git a/themes/base/base.css b/themes/base/base.css
index 3b33e9bc0..4d7433491 100644
--- a/themes/base/base.css
+++ b/themes/base/base.css
@@ -13,6 +13,7 @@
@import url("accordion.css");
@import url("autocomplete.css");
@import url("button.css");
+@import url("calendar.css");
@import url("checkboxradio.css");
@import url("controlgroup.css");
@import url("datepicker.css");
diff --git a/themes/base/calendar.css b/themes/base/calendar.css
new file mode 100644
index 000000000..def9fe4ff
--- /dev/null
+++ b/themes/base/calendar.css
@@ -0,0 +1,158 @@
+/*!
+ * jQuery UI Calendar @VERSION
+ * http://jqueryui.com
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/calendar/#theming
+ */
+.ui-calendar {
+ width: 17em;
+ padding: .2em .2em 0;
+}
+
+/* calendar header */
+.ui-calendar .ui-calendar-header {
+ position: relative;
+ padding: .2em 0;
+}
+.ui-calendar .ui-calendar-prev,
+.ui-calendar .ui-calendar-next {
+ cursor: pointer;
+ position: absolute;
+ top: 2px;
+ width: 36px;
+ height: 31px;
+}
+.ui-calendar .ui-calendar-prev:not(.ui-state-hover):not(.ui-state-focus),
+.ui-calendar .ui-calendar-next:not(.ui-state-hover):not(.ui-state-focus) {
+ background: none;
+ border: none;
+}
+.ui-calendar .ui-calendar-prev {
+ left: 2px;
+}
+.ui-calendar .ui-calendar-next {
+ right: 2px;
+}
+.ui-calendar .ui-calendar-prev .ui-icon,
+.ui-calendar .ui-calendar-next .ui-icon {
+ display: block;
+ position: absolute;
+ left: 50%;
+ margin-left: -8px;
+ top: 50%;
+ margin-top: -8px;
+}
+.ui-calendar .ui-calendar-title {
+ line-height: 1.8em;
+ text-align: center;
+}
+
+/* calendar grid */
+.ui-calendar table {
+ width: 100%;
+ font-size: .9em;
+ border-collapse: collapse;
+ margin: 0 0 .4em;
+}
+.ui-calendar th {
+ padding: .7em .3em;
+ text-align: center;
+ font-weight: bold;
+ border: 0;
+}
+.ui-calendar td {
+ border: 0;
+ padding: 1px;
+}
+.ui-calendar td button {
+ display: block;
+ padding: .2em;
+ text-align: right;
+ cursor: pointer;
+ width: 100%;
+}
+.ui-calendar td button::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+.ui-calendar .ui-state-disabled button {
+ cursor: default;
+}
+
+/* button pane */
+.ui-calendar .ui-calendar-buttonpane {
+ background-image: none;
+ margin: .7em 0 0 0;
+ padding: 0 .2em;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 0;
+}
+.ui-calendar .ui-calendar-buttonpane button {
+ float: right;
+ margin: .5em .2em .4em;
+ cursor: pointer;
+ padding: .2em .6em .3em .6em;
+ width: auto;
+ overflow: visible;
+}
+.ui-calendar .ui-calendar-buttonpane button.ui-calendar-current {
+ float: left;
+}
+
+/* with multiple calendars */
+.ui-calendar-multi {
+ width: auto;
+ display: inline-block;
+}
+.ui-calendar-multi .ui-calendar-group {
+ width: 17em;
+ float: left;
+}
+.ui-calendar-multi .ui-calendar-group table {
+ width: 95%;
+ margin: 0 2.5% .4em;
+}
+.ui-calendar-multi .ui-calendar-buttonpane {
+ clear: left;
+}
+.ui-calendar-row-break {
+ clear: both;
+ width: 100%;
+ font-size: 0;
+}
+
+/* RTL support */
+.ui-calendar-rtl {
+ direction: rtl;
+}
+.ui-calendar-rtl .ui-calendar-prev {
+ right: 2px;
+ left: auto;
+}
+.ui-calendar-rtl .ui-calendar-next {
+ left: 2px;
+ right: auto;
+}
+.ui-calendar-rtl .ui-calendar-prev:hover {
+ right: 1px;
+ left: auto;
+}
+.ui-calendar-rtl .ui-calendar-next:hover {
+ left: 1px;
+ right: auto;
+}
+.ui-calendar-rtl .ui-calendar-buttonpane {
+ clear: right;
+}
+.ui-calendar-rtl .ui-calendar-buttonpane button {
+ float: left;
+}
+.ui-calendar-rtl .ui-calendar-buttonpane button.ui-calendar-current,
+.ui-calendar-rtl .ui-calendar-group {
+ float: right;
+}
diff --git a/themes/base/datepicker.css b/themes/base/datepicker.css
index 91da063a6..b19f5bda8 100644
--- a/themes/base/datepicker.css
+++ b/themes/base/datepicker.css
@@ -9,177 +9,7 @@
* http://api.jqueryui.com/datepicker/#theming
*/
.ui-datepicker {
- width: 17em;
- padding: .2em .2em 0;
display: none;
-}
-.ui-datepicker .ui-datepicker-header {
- position: relative;
- padding: .2em 0;
-}
-.ui-datepicker .ui-datepicker-prev,
-.ui-datepicker .ui-datepicker-next {
- position: absolute;
- top: 2px;
- width: 1.8em;
- height: 1.8em;
-}
-.ui-datepicker .ui-datepicker-prev-hover,
-.ui-datepicker .ui-datepicker-next-hover {
- top: 1px;
-}
-.ui-datepicker .ui-datepicker-prev {
- left: 2px;
-}
-.ui-datepicker .ui-datepicker-next {
- right: 2px;
-}
-.ui-datepicker .ui-datepicker-prev-hover {
- left: 1px;
-}
-.ui-datepicker .ui-datepicker-next-hover {
- right: 1px;
-}
-.ui-datepicker .ui-datepicker-prev span,
-.ui-datepicker .ui-datepicker-next span {
- display: block;
position: absolute;
- left: 50%;
- margin-left: -8px;
- top: 50%;
- margin-top: -8px;
-}
-.ui-datepicker .ui-datepicker-title {
- margin: 0 2.3em;
- line-height: 1.8em;
- text-align: center;
-}
-.ui-datepicker .ui-datepicker-title select {
- font-size: 1em;
- margin: 1px 0;
-}
-.ui-datepicker select.ui-datepicker-month,
-.ui-datepicker select.ui-datepicker-year {
- width: 45%;
-}
-.ui-datepicker table {
- width: 100%;
- font-size: .9em;
- border-collapse: collapse;
- margin: 0 0 .4em;
-}
-.ui-datepicker th {
- padding: .7em .3em;
- text-align: center;
- font-weight: bold;
- border: 0;
-}
-.ui-datepicker td {
- border: 0;
- padding: 1px;
-}
-.ui-datepicker td span,
-.ui-datepicker td a {
- display: block;
- padding: .2em;
- text-align: right;
- text-decoration: none;
-}
-.ui-datepicker .ui-datepicker-buttonpane {
- background-image: none;
- margin: .7em 0 0 0;
- padding: 0 .2em;
- border-left: 0;
- border-right: 0;
- border-bottom: 0;
-}
-.ui-datepicker .ui-datepicker-buttonpane button {
- float: right;
- margin: .5em .2em .4em;
- cursor: pointer;
- padding: .2em .6em .3em .6em;
- width: auto;
- overflow: visible;
-}
-.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
- float: left;
-}
-
-/* with multiple calendars */
-.ui-datepicker.ui-datepicker-multi {
- width: auto;
-}
-.ui-datepicker-multi .ui-datepicker-group {
- float: left;
-}
-.ui-datepicker-multi .ui-datepicker-group table {
- width: 95%;
- margin: 0 auto .4em;
-}
-.ui-datepicker-multi-2 .ui-datepicker-group {
- width: 50%;
-}
-.ui-datepicker-multi-3 .ui-datepicker-group {
- width: 33.3%;
-}
-.ui-datepicker-multi-4 .ui-datepicker-group {
- width: 25%;
-}
-.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
-.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
- border-left-width: 0;
-}
-.ui-datepicker-multi .ui-datepicker-buttonpane {
- clear: left;
-}
-.ui-datepicker-row-break {
- clear: both;
- width: 100%;
- font-size: 0;
-}
-
-/* RTL support */
-.ui-datepicker-rtl {
- direction: rtl;
-}
-.ui-datepicker-rtl .ui-datepicker-prev {
- right: 2px;
- left: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-next {
- left: 2px;
- right: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-prev:hover {
- right: 1px;
- left: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-next:hover {
- left: 1px;
- right: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane {
- clear: right;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane button {
- float: left;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
-.ui-datepicker-rtl .ui-datepicker-group {
- float: right;
-}
-.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
-.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
- border-right-width: 0;
- border-left-width: 1px;
}
-/* Icons */
-.ui-datepicker .ui-icon {
- display: block;
- text-indent: -99999px;
- overflow: hidden;
- background-repeat: no-repeat;
- left: .5em;
- top: .3em;
-}
diff --git a/ui/date.js b/ui/date.js
new file mode 100644
index 000000000..41effff2b
--- /dev/null
+++ b/ui/date.js
@@ -0,0 +1,192 @@
+/*
+ * Calendar math built on jquery-global
+ *
+ * Based on Marc Grabanski's jQuery Date Plugin
+ * http://marcgrabanski.com/articles/jquery-date-plugin
+ */
+( function( factory ) {
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD. Register as an anonymous module.
+ define( [
+ "jquery", "./version" ], factory );
+ } else {
+
+ // Browser globals
+ factory( jQuery );
+ }
+}( function( $ ) {
+
+$.ui.date = function( date, attributes ) {
+ if ( !( this instanceof $.ui.date ) ) {
+ return new $.ui.date( date, attributes );
+ }
+
+ this.setAttributes( attributes );
+
+ if ( typeof date === "string" && date.length ) {
+ this.dateObject = attributes.parse( date );
+ } else if ( $.type( date ) === "date" ) {
+ this.dateObject = date;
+ }
+
+ this.dateObject = this.dateObject || new Date();
+};
+
+$.extend( $.ui.date.prototype, {
+
+ setAttributes: function( attributes ) {
+ this.attributes = attributes;
+ this.firstDay = this.attributes.firstDay;
+ },
+
+ // TODO: Same as the underlying Date object's terminology, but still misleading.
+ // TODO: We can use .setTime() instead of new Date and rename to setTimestamp.
+ setTime: function( time ) {
+ this.dateObject = new Date( time );
+ return this;
+ },
+
+ setDay: function( day ) {
+ var date = this.dateObject;
+
+ // FIXME: Why not to use .setDate?
+ this.dateObject = new Date( date.getFullYear(), date.getMonth(), day, date.getHours(),
+ date.getMinutes(), date.getSeconds() );
+ return this;
+ },
+
+ setFullDate: function( year, month, day ) {
+ this.dateObject = new Date( year, month, day );
+ return this;
+ },
+
+ adjust: function( period, offset ) {
+ var date = this.dateObject,
+ day = period === "D" ? date.getDate() + offset : date.getDate(),
+ month = period === "M" ? date.getMonth() + offset : date.getMonth(),
+ year = period === "Y" ? date.getFullYear() + offset : date.getFullYear();
+
+ // If not day, update the day to the new month and year
+ if ( period !== "D" ) {
+ day = Math.max( 1, Math.min( day, this.daysInMonth( year, month ) ) );
+ }
+ this.dateObject = new Date( year, month, day, date.getHours(),
+ date.getMinutes(), date.getSeconds() );
+ return this;
+ },
+
+ daysInMonth: function( year, month ) {
+ var date = this.dateObject;
+ year = year || date.getFullYear();
+ month = month || date.getMonth();
+ return 32 - new Date( year, month, 32 ).getDate();
+ },
+
+ monthName: function() {
+ return this.attributes.formatMonth( this.dateObject );
+ },
+
+ day: function() {
+ return this.dateObject.getDate();
+ },
+
+ month: function() {
+ return this.dateObject.getMonth();
+ },
+
+ year: function() {
+ return this.dateObject.getFullYear();
+ },
+
+ weekdays: function() {
+ var date, dow,
+ firstDay = this.firstDay,
+ result = [];
+
+ // date = firstDay
+ date = new Date( this.dateObject.getTime() );
+ date.setDate( date.getDate() + firstDay - 1 - date.getDay() );
+
+ for ( dow = 0; dow < 7; dow++ ) {
+ date.setTime( date.getTime() + 86400000 );
+ result.push( {
+ shortname: this.attributes.formatWeekdayShort( date ),
+ fullname: this.attributes.formatWeekdayFull( date )
+ } );
+ }
+
+ return result;
+ },
+
+ days: function() {
+ var row, week, dayx, day,
+ result = [],
+ today = new $.ui.date( new Date(), this.attributes ),
+ date = this.dateObject,
+ firstDayOfMonth = new Date( this.year(), date.getMonth(), 1 ).getDay(),
+ leadDays = ( firstDayOfMonth - this.firstDay + 7 ) % 7,
+ rows = Math.ceil( ( leadDays + this.daysInMonth() ) / 7 ),
+ printDate = new Date( this.year(), date.getMonth(), 1 - leadDays );
+
+ for ( row = 0; row < rows; row++ ) {
+ week = result[ result.length ] = {
+ number: this.attributes.formatWeekOfYear( printDate ),
+ days: []
+ };
+ for ( dayx = 0; dayx < 7; dayx++ ) {
+ day = week.days[ week.days.length ] = {
+ lead: printDate.getMonth() !== date.getMonth(),
+ date: printDate.getDate(),
+ month: printDate.getMonth(),
+ year: printDate.getFullYear(),
+ timestamp: printDate.getTime(),
+ today: today.equal( printDate )
+ };
+ day.render = day.selectable = !day.lead;
+ if ( this.eachDay ) {
+ this.eachDay( day );
+ }
+
+ // TODO use adjust("D", 1)?
+ printDate.setDate( printDate.getDate() + 1 );
+ }
+ }
+ return result;
+ },
+
+ // specialized for multi-month template, could be used in general
+ months: function( add ) {
+ var clone, i,
+ result = [ this ];
+
+ for ( i = 0; i < add; i++ ) {
+ clone = this.clone();
+ clone.adjust( "M", i + 1 );
+ result.push( clone );
+ }
+ result[ 0 ].first = true;
+ result[ result.length - 1 ].last = true;
+ return result;
+ },
+
+ clone: function() {
+ var date = this.dateObject;
+ return new $.ui.date( new Date( date.getTime() ), this.attributes );
+ },
+
+ equal: function( other ) {
+ var format = function( date ) {
+ return "" + date.getFullYear() + date.getMonth() + date.getDate();
+ };
+ return format( this.dateObject ) === format( other );
+ },
+
+ date: function() {
+ return this.dateObject;
+ }
+} );
+
+return $.ui.date;
+
+} ) );
diff --git a/ui/i18n/datepicker-af.js b/ui/i18n/datepicker-af.js
deleted file mode 100644
index c75688884..000000000
--- a/ui/i18n/datepicker-af.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Afrikaans initialisation for the jQuery UI date picker plugin. */
-/* Written by Renier Pretorius. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.af = {
- closeText: "Selekteer",
- prevText: "Vorige",
- nextText: "Volgende",
- currentText: "Vandag",
- monthNames: [ "Januarie","Februarie","Maart","April","Mei","Junie",
- "Julie","Augustus","September","Oktober","November","Desember" ],
- monthNamesShort: [ "Jan", "Feb", "Mrt", "Apr", "Mei", "Jun",
- "Jul", "Aug", "Sep", "Okt", "Nov", "Des" ],
- dayNames: [ "Sondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrydag", "Saterdag" ],
- dayNamesShort: [ "Son", "Maa", "Din", "Woe", "Don", "Vry", "Sat" ],
- dayNamesMin: [ "So","Ma","Di","Wo","Do","Vr","Sa" ],
- weekHeader: "Wk",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.af );
-
-return datepicker.regional.af;
-
-} ) );
diff --git a/ui/i18n/datepicker-ar-DZ.js b/ui/i18n/datepicker-ar-DZ.js
deleted file mode 100644
index 6035ce292..000000000
--- a/ui/i18n/datepicker-ar-DZ.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Algerian Arabic Translation for jQuery UI date picker plugin. (can be used for Tunisia)*/
-/* Mohamed Cherif BOUCHELAGHEM -- cherifbouchelaghem@yahoo.fr */
-
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "ar-DZ" ] = {
- closeText: "إغلاق",
- prevText: "&#x3C;السابق",
- nextText: "التالي&#x3E;",
- currentText: "اليوم",
- monthNames: [ "جانفي", "فيفري", "مارس", "أفريل", "ماي", "جوان",
- "جويلية", "أوت", "سبتمبر","أكتوبر", "نوفمبر", "ديسمبر" ],
- monthNamesShort: [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" ],
- dayNames: [ "الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت" ],
- dayNamesShort: [ "الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت" ],
- dayNamesMin: [ "الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت" ],
- weekHeader: "أسبوع",
- dateFormat: "dd/mm/yy",
- firstDay: 6,
- isRTL: true,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional[ "ar-DZ" ] );
-
-return datepicker.regional[ "ar-DZ" ];
-
-} ) );
diff --git a/ui/i18n/datepicker-ar.js b/ui/i18n/datepicker-ar.js
deleted file mode 100644
index 025d98484..000000000
--- a/ui/i18n/datepicker-ar.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Arabic Translation for jQuery UI date picker plugin. */
-/* Used in most of Arab countries, primarily in Bahrain, Kuwait, Oman, Qatar, Saudi Arabia and the United Arab Emirates, Egypt, Sudan and Yemen. */
-/* Written by Mohammed Alshehri -- m@dralshehri.com */
-
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.ar = {
- closeText: "إغلاق",
- prevText: "&#x3C;السابق",
- nextText: "التالي&#x3E;",
- currentText: "اليوم",
- monthNames: [ "يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو",
- "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر" ],
- monthNamesShort: [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" ],
- dayNames: [ "الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت" ],
- dayNamesShort: [ "أحد", "اثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت" ],
- dayNamesMin: [ "ح", "ن", "ث", "ر", "خ", "ج", "س" ],
- weekHeader: "أسبوع",
- dateFormat: "dd/mm/yy",
- firstDay: 0,
- isRTL: true,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.ar );
-
-return datepicker.regional.ar;
-
-} ) );
diff --git a/ui/i18n/datepicker-az.js b/ui/i18n/datepicker-az.js
deleted file mode 100644
index 2ebdcfa8b..000000000
--- a/ui/i18n/datepicker-az.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Jamil Najafov (necefov33@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.az = {
- closeText: "Bağla",
- prevText: "&#x3C;Geri",
- nextText: "İrəli&#x3E;",
- currentText: "Bugün",
- monthNames: [ "Yanvar","Fevral","Mart","Aprel","May","İyun",
- "İyul","Avqust","Sentyabr","Oktyabr","Noyabr","Dekabr" ],
- monthNamesShort: [ "Yan","Fev","Mar","Apr","May","İyun",
- "İyul","Avq","Sen","Okt","Noy","Dek" ],
- dayNames: [ "Bazar","Bazar ertəsi","Çərşənbə axşamı","Çərşənbə","Cümə axşamı","Cümə","Şənbə" ],
- dayNamesShort: [ "B","Be","Ça","Ç","Ca","C","Ş" ],
- dayNamesMin: [ "B","B","Ç","С","Ç","C","Ş" ],
- weekHeader: "Hf",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.az );
-
-return datepicker.regional.az;
-
-} ) );
diff --git a/ui/i18n/datepicker-be.js b/ui/i18n/datepicker-be.js
deleted file mode 100644
index 7d96dd1da..000000000
--- a/ui/i18n/datepicker-be.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Belarusian initialisation for the jQuery UI date picker plugin. */
-/* Written by Pavel Selitskas <p.selitskas@gmail.com> */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.be = {
- closeText: "Зачыніць",
- prevText: "&larr;Папяр.",
- nextText: "Наст.&rarr;",
- currentText: "Сёньня",
- monthNames: [ "Студзень","Люты","Сакавік","Красавік","Травень","Чэрвень",
- "Ліпень","Жнівень","Верасень","Кастрычнік","Лістапад","Сьнежань" ],
- monthNamesShort: [ "Сту","Лют","Сак","Кра","Тра","Чэр",
- "Ліп","Жні","Вер","Кас","Ліс","Сьн" ],
- dayNames: [ "нядзеля","панядзелак","аўторак","серада","чацьвер","пятніца","субота" ],
- dayNamesShort: [ "ндз","пнд","аўт","срд","чцв","птн","сбт" ],
- dayNamesMin: [ "Нд","Пн","Аў","Ср","Чц","Пт","Сб" ],
- weekHeader: "Тд",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.be );
-
-return datepicker.regional.be;
-
-} ) );
diff --git a/ui/i18n/datepicker-bg.js b/ui/i18n/datepicker-bg.js
deleted file mode 100644
index cb066a4c9..000000000
--- a/ui/i18n/datepicker-bg.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Bulgarian initialisation for the jQuery UI date picker plugin. */
-/* Written by Stoyan Kyosev (http://svest.org). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.bg = {
- closeText: "затвори",
- prevText: "&#x3C;назад",
- nextText: "напред&#x3E;",
- nextBigText: "&#x3E;&#x3E;",
- currentText: "днес",
- monthNames: [ "Януари","Февруари","Март","Април","Май","Юни",
- "Юли","Август","Септември","Октомври","Ноември","Декември" ],
- monthNamesShort: [ "Яну","Фев","Мар","Апр","Май","Юни",
- "Юли","Авг","Сеп","Окт","Нов","Дек" ],
- dayNames: [ "Неделя","Понеделник","Вторник","Сряда","Четвъртък","Петък","Събота" ],
- dayNamesShort: [ "Нед","Пон","Вто","Сря","Чет","Пет","Съб" ],
- dayNamesMin: [ "Не","По","Вт","Ср","Че","Пе","Съ" ],
- weekHeader: "Wk",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.bg );
-
-return datepicker.regional.bg;
-
-} ) );
diff --git a/ui/i18n/datepicker-bs.js b/ui/i18n/datepicker-bs.js
deleted file mode 100644
index b9f2e2869..000000000
--- a/ui/i18n/datepicker-bs.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Bosnian i18n for the jQuery UI date picker plugin. */
-/* Written by Kenan Konjo. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.bs = {
- closeText: "Zatvori",
- prevText: "&#x3C;",
- nextText: "&#x3E;",
- currentText: "Danas",
- monthNames: [ "Januar","Februar","Mart","April","Maj","Juni",
- "Juli","August","Septembar","Oktobar","Novembar","Decembar" ],
- monthNamesShort: [ "Jan","Feb","Mar","Apr","Maj","Jun",
- "Jul","Aug","Sep","Okt","Nov","Dec" ],
- dayNames: [ "Nedelja","Ponedeljak","Utorak","Srijeda","Četvrtak","Petak","Subota" ],
- dayNamesShort: [ "Ned","Pon","Uto","Sri","Čet","Pet","Sub" ],
- dayNamesMin: [ "Ne","Po","Ut","Sr","Če","Pe","Su" ],
- weekHeader: "Wk",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.bs );
-
-return datepicker.regional.bs;
-
-} ) );
diff --git a/ui/i18n/datepicker-ca.js b/ui/i18n/datepicker-ca.js
deleted file mode 100644
index 9febd90ee..000000000
--- a/ui/i18n/datepicker-ca.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Inicialització en català per a l'extensió 'UI date picker' per jQuery. */
-/* Writers: (joan.leon@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.ca = {
- closeText: "Tanca",
- prevText: "Anterior",
- nextText: "Següent",
- currentText: "Avui",
- monthNames: [ "gener","febrer","març","abril","maig","juny",
- "juliol","agost","setembre","octubre","novembre","desembre" ],
- monthNamesShort: [ "gen","feb","març","abr","maig","juny",
- "jul","ag","set","oct","nov","des" ],
- dayNames: [ "diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte" ],
- dayNamesShort: [ "dg","dl","dt","dc","dj","dv","ds" ],
- dayNamesMin: [ "dg","dl","dt","dc","dj","dv","ds" ],
- weekHeader: "Set",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.ca );
-
-return datepicker.regional.ca;
-
-} ) );
diff --git a/ui/i18n/datepicker-cs.js b/ui/i18n/datepicker-cs.js
deleted file mode 100644
index c2f79cf9e..000000000
--- a/ui/i18n/datepicker-cs.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Czech initialisation for the jQuery UI date picker plugin. */
-/* Written by Tomas Muller (tomas@tomas-muller.net). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.cs = {
- closeText: "Zavřít",
- prevText: "&#x3C;Dříve",
- nextText: "Později&#x3E;",
- currentText: "Nyní",
- monthNames: [ "leden","únor","březen","duben","květen","červen",
- "červenec","srpen","září","říjen","listopad","prosinec" ],
- monthNamesShort: [ "led","úno","bře","dub","kvě","čer",
- "čvc","srp","zář","říj","lis","pro" ],
- dayNames: [ "neděle", "pondělí", "úterý", "středa", "čtvrtek", "pátek", "sobota" ],
- dayNamesShort: [ "ne", "po", "út", "st", "čt", "pá", "so" ],
- dayNamesMin: [ "ne","po","út","st","čt","pá","so" ],
- weekHeader: "Týd",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.cs );
-
-return datepicker.regional.cs;
-
-} ) );
diff --git a/ui/i18n/datepicker-cy-GB.js b/ui/i18n/datepicker-cy-GB.js
deleted file mode 100644
index 26643b50c..000000000
--- a/ui/i18n/datepicker-cy-GB.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Welsh/UK initialisation for the jQuery UI date picker plugin. */
-/* Written by William Griffiths. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "cy-GB" ] = {
- closeText: "Done",
- prevText: "Prev",
- nextText: "Next",
- currentText: "Today",
- monthNames: [ "Ionawr","Chwefror","Mawrth","Ebrill","Mai","Mehefin",
- "Gorffennaf","Awst","Medi","Hydref","Tachwedd","Rhagfyr" ],
- monthNamesShort: [ "Ion", "Chw", "Maw", "Ebr", "Mai", "Meh",
- "Gor", "Aws", "Med", "Hyd", "Tac", "Rha" ],
- dayNames: [ "Dydd Sul", "Dydd Llun", "Dydd Mawrth", "Dydd Mercher", "Dydd Iau", "Dydd Gwener", "Dydd Sadwrn" ],
- dayNamesShort: [ "Sul", "Llu", "Maw", "Mer", "Iau", "Gwe", "Sad" ],
- dayNamesMin: [ "Su","Ll","Ma","Me","Ia","Gw","Sa" ],
- weekHeader: "Wy",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional[ "cy-GB" ] );
-
-return datepicker.regional[ "cy-GB" ];
-
-} ) );
diff --git a/ui/i18n/datepicker-da.js b/ui/i18n/datepicker-da.js
deleted file mode 100644
index 273f0e3ff..000000000
--- a/ui/i18n/datepicker-da.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Danish initialisation for the jQuery UI date picker plugin. */
-/* Written by Jan Christensen ( deletestuff@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.da = {
- closeText: "Luk",
- prevText: "&#x3C;Forrige",
- nextText: "Næste&#x3E;",
- currentText: "Idag",
- monthNames: [ "Januar","Februar","Marts","April","Maj","Juni",
- "Juli","August","September","Oktober","November","December" ],
- monthNamesShort: [ "Jan","Feb","Mar","Apr","Maj","Jun",
- "Jul","Aug","Sep","Okt","Nov","Dec" ],
- dayNames: [ "Søndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","Lørdag" ],
- dayNamesShort: [ "Søn","Man","Tir","Ons","Tor","Fre","Lør" ],
- dayNamesMin: [ "Sø","Ma","Ti","On","To","Fr","Lø" ],
- weekHeader: "Uge",
- dateFormat: "dd-mm-yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.da );
-
-return datepicker.regional.da;
-
-} ) );
diff --git a/ui/i18n/datepicker-de.js b/ui/i18n/datepicker-de.js
deleted file mode 100644
index a67790844..000000000
--- a/ui/i18n/datepicker-de.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* German initialisation for the jQuery UI date picker plugin. */
-/* Written by Milian Wolff (mail@milianw.de). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.de = {
- closeText: "Schließen",
- prevText: "&#x3C;Zurück",
- nextText: "Vor&#x3E;",
- currentText: "Heute",
- monthNames: [ "Januar","Februar","März","April","Mai","Juni",
- "Juli","August","September","Oktober","November","Dezember" ],
- monthNamesShort: [ "Jan","Feb","Mär","Apr","Mai","Jun",
- "Jul","Aug","Sep","Okt","Nov","Dez" ],
- dayNames: [ "Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag" ],
- dayNamesShort: [ "So","Mo","Di","Mi","Do","Fr","Sa" ],
- dayNamesMin: [ "So","Mo","Di","Mi","Do","Fr","Sa" ],
- weekHeader: "KW",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.de );
-
-return datepicker.regional.de;
-
-} ) );
diff --git a/ui/i18n/datepicker-el.js b/ui/i18n/datepicker-el.js
deleted file mode 100644
index f08d6f27d..000000000
--- a/ui/i18n/datepicker-el.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Greek (el) initialisation for the jQuery UI date picker plugin. */
-/* Written by Alex Cicovic (http://www.alexcicovic.com) */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.el = {
- closeText: "Κλείσιμο",
- prevText: "Προηγούμενος",
- nextText: "Επόμενος",
- currentText: "Σήμερα",
- monthNames: [ "Ιανουάριος","Φεβρουάριος","Μάρτιος","Απρίλιος","Μάιος","Ιούνιος",
- "Ιούλιος","Αύγουστος","Σεπτέμβριος","Οκτώβριος","Νοέμβριος","Δεκέμβριος" ],
- monthNamesShort: [ "Ιαν","Φεβ","Μαρ","Απρ","Μαι","Ιουν",
- "Ιουλ","Αυγ","Σεπ","Οκτ","Νοε","Δεκ" ],
- dayNames: [ "Κυριακή","Δευτέρα","Τρίτη","Τετάρτη","Πέμπτη","Παρασκευή","Σάββατο" ],
- dayNamesShort: [ "Κυρ","Δευ","Τρι","Τετ","Πεμ","Παρ","Σαβ" ],
- dayNamesMin: [ "Κυ","Δε","Τρ","Τε","Πε","Πα","Σα" ],
- weekHeader: "Εβδ",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.el );
-
-return datepicker.regional.el;
-
-} ) );
diff --git a/ui/i18n/datepicker-en-AU.js b/ui/i18n/datepicker-en-AU.js
deleted file mode 100644
index f15277c37..000000000
--- a/ui/i18n/datepicker-en-AU.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* English/Australia initialisation for the jQuery UI date picker plugin. */
-/* Based on the en-GB initialisation. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "en-AU" ] = {
- closeText: "Done",
- prevText: "Prev",
- nextText: "Next",
- currentText: "Today",
- monthNames: [ "January","February","March","April","May","June",
- "July","August","September","October","November","December" ],
- monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
- dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
- dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
- dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ],
- weekHeader: "Wk",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional[ "en-AU" ] );
-
-return datepicker.regional[ "en-AU" ];
-
-} ) );
diff --git a/ui/i18n/datepicker-en-GB.js b/ui/i18n/datepicker-en-GB.js
deleted file mode 100644
index c961c1865..000000000
--- a/ui/i18n/datepicker-en-GB.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* English/UK initialisation for the jQuery UI date picker plugin. */
-/* Written by Stuart. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "en-GB" ] = {
- closeText: "Done",
- prevText: "Prev",
- nextText: "Next",
- currentText: "Today",
- monthNames: [ "January","February","March","April","May","June",
- "July","August","September","October","November","December" ],
- monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
- dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
- dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
- dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ],
- weekHeader: "Wk",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional[ "en-GB" ] );
-
-return datepicker.regional[ "en-GB" ];
-
-} ) );
diff --git a/ui/i18n/datepicker-en-NZ.js b/ui/i18n/datepicker-en-NZ.js
deleted file mode 100644
index 704636225..000000000
--- a/ui/i18n/datepicker-en-NZ.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* English/New Zealand initialisation for the jQuery UI date picker plugin. */
-/* Based on the en-GB initialisation. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "en-NZ" ] = {
- closeText: "Done",
- prevText: "Prev",
- nextText: "Next",
- currentText: "Today",
- monthNames: [ "January","February","March","April","May","June",
- "July","August","September","October","November","December" ],
- monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
- dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
- dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
- dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ],
- weekHeader: "Wk",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional[ "en-NZ" ] );
-
-return datepicker.regional[ "en-NZ" ];
-
-} ) );
diff --git a/ui/i18n/datepicker-eo.js b/ui/i18n/datepicker-eo.js
deleted file mode 100644
index 25f6162b5..000000000
--- a/ui/i18n/datepicker-eo.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Esperanto initialisation for the jQuery UI date picker plugin. */
-/* Written by Olivier M. (olivierweb@ifrance.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.eo = {
- closeText: "Fermi",
- prevText: "&#x3C;Anta",
- nextText: "Sekv&#x3E;",
- currentText: "Nuna",
- monthNames: [ "Januaro","Februaro","Marto","Aprilo","Majo","Junio",
- "Julio","Aŭgusto","Septembro","Oktobro","Novembro","Decembro" ],
- monthNamesShort: [ "Jan","Feb","Mar","Apr","Maj","Jun",
- "Jul","Aŭg","Sep","Okt","Nov","Dec" ],
- dayNames: [ "Dimanĉo","Lundo","Mardo","Merkredo","Ĵaŭdo","Vendredo","Sabato" ],
- dayNamesShort: [ "Dim","Lun","Mar","Mer","Ĵaŭ","Ven","Sab" ],
- dayNamesMin: [ "Di","Lu","Ma","Me","Ĵa","Ve","Sa" ],
- weekHeader: "Sb",
- dateFormat: "dd/mm/yy",
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.eo );
-
-return datepicker.regional.eo;
-
-} ) );
diff --git a/ui/i18n/datepicker-es.js b/ui/i18n/datepicker-es.js
deleted file mode 100644
index ea7116e0b..000000000
--- a/ui/i18n/datepicker-es.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Inicialización en español para la extensión 'UI date picker' para jQuery. */
-/* Traducido por Vester (xvester@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.es = {
- closeText: "Cerrar",
- prevText: "&#x3C;Ant",
- nextText: "Sig&#x3E;",
- currentText: "Hoy",
- monthNames: [ "enero","febrero","marzo","abril","mayo","junio",
- "julio","agosto","septiembre","octubre","noviembre","diciembre" ],
- monthNamesShort: [ "ene","feb","mar","abr","may","jun",
- "jul","ago","sep","oct","nov","dic" ],
- dayNames: [ "domingo","lunes","martes","miércoles","jueves","viernes","sábado" ],
- dayNamesShort: [ "dom","lun","mar","mié","jue","vie","sáb" ],
- dayNamesMin: [ "D","L","M","X","J","V","S" ],
- weekHeader: "Sm",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.es );
-
-return datepicker.regional.es;
-
-} ) );
diff --git a/ui/i18n/datepicker-et.js b/ui/i18n/datepicker-et.js
deleted file mode 100644
index 691675a98..000000000
--- a/ui/i18n/datepicker-et.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Estonian initialisation for the jQuery UI date picker plugin. */
-/* Written by Mart Sõmermaa (mrts.pydev at gmail com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.et = {
- closeText: "Sulge",
- prevText: "Eelnev",
- nextText: "Järgnev",
- currentText: "Täna",
- monthNames: [ "Jaanuar","Veebruar","Märts","Aprill","Mai","Juuni",
- "Juuli","August","September","Oktoober","November","Detsember" ],
- monthNamesShort: [ "Jaan", "Veebr", "Märts", "Apr", "Mai", "Juuni",
- "Juuli", "Aug", "Sept", "Okt", "Nov", "Dets" ],
- dayNames: [ "Pühapäev", "Esmaspäev", "Teisipäev", "Kolmapäev", "Neljapäev", "Reede", "Laupäev" ],
- dayNamesShort: [ "Pühap", "Esmasp", "Teisip", "Kolmap", "Neljap", "Reede", "Laup" ],
- dayNamesMin: [ "P","E","T","K","N","R","L" ],
- weekHeader: "näd",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.et );
-
-return datepicker.regional.et;
-
-} ) );
diff --git a/ui/i18n/datepicker-eu.js b/ui/i18n/datepicker-eu.js
deleted file mode 100644
index 8ea1ef9e5..000000000
--- a/ui/i18n/datepicker-eu.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Karrikas-ek itzulia (karrikas@karrikas.com) */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.eu = {
- closeText: "Egina",
- prevText: "&#x3C;Aur",
- nextText: "Hur&#x3E;",
- currentText: "Gaur",
- monthNames: [ "urtarrila","otsaila","martxoa","apirila","maiatza","ekaina",
- "uztaila","abuztua","iraila","urria","azaroa","abendua" ],
- monthNamesShort: [ "urt.","ots.","mar.","api.","mai.","eka.",
- "uzt.","abu.","ira.","urr.","aza.","abe." ],
- dayNames: [ "igandea","astelehena","asteartea","asteazkena","osteguna","ostirala","larunbata" ],
- dayNamesShort: [ "ig.","al.","ar.","az.","og.","ol.","lr." ],
- dayNamesMin: [ "ig","al","ar","az","og","ol","lr" ],
- weekHeader: "As",
- dateFormat: "yy-mm-dd",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.eu );
-
-return datepicker.regional.eu;
-
-} ) );
diff --git a/ui/i18n/datepicker-fa.js b/ui/i18n/datepicker-fa.js
deleted file mode 100644
index 71da4981d..000000000
--- a/ui/i18n/datepicker-fa.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Persian (Farsi) Translation for the jQuery UI date picker plugin. */
-/* Javad Mowlanezhad -- jmowla@gmail.com */
-/* Jalali calendar should supported soon! (Its implemented but I have to test it) */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.fa = {
- closeText: "بستن",
- prevText: "&#x3C;قبلی",
- nextText: "بعدی&#x3E;",
- currentText: "امروز",
- monthNames: [
- "ژانویه",
- "فوریه",
- "مارس",
- "آوریل",
- "مه",
- "ژوئن",
- "ژوئیه",
- "اوت",
- "سپتامبر",
- "اکتبر",
- "نوامبر",
- "دسامبر"
- ],
- monthNamesShort: [ "1","2","3","4","5","6","7","8","9","10","11","12" ],
- dayNames: [
- "يکشنبه",
- "دوشنبه",
- "سه‌شنبه",
- "چهارشنبه",
- "پنجشنبه",
- "جمعه",
- "شنبه"
- ],
- dayNamesShort: [
- "ی",
- "د",
- "س",
- "چ",
- "پ",
- "ج",
- "ش"
- ],
- dayNamesMin: [
- "ی",
- "د",
- "س",
- "چ",
- "پ",
- "ج",
- "ش"
- ],
- weekHeader: "هف",
- dateFormat: "yy/mm/dd",
- firstDay: 6,
- isRTL: true,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.fa );
-
-return datepicker.regional.fa;
-
-} ) );
diff --git a/ui/i18n/datepicker-fi.js b/ui/i18n/datepicker-fi.js
deleted file mode 100644
index a8386ff62..000000000
--- a/ui/i18n/datepicker-fi.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Finnish initialisation for the jQuery UI date picker plugin. */
-/* Written by Harri Kilpiö (harrikilpio@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.fi = {
- closeText: "Sulje",
- prevText: "&#xAB;Edellinen",
- nextText: "Seuraava&#xBB;",
- currentText: "Tänään",
- monthNames: [ "Tammikuu","Helmikuu","Maaliskuu","Huhtikuu","Toukokuu","Kesäkuu",
- "Heinäkuu","Elokuu","Syyskuu","Lokakuu","Marraskuu","Joulukuu" ],
- monthNamesShort: [ "Tammi","Helmi","Maalis","Huhti","Touko","Kesä",
- "Heinä","Elo","Syys","Loka","Marras","Joulu" ],
- dayNamesShort: [ "Su","Ma","Ti","Ke","To","Pe","La" ],
- dayNames: [ "Sunnuntai","Maanantai","Tiistai","Keskiviikko","Torstai","Perjantai","Lauantai" ],
- dayNamesMin: [ "Su","Ma","Ti","Ke","To","Pe","La" ],
- weekHeader: "Vk",
- dateFormat: "d.m.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.fi );
-
-return datepicker.regional.fi;
-
-} ) );
diff --git a/ui/i18n/datepicker-fo.js b/ui/i18n/datepicker-fo.js
deleted file mode 100644
index df1e08951..000000000
--- a/ui/i18n/datepicker-fo.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Faroese initialisation for the jQuery UI date picker plugin */
-/* Written by Sverri Mohr Olsen, sverrimo@gmail.com */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.fo = {
- closeText: "Lat aftur",
- prevText: "&#x3C;Fyrra",
- nextText: "Næsta&#x3E;",
- currentText: "Í dag",
- monthNames: [ "Januar","Februar","Mars","Apríl","Mei","Juni",
- "Juli","August","September","Oktober","November","Desember" ],
- monthNamesShort: [ "Jan","Feb","Mar","Apr","Mei","Jun",
- "Jul","Aug","Sep","Okt","Nov","Des" ],
- dayNames: [ "Sunnudagur","Mánadagur","Týsdagur","Mikudagur","Hósdagur","Fríggjadagur","Leyardagur" ],
- dayNamesShort: [ "Sun","Mán","Týs","Mik","Hós","Frí","Ley" ],
- dayNamesMin: [ "Su","Má","Tý","Mi","Hó","Fr","Le" ],
- weekHeader: "Vk",
- dateFormat: "dd-mm-yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.fo );
-
-return datepicker.regional.fo;
-
-} ) );
diff --git a/ui/i18n/datepicker-fr-CA.js b/ui/i18n/datepicker-fr-CA.js
deleted file mode 100644
index b590277d4..000000000
--- a/ui/i18n/datepicker-fr-CA.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Canadian-French initialisation for the jQuery UI date picker plugin. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "fr-CA" ] = {
- closeText: "Fermer",
- prevText: "Précédent",
- nextText: "Suivant",
- currentText: "Aujourd'hui",
- monthNames: [ "janvier", "février", "mars", "avril", "mai", "juin",
- "juillet", "août", "septembre", "octobre", "novembre", "décembre" ],
- monthNamesShort: [ "janv.", "févr.", "mars", "avril", "mai", "juin",
- "juil.", "août", "sept.", "oct.", "nov.", "déc." ],
- dayNames: [ "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" ],
- dayNamesShort: [ "dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam." ],
- dayNamesMin: [ "D", "L", "M", "M", "J", "V", "S" ],
- weekHeader: "Sem.",
- dateFormat: "yy-mm-dd",
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ""
-};
-datepicker.setDefaults( datepicker.regional[ "fr-CA" ] );
-
-return datepicker.regional[ "fr-CA" ];
-
-} ) );
diff --git a/ui/i18n/datepicker-fr-CH.js b/ui/i18n/datepicker-fr-CH.js
deleted file mode 100644
index d2f0584d6..000000000
--- a/ui/i18n/datepicker-fr-CH.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Swiss-French initialisation for the jQuery UI date picker plugin. */
-/* Written Martin Voelkle (martin.voelkle@e-tc.ch). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "fr-CH" ] = {
- closeText: "Fermer",
- prevText: "&#x3C;Préc",
- nextText: "Suiv&#x3E;",
- currentText: "Courant",
- monthNames: [ "janvier", "février", "mars", "avril", "mai", "juin",
- "juillet", "août", "septembre", "octobre", "novembre", "décembre" ],
- monthNamesShort: [ "janv.", "févr.", "mars", "avril", "mai", "juin",
- "juil.", "août", "sept.", "oct.", "nov.", "déc." ],
- dayNames: [ "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" ],
- dayNamesShort: [ "dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam." ],
- dayNamesMin: [ "D", "L", "M", "M", "J", "V", "S" ],
- weekHeader: "Sm",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional[ "fr-CH" ] );
-
-return datepicker.regional[ "fr-CH" ];
-
-} ) );
diff --git a/ui/i18n/datepicker-fr.js b/ui/i18n/datepicker-fr.js
deleted file mode 100644
index 9e39fbd68..000000000
--- a/ui/i18n/datepicker-fr.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* French initialisation for the jQuery UI date picker plugin. */
-/* Written by Keith Wood (kbwood{at}iinet.com.au),
- Stéphane Nahmani (sholby@sholby.net),
- Stéphane Raimbault <stephane.raimbault@gmail.com> */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.fr = {
- closeText: "Fermer",
- prevText: "Précédent",
- nextText: "Suivant",
- currentText: "Aujourd'hui",
- monthNames: [ "janvier", "février", "mars", "avril", "mai", "juin",
- "juillet", "août", "septembre", "octobre", "novembre", "décembre" ],
- monthNamesShort: [ "janv.", "févr.", "mars", "avr.", "mai", "juin",
- "juil.", "août", "sept.", "oct.", "nov.", "déc." ],
- dayNames: [ "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" ],
- dayNamesShort: [ "dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam." ],
- dayNamesMin: [ "D","L","M","M","J","V","S" ],
- weekHeader: "Sem.",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.fr );
-
-return datepicker.regional.fr;
-
-} ) );
diff --git a/ui/i18n/datepicker-gl.js b/ui/i18n/datepicker-gl.js
deleted file mode 100644
index 276523074..000000000
--- a/ui/i18n/datepicker-gl.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Galician localization for 'UI date picker' jQuery extension. */
-/* Translated by Jorge Barreiro <yortx.barry@gmail.com>. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.gl = {
- closeText: "Pechar",
- prevText: "&#x3C;Ant",
- nextText: "Seg&#x3E;",
- currentText: "Hoxe",
- monthNames: [ "Xaneiro","Febreiro","Marzo","Abril","Maio","Xuño",
- "Xullo","Agosto","Setembro","Outubro","Novembro","Decembro" ],
- monthNamesShort: [ "Xan","Feb","Mar","Abr","Mai","Xuñ",
- "Xul","Ago","Set","Out","Nov","Dec" ],
- dayNames: [ "Domingo","Luns","Martes","Mércores","Xoves","Venres","Sábado" ],
- dayNamesShort: [ "Dom","Lun","Mar","Mér","Xov","Ven","Sáb" ],
- dayNamesMin: [ "Do","Lu","Ma","Mé","Xo","Ve","Sá" ],
- weekHeader: "Sm",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.gl );
-
-return datepicker.regional.gl;
-
-} ) );
diff --git a/ui/i18n/datepicker-he.js b/ui/i18n/datepicker-he.js
deleted file mode 100644
index fb6238fda..000000000
--- a/ui/i18n/datepicker-he.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Hebrew initialisation for the UI Datepicker extension. */
-/* Written by Amir Hardon (ahardon at gmail dot com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.he = {
- closeText: "סגור",
- prevText: "&#x3C;הקודם",
- nextText: "הבא&#x3E;",
- currentText: "היום",
- monthNames: [ "ינואר","פברואר","מרץ","אפריל","מאי","יוני",
- "יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר" ],
- monthNamesShort: [ "ינו","פבר","מרץ","אפר","מאי","יוני",
- "יולי","אוג","ספט","אוק","נוב","דצמ" ],
- dayNames: [ "ראשון","שני","שלישי","רביעי","חמישי","שישי","שבת" ],
- dayNamesShort: [ "א'","ב'","ג'","ד'","ה'","ו'","שבת" ],
- dayNamesMin: [ "א'","ב'","ג'","ד'","ה'","ו'","שבת" ],
- weekHeader: "Wk",
- dateFormat: "dd/mm/yy",
- firstDay: 0,
- isRTL: true,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.he );
-
-return datepicker.regional.he;
-
-} ) );
diff --git a/ui/i18n/datepicker-hi.js b/ui/i18n/datepicker-hi.js
deleted file mode 100644
index 3b1209724..000000000
--- a/ui/i18n/datepicker-hi.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Hindi initialisation for the jQuery UI date picker plugin. */
-/* Written by Michael Dawart. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.hi = {
- closeText: "बंद",
- prevText: "पिछला",
- nextText: "अगला",
- currentText: "आज",
- monthNames: [ "जनवरी ","फरवरी","मार्च","अप्रेल","मई","जून",
- "जूलाई","अगस्त ","सितम्बर","अक्टूबर","नवम्बर","दिसम्बर" ],
- monthNamesShort: [ "जन", "फर", "मार्च", "अप्रेल", "मई", "जून",
- "जूलाई", "अग", "सित", "अक्ट", "नव", "दि" ],
- dayNames: [ "रविवार", "सोमवार", "मंगलवार", "बुधवार", "गुरुवार", "शुक्रवार", "शनिवार" ],
- dayNamesShort: [ "रवि", "सोम", "मंगल", "बुध", "गुरु", "शुक्र", "शनि" ],
- dayNamesMin: [ "रवि", "सोम", "मंगल", "बुध", "गुरु", "शुक्र", "शनि" ],
- weekHeader: "हफ्ता",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.hi );
-
-return datepicker.regional.hi;
-
-} ) );
diff --git a/ui/i18n/datepicker-hr.js b/ui/i18n/datepicker-hr.js
deleted file mode 100644
index 5e218c12d..000000000
--- a/ui/i18n/datepicker-hr.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Croatian i18n for the jQuery UI date picker plugin. */
-/* Written by Vjekoslav Nesek. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.hr = {
- closeText: "Zatvori",
- prevText: "&#x3C;",
- nextText: "&#x3E;",
- currentText: "Danas",
- monthNames: [ "Siječanj","Veljača","Ožujak","Travanj","Svibanj","Lipanj",
- "Srpanj","Kolovoz","Rujan","Listopad","Studeni","Prosinac" ],
- monthNamesShort: [ "Sij","Velj","Ožu","Tra","Svi","Lip",
- "Srp","Kol","Ruj","Lis","Stu","Pro" ],
- dayNames: [ "Nedjelja","Ponedjeljak","Utorak","Srijeda","Četvrtak","Petak","Subota" ],
- dayNamesShort: [ "Ned","Pon","Uto","Sri","Čet","Pet","Sub" ],
- dayNamesMin: [ "Ne","Po","Ut","Sr","Če","Pe","Su" ],
- weekHeader: "Tje",
- dateFormat: "dd.mm.yy.",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.hr );
-
-return datepicker.regional.hr;
-
-} ) );
diff --git a/ui/i18n/datepicker-hu.js b/ui/i18n/datepicker-hu.js
deleted file mode 100644
index 22bbe7031..000000000
--- a/ui/i18n/datepicker-hu.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Hungarian initialisation for the jQuery UI date picker plugin. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.hu = {
- closeText: "bezár",
- prevText: "vissza",
- nextText: "előre",
- currentText: "ma",
- monthNames: [ "Január", "Február", "Március", "Április", "Május", "Június",
- "Július", "Augusztus", "Szeptember", "Október", "November", "December" ],
- monthNamesShort: [ "Jan", "Feb", "Már", "Ápr", "Máj", "Jún",
- "Júl", "Aug", "Szep", "Okt", "Nov", "Dec" ],
- dayNames: [ "Vasárnap", "Hétfő", "Kedd", "Szerda", "Csütörtök", "Péntek", "Szombat" ],
- dayNamesShort: [ "Vas", "Hét", "Ked", "Sze", "Csü", "Pén", "Szo" ],
- dayNamesMin: [ "V", "H", "K", "Sze", "Cs", "P", "Szo" ],
- weekHeader: "Hét",
- dateFormat: "yy.mm.dd.",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.hu );
-
-return datepicker.regional.hu;
-
-} ) );
diff --git a/ui/i18n/datepicker-hy.js b/ui/i18n/datepicker-hy.js
deleted file mode 100644
index 95638b310..000000000
--- a/ui/i18n/datepicker-hy.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Armenian(UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Levon Zakaryan (levon.zakaryan@gmail.com)*/
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.hy = {
- closeText: "Փակել",
- prevText: "&#x3C;Նախ.",
- nextText: "Հաջ.&#x3E;",
- currentText: "Այսօր",
- monthNames: [ "Հունվար","Փետրվար","Մարտ","Ապրիլ","Մայիս","Հունիս",
- "Հուլիս","Օգոստոս","Սեպտեմբեր","Հոկտեմբեր","Նոյեմբեր","Դեկտեմբեր" ],
- monthNamesShort: [ "Հունվ","Փետր","Մարտ","Ապր","Մայիս","Հունիս",
- "Հուլ","Օգս","Սեպ","Հոկ","Նոյ","Դեկ" ],
- dayNames: [ "կիրակի","եկուշաբթի","երեքշաբթի","չորեքշաբթի","հինգշաբթի","ուրբաթ","շաբաթ" ],
- dayNamesShort: [ "կիր","երկ","երք","չրք","հնգ","ուրբ","շբթ" ],
- dayNamesMin: [ "կիր","երկ","երք","չրք","հնգ","ուրբ","շբթ" ],
- weekHeader: "ՇԲՏ",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.hy );
-
-return datepicker.regional.hy;
-
-} ) );
diff --git a/ui/i18n/datepicker-id.js b/ui/i18n/datepicker-id.js
deleted file mode 100644
index 5aef348af..000000000
--- a/ui/i18n/datepicker-id.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Indonesian initialisation for the jQuery UI date picker plugin. */
-/* Written by Deden Fathurahman (dedenf@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.id = {
- closeText: "Tutup",
- prevText: "&#x3C;mundur",
- nextText: "maju&#x3E;",
- currentText: "hari ini",
- monthNames: [ "Januari","Februari","Maret","April","Mei","Juni",
- "Juli","Agustus","September","Oktober","Nopember","Desember" ],
- monthNamesShort: [ "Jan","Feb","Mar","Apr","Mei","Jun",
- "Jul","Agus","Sep","Okt","Nop","Des" ],
- dayNames: [ "Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu" ],
- dayNamesShort: [ "Min","Sen","Sel","Rab","kam","Jum","Sab" ],
- dayNamesMin: [ "Mg","Sn","Sl","Rb","Km","jm","Sb" ],
- weekHeader: "Mg",
- dateFormat: "dd/mm/yy",
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.id );
-
-return datepicker.regional.id;
-
-} ) );
diff --git a/ui/i18n/datepicker-is.js b/ui/i18n/datepicker-is.js
deleted file mode 100644
index f977de326..000000000
--- a/ui/i18n/datepicker-is.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Icelandic initialisation for the jQuery UI date picker plugin. */
-/* Written by Haukur H. Thorsson (haukur@eskill.is). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.is = {
- closeText: "Loka",
- prevText: "&#x3C; Fyrri",
- nextText: "Næsti &#x3E;",
- currentText: "Í dag",
- monthNames: [ "Janúar","Febrúar","Mars","Apríl","Maí","Júní",
- "Júlí","Ágúst","September","Október","Nóvember","Desember" ],
- monthNamesShort: [ "Jan","Feb","Mar","Apr","Maí","Jún",
- "Júl","Ágú","Sep","Okt","Nóv","Des" ],
- dayNames: [ "Sunnudagur","Mánudagur","Þriðjudagur","Miðvikudagur","Fimmtudagur","Föstudagur","Laugardagur" ],
- dayNamesShort: [ "Sun","Mán","Þri","Mið","Fim","Fös","Lau" ],
- dayNamesMin: [ "Su","Má","Þr","Mi","Fi","Fö","La" ],
- weekHeader: "Vika",
- dateFormat: "dd.mm.yy",
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.is );
-
-return datepicker.regional.is;
-
-} ) );
diff --git a/ui/i18n/datepicker-it-CH.js b/ui/i18n/datepicker-it-CH.js
deleted file mode 100644
index 9895da4cc..000000000
--- a/ui/i18n/datepicker-it-CH.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Italian initialisation for the jQuery UI date picker plugin. */
-/* Written by Antonello Pasella (antonello.pasella@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "it-CH" ] = {
- closeText: "Chiudi",
- prevText: "&#x3C;Prec",
- nextText: "Succ&#x3E;",
- currentText: "Oggi",
- monthNames: [ "Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno",
- "Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre" ],
- monthNamesShort: [ "Gen","Feb","Mar","Apr","Mag","Giu",
- "Lug","Ago","Set","Ott","Nov","Dic" ],
- dayNames: [ "Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato" ],
- dayNamesShort: [ "Dom","Lun","Mar","Mer","Gio","Ven","Sab" ],
- dayNamesMin: [ "Do","Lu","Ma","Me","Gi","Ve","Sa" ],
- weekHeader: "Sm",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional[ "it-CH" ] );
-
-return datepicker.regional[ "it-CH" ];
-
-} ) );
diff --git a/ui/i18n/datepicker-it.js b/ui/i18n/datepicker-it.js
deleted file mode 100644
index d67cb6c24..000000000
--- a/ui/i18n/datepicker-it.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Italian initialisation for the jQuery UI date picker plugin. */
-/* Written by Antonello Pasella (antonello.pasella@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.it = {
- closeText: "Chiudi",
- prevText: "&#x3C;Prec",
- nextText: "Succ&#x3E;",
- currentText: "Oggi",
- monthNames: [ "Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno",
- "Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre" ],
- monthNamesShort: [ "Gen","Feb","Mar","Apr","Mag","Giu",
- "Lug","Ago","Set","Ott","Nov","Dic" ],
- dayNames: [ "Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato" ],
- dayNamesShort: [ "Dom","Lun","Mar","Mer","Gio","Ven","Sab" ],
- dayNamesMin: [ "Do","Lu","Ma","Me","Gi","Ve","Sa" ],
- weekHeader: "Sm",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.it );
-
-return datepicker.regional.it;
-
-} ) );
diff --git a/ui/i18n/datepicker-ja.js b/ui/i18n/datepicker-ja.js
deleted file mode 100644
index 52b10583c..000000000
--- a/ui/i18n/datepicker-ja.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Japanese initialisation for the jQuery UI date picker plugin. */
-/* Written by Kentaro SATO (kentaro@ranvis.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.ja = {
- closeText: "閉じる",
- prevText: "&#x3C;前",
- nextText: "次&#x3E;",
- currentText: "今日",
- monthNames: [ "1月","2月","3月","4月","5月","6月",
- "7月","8月","9月","10月","11月","12月" ],
- monthNamesShort: [ "1月","2月","3月","4月","5月","6月",
- "7月","8月","9月","10月","11月","12月" ],
- dayNames: [ "日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日" ],
- dayNamesShort: [ "日","月","火","水","木","金","土" ],
- dayNamesMin: [ "日","月","火","水","木","金","土" ],
- weekHeader: "週",
- dateFormat: "yy/mm/dd",
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: "年" };
-datepicker.setDefaults( datepicker.regional.ja );
-
-return datepicker.regional.ja;
-
-} ) );
diff --git a/ui/i18n/datepicker-ka.js b/ui/i18n/datepicker-ka.js
deleted file mode 100644
index 6a4aa392f..000000000
--- a/ui/i18n/datepicker-ka.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Georgian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Lado Lomidze (lado.lomidze@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.ka = {
- closeText: "დახურვა",
- prevText: "&#x3c; წინა",
- nextText: "შემდეგი &#x3e;",
- currentText: "დღეს",
- monthNames: [ "იანვარი","თებერვალი","მარტი","აპრილი","მაისი","ივნისი", "ივლისი","აგვისტო","სექტემბერი","ოქტომბერი","ნოემბერი","დეკემბერი" ],
- monthNamesShort: [ "იან","თებ","მარ","აპრ","მაი","ივნ", "ივლ","აგვ","სექ","ოქტ","ნოე","დეკ" ],
- dayNames: [ "კვირა","ორშაბათი","სამშაბათი","ოთხშაბათი","ხუთშაბათი","პარასკევი","შაბათი" ],
- dayNamesShort: [ "კვ","ორშ","სამ","ოთხ","ხუთ","პარ","შაბ" ],
- dayNamesMin: [ "კვ","ორშ","სამ","ოთხ","ხუთ","პარ","შაბ" ],
- weekHeader: "კვირა",
- dateFormat: "dd-mm-yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.ka );
-
-return datepicker.regional.ka;
-
-} ) );
diff --git a/ui/i18n/datepicker-kk.js b/ui/i18n/datepicker-kk.js
deleted file mode 100644
index fa0121f8c..000000000
--- a/ui/i18n/datepicker-kk.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.kk = {
- closeText: "Жабу",
- prevText: "&#x3C;Алдыңғы",
- nextText: "Келесі&#x3E;",
- currentText: "Бүгін",
- monthNames: [ "Қаңтар","Ақпан","Наурыз","Сәуір","Мамыр","Маусым",
- "Шілде","Тамыз","Қыркүйек","Қазан","Қараша","Желтоқсан" ],
- monthNamesShort: [ "Қаң","Ақп","Нау","Сәу","Мам","Мау",
- "Шіл","Там","Қыр","Қаз","Қар","Жел" ],
- dayNames: [ "Жексенбі","Дүйсенбі","Сейсенбі","Сәрсенбі","Бейсенбі","Жұма","Сенбі" ],
- dayNamesShort: [ "жкс","дсн","ссн","срс","бсн","жма","снб" ],
- dayNamesMin: [ "Жк","Дс","Сс","Ср","Бс","Жм","Сн" ],
- weekHeader: "Не",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.kk );
-
-return datepicker.regional.kk;
-
-} ) );
diff --git a/ui/i18n/datepicker-km.js b/ui/i18n/datepicker-km.js
deleted file mode 100644
index d8a4596bc..000000000
--- a/ui/i18n/datepicker-km.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Khmer initialisation for the jQuery calendar extension. */
-/* Written by Chandara Om (chandara.teacher@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.km = {
- closeText: "ធ្វើ​រួច",
- prevText: "មុន",
- nextText: "បន្ទាប់",
- currentText: "ថ្ងៃ​នេះ",
- monthNames: [ "មករា","កុម្ភៈ","មីនា","មេសា","ឧសភា","មិថុនា",
- "កក្កដា","សីហា","កញ្ញា","តុលា","វិច្ឆិកា","ធ្នូ" ],
- monthNamesShort: [ "មករា","កុម្ភៈ","មីនា","មេសា","ឧសភា","មិថុនា",
- "កក្កដា","សីហា","កញ្ញា","តុលា","វិច្ឆិកា","ធ្នូ" ],
- dayNames: [ "អាទិត្យ", "ចន្ទ", "អង្គារ", "ពុធ", "ព្រហស្បតិ៍", "សុក្រ", "សៅរ៍" ],
- dayNamesShort: [ "អា", "ច", "អ", "ពុ", "ព្រហ", "សុ", "សៅ" ],
- dayNamesMin: [ "អា", "ច", "អ", "ពុ", "ព្រហ", "សុ", "សៅ" ],
- weekHeader: "សប្ដាហ៍",
- dateFormat: "dd-mm-yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.km );
-
-return datepicker.regional.km;
-
-} ) );
diff --git a/ui/i18n/datepicker-ko.js b/ui/i18n/datepicker-ko.js
deleted file mode 100644
index 8879a9950..000000000
--- a/ui/i18n/datepicker-ko.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Korean initialisation for the jQuery calendar extension. */
-/* Written by DaeKwon Kang (ncrash.dk@gmail.com), Edited by Genie and Myeongjin Lee. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.ko = {
- closeText: "닫기",
- prevText: "이전달",
- nextText: "다음달",
- currentText: "오늘",
- monthNames: [ "1월","2월","3월","4월","5월","6월",
- "7월","8월","9월","10월","11월","12월" ],
- monthNamesShort: [ "1월","2월","3월","4월","5월","6월",
- "7월","8월","9월","10월","11월","12월" ],
- dayNames: [ "일요일","월요일","화요일","수요일","목요일","금요일","토요일" ],
- dayNamesShort: [ "일","월","화","수","목","금","토" ],
- dayNamesMin: [ "일","월","화","수","목","금","토" ],
- weekHeader: "주",
- dateFormat: "yy. m. d.",
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: "년" };
-datepicker.setDefaults( datepicker.regional.ko );
-
-return datepicker.regional.ko;
-
-} ) );
diff --git a/ui/i18n/datepicker-ky.js b/ui/i18n/datepicker-ky.js
deleted file mode 100644
index f748bc606..000000000
--- a/ui/i18n/datepicker-ky.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Kyrgyz (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Sergey Kartashov (ebishkek@yandex.ru). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.ky = {
- closeText: "Жабуу",
- prevText: "&#x3c;Мур",
- nextText: "Кий&#x3e;",
- currentText: "Бүгүн",
- monthNames: [ "Январь","Февраль","Март","Апрель","Май","Июнь",
- "Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь" ],
- monthNamesShort: [ "Янв","Фев","Мар","Апр","Май","Июн",
- "Июл","Авг","Сен","Окт","Ноя","Дек" ],
- dayNames: [ "жекшемби", "дүйшөмбү", "шейшемби", "шаршемби", "бейшемби", "жума", "ишемби" ],
- dayNamesShort: [ "жек", "дүй", "шей", "шар", "бей", "жум", "ише" ],
- dayNamesMin: [ "Жк","Дш","Шш","Шр","Бш","Жм","Иш" ],
- weekHeader: "Жум",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ""
-};
-datepicker.setDefaults( datepicker.regional.ky );
-
-return datepicker.regional.ky;
-
-} ) );
diff --git a/ui/i18n/datepicker-lb.js b/ui/i18n/datepicker-lb.js
deleted file mode 100644
index a8fa03b8f..000000000
--- a/ui/i18n/datepicker-lb.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Luxembourgish initialisation for the jQuery UI date picker plugin. */
-/* Written by Michel Weimerskirch <michel@weimerskirch.net> */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.lb = {
- closeText: "Fäerdeg",
- prevText: "Zréck",
- nextText: "Weider",
- currentText: "Haut",
- monthNames: [ "Januar","Februar","Mäerz","Abrëll","Mee","Juni",
- "Juli","August","September","Oktober","November","Dezember" ],
- monthNamesShort: [ "Jan", "Feb", "Mäe", "Abr", "Mee", "Jun",
- "Jul", "Aug", "Sep", "Okt", "Nov", "Dez" ],
- dayNames: [ "Sonndeg", "Méindeg", "Dënschdeg", "Mëttwoch", "Donneschdeg", "Freideg", "Samschdeg" ],
- dayNamesShort: [ "Son", "Méi", "Dën", "Mët", "Don", "Fre", "Sam" ],
- dayNamesMin: [ "So","Mé","Dë","Më","Do","Fr","Sa" ],
- weekHeader: "W",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.lb );
-
-return datepicker.regional.lb;
-
-} ) );
diff --git a/ui/i18n/datepicker-lt.js b/ui/i18n/datepicker-lt.js
deleted file mode 100644
index 35554764f..000000000
--- a/ui/i18n/datepicker-lt.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* @author Arturas Paleicikas <arturas@avalon.lt> */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.lt = {
- closeText: "Uždaryti",
- prevText: "&#x3C;Atgal",
- nextText: "Pirmyn&#x3E;",
- currentText: "Šiandien",
- monthNames: [ "Sausis","Vasaris","Kovas","Balandis","Gegužė","Birželis",
- "Liepa","Rugpjūtis","Rugsėjis","Spalis","Lapkritis","Gruodis" ],
- monthNamesShort: [ "Sau","Vas","Kov","Bal","Geg","Bir",
- "Lie","Rugp","Rugs","Spa","Lap","Gru" ],
- dayNames: [ "sekmadienis","pirmadienis","antradienis","trečiadienis","ketvirtadienis","penktadienis","šeštadienis" ],
- dayNamesShort: [ "sek","pir","ant","tre","ket","pen","šeš" ],
- dayNamesMin: [ "Se","Pr","An","Tr","Ke","Pe","Še" ],
- weekHeader: "SAV",
- dateFormat: "yy-mm-dd",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.lt );
-
-return datepicker.regional.lt;
-
-} ) );
diff --git a/ui/i18n/datepicker-lv.js b/ui/i18n/datepicker-lv.js
deleted file mode 100644
index ec49c43a6..000000000
--- a/ui/i18n/datepicker-lv.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Latvian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* @author Arturas Paleicikas <arturas.paleicikas@metasite.net> */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.lv = {
- closeText: "Aizvērt",
- prevText: "Iepr.",
- nextText: "Nāk.",
- currentText: "Šodien",
- monthNames: [ "Janvāris","Februāris","Marts","Aprīlis","Maijs","Jūnijs",
- "Jūlijs","Augusts","Septembris","Oktobris","Novembris","Decembris" ],
- monthNamesShort: [ "Jan","Feb","Mar","Apr","Mai","Jūn",
- "Jūl","Aug","Sep","Okt","Nov","Dec" ],
- dayNames: [ "svētdiena","pirmdiena","otrdiena","trešdiena","ceturtdiena","piektdiena","sestdiena" ],
- dayNamesShort: [ "svt","prm","otr","tre","ctr","pkt","sst" ],
- dayNamesMin: [ "Sv","Pr","Ot","Tr","Ct","Pk","Ss" ],
- weekHeader: "Ned.",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.lv );
-
-return datepicker.regional.lv;
-
-} ) );
diff --git a/ui/i18n/datepicker-mk.js b/ui/i18n/datepicker-mk.js
deleted file mode 100644
index 97864ab15..000000000
--- a/ui/i18n/datepicker-mk.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Macedonian i18n for the jQuery UI date picker plugin. */
-/* Written by Stojce Slavkovski. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.mk = {
- closeText: "Затвори",
- prevText: "&#x3C;",
- nextText: "&#x3E;",
- currentText: "Денес",
- monthNames: [ "Јануари","Февруари","Март","Април","Мај","Јуни",
- "Јули","Август","Септември","Октомври","Ноември","Декември" ],
- monthNamesShort: [ "Јан","Фев","Мар","Апр","Мај","Јун",
- "Јул","Авг","Сеп","Окт","Ное","Дек" ],
- dayNames: [ "Недела","Понеделник","Вторник","Среда","Четврток","Петок","Сабота" ],
- dayNamesShort: [ "Нед","Пон","Вто","Сре","Чет","Пет","Саб" ],
- dayNamesMin: [ "Не","По","Вт","Ср","Че","Пе","Са" ],
- weekHeader: "Сед",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.mk );
-
-return datepicker.regional.mk;
-
-} ) );
diff --git a/ui/i18n/datepicker-ml.js b/ui/i18n/datepicker-ml.js
deleted file mode 100644
index 440e09e03..000000000
--- a/ui/i18n/datepicker-ml.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Malayalam (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Saji Nediyanchath (saji89@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.ml = {
- closeText: "ശരി",
- prevText: "മുന്നത്തെ",
- nextText: "അടുത്തത് ",
- currentText: "ഇന്ന്",
- monthNames: [ "ജനുവരി","ഫെബ്രുവരി","മാര്‍ച്ച്","ഏപ്രില്‍","മേയ്","ജൂണ്‍",
- "ജൂലൈ","ആഗസ്റ്റ്","സെപ്റ്റംബര്‍","ഒക്ടോബര്‍","നവംബര്‍","ഡിസംബര്‍" ],
- monthNamesShort: [ "ജനു", "ഫെബ്", "മാര്‍", "ഏപ്രി", "മേയ്", "ജൂണ്‍",
- "ജൂലാ", "ആഗ", "സെപ്", "ഒക്ടോ", "നവം", "ഡിസ" ],
- dayNames: [ "ഞായര്‍", "തിങ്കള്‍", "ചൊവ്വ", "ബുധന്‍", "വ്യാഴം", "വെള്ളി", "ശനി" ],
- dayNamesShort: [ "ഞായ", "തിങ്ക", "ചൊവ്വ", "ബുധ", "വ്യാഴം", "വെള്ളി", "ശനി" ],
- dayNamesMin: [ "ഞാ","തി","ചൊ","ബു","വ്യാ","വെ","ശ" ],
- weekHeader: "ആ",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.ml );
-
-return datepicker.regional.ml;
-
-} ) );
diff --git a/ui/i18n/datepicker-ms.js b/ui/i18n/datepicker-ms.js
deleted file mode 100644
index 58bc4f579..000000000
--- a/ui/i18n/datepicker-ms.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Malaysian initialisation for the jQuery UI date picker plugin. */
-/* Written by Mohd Nawawi Mohamad Jamili (nawawi@ronggeng.net). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.ms = {
- closeText: "Tutup",
- prevText: "&#x3C;Sebelum",
- nextText: "Selepas&#x3E;",
- currentText: "hari ini",
- monthNames: [ "Januari","Februari","Mac","April","Mei","Jun",
- "Julai","Ogos","September","Oktober","November","Disember" ],
- monthNamesShort: [ "Jan","Feb","Mac","Apr","Mei","Jun",
- "Jul","Ogo","Sep","Okt","Nov","Dis" ],
- dayNames: [ "Ahad","Isnin","Selasa","Rabu","Khamis","Jumaat","Sabtu" ],
- dayNamesShort: [ "Aha","Isn","Sel","Rab","kha","Jum","Sab" ],
- dayNamesMin: [ "Ah","Is","Se","Ra","Kh","Ju","Sa" ],
- weekHeader: "Mg",
- dateFormat: "dd/mm/yy",
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.ms );
-
-return datepicker.regional.ms;
-
-} ) );
diff --git a/ui/i18n/datepicker-nb.js b/ui/i18n/datepicker-nb.js
deleted file mode 100644
index 128f6836d..000000000
--- a/ui/i18n/datepicker-nb.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Norwegian Bokmål initialisation for the jQuery UI date picker plugin. */
-/* Written by Bjørn Johansen (post@bjornjohansen.no). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.nb = {
- closeText: "Lukk",
- prevText: "&#xAB;Forrige",
- nextText: "Neste&#xBB;",
- currentText: "I dag",
- monthNames: [ "januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember" ],
- monthNamesShort: [ "jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des" ],
- dayNamesShort: [ "søn","man","tir","ons","tor","fre","lør" ],
- dayNames: [ "søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag" ],
- dayNamesMin: [ "sø","ma","ti","on","to","fr","lø" ],
- weekHeader: "Uke",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ""
-};
-datepicker.setDefaults( datepicker.regional.nb );
-
-return datepicker.regional.nb;
-
-} ) );
diff --git a/ui/i18n/datepicker-nl-BE.js b/ui/i18n/datepicker-nl-BE.js
deleted file mode 100644
index 9ea22002d..000000000
--- a/ui/i18n/datepicker-nl-BE.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Dutch (Belgium) initialisation for the jQuery UI date picker plugin. */
-/* David De Sloovere @DavidDeSloovere */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "nl-BE" ] = {
- closeText: "Sluiten",
- prevText: "←",
- nextText: "→",
- currentText: "Vandaag",
- monthNames: [ "januari", "februari", "maart", "april", "mei", "juni",
- "juli", "augustus", "september", "oktober", "november", "december" ],
- monthNamesShort: [ "jan", "feb", "mrt", "apr", "mei", "jun",
- "jul", "aug", "sep", "okt", "nov", "dec" ],
- dayNames: [ "zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag" ],
- dayNamesShort: [ "zon", "maa", "din", "woe", "don", "vri", "zat" ],
- dayNamesMin: [ "zo", "ma", "di", "wo", "do", "vr", "za" ],
- weekHeader: "Wk",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional[ "nl-BE" ] );
-
-return datepicker.regional[ "nl-BE" ];
-
-} ) );
diff --git a/ui/i18n/datepicker-nl.js b/ui/i18n/datepicker-nl.js
deleted file mode 100644
index 7fcbff1ac..000000000
--- a/ui/i18n/datepicker-nl.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Mathias Bynens <http://mathiasbynens.be/> */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.nl = {
- closeText: "Sluiten",
- prevText: "←",
- nextText: "→",
- currentText: "Vandaag",
- monthNames: [ "januari", "februari", "maart", "april", "mei", "juni",
- "juli", "augustus", "september", "oktober", "november", "december" ],
- monthNamesShort: [ "jan", "feb", "mrt", "apr", "mei", "jun",
- "jul", "aug", "sep", "okt", "nov", "dec" ],
- dayNames: [ "zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag" ],
- dayNamesShort: [ "zon", "maa", "din", "woe", "don", "vri", "zat" ],
- dayNamesMin: [ "zo", "ma", "di", "wo", "do", "vr", "za" ],
- weekHeader: "Wk",
- dateFormat: "dd-mm-yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.nl );
-
-return datepicker.regional.nl;
-
-} ) );
diff --git a/ui/i18n/datepicker-nn.js b/ui/i18n/datepicker-nn.js
deleted file mode 100644
index dfaec387b..000000000
--- a/ui/i18n/datepicker-nn.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Norwegian Nynorsk initialisation for the jQuery UI date picker plugin. */
-/* Written by Bjørn Johansen (post@bjornjohansen.no). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.nn = {
- closeText: "Lukk",
- prevText: "&#xAB;Førre",
- nextText: "Neste&#xBB;",
- currentText: "I dag",
- monthNames: [ "januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember" ],
- monthNamesShort: [ "jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des" ],
- dayNamesShort: [ "sun","mån","tys","ons","tor","fre","lau" ],
- dayNames: [ "sundag","måndag","tysdag","onsdag","torsdag","fredag","laurdag" ],
- dayNamesMin: [ "su","må","ty","on","to","fr","la" ],
- weekHeader: "Veke",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ""
-};
-datepicker.setDefaults( datepicker.regional.nn );
-
-return datepicker.regional.nn;
-
-} ) );
diff --git a/ui/i18n/datepicker-no.js b/ui/i18n/datepicker-no.js
deleted file mode 100644
index 559aa111b..000000000
--- a/ui/i18n/datepicker-no.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Norwegian initialisation for the jQuery UI date picker plugin. */
-/* Written by Naimdjon Takhirov (naimdjon@gmail.com). */
-
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.no = {
- closeText: "Lukk",
- prevText: "&#xAB;Forrige",
- nextText: "Neste&#xBB;",
- currentText: "I dag",
- monthNames: [ "januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember" ],
- monthNamesShort: [ "jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des" ],
- dayNamesShort: [ "søn","man","tir","ons","tor","fre","lør" ],
- dayNames: [ "søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag" ],
- dayNamesMin: [ "sø","ma","ti","on","to","fr","lø" ],
- weekHeader: "Uke",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ""
-};
-datepicker.setDefaults( datepicker.regional.no );
-
-return datepicker.regional.no;
-
-} ) );
diff --git a/ui/i18n/datepicker-pl.js b/ui/i18n/datepicker-pl.js
deleted file mode 100644
index c2fddc132..000000000
--- a/ui/i18n/datepicker-pl.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Polish initialisation for the jQuery UI date picker plugin. */
-/* Written by Jacek Wysocki (jacek.wysocki@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.pl = {
- closeText: "Zamknij",
- prevText: "&#x3C;Poprzedni",
- nextText: "Następny&#x3E;",
- currentText: "Dziś",
- monthNames: [ "Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec",
- "Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień" ],
- monthNamesShort: [ "Sty","Lu","Mar","Kw","Maj","Cze",
- "Lip","Sie","Wrz","Pa","Lis","Gru" ],
- dayNames: [ "Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota" ],
- dayNamesShort: [ "Nie","Pn","Wt","Śr","Czw","Pt","So" ],
- dayNamesMin: [ "N","Pn","Wt","Śr","Cz","Pt","So" ],
- weekHeader: "Tydz",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.pl );
-
-return datepicker.regional.pl;
-
-} ) );
diff --git a/ui/i18n/datepicker-pt-BR.js b/ui/i18n/datepicker-pt-BR.js
deleted file mode 100644
index c4c0d541c..000000000
--- a/ui/i18n/datepicker-pt-BR.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Brazilian initialisation for the jQuery UI date picker plugin. */
-/* Written by Leonildo Costa Silva (leocsilva@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "pt-BR" ] = {
- closeText: "Fechar",
- prevText: "&#x3C;Anterior",
- nextText: "Próximo&#x3E;",
- currentText: "Hoje",
- monthNames: [ "Janeiro","Fevereiro","Março","Abril","Maio","Junho",
- "Julho","Agosto","Setembro","Outubro","Novembro","Dezembro" ],
- monthNamesShort: [ "Jan","Fev","Mar","Abr","Mai","Jun",
- "Jul","Ago","Set","Out","Nov","Dez" ],
- dayNames: [ "Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado" ],
- dayNamesShort: [ "Dom","Seg","Ter","Qua","Qui","Sex","Sáb" ],
- dayNamesMin: [ "Dom","Seg","Ter","Qua","Qui","Sex","Sáb" ],
- weekHeader: "Sm",
- dateFormat: "dd/mm/yy",
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional[ "pt-BR" ] );
-
-return datepicker.regional[ "pt-BR" ];
-
-} ) );
diff --git a/ui/i18n/datepicker-pt.js b/ui/i18n/datepicker-pt.js
deleted file mode 100644
index baed7f3de..000000000
--- a/ui/i18n/datepicker-pt.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Portuguese initialisation for the jQuery UI date picker plugin. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.pt = {
- closeText: "Fechar",
- prevText: "Anterior",
- nextText: "Seguinte",
- currentText: "Hoje",
- monthNames: [ "Janeiro","Fevereiro","Março","Abril","Maio","Junho",
- "Julho","Agosto","Setembro","Outubro","Novembro","Dezembro" ],
- monthNamesShort: [ "Jan","Fev","Mar","Abr","Mai","Jun",
- "Jul","Ago","Set","Out","Nov","Dez" ],
- dayNames: [ "Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado" ],
- dayNamesShort: [ "Dom","Seg","Ter","Qua","Qui","Sex","Sáb" ],
- dayNamesMin: [ "Dom","Seg","Ter","Qua","Qui","Sex","Sáb" ],
- weekHeader: "Sem",
- dateFormat: "dd/mm/yy",
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.pt );
-
-return datepicker.regional.pt;
-
-} ) );
diff --git a/ui/i18n/datepicker-rm.js b/ui/i18n/datepicker-rm.js
deleted file mode 100644
index 856c8c254..000000000
--- a/ui/i18n/datepicker-rm.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Romansh initialisation for the jQuery UI date picker plugin. */
-/* Written by Yvonne Gienal (yvonne.gienal@educa.ch). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.rm = {
- closeText: "Serrar",
- prevText: "&#x3C;Suandant",
- nextText: "Precedent&#x3E;",
- currentText: "Actual",
- monthNames: [ "Schaner","Favrer","Mars","Avrigl","Matg","Zercladur", "Fanadur","Avust","Settember","October","November","December" ],
- monthNamesShort: [ "Scha","Fev","Mar","Avr","Matg","Zer", "Fan","Avu","Sett","Oct","Nov","Dec" ],
- dayNames: [ "Dumengia","Glindesdi","Mardi","Mesemna","Gievgia","Venderdi","Sonda" ],
- dayNamesShort: [ "Dum","Gli","Mar","Mes","Gie","Ven","Som" ],
- dayNamesMin: [ "Du","Gl","Ma","Me","Gi","Ve","So" ],
- weekHeader: "emna",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.rm );
-
-return datepicker.regional.rm;
-
-} ) );
diff --git a/ui/i18n/datepicker-ro.js b/ui/i18n/datepicker-ro.js
deleted file mode 100644
index b26665c25..000000000
--- a/ui/i18n/datepicker-ro.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Romanian initialisation for the jQuery UI date picker plugin.
- *
- * Written by Edmond L. (ll_edmond@walla.com)
- * and Ionut G. Stan (ionut.g.stan@gmail.com)
- */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.ro = {
- closeText: "Închide",
- prevText: "&#xAB; Luna precedentă",
- nextText: "Luna următoare &#xBB;",
- currentText: "Azi",
- monthNames: [ "Ianuarie","Februarie","Martie","Aprilie","Mai","Iunie",
- "Iulie","August","Septembrie","Octombrie","Noiembrie","Decembrie" ],
- monthNamesShort: [ "Ian", "Feb", "Mar", "Apr", "Mai", "Iun",
- "Iul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
- dayNames: [ "Duminică", "Luni", "Marţi", "Miercuri", "Joi", "Vineri", "Sâmbătă" ],
- dayNamesShort: [ "Dum", "Lun", "Mar", "Mie", "Joi", "Vin", "Sâm" ],
- dayNamesMin: [ "Du","Lu","Ma","Mi","Jo","Vi","Sâ" ],
- weekHeader: "Săpt",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.ro );
-
-return datepicker.regional.ro;
-
-} ) );
diff --git a/ui/i18n/datepicker-ru.js b/ui/i18n/datepicker-ru.js
deleted file mode 100644
index 223e77645..000000000
--- a/ui/i18n/datepicker-ru.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Russian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Andrew Stromnov (stromnov@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.ru = {
- closeText: "Закрыть",
- prevText: "&#x3C;Пред",
- nextText: "След&#x3E;",
- currentText: "Сегодня",
- monthNames: [ "Январь","Февраль","Март","Апрель","Май","Июнь",
- "Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь" ],
- monthNamesShort: [ "Янв","Фев","Мар","Апр","Май","Июн",
- "Июл","Авг","Сен","Окт","Ноя","Дек" ],
- dayNames: [ "воскресенье","понедельник","вторник","среда","четверг","пятница","суббота" ],
- dayNamesShort: [ "вск","пнд","втр","срд","чтв","птн","сбт" ],
- dayNamesMin: [ "Вс","Пн","Вт","Ср","Чт","Пт","Сб" ],
- weekHeader: "Нед",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.ru );
-
-return datepicker.regional.ru;
-
-} ) );
diff --git a/ui/i18n/datepicker-sk.js b/ui/i18n/datepicker-sk.js
deleted file mode 100644
index 16d8bdfe4..000000000
--- a/ui/i18n/datepicker-sk.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Slovak initialisation for the jQuery UI date picker plugin. */
-/* Written by Vojtech Rinik (vojto@hmm.sk). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.sk = {
- closeText: "Zavrieť",
- prevText: "&#x3C;Predchádzajúci",
- nextText: "Nasledujúci&#x3E;",
- currentText: "Dnes",
- monthNames: [ "január","február","marec","apríl","máj","jún",
- "júl","august","september","október","november","december" ],
- monthNamesShort: [ "Jan","Feb","Mar","Apr","Máj","Jún",
- "Júl","Aug","Sep","Okt","Nov","Dec" ],
- dayNames: [ "nedeľa","pondelok","utorok","streda","štvrtok","piatok","sobota" ],
- dayNamesShort: [ "Ned","Pon","Uto","Str","Štv","Pia","Sob" ],
- dayNamesMin: [ "Ne","Po","Ut","St","Št","Pia","So" ],
- weekHeader: "Ty",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.sk );
-
-return datepicker.regional.sk;
-
-} ) );
diff --git a/ui/i18n/datepicker-sl.js b/ui/i18n/datepicker-sl.js
deleted file mode 100644
index 689162492..000000000
--- a/ui/i18n/datepicker-sl.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Slovenian initialisation for the jQuery UI date picker plugin. */
-/* Written by Jaka Jancar (jaka@kubje.org). */
-/* c = č, s = š z = ž C = Č S = Š Z = Ž */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.sl = {
- closeText: "Zapri",
- prevText: "&#x3C;Prejšnji",
- nextText: "Naslednji&#x3E;",
- currentText: "Trenutni",
- monthNames: [ "Januar","Februar","Marec","April","Maj","Junij",
- "Julij","Avgust","September","Oktober","November","December" ],
- monthNamesShort: [ "Jan","Feb","Mar","Apr","Maj","Jun",
- "Jul","Avg","Sep","Okt","Nov","Dec" ],
- dayNames: [ "Nedelja","Ponedeljek","Torek","Sreda","Četrtek","Petek","Sobota" ],
- dayNamesShort: [ "Ned","Pon","Tor","Sre","Čet","Pet","Sob" ],
- dayNamesMin: [ "Ne","Po","To","Sr","Če","Pe","So" ],
- weekHeader: "Teden",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.sl );
-
-return datepicker.regional.sl;
-
-} ) );
diff --git a/ui/i18n/datepicker-sq.js b/ui/i18n/datepicker-sq.js
deleted file mode 100644
index 34fe66a59..000000000
--- a/ui/i18n/datepicker-sq.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Albanian initialisation for the jQuery UI date picker plugin. */
-/* Written by Flakron Bytyqi (flakron@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.sq = {
- closeText: "mbylle",
- prevText: "&#x3C;mbrapa",
- nextText: "Përpara&#x3E;",
- currentText: "sot",
- monthNames: [ "Janar","Shkurt","Mars","Prill","Maj","Qershor",
- "Korrik","Gusht","Shtator","Tetor","Nëntor","Dhjetor" ],
- monthNamesShort: [ "Jan","Shk","Mar","Pri","Maj","Qer",
- "Kor","Gus","Sht","Tet","Nën","Dhj" ],
- dayNames: [ "E Diel","E Hënë","E Martë","E Mërkurë","E Enjte","E Premte","E Shtune" ],
- dayNamesShort: [ "Di","Hë","Ma","Më","En","Pr","Sh" ],
- dayNamesMin: [ "Di","Hë","Ma","Më","En","Pr","Sh" ],
- weekHeader: "Ja",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.sq );
-
-return datepicker.regional.sq;
-
-} ) );
diff --git a/ui/i18n/datepicker-sr-SR.js b/ui/i18n/datepicker-sr-SR.js
deleted file mode 100644
index e9db26a42..000000000
--- a/ui/i18n/datepicker-sr-SR.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Serbian i18n for the jQuery UI date picker plugin. */
-/* Written by Dejan Dimić. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "sr-SR" ] = {
- closeText: "Zatvori",
- prevText: "&#x3C;",
- nextText: "&#x3E;",
- currentText: "Danas",
- monthNames: [ "Januar","Februar","Mart","April","Maj","Jun",
- "Jul","Avgust","Septembar","Oktobar","Novembar","Decembar" ],
- monthNamesShort: [ "Jan","Feb","Mar","Apr","Maj","Jun",
- "Jul","Avg","Sep","Okt","Nov","Dec" ],
- dayNames: [ "Nedelja","Ponedeljak","Utorak","Sreda","Četvrtak","Petak","Subota" ],
- dayNamesShort: [ "Ned","Pon","Uto","Sre","Čet","Pet","Sub" ],
- dayNamesMin: [ "Ne","Po","Ut","Sr","Če","Pe","Su" ],
- weekHeader: "Sed",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional[ "sr-SR" ] );
-
-return datepicker.regional[ "sr-SR" ];
-
-} ) );
diff --git a/ui/i18n/datepicker-sr.js b/ui/i18n/datepicker-sr.js
deleted file mode 100644
index fa8827aa1..000000000
--- a/ui/i18n/datepicker-sr.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Serbian i18n for the jQuery UI date picker plugin. */
-/* Written by Dejan Dimić. */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.sr = {
- closeText: "Затвори",
- prevText: "&#x3C;",
- nextText: "&#x3E;",
- currentText: "Данас",
- monthNames: [ "Јануар","Фебруар","Март","Април","Мај","Јун",
- "Јул","Август","Септембар","Октобар","Новембар","Децембар" ],
- monthNamesShort: [ "Јан","Феб","Мар","Апр","Мај","Јун",
- "Јул","Авг","Сеп","Окт","Нов","Дец" ],
- dayNames: [ "Недеља","Понедељак","Уторак","Среда","Четвртак","Петак","Субота" ],
- dayNamesShort: [ "Нед","Пон","Уто","Сре","Чет","Пет","Суб" ],
- dayNamesMin: [ "Не","По","Ут","Ср","Че","Пе","Су" ],
- weekHeader: "Сед",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.sr );
-
-return datepicker.regional.sr;
-
-} ) );
diff --git a/ui/i18n/datepicker-sv.js b/ui/i18n/datepicker-sv.js
deleted file mode 100644
index 92686efa4..000000000
--- a/ui/i18n/datepicker-sv.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Swedish initialisation for the jQuery UI date picker plugin. */
-/* Written by Anders Ekdahl ( anders@nomadiz.se). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.sv = {
- closeText: "Stäng",
- prevText: "&#xAB;Förra",
- nextText: "Nästa&#xBB;",
- currentText: "Idag",
- monthNames: [ "Januari","Februari","Mars","April","Maj","Juni",
- "Juli","Augusti","September","Oktober","November","December" ],
- monthNamesShort: [ "Jan","Feb","Mar","Apr","Maj","Jun",
- "Jul","Aug","Sep","Okt","Nov","Dec" ],
- dayNamesShort: [ "Sön","Mån","Tis","Ons","Tor","Fre","Lör" ],
- dayNames: [ "Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag" ],
- dayNamesMin: [ "Sö","Må","Ti","On","To","Fr","Lö" ],
- weekHeader: "Ve",
- dateFormat: "yy-mm-dd",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.sv );
-
-return datepicker.regional.sv;
-
-} ) );
diff --git a/ui/i18n/datepicker-ta.js b/ui/i18n/datepicker-ta.js
deleted file mode 100644
index e3f09b00c..000000000
--- a/ui/i18n/datepicker-ta.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Tamil (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by S A Sureshkumar (saskumar@live.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.ta = {
- closeText: "மூடு",
- prevText: "முன்னையது",
- nextText: "அடுத்தது",
- currentText: "இன்று",
- monthNames: [ "தை","மாசி","பங்குனி","சித்திரை","வைகாசி","ஆனி",
- "ஆடி","ஆவணி","புரட்டாசி","ஐப்பசி","கார்த்திகை","மார்கழி" ],
- monthNamesShort: [ "தை","மாசி","பங்","சித்","வைகா","ஆனி",
- "ஆடி","ஆவ","புர","ஐப்","கார்","மார்" ],
- dayNames: [ "ஞாயிற்றுக்கிழமை","திங்கட்கிழமை","செவ்வாய்க்கிழமை","புதன்கிழமை","வியாழக்கிழமை","வெள்ளிக்கிழமை","சனிக்கிழமை" ],
- dayNamesShort: [ "ஞாயிறு","திங்கள்","செவ்வாய்","புதன்","வியாழன்","வெள்ளி","சனி" ],
- dayNamesMin: [ "ஞா","தி","செ","பு","வி","வெ","ச" ],
- weekHeader: "Не",
- dateFormat: "dd/mm/yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.ta );
-
-return datepicker.regional.ta;
-
-} ) );
diff --git a/ui/i18n/datepicker-th.js b/ui/i18n/datepicker-th.js
deleted file mode 100644
index 6de48cf96..000000000
--- a/ui/i18n/datepicker-th.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Thai initialisation for the jQuery UI date picker plugin. */
-/* Written by pipo (pipo@sixhead.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.th = {
- closeText: "ปิด",
- prevText: "&#xAB;&#xA0;ย้อน",
- nextText: "ถัดไป&#xA0;&#xBB;",
- currentText: "วันนี้",
- monthNames: [ "มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน",
- "กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม" ],
- monthNamesShort: [ "ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.",
- "ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค." ],
- dayNames: [ "อาทิตย์","จันทร์","อังคาร","พุธ","พฤหัสบดี","ศุกร์","เสาร์" ],
- dayNamesShort: [ "อา.","จ.","อ.","พ.","พฤ.","ศ.","ส." ],
- dayNamesMin: [ "อา.","จ.","อ.","พ.","พฤ.","ศ.","ส." ],
- weekHeader: "Wk",
- dateFormat: "dd/mm/yy",
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.th );
-
-return datepicker.regional.th;
-
-} ) );
diff --git a/ui/i18n/datepicker-tj.js b/ui/i18n/datepicker-tj.js
deleted file mode 100644
index 8ede4ddcb..000000000
--- a/ui/i18n/datepicker-tj.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Tajiki (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Abdurahmon Saidov (saidovab@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.tj = {
- closeText: "Идома",
- prevText: "&#x3c;Қафо",
- nextText: "Пеш&#x3e;",
- currentText: "Имрӯз",
- monthNames: [ "Январ","Феврал","Март","Апрел","Май","Июн",
- "Июл","Август","Сентябр","Октябр","Ноябр","Декабр" ],
- monthNamesShort: [ "Янв","Фев","Мар","Апр","Май","Июн",
- "Июл","Авг","Сен","Окт","Ноя","Дек" ],
- dayNames: [ "якшанбе","душанбе","сешанбе","чоршанбе","панҷшанбе","ҷумъа","шанбе" ],
- dayNamesShort: [ "якш","душ","сеш","чор","пан","ҷум","шан" ],
- dayNamesMin: [ "Як","Дш","Сш","Чш","Пш","Ҷм","Шн" ],
- weekHeader: "Хф",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.tj );
-
-return datepicker.regional.tj;
-
-} ) );
diff --git a/ui/i18n/datepicker-tr.js b/ui/i18n/datepicker-tr.js
deleted file mode 100644
index 8328e2199..000000000
--- a/ui/i18n/datepicker-tr.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Turkish initialisation for the jQuery UI date picker plugin. */
-/* Written by Izzet Emre Erkan (kara@karalamalar.net). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.tr = {
- closeText: "kapat",
- prevText: "&#x3C;geri",
- nextText: "ileri&#x3e",
- currentText: "bugün",
- monthNames: [ "Ocak","Şubat","Mart","Nisan","Mayıs","Haziran",
- "Temmuz","Ağustos","Eylül","Ekim","Kasım","Aralık" ],
- monthNamesShort: [ "Oca","Şub","Mar","Nis","May","Haz",
- "Tem","Ağu","Eyl","Eki","Kas","Ara" ],
- dayNames: [ "Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi" ],
- dayNamesShort: [ "Pz","Pt","Sa","Ça","Pe","Cu","Ct" ],
- dayNamesMin: [ "Pz","Pt","Sa","Ça","Pe","Cu","Ct" ],
- weekHeader: "Hf",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.tr );
-
-return datepicker.regional.tr;
-
-} ) );
diff --git a/ui/i18n/datepicker-uk.js b/ui/i18n/datepicker-uk.js
deleted file mode 100644
index c82501ad2..000000000
--- a/ui/i18n/datepicker-uk.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Ukrainian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Maxim Drogobitskiy (maxdao@gmail.com). */
-/* Corrected by Igor Milla (igor.fsp.milla@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.uk = {
- closeText: "Закрити",
- prevText: "&#x3C;",
- nextText: "&#x3E;",
- currentText: "Сьогодні",
- monthNames: [ "Січень","Лютий","Березень","Квітень","Травень","Червень",
- "Липень","Серпень","Вересень","Жовтень","Листопад","Грудень" ],
- monthNamesShort: [ "Січ","Лют","Бер","Кві","Тра","Чер",
- "Лип","Сер","Вер","Жов","Лис","Гру" ],
- dayNames: [ "неділя","понеділок","вівторок","середа","четвер","п’ятниця","субота" ],
- dayNamesShort: [ "нед","пнд","вів","срд","чтв","птн","сбт" ],
- dayNamesMin: [ "Нд","Пн","Вт","Ср","Чт","Пт","Сб" ],
- weekHeader: "Тиж",
- dateFormat: "dd.mm.yy",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.uk );
-
-return datepicker.regional.uk;
-
-} ) );
diff --git a/ui/i18n/datepicker-vi.js b/ui/i18n/datepicker-vi.js
deleted file mode 100644
index 2c208ab71..000000000
--- a/ui/i18n/datepicker-vi.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Vietnamese initialisation for the jQuery UI date picker plugin. */
-/* Translated by Le Thanh Huy (lthanhhuy@cit.ctu.edu.vn). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional.vi = {
- closeText: "Đóng",
- prevText: "&#x3C;Trước",
- nextText: "Tiếp&#x3E;",
- currentText: "Hôm nay",
- monthNames: [ "Tháng Một", "Tháng Hai", "Tháng Ba", "Tháng Tư", "Tháng Năm", "Tháng Sáu",
- "Tháng Bảy", "Tháng Tám", "Tháng Chín", "Tháng Mười", "Tháng Mười Một", "Tháng Mười Hai" ],
- monthNamesShort: [ "Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6",
- "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12" ],
- dayNames: [ "Chủ Nhật", "Thứ Hai", "Thứ Ba", "Thứ Tư", "Thứ Năm", "Thứ Sáu", "Thứ Bảy" ],
- dayNamesShort: [ "CN", "T2", "T3", "T4", "T5", "T6", "T7" ],
- dayNamesMin: [ "CN", "T2", "T3", "T4", "T5", "T6", "T7" ],
- weekHeader: "Tu",
- dateFormat: "dd/mm/yy",
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: "" };
-datepicker.setDefaults( datepicker.regional.vi );
-
-return datepicker.regional.vi;
-
-} ) );
diff --git a/ui/i18n/datepicker-zh-CN.js b/ui/i18n/datepicker-zh-CN.js
deleted file mode 100644
index 91f99b4ed..000000000
--- a/ui/i18n/datepicker-zh-CN.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Chinese initialisation for the jQuery UI date picker plugin. */
-/* Written by Cloudream (cloudream@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "zh-CN" ] = {
- closeText: "关闭",
- prevText: "&#x3C;上月",
- nextText: "下月&#x3E;",
- currentText: "今天",
- monthNames: [ "一月","二月","三月","四月","五月","六月",
- "七月","八月","九月","十月","十一月","十二月" ],
- monthNamesShort: [ "一月","二月","三月","四月","五月","六月",
- "七月","八月","九月","十月","十一月","十二月" ],
- dayNames: [ "星期日","星期一","星期二","星期三","星期四","星期五","星期六" ],
- dayNamesShort: [ "周日","周一","周二","周三","周四","周五","周六" ],
- dayNamesMin: [ "日","一","二","三","四","五","六" ],
- weekHeader: "周",
- dateFormat: "yy-mm-dd",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: "年" };
-datepicker.setDefaults( datepicker.regional[ "zh-CN" ] );
-
-return datepicker.regional[ "zh-CN" ];
-
-} ) );
diff --git a/ui/i18n/datepicker-zh-HK.js b/ui/i18n/datepicker-zh-HK.js
deleted file mode 100644
index 27f02bc65..000000000
--- a/ui/i18n/datepicker-zh-HK.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Chinese initialisation for the jQuery UI date picker plugin. */
-/* Written by SCCY (samuelcychan@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "zh-HK" ] = {
- closeText: "關閉",
- prevText: "&#x3C;上月",
- nextText: "下月&#x3E;",
- currentText: "今天",
- monthNames: [ "一月","二月","三月","四月","五月","六月",
- "七月","八月","九月","十月","十一月","十二月" ],
- monthNamesShort: [ "一月","二月","三月","四月","五月","六月",
- "七月","八月","九月","十月","十一月","十二月" ],
- dayNames: [ "星期日","星期一","星期二","星期三","星期四","星期五","星期六" ],
- dayNamesShort: [ "周日","周一","周二","周三","周四","周五","周六" ],
- dayNamesMin: [ "日","一","二","三","四","五","六" ],
- weekHeader: "周",
- dateFormat: "dd-mm-yy",
- firstDay: 0,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: "年" };
-datepicker.setDefaults( datepicker.regional[ "zh-HK" ] );
-
-return datepicker.regional[ "zh-HK" ];
-
-} ) );
diff --git a/ui/i18n/datepicker-zh-TW.js b/ui/i18n/datepicker-zh-TW.js
deleted file mode 100644
index c20754bd5..000000000
--- a/ui/i18n/datepicker-zh-TW.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Chinese initialisation for the jQuery UI date picker plugin. */
-/* Written by Ressol (ressol@gmail.com). */
-( function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define( [ "../widgets/datepicker" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery.datepicker );
- }
-}( function( datepicker ) {
-
-datepicker.regional[ "zh-TW" ] = {
- closeText: "關閉",
- prevText: "&#x3C;上月",
- nextText: "下月&#x3E;",
- currentText: "今天",
- monthNames: [ "一月","二月","三月","四月","五月","六月",
- "七月","八月","九月","十月","十一月","十二月" ],
- monthNamesShort: [ "一月","二月","三月","四月","五月","六月",
- "七月","八月","九月","十月","十一月","十二月" ],
- dayNames: [ "星期日","星期一","星期二","星期三","星期四","星期五","星期六" ],
- dayNamesShort: [ "周日","周一","周二","周三","周四","周五","周六" ],
- dayNamesMin: [ "日","一","二","三","四","五","六" ],
- weekHeader: "周",
- dateFormat: "yy/mm/dd",
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: true,
- yearSuffix: "年" };
-datepicker.setDefaults( datepicker.regional[ "zh-TW" ] );
-
-return datepicker.regional[ "zh-TW" ];
-
-} ) );
diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js
new file mode 100644
index 000000000..c056a9ac2
--- /dev/null
+++ b/ui/widgets/calendar.js
@@ -0,0 +1,689 @@
+/*!
+ * jQuery UI Calendar @VERSION
+ * http://jqueryui.com
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Datepicker
+//>>group: Widgets
+//>>description: Displays a calendar for inline date selection.
+//>>docs: http://api.jqueryui.com/calendar/
+//>>demos: http://jqueryui.com/calendar/
+
+( function( factory ) {
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD. Register as an anonymous module.
+ define( [
+ "jquery",
+ "globalize",
+ "globalize/date",
+ "globalize-locales",
+ "../date",
+ "./button",
+ "../widget",
+ "../version",
+ "../keycode",
+ "../unique-id",
+ "../tabbable",
+ "../escape-selector"
+ ], factory );
+ } else {
+
+ // Browser globals
+ factory( jQuery, Globalize );
+ }
+}( function( $, Globalize ) {
+
+return $.widget( "ui.calendar", {
+ version: "@VERSION",
+ options: {
+ buttons: [],
+ dateFormat: { date: "short" },
+ eachDay: $.noop,
+ labels: {
+ "datePickerRole": "date picker",
+ "nextText": "Next",
+ "prevText": "Prev",
+ "weekHeader": "Wk"
+ },
+ locale: "en",
+ max: null,
+ min: null,
+ numberOfMonths: 1,
+ showWeek: false,
+ value: null,
+
+ // callbacks
+ select: null
+ },
+
+ refreshRelatedOptions: {
+ dateFormat: true,
+ eachDay: true,
+ locale: true,
+ max: true,
+ min: true,
+ showWeek: true,
+ value: true
+ },
+
+ _create: function() {
+ this.id = this.element.uniqueId().attr( "id" );
+ this.labels = this.options.labels;
+ this.buttonClickContext = this.element[ 0 ];
+
+ this._setLocale( this.options.locale, this.options.dateFormat );
+
+ this.date = new $.ui.date( this.options.value, this._calendarDateOptions );
+ this.viewDate = this.date.clone();
+ this.viewDate.eachDay = this.options.eachDay;
+
+ this._on( this.element, {
+ "click .ui-calendar-prev": function( event ) {
+ event.preventDefault();
+ this.date.adjust( "M", -this.options.numberOfMonths );
+ this.viewDate.setTime( this.date.date().getTime() );
+ this.refresh();
+ },
+ "click .ui-calendar-next": function( event ) {
+ event.preventDefault();
+ this.date.adjust( "M", this.options.numberOfMonths );
+ this.viewDate.setTime( this.date.date().getTime() );
+ this.refresh();
+ },
+ "mousedown .ui-calendar-calendar button": function( event ) {
+ event.preventDefault();
+
+ this._setOption( "value", new Date( $( event.currentTarget ).data( "timestamp" ) ) );
+ this.refresh();
+ this._trigger( "select", event );
+ this.grid.focus();
+ },
+ "mouseenter .ui-calendar-header button": "_hover",
+ "mouseleave .ui-calendar-header button": "_hover",
+ "mouseenter .ui-calendar-calendar button": "_hover",
+ "mouseleave .ui-calendar-calendar button": "_hover",
+ "keydown .ui-calendar-calendar": "_handleKeydown"
+ } );
+
+ this._createCalendar();
+ },
+
+ _hover: function( event ) {
+ $( event.currentTarget ).toggleClass( "ui-state-hover" );
+ },
+
+ _handleKeydown: function( event ) {
+ switch ( event.keyCode ) {
+ case $.ui.keyCode.ENTER:
+ this.activeDescendant.mousedown();
+ return;
+ case $.ui.keyCode.PAGE_UP:
+ this.date.adjust( event.altKey ? "Y" : "M", -1 );
+ break;
+ case $.ui.keyCode.PAGE_DOWN:
+ this.date.adjust( event.altKey ? "Y" : "M", 1 );
+ break;
+ case $.ui.keyCode.END:
+ this.date.setDay( this.date.daysInMonth() );
+ break;
+ case $.ui.keyCode.HOME:
+ this.date.setDay( 1 );
+ break;
+ case $.ui.keyCode.LEFT:
+ this.date.adjust( "D", -1 );
+ break;
+ case $.ui.keyCode.UP:
+ this.date.adjust( "D", -7 );
+ break;
+ case $.ui.keyCode.RIGHT:
+ this.date.adjust( "D", 1 );
+ break;
+ case $.ui.keyCode.DOWN:
+ this.date.adjust( "D", 7 );
+ break;
+ default:
+ event.preventDefault();
+ return;
+ }
+
+ if ( this._needsRefresh() ) {
+ if ( this.options.numberOfMonths > 1 && this.date.year() === this.viewDate.year() ) {
+ this.viewDate.adjust( "M", this.options.numberOfMonths *
+ ( this.date.month() > this.viewDate.month() ? 1 : -1 )
+ );
+ this.refresh();
+ } else {
+ this.viewDate.setTime( this.date.date().getTime() );
+ this.refresh();
+ }
+ this.grid.focus();
+ }
+
+ this._setActiveDescendant();
+ },
+
+ _needsRefresh: function() {
+ if ( this.date.month() !== this.viewDate.month() || this.date.year() !== this.viewDate.year() ) {
+
+ // Check if the needed day is already present in our grid due
+ // to eachDay option changes (eg. other-months demo)
+ return !this.grid.find(
+ "#" + $.ui.escapeSelector( this._getDayId( this.date ) )
+ ).length;
+ }
+
+ return false;
+ },
+
+ _setActiveDescendant: function() {
+ var id = this._getDayId( this.date );
+
+ this.grid
+ .attr( "aria-activedescendant", id )
+ .find( ".ui-state-focus" )
+ .removeClass( "ui-state-focus" );
+
+ this.activeDescendant = this.grid.find(
+ "#" + $.ui.escapeSelector( id ) + " > button"
+ ).addClass( "ui-state-focus" );
+ },
+
+ _setLocale: function( locale, dateFormat ) {
+ var globalize = new Globalize( locale ),
+ weekdayShortFormatter = globalize.dateFormatter( { raw: "EEEEEE" } ),
+ weekdayNarrowFormatter = globalize.dateFormatter( { raw: "EEEEE" } ),
+ firstDayRaw = globalize.dateFormatter( { raw: "c" } )( new Date( 1970, 0, 3 ) );
+
+ this._format = globalize.dateFormatter( dateFormat );
+ this._parse = globalize.dateParser( dateFormat );
+ this._calendarDateOptions = {
+ firstDay: ( 7 - globalize.parseNumber( firstDayRaw ) ),
+ formatWeekdayShort: function( date ) {
+
+ // Return the short weekday if its length is < 3. Otherwise, its narrow form.
+ var shortWeekday = weekdayShortFormatter( date );
+
+ return shortWeekday.length > 3 ? weekdayNarrowFormatter( date ) : shortWeekday;
+ },
+ formatWeekdayFull: globalize.dateFormatter( { raw: "EEEE" } ),
+ formatMonth: globalize.dateFormatter( { raw: "MMMM" } ),
+ formatWeekOfYear: globalize.dateFormatter( { raw: "w" } ),
+ parse: this._parse
+ };
+ },
+
+ _createCalendar: function() {
+ var classes = "ui-calendar ui-widget ui-widget-content ui-helper-clearfix ui-corner-all",
+ pickerHtml = "";
+
+ if ( this.options.numberOfMonths === 1 ) {
+ pickerHtml = this._buildHeader() + this._buildGrid();
+ } else {
+ pickerHtml = this._buildMultiplePicker();
+ classes += " ui-calendar-multi";
+ }
+
+ this.element
+ .addClass( classes )
+ .attr( {
+ role: "region",
+ "aria-labelledby": this.id + "-title"
+ } )
+ .html( pickerHtml );
+
+ this.prevButton = this.element.find( ".ui-calendar-prev" );
+ this.nextButton = this.element.find( ".ui-calendar-next" );
+ this._refreshHeaderButtons();
+
+ this._createButtonPane();
+
+ this.grid = this.element.find( ".ui-calendar-calendar" );
+ },
+
+ _buildMultiplePicker: function() {
+ var headerClass,
+ html = "",
+ currentDate = this.viewDate,
+ months = this.viewDate.months( this.options.numberOfMonths - 1 ),
+ i = 0;
+
+ for ( ; i < months.length; i++ ) {
+
+ // TODO: Shouldn't we pass date as a parameter to build* fns instead of setting this.date?
+ this.viewDate = months[ i ];
+ headerClass = "ui-calendar-header ui-widget-header ui-helper-clearfix";
+ if ( months[ i ].first ) {
+ headerClass += " ui-corner-left";
+ } else if ( months[ i ].last ) {
+ headerClass += " ui-corner-right";
+ }
+
+ html += "<div class='ui-calendar-group'>" +
+ "<div class='" + headerClass + "'>";
+ if ( months[ i ].first ) {
+ html += this._buildPreviousLink();
+ } else if ( months[ i ].last ) {
+ html += this._buildNextLink();
+ }
+
+ html += this._buildTitlebar() + "</div>" + this._buildGrid() + "</div>";
+ }
+
+ html += "<div class='ui-calendar-row-break'></div>";
+
+ this.viewDate = currentDate;
+
+ return html;
+ },
+
+ _buildHeader: function() {
+ return "<div class='ui-calendar-header ui-widget-header ui-helper-clearfix ui-corner-all'>" +
+ this._buildPreviousLink() +
+ this._buildNextLink() +
+ this._buildTitlebar() +
+ "</div>";
+ },
+
+ _buildPreviousLink: function() {
+ return "<button class='ui-calendar-prev ui-corner-all'>" +
+ "<span class='ui-icon ui-icon-circle-triangle-w'></span>" +
+ "</button>";
+ },
+
+ _buildNextLink: function() {
+ return "<button class='ui-calendar-next ui-corner-all'>" +
+ "<span class='ui-icon ui-icon-circle-triangle-e'></span>" +
+ "</button>";
+ },
+
+ _buildTitlebar: function() {
+ return "<div role='header' id='" + this.id + "-title'>" +
+ "<div id='" + this.id + "-month-label' class='ui-calendar-title'>" +
+ this._buildTitle() +
+ "</div>" +
+ "<span class='ui-helper-hidden-accessible'>, " +
+ this._getTranslation( "datePickerRole" ) +
+ "</span>" +
+ "</div>";
+ },
+
+ _buildTitle: function() {
+ return "<span class='ui-calendar-month'>" +
+ this.viewDate.monthName() +
+ "</span> " +
+ "<span class='ui-calendar-year'>" +
+ this.viewDate.year() +
+ "</span>";
+ },
+
+ _buildGrid: function() {
+ return "<table class='ui-calendar-calendar' role='grid' aria-readonly='true' " +
+ "aria-labelledby='" + this.id + "-month-label' tabindex='0' " +
+ "aria-activedescendant='" + this._getDayId( this.date ) + "'>" +
+ this._buildGridHeading() +
+ this._buildGridBody() +
+ "</table>";
+ },
+
+ _buildGridHeading: function() {
+ var cells = "",
+ i = 0,
+ weekDayLength = this.viewDate.weekdays().length,
+ weekdays = this.viewDate.weekdays();
+
+ if ( this.options.showWeek ) {
+ cells += "<th class='ui-calendar-week-col'>" + this._getTranslation( "weekHeader" ) + "</th>";
+ }
+ for ( ; i < weekDayLength; i++ ) {
+ cells += this._buildGridHeaderCell( weekdays[ i ] );
+ }
+
+ return "<thead role='presentation'>" +
+ "<tr role='row'>" + cells + "</tr>" +
+ "</thead>";
+ },
+
+ _buildGridHeaderCell: function( day ) {
+ return "<th role='columnheader' abbr='" + day.fullname + "' aria-label='" + day.fullname + "'>" +
+ "<span title='" + day.fullname + "'>" +
+ day.shortname +
+ "</span>" +
+ "</th>";
+ },
+
+ _buildGridBody: function() {
+ var days = this.viewDate.days(),
+ i = 0,
+ rows = "";
+
+ for ( ; i < days.length; i++ ) {
+ rows += this._buildWeekRow( days[ i ] );
+ }
+
+ return "<tbody role='presentation'>" + rows + "</tbody>";
+ },
+
+ _buildWeekRow: function( week ) {
+ var cells = "",
+ i = 0;
+
+ if ( this.options.showWeek ) {
+ cells += "<td class='ui-calendar-week-col'>" + week.number + "</td>";
+ }
+ for ( ; i < week.days.length; i++ ) {
+ cells += this._buildDayCell( week.days[ i ] );
+ }
+
+ return "<tr role='row'>" + cells + "</tr>";
+ },
+
+ _buildDayCell: function( day ) {
+ var content = "",
+ attributes = [
+ "role='gridcell'",
+ "aria-selected='" + ( this._isCurrent( day ) ? true : false ) + "'"
+ ],
+ selectable = ( day.selectable && this._isValid( new Date( day.timestamp ) ) );
+
+ if ( day.render ) {
+ attributes.push( "id='" + this.id + "-" + day.year + "-" + day.month + "-" + day.date + "'" );
+
+ if ( !selectable ) {
+ attributes.push( "aria-disabled='true'" );
+ attributes.push( "class='ui-state-disabled'" );
+ }
+
+ content = this._buildDayElement( day, selectable );
+ }
+
+ return "<td " + attributes.join( " " ) + ">" + content + "</td>";
+ },
+
+ _getDayId: function( date ) {
+ return this.id + "-" + date.year() + "-" + date.month() + "-" + date.day();
+ },
+
+ _buildDayElement: function( day, selectable ) {
+ var attributes, content,
+ classes = [ "ui-state-default" ];
+
+ if ( day === this.date && selectable ) {
+ classes.push( "ui-state-focus" );
+ }
+ if ( this._isCurrent( day ) ) {
+ classes.push( "ui-state-active" );
+ }
+ if ( day.today ) {
+ classes.push( "ui-state-highlight" );
+ }
+ if ( day.extraClasses ) {
+ classes.push( day.extraClasses.split( " " ) );
+ }
+
+ attributes = " class='" + classes.join( " " ) + "'";
+ if ( selectable ) {
+ attributes += " tabindex='-1' data-timestamp='" + day.timestamp + "'";
+ } else {
+ attributes += " disabled='disabled'";
+ }
+ content = "<button" + attributes + ">" + day.date + "</button>";
+
+ if ( day.today ) {
+ content += "<span class='ui-helper-hidden-accessible'>, " + this._getTranslation( "currentText" ) + "</span>";
+ }
+
+ return content;
+ },
+
+ _isCurrent: function( day ) {
+ return this.options.value && day.timestamp === this.options.value.getTime();
+ },
+
+ _createButtonPane: function() {
+ this.buttonPane = $( "<div>" )
+ .addClass( "ui-calendar-buttonpane ui-widget-content ui-helper-clearfix" );
+
+ this.buttonSet = $( "<div>" )
+ .addClass( "ui-calendar-buttonset" )
+ .appendTo( this.buttonPane );
+
+ this._createButtons();
+ },
+
+ _createButtons: function() {
+ var that = this,
+ buttons = this.options.buttons;
+
+ this.buttonPane.remove();
+ this.buttonSet.empty();
+
+ if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
+ this.element.removeClass( "ui-calendar-buttons" );
+ return;
+ }
+
+ $.each( buttons, function( name, props ) {
+ var click, buttonOptions;
+ props = $.isFunction( props ) ?
+ { click: props, text: name } :
+ props;
+
+ // Default to a non-submitting button
+ props = $.extend( { type: "button" }, props );
+
+ // Change the context for the click callback to be the main element
+ click = props.click;
+ props.click = function() {
+ click.apply( that.buttonClickContext, arguments );
+ };
+ buttonOptions = {
+ icons: props.icons,
+ text: props.showText
+ };
+ delete props.icons;
+ delete props.showText;
+ $( "<button></button>", props )
+ .button( buttonOptions )
+ .appendTo( that.buttonSet );
+ } );
+ this.element.addClass( "ui-calendar-buttons" );
+ this.buttonPane.appendTo( this.element );
+ },
+
+ // Refreshing the entire calendar during interaction confuses screen readers, specifically
+ // because the grid heading is marked up as a live region and will often not update if it's
+ // destroyed and recreated instead of just having its text change. Additionally, interacting
+ // with the prev and next links would cause loss of focus issues because the links being
+ // interacted with will disappear while focused.
+ refresh: function() {
+ this.labels = this.options.labels;
+
+ // Determine which day gridcell to focus after refresh
+ // TODO: Prevent disabled cells from being focused
+ if ( this.options.numberOfMonths === 1 ) {
+ this.grid = $( this._buildGrid() );
+ this.element.find( ".ui-calendar-title" ).html( this._buildTitle() );
+ this.element.find( ".ui-calendar-calendar" ).replaceWith( this.grid );
+ } else {
+ this._refreshMultiplePicker();
+ }
+
+ this._refreshHeaderButtons();
+ this._createButtons();
+ },
+
+ _refreshHeaderButtons: function() {
+ var prevText = this._getTranslation( "prevText" ),
+ nextText = this._getTranslation( "nextText" );
+
+ this.prevButton.attr( "title", prevText ).children().html( prevText );
+ this.nextButton.attr( "title", nextText ).children().html( nextText );
+ this._headerButtonsState();
+ },
+
+ _headerButtonsState: function() {
+ var months = this.viewDate.months( this.options.numberOfMonths - 1 ),
+ i = 0;
+
+ for ( ; i < months.length; i++ ) {
+ if ( this.options.min !== null && months[ i ].first ) {
+ this._disableElement( this.prevButton,
+ ( this.options.min.getMonth() >= months[ i ].month() &&
+ this.options.min.getFullYear() === months[ i ].year() ) ||
+ this.options.min.getFullYear() > months[ i ].year()
+ );
+ }
+ if ( this.options.max !== null && months[ i ].last ) {
+ this._disableElement( this.nextButton,
+ ( this.options.max.getMonth() <= months[ i ].month() &&
+ this.options.max.getFullYear() === months[ i ].year() ) ||
+ this.options.max.getFullYear() < months[ i ].year()
+ );
+ }
+ }
+ },
+
+ _disableElement: function( element, state ) {
+ element
+ .attr( "aria-disabled", state )
+ .toggleClass( "ui-state-disabled", state );
+ },
+
+ _refreshMultiplePicker: function() {
+ var i = 0;
+
+ for ( ; i < this.options.numberOfMonths; i++ ) {
+ this.element.find( ".ui-calendar-title" ).eq( i ).html( this._buildTitle() );
+ this.element.find( ".ui-calendar-calendar" ).eq( i ).html( this._buildGrid() );
+ this.viewDate.adjust( "M", 1 );
+ }
+ this.viewDate.adjust( "M", -this.options.numberOfMonths );
+
+ // TODO: This assumes focus is on the first grid. For multi pickers, the widget needs
+ // to maintain the currently focused grid and base queries like this off of it.
+ this.element.find( ".ui-state-focus" ).not( ":first" ).removeClass( "ui-state-focus" );
+ },
+
+ _getTranslation: function( key ) {
+ return $( "<a>" ).text( this.labels[ key ] ).html();
+ },
+
+ _setHiddenPicker: function() {
+ this.element.attr( {
+ "aria-hidden": "true",
+ "aria-expanded": "false"
+ } );
+ },
+
+ value: function( value ) {
+ if ( arguments.length ) {
+ this.valueAsDate( this._parse( value ) );
+ } else {
+ return this._format( this.option( "value" ) );
+ }
+ },
+
+ valueAsDate: function( value ) {
+ if ( arguments.length ) {
+ this.option( "value", value );
+ } else {
+ return this.options.value;
+ }
+ },
+
+ _isValid: function( value ) {
+ if ( $.type( value ) !== "date" ) {
+ return false;
+ }
+
+ if ( $.type( this.options.max ) === "date" ) {
+ if ( value > this.options.max ) {
+ return false;
+ }
+ }
+
+ if ( $.type( this.options.min ) === "date" ) {
+ if ( value < this.options.min ) {
+ return false;
+ }
+ }
+
+ return true;
+ },
+
+ _destroy: function() {
+ this.element
+ .off( ".calendar" )
+ .removeClass( "ui-calendar ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-calendar-multi" )
+ .removeAttr( "role aria-labelledby" )
+ .removeUniqueId()
+ .empty();
+ },
+
+ _setOptions: function( options ) {
+ var that = this,
+ refresh = false,
+ dateAttributes = false;
+
+ $.each( options, function( key, value ) {
+ that._setOption( key, value );
+
+ if ( key in that.refreshRelatedOptions ) {
+ refresh = true;
+ }
+ if ( key === "dateFormat" || key === "locale" ) {
+ dateAttributes = true;
+ }
+ } );
+
+ if ( dateAttributes ) {
+ this._setLocale( this.options.locale, this.options.dateFormat );
+ this.date.setAttributes( this._calendarDateOptions );
+ this.viewDate.setAttributes( this._calendarDateOptions );
+ }
+ if ( refresh ) {
+ this.viewDate.setTime( this.date.date().getTime() );
+ this.refresh();
+ }
+ },
+
+ _setOption: function( key, value ) {
+ if ( key === "value" ) {
+ if ( this._isValid( value ) ) {
+ this.date.setTime( value.getTime() );
+ this._super( key, value );
+ }
+ return;
+ }
+
+ if ( key === "max" || key === "min" ) {
+ if ( $.type( value ) === "date" || value === null ) {
+ this._super( key, value );
+ }
+ return;
+ }
+
+ this._super( key, value );
+
+ if ( key === "buttons" ) {
+ this._createButtons();
+ }
+
+ if ( key === "disabled" ) {
+ this.element
+ .toggleClass( "ui-state-disabled", value )
+ .attr( "aria-disabled", value );
+ }
+
+ if ( key === "eachDay" ) {
+ this.viewDate.eachDay = value;
+ }
+ }
+} );
+
+} ) );
diff --git a/ui/widgets/datepicker.js b/ui/widgets/datepicker.js
index b116a1352..3534b3144 100644
--- a/ui/widgets/datepicker.js
+++ b/ui/widgets/datepicker.js
@@ -1,4 +1,3 @@
-/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
/*!
* jQuery UI Datepicker @VERSION
* http://jqueryui.com
@@ -10,12 +9,9 @@
//>>label: Datepicker
//>>group: Widgets
-//>>description: Displays a calendar from an input or inline for selecting dates.
+//>>description: Displays a calendar for input-based date selection.
//>>docs: http://api.jqueryui.com/datepicker/
//>>demos: http://jqueryui.com/datepicker/
-//>>css.structure: ../../themes/base/core.css
-//>>css.structure: ../../themes/base/datepicker.css
-//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
@@ -23,2097 +19,347 @@
// AMD. Register as an anonymous module.
define( [
"jquery",
+ "globalize",
+ "globalize/date",
+ "./calendar",
+ "../widget",
+ "../position",
"../version",
"../keycode"
], factory );
} else {
// Browser globals
- factory( jQuery );
+ factory( jQuery, Globalize );
}
-}( function( $ ) {
+}( function( $, Globalize ) {
-$.extend( $.ui, { datepicker: { version: "@VERSION" } } );
+var widget = $.widget( "ui.datepicker", {
+ version: "@VERSION",
+ options: {
+ appendTo: null,
+ position: {
+ my: "left top",
+ at: "left bottom"
+ },
+ show: true,
+ hide: true,
-var datepicker_instActive;
-
-function datepicker_getZindex( elem ) {
- var position, value;
- while ( elem.length && elem[ 0 ] !== document ) {
-
- // Ignore z-index if position is set to a value where z-index is ignored by the browser
- // This makes behavior of this function consistent across browsers
- // WebKit always returns auto if the element is positioned
- position = elem.css( "position" );
- if ( position === "absolute" || position === "relative" || position === "fixed" ) {
-
- // IE returns 0 when zIndex is not specified
- // other browsers return a string
- // we ignore the case of nested elements with an explicit value of 0
- // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
- value = parseInt( elem.css( "zIndex" ), 10 );
- if ( !isNaN( value ) && value !== 0 ) {
- return value;
- }
- }
- elem = elem.parent();
- }
-
- return 0;
-}
-/* Date picker manager.
- Use the singleton instance of this class, $.datepicker, to interact with the date picker.
- Settings for (groups of) date pickers are maintained in an instance object,
- allowing multiple different settings on the same page. */
-
-function Datepicker() {
- this._curInst = null; // The current instance in use
- this._keyEvent = false; // If the last event was a key event
- this._disabledInputs = []; // List of date picker inputs that have been disabled
- this._datepickerShowing = false; // True if the popup picker is showing , false if not
- this._inDialog = false; // True if showing within a "dialog", false if not
- this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
- this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
- this._appendClass = "ui-datepicker-append"; // The name of the append marker class
- this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
- this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
- this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
- this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
- this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
- this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
- this.regional = []; // Available regional settings, indexed by language code
- this.regional[ "" ] = { // Default regional settings
- closeText: "Done", // Display text for close link
- prevText: "Prev", // Display text for previous month link
- nextText: "Next", // Display text for next month link
- currentText: "Today", // Display text for current month link
- monthNames: [ "January","February","March","April","May","June",
- "July","August","September","October","November","December" ], // Names of months for drop-down and formatting
- monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
- dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
- dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
- dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
- weekHeader: "Wk", // Column header for week of the year
- dateFormat: "mm/dd/yy", // See format options on parseDate
- firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
- isRTL: false, // True if right-to-left language, false if left-to-right
- showMonthAfterYear: false, // True if the year select precedes month, false for month then year
- yearSuffix: "" // Additional text to append to the year in the month headers
- };
- this._defaults = { // Global defaults for all the date picker instances
- showOn: "focus", // "focus" for popup on focus,
- // "button" for trigger button, or "both" for either
- showAnim: "fadeIn", // Name of jQuery animation for popup
- showOptions: {}, // Options for enhanced animations
- defaultDate: null, // Used when field is blank: actual date,
- // +/-number for offset from today, null for today
- appendText: "", // Display text following the input box, e.g. showing the format
- buttonText: "...", // Text for trigger button
- buttonImage: "", // URL for trigger button image
- buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
- hideIfNoPrevNext: false, // True to hide next/previous month links
- // if not applicable, false to just disable them
- navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
- gotoCurrent: false, // True if today link goes back to current selection instead
- changeMonth: false, // True if month can be selected directly, false if only prev/next
- changeYear: false, // True if year can be selected directly, false if only prev/next
- yearRange: "c-10:c+10", // Range of years to display in drop-down,
- // either relative to today's year (-nn:+nn), relative to currently displayed year
- // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
- showOtherMonths: false, // True to show dates in other months, false to leave blank
- selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
- showWeek: false, // True to show week of the year, false to not show it
- calculateWeek: this.iso8601Week, // How to calculate the week of the year,
- // takes a Date and returns the number of the week for it
- shortYearCutoff: "+10", // Short year values < this are in the current century,
- // > this are in the previous century,
- // string value starting with "+" for current year + value
- minDate: null, // The earliest selectable date, or null for no limit
- maxDate: null, // The latest selectable date, or null for no limit
- duration: "fast", // Duration of display/closure
- beforeShowDay: null, // Function that takes a date and returns an array with
- // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
- // [2] = cell title (optional), e.g. $.datepicker.noWeekends
- beforeShow: null, // Function that takes an input field and
- // returns a set of custom settings for the date picker
- onSelect: null, // Define a callback function when a date is selected
- onChangeMonthYear: null, // Define a callback function when the month or year is changed
- onClose: null, // Define a callback function when the datepicker is closed
- numberOfMonths: 1, // Number of months to show at a time
- showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
- stepMonths: 1, // Number of months to step back/forward
- stepBigMonths: 12, // Number of months to step back/forward for the big links
- altField: "", // Selector for an alternate field to store selected dates into
- altFormat: "", // The date format to use for the alternate field
- constrainInput: true, // The input is constrained by the current date format
- showButtonPanel: false, // True to show button panel, false to not show it
- autoSize: false, // True to size the input for the date format, false to leave as is
- disabled: false // The initial disabled state
- };
- $.extend( this._defaults, this.regional[ "" ] );
- this.regional.en = $.extend( true, {}, this.regional[ "" ] );
- this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
- this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
-}
-
-$.extend( Datepicker.prototype, {
- /* Class name added to elements to indicate already configured with a date picker. */
- markerClassName: "hasDatepicker",
-
- //Keep track of the maximum number of rows displayed (see #7043)
- maxRows: 4,
-
- // TODO rename to "widget" when switching to widget factory
- _widgetDatepicker: function() {
- return this.dpDiv;
- },
-
- /* Override the default settings for all instances of the date picker.
- * @param settings object - the new settings to use as defaults (anonymous object)
- * @return the manager object
- */
- setDefaults: function( settings ) {
- datepicker_extendRemove( this._defaults, settings || {} );
- return this;
- },
-
- /* Attach the date picker to a jQuery selection.
- * @param target element - the target input field or division or span
- * @param settings object - the new settings to use for this date picker instance (anonymous)
- */
- _attachDatepicker: function( target, settings ) {
- var nodeName, inline, inst;
- nodeName = target.nodeName.toLowerCase();
- inline = ( nodeName === "div" || nodeName === "span" );
- if ( !target.id ) {
- this.uuid += 1;
- target.id = "dp" + this.uuid;
- }
- inst = this._newInst( $( target ), inline );
- inst.settings = $.extend( {}, settings || {} );
- if ( nodeName === "input" ) {
- this._connectDatepicker( target, inst );
- } else if ( inline ) {
- this._inlineDatepicker( target, inst );
- }
- },
-
- /* Create a new instance object. */
- _newInst: function( target, inline ) {
- var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
- return { id: id, input: target, // associated target
- selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
- drawMonth: 0, drawYear: 0, // month being drawn
- inline: inline, // is datepicker inline or not
- dpDiv: ( !inline ? this.dpDiv : // presentation div
- datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
- },
-
- /* Attach the date picker to an input field. */
- _connectDatepicker: function( target, inst ) {
- var input = $( target );
- inst.append = $( [] );
- inst.trigger = $( [] );
- if ( input.hasClass( this.markerClassName ) ) {
- return;
- }
- this._attachments( input, inst );
- input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
- on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
- this._autoSize( inst );
- $.data( target, "datepicker", inst );
-
- //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
- if ( inst.settings.disabled ) {
- this._disableDatepicker( target );
- }
+ // callbacks
+ beforeOpen: null,
+ close: null,
+ open: null,
+ select: null
},
- /* Make attachments based on settings. */
- _attachments: function( input, inst ) {
- var showOn, buttonText, buttonImage,
- appendText = this._get( inst, "appendText" ),
- isRTL = this._get( inst, "isRTL" );
-
- if ( inst.append ) {
- inst.append.remove();
- }
- if ( appendText ) {
- inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
- input[ isRTL ? "before" : "after" ]( inst.append );
- }
-
- input.off( "focus", this._showDatepicker );
+ calendarOptions: [ "buttons", "disabled", "dateFormat", "eachDay", "labels",
+ "locale", "max", "min", "numberOfMonths", "showWeek" ],
- if ( inst.trigger ) {
- inst.trigger.remove();
- }
+ _create: function() {
+ this.suppressExpandOnFocus = false;
- showOn = this._get( inst, "showOn" );
- if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
- input.on( "focus", this._showDatepicker );
+ if ( $.type( this.options.max ) === "string" ) {
+ this.options.max = Globalize.parseDate( this.options.max, { raw: "yyyy-MM-dd" } );
}
- if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
- buttonText = this._get( inst, "buttonText" );
- buttonImage = this._get( inst, "buttonImage" );
- inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
- $( "<img/>" ).addClass( this._triggerClass ).
- attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
- $( "<button type='button'></button>" ).addClass( this._triggerClass ).
- html( !buttonImage ? buttonText : $( "<img/>" ).attr(
- { src:buttonImage, alt:buttonText, title:buttonText } ) ) );
- input[ isRTL ? "before" : "after" ]( inst.trigger );
- inst.trigger.on( "click", function() {
- if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
- $.datepicker._hideDatepicker();
- } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
- $.datepicker._hideDatepicker();
- $.datepicker._showDatepicker( input[ 0 ] );
- } else {
- $.datepicker._showDatepicker( input[ 0 ] );
- }
- return false;
- } );
+ if ( $.type( this.options.min ) === "string" ) {
+ this.options.min = Globalize.parseDate( this.options.min, { raw: "yyyy-MM-dd" } );
}
- },
- /* Apply the maximum length for the date format. */
- _autoSize: function( inst ) {
- if ( this._get( inst, "autoSize" ) && !inst.inline ) {
- var findMax, max, maxI, i,
- date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
- dateFormat = this._get( inst, "dateFormat" );
+ this._createCalendar();
- if ( dateFormat.match( /[DM]/ ) ) {
- findMax = function( names ) {
- max = 0;
- maxI = 0;
- for ( i = 0; i < names.length; i++ ) {
- if ( names[ i ].length > max ) {
- max = names[ i ].length;
- maxI = i;
- }
- }
- return maxI;
- };
- date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
- "monthNames" : "monthNamesShort" ) ) ) );
- date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
- "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
- }
- inst.input.attr( "size", this._formatDate( inst, date ).length );
- }
+ this._on( this._inputEvents );
+ this._on( this.calendar, this._calendarEvents );
+ this._on( this.document, this._documentEvents );
},
- /* Attach an inline date picker to a div. */
- _inlineDatepicker: function( target, inst ) {
- var divSpan = $( target );
- if ( divSpan.hasClass( this.markerClassName ) ) {
- return;
- }
- divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
- $.data( target, "datepicker", inst );
- this._setDate( inst, this._getDefaultDate( inst ), true );
- this._updateDatepicker( inst );
- this._updateAlternate( inst );
-
- //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
- if ( inst.settings.disabled ) {
- this._disableDatepicker( target );
- }
-
- // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
- // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
- inst.dpDiv.css( "display", "block" );
- },
-
- /* Pop-up the date picker in a "dialog" box.
- * @param input element - ignored
- * @param date string or Date - the initial date to display
- * @param onSelect function - the function to call when a date is selected
- * @param settings object - update the dialog date picker instance's settings (anonymous object)
- * @param pos int[2] - coordinates for the dialog's position within the screen or
- * event - with x/y coordinates or
- * leave empty for default (screen centre)
- * @return the manager object
- */
- _dialogDatepicker: function( input, date, onSelect, settings, pos ) {
- var id, browserWidth, browserHeight, scrollX, scrollY,
- inst = this._dialogInst; // internal instance
+ _getCreateOptions: function() {
+ var max = this.element.attr( "max" ),
+ min = this.element.attr( "min" ),
+ options = {};
- if ( !inst ) {
- this.uuid += 1;
- id = "dp" + this.uuid;
- this._dialogInput = $( "<input type='text' id='" + id +
- "' style='position: absolute; top: -100px; width: 0px;'/>" );
- this._dialogInput.on( "keydown", this._doKeyDown );
- $( "body" ).append( this._dialogInput );
- inst = this._dialogInst = this._newInst( this._dialogInput, false );
- inst.settings = {};
- $.data( this._dialogInput[ 0 ], "datepicker", inst );
+ if ( max !== undefined ) {
+ options.max = Globalize.parseDate( max, { raw: "yyyy-MM-dd" } );
}
- datepicker_extendRemove( inst.settings, settings || {} );
- date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
- this._dialogInput.val( date );
- this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
- if ( !this._pos ) {
- browserWidth = document.documentElement.clientWidth;
- browserHeight = document.documentElement.clientHeight;
- scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
- scrollY = document.documentElement.scrollTop || document.body.scrollTop;
- this._pos = // should use actual width/height below
- [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
+ if ( min !== undefined ) {
+ options.min = Globalize.parseDate( min, { raw: "yyyy-MM-dd" } );
}
- // Move input on screen for focus, but hidden behind dialog
- this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
- inst.settings.onSelect = onSelect;
- this._inDialog = true;
- this.dpDiv.addClass( this._dialogClass );
- this._showDatepicker( this._dialogInput[ 0 ] );
- if ( $.blockUI ) {
- $.blockUI( this.dpDiv );
- }
- $.data( this._dialogInput[ 0 ], "datepicker", inst );
- return this;
+ return options;
},
- /* Detach a datepicker from its control.
- * @param target element - the target input field or division or span
- */
- _destroyDatepicker: function( target ) {
- var nodeName,
- $target = $( target ),
- inst = $.data( target, "datepicker" );
+ _createCalendar: function() {
+ var that = this,
+ globalize = new Globalize( this.options.locale );
- if ( !$target.hasClass( this.markerClassName ) ) {
- return;
- }
-
- nodeName = target.nodeName.toLowerCase();
- $.removeData( target, "datepicker" );
- if ( nodeName === "input" ) {
- inst.append.remove();
- inst.trigger.remove();
- $target.removeClass( this.markerClassName ).
- off( "focus", this._showDatepicker ).
- off( "keydown", this._doKeyDown ).
- off( "keypress", this._doKeyPress ).
- off( "keyup", this._doKeyUp );
- } else if ( nodeName === "div" || nodeName === "span" ) {
- $target.removeClass( this.markerClassName ).empty();
- }
+ this.calendar = $( "<div>" )
+ .addClass( "ui-front ui-datepicker" )
+ .appendTo( this._appendTo() );
- if ( datepicker_instActive === inst ) {
- datepicker_instActive = null;
- }
- },
-
- /* Enable the date picker to a jQuery selection.
- * @param target element - the target input field or division or span
- */
- _enableDatepicker: function( target ) {
- var nodeName, inline,
- $target = $( target ),
- inst = $.data( target, "datepicker" );
-
- if ( !$target.hasClass( this.markerClassName ) ) {
- return;
- }
-
- nodeName = target.nodeName.toLowerCase();
- if ( nodeName === "input" ) {
- target.disabled = false;
- inst.trigger.filter( "button" ).
- each( function() { this.disabled = false; } ).end().
- filter( "img" ).css( { opacity: "1.0", cursor: "" } );
- } else if ( nodeName === "div" || nodeName === "span" ) {
- inline = $target.children( "." + this._inlineClass );
- inline.children().removeClass( "ui-state-disabled" );
- inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
- prop( "disabled", false );
- }
- this._disabledInputs = $.map( this._disabledInputs,
- function( value ) { return ( value === target ? null : value ); } ); // delete entry
- },
-
- /* Disable the date picker to a jQuery selection.
- * @param target element - the target input field or division or span
- */
- _disableDatepicker: function( target ) {
- var nodeName, inline,
- $target = $( target ),
- inst = $.data( target, "datepicker" );
-
- if ( !$target.hasClass( this.markerClassName ) ) {
- return;
- }
-
- nodeName = target.nodeName.toLowerCase();
- if ( nodeName === "input" ) {
- target.disabled = true;
- inst.trigger.filter( "button" ).
- each( function() { this.disabled = true; } ).end().
- filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
- } else if ( nodeName === "div" || nodeName === "span" ) {
- inline = $target.children( "." + this._inlineClass );
- inline.children().addClass( "ui-state-disabled" );
- inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
- prop( "disabled", true );
- }
- this._disabledInputs = $.map( this._disabledInputs,
- function( value ) { return ( value === target ? null : value ); } ); // delete entry
- this._disabledInputs[ this._disabledInputs.length ] = target;
- },
-
- /* Is the first field in a jQuery collection disabled as a datepicker?
- * @param target element - the target input field or division or span
- * @return boolean - true if disabled, false if enabled
- */
- _isDisabledDatepicker: function( target ) {
- if ( !target ) {
- return false;
- }
- for ( var i = 0; i < this._disabledInputs.length; i++ ) {
- if ( this._disabledInputs[ i ] === target ) {
- return true;
- }
- }
- return false;
- },
-
- /* Retrieve the instance data for the target control.
- * @param target element - the target input field or division or span
- * @return object - the associated instance data
- * @throws error if a jQuery problem getting data
- */
- _getInst: function( target ) {
- try {
- return $.data( target, "datepicker" );
- }
- catch ( err ) {
- throw "Missing instance data for this datepicker";
- }
- },
-
- /* Update or retrieve the settings for a date picker attached to an input field or division.
- * @param target element - the target input field or division or span
- * @param name object - the new settings to update or
- * string - the name of the setting to change or retrieve,
- * when retrieving also "all" for all instance settings or
- * "defaults" for all global defaults
- * @param value any - the new value for the setting
- * (omit if above is an object or to retrieve a value)
- */
- _optionDatepicker: function( target, name, value ) {
- var settings, date, minDate, maxDate,
- inst = this._getInst( target );
-
- if ( arguments.length === 2 && typeof name === "string" ) {
- return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
- ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
- this._get( inst, name ) ) : null ) );
- }
-
- settings = name || {};
- if ( typeof name === "string" ) {
- settings = {};
- settings[ name ] = value;
- }
-
- if ( inst ) {
- if ( this._curInst === inst ) {
- this._hideDatepicker();
- }
-
- date = this._getDateDatepicker( target, true );
- minDate = this._getMinMaxDate( inst, "min" );
- maxDate = this._getMinMaxDate( inst, "max" );
- datepicker_extendRemove( inst.settings, settings );
-
- // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
- if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
- inst.settings.minDate = this._formatDate( inst, minDate );
- }
- if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
- inst.settings.maxDate = this._formatDate( inst, maxDate );
- }
- if ( "disabled" in settings ) {
- if ( settings.disabled ) {
- this._disableDatepicker( target );
- } else {
- this._enableDatepicker( target );
+ // Initialize calendar widget
+ this.calendarInstance = this.calendar
+ .calendar( $.extend( {}, this.options, {
+ value: globalize.dateParser( this.options.dateFormat )( this.element.val() ),
+ select: function( event ) {
+ that.element.val( that.calendarInstance.value() );
+ that.close();
+ that._focusTrigger();
+ that._trigger( "select", event );
}
- }
- this._attachments( $( target ), inst );
- this._autoSize( inst );
- this._setDate( inst, date );
- this._updateAlternate( inst );
- this._updateDatepicker( inst );
- }
- },
+ } ) )
+ .calendar( "instance" );
- // Change method deprecated
- _changeDatepicker: function( target, name, value ) {
- this._optionDatepicker( target, name, value );
- },
+ this.calendarInstance.buttonClickContext = that.element[ 0 ];
- /* Redraw the date picker attached to an input field or division.
- * @param target element - the target input field or division or span
- */
- _refreshDatepicker: function( target ) {
- var inst = this._getInst( target );
- if ( inst ) {
- this._updateDatepicker( inst );
- }
- },
-
- /* Set the dates for a jQuery selection.
- * @param target element - the target input field or division or span
- * @param date Date - the new date
- */
- _setDateDatepicker: function( target, date ) {
- var inst = this._getInst( target );
- if ( inst ) {
- this._setDate( inst, date );
- this._updateDatepicker( inst );
- this._updateAlternate( inst );
- }
- },
+ this._setHiddenPicker();
- /* Get the date(s) for the first entry in a jQuery selection.
- * @param target element - the target input field or division or span
- * @param noDefault boolean - true if no default date is to be used
- * @return Date - the current date
- */
- _getDateDatepicker: function( target, noDefault ) {
- var inst = this._getInst( target );
- if ( inst && !inst.inline ) {
- this._setDateFromField( inst, noDefault );
- }
- return ( inst ? this._getDate( inst ) : null );
+ this.element.attr( {
+ "aria-haspopup": true,
+ "aria-owns": this.calendar.attr( "id" )
+ } );
},
- /* Handle keystrokes. */
- _doKeyDown: function( event ) {
- var onSelect, dateStr, sel,
- inst = $.datepicker._getInst( event.target ),
- handled = true,
- isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
-
- inst._keyEvent = true;
- if ( $.datepicker._datepickerShowing ) {
+ _inputEvents: {
+ keydown: function( event ) {
switch ( event.keyCode ) {
- case 9: $.datepicker._hideDatepicker();
- handled = false;
- break; // hide on tab out
- case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
- $.datepicker._currentClass + ")", inst.dpDiv );
- if ( sel[ 0 ] ) {
- $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
- }
-
- onSelect = $.datepicker._get( inst, "onSelect" );
- if ( onSelect ) {
- dateStr = $.datepicker._formatDate( inst );
-
- // Trigger custom callback
- onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
- } else {
- $.datepicker._hideDatepicker();
- }
-
- return false; // don't submit the form
- case 27: $.datepicker._hideDatepicker();
- break; // hide on escape
- case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
- -$.datepicker._get( inst, "stepBigMonths" ) :
- -$.datepicker._get( inst, "stepMonths" ) ), "M" );
- break; // previous month/year on page up/+ ctrl
- case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
- +$.datepicker._get( inst, "stepBigMonths" ) :
- +$.datepicker._get( inst, "stepMonths" ) ), "M" );
- break; // next month/year on page down/+ ctrl
- case 35: if ( event.ctrlKey || event.metaKey ) {
- $.datepicker._clearDate( event.target );
- }
- handled = event.ctrlKey || event.metaKey;
- break; // clear on ctrl or command +end
- case 36: if ( event.ctrlKey || event.metaKey ) {
- $.datepicker._gotoToday( event.target );
- }
- handled = event.ctrlKey || event.metaKey;
- break; // current on ctrl or command +home
- case 37: if ( event.ctrlKey || event.metaKey ) {
- $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
- }
- handled = event.ctrlKey || event.metaKey;
-
- // -1 day on ctrl or command +left
- if ( event.originalEvent.altKey ) {
- $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
- -$.datepicker._get( inst, "stepBigMonths" ) :
- -$.datepicker._get( inst, "stepMonths" ) ), "M" );
- }
-
- // next month/year on alt +left on Mac
- break;
- case 38: if ( event.ctrlKey || event.metaKey ) {
- $.datepicker._adjustDate( event.target, -7, "D" );
- }
- handled = event.ctrlKey || event.metaKey;
- break; // -1 week on ctrl or command +up
- case 39: if ( event.ctrlKey || event.metaKey ) {
- $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
- }
- handled = event.ctrlKey || event.metaKey;
-
- // +1 day on ctrl or command +right
- if ( event.originalEvent.altKey ) {
- $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
- +$.datepicker._get( inst, "stepBigMonths" ) :
- +$.datepicker._get( inst, "stepMonths" ) ), "M" );
- }
-
- // next month/year on alt +right
- break;
- case 40: if ( event.ctrlKey || event.metaKey ) {
- $.datepicker._adjustDate( event.target, +7, "D" );
- }
- handled = event.ctrlKey || event.metaKey;
- break; // +1 week on ctrl or command +down
- default: handled = false;
+ case $.ui.keyCode.TAB:
+
+ // Waiting for close() will make popup hide too late, which breaks tab key behavior
+ this.calendar.hide();
+ this.close( event );
+ break;
+ case $.ui.keyCode.ESCAPE:
+ if ( this.isOpen ) {
+ this.close( event );
+ }
+ break;
+ case $.ui.keyCode.DOWN:
+ case $.ui.keyCode.UP:
+ clearTimeout( this.closeTimer );
+ this._delay( function() {
+ this.open( event );
+ this.calendarInstance.grid.focus();
+ }, 1 );
+ break;
}
- } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
- $.datepicker._showDatepicker( this );
- } else {
- handled = false;
- }
-
- if ( handled ) {
- event.preventDefault();
- event.stopPropagation();
- }
- },
-
- /* Filter entered characters - based on date format. */
- _doKeyPress: function( event ) {
- var chars, chr,
- inst = $.datepicker._getInst( event.target );
-
- if ( $.datepicker._get( inst, "constrainInput" ) ) {
- chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
- chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
- return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
- }
- },
-
- /* Synchronise manual entry and field/alternate field. */
- _doKeyUp: function( event ) {
- var date,
- inst = $.datepicker._getInst( event.target );
-
- if ( inst.input.val() !== inst.lastVal ) {
- try {
- date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
- ( inst.input ? inst.input.val() : null ),
- $.datepicker._getFormatConfig( inst ) );
-
- if ( date ) { // only if valid
- $.datepicker._setDateFromField( inst );
- $.datepicker._updateAlternate( inst );
- $.datepicker._updateDatepicker( inst );
- }
+ },
+ keyup: function() {
+ if ( this.isValid() ) {
+ this.refresh();
}
- catch ( err ) {
+ },
+ mousedown: function( event ) {
+ if ( this.isOpen ) {
+ this.suppressExpandOnFocus = true;
+ this.close();
+ return;
}
- }
- return true;
- },
-
- /* Pop-up the date picker for a given input field.
- * If false returned from beforeShow event handler do not show.
- * @param input element - the input field attached to the date picker or
- * event - if triggered by focus
- */
- _showDatepicker: function( input ) {
- input = input.target || input;
- if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
- input = $( "input", input.parentNode )[ 0 ];
- }
-
- if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
- return;
- }
-
- var inst, beforeShow, beforeShowSettings, isFixed,
- offset, showAnim, duration;
-
- inst = $.datepicker._getInst( input );
- if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
- $.datepicker._curInst.dpDiv.stop( true, true );
- if ( inst && $.datepicker._datepickerShowing ) {
- $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
+ this.open( event );
+ clearTimeout( this.closeTimer );
+ },
+ focus: function( event ) {
+ if ( !this.suppressExpandOnFocus && !this.isOpen ) {
+ this._delay( function() {
+ this.open( event );
+ } );
+ }
+ this._delay( function() {
+ this.suppressExpandOnFocus = false;
+ }, 100 );
+ },
+ blur: function() {
+ this.suppressExpandOnFocus = false;
+ }
+ },
+
+ _calendarEvents: {
+ focusout: function( event ) {
+
+ // use a timer to allow click to clear it and letting that
+ // handle the closing instead of opening again
+ // also allows tabbing inside the calendar without it closing
+ this.closeTimer = this._delay( function() {
+ this.close( event );
+ }, 150 );
+ },
+ focusin: function() {
+ clearTimeout( this.closeTimer );
+ },
+ mouseup: function() {
+ clearTimeout( this.closeTimer );
+ },
+
+ // TODO on TAB (or shift TAB), make sure it ends up on something useful in DOM order
+ keyup: function( event ) {
+ if ( event.keyCode === $.ui.keyCode.ESCAPE && this.calendar.is( ":visible" ) ) {
+ this.close( event );
+ this._focusTrigger();
}
}
+ },
- beforeShow = $.datepicker._get( inst, "beforeShow" );
- beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
- if ( beforeShowSettings === false ) {
- return;
- }
- datepicker_extendRemove( inst.settings, beforeShowSettings );
-
- inst.lastVal = null;
- $.datepicker._lastInput = input;
- $.datepicker._setDateFromField( inst );
-
- if ( $.datepicker._inDialog ) { // hide cursor
- input.value = "";
- }
- if ( !$.datepicker._pos ) { // position below input
- $.datepicker._pos = $.datepicker._findPos( input );
- $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
- }
-
- isFixed = false;
- $( input ).parents().each( function() {
- isFixed |= $( this ).css( "position" ) === "fixed";
- return !isFixed;
- } );
-
- offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
- $.datepicker._pos = null;
-
- //to avoid flashes on Firefox
- inst.dpDiv.empty();
-
- // determine sizing offscreen
- inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
- $.datepicker._updateDatepicker( inst );
-
- // fix width for dynamic number of date pickers
- // and adjust position before showing
- offset = $.datepicker._checkOffset( inst, offset, isFixed );
- inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
- "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
- left: offset.left + "px", top: offset.top + "px" } );
-
- if ( !inst.inline ) {
- showAnim = $.datepicker._get( inst, "showAnim" );
- duration = $.datepicker._get( inst, "duration" );
- inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
- $.datepicker._datepickerShowing = true;
-
- if ( $.effects && $.effects.effect[ showAnim ] ) {
- inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
- } else {
- inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
+ _documentEvents: {
+ mousedown: function( event ) {
+ if ( !this.isOpen ) {
+ return;
}
- if ( $.datepicker._shouldFocusInput( inst ) ) {
- inst.input.trigger( "focus" );
+ if ( !$( event.target ).closest( this.element.add( this.calendar ) ).length ) {
+ this.close( event );
}
-
- $.datepicker._curInst = inst;
}
},
- /* Generate the date picker content. */
- _updateDatepicker: function( inst ) {
- this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
- datepicker_instActive = inst; // for delegate hover events
- inst.dpDiv.empty().append( this._generateHTML( inst ) );
- this._attachHandlers( inst );
-
- var origyearshtml,
- numMonths = this._getNumberOfMonths( inst ),
- cols = numMonths[ 1 ],
- width = 17,
- activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
+ _appendTo: function() {
+ var element = this.options.appendTo;
- if ( activeCell.length > 0 ) {
- datepicker_handleMouseover.apply( activeCell.get( 0 ) );
+ if ( element ) {
+ element = element.jquery || element.nodeType ?
+ $( element ) :
+ this.document.find( element ).eq( 0 );
}
- inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
- if ( cols > 1 ) {
- inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
+ if ( !element || !element[ 0 ] ) {
+ element = this.element.closest( ".ui-front, dialog" );
}
- inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
- "Class" ]( "ui-datepicker-multi" );
- inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
- "Class" ]( "ui-datepicker-rtl" );
- if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
- inst.input.trigger( "focus" );
+ if ( !element.length ) {
+ element = this.document[ 0 ].body;
}
- // Deffered render of the years select (to avoid flashes on Firefox)
- if ( inst.yearshtml ) {
- origyearshtml = inst.yearshtml;
- setTimeout( function() {
-
- //assure that inst.yearshtml didn't change.
- if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
- inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
- }
- origyearshtml = inst.yearshtml = null;
- }, 0 );
- }
+ return element;
},
- // #6694 - don't focus the input if it's already focused
- // this breaks the change event in IE
- // Support: IE and jQuery <1.9
- _shouldFocusInput: function( inst ) {
- return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
+ _focusTrigger: function() {
+ this.suppressExpandOnFocus = true;
+ this.element.focus();
},
- /* Check positioning to remain on screen. */
- _checkOffset: function( inst, offset, isFixed ) {
- var dpWidth = inst.dpDiv.outerWidth(),
- dpHeight = inst.dpDiv.outerHeight(),
- inputWidth = inst.input ? inst.input.outerWidth() : 0,
- inputHeight = inst.input ? inst.input.outerHeight() : 0,
- viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
- viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
-
- offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
- offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
- offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
-
- // Now check if datepicker is showing outside window viewport - move to a better place if so.
- offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
- Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
- offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
- Math.abs( dpHeight + inputHeight ) : 0 );
-
- return offset;
+ refresh: function() {
+ this.calendarInstance.option( "value", this._getParsedValue() );
},
- /* Find an object's position on the screen. */
- _findPos: function( obj ) {
- var position,
- inst = this._getInst( obj ),
- isRTL = this._get( inst, "isRTL" );
-
- while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
- obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
- }
-
- position = $( obj ).offset();
- return [ position.left, position.top ];
- },
-
- /* Hide the date picker from view.
- * @param input element - the input field attached to the date picker
- */
- _hideDatepicker: function( input ) {
- var showAnim, duration, postProcess, onClose,
- inst = this._curInst;
-
- if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
+ open: function( event ) {
+ if ( this.isOpen ) {
return;
}
-
- if ( this._datepickerShowing ) {
- showAnim = this._get( inst, "showAnim" );
- duration = this._get( inst, "duration" );
- postProcess = function() {
- $.datepicker._tidyDialog( inst );
- };
-
- // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
- if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
- inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
- } else {
- inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
- ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
- }
-
- if ( !showAnim ) {
- postProcess();
- }
- this._datepickerShowing = false;
-
- onClose = this._get( inst, "onClose" );
- if ( onClose ) {
- onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
- }
-
- this._lastInput = null;
- if ( this._inDialog ) {
- this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
- if ( $.blockUI ) {
- $.unblockUI();
- $( "body" ).append( this.dpDiv );
- }
- }
- this._inDialog = false;
- }
- },
-
- /* Tidy up after a dialog display. */
- _tidyDialog: function( inst ) {
- inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
- },
-
- /* Close date picker if clicked elsewhere. */
- _checkExternalClick: function( event ) {
- if ( !$.datepicker._curInst ) {
+ if ( this._trigger( "beforeOpen", event ) === false ) {
return;
}
- var $target = $( event.target ),
- inst = $.datepicker._getInst( $target[ 0 ] );
-
- if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
- $target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
- !$target.hasClass( $.datepicker.markerClassName ) &&
- !$target.closest( "." + $.datepicker._triggerClass ).length &&
- $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
- ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
- $.datepicker._hideDatepicker();
- }
- },
-
- /* Adjust one of the date sub-fields. */
- _adjustDate: function( id, offset, period ) {
- var target = $( id ),
- inst = this._getInst( target[ 0 ] );
+ this.calendarInstance.refresh();
+ this.calendar
+ .attr( {
+ "aria-hidden": false,
+ "aria-expanded": true
+ } )
+ .show()
+ .position( this._buildPosition() )
+ .hide();
+ this._show( this.calendar, this.options.show );
- if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
- return;
- }
- this._adjustInstDate( inst, offset +
- ( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
- period );
- this._updateDatepicker( inst );
- },
+ // Take trigger out of tab order to allow shift-tab to skip trigger
+ // TODO Does this really make sense? related bug: tab-shift moves focus to last element on page
+ this.element.attr( "tabindex", -1 );
+ this.isOpen = true;
- /* Action for current link. */
- _gotoToday: function( id ) {
- var date,
- target = $( id ),
- inst = this._getInst( target[ 0 ] );
-
- if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
- inst.selectedDay = inst.currentDay;
- inst.drawMonth = inst.selectedMonth = inst.currentMonth;
- inst.drawYear = inst.selectedYear = inst.currentYear;
- } else {
- date = new Date();
- inst.selectedDay = date.getDate();
- inst.drawMonth = inst.selectedMonth = date.getMonth();
- inst.drawYear = inst.selectedYear = date.getFullYear();
- }
- this._notifyChange( inst );
- this._adjustDate( target );
+ this._trigger( "open", event );
},
- /* Action for selecting a new month/year. */
- _selectMonthYear: function( id, select, period ) {
- var target = $( id ),
- inst = this._getInst( target[ 0 ] );
+ close: function( event ) {
+ this._setHiddenPicker();
+ this._hide( this.calendar, this.options.hide );
- inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
- inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
- parseInt( select.options[ select.selectedIndex ].value, 10 );
+ this.element.attr( "tabindex", 0 );
- this._notifyChange( inst );
- this._adjustDate( target );
+ this.isOpen = false;
+ this._trigger( "close", event );
},
- /* Action for selecting a day. */
- _selectDay: function( id, month, year, td ) {
- var inst,
- target = $( id );
-
- if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
- return;
- }
-
- inst = this._getInst( target[ 0 ] );
- inst.selectedDay = inst.currentDay = $( "a", td ).html();
- inst.selectedMonth = inst.currentMonth = month;
- inst.selectedYear = inst.currentYear = year;
- this._selectDate( id, this._formatDate( inst,
- inst.currentDay, inst.currentMonth, inst.currentYear ) );
+ _setHiddenPicker: function() {
+ this.calendar.attr( {
+ "aria-hidden": true,
+ "aria-expanded": false
+ } );
},
- /* Erase the input field and hide the date picker. */
- _clearDate: function( id ) {
- var target = $( id );
- this._selectDate( target, "" );
+ _buildPosition: function() {
+ return $.extend( { of: this.element }, this.options.position );
},
- /* Update the input field with the selected date. */
- _selectDate: function( id, dateStr ) {
- var onSelect,
- target = $( id ),
- inst = this._getInst( target[ 0 ] );
-
- dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
- if ( inst.input ) {
- inst.input.val( dateStr );
- }
- this._updateAlternate( inst );
-
- onSelect = this._get( inst, "onSelect" );
- if ( onSelect ) {
- onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback
- } else if ( inst.input ) {
- inst.input.trigger( "change" ); // fire the change event
- }
-
- if ( inst.inline ) {
- this._updateDatepicker( inst );
+ value: function( value ) {
+ if ( arguments.length ) {
+ this.valueAsDate( this.calendarInstance._parse( value ) );
} else {
- this._hideDatepicker();
- this._lastInput = inst.input[ 0 ];
- if ( typeof( inst.input[ 0 ] ) !== "object" ) {
- inst.input.trigger( "focus" ); // restore focus
- }
- this._lastInput = null;
+ return this._getParsedValue() ? this.element.val() : null;
}
},
- /* Update any alternate field to synchronise with the main field. */
- _updateAlternate: function( inst ) {
- var altFormat, date, dateStr,
- altField = this._get( inst, "altField" );
-
- if ( altField ) { // update alternate field too
- altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
- date = this._getDate( inst );
- dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
- $( altField ).val( dateStr );
- }
- },
-
- /* Set as beforeShowDay function to prevent selection of weekends.
- * @param date Date - the date to customise
- * @return [boolean, string] - is this date selectable?, what is its CSS class?
- */
- noWeekends: function( date ) {
- var day = date.getDay();
- return [ ( day > 0 && day < 6 ), "" ];
- },
-
- /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
- * @param date Date - the date to get the week for
- * @return number - the number of the week within the year that contains this date
- */
- iso8601Week: function( date ) {
- var time,
- checkDate = new Date( date.getTime() );
-
- // Find Thursday of this week starting on Monday
- checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
-
- time = checkDate.getTime();
- checkDate.setMonth( 0 ); // Compare with Jan 1
- checkDate.setDate( 1 );
- return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
- },
-
- /* Parse a string value into a date object.
- * See formatDate below for the possible formats.
- *
- * @param format string - the expected format of the date
- * @param value string - the date in the above format
- * @param settings Object - attributes include:
- * shortYearCutoff number - the cutoff year for determining the century (optional)
- * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
- * dayNames string[7] - names of the days from Sunday (optional)
- * monthNamesShort string[12] - abbreviated names of the months (optional)
- * monthNames string[12] - names of the months (optional)
- * @return Date - the extracted date value or null if value is blank
- */
- parseDate: function( format, value, settings ) {
- if ( format == null || value == null ) {
- throw "Invalid arguments";
- }
-
- value = ( typeof value === "object" ? value.toString() : value + "" );
- if ( value === "" ) {
- return null;
- }
-
- var iFormat, dim, extra,
- iValue = 0,
- shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
- shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
- new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
- dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
- dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
- monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
- monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
- year = -1,
- month = -1,
- day = -1,
- doy = -1,
- literal = false,
- date,
-
- // Check whether a format character is doubled
- lookAhead = function( match ) {
- var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
- if ( matches ) {
- iFormat++;
- }
- return matches;
- },
-
- // Extract a number from the string value
- getNumber = function( match ) {
- var isDoubled = lookAhead( match ),
- size = ( match === "@" ? 14 : ( match === "!" ? 20 :
- ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
- minSize = ( match === "y" ? size : 1 ),
- digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
- num = value.substring( iValue ).match( digits );
- if ( !num ) {
- throw "Missing number at position " + iValue;
- }
- iValue += num[ 0 ].length;
- return parseInt( num[ 0 ], 10 );
- },
-
- // Extract a name from the string value and convert to an index
- getName = function( match, shortNames, longNames ) {
- var index = -1,
- names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
- return [ [ k, v ] ];
- } ).sort( function( a, b ) {
- return -( a[ 1 ].length - b[ 1 ].length );
- } );
-
- $.each( names, function( i, pair ) {
- var name = pair[ 1 ];
- if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
- index = pair[ 0 ];
- iValue += name.length;
- return false;
- }
- } );
- if ( index !== -1 ) {
- return index + 1;
- } else {
- throw "Unknown name at position " + iValue;
- }
- },
-
- // Confirm that a literal character matches the string value
- checkLiteral = function() {
- if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
- throw "Unexpected literal at position " + iValue;
- }
- iValue++;
- };
-
- for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
- if ( literal ) {
- if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
- literal = false;
- } else {
- checkLiteral();
- }
- } else {
- switch ( format.charAt( iFormat ) ) {
- case "d":
- day = getNumber( "d" );
- break;
- case "D":
- getName( "D", dayNamesShort, dayNames );
- break;
- case "o":
- doy = getNumber( "o" );
- break;
- case "m":
- month = getNumber( "m" );
- break;
- case "M":
- month = getName( "M", monthNamesShort, monthNames );
- break;
- case "y":
- year = getNumber( "y" );
- break;
- case "@":
- date = new Date( getNumber( "@" ) );
- year = date.getFullYear();
- month = date.getMonth() + 1;
- day = date.getDate();
- break;
- case "!":
- date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
- year = date.getFullYear();
- month = date.getMonth() + 1;
- day = date.getDate();
- break;
- case "'":
- if ( lookAhead( "'" ) ) {
- checkLiteral();
- } else {
- literal = true;
- }
- break;
- default:
- checkLiteral();
- }
- }
- }
-
- if ( iValue < value.length ) {
- extra = value.substr( iValue );
- if ( !/^\s+/.test( extra ) ) {
- throw "Extra/unparsed characters found in date: " + extra;
+ valueAsDate: function( value ) {
+ if ( arguments.length ) {
+ if ( this.calendarInstance._isValid( value ) ) {
+ this.calendarInstance.valueAsDate( value );
+ this.element.val( this.calendarInstance._format( value ) );
}
+ } else {
+ return this._getParsedValue();
}
-
- if ( year === -1 ) {
- year = new Date().getFullYear();
- } else if ( year < 100 ) {
- year += new Date().getFullYear() - new Date().getFullYear() % 100 +
- ( year <= shortYearCutoff ? 0 : -100 );
- }
-
- if ( doy > -1 ) {
- month = 1;
- day = doy;
- do {
- dim = this._getDaysInMonth( year, month - 1 );
- if ( day <= dim ) {
- break;
- }
- month++;
- day -= dim;
- } while ( true );
- }
-
- date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
- if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
- throw "Invalid date"; // E.g. 31/02/00
- }
- return date;
- },
-
- /* Standard date formats. */
- ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
- COOKIE: "D, dd M yy",
- ISO_8601: "yy-mm-dd",
- RFC_822: "D, d M y",
- RFC_850: "DD, dd-M-y",
- RFC_1036: "D, d M y",
- RFC_1123: "D, d M yy",
- RFC_2822: "D, d M yy",
- RSS: "D, d M y", // RFC 822
- TICKS: "!",
- TIMESTAMP: "@",
- W3C: "yy-mm-dd", // ISO 8601
-
- _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
- Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
-
- /* Format a date object into a string value.
- * The format can be combinations of the following:
- * d - day of month (no leading zero)
- * dd - day of month (two digit)
- * o - day of year (no leading zeros)
- * oo - day of year (three digit)
- * D - day name short
- * DD - day name long
- * m - month of year (no leading zero)
- * mm - month of year (two digit)
- * M - month name short
- * MM - month name long
- * y - year (two digit)
- * yy - year (four digit)
- * @ - Unix timestamp (ms since 01/01/1970)
- * ! - Windows ticks (100ns since 01/01/0001)
- * "..." - literal text
- * '' - single quote
- *
- * @param format string - the desired format of the date
- * @param date Date - the date value to format
- * @param settings Object - attributes include:
- * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
- * dayNames string[7] - names of the days from Sunday (optional)
- * monthNamesShort string[12] - abbreviated names of the months (optional)
- * monthNames string[12] - names of the months (optional)
- * @return string - the date in the above format
- */
- formatDate: function( format, date, settings ) {
- if ( !date ) {
- return "";
- }
-
- var iFormat,
- dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
- dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
- monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
- monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
-
- // Check whether a format character is doubled
- lookAhead = function( match ) {
- var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
- if ( matches ) {
- iFormat++;
- }
- return matches;
- },
-
- // Format a number, with leading zero if necessary
- formatNumber = function( match, value, len ) {
- var num = "" + value;
- if ( lookAhead( match ) ) {
- while ( num.length < len ) {
- num = "0" + num;
- }
- }
- return num;
- },
-
- // Format a name, short or long as requested
- formatName = function( match, value, shortNames, longNames ) {
- return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
- },
- output = "",
- literal = false;
-
- if ( date ) {
- for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
- if ( literal ) {
- if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
- literal = false;
- } else {
- output += format.charAt( iFormat );
- }
- } else {
- switch ( format.charAt( iFormat ) ) {
- case "d":
- output += formatNumber( "d", date.getDate(), 2 );
- break;
- case "D":
- output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
- break;
- case "o":
- output += formatNumber( "o",
- Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
- break;
- case "m":
- output += formatNumber( "m", date.getMonth() + 1, 2 );
- break;
- case "M":
- output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
- break;
- case "y":
- output += ( lookAhead( "y" ) ? date.getFullYear() :
- ( date.getYear() % 100 < 10 ? "0" : "" ) + date.getYear() % 100 );
- break;
- case "@":
- output += date.getTime();
- break;
- case "!":
- output += date.getTime() * 10000 + this._ticksTo1970;
- break;
- case "'":
- if ( lookAhead( "'" ) ) {
- output += "'";
- } else {
- literal = true;
- }
- break;
- default:
- output += format.charAt( iFormat );
- }
- }
- }
- }
- return output;
- },
-
- /* Extract all possible characters from the date format. */
- _possibleChars: function( format ) {
- var iFormat,
- chars = "",
- literal = false,
-
- // Check whether a format character is doubled
- lookAhead = function( match ) {
- var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
- if ( matches ) {
- iFormat++;
- }
- return matches;
- };
-
- for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
- if ( literal ) {
- if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
- literal = false;
- } else {
- chars += format.charAt( iFormat );
- }
- } else {
- switch ( format.charAt( iFormat ) ) {
- case "d": case "m": case "y": case "@":
- chars += "0123456789";
- break;
- case "D": case "M":
- return null; // Accept anything
- case "'":
- if ( lookAhead( "'" ) ) {
- chars += "'";
- } else {
- literal = true;
- }
- break;
- default:
- chars += format.charAt( iFormat );
- }
- }
- }
- return chars;
- },
-
- /* Get a setting value, defaulting if necessary. */
- _get: function( inst, name ) {
- return inst.settings[ name ] !== undefined ?
- inst.settings[ name ] : this._defaults[ name ];
- },
-
- /* Parse existing date and initialise date picker. */
- _setDateFromField: function( inst, noDefault ) {
- if ( inst.input.val() === inst.lastVal ) {
- return;
- }
-
- var dateFormat = this._get( inst, "dateFormat" ),
- dates = inst.lastVal = inst.input ? inst.input.val() : null,
- defaultDate = this._getDefaultDate( inst ),
- date = defaultDate,
- settings = this._getFormatConfig( inst );
-
- try {
- date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
- } catch ( event ) {
- dates = ( noDefault ? "" : dates );
- }
- inst.selectedDay = date.getDate();
- inst.drawMonth = inst.selectedMonth = date.getMonth();
- inst.drawYear = inst.selectedYear = date.getFullYear();
- inst.currentDay = ( dates ? date.getDate() : 0 );
- inst.currentMonth = ( dates ? date.getMonth() : 0 );
- inst.currentYear = ( dates ? date.getFullYear() : 0 );
- this._adjustInstDate( inst );
- },
-
- /* Retrieve the default date shown on opening. */
- _getDefaultDate: function( inst ) {
- return this._restrictMinMax( inst,
- this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
- },
-
- /* A date may be specified as an exact value or a relative one. */
- _determineDate: function( inst, date, defaultDate ) {
- var offsetNumeric = function( offset ) {
- var date = new Date();
- date.setDate( date.getDate() + offset );
- return date;
- },
- offsetString = function( offset ) {
- try {
- return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
- offset, $.datepicker._getFormatConfig( inst ) );
- }
- catch ( e ) {
-
- // Ignore
- }
-
- var date = ( offset.toLowerCase().match( /^c/ ) ?
- $.datepicker._getDate( inst ) : null ) || new Date(),
- year = date.getFullYear(),
- month = date.getMonth(),
- day = date.getDate(),
- pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
- matches = pattern.exec( offset );
-
- while ( matches ) {
- switch ( matches[ 2 ] || "d" ) {
- case "d" : case "D" :
- day += parseInt( matches[ 1 ], 10 ); break;
- case "w" : case "W" :
- day += parseInt( matches[ 1 ], 10 ) * 7; break;
- case "m" : case "M" :
- month += parseInt( matches[ 1 ], 10 );
- day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
- break;
- case "y": case "Y" :
- year += parseInt( matches[ 1 ], 10 );
- day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
- break;
- }
- matches = pattern.exec( offset );
- }
- return new Date( year, month, day );
- },
- newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
- ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
-
- newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
- if ( newDate ) {
- newDate.setHours( 0 );
- newDate.setMinutes( 0 );
- newDate.setSeconds( 0 );
- newDate.setMilliseconds( 0 );
- }
- return this._daylightSavingAdjust( newDate );
},
- /* Handle switch to/from daylight saving.
- * Hours may be non-zero on daylight saving cut-over:
- * > 12 when midnight changeover, but then cannot generate
- * midnight datetime, so jump to 1AM, otherwise reset.
- * @param date (Date) the date to check
- * @return (Date) the corrected date
- */
- _daylightSavingAdjust: function( date ) {
- if ( !date ) {
- return null;
- }
- date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
- return date;
+ isValid: function() {
+ return this.calendarInstance._isValid( this._getParsedValue() );
},
- /* Set the date(s) directly. */
- _setDate: function( inst, date, noChange ) {
- var clear = !date,
- origMonth = inst.selectedMonth,
- origYear = inst.selectedYear,
- newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
-
- inst.selectedDay = inst.currentDay = newDate.getDate();
- inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
- inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
- if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
- this._notifyChange( inst );
- }
- this._adjustInstDate( inst );
- if ( inst.input ) {
- inst.input.val( clear ? "" : this._formatDate( inst ) );
- }
+ _destroy: function() {
+ this.calendarInstance.destroy();
+ this.calendar.remove();
+ this.element.removeAttr( "aria-haspopup aria-owns" );
},
- /* Retrieve the date(s) directly. */
- _getDate: function( inst ) {
- var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
- this._daylightSavingAdjust( new Date(
- inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
- return startDate;
+ widget: function() {
+ return this.calendar;
},
- /* Attach the onxxx handlers. These are declared statically so
- * they work with static code transformers like Caja.
- */
- _attachHandlers: function( inst ) {
- var stepMonths = this._get( inst, "stepMonths" ),
- id = "#" + inst.id.replace( /\\\\/g, "\\" );
- inst.dpDiv.find( "[data-handler]" ).map( function() {
- var handler = {
- prev: function() {
- $.datepicker._adjustDate( id, -stepMonths, "M" );
- },
- next: function() {
- $.datepicker._adjustDate( id, +stepMonths, "M" );
- },
- hide: function() {
- $.datepicker._hideDatepicker();
- },
- today: function() {
- $.datepicker._gotoToday( id );
- },
- selectDay: function() {
- $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
- return false;
- },
- selectMonth: function() {
- $.datepicker._selectMonthYear( id, this, "M" );
- return false;
- },
- selectYear: function() {
- $.datepicker._selectMonthYear( id, this, "Y" );
- return false;
- }
- };
- $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
- } );
+ _getParsedValue: function() {
+ return this.calendarInstance._parse( this.element.val() );
},
- /* Generate the HTML for the current state of the date picker. */
- _generateHTML: function( inst ) {
- var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
- controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
- monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
- selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
- cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
- printDate, dRow, tbody, daySettings, otherMonth, unselectable,
- tempDate = new Date(),
- today = this._daylightSavingAdjust(
- new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
- isRTL = this._get( inst, "isRTL" ),
- showButtonPanel = this._get( inst, "showButtonPanel" ),
- hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
- navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
- numMonths = this._getNumberOfMonths( inst ),
- showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
- stepMonths = this._get( inst, "stepMonths" ),
- isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
- currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
- new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
- minDate = this._getMinMaxDate( inst, "min" ),
- maxDate = this._getMinMaxDate( inst, "max" ),
- drawMonth = inst.drawMonth - showCurrentAtPos,
- drawYear = inst.drawYear;
+ _setOption: function( key, value ) {
+ this._super( key, value );
- if ( drawMonth < 0 ) {
- drawMonth += 12;
- drawYear--;
- }
- if ( maxDate ) {
- maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
- maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
- maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
- while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
- drawMonth--;
- if ( drawMonth < 0 ) {
- drawMonth = 11;
- drawYear--;
- }
- }
+ if ( $.inArray( key, this.calendarOptions ) !== -1 ) {
+ this.calendarInstance.option( key, value );
}
- inst.drawMonth = drawMonth;
- inst.drawYear = drawYear;
-
- prevText = this._get( inst, "prevText" );
- prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
- this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
- this._getFormatConfig( inst ) ) );
-
- prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
- "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
- " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
- ( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" ) );
-
- nextText = this._get( inst, "nextText" );
- nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
- this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
- this._getFormatConfig( inst ) ) );
-
- next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
- "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
- " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
- ( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" ) );
-
- currentText = this._get( inst, "currentText" );
- gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
- currentText = ( !navigationAsDateFormat ? currentText :
- this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
-
- controls = ( !inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
- this._get( inst, "closeText" ) + "</button>" : "" );
-
- buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
- ( this._isInRange( inst, gotoDate ) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
- ">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
-
- firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
- firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
-
- showWeek = this._get( inst, "showWeek" );
- dayNames = this._get( inst, "dayNames" );
- dayNamesMin = this._get( inst, "dayNamesMin" );
- monthNames = this._get( inst, "monthNames" );
- monthNamesShort = this._get( inst, "monthNamesShort" );
- beforeShowDay = this._get( inst, "beforeShowDay" );
- showOtherMonths = this._get( inst, "showOtherMonths" );
- selectOtherMonths = this._get( inst, "selectOtherMonths" );
- defaultDate = this._getDefaultDate( inst );
- html = "";
-
- for ( row = 0; row < numMonths[ 0 ]; row++ ) {
- group = "";
- this.maxRows = 4;
- for ( col = 0; col < numMonths[ 1 ]; col++ ) {
- selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
- cornerClass = " ui-corner-all";
- calender = "";
- if ( isMultiMonth ) {
- calender += "<div class='ui-datepicker-group";
- if ( numMonths[ 1 ] > 1 ) {
- switch ( col ) {
- case 0: calender += " ui-datepicker-group-first";
- cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
- case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
- cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
- default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
- }
- }
- calender += "'>";
- }
- calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
- ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
- ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
- this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
- row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
- "</div><table class='ui-datepicker-calendar'><thead>" +
- "<tr>";
- thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
- for ( dow = 0; dow < 7; dow++ ) { // days of the week
- day = ( dow + firstDay ) % 7;
- thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
- "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
- }
- calender += thead + "</tr></thead><tbody>";
- daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
- if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
- inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
- }
- leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
- curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
- numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
- this.maxRows = numRows;
- printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
- for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
- calender += "<tr>";
- tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
- this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
- for ( dow = 0; dow < 7; dow++ ) { // create date picker days
- daySettings = ( beforeShowDay ?
- beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
- otherMonth = ( printDate.getMonth() !== drawMonth );
- unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
- ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
- tbody += "<td class='" +
- ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
- ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
- ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
- ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
- // or defaultDate is current printedDate and defaultDate is selectedDate
- " " + this._dayOverClass : "" ) + // highlight selected day
- ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days
- ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
- ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
- ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
- ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
- ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
- ( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
- ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
- ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
- ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
- ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
- "' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
- printDate.setDate( printDate.getDate() + 1 );
- printDate = this._daylightSavingAdjust( printDate );
- }
- calender += tbody + "</tr>";
- }
- drawMonth++;
- if ( drawMonth > 11 ) {
- drawMonth = 0;
- drawYear++;
- }
- calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
- ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
- group += calender;
- }
- html += group;
- }
- html += buttonPanel;
- inst._keyEvent = false;
- return html;
- },
-
- /* Generate the month and year header. */
- _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
- secondary, monthNames, monthNamesShort ) {
-
- var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
- changeMonth = this._get( inst, "changeMonth" ),
- changeYear = this._get( inst, "changeYear" ),
- showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
- html = "<div class='ui-datepicker-title'>",
- monthHtml = "";
-
- // Month selection
- if ( secondary || !changeMonth ) {
- monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
- } else {
- inMinYear = ( minDate && minDate.getFullYear() === drawYear );
- inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
- monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
- for ( month = 0; month < 12; month++ ) {
- if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
- monthHtml += "<option value='" + month + "'" +
- ( month === drawMonth ? " selected='selected'" : "" ) +
- ">" + monthNamesShort[ month ] + "</option>";
- }
- }
- monthHtml += "</select>";
+ if ( key === "appendTo" ) {
+ this.calendar.appendTo( this._appendTo() );
}
- if ( !showMonthAfterYear ) {
- html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
+ if ( key === "locale" || key === "dateFormat" ) {
+ this.element.val( this.calendarInstance.value() );
}
- // Year selection
- if ( !inst.yearshtml ) {
- inst.yearshtml = "";
- if ( secondary || !changeYear ) {
- html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
- } else {
+ if ( key === "disabled" ) {
+ this.element
+ .prop( "disabled", value )
+ .toggleClass( "ui-state-disabled", value )
+ .attr( "aria-disabled", value );
- // determine range of years to display
- years = this._get( inst, "yearRange" ).split( ":" );
- thisYear = new Date().getFullYear();
- determineYear = function( value ) {
- var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
- ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
- parseInt( value, 10 ) ) );
- return ( isNaN( year ) ? thisYear : year );
- };
- year = determineYear( years[ 0 ] );
- endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
- year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
- endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
- inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
- for ( ; year <= endYear; year++ ) {
- inst.yearshtml += "<option value='" + year + "'" +
- ( year === drawYear ? " selected='selected'" : "" ) +
- ">" + year + "</option>";
- }
- inst.yearshtml += "</select>";
-
- html += inst.yearshtml;
- inst.yearshtml = null;
+ if ( value ) {
+ this.close();
}
}
- html += this._get( inst, "yearSuffix" );
- if ( showMonthAfterYear ) {
- html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
- }
- html += "</div>"; // Close datepicker_header
- return html;
- },
-
- /* Adjust one of the date sub-fields. */
- _adjustInstDate: function( inst, offset, period ) {
- var year = inst.drawYear + ( period === "Y" ? offset : 0 ),
- month = inst.drawMonth + ( period === "M" ? offset : 0 ),
- day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
- date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
-
- inst.selectedDay = date.getDate();
- inst.drawMonth = inst.selectedMonth = date.getMonth();
- inst.drawYear = inst.selectedYear = date.getFullYear();
- if ( period === "M" || period === "Y" ) {
- this._notifyChange( inst );
- }
- },
-
- /* Ensure a date is within any min/max bounds. */
- _restrictMinMax: function( inst, date ) {
- var minDate = this._getMinMaxDate( inst, "min" ),
- maxDate = this._getMinMaxDate( inst, "max" ),
- newDate = ( minDate && date < minDate ? minDate : date );
- return ( maxDate && newDate > maxDate ? maxDate : newDate );
- },
-
- /* Notify change of month/year. */
- _notifyChange: function( inst ) {
- var onChange = this._get( inst, "onChangeMonthYear" );
- if ( onChange ) {
- onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
- [ inst.selectedYear, inst.selectedMonth + 1, inst ] );
- }
- },
-
- /* Determine the number of months to show. */
- _getNumberOfMonths: function( inst ) {
- var numMonths = this._get( inst, "numberOfMonths" );
- return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
- },
-
- /* Determine the current maximum date - ensure no time components are set. */
- _getMinMaxDate: function( inst, minMax ) {
- return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
- },
-
- /* Find the number of days in a given month. */
- _getDaysInMonth: function( year, month ) {
- return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
- },
-
- /* Find the day of the week of the first of a month. */
- _getFirstDayOfMonth: function( year, month ) {
- return new Date( year, month, 1 ).getDay();
- },
-
- /* Determines if we should allow a "next/prev" month display change. */
- _canAdjustMonth: function( inst, offset, curYear, curMonth ) {
- var numMonths = this._getNumberOfMonths( inst ),
- date = this._daylightSavingAdjust( new Date( curYear,
- curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
-
- if ( offset < 0 ) {
- date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
- }
- return this._isInRange( inst, date );
- },
-
- /* Is the given date in the accepted range? */
- _isInRange: function( inst, date ) {
- var yearSplit, currentYear,
- minDate = this._getMinMaxDate( inst, "min" ),
- maxDate = this._getMinMaxDate( inst, "max" ),
- minYear = null,
- maxYear = null,
- years = this._get( inst, "yearRange" );
- if ( years ) {
- yearSplit = years.split( ":" );
- currentYear = new Date().getFullYear();
- minYear = parseInt( yearSplit[ 0 ], 10 );
- maxYear = parseInt( yearSplit[ 1 ], 10 );
- if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
- minYear += currentYear;
- }
- if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
- maxYear += currentYear;
- }
- }
-
- return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
- ( !maxDate || date.getTime() <= maxDate.getTime() ) &&
- ( !minYear || date.getFullYear() >= minYear ) &&
- ( !maxYear || date.getFullYear() <= maxYear ) );
- },
-
- /* Provide the configuration settings for formatting/parsing. */
- _getFormatConfig: function( inst ) {
- var shortYearCutoff = this._get( inst, "shortYearCutoff" );
- shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
- new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
- return { shortYearCutoff: shortYearCutoff,
- dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
- monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
- },
-
- /* Format the given date for display. */
- _formatDate: function( inst, day, month, year ) {
- if ( !day ) {
- inst.currentDay = inst.selectedDay;
- inst.currentMonth = inst.selectedMonth;
- inst.currentYear = inst.selectedYear;
+ if ( key === "position" ) {
+ this.calendar.position( this._buildPosition() );
}
- var date = ( day ? ( typeof day === "object" ? day :
- this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
- this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
- return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
}
} );
-/*
- * Bind hover events for datepicker elements.
- * Done via delegate so the binding only occurs once in the lifetime of the parent div.
- * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
- */
-function datepicker_bindHover( dpDiv ) {
- var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
- return dpDiv.on( "mouseout", selector, function() {
- $( this ).removeClass( "ui-state-hover" );
- if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
- $( this ).removeClass( "ui-datepicker-prev-hover" );
- }
- if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
- $( this ).removeClass( "ui-datepicker-next-hover" );
- }
- } )
- .on( "mouseover", selector, datepicker_handleMouseover );
-}
-
-function datepicker_handleMouseover() {
- if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
- $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
- $( this ).addClass( "ui-state-hover" );
- if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
- $( this ).addClass( "ui-datepicker-prev-hover" );
- }
- if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
- $( this ).addClass( "ui-datepicker-next-hover" );
- }
- }
-}
-
-/* jQuery extend now ignores nulls! */
-function datepicker_extendRemove( target, props ) {
- $.extend( target, props );
- for ( var name in props ) {
- if ( props[ name ] == null ) {
- target[ name ] = props[ name ];
- }
- }
- return target;
-}
-
-/* Invoke the datepicker functionality.
- @param options string - a command, optionally followed by additional parameters or
- Object - settings for attaching new datepicker functionality
- @return jQuery object */
-$.fn.datepicker = function( options ) {
-
- /* Verify an empty collection wasn't passed - Fixes #6976 */
- if ( !this.length ) {
- return this;
- }
-
- /* Initialise the date picker. */
- if ( !$.datepicker.initialized ) {
- $( document ).on( "mousedown", $.datepicker._checkExternalClick );
- $.datepicker.initialized = true;
- }
-
- /* Append datepicker main container to body if not exist. */
- if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
- $( "body" ).append( $.datepicker.dpDiv );
- }
-
- var otherArgs = Array.prototype.slice.call( arguments, 1 );
- if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
- return $.datepicker[ "_" + options + "Datepicker" ].
- apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
- }
- if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
- return $.datepicker[ "_" + options + "Datepicker" ].
- apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
- }
- return this.each( function() {
- typeof options === "string" ?
- $.datepicker[ "_" + options + "Datepicker" ].
- apply( $.datepicker, [ this ].concat( otherArgs ) ) :
- $.datepicker._attachDatepicker( this, options );
- } );
-};
-
-$.datepicker = new Datepicker(); // singleton instance
-$.datepicker.initialized = false;
-$.datepicker.uuid = new Date().getTime();
-$.datepicker.version = "@VERSION";
+$.each( $.ui.datepicker.prototype.calendarOptions, function( index, option ) {
+ $.ui.datepicker.prototype.options[ option ] = $.ui.calendar.prototype.options[ option ];
+} );
-return $.datepicker;
+return widget;
} ) );