11angular . module ( "materialCalendar" , [ "ngMaterial" , "ngSanitize" ] ) ;
22
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-
103angular . module ( "materialCalendar" ) . constant ( "config" , {
114 version : "0.2.9" ,
125 debug : document . domain . indexOf ( "localhost" ) > - 1
@@ -19,18 +12,18 @@ angular.module("materialCalendar").config(["config", "$logProvider", "$compilePr
1912 }
2013} ] ) ;
2114
22- angular . module ( "materialCalendar" ) . service ( "Calendar" , [ "$filter" , function ( $filter ) {
15+ angular . module ( "materialCalendar" ) . service ( "Calendar" , [ function ( ) {
2316
2417 function Calendar ( year , month , options ) {
2518
26- var now = $filter ( "dateToGmt" ) ( ) ;
19+ var now = new Date ( ) ;
2720
2821 this . getNumDays = function ( ) {
29- return $filter ( "dateToGmt" ) ( new Date (
22+ return new Date (
3023 this . start . getYear ( ) ,
3124 this . start . getMonth ( ) ,
3225 0
33- ) ) . getDate ( ) ;
26+ ) . getDate ( ) ;
3427 } ;
3528
3629 this . setWeekStartsOn = function ( i ) {
@@ -53,90 +46,81 @@ angular.module("materialCalendar").service("Calendar", ["$filter", function($fil
5346
5447 // Get first date of month.
5548 var date = this . start ;
56- var first = new Date ( date . getFullYear ( ) , date . getMonth ( ) , 1 ) ;
57-
58- if ( first . getDay ( ) !== this . weekStartsOn ) {
5949
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 ) ;
6752
53+ while ( first . getDay ( ) != this . weekStartsOn ) {
54+ var d = first . getDate ( ) ;
55+ first . setDate ( d - 1 ) ;
6856 }
6957
7058 return first ;
7159
7260 } ;
7361
7462 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+ }
7668 } ;
7769
7870 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+ }
8477 } ;
8578
8679 // Month should be the javascript indexed month, 0 is January, etc.
8780 this . init = function ( year , month ) {
8881
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 ( ) ;
9885
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 ] ;
10288
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+ }
10795
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+ }
112103
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+ }
115108
116- date = $filter ( "dateToGmt" ) ( new Date ( first . valueOf ( ) + ( i * 86400000 ) ) ) ;
109+ this . weeks = [ ] ;
110+ for ( var i = 0 ; i < monthLength ; ++ i ) {
117111
118112 // Let's start a new week.
119- // @todo If timezone changes, this goes haywire.
120113 if ( i % 7 === 0 ) {
121114 this . weeks . push ( [ ] ) ;
122115 }
123116
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 ) ) ;
132120
133- }
121+ // Increment it.
122+ date . setDate ( date . getDate ( ) + 1 ) ;
134123
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- }
140124 }
141125
142126 } ;
@@ -152,7 +136,7 @@ angular.module("materialCalendar").service("Calendar", ["$filter", function($fil
152136angular . module ( "materialCalendar" ) . directive ( "calendarMd" , [ "$compile" , "$timeout" , "$parse" , "$http" , "$q" , "$filter" , "$log" , "Calendar" , function ( $compile , $timeout , $parse , $http , $q , $filter , $log , Calendar ) {
153137
154138 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>" ;
156140
157141 var injectCss = function ( ) {
158142 if ( ! hasCss ) {
@@ -221,7 +205,7 @@ angular.module("materialCalendar").directive("calendarMd", ["$compile", "$timeou
221205 $scope . dayTooltipFormat = $scope . dayTooltipFormat || "fullDate" ;
222206
223207 $scope . sameMonth = function ( date ) {
224- var d = $filter ( "dateToGmt" ) ( date ) ;
208+ var d = angular . copy ( date ) ;
225209 return d . getFullYear ( ) === $scope . calendar . year &&
226210 d . getMonth ( ) === $scope . calendar . month ;
227211 } ;
0 commit comments