1
1
angular . module ( "materialCalendar" , [ "ngMaterial" , "ngSanitize" ] ) ;
2
2
3
- angular . module ( "materialCalendar" ) . filter ( "dateToGmt" , function ( ) {
4
- return function ( date ) {
5
- date = date || new Date ( ) ;
6
- return new Date ( Date . UTC ( date . getFullYear ( ) , date . getMonth ( ) , date . getDate ( ) ) ) ;
7
- } ;
8
- } ) ;
9
-
10
3
angular . module ( "materialCalendar" ) . constant ( "config" , {
11
4
version : "0.2.9" ,
12
5
debug : document . domain . indexOf ( "localhost" ) > - 1
@@ -19,18 +12,18 @@ angular.module("materialCalendar").config(["config", "$logProvider", "$compilePr
19
12
}
20
13
} ] ) ;
21
14
22
- angular . module ( "materialCalendar" ) . service ( "Calendar" , [ "$filter" , function ( $filter ) {
15
+ angular . module ( "materialCalendar" ) . service ( "Calendar" , [ function ( ) {
23
16
24
17
function Calendar ( year , month , options ) {
25
18
26
- var now = $filter ( "dateToGmt" ) ( ) ;
19
+ var now = new Date ( ) ;
27
20
28
21
this . getNumDays = function ( ) {
29
- return $filter ( "dateToGmt" ) ( new Date (
22
+ return new Date (
30
23
this . start . getYear ( ) ,
31
24
this . start . getMonth ( ) ,
32
25
0
33
- ) ) . getDate ( ) ;
26
+ ) . getDate ( ) ;
34
27
} ;
35
28
36
29
this . setWeekStartsOn = function ( i ) {
@@ -53,90 +46,81 @@ angular.module("materialCalendar").service("Calendar", ["$filter", function($fil
53
46
54
47
// Get first date of month.
55
48
var date = this . start ;
56
- var first = new Date ( date . getFullYear ( ) , date . getMonth ( ) , 1 ) ;
57
-
58
- if ( first . getDay ( ) !== this . weekStartsOn ) {
59
49
60
- // Set the first day of the month.
61
- first . setDate ( first . getDate ( ) - first . getDay ( ) + ( this . weekStartsOn ) ) ;
62
-
63
- // Sanity check to prevent first/last week from being out of month.
64
- if ( first . getDate ( ) > 1 && first . getDate ( ) < 7 ) {
65
- first . setDate ( first . getDate ( ) - 7 ) ;
66
- }
50
+ // Undo the timezone offset here.
51
+ var first = angular . copy ( date ) ;
67
52
53
+ while ( first . getDay ( ) != this . weekStartsOn ) {
54
+ var d = first . getDate ( ) ;
55
+ first . setDate ( d - 1 ) ;
68
56
}
69
57
70
58
return first ;
71
59
72
60
} ;
73
61
74
62
this . next = function ( ) {
75
- this . init ( this . year , this . month + 1 ) ;
63
+ if ( this . start . getMonth ( ) < 11 ) {
64
+ this . init ( this . start . getFullYear ( ) , this . start . getMonth ( ) + 1 ) ;
65
+ } else {
66
+ this . init ( this . start . getFullYear ( ) + 1 , 0 ) ;
67
+ }
76
68
} ;
77
69
78
70
this . prev = function ( ) {
79
- this . init ( this . year , this . month - 1 ) ;
80
- } ;
81
-
82
- this . _isFirstDayOfWeek = function ( date ) {
83
- return ! date . getDay ( ) ;
71
+ if ( this . month ) {
72
+ this . init ( this . start . getFullYear ( ) , this . start . getMonth ( ) - 1 ) ;
73
+ return ;
74
+ } else {
75
+ this . init ( this . start . getFullYear ( ) - 1 , 11 ) ;
76
+ }
84
77
} ;
85
78
86
79
// Month should be the javascript indexed month, 0 is January, etc.
87
80
this . init = function ( year , month ) {
88
81
89
- if ( year ) {
90
- if ( month ) {
91
- this . year = year ;
92
- this . month = month ;
93
- } else {
94
- this . year = year - 1 ;
95
- this . month = 11 ;
96
- }
97
- }
82
+ var now = new Date ( ) ;
83
+ this . year = angular . isDefined ( year ) ? year : now . getFullYear ( ) ;
84
+ this . month = angular . isDefined ( month ) ? month : now . getMonth ( ) ;
98
85
99
- // Set up the new date.
100
- this . start = $filter ( "dateToGmt" ) ( new Date ( this . year , this . month , 1 , 0 , 0 ) ) ;
101
- this . weeks = [ ] ;
86
+ var daysInMonth = [ 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ] ;
87
+ var monthLength = daysInMonth [ this . month ] ;
102
88
103
- // Reset the month and year to handle the case of many
104
- // prev/next calls across years.
105
- this . year = this . start . getFullYear ( ) ;
106
- this . month = this . start . getMonth ( ) ;
89
+ // Figure out if is a leap year.
90
+ if ( this . month == 1 ) {
91
+ if ( ( this . year % 4 == 0 && this . year % 100 != 0 ) || this . year % 400 == 0 ) {
92
+ monthLength = 29 ;
93
+ }
94
+ }
107
95
108
- var date ;
109
- var first = this . getFirstDayOfCalendar ( ) ;
110
- var i = 0 ;
111
- var _i = first . getDate ( ) == 1 && this . getNumDays ( ) == 28 ? 28 : 42 ;
96
+ // First day of calendar month.
97
+ this . start = new Date ( this . year , this . month , 1 ) ;
98
+ var date = angular . copy ( this . start ) ;
99
+ while ( date . getDay ( ) != this . weekStartsOn ) {
100
+ date . setDate ( date . getDate ( ) - 1 ) ;
101
+ monthLength ++ ;
102
+ }
112
103
113
- // @todo Need to fix for up to 6 weeks.
114
- for ( ; i < _i ; i ++ ) {
104
+ // Last day of calendar month.
105
+ while ( monthLength % 7 !== 0 ) {
106
+ monthLength ++ ;
107
+ }
115
108
116
- date = $filter ( "dateToGmt" ) ( new Date ( first . valueOf ( ) + ( i * 86400000 ) ) ) ;
109
+ this . weeks = [ ] ;
110
+ for ( var i = 0 ; i < monthLength ; ++ i ) {
117
111
118
112
// Let's start a new week.
119
- // @todo If timezone changes, this goes haywire.
120
113
if ( i % 7 === 0 ) {
121
114
this . weeks . push ( [ ] ) ;
122
115
}
123
116
124
- // Sanity check to prevent first day of week from being in next month.
125
- if ( this . weeks . length > 1 && ! this . weeks [ this . weeks . length - 1 ] . length ) {
126
- if ( date . getMonth ( ) !== this . month ) {
127
- break ;
128
- }
129
- }
130
-
131
- this . weeks [ this . weeks . length - 1 ] . push ( date ) ;
117
+ // Add copy of the date. If not a copy,
118
+ // it will get updated shortly.
119
+ this . weeks [ this . weeks . length - 1 ] . push ( angular . copy ( date ) ) ;
132
120
133
- }
121
+ // Increment it.
122
+ date . setDate ( date . getDate ( ) + 1 ) ;
134
123
135
- // Sanity check to prevent empty weeks.
136
- for ( var x = this . weeks . length - 1 ; x >= 0 ; -- x ) {
137
- if ( this . weeks [ x ] . length === 0 ) {
138
- this . weeks . splice ( x , 1 ) ;
139
- }
140
124
}
141
125
142
126
} ;
@@ -152,7 +136,7 @@ angular.module("materialCalendar").service("Calendar", ["$filter", function($fil
152
136
angular . module ( "materialCalendar" ) . directive ( "calendarMd" , [ "$compile" , "$timeout" , "$parse" , "$http" , "$q" , "$filter" , "$log" , "Calendar" , function ( $compile , $timeout , $parse , $http , $q , $filter , $log , Calendar ) {
153
137
154
138
var hasCss ;
155
- var defaultTemplate = "<md-content layout='column' layout-fill flex md-swipe-left='next()' md-swipe-right='prev()'><md-toolbar><div class='md-toolbar-tools' layout='row'><md-button ng-click='prev()' aria-label='Previous month'><md-tooltip ng-if='::tooltips()'>Previous month</md-tooltip>«</md-button><div flex></div><h2 class='calendar-md-title'><span>{{ calendar.start | date:titleFormat:timezone }}</span></h2><div flex></div><md-button ng-click='next()' aria-label='Next month'><md-tooltip ng-if='::tooltips()'>Next month</md-tooltip>»</md-button></div></md-toolbar><!-- agenda view --><md-content ng-if='weekLayout === columnWeekLayout' class='agenda'><div ng-repeat='week in calendar.weeks track by $index'><div ng-if='sameMonth(day)' ng-class='{ active: active === day }' ng-click='handleDayClick(day)' ng-repeat='day in week' layout><md-tooltip ng-if='::tooltips()'>{{ day | date:dayTooltipFormat:timezone }}</md-tooltip><div>{{ day | date:dayFormat:timezone }}</div><div flex ng-bind-html='getDayContent(day)'></div></div></div></md-content><!-- calendar view --><md-content ng-if='weekLayout !== columnWeekLayout' flex layout='column' class='calendar'><div layout='row' layout-fill class='subheader'><div layout-padding class='subheader-day' flex ng-repeat='day in calendar.weeks[0]'><md-tooltip ng-if='::tooltips()'>{{ day | date:dayLabelTooltipFormat:timezone }}</md-tooltip>{{ day | date:dayLabelFormat:timezone }}</div></div><div ng-if='week.length' ng-repeat='week in calendar.weeks track by $index' flex layout='row' layout-fill><div tabindex='{{ sameMonth(day) ? (day | date:dayFormat:timezone) : 0 }}' ng-repeat='day in week track by $index' ng-click='handleDayClick(day)' flex layout layout-padding ng-class='{"disabled" : ! sameMonth(day), "active": isActive(day), "md-whiteframe-12dp": hover || focus }' ng-focus='focus = true;' ng-blur='focus = false;' ng-mouseleave='hover = false' ng-mouseenter='hover = true'><md-tooltip ng-if='::tooltips()'>{{ day | date:dayTooltipFormat:timezone }}</md-tooltip><div>{{ day | date:dayFormat:timezone }}</div><div flex ng-bind-html='data[dayKey(day)]'></div></div></div></md-content></md-content>" ;
139
+ var defaultTemplate = "<md-content layout='column' layout-fill flex md-swipe-left='next()' md-swipe-right='prev()'><md-toolbar><div class='md-toolbar-tools' layout='row'><md-button ng-click='prev()' aria-label='Previous month'><md-tooltip ng-if='::tooltips()'>Previous month</md-tooltip>«</md-button><div flex></div><h2 class='calendar-md-title'><span>{{ calendar.start | date:titleFormat:timezone }}</span></h2><div flex></div><md-button ng-click='next()' aria-label='Next month'><md-tooltip ng-if='::tooltips()'>Next month</md-tooltip>»</md-button></div></md-toolbar><!-- agenda view --><md-content ng-if='weekLayout === columnWeekLayout' class='agenda'><div ng-repeat='week in calendar.weeks track by $index'><div ng-if='sameMonth(day)' ng-class='{ active: active === day }' ng-click='handleDayClick(day)' ng-repeat='day in week' layout><md-tooltip ng-if='::tooltips()'>{{ day | date:dayTooltipFormat:timezone }}</md-tooltip><div>{{ day | date:dayFormat:timezone }}</div><div flex ng-bind-html='getDayContent(day)'></div></div></div></md-content><!-- calendar view --><md-content ng-if='weekLayout !== columnWeekLayout' flex layout='column' class='calendar'><div layout='row' layout-fill class='subheader'><div layout-padding class='subheader-day' flex ng-repeat='day in calendar.weeks[0]'><md-tooltip ng-if='::tooltips()'>{{ day | date:dayLabelTooltipFormat }}</md-tooltip>{{ day | date:dayLabelFormat }}</div></div><div ng-if='week.length' ng-repeat='week in calendar.weeks track by $index' flex layout='row' layout-fill><div tabindex='{{ sameMonth(day) ? (day | date:dayFormat:timezone) : 0 }}' ng-repeat='day in week track by $index' ng-click='handleDayClick(day)' flex layout layout-padding ng-class='{"disabled" : ! sameMonth(day), "active": isActive(day), "md-whiteframe-12dp": hover || focus }' ng-focus='focus = true;' ng-blur='focus = false;' ng-mouseleave='hover = false' ng-mouseenter='hover = true'><md-tooltip ng-if='::tooltips()'>{{ day | date:dayTooltipFormat }}</md-tooltip><div>{{ day | date:dayFormat }}</div><div flex ng-bind-html='data[dayKey(day)]'></div></div></div></md-content></md-content>" ;
156
140
157
141
var injectCss = function ( ) {
158
142
if ( ! hasCss ) {
@@ -221,7 +205,7 @@ angular.module("materialCalendar").directive("calendarMd", ["$compile", "$timeou
221
205
$scope . dayTooltipFormat = $scope . dayTooltipFormat || "fullDate" ;
222
206
223
207
$scope . sameMonth = function ( date ) {
224
- var d = $filter ( "dateToGmt" ) ( date ) ;
208
+ var d = angular . copy ( date ) ;
225
209
return d . getFullYear ( ) === $scope . calendar . year &&
226
210
d . getMonth ( ) === $scope . calendar . month ;
227
211
} ;
0 commit comments