bitsnote-assets 0.0.4 → 0.0.5

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 (26) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/daterangepicker/daterangepicker.js +1113 -0
  3. data/app/assets/stylesheets/daterangepicker/daterangepicker.css +284 -0
  4. data/lib/bitsnote-assets.rb +1 -24
  5. data/lib/bitsnote-assets/version.rb +1 -1
  6. metadata +4 -22
  7. data/app/assets/javascripts/pickadate/picker.date.js +0 -1349
  8. data/app/assets/javascripts/pickadate/picker.date.min.js +0 -5
  9. data/app/assets/javascripts/pickadate/picker.js +0 -1078
  10. data/app/assets/javascripts/pickadate/picker.min.js +0 -7
  11. data/app/assets/javascripts/pickadate/picker.time.js +0 -1014
  12. data/app/assets/javascripts/pickadate/picker.time.min.js +0 -5
  13. data/app/assets/stylesheets/pickadate/classic.css +0 -109
  14. data/app/assets/stylesheets/pickadate/classic.date.css +0 -301
  15. data/app/assets/stylesheets/pickadate/classic.date.min.css +0 -1
  16. data/app/assets/stylesheets/pickadate/classic.min.css +0 -4
  17. data/app/assets/stylesheets/pickadate/classic.time.css +0 -131
  18. data/app/assets/stylesheets/pickadate/classic.time.min.css +0 -1
  19. data/app/assets/stylesheets/pickadate/default.css +0 -175
  20. data/app/assets/stylesheets/pickadate/default.date.css +0 -301
  21. data/app/assets/stylesheets/pickadate/default.date.min.css +0 -1
  22. data/app/assets/stylesheets/pickadate/default.min.css +0 -4
  23. data/app/assets/stylesheets/pickadate/default.time.css +0 -125
  24. data/app/assets/stylesheets/pickadate/default.time.min.css +0 -1
  25. data/app/assets/stylesheets/pickadate/rtl.css +0 -29
  26. data/app/assets/stylesheets/pickadate/rtl.min.css +0 -3
@@ -0,0 +1,284 @@
1
+ /*!
2
+ * Stylesheet for the Date Range Picker, for use with Bootstrap 3.x
3
+ *
4
+ * Copyright 2013 Dan Grossman ( http://www.dangrossman.info )
5
+ * Licensed under the Apache License v2.0
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Built for http://www.improvely.com
9
+ */
10
+
11
+ .daterangepicker.dropdown-menu {
12
+ max-width: none;
13
+ z-index: 3000;
14
+ }
15
+
16
+ .daterangepicker.opensleft .ranges, .daterangepicker.opensleft .calendar {
17
+ float: left;
18
+ margin: 4px;
19
+ }
20
+
21
+ .daterangepicker.opensright .ranges, .daterangepicker.opensright .calendar {
22
+ float: right;
23
+ margin: 4px;
24
+ }
25
+
26
+ .daterangepicker .ranges {
27
+ width: 160px;
28
+ text-align: left;
29
+ }
30
+
31
+ .daterangepicker .ranges .range_inputs>div {
32
+ float: left;
33
+ }
34
+
35
+ .daterangepicker .ranges .range_inputs>div:nth-child(2) {
36
+ padding-left: 11px;
37
+ }
38
+
39
+ .daterangepicker .calendar {
40
+ display: none;
41
+ max-width: 270px;
42
+ }
43
+
44
+ .daterangepicker.show-calendar .calendar {
45
+ display: block;
46
+ }
47
+
48
+ .daterangepicker .calendar.single .calendar-date {
49
+ border: none;
50
+ }
51
+
52
+ .daterangepicker .calendar th, .daterangepicker .calendar td {
53
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
54
+ white-space: nowrap;
55
+ text-align: center;
56
+ min-width: 32px;
57
+ }
58
+
59
+ .daterangepicker .daterangepicker_start_input label,
60
+ .daterangepicker .daterangepicker_end_input label {
61
+ color: #333;
62
+ display: block;
63
+ font-size: 11px;
64
+ font-weight: normal;
65
+ height: 20px;
66
+ line-height: 20px;
67
+ margin-bottom: 2px;
68
+ text-shadow: #fff 1px 1px 0px;
69
+ text-transform: uppercase;
70
+ width: 74px;
71
+ }
72
+
73
+ .daterangepicker .ranges input {
74
+ font-size: 11px;
75
+ }
76
+
77
+ .daterangepicker .ranges .input-mini {
78
+ border: 1px solid #ccc;
79
+ border-radius: 4px;
80
+ color: #555;
81
+ display: block;
82
+ font-size: 11px;
83
+ height: 30px;
84
+ line-height: 30px;
85
+ vertical-align: middle;
86
+ margin: 0 0 10px 0;
87
+ padding: 0 6px;
88
+ width: 74px;
89
+ }
90
+
91
+ .daterangepicker .ranges ul {
92
+ list-style: none;
93
+ margin: 0;
94
+ padding: 0;
95
+ }
96
+
97
+ .daterangepicker .ranges li {
98
+ font-size: 13px;
99
+ background: #f5f5f5;
100
+ border: 1px solid #f5f5f5;
101
+ color: #08c;
102
+ padding: 3px 12px;
103
+ margin-bottom: 8px;
104
+ -webkit-border-radius: 5px;
105
+ -moz-border-radius: 5px;
106
+ border-radius: 5px;
107
+ cursor: pointer;
108
+ }
109
+
110
+ .daterangepicker .ranges li.active, .daterangepicker .ranges li:hover {
111
+ background: #08c;
112
+ border: 1px solid #08c;
113
+ color: #fff;
114
+ }
115
+
116
+ .daterangepicker .calendar-date {
117
+ border: 1px solid #ddd;
118
+ padding: 4px;
119
+ border-radius: 4px;
120
+ background: #fff;
121
+ }
122
+
123
+ .daterangepicker .calendar-time {
124
+ text-align: center;
125
+ margin: 8px auto 0 auto;
126
+ line-height: 30px;
127
+ }
128
+
129
+ .daterangepicker {
130
+ position: absolute;
131
+ background: #fff;
132
+ top: 100px;
133
+ left: 20px;
134
+ padding: 4px;
135
+ margin-top: 1px;
136
+ -webkit-border-radius: 4px;
137
+ -moz-border-radius: 4px;
138
+ border-radius: 4px;
139
+ }
140
+
141
+ .daterangepicker.opensleft:before {
142
+ position: absolute;
143
+ top: -7px;
144
+ right: 9px;
145
+ display: inline-block;
146
+ border-right: 7px solid transparent;
147
+ border-bottom: 7px solid #ccc;
148
+ border-left: 7px solid transparent;
149
+ border-bottom-color: rgba(0, 0, 0, 0.2);
150
+ content: '';
151
+ }
152
+
153
+ .daterangepicker.opensleft:after {
154
+ position: absolute;
155
+ top: -6px;
156
+ right: 10px;
157
+ display: inline-block;
158
+ border-right: 6px solid transparent;
159
+ border-bottom: 6px solid #fff;
160
+ border-left: 6px solid transparent;
161
+ content: '';
162
+ }
163
+
164
+ .daterangepicker.opensright:before {
165
+ position: absolute;
166
+ top: -7px;
167
+ left: 9px;
168
+ display: inline-block;
169
+ border-right: 7px solid transparent;
170
+ border-bottom: 7px solid #ccc;
171
+ border-left: 7px solid transparent;
172
+ border-bottom-color: rgba(0, 0, 0, 0.2);
173
+ content: '';
174
+ }
175
+
176
+ .daterangepicker.opensright:after {
177
+ position: absolute;
178
+ top: -6px;
179
+ left: 10px;
180
+ display: inline-block;
181
+ border-right: 6px solid transparent;
182
+ border-bottom: 6px solid #fff;
183
+ border-left: 6px solid transparent;
184
+ content: '';
185
+ }
186
+
187
+ .daterangepicker table {
188
+ width: 100%;
189
+ margin: 0;
190
+ }
191
+
192
+ .daterangepicker td, .daterangepicker th {
193
+ text-align: center;
194
+ width: 20px;
195
+ height: 20px;
196
+ -webkit-border-radius: 4px;
197
+ -moz-border-radius: 4px;
198
+ border-radius: 4px;
199
+ cursor: pointer;
200
+ white-space: nowrap;
201
+ }
202
+
203
+ .daterangepicker td.off {
204
+ color: #999;
205
+ }
206
+
207
+ .daterangepicker td.disabled {
208
+ color: #999;
209
+ }
210
+
211
+ .daterangepicker td.available:hover, .daterangepicker th.available:hover {
212
+ background: #eee;
213
+ }
214
+
215
+ .daterangepicker td.in-range {
216
+ background: #ebf4f8;
217
+ -webkit-border-radius: 0;
218
+ -moz-border-radius: 0;
219
+ border-radius: 0;
220
+ }
221
+
222
+ .daterangepicker td.available + td.start-date {
223
+ -webkit-border-radius: 4px 0 0 4px;
224
+ -moz-border-radius: 4px 0 0 4px;
225
+ border-radius: 4px 0 0 4px;
226
+ }
227
+
228
+ .daterangepicker td.in-range + td.end-date{
229
+ -webkit-border-radius: 0 4px 4px 0;
230
+ -moz-border-radius: 0 4px 4px 0;
231
+ border-radius: 0 4px 4px 0;
232
+ }
233
+
234
+ .daterangepicker td.start-date.end-date{
235
+ -webkit-border-radius: 4px !important;
236
+ -moz-border-radius: 4px !important;
237
+ border-radius: 4px !important;
238
+ }
239
+
240
+ .daterangepicker td.active, .daterangepicker td.active:hover {
241
+ background-color: #357ebd;
242
+ border-color: #3071a9;
243
+ color: #fff;
244
+ }
245
+
246
+ .daterangepicker td.week, .daterangepicker th.week {
247
+ font-size: 80%;
248
+ color: #ccc;
249
+ }
250
+
251
+ .daterangepicker select.monthselect, .daterangepicker select.yearselect {
252
+ font-size: 12px;
253
+ padding: 1px;
254
+ height: auto;
255
+ margin: 0;
256
+ cursor: default;
257
+ }
258
+
259
+ .daterangepicker select.monthselect {
260
+ margin-right: 2%;
261
+ width: 56%;
262
+ }
263
+
264
+ .daterangepicker select.yearselect {
265
+ width: 40%;
266
+ }
267
+
268
+ .daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.ampmselect {
269
+ width: 50px;
270
+ margin-bottom: 0;
271
+ }
272
+
273
+ .daterangepicker_start_input {
274
+ float: left;
275
+ }
276
+
277
+ .daterangepicker_end_input {
278
+ float: left;
279
+ padding-left: 11px
280
+ }
281
+
282
+ .daterangepicker th.month {
283
+ width: auto;
284
+ }
@@ -63,15 +63,6 @@ module BitsnoteAssets
63
63
  :spin_js => {
64
64
  :default => "#{CDNJS}/spin.js/#{SPIN_VERSION}/spin.min.js"
65
65
  },
66
- :pickadate_js => {
67
- :default => "#{CDNJS}/pickadate.js/#{PICKADATE_VERSION}/compressed/picker.js"
68
- },
69
- :pickadate_date_js => {
70
- :default => "#{CDNJS}/pickadate.js/#{PICKADATE_VERSION}/compressed/picker.date.js"
71
- },
72
- :pickadate_time_js => {
73
- :default => "#{CDNJS}/pickadate.js/#{PICKADATE_VERSION}/compressed/picker.time.js"
74
- },
75
66
  :codemirror_js => {
76
67
  :default => "#{CDNJS}/codemirror/#{CODEMIRROR_VERSION}/codemirror.min.js"
77
68
  },
@@ -183,20 +174,6 @@ module BitsnoteAssets
183
174
  end
184
175
  end
185
176
 
186
- def pickadate_js_include_tag(name, options = {})
187
- js_include_tag(name, 'pickadate/picker', :pickadate_js_url, options) do |asset|
188
- "window.Picker"
189
- end
190
- end
191
-
192
- def pickadate_date_js_include_tag(name, options = {})
193
- js_include_tag(name, 'pickadate/picker.date', :pickadate_date_js_url, options)
194
- end
195
-
196
- def pickadate_time_js_include_tag(name, options = {})
197
- js_include_tag(name, 'pickadate/picker.time', :pickadate_time_js_url, options)
198
- end
199
-
200
177
  def codemirror_js_include_tag(name, options = {})
201
178
  js_include_tag(name, 'codemirror', :codemirror_js_url, options) do |asset|
202
179
  "window.CodeMirror"
@@ -204,7 +181,7 @@ module BitsnoteAssets
204
181
  end
205
182
 
206
183
  def codemirror_markdown_js_include_tag(name, options = {})
207
- js_include_tag(name, 'codemirror/modes/markdown', :codemirror_js_url, options) do
184
+ js_include_tag(name, 'codemirror/modes/markdown', :codemirror_markdown_js_url, options) do
208
185
  "window.CodeMirror.modes.markdown"
209
186
  end
210
187
  end
@@ -1,3 +1,3 @@
1
1
  module BitsnoteAssets
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitsnote-assets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yen-Ju Chen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-01 00:00:00.000000000 Z
11
+ date: 2014-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -104,6 +104,7 @@ files:
104
104
  - app/assets/javascripts/angular/angular.min.js
105
105
  - app/assets/javascripts/bootstrap/bootstrap.js
106
106
  - app/assets/javascripts/bootstrap/bootstrap.min.js
107
+ - app/assets/javascripts/daterangepicker/daterangepicker.js
107
108
  - app/assets/javascripts/fullcalendar/fullcalendar.js
108
109
  - app/assets/javascripts/fullcalendar/fullcalendar.min.js
109
110
  - app/assets/javascripts/ionic/ionic-angular.js
@@ -118,12 +119,6 @@ files:
118
119
  - app/assets/javascripts/moment/moment-with-locales.min.js
119
120
  - app/assets/javascripts/moment/moment.js
120
121
  - app/assets/javascripts/moment/moment.min.js
121
- - app/assets/javascripts/pickadate/picker.date.js
122
- - app/assets/javascripts/pickadate/picker.date.min.js
123
- - app/assets/javascripts/pickadate/picker.js
124
- - app/assets/javascripts/pickadate/picker.min.js
125
- - app/assets/javascripts/pickadate/picker.time.js
126
- - app/assets/javascripts/pickadate/picker.time.min.js
127
122
  - app/assets/javascripts/spin/spin.js
128
123
  - app/assets/javascripts/spin/spin.min.js
129
124
  - app/assets/javascripts/summernote/summernote.js
@@ -133,25 +128,12 @@ files:
133
128
  - app/assets/stylesheets/bootstrap/bootstrap-theme.min.css
134
129
  - app/assets/stylesheets/bootstrap/bootstrap.css.erb
135
130
  - app/assets/stylesheets/bootstrap/bootstrap.min.css.erb
131
+ - app/assets/stylesheets/daterangepicker/daterangepicker.css
136
132
  - app/assets/stylesheets/fullcalendar/fullcalendar.css
137
133
  - app/assets/stylesheets/fullcalendar/fullcalendar.min.css
138
134
  - app/assets/stylesheets/fullcalendar/fullcalendar.print.css
139
135
  - app/assets/stylesheets/ionic/ionic.css.erb
140
136
  - app/assets/stylesheets/ionic/ionic.min.css.erb
141
- - app/assets/stylesheets/pickadate/classic.css
142
- - app/assets/stylesheets/pickadate/classic.date.css
143
- - app/assets/stylesheets/pickadate/classic.date.min.css
144
- - app/assets/stylesheets/pickadate/classic.min.css
145
- - app/assets/stylesheets/pickadate/classic.time.css
146
- - app/assets/stylesheets/pickadate/classic.time.min.css
147
- - app/assets/stylesheets/pickadate/default.css
148
- - app/assets/stylesheets/pickadate/default.date.css
149
- - app/assets/stylesheets/pickadate/default.date.min.css
150
- - app/assets/stylesheets/pickadate/default.min.css
151
- - app/assets/stylesheets/pickadate/default.time.css
152
- - app/assets/stylesheets/pickadate/default.time.min.css
153
- - app/assets/stylesheets/pickadate/rtl.css
154
- - app/assets/stylesheets/pickadate/rtl.min.css
155
137
  - app/assets/stylesheets/summernote/summernote-bs3.css
156
138
  - app/assets/stylesheets/summernote/summernote.css
157
139
  - lib/bitsnote-assets.rb
@@ -1,1349 +0,0 @@
1
-
2
- /*!
3
- * Date picker for pickadate.js v3.5.3
4
- * http://amsul.github.io/pickadate.js/date.htm
5
- */
6
-
7
- (function ( factory ) {
8
-
9
- // AMD.
10
- if ( typeof define == 'function' && define.amd )
11
- define( ['picker','jquery'], factory )
12
-
13
- // Node.js/browserify.
14
- else if ( typeof exports == 'object' )
15
- module.exports = factory( require('./picker.js'), require('jquery') )
16
-
17
- // Browser globals.
18
- else factory( Picker, jQuery )
19
-
20
- }(function( Picker, $ ) {
21
-
22
-
23
- /**
24
- * Globals and constants
25
- */
26
- var DAYS_IN_WEEK = 7,
27
- WEEKS_IN_CALENDAR = 6,
28
- _ = Picker._
29
-
30
-
31
-
32
- /**
33
- * The date picker constructor
34
- */
35
- function DatePicker( picker, settings ) {
36
-
37
- var calendar = this,
38
- element = picker.$node[ 0 ],
39
- elementValue = element.value,
40
- elementDataValue = picker.$node.data( 'value' ),
41
- valueString = elementDataValue || elementValue,
42
- formatString = elementDataValue ? settings.formatSubmit : settings.format,
43
- isRTL = function() {
44
-
45
- return element.currentStyle ?
46
-
47
- // For IE.
48
- element.currentStyle.direction == 'rtl' :
49
-
50
- // For normal browsers.
51
- getComputedStyle( picker.$root[0] ).direction == 'rtl'
52
- }
53
-
54
- calendar.settings = settings
55
- calendar.$node = picker.$node
56
-
57
- // The queue of methods that will be used to build item objects.
58
- calendar.queue = {
59
- min: 'measure create',
60
- max: 'measure create',
61
- now: 'now create',
62
- select: 'parse create validate',
63
- highlight: 'parse navigate create validate',
64
- view: 'parse create validate viewset',
65
- disable: 'deactivate',
66
- enable: 'activate'
67
- }
68
-
69
- // The component's item object.
70
- calendar.item = {}
71
-
72
- calendar.item.clear = null
73
- calendar.item.disable = ( settings.disable || [] ).slice( 0 )
74
- calendar.item.enable = -(function( collectionDisabled ) {
75
- return collectionDisabled[ 0 ] === true ? collectionDisabled.shift() : -1
76
- })( calendar.item.disable )
77
-
78
- calendar.
79
- set( 'min', settings.min ).
80
- set( 'max', settings.max ).
81
- set( 'now' )
82
-
83
- // When there’s a value, set the `select`, which in turn
84
- // also sets the `highlight` and `view`.
85
- if ( valueString ) {
86
- calendar.set( 'select', valueString, { format: formatString })
87
- }
88
-
89
- // If there’s no value, default to highlighting “today”.
90
- else {
91
- calendar.
92
- set( 'select', null ).
93
- set( 'highlight', calendar.item.now )
94
- }
95
-
96
-
97
- // The keycode to movement mapping.
98
- calendar.key = {
99
- 40: 7, // Down
100
- 38: -7, // Up
101
- 39: function() { return isRTL() ? -1 : 1 }, // Right
102
- 37: function() { return isRTL() ? 1 : -1 }, // Left
103
- go: function( timeChange ) {
104
- var highlightedObject = calendar.item.highlight,
105
- targetDate = new Date( highlightedObject.year, highlightedObject.month, highlightedObject.date + timeChange )
106
- calendar.set(
107
- 'highlight',
108
- [ targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate() ],
109
- { interval: timeChange }
110
- )
111
- this.render()
112
- }
113
- }
114
-
115
-
116
- // Bind some picker events.
117
- picker.
118
- on( 'render', function() {
119
- picker.$root.find( '.' + settings.klass.selectMonth ).on( 'change', function() {
120
- var value = this.value
121
- if ( value ) {
122
- picker.set( 'highlight', [ picker.get( 'view' ).year, value, picker.get( 'highlight' ).date ] )
123
- picker.$root.find( '.' + settings.klass.selectMonth ).trigger( 'focus' )
124
- }
125
- })
126
- picker.$root.find( '.' + settings.klass.selectYear ).on( 'change', function() {
127
- var value = this.value
128
- if ( value ) {
129
- picker.set( 'highlight', [ value, picker.get( 'view' ).month, picker.get( 'highlight' ).date ] )
130
- picker.$root.find( '.' + settings.klass.selectYear ).trigger( 'focus' )
131
- }
132
- })
133
- }, 1 ).
134
- on( 'open', function() {
135
- var includeToday = ''
136
- if ( calendar.disabled( calendar.get('now') ) ) {
137
- includeToday = ':not(.' + settings.klass.buttonToday + ')'
138
- }
139
- picker.$root.find( 'button' + includeToday + ', select' ).attr( 'disabled', false )
140
- }, 1 ).
141
- on( 'close', function() {
142
- picker.$root.find( 'button, select' ).attr( 'disabled', true )
143
- }, 1 )
144
-
145
- } //DatePicker
146
-
147
-
148
- /**
149
- * Set a datepicker item object.
150
- */
151
- DatePicker.prototype.set = function( type, value, options ) {
152
-
153
- var calendar = this,
154
- calendarItem = calendar.item
155
-
156
- // If the value is `null` just set it immediately.
157
- if ( value === null ) {
158
- if ( type == 'clear' ) type = 'select'
159
- calendarItem[ type ] = value
160
- return calendar
161
- }
162
-
163
- // Otherwise go through the queue of methods, and invoke the functions.
164
- // Update this as the time unit, and set the final value as this item.
165
- // * In the case of `enable`, keep the queue but set `disable` instead.
166
- // And in the case of `flip`, keep the queue but set `enable` instead.
167
- calendarItem[ ( type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type ) ] = calendar.queue[ type ].split( ' ' ).map( function( method ) {
168
- value = calendar[ method ]( type, value, options )
169
- return value
170
- }).pop()
171
-
172
- // Check if we need to cascade through more updates.
173
- if ( type == 'select' ) {
174
- calendar.set( 'highlight', calendarItem.select, options )
175
- }
176
- else if ( type == 'highlight' ) {
177
- calendar.set( 'view', calendarItem.highlight, options )
178
- }
179
- else if ( type.match( /^(flip|min|max|disable|enable)$/ ) ) {
180
- if ( calendarItem.select && calendar.disabled( calendarItem.select ) ) {
181
- calendar.set( 'select', calendarItem.select, options )
182
- }
183
- if ( calendarItem.highlight && calendar.disabled( calendarItem.highlight ) ) {
184
- calendar.set( 'highlight', calendarItem.highlight, options )
185
- }
186
- }
187
-
188
- return calendar
189
- } //DatePicker.prototype.set
190
-
191
-
192
- /**
193
- * Get a datepicker item object.
194
- */
195
- DatePicker.prototype.get = function( type ) {
196
- return this.item[ type ]
197
- } //DatePicker.prototype.get
198
-
199
-
200
- /**
201
- * Create a picker date object.
202
- */
203
- DatePicker.prototype.create = function( type, value, options ) {
204
-
205
- var isInfiniteValue,
206
- calendar = this
207
-
208
- // If there’s no value, use the type as the value.
209
- value = value === undefined ? type : value
210
-
211
-
212
- // If it’s infinity, update the value.
213
- if ( value == -Infinity || value == Infinity ) {
214
- isInfiniteValue = value
215
- }
216
-
217
- // If it’s an object, use the native date object.
218
- else if ( $.isPlainObject( value ) && _.isInteger( value.pick ) ) {
219
- value = value.obj
220
- }
221
-
222
- // If it’s an array, convert it into a date and make sure
223
- // that it’s a valid date – otherwise default to today.
224
- else if ( $.isArray( value ) ) {
225
- value = new Date( value[ 0 ], value[ 1 ], value[ 2 ] )
226
- value = _.isDate( value ) ? value : calendar.create().obj
227
- }
228
-
229
- // If it’s a number or date object, make a normalized date.
230
- else if ( _.isInteger( value ) || _.isDate( value ) ) {
231
- value = calendar.normalize( new Date( value ), options )
232
- }
233
-
234
- // If it’s a literal true or any other case, set it to now.
235
- else /*if ( value === true )*/ {
236
- value = calendar.now( type, value, options )
237
- }
238
-
239
- // Return the compiled object.
240
- return {
241
- year: isInfiniteValue || value.getFullYear(),
242
- month: isInfiniteValue || value.getMonth(),
243
- date: isInfiniteValue || value.getDate(),
244
- day: isInfiniteValue || value.getDay(),
245
- obj: isInfiniteValue || value,
246
- pick: isInfiniteValue || value.getTime()
247
- }
248
- } //DatePicker.prototype.create
249
-
250
-
251
- /**
252
- * Create a range limit object using an array, date object,
253
- * literal “true”, or integer relative to another time.
254
- */
255
- DatePicker.prototype.createRange = function( from, to ) {
256
-
257
- var calendar = this,
258
- createDate = function( date ) {
259
- if ( date === true || $.isArray( date ) || _.isDate( date ) ) {
260
- return calendar.create( date )
261
- }
262
- return date
263
- }
264
-
265
- // Create objects if possible.
266
- if ( !_.isInteger( from ) ) {
267
- from = createDate( from )
268
- }
269
- if ( !_.isInteger( to ) ) {
270
- to = createDate( to )
271
- }
272
-
273
- // Create relative dates.
274
- if ( _.isInteger( from ) && $.isPlainObject( to ) ) {
275
- from = [ to.year, to.month, to.date + from ];
276
- }
277
- else if ( _.isInteger( to ) && $.isPlainObject( from ) ) {
278
- to = [ from.year, from.month, from.date + to ];
279
- }
280
-
281
- return {
282
- from: createDate( from ),
283
- to: createDate( to )
284
- }
285
- } //DatePicker.prototype.createRange
286
-
287
-
288
- /**
289
- * Check if a date unit falls within a date range object.
290
- */
291
- DatePicker.prototype.withinRange = function( range, dateUnit ) {
292
- range = this.createRange(range.from, range.to)
293
- return dateUnit.pick >= range.from.pick && dateUnit.pick <= range.to.pick
294
- }
295
-
296
-
297
- /**
298
- * Check if two date range objects overlap.
299
- */
300
- DatePicker.prototype.overlapRanges = function( one, two ) {
301
-
302
- var calendar = this
303
-
304
- // Convert the ranges into comparable dates.
305
- one = calendar.createRange( one.from, one.to )
306
- two = calendar.createRange( two.from, two.to )
307
-
308
- return calendar.withinRange( one, two.from ) || calendar.withinRange( one, two.to ) ||
309
- calendar.withinRange( two, one.from ) || calendar.withinRange( two, one.to )
310
- }
311
-
312
-
313
- /**
314
- * Get the date today.
315
- */
316
- DatePicker.prototype.now = function( type, value, options ) {
317
- value = new Date()
318
- if ( options && options.rel ) {
319
- value.setDate( value.getDate() + options.rel )
320
- }
321
- return this.normalize( value, options )
322
- }
323
-
324
-
325
- /**
326
- * Navigate to next/prev month.
327
- */
328
- DatePicker.prototype.navigate = function( type, value, options ) {
329
-
330
- var targetDateObject,
331
- targetYear,
332
- targetMonth,
333
- targetDate,
334
- isTargetArray = $.isArray( value ),
335
- isTargetObject = $.isPlainObject( value ),
336
- viewsetObject = this.item.view/*,
337
- safety = 100*/
338
-
339
-
340
- if ( isTargetArray || isTargetObject ) {
341
-
342
- if ( isTargetObject ) {
343
- targetYear = value.year
344
- targetMonth = value.month
345
- targetDate = value.date
346
- }
347
- else {
348
- targetYear = +value[0]
349
- targetMonth = +value[1]
350
- targetDate = +value[2]
351
- }
352
-
353
- // If we’re navigating months but the view is in a different
354
- // month, navigate to the view’s year and month.
355
- if ( options && options.nav && viewsetObject && viewsetObject.month !== targetMonth ) {
356
- targetYear = viewsetObject.year
357
- targetMonth = viewsetObject.month
358
- }
359
-
360
- // Figure out the expected target year and month.
361
- targetDateObject = new Date( targetYear, targetMonth + ( options && options.nav ? options.nav : 0 ), 1 )
362
- targetYear = targetDateObject.getFullYear()
363
- targetMonth = targetDateObject.getMonth()
364
-
365
- // If the month we’re going to doesn’t have enough days,
366
- // keep decreasing the date until we reach the month’s last date.
367
- while ( /*safety &&*/ new Date( targetYear, targetMonth, targetDate ).getMonth() !== targetMonth ) {
368
- targetDate -= 1
369
- /*safety -= 1
370
- if ( !safety ) {
371
- throw 'Fell into an infinite loop while navigating to ' + new Date( targetYear, targetMonth, targetDate ) + '.'
372
- }*/
373
- }
374
-
375
- value = [ targetYear, targetMonth, targetDate ]
376
- }
377
-
378
- return value
379
- } //DatePicker.prototype.navigate
380
-
381
-
382
- /**
383
- * Normalize a date by setting the hours to midnight.
384
- */
385
- DatePicker.prototype.normalize = function( value/*, options*/ ) {
386
- value.setHours( 0, 0, 0, 0 )
387
- return value
388
- }
389
-
390
-
391
- /**
392
- * Measure the range of dates.
393
- */
394
- DatePicker.prototype.measure = function( type, value/*, options*/ ) {
395
-
396
- var calendar = this
397
-
398
- // If it’s anything false-y, remove the limits.
399
- if ( !value ) {
400
- value = type == 'min' ? -Infinity : Infinity
401
- }
402
-
403
- // If it’s a string, parse it.
404
- else if ( typeof value == 'string' ) {
405
- value = calendar.parse( type, value )
406
- }
407
-
408
- // If it's an integer, get a date relative to today.
409
- else if ( _.isInteger( value ) ) {
410
- value = calendar.now( type, value, { rel: value } )
411
- }
412
-
413
- return value
414
- } ///DatePicker.prototype.measure
415
-
416
-
417
- /**
418
- * Create a viewset object based on navigation.
419
- */
420
- DatePicker.prototype.viewset = function( type, dateObject/*, options*/ ) {
421
- return this.create([ dateObject.year, dateObject.month, 1 ])
422
- }
423
-
424
-
425
- /**
426
- * Validate a date as enabled and shift if needed.
427
- */
428
- DatePicker.prototype.validate = function( type, dateObject, options ) {
429
-
430
- var calendar = this,
431
-
432
- // Keep a reference to the original date.
433
- originalDateObject = dateObject,
434
-
435
- // Make sure we have an interval.
436
- interval = options && options.interval ? options.interval : 1,
437
-
438
- // Check if the calendar enabled dates are inverted.
439
- isFlippedBase = calendar.item.enable === -1,
440
-
441
- // Check if we have any enabled dates after/before now.
442
- hasEnabledBeforeTarget, hasEnabledAfterTarget,
443
-
444
- // The min & max limits.
445
- minLimitObject = calendar.item.min,
446
- maxLimitObject = calendar.item.max,
447
-
448
- // Check if we’ve reached the limit during shifting.
449
- reachedMin, reachedMax,
450
-
451
- // Check if the calendar is inverted and at least one weekday is enabled.
452
- hasEnabledWeekdays = isFlippedBase && calendar.item.disable.filter( function( value ) {
453
-
454
- // If there’s a date, check where it is relative to the target.
455
- if ( $.isArray( value ) ) {
456
- var dateTime = calendar.create( value ).pick
457
- if ( dateTime < dateObject.pick ) hasEnabledBeforeTarget = true
458
- else if ( dateTime > dateObject.pick ) hasEnabledAfterTarget = true
459
- }
460
-
461
- // Return only integers for enabled weekdays.
462
- return _.isInteger( value )
463
- }).length/*,
464
-
465
- safety = 100*/
466
-
467
-
468
-
469
- // Cases to validate for:
470
- // [1] Not inverted and date disabled.
471
- // [2] Inverted and some dates enabled.
472
- // [3] Not inverted and out of range.
473
- //
474
- // Cases to **not** validate for:
475
- // • Navigating months.
476
- // • Not inverted and date enabled.
477
- // • Inverted and all dates disabled.
478
- // • ..and anything else.
479
- if ( !options || !options.nav ) if (
480
- /* 1 */ ( !isFlippedBase && calendar.disabled( dateObject ) ) ||
481
- /* 2 */ ( isFlippedBase && calendar.disabled( dateObject ) && ( hasEnabledWeekdays || hasEnabledBeforeTarget || hasEnabledAfterTarget ) ) ||
482
- /* 3 */ ( !isFlippedBase && (dateObject.pick <= minLimitObject.pick || dateObject.pick >= maxLimitObject.pick) )
483
- ) {
484
-
485
-
486
- // When inverted, flip the direction if there aren’t any enabled weekdays
487
- // and there are no enabled dates in the direction of the interval.
488
- if ( isFlippedBase && !hasEnabledWeekdays && ( ( !hasEnabledAfterTarget && interval > 0 ) || ( !hasEnabledBeforeTarget && interval < 0 ) ) ) {
489
- interval *= -1
490
- }
491
-
492
-
493
- // Keep looping until we reach an enabled date.
494
- while ( /*safety &&*/ calendar.disabled( dateObject ) ) {
495
-
496
- /*safety -= 1
497
- if ( !safety ) {
498
- throw 'Fell into an infinite loop while validating ' + dateObject.obj + '.'
499
- }*/
500
-
501
-
502
- // If we’ve looped into the next/prev month with a large interval, return to the original date and flatten the interval.
503
- if ( Math.abs( interval ) > 1 && ( dateObject.month < originalDateObject.month || dateObject.month > originalDateObject.month ) ) {
504
- dateObject = originalDateObject
505
- interval = interval > 0 ? 1 : -1
506
- }
507
-
508
-
509
- // If we’ve reached the min/max limit, reverse the direction, flatten the interval and set it to the limit.
510
- if ( dateObject.pick <= minLimitObject.pick ) {
511
- reachedMin = true
512
- interval = 1
513
- dateObject = calendar.create([
514
- minLimitObject.year,
515
- minLimitObject.month,
516
- minLimitObject.date + (dateObject.pick === minLimitObject.pick ? 0 : -1)
517
- ])
518
- }
519
- else if ( dateObject.pick >= maxLimitObject.pick ) {
520
- reachedMax = true
521
- interval = -1
522
- dateObject = calendar.create([
523
- maxLimitObject.year,
524
- maxLimitObject.month,
525
- maxLimitObject.date + (dateObject.pick === maxLimitObject.pick ? 0 : 1)
526
- ])
527
- }
528
-
529
-
530
- // If we’ve reached both limits, just break out of the loop.
531
- if ( reachedMin && reachedMax ) {
532
- break
533
- }
534
-
535
-
536
- // Finally, create the shifted date using the interval and keep looping.
537
- dateObject = calendar.create([ dateObject.year, dateObject.month, dateObject.date + interval ])
538
- }
539
-
540
- } //endif
541
-
542
-
543
- // Return the date object settled on.
544
- return dateObject
545
- } //DatePicker.prototype.validate
546
-
547
-
548
- /**
549
- * Check if a date is disabled.
550
- */
551
- DatePicker.prototype.disabled = function( dateToVerify ) {
552
-
553
- var
554
- calendar = this,
555
-
556
- // Filter through the disabled dates to check if this is one.
557
- isDisabledMatch = calendar.item.disable.filter( function( dateToDisable ) {
558
-
559
- // If the date is a number, match the weekday with 0index and `firstDay` check.
560
- if ( _.isInteger( dateToDisable ) ) {
561
- return dateToVerify.day === ( calendar.settings.firstDay ? dateToDisable : dateToDisable - 1 ) % 7
562
- }
563
-
564
- // If it’s an array or a native JS date, create and match the exact date.
565
- if ( $.isArray( dateToDisable ) || _.isDate( dateToDisable ) ) {
566
- return dateToVerify.pick === calendar.create( dateToDisable ).pick
567
- }
568
-
569
- // If it’s an object, match a date within the “from” and “to” range.
570
- if ( $.isPlainObject( dateToDisable ) ) {
571
- return calendar.withinRange( dateToDisable, dateToVerify )
572
- }
573
- })
574
-
575
- // If this date matches a disabled date, confirm it’s not inverted.
576
- isDisabledMatch = isDisabledMatch.length && !isDisabledMatch.filter(function( dateToDisable ) {
577
- return $.isArray( dateToDisable ) && dateToDisable[3] == 'inverted' ||
578
- $.isPlainObject( dateToDisable ) && dateToDisable.inverted
579
- }).length
580
-
581
- // Check the calendar “enabled” flag and respectively flip the
582
- // disabled state. Then also check if it’s beyond the min/max limits.
583
- return calendar.item.enable === -1 ? !isDisabledMatch : isDisabledMatch ||
584
- dateToVerify.pick < calendar.item.min.pick ||
585
- dateToVerify.pick > calendar.item.max.pick
586
-
587
- } //DatePicker.prototype.disabled
588
-
589
-
590
- /**
591
- * Parse a string into a usable type.
592
- */
593
- DatePicker.prototype.parse = function( type, value, options ) {
594
-
595
- var calendar = this,
596
- parsingObject = {}
597
-
598
- // If it’s already parsed, we’re good.
599
- if ( !value || typeof value != 'string' ) {
600
- return value
601
- }
602
-
603
- // We need a `.format` to parse the value with.
604
- if ( !( options && options.format ) ) {
605
- options = options || {}
606
- options.format = calendar.settings.format
607
- }
608
-
609
- // Convert the format into an array and then map through it.
610
- calendar.formats.toArray( options.format ).map( function( label ) {
611
-
612
- var
613
- // Grab the formatting label.
614
- formattingLabel = calendar.formats[ label ],
615
-
616
- // The format length is from the formatting label function or the
617
- // label length without the escaping exclamation (!) mark.
618
- formatLength = formattingLabel ? _.trigger( formattingLabel, calendar, [ value, parsingObject ] ) : label.replace( /^!/, '' ).length
619
-
620
- // If there's a format label, split the value up to the format length.
621
- // Then add it to the parsing object with appropriate label.
622
- if ( formattingLabel ) {
623
- parsingObject[ label ] = value.substr( 0, formatLength )
624
- }
625
-
626
- // Update the value as the substring from format length to end.
627
- value = value.substr( formatLength )
628
- })
629
-
630
- // Compensate for month 0index.
631
- return [
632
- parsingObject.yyyy || parsingObject.yy,
633
- +( parsingObject.mm || parsingObject.m ) - 1,
634
- parsingObject.dd || parsingObject.d
635
- ]
636
- } //DatePicker.prototype.parse
637
-
638
-
639
- /**
640
- * Various formats to display the object in.
641
- */
642
- DatePicker.prototype.formats = (function() {
643
-
644
- // Return the length of the first word in a collection.
645
- function getWordLengthFromCollection( string, collection, dateObject ) {
646
-
647
- // Grab the first word from the string.
648
- var word = string.match( /\w+/ )[ 0 ]
649
-
650
- // If there's no month index, add it to the date object
651
- if ( !dateObject.mm && !dateObject.m ) {
652
- dateObject.m = collection.indexOf( word ) + 1
653
- }
654
-
655
- // Return the length of the word.
656
- return word.length
657
- }
658
-
659
- // Get the length of the first word in a string.
660
- function getFirstWordLength( string ) {
661
- return string.match( /\w+/ )[ 0 ].length
662
- }
663
-
664
- return {
665
-
666
- d: function( string, dateObject ) {
667
-
668
- // If there's string, then get the digits length.
669
- // Otherwise return the selected date.
670
- return string ? _.digits( string ) : dateObject.date
671
- },
672
- dd: function( string, dateObject ) {
673
-
674
- // If there's a string, then the length is always 2.
675
- // Otherwise return the selected date with a leading zero.
676
- return string ? 2 : _.lead( dateObject.date )
677
- },
678
- ddd: function( string, dateObject ) {
679
-
680
- // If there's a string, then get the length of the first word.
681
- // Otherwise return the short selected weekday.
682
- return string ? getFirstWordLength( string ) : this.settings.weekdaysShort[ dateObject.day ]
683
- },
684
- dddd: function( string, dateObject ) {
685
-
686
- // If there's a string, then get the length of the first word.
687
- // Otherwise return the full selected weekday.
688
- return string ? getFirstWordLength( string ) : this.settings.weekdaysFull[ dateObject.day ]
689
- },
690
- m: function( string, dateObject ) {
691
-
692
- // If there's a string, then get the length of the digits
693
- // Otherwise return the selected month with 0index compensation.
694
- return string ? _.digits( string ) : dateObject.month + 1
695
- },
696
- mm: function( string, dateObject ) {
697
-
698
- // If there's a string, then the length is always 2.
699
- // Otherwise return the selected month with 0index and leading zero.
700
- return string ? 2 : _.lead( dateObject.month + 1 )
701
- },
702
- mmm: function( string, dateObject ) {
703
-
704
- var collection = this.settings.monthsShort
705
-
706
- // If there's a string, get length of the relevant month from the short
707
- // months collection. Otherwise return the selected month from that collection.
708
- return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ]
709
- },
710
- mmmm: function( string, dateObject ) {
711
-
712
- var collection = this.settings.monthsFull
713
-
714
- // If there's a string, get length of the relevant month from the full
715
- // months collection. Otherwise return the selected month from that collection.
716
- return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ]
717
- },
718
- yy: function( string, dateObject ) {
719
-
720
- // If there's a string, then the length is always 2.
721
- // Otherwise return the selected year by slicing out the first 2 digits.
722
- return string ? 2 : ( '' + dateObject.year ).slice( 2 )
723
- },
724
- yyyy: function( string, dateObject ) {
725
-
726
- // If there's a string, then the length is always 4.
727
- // Otherwise return the selected year.
728
- return string ? 4 : dateObject.year
729
- },
730
-
731
- // Create an array by splitting the formatting string passed.
732
- toArray: function( formatString ) { return formatString.split( /(d{1,4}|m{1,4}|y{4}|yy|!.)/g ) },
733
-
734
- // Format an object into a string using the formatting options.
735
- toString: function ( formatString, itemObject ) {
736
- var calendar = this
737
- return calendar.formats.toArray( formatString ).map( function( label ) {
738
- return _.trigger( calendar.formats[ label ], calendar, [ 0, itemObject ] ) || label.replace( /^!/, '' )
739
- }).join( '' )
740
- }
741
- }
742
- })() //DatePicker.prototype.formats
743
-
744
-
745
-
746
-
747
- /**
748
- * Check if two date units are the exact.
749
- */
750
- DatePicker.prototype.isDateExact = function( one, two ) {
751
-
752
- var calendar = this
753
-
754
- // When we’re working with weekdays, do a direct comparison.
755
- if (
756
- ( _.isInteger( one ) && _.isInteger( two ) ) ||
757
- ( typeof one == 'boolean' && typeof two == 'boolean' )
758
- ) {
759
- return one === two
760
- }
761
-
762
- // When we’re working with date representations, compare the “pick” value.
763
- if (
764
- ( _.isDate( one ) || $.isArray( one ) ) &&
765
- ( _.isDate( two ) || $.isArray( two ) )
766
- ) {
767
- return calendar.create( one ).pick === calendar.create( two ).pick
768
- }
769
-
770
- // When we’re working with range objects, compare the “from” and “to”.
771
- if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {
772
- return calendar.isDateExact( one.from, two.from ) && calendar.isDateExact( one.to, two.to )
773
- }
774
-
775
- return false
776
- }
777
-
778
-
779
- /**
780
- * Check if two date units overlap.
781
- */
782
- DatePicker.prototype.isDateOverlap = function( one, two ) {
783
-
784
- var calendar = this,
785
- firstDay = calendar.settings.firstDay ? 1 : 0
786
-
787
- // When we’re working with a weekday index, compare the days.
788
- if ( _.isInteger( one ) && ( _.isDate( two ) || $.isArray( two ) ) ) {
789
- one = one % 7 + firstDay
790
- return one === calendar.create( two ).day + 1
791
- }
792
- if ( _.isInteger( two ) && ( _.isDate( one ) || $.isArray( one ) ) ) {
793
- two = two % 7 + firstDay
794
- return two === calendar.create( one ).day + 1
795
- }
796
-
797
- // When we’re working with range objects, check if the ranges overlap.
798
- if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {
799
- return calendar.overlapRanges( one, two )
800
- }
801
-
802
- return false
803
- }
804
-
805
-
806
- /**
807
- * Flip the “enabled” state.
808
- */
809
- DatePicker.prototype.flipEnable = function(val) {
810
- var itemObject = this.item
811
- itemObject.enable = val || (itemObject.enable == -1 ? 1 : -1)
812
- }
813
-
814
-
815
- /**
816
- * Mark a collection of dates as “disabled”.
817
- */
818
- DatePicker.prototype.deactivate = function( type, datesToDisable ) {
819
-
820
- var calendar = this,
821
- disabledItems = calendar.item.disable.slice(0)
822
-
823
-
824
- // If we’re flipping, that’s all we need to do.
825
- if ( datesToDisable == 'flip' ) {
826
- calendar.flipEnable()
827
- }
828
-
829
- else if ( datesToDisable === false ) {
830
- calendar.flipEnable(1)
831
- disabledItems = []
832
- }
833
-
834
- else if ( datesToDisable === true ) {
835
- calendar.flipEnable(-1)
836
- disabledItems = []
837
- }
838
-
839
- // Otherwise go through the dates to disable.
840
- else {
841
-
842
- datesToDisable.map(function( unitToDisable ) {
843
-
844
- var matchFound
845
-
846
- // When we have disabled items, check for matches.
847
- // If something is matched, immediately break out.
848
- for ( var index = 0; index < disabledItems.length; index += 1 ) {
849
- if ( calendar.isDateExact( unitToDisable, disabledItems[index] ) ) {
850
- matchFound = true
851
- break
852
- }
853
- }
854
-
855
- // If nothing was found, add the validated unit to the collection.
856
- if ( !matchFound ) {
857
- if (
858
- _.isInteger( unitToDisable ) ||
859
- _.isDate( unitToDisable ) ||
860
- $.isArray( unitToDisable ) ||
861
- ( $.isPlainObject( unitToDisable ) && unitToDisable.from && unitToDisable.to )
862
- ) {
863
- disabledItems.push( unitToDisable )
864
- }
865
- }
866
- })
867
- }
868
-
869
- // Return the updated collection.
870
- return disabledItems
871
- } //DatePicker.prototype.deactivate
872
-
873
-
874
- /**
875
- * Mark a collection of dates as “enabled”.
876
- */
877
- DatePicker.prototype.activate = function( type, datesToEnable ) {
878
-
879
- var calendar = this,
880
- disabledItems = calendar.item.disable,
881
- disabledItemsCount = disabledItems.length
882
-
883
- // If we’re flipping, that’s all we need to do.
884
- if ( datesToEnable == 'flip' ) {
885
- calendar.flipEnable()
886
- }
887
-
888
- else if ( datesToEnable === true ) {
889
- calendar.flipEnable(1)
890
- disabledItems = []
891
- }
892
-
893
- else if ( datesToEnable === false ) {
894
- calendar.flipEnable(-1)
895
- disabledItems = []
896
- }
897
-
898
- // Otherwise go through the disabled dates.
899
- else {
900
-
901
- datesToEnable.map(function( unitToEnable ) {
902
-
903
- var matchFound,
904
- disabledUnit,
905
- index,
906
- isExactRange
907
-
908
- // Go through the disabled items and try to find a match.
909
- for ( index = 0; index < disabledItemsCount; index += 1 ) {
910
-
911
- disabledUnit = disabledItems[index]
912
-
913
- // When an exact match is found, remove it from the collection.
914
- if ( calendar.isDateExact( disabledUnit, unitToEnable ) ) {
915
- matchFound = disabledItems[index] = null
916
- isExactRange = true
917
- break
918
- }
919
-
920
- // When an overlapped match is found, add the “inverted” state to it.
921
- else if ( calendar.isDateOverlap( disabledUnit, unitToEnable ) ) {
922
- if ( $.isPlainObject( unitToEnable ) ) {
923
- unitToEnable.inverted = true
924
- matchFound = unitToEnable
925
- }
926
- else if ( $.isArray( unitToEnable ) ) {
927
- matchFound = unitToEnable
928
- if ( !matchFound[3] ) matchFound.push( 'inverted' )
929
- }
930
- else if ( _.isDate( unitToEnable ) ) {
931
- matchFound = [ unitToEnable.getFullYear(), unitToEnable.getMonth(), unitToEnable.getDate(), 'inverted' ]
932
- }
933
- break
934
- }
935
- }
936
-
937
- // If a match was found, remove a previous duplicate entry.
938
- if ( matchFound ) for ( index = 0; index < disabledItemsCount; index += 1 ) {
939
- if ( calendar.isDateExact( disabledItems[index], unitToEnable ) ) {
940
- disabledItems[index] = null
941
- break
942
- }
943
- }
944
-
945
- // In the event that we’re dealing with an exact range of dates,
946
- // make sure there are no “inverted” dates because of it.
947
- if ( isExactRange ) for ( index = 0; index < disabledItemsCount; index += 1 ) {
948
- if ( calendar.isDateOverlap( disabledItems[index], unitToEnable ) ) {
949
- disabledItems[index] = null
950
- break
951
- }
952
- }
953
-
954
- // If something is still matched, add it into the collection.
955
- if ( matchFound ) {
956
- disabledItems.push( matchFound )
957
- }
958
- })
959
- }
960
-
961
- // Return the updated collection.
962
- return disabledItems.filter(function( val ) { return val != null })
963
- } //DatePicker.prototype.activate
964
-
965
-
966
- /**
967
- * Create a string for the nodes in the picker.
968
- */
969
- DatePicker.prototype.nodes = function( isOpen ) {
970
-
971
- var
972
- calendar = this,
973
- settings = calendar.settings,
974
- calendarItem = calendar.item,
975
- nowObject = calendarItem.now,
976
- selectedObject = calendarItem.select,
977
- highlightedObject = calendarItem.highlight,
978
- viewsetObject = calendarItem.view,
979
- disabledCollection = calendarItem.disable,
980
- minLimitObject = calendarItem.min,
981
- maxLimitObject = calendarItem.max,
982
-
983
-
984
- // Create the calendar table head using a copy of weekday labels collection.
985
- // * We do a copy so we don't mutate the original array.
986
- tableHead = (function( collection, fullCollection ) {
987
-
988
- // If the first day should be Monday, move Sunday to the end.
989
- if ( settings.firstDay ) {
990
- collection.push( collection.shift() )
991
- fullCollection.push( fullCollection.shift() )
992
- }
993
-
994
- // Create and return the table head group.
995
- return _.node(
996
- 'thead',
997
- _.node(
998
- 'tr',
999
- _.group({
1000
- min: 0,
1001
- max: DAYS_IN_WEEK - 1,
1002
- i: 1,
1003
- node: 'th',
1004
- item: function( counter ) {
1005
- return [
1006
- collection[ counter ],
1007
- settings.klass.weekdays,
1008
- 'scope=col title="' + fullCollection[ counter ] + '"'
1009
- ]
1010
- }
1011
- })
1012
- )
1013
- ) //endreturn
1014
- })( ( settings.showWeekdaysFull ? settings.weekdaysFull : settings.weekdaysShort ).slice( 0 ), settings.weekdaysFull.slice( 0 ) ), //tableHead
1015
-
1016
-
1017
- // Create the nav for next/prev month.
1018
- createMonthNav = function( next ) {
1019
-
1020
- // Otherwise, return the created month tag.
1021
- return _.node(
1022
- 'div',
1023
- ' ',
1024
- settings.klass[ 'nav' + ( next ? 'Next' : 'Prev' ) ] + (
1025
-
1026
- // If the focused month is outside the range, disabled the button.
1027
- ( next && viewsetObject.year >= maxLimitObject.year && viewsetObject.month >= maxLimitObject.month ) ||
1028
- ( !next && viewsetObject.year <= minLimitObject.year && viewsetObject.month <= minLimitObject.month ) ?
1029
- ' ' + settings.klass.navDisabled : ''
1030
- ),
1031
- 'data-nav=' + ( next || -1 ) + ' ' +
1032
- _.ariaAttr({
1033
- role: 'button',
1034
- controls: calendar.$node[0].id + '_table'
1035
- }) + ' ' +
1036
- 'title="' + (next ? settings.labelMonthNext : settings.labelMonthPrev ) + '"'
1037
- ) //endreturn
1038
- }, //createMonthNav
1039
-
1040
-
1041
- // Create the month label.
1042
- createMonthLabel = function() {
1043
-
1044
- var monthsCollection = settings.showMonthsShort ? settings.monthsShort : settings.monthsFull
1045
-
1046
- // If there are months to select, add a dropdown menu.
1047
- if ( settings.selectMonths ) {
1048
-
1049
- return _.node( 'select',
1050
- _.group({
1051
- min: 0,
1052
- max: 11,
1053
- i: 1,
1054
- node: 'option',
1055
- item: function( loopedMonth ) {
1056
-
1057
- return [
1058
-
1059
- // The looped month and no classes.
1060
- monthsCollection[ loopedMonth ], 0,
1061
-
1062
- // Set the value and selected index.
1063
- 'value=' + loopedMonth +
1064
- ( viewsetObject.month == loopedMonth ? ' selected' : '' ) +
1065
- (
1066
- (
1067
- ( viewsetObject.year == minLimitObject.year && loopedMonth < minLimitObject.month ) ||
1068
- ( viewsetObject.year == maxLimitObject.year && loopedMonth > maxLimitObject.month )
1069
- ) ?
1070
- ' disabled' : ''
1071
- )
1072
- ]
1073
- }
1074
- }),
1075
- settings.klass.selectMonth,
1076
- ( isOpen ? '' : 'disabled' ) + ' ' +
1077
- _.ariaAttr({ controls: calendar.$node[0].id + '_table' }) + ' ' +
1078
- 'title="' + settings.labelMonthSelect + '"'
1079
- )
1080
- }
1081
-
1082
- // If there's a need for a month selector
1083
- return _.node( 'div', monthsCollection[ viewsetObject.month ], settings.klass.month )
1084
- }, //createMonthLabel
1085
-
1086
-
1087
- // Create the year label.
1088
- createYearLabel = function() {
1089
-
1090
- var focusedYear = viewsetObject.year,
1091
-
1092
- // If years selector is set to a literal "true", set it to 5. Otherwise
1093
- // divide in half to get half before and half after focused year.
1094
- numberYears = settings.selectYears === true ? 5 : ~~( settings.selectYears / 2 )
1095
-
1096
- // If there are years to select, add a dropdown menu.
1097
- if ( numberYears ) {
1098
-
1099
- var
1100
- minYear = minLimitObject.year,
1101
- maxYear = maxLimitObject.year,
1102
- lowestYear = focusedYear - numberYears,
1103
- highestYear = focusedYear + numberYears
1104
-
1105
- // If the min year is greater than the lowest year, increase the highest year
1106
- // by the difference and set the lowest year to the min year.
1107
- if ( minYear > lowestYear ) {
1108
- highestYear += minYear - lowestYear
1109
- lowestYear = minYear
1110
- }
1111
-
1112
- // If the max year is less than the highest year, decrease the lowest year
1113
- // by the lower of the two: available and needed years. Then set the
1114
- // highest year to the max year.
1115
- if ( maxYear < highestYear ) {
1116
-
1117
- var availableYears = lowestYear - minYear,
1118
- neededYears = highestYear - maxYear
1119
-
1120
- lowestYear -= availableYears > neededYears ? neededYears : availableYears
1121
- highestYear = maxYear
1122
- }
1123
-
1124
- return _.node( 'select',
1125
- _.group({
1126
- min: lowestYear,
1127
- max: highestYear,
1128
- i: 1,
1129
- node: 'option',
1130
- item: function( loopedYear ) {
1131
- return [
1132
-
1133
- // The looped year and no classes.
1134
- loopedYear, 0,
1135
-
1136
- // Set the value and selected index.
1137
- 'value=' + loopedYear + ( focusedYear == loopedYear ? ' selected' : '' )
1138
- ]
1139
- }
1140
- }),
1141
- settings.klass.selectYear,
1142
- ( isOpen ? '' : 'disabled' ) + ' ' + _.ariaAttr({ controls: calendar.$node[0].id + '_table' }) + ' ' +
1143
- 'title="' + settings.labelYearSelect + '"'
1144
- )
1145
- }
1146
-
1147
- // Otherwise just return the year focused
1148
- return _.node( 'div', focusedYear, settings.klass.year )
1149
- } //createYearLabel
1150
-
1151
-
1152
- // Create and return the entire calendar.
1153
- return _.node(
1154
- 'div',
1155
- ( settings.selectYears ? createYearLabel() + createMonthLabel() : createMonthLabel() + createYearLabel() ) +
1156
- createMonthNav() + createMonthNav( 1 ),
1157
- settings.klass.header
1158
- ) + _.node(
1159
- 'table',
1160
- tableHead +
1161
- _.node(
1162
- 'tbody',
1163
- _.group({
1164
- min: 0,
1165
- max: WEEKS_IN_CALENDAR - 1,
1166
- i: 1,
1167
- node: 'tr',
1168
- item: function( rowCounter ) {
1169
-
1170
- // If Monday is the first day and the month starts on Sunday, shift the date back a week.
1171
- var shiftDateBy = settings.firstDay && calendar.create([ viewsetObject.year, viewsetObject.month, 1 ]).day === 0 ? -7 : 0
1172
-
1173
- return [
1174
- _.group({
1175
- min: DAYS_IN_WEEK * rowCounter - viewsetObject.day + shiftDateBy + 1, // Add 1 for weekday 0index
1176
- max: function() {
1177
- return this.min + DAYS_IN_WEEK - 1
1178
- },
1179
- i: 1,
1180
- node: 'td',
1181
- item: function( targetDate ) {
1182
-
1183
- // Convert the time date from a relative date to a target date.
1184
- targetDate = calendar.create([ viewsetObject.year, viewsetObject.month, targetDate + ( settings.firstDay ? 1 : 0 ) ])
1185
-
1186
- var isSelected = selectedObject && selectedObject.pick == targetDate.pick,
1187
- isHighlighted = highlightedObject && highlightedObject.pick == targetDate.pick,
1188
- isDisabled = disabledCollection && calendar.disabled( targetDate ) || targetDate.pick < minLimitObject.pick || targetDate.pick > maxLimitObject.pick
1189
-
1190
- return [
1191
- _.node(
1192
- 'div',
1193
- targetDate.date,
1194
- (function( klasses ) {
1195
-
1196
- // Add the `infocus` or `outfocus` classes based on month in view.
1197
- klasses.push( viewsetObject.month == targetDate.month ? settings.klass.infocus : settings.klass.outfocus )
1198
-
1199
- // Add the `today` class if needed.
1200
- if ( nowObject.pick == targetDate.pick ) {
1201
- klasses.push( settings.klass.now )
1202
- }
1203
-
1204
- // Add the `selected` class if something's selected and the time matches.
1205
- if ( isSelected ) {
1206
- klasses.push( settings.klass.selected )
1207
- }
1208
-
1209
- // Add the `highlighted` class if something's highlighted and the time matches.
1210
- if ( isHighlighted ) {
1211
- klasses.push( settings.klass.highlighted )
1212
- }
1213
-
1214
- // Add the `disabled` class if something's disabled and the object matches.
1215
- if ( isDisabled ) {
1216
- klasses.push( settings.klass.disabled )
1217
- }
1218
-
1219
- return klasses.join( ' ' )
1220
- })([ settings.klass.day ]),
1221
- 'data-pick=' + targetDate.pick + ' ' + _.ariaAttr({
1222
- role: 'gridcell',
1223
- selected: isSelected && calendar.$node.val() === _.trigger(
1224
- calendar.formats.toString,
1225
- calendar,
1226
- [ settings.format, targetDate ]
1227
- ) ? true : null,
1228
- activedescendant: isHighlighted ? true : null,
1229
- disabled: isDisabled ? true : null
1230
- })
1231
- ),
1232
- '',
1233
- _.ariaAttr({ role: 'presentation' })
1234
- ] //endreturn
1235
- }
1236
- })
1237
- ] //endreturn
1238
- }
1239
- })
1240
- ),
1241
- settings.klass.table,
1242
- 'id="' + calendar.$node[0].id + '_table' + '" ' + _.ariaAttr({
1243
- role: 'grid',
1244
- controls: calendar.$node[0].id,
1245
- readonly: true
1246
- })
1247
- ) +
1248
-
1249
- // * For Firefox forms to submit, make sure to set the buttons’ `type` attributes as “button”.
1250
- _.node(
1251
- 'div',
1252
- _.node( 'button', settings.today, settings.klass.buttonToday,
1253
- 'type=button data-pick=' + nowObject.pick +
1254
- ( isOpen && !calendar.disabled(nowObject) ? '' : ' disabled' ) + ' ' +
1255
- _.ariaAttr({ controls: calendar.$node[0].id }) ) +
1256
- _.node( 'button', settings.clear, settings.klass.buttonClear,
1257
- 'type=button data-clear=1' +
1258
- ( isOpen ? '' : ' disabled' ) + ' ' +
1259
- _.ariaAttr({ controls: calendar.$node[0].id }) ) +
1260
- _.node('button', settings.close, settings.klass.buttonClose,
1261
- 'type=button data-close=true ' +
1262
- ( isOpen ? '' : ' disabled' ) + ' ' +
1263
- _.ariaAttr({ controls: calendar.$node[0].id }) ),
1264
- settings.klass.footer
1265
- ) //endreturn
1266
- } //DatePicker.prototype.nodes
1267
-
1268
-
1269
-
1270
-
1271
- /**
1272
- * The date picker defaults.
1273
- */
1274
- DatePicker.defaults = (function( prefix ) {
1275
-
1276
- return {
1277
-
1278
- // The title label to use for the month nav buttons
1279
- labelMonthNext: 'Next month',
1280
- labelMonthPrev: 'Previous month',
1281
-
1282
- // The title label to use for the dropdown selectors
1283
- labelMonthSelect: 'Select a month',
1284
- labelYearSelect: 'Select a year',
1285
-
1286
- // Months and weekdays
1287
- monthsFull: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ],
1288
- monthsShort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
1289
- weekdaysFull: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
1290
- weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
1291
-
1292
- // Today and clear
1293
- today: 'Today',
1294
- clear: 'Clear',
1295
- close: 'Close',
1296
-
1297
- // The format to show on the `input` element
1298
- format: 'd mmmm, yyyy',
1299
-
1300
- // Classes
1301
- klass: {
1302
-
1303
- table: prefix + 'table',
1304
-
1305
- header: prefix + 'header',
1306
-
1307
- navPrev: prefix + 'nav--prev',
1308
- navNext: prefix + 'nav--next',
1309
- navDisabled: prefix + 'nav--disabled',
1310
-
1311
- month: prefix + 'month',
1312
- year: prefix + 'year',
1313
-
1314
- selectMonth: prefix + 'select--month',
1315
- selectYear: prefix + 'select--year',
1316
-
1317
- weekdays: prefix + 'weekday',
1318
-
1319
- day: prefix + 'day',
1320
- disabled: prefix + 'day--disabled',
1321
- selected: prefix + 'day--selected',
1322
- highlighted: prefix + 'day--highlighted',
1323
- now: prefix + 'day--today',
1324
- infocus: prefix + 'day--infocus',
1325
- outfocus: prefix + 'day--outfocus',
1326
-
1327
- footer: prefix + 'footer',
1328
-
1329
- buttonClear: prefix + 'button--clear',
1330
- buttonToday: prefix + 'button--today',
1331
- buttonClose: prefix + 'button--close'
1332
- }
1333
- }
1334
- })( Picker.klasses().picker + '__' )
1335
-
1336
-
1337
-
1338
-
1339
-
1340
- /**
1341
- * Extend the picker to add the date picker.
1342
- */
1343
- Picker.extend( 'pickadate', DatePicker )
1344
-
1345
-
1346
- }));
1347
-
1348
-
1349
-