bootstrap-datepicker 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. data/.gitignore +7 -0
  2. data/.hgignore +3 -0
  3. data/.hgtags +9 -0
  4. data/.travis.yml +4 -0
  5. data/CHANGELOG.md +89 -0
  6. data/CONTRIBUTING.md +40 -0
  7. data/Gemfile +4 -0
  8. data/Gruntfile.js +165 -0
  9. data/LICENSE +202 -0
  10. data/README.md +24 -0
  11. data/Rakefile +1 -0
  12. data/bootstrap-datepicker.gemspec +26 -0
  13. data/bower.json +9 -0
  14. data/build/build.less +67 -0
  15. data/build/build3.less +71 -0
  16. data/build/build_standalone.less +61 -0
  17. data/build/build_standalone3.less +63 -0
  18. data/composer.json +19 -0
  19. data/css/datepicker.css +509 -0
  20. data/css/datepicker3.css +790 -0
  21. data/docs/Makefile +153 -0
  22. data/docs/REAME.md +8 -0
  23. data/docs/_static/demo_head.png +0 -0
  24. data/docs/conf.py +248 -0
  25. data/docs/events.rst +48 -0
  26. data/docs/i18n.rst +28 -0
  27. data/docs/index.rst +122 -0
  28. data/docs/keyboard.rst +30 -0
  29. data/docs/make.bat +190 -0
  30. data/docs/markup.rst +50 -0
  31. data/docs/methods.rst +156 -0
  32. data/docs/options.rst +191 -0
  33. data/js/bootstrap-datepicker.js +1609 -0
  34. data/js/locales/bootstrap-datepicker.ar.js +15 -0
  35. data/js/locales/bootstrap-datepicker.bg.js +14 -0
  36. data/js/locales/bootstrap-datepicker.ca.js +14 -0
  37. data/js/locales/bootstrap-datepicker.cs.js +15 -0
  38. data/js/locales/bootstrap-datepicker.cy.js +14 -0
  39. data/js/locales/bootstrap-datepicker.da.js +15 -0
  40. data/js/locales/bootstrap-datepicker.de.js +17 -0
  41. data/js/locales/bootstrap-datepicker.el.js +13 -0
  42. data/js/locales/bootstrap-datepicker.es.js +14 -0
  43. data/js/locales/bootstrap-datepicker.et.js +18 -0
  44. data/js/locales/bootstrap-datepicker.fa.js +17 -0
  45. data/js/locales/bootstrap-datepicker.fi.js +16 -0
  46. data/js/locales/bootstrap-datepicker.fr.js +17 -0
  47. data/js/locales/bootstrap-datepicker.gl.js +11 -0
  48. data/js/locales/bootstrap-datepicker.he.js +15 -0
  49. data/js/locales/bootstrap-datepicker.hr.js +13 -0
  50. data/js/locales/bootstrap-datepicker.hu.js +16 -0
  51. data/js/locales/bootstrap-datepicker.id.js +15 -0
  52. data/js/locales/bootstrap-datepicker.is.js +14 -0
  53. data/js/locales/bootstrap-datepicker.it.js +16 -0
  54. data/js/locales/bootstrap-datepicker.ja.js +15 -0
  55. data/js/locales/bootstrap-datepicker.ka.js +17 -0
  56. data/js/locales/bootstrap-datepicker.kk.js +15 -0
  57. data/js/locales/bootstrap-datepicker.kr.js +13 -0
  58. data/js/locales/bootstrap-datepicker.lt.js +16 -0
  59. data/js/locales/bootstrap-datepicker.lv.js +16 -0
  60. data/js/locales/bootstrap-datepicker.mk.js +15 -0
  61. data/js/locales/bootstrap-datepicker.ms.js +14 -0
  62. data/js/locales/bootstrap-datepicker.nb.js +14 -0
  63. data/js/locales/bootstrap-datepicker.nl-BE.js +17 -0
  64. data/js/locales/bootstrap-datepicker.nl.js +14 -0
  65. data/js/locales/bootstrap-datepicker.no.js +16 -0
  66. data/js/locales/bootstrap-datepicker.pl.js +15 -0
  67. data/js/locales/bootstrap-datepicker.pt-BR.js +15 -0
  68. data/js/locales/bootstrap-datepicker.pt.js +16 -0
  69. data/js/locales/bootstrap-datepicker.ro.js +15 -0
  70. data/js/locales/bootstrap-datepicker.rs-latin.js +14 -0
  71. data/js/locales/bootstrap-datepicker.rs.js +14 -0
  72. data/js/locales/bootstrap-datepicker.ru.js +15 -0
  73. data/js/locales/bootstrap-datepicker.sk.js +15 -0
  74. data/js/locales/bootstrap-datepicker.sl.js +14 -0
  75. data/js/locales/bootstrap-datepicker.sq.js +15 -0
  76. data/js/locales/bootstrap-datepicker.sv.js +16 -0
  77. data/js/locales/bootstrap-datepicker.sw.js +15 -0
  78. data/js/locales/bootstrap-datepicker.th.js +14 -0
  79. data/js/locales/bootstrap-datepicker.tr.js +16 -0
  80. data/js/locales/bootstrap-datepicker.ua.js +15 -0
  81. data/js/locales/bootstrap-datepicker.uk.js +14 -0
  82. data/js/locales/bootstrap-datepicker.vi.js +16 -0
  83. data/js/locales/bootstrap-datepicker.zh-CN.js +16 -0
  84. data/js/locales/bootstrap-datepicker.zh-TW.js +17 -0
  85. data/less/datepicker.less +265 -0
  86. data/less/datepicker3.less +252 -0
  87. data/lib/bootstrap-datepicker.rb +11 -0
  88. data/lib/bootstrap-datepicker/version.rb +9 -0
  89. data/package.json +32 -0
  90. data/sass/build_standalone-sass.scss +70 -0
  91. data/sass/datepicker.scss +270 -0
  92. data/test/Readme.md +9 -0
  93. data/test/less_test.js +19 -0
  94. data/test/scss_test.js +19 -0
  95. data/test/support/less.patch +4 -0
  96. data/test/support/scss.patch +493 -0
  97. data/tests/README.md +55 -0
  98. data/tests/_coverage.html +26 -0
  99. data/tests/assets/coverage.js +48 -0
  100. data/tests/assets/jquery-1.7.1.min.js +4 -0
  101. data/tests/assets/mock.js +26 -0
  102. data/tests/assets/qunit-logging.js +29 -0
  103. data/tests/assets/qunit.css +235 -0
  104. data/tests/assets/qunit.js +1669 -0
  105. data/tests/assets/utils.js +21 -0
  106. data/tests/run-qunit.js +157 -0
  107. data/tests/suites/calendar-weeks.js +48 -0
  108. data/tests/suites/component.js +202 -0
  109. data/tests/suites/data-api.js +114 -0
  110. data/tests/suites/events.js +306 -0
  111. data/tests/suites/formats.js +235 -0
  112. data/tests/suites/inline.js +28 -0
  113. data/tests/suites/keyboard_navigation/2011.js +92 -0
  114. data/tests/suites/keyboard_navigation/2012.js +468 -0
  115. data/tests/suites/keyboard_navigation/all.js +26 -0
  116. data/tests/suites/methods.js +78 -0
  117. data/tests/suites/mouse_navigation/2011.js +66 -0
  118. data/tests/suites/mouse_navigation/2012.js +251 -0
  119. data/tests/suites/mouse_navigation/all.js +33 -0
  120. data/tests/suites/noconflict.js +20 -0
  121. data/tests/suites/options.js +648 -0
  122. data/tests/tests.html +50 -0
  123. metadata +240 -0
@@ -0,0 +1,28 @@
1
+ module('Inline', {
2
+ setup: function(){
3
+ this.component = $('<div data-date="12-02-2012"></div>')
4
+ .appendTo('#qunit-fixture')
5
+ .datepicker({format: "dd-mm-yyyy"});
6
+ this.dp = this.component.data('datepicker')
7
+ this.picker = this.dp.picker;
8
+ },
9
+ teardown: function(){
10
+ this.picker.remove();
11
+ }
12
+ });
13
+
14
+
15
+ test('Picker gets date/viewDate from data-date attr', function(){
16
+ datesEqual(this.dp.dates[0], UTCDate(2012, 1, 12));
17
+ datesEqual(this.dp.viewDate, UTCDate(2012, 1, 12));
18
+ });
19
+
20
+
21
+ test('Visible after init', function(){
22
+ ok(this.picker.is(':visible'));
23
+ });
24
+
25
+ test('update', function(){
26
+ this.dp.update('13-03-2012')
27
+ datesEqual(this.dp.dates[0], UTCDate(2012, 2, 13));
28
+ });
@@ -0,0 +1,92 @@
1
+ module('Keyboard Navigation 2011', {
2
+ setup: function(){
3
+ /*
4
+ Tests start with picker on March 31, 2011. Fun facts:
5
+
6
+ * March 1, 2011 was on a Tuesday
7
+ * March 31, 2011 was on a Thursday
8
+ */
9
+ this.input = $('<input type="text" value="31-03-2011">')
10
+ .appendTo('#qunit-fixture')
11
+ .datepicker({format: "dd-mm-yyyy"})
12
+ .focus(); // Activate for visibility checks
13
+ this.dp = this.input.data('datepicker')
14
+ this.picker = this.dp.picker;
15
+ },
16
+ teardown: function(){
17
+ this.picker.remove();
18
+ }
19
+ });
20
+
21
+ test('Regression: by week (up/down arrows); up from Mar 6, 2011 should go to Feb 27, 2011', function(){
22
+ var target;
23
+
24
+ this.input.val('06-03-2011').datepicker('update');
25
+
26
+ equal(this.dp.viewMode, 0);
27
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
28
+ equal(target.text(), 'March 2011', 'Title is "March 2011"');
29
+ datesEqual(this.dp.viewDate, UTCDate(2011, 2, 6));
30
+ datesEqual(this.dp.dates.get(-1), UTCDate(2011, 2, 6));
31
+ equal(this.dp.focusDate, null);
32
+
33
+ // Navigation: -1 week, up arrow key
34
+ this.input.trigger({
35
+ type: 'keydown',
36
+ keyCode: 38
37
+ });
38
+ datesEqual(this.dp.viewDate, UTCDate(2011, 1, 27));
39
+ datesEqual(this.dp.dates.get(-1), UTCDate(2011, 2, 6));
40
+ datesEqual(this.dp.focusDate, UTCDate(2011, 1, 27));
41
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
42
+ equal(target.text(), 'February 2011', 'Title is "February 2011"');
43
+ });
44
+
45
+ test('Regression: by day (left/right arrows); left from Mar 1, 2011 should go to Feb 28, 2011', function(){
46
+ var target;
47
+
48
+ this.input.val('01-03-2011').datepicker('update');
49
+
50
+ equal(this.dp.viewMode, 0);
51
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
52
+ equal(target.text(), 'March 2011', 'Title is "March 2011"');
53
+ datesEqual(this.dp.viewDate, UTCDate(2011, 2, 1));
54
+ datesEqual(this.dp.dates.get(-1), UTCDate(2011, 2, 1));
55
+ equal(this.dp.focusDate, null);
56
+
57
+ // Navigation: -1 day left arrow key
58
+ this.input.trigger({
59
+ type: 'keydown',
60
+ keyCode: 37
61
+ });
62
+ datesEqual(this.dp.viewDate, UTCDate(2011, 1, 28));
63
+ datesEqual(this.dp.dates.get(-1), UTCDate(2011, 2, 1));
64
+ datesEqual(this.dp.focusDate, UTCDate(2011, 1, 28));
65
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
66
+ equal(target.text(), 'February 2011', 'Title is "February 2011"');
67
+ });
68
+
69
+ test('Regression: by month (shift + left/right arrows); left from Mar 15, 2011 should go to Feb 15, 2011', function(){
70
+ var target;
71
+
72
+ this.input.val('15-03-2011').datepicker('update');
73
+
74
+ equal(this.dp.viewMode, 0);
75
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
76
+ equal(target.text(), 'March 2011', 'Title is "March 2011"');
77
+ datesEqual(this.dp.viewDate, UTCDate(2011, 2, 15));
78
+ datesEqual(this.dp.dates.get(-1), UTCDate(2011, 2, 15));
79
+ equal(this.dp.focusDate, null);
80
+
81
+ // Navigation: -1 month, shift + left arrow key
82
+ this.input.trigger({
83
+ type: 'keydown',
84
+ keyCode: 37,
85
+ shiftKey: true
86
+ });
87
+ datesEqual(this.dp.viewDate, UTCDate(2011, 1, 15));
88
+ datesEqual(this.dp.dates.get(-1), UTCDate(2011, 2, 15));
89
+ datesEqual(this.dp.focusDate, UTCDate(2011, 1, 15));
90
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
91
+ equal(target.text(), 'February 2011', 'Title is "February 2011"');
92
+ });
@@ -0,0 +1,468 @@
1
+ module('Keyboard Navigation 2012', {
2
+ setup: function(){
3
+ /*
4
+ Tests start with picker on March 31, 2012. Fun facts:
5
+
6
+ * February 1, 2012 was on a Wednesday
7
+ * February 29, 2012 was on a Wednesday
8
+ * March 1, 2012 was on a Thursday
9
+ * March 31, 2012 was on a Saturday
10
+ */
11
+ this.input = $('<input type="text" value="31-03-2012">')
12
+ .appendTo('#qunit-fixture')
13
+ .datepicker({format: "dd-mm-yyyy"})
14
+ .focus(); // Activate for visibility checks
15
+ this.dp = this.input.data('datepicker')
16
+ this.picker = this.dp.picker;
17
+ },
18
+ teardown: function(){
19
+ this.picker.remove();
20
+ }
21
+ });
22
+
23
+
24
+ test('by day (right/left arrows)', function(){
25
+ var target;
26
+
27
+ equal(this.dp.viewMode, 0);
28
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
29
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
30
+
31
+ // Navigation: -1 day, left arrow key
32
+ this.input.trigger({
33
+ type: 'keydown',
34
+ keyCode: 37
35
+ });
36
+ // view and focus updated on keyboard navigation, not selected
37
+ datesEqual(this.dp.viewDate, UTCDate(2012, 2, 30));
38
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
39
+ datesEqual(this.dp.focusDate, UTCDate(2012, 2, 30));
40
+ // Month not changed
41
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
42
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
43
+
44
+ // Navigation: +1 day, right arrow key
45
+ for (var i=0; i<2; i++)
46
+ this.input.trigger({
47
+ type: 'keydown',
48
+ keyCode: 39
49
+ });
50
+ datesEqual(this.dp.viewDate, UTCDate(2012, 3, 1));
51
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
52
+ datesEqual(this.dp.focusDate, UTCDate(2012, 3, 1));
53
+ // Month changed: April 1 (this is not a joke!)
54
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
55
+ equal(target.text(), 'April 2012', 'Title is "April 2012"');
56
+ });
57
+
58
+ test('by week (up/down arrows)', function(){
59
+ var target;
60
+
61
+ equal(this.dp.viewMode, 0);
62
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
63
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
64
+
65
+ // Navigation: -1 week, up arrow key
66
+ this.input.trigger({
67
+ type: 'keydown',
68
+ keyCode: 38
69
+ });
70
+ // view and focus updated on keyboard navigation, not selected
71
+ datesEqual(this.dp.viewDate, UTCDate(2012, 2, 24));
72
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
73
+ datesEqual(this.dp.focusDate, UTCDate(2012, 2, 24));
74
+ // Month not changed
75
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
76
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
77
+
78
+ // Navigation: +1 week, down arrow key
79
+ for (var i=0; i<2; i++)
80
+ this.input.trigger({
81
+ type: 'keydown',
82
+ keyCode: 40
83
+ });
84
+ datesEqual(this.dp.viewDate, UTCDate(2012, 3, 7));
85
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
86
+ datesEqual(this.dp.focusDate, UTCDate(2012, 3, 7));
87
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
88
+ equal(target.text(), 'April 2012', 'Title is "April 2012"');
89
+ });
90
+
91
+ test('by month, v1 (shift + left/right arrows)', function(){
92
+ var target;
93
+
94
+ equal(this.dp.viewMode, 0);
95
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
96
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
97
+
98
+ // Navigation: -1 month, shift + left arrow key
99
+ this.input.trigger({
100
+ type: 'keydown',
101
+ keyCode: 37,
102
+ shiftKey: true
103
+ });
104
+ // view and focus updated on keyboard navigation w/ graceful date ends, not selected
105
+ datesEqual(this.dp.viewDate, UTCDate(2012, 1, 29));
106
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
107
+ datesEqual(this.dp.focusDate, UTCDate(2012, 1, 29));
108
+ // Month not changed
109
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
110
+ equal(target.text(), 'February 2012', 'Title is "February 2012"');
111
+
112
+ // Navigation: +1 month, shift + right arrow key
113
+ for (var i=0; i<2; i++)
114
+ this.input.trigger({
115
+ type: 'keydown',
116
+ keyCode: 39,
117
+ shiftKey: true
118
+ });
119
+ datesEqual(this.dp.viewDate, UTCDate(2012, 3, 29));
120
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
121
+ datesEqual(this.dp.focusDate, UTCDate(2012, 3, 29));
122
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
123
+ equal(target.text(), 'April 2012', 'Title is "April 2012"');
124
+ });
125
+
126
+ test('by month, v2 (shift + up/down arrows)', function(){
127
+ var target;
128
+
129
+ equal(this.dp.viewMode, 0);
130
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
131
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
132
+
133
+ // Navigation: -1 month, shift + up arrow key
134
+ this.input.trigger({
135
+ type: 'keydown',
136
+ keyCode: 38,
137
+ shiftKey: true
138
+ });
139
+ // view and focus updated on keyboard navigation w/ graceful date ends, not selected
140
+ datesEqual(this.dp.viewDate, UTCDate(2012, 1, 29));
141
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
142
+ datesEqual(this.dp.focusDate, UTCDate(2012, 1, 29));
143
+ // Month not changed
144
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
145
+ equal(target.text(), 'February 2012', 'Title is "February 2012"');
146
+
147
+ // Navigation: +1 month, shift + down arrow key
148
+ for (var i=0; i<2; i++)
149
+ this.input.trigger({
150
+ type: 'keydown',
151
+ keyCode: 40,
152
+ shiftKey: true
153
+ });
154
+ datesEqual(this.dp.viewDate, UTCDate(2012, 3, 29));
155
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
156
+ datesEqual(this.dp.focusDate, UTCDate(2012, 3, 29));
157
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
158
+ equal(target.text(), 'April 2012', 'Title is "April 2012"');
159
+ });
160
+
161
+ test('by year, v1 (ctrl + left/right arrows)', function(){
162
+ var target;
163
+
164
+ equal(this.dp.viewMode, 0);
165
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
166
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
167
+
168
+ // Navigation: -1 year, ctrl + left arrow key
169
+ this.input.trigger({
170
+ type: 'keydown',
171
+ keyCode: 37,
172
+ ctrlKey: true
173
+ });
174
+ // view and focus updated on keyboard navigation, not selected
175
+ datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
176
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
177
+ datesEqual(this.dp.focusDate, UTCDate(2011, 2, 31));
178
+ // Month not changed
179
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
180
+ equal(target.text(), 'March 2011', 'Title is "March 2011"');
181
+
182
+ // Navigation: +1 year, ctrl + right arrow key
183
+ for (var i=0; i<2; i++)
184
+ this.input.trigger({
185
+ type: 'keydown',
186
+ keyCode: 39,
187
+ ctrlKey: true
188
+ });
189
+ datesEqual(this.dp.viewDate, UTCDate(2013, 2, 31));
190
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
191
+ datesEqual(this.dp.focusDate, UTCDate(2013, 2, 31));
192
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
193
+ equal(target.text(), 'March 2013', 'Title is "March 2013"');
194
+ });
195
+
196
+ test('by year, v2 (ctrl + up/down arrows)', function(){
197
+ var target;
198
+
199
+ equal(this.dp.viewMode, 0);
200
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
201
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
202
+
203
+ // Navigation: -1 year, ctrl + up arrow key
204
+ this.input.trigger({
205
+ type: 'keydown',
206
+ keyCode: 38,
207
+ ctrlKey: true
208
+ });
209
+ // view and focus updated on keyboard navigation, not selected
210
+ datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
211
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
212
+ datesEqual(this.dp.focusDate, UTCDate(2011, 2, 31));
213
+ // Month not changed
214
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
215
+ equal(target.text(), 'March 2011', 'Title is "March 2011"');
216
+
217
+ // Navigation: +1 year, ctrl + down arrow key
218
+ for (var i=0; i<2; i++)
219
+ this.input.trigger({
220
+ type: 'keydown',
221
+ keyCode: 40,
222
+ ctrlKey: true
223
+ });
224
+ datesEqual(this.dp.viewDate, UTCDate(2013, 2, 31));
225
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
226
+ datesEqual(this.dp.focusDate, UTCDate(2013, 2, 31));
227
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
228
+ equal(target.text(), 'March 2013', 'Title is "March 2013"');
229
+ });
230
+
231
+ test('by year, v3 (ctrl + shift + left/right arrows)', function(){
232
+ var target;
233
+
234
+ equal(this.dp.viewMode, 0);
235
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
236
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
237
+
238
+ // Navigation: -1 year, ctrl + left arrow key
239
+ this.input.trigger({
240
+ type: 'keydown',
241
+ keyCode: 37,
242
+ ctrlKey: true,
243
+ shiftKey: true
244
+ });
245
+ // view and focus updated on keyboard navigation, not selected
246
+ datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
247
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
248
+ datesEqual(this.dp.focusDate, UTCDate(2011, 2, 31));
249
+ // Month not changed
250
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
251
+ equal(target.text(), 'March 2011', 'Title is "March 2011"');
252
+
253
+ // Navigation: +1 year, ctrl + right arrow key
254
+ for (var i=0; i<2; i++)
255
+ this.input.trigger({
256
+ type: 'keydown',
257
+ keyCode: 39,
258
+ ctrlKey: true,
259
+ shiftKey: true
260
+ });
261
+ datesEqual(this.dp.viewDate, UTCDate(2013, 2, 31));
262
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
263
+ datesEqual(this.dp.focusDate, UTCDate(2013, 2, 31));
264
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
265
+ equal(target.text(), 'March 2013', 'Title is "March 2013"');
266
+ });
267
+
268
+ test('by year, v4 (ctrl + shift + up/down arrows)', function(){
269
+ var target;
270
+
271
+ equal(this.dp.viewMode, 0);
272
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
273
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
274
+
275
+ // Navigation: -1 year, ctrl + up arrow key
276
+ this.input.trigger({
277
+ type: 'keydown',
278
+ keyCode: 38,
279
+ ctrlKey: true,
280
+ shiftKey: true
281
+ });
282
+ // view and focus updated on keyboard navigation, not selected
283
+ datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
284
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
285
+ datesEqual(this.dp.focusDate, UTCDate(2011, 2, 31));
286
+ // Month not changed
287
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
288
+ equal(target.text(), 'March 2011', 'Title is "March 2011"');
289
+
290
+ // Navigation: +1 year, ctrl + down arrow key
291
+ for (var i=0; i<2; i++)
292
+ this.input.trigger({
293
+ type: 'keydown',
294
+ keyCode: 40,
295
+ ctrlKey: true,
296
+ shiftKey: true
297
+ });
298
+ datesEqual(this.dp.viewDate, UTCDate(2013, 2, 31));
299
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
300
+ datesEqual(this.dp.focusDate, UTCDate(2013, 2, 31));
301
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
302
+ equal(target.text(), 'March 2013', 'Title is "March 2013"');
303
+ });
304
+
305
+ test('by year, from leap day', function(){
306
+ var target;
307
+
308
+ equal(this.dp.viewMode, 0);
309
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
310
+
311
+ this.input.val('29-02-2012').datepicker('update');
312
+ datesEqual(this.dp.viewDate, UTCDate(2012, 1, 29));
313
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 1, 29));
314
+ equal(this.dp.focusDate, null);
315
+ equal(target.text(), 'February 2012', 'Title is "February 2012"');
316
+
317
+ // Navigation: -1 year
318
+ this.input.trigger({
319
+ type: 'keydown',
320
+ keyCode: 37,
321
+ ctrlKey: true
322
+ });
323
+ // view and focus updated on keyboard navigation w/ graceful month ends, not selected
324
+ datesEqual(this.dp.viewDate, UTCDate(2011, 1, 28));
325
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 1, 29));
326
+ datesEqual(this.dp.focusDate, UTCDate(2011, 1, 28));
327
+ // Month not changed
328
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
329
+ equal(target.text(), 'February 2011', 'Title is "February 2011"');
330
+
331
+ // Navigation: +1 year, back to leap year
332
+ this.input.trigger({
333
+ type: 'keydown',
334
+ keyCode: 39,
335
+ ctrlKey: true
336
+ });
337
+ // view and focus updated on keyboard navigation w/ graceful month ends, not selected
338
+ datesEqual(this.dp.viewDate, UTCDate(2012, 1, 28));
339
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 1, 29));
340
+ datesEqual(this.dp.focusDate, UTCDate(2012, 1, 28));
341
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
342
+ equal(target.text(), 'February 2012', 'Title is "February 2012"');
343
+
344
+ // Navigation: +1 year
345
+ this.input.trigger({
346
+ type: 'keydown',
347
+ keyCode: 39,
348
+ ctrlKey: true
349
+ });
350
+ // view and focus updated on keyboard navigation w/ graceful month ends, not selected
351
+ datesEqual(this.dp.viewDate, UTCDate(2013, 1, 28));
352
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 1, 29));
353
+ datesEqual(this.dp.focusDate, UTCDate(2013, 1, 28));
354
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
355
+ equal(target.text(), 'February 2013', 'Title is "February 2013"');
356
+ });
357
+
358
+ test('Selection (spacebar)', function(){
359
+ var target;
360
+
361
+ equal(this.dp.viewMode, 0);
362
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
363
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
364
+
365
+ // Navigation: -1 day, left arrow key
366
+ this.input.trigger({
367
+ type: 'keydown',
368
+ keyCode: 37
369
+ });
370
+ // view and focus updated on keyboard navigation, not selected
371
+ datesEqual(this.dp.viewDate, UTCDate(2012, 2, 30));
372
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
373
+ datesEqual(this.dp.focusDate, UTCDate(2012, 2, 30));
374
+ // Month not changed
375
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
376
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
377
+
378
+ // Selection: Enter
379
+ this.input.trigger({
380
+ type: 'keydown',
381
+ keyCode: 32
382
+ });
383
+ // view and selection updated, focus cleared
384
+ datesEqual(this.dp.viewDate, UTCDate(2012, 2, 30));
385
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 30));
386
+ equal(this.dp.focusDate, null);
387
+ // Month not changed
388
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
389
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
390
+
391
+ ok(this.picker.is(':visible'), 'Picker is not hidden');
392
+ });
393
+
394
+ test('Selection + hide (enter)', function(){
395
+ var target;
396
+
397
+ equal(this.dp.viewMode, 0);
398
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
399
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
400
+
401
+ // Navigation: -1 day, left arrow key
402
+ this.input.trigger({
403
+ type: 'keydown',
404
+ keyCode: 37
405
+ });
406
+ // view and focus updated on keyboard navigation, not selected
407
+ datesEqual(this.dp.viewDate, UTCDate(2012, 2, 30));
408
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
409
+ datesEqual(this.dp.focusDate, UTCDate(2012, 2, 30));
410
+ // Month not changed
411
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
412
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
413
+
414
+ // Selection: Enter
415
+ this.input.trigger({
416
+ type: 'keydown',
417
+ keyCode: 13
418
+ });
419
+ // view and selection updatedfocus cleared
420
+ datesEqual(this.dp.viewDate, UTCDate(2012, 2, 30));
421
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 30));
422
+ equal(this.dp.focusDate, null);
423
+ // Month not changed
424
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
425
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
426
+
427
+ ok(this.picker.is(':not(:visible)'), 'Picker is hidden');
428
+ });
429
+
430
+ test('Toggle hide/show (escape); navigation while hidden is suppressed', function(){
431
+ var target;
432
+
433
+ equal(this.dp.viewMode, 0);
434
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
435
+ equal(target.text(), 'March 2012', 'Title is "March 2012"');
436
+
437
+ ok(this.picker.is(':visible'), 'Picker is visible');
438
+
439
+ // Hide
440
+ this.input.trigger({
441
+ type: 'keydown',
442
+ keyCode: 27
443
+ });
444
+
445
+ ok(this.picker.is(':not(:visible)'), 'Picker is hidden');
446
+ datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
447
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
448
+
449
+ // left arrow key, *doesn't* navigate
450
+ this.input.trigger({
451
+ type: 'keydown',
452
+ keyCode: 37
453
+ });
454
+
455
+ datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
456
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
457
+
458
+ // Show
459
+ this.input.trigger({
460
+ type: 'keydown',
461
+ keyCode: 27
462
+ });
463
+
464
+ ok(this.picker.is(':visible'), 'Picker is visible');
465
+ datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
466
+ datesEqual(this.dp.dates.get(-1), UTCDate(2012, 2, 31));
467
+ });
468
+