rsence-pre 3.0.0.8 → 3.0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/client/conf/client_pkg.yaml +6 -2
  4. data/client/js/comm/queue/queue.js +32 -44
  5. data/client/js/comm/transporter/transporter.js +24 -16
  6. data/client/js/comm/values/values.js +27 -15
  7. data/client/js/controls/button/button.coffee +14 -5
  8. data/client/js/controls/button/themes/default/button.css +4 -2
  9. data/client/js/controls/checkbox/checkbox.js +4 -4
  10. data/client/js/controls/dialogs/sheet/sheet.js +11 -11
  11. data/client/js/controls/dialogs/sheet/themes/default/sheet.html +1 -1
  12. data/client/js/controls/imageview/imageview.js +15 -15
  13. data/client/js/controls/numerictextcontrol/numerictextcontrol.coffee +32 -10
  14. data/client/js/controls/onoffbutton/onoffbutton.coffee +5 -5
  15. data/client/js/controls/progress/progressbar/progressbar.js +6 -7
  16. data/client/js/controls/progress/progressbar/themes/default/progressbar.css +4 -4
  17. data/client/js/controls/progress/progressbar/themes/default/progressbar.html +1 -2
  18. data/client/js/controls/sliders/slider/slider.js +74 -79
  19. data/client/js/controls/stepper/stepper.js +31 -31
  20. data/client/js/controls/stringview/stringview.js +20 -8
  21. data/client/js/controls/tab/tab.js +57 -63
  22. data/client/js/controls/tab/themes/default/tab.html +4 -1
  23. data/client/js/controls/textcontrol/textcontrol.coffee +13 -3
  24. data/client/js/controls/validatorview/validatorview.js +4 -4
  25. data/client/js/controls/window/window.js +43 -56
  26. data/client/js/core/class/class.js +25 -23
  27. data/client/js/core/elem/elem.coffee +8 -1
  28. data/client/js/core/rsence_ns/rsence_ns.coffee +6 -2
  29. data/client/js/core/util/util_methods/util_methods.coffee +57 -15
  30. data/client/js/datetime/calendar/calendar.coffee +196 -199
  31. data/client/js/datetime/calendar/themes/default/calendar.css +81 -159
  32. data/client/js/datetime/calendar/themes/default/calendar.html +9 -18
  33. data/client/js/datetime/datepicker/datepicker.coffee +18 -3
  34. data/client/js/datetime/datetimepicker/datetimepicker.coffee +6 -1
  35. data/client/js/datetime/datetimevalue/datetimevalue.coffee +194 -0
  36. data/client/js/datetime/momentjs/momentjs.js +310 -76
  37. data/client/js/datetime/timepicker/timepicker.coffee +6 -1
  38. data/client/js/datetime/timesheet/timesheet.js +59 -61
  39. data/client/js/foundation/control/control.js +45 -44
  40. data/client/js/foundation/control/controldefaults/controldefaults.js +13 -9
  41. data/client/js/foundation/control/dyncontrol/dyncontrol.js +45 -57
  42. data/client/js/foundation/control/eventresponder/eventresponder.js +97 -97
  43. data/client/js/foundation/control/valuematrix/valuematrix.js +13 -13
  44. data/client/js/foundation/eventmanager/eventmanager.coffee +50 -32
  45. data/client/js/foundation/geom/rect/rect.js +43 -32
  46. data/client/js/foundation/locale_settings/locale_settings.js +36 -25
  47. data/client/js/foundation/system/system.js +79 -67
  48. data/client/js/foundation/thememanager/thememanager.coffee +11 -1
  49. data/client/js/foundation/value/pullvalue/pullvalue.coffee +7 -0
  50. data/client/js/foundation/value/pushvalue/pushvalue.coffee +25 -0
  51. data/client/js/foundation/value/value.js +22 -15
  52. data/client/js/foundation/view/view.js +94 -55
  53. data/client/js/foundation/view/viewdefaults/viewdefaults.js +5 -1
  54. data/client/js/lists/listitems/listitems.js +26 -4
  55. data/client/js/menus/combobox/combobox.coffee +55 -0
  56. data/client/js/menus/minimenu/minimenu.js +61 -30
  57. data/client/js/menus/minimenu/themes/default/minimenu.css +1 -6
  58. data/client/js/menus/minimenu/themes/default/minimenu.html +5 -4
  59. data/client/js/menus/minimenuitem/minimenuitem.js +6 -6
  60. data/client/js/menus/popupmenu/themes/default/popupmenu.css +1 -6
  61. data/client/js/menus/popupmenu/themes/default/popupmenu.html +5 -4
  62. data/client/js/tables/table/table.coffee +109 -64
  63. data/client/js/tables/table/themes/default/table.css +4 -0
  64. data/lib/rsence/msg.rb +64 -64
  65. data/lib/rsence/plugins/plugin.rb +68 -52
  66. data/lib/rsence/session/sequel_sessionstorage.rb +5 -5
  67. data/lib/rsence/value.rb +79 -59
  68. data/plugins/client_pkg/lib/client_pkg_build.rb +5 -1
  69. data/plugins/client_pkg/lib/client_pkg_serve.rb +40 -32
  70. data/plugins/main/js/main.js +46 -28
  71. metadata +6 -8
  72. data/client/js/datetime/calendar/themes/default/calendar_arrows.png +0 -0
  73. data/client/js/datetime/calendar/themes/default/calendar_bg.png +0 -0
  74. data/client/js/datetime/calendar/themes/default/calendar_parts1.png +0 -0
  75. data/client/js/datetime/calendar/themes/default/calendar_parts2.png +0 -0
  76. data/client/js/datetime/datetimepicker/datetimepicker.js +0 -210
  77. data/client/js/datetime/datetimevalue/datetimevalue.js +0 -265
@@ -21,9 +21,10 @@
21
21
 
22
22
  // ASP.NET json date format regex
23
23
  aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
24
+ aspNetTimeSpanJsonRegex = /(\-)?(\d*)?\.?(\d+)\:(\d+)\:(\d+)\.?(\d{3})?/,
24
25
 
25
26
  // format tokens
26
- formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,
27
+ formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,
27
28
  localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
28
29
 
29
30
  // parsing tokens
@@ -35,7 +36,7 @@
35
36
  parseTokenThreeDigits = /\d{3}/, // 000 - 999
36
37
  parseTokenFourDigits = /\d{1,4}/, // 0 - 9999
37
38
  parseTokenSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
38
- parseTokenWord = /[0-9]*[a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF]+\s*?[\u0600-\u06FF]+/i, // any word (or two) characters or numbers including two word month in arabic.
39
+ parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic.
39
40
  parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i, // +00:00 -00:00 +0000 -0000 or Z
40
41
  parseTokenT = /T/i, // T (ISO seperator)
41
42
  parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
@@ -57,7 +58,7 @@
57
58
  parseTimezoneChunker = /([\+\-]|\d\d)/gi,
58
59
 
59
60
  // getter and setter names
60
- proxyGettersAndSetters = 'Month|Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
61
+ proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
61
62
  unitMillisecondFactors = {
62
63
  'Milliseconds' : 1,
63
64
  'Seconds' : 1e3,
@@ -68,6 +69,17 @@
68
69
  'Years' : 31536e6
69
70
  },
70
71
 
72
+ unitAliases = {
73
+ ms : 'millisecond',
74
+ s : 'second',
75
+ m : 'minute',
76
+ h : 'hour',
77
+ d : 'day',
78
+ w : 'week',
79
+ M : 'month',
80
+ y : 'year'
81
+ },
82
+
71
83
  // format function strings
72
84
  formatFunctions = {},
73
85
 
@@ -118,6 +130,30 @@
118
130
  YYYYY : function () {
119
131
  return leftZeroFill(this.year(), 5);
120
132
  },
133
+ gg : function () {
134
+ return leftZeroFill(this.weekYear() % 100, 2);
135
+ },
136
+ gggg : function () {
137
+ return this.weekYear();
138
+ },
139
+ ggggg : function () {
140
+ return leftZeroFill(this.weekYear(), 5);
141
+ },
142
+ GG : function () {
143
+ return leftZeroFill(this.isoWeekYear() % 100, 2);
144
+ },
145
+ GGGG : function () {
146
+ return this.isoWeekYear();
147
+ },
148
+ GGGGG : function () {
149
+ return leftZeroFill(this.isoWeekYear(), 5);
150
+ },
151
+ e : function () {
152
+ return this.weekday();
153
+ },
154
+ E : function () {
155
+ return this.isoWeekday();
156
+ },
121
157
  a : function () {
122
158
  return this.lang().meridiem(this.hours(), this.minutes(), true);
123
159
  },
@@ -163,6 +199,12 @@
163
199
  }
164
200
  return b + leftZeroFill(~~(10 * a / 6), 4);
165
201
  },
202
+ z : function () {
203
+ return this.zoneAbbr();
204
+ },
205
+ zz : function () {
206
+ return this.zoneName();
207
+ },
166
208
  X : function () {
167
209
  return this.unix();
168
210
  }
@@ -173,15 +215,15 @@
173
215
  return leftZeroFill(func.call(this, a), count);
174
216
  };
175
217
  }
176
- function ordinalizeToken(func) {
218
+ function ordinalizeToken(func, period) {
177
219
  return function (a) {
178
- return this.lang().ordinal(func.call(this, a));
220
+ return this.lang().ordinal(func.call(this, a), period);
179
221
  };
180
222
  }
181
223
 
182
224
  while (ordinalizeTokens.length) {
183
225
  i = ordinalizeTokens.pop();
184
- formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i]);
226
+ formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);
185
227
  }
186
228
  while (paddedTokens.length) {
187
229
  i = paddedTokens.pop();
@@ -289,24 +331,39 @@
289
331
  }
290
332
 
291
333
  // helper function for _.addTime and _.subtractTime
292
- function addOrSubtractDurationFromMoment(mom, duration, isAdding) {
293
- var ms = duration._milliseconds,
294
- d = duration._days,
295
- M = duration._months,
334
+ function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) {
335
+ var milliseconds = duration._milliseconds,
336
+ days = duration._days,
337
+ months = duration._months,
338
+ minutes,
339
+ hours,
296
340
  currentDate;
297
341
 
298
- if (ms) {
299
- mom._d.setTime(+mom + ms * isAdding);
342
+ if (milliseconds) {
343
+ mom._d.setTime(+mom._d + milliseconds * isAdding);
344
+ }
345
+ // store the minutes and hours so we can restore them
346
+ if (days || months) {
347
+ minutes = mom.minute();
348
+ hours = mom.hour();
300
349
  }
301
- if (d) {
302
- mom.date(mom.date() + d * isAdding);
350
+ if (days) {
351
+ mom.date(mom.date() + days * isAdding);
303
352
  }
304
- if (M) {
353
+ if (months) {
305
354
  currentDate = mom.date();
306
355
  mom.date(1)
307
- .month(mom.month() + M * isAdding)
356
+ .month(mom.month() + months * isAdding)
308
357
  .date(Math.min(currentDate, mom.daysInMonth()));
309
358
  }
359
+ if (milliseconds && !ignoreUpdateOffset) {
360
+ moment.updateOffset(mom);
361
+ }
362
+ // restore the minutes and hours after possibly changing dst
363
+ if (days || months) {
364
+ mom.minute(minutes);
365
+ mom.hour(hours);
366
+ }
310
367
  }
311
368
 
312
369
  // check if is an array
@@ -328,6 +385,10 @@
328
385
  return diffs + lengthDiff;
329
386
  }
330
387
 
388
+ function normalizeUnits(units) {
389
+ return units ? unitAliases[units] || units.toLowerCase().replace(/(.)s$/, '$1') : units;
390
+ }
391
+
331
392
 
332
393
  /************************************
333
394
  Languages
@@ -358,7 +419,7 @@
358
419
  },
359
420
 
360
421
  monthsParse : function (monthName) {
361
- var i, mom, regex, output;
422
+ var i, mom, regex;
362
423
 
363
424
  if (!this._monthsParse) {
364
425
  this._monthsParse = [];
@@ -393,6 +454,27 @@
393
454
  return this._weekdaysMin[m.day()];
394
455
  },
395
456
 
457
+ weekdaysParse : function (weekdayName) {
458
+ var i, mom, regex;
459
+
460
+ if (!this._weekdaysParse) {
461
+ this._weekdaysParse = [];
462
+ }
463
+
464
+ for (i = 0; i < 7; i++) {
465
+ // make the regex if we don't have it already
466
+ if (!this._weekdaysParse[i]) {
467
+ mom = moment([2000, 1]).day(i);
468
+ regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
469
+ this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
470
+ }
471
+ // test the regex
472
+ if (this._weekdaysParse[i].test(weekdayName)) {
473
+ return i;
474
+ }
475
+ }
476
+ },
477
+
396
478
  _longDateFormat : {
397
479
  LT : "h:mm A",
398
480
  L : "MM/DD/YYYY",
@@ -411,6 +493,11 @@
411
493
  return output;
412
494
  },
413
495
 
496
+ isPM : function (input) {
497
+ return ((input + '').toLowerCase()[0] === 'p');
498
+ },
499
+
500
+ _meridiemParse : /[ap]\.?m?\.?/i,
414
501
  meridiem : function (hours, minutes, isLower) {
415
502
  if (hours > 11) {
416
503
  return isLower ? 'pm' : 'PM';
@@ -424,7 +511,7 @@
424
511
  nextDay : '[Tomorrow at] LT',
425
512
  nextWeek : 'dddd [at] LT',
426
513
  lastDay : '[Yesterday at] LT',
427
- lastWeek : '[last] dddd [at] LT',
514
+ lastWeek : '[Last] dddd [at] LT',
428
515
  sameElse : 'L'
429
516
  },
430
517
  calendar : function (key, mom) {
@@ -472,7 +559,7 @@
472
559
  },
473
560
 
474
561
  week : function (mom) {
475
- return weekOfYear(mom, this._week.dow, this._week.doy);
562
+ return weekOfYear(mom, this._week.dow, this._week.doy).week;
476
563
  },
477
564
  _week : {
478
565
  dow : 0, // Sunday is the first day of the week.
@@ -536,7 +623,7 @@
536
623
  return function (mom) {
537
624
  var output = "";
538
625
  for (i = 0; i < length; i++) {
539
- output += typeof array[i].call === 'function' ? array[i].call(mom, format) : array[i];
626
+ output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
540
627
  }
541
628
  return output;
542
629
  };
@@ -568,7 +655,7 @@
568
655
 
569
656
 
570
657
  // get the regex to find the next token
571
- function getParseRegexForToken(token) {
658
+ function getParseRegexForToken(token, config) {
572
659
  switch (token) {
573
660
  case 'DDDD':
574
661
  return parseTokenThreeDigits;
@@ -586,9 +673,10 @@
586
673
  case 'dd':
587
674
  case 'ddd':
588
675
  case 'dddd':
676
+ return parseTokenWord;
589
677
  case 'a':
590
678
  case 'A':
591
- return parseTokenWord;
679
+ return getLangDefinition(config._l)._meridiemParse;
592
680
  case 'X':
593
681
  return parseTokenTimestampMs;
594
682
  case 'Z':
@@ -616,6 +704,14 @@
616
704
  }
617
705
  }
618
706
 
707
+ function timezoneMinutesFromString(string) {
708
+ var tzchunk = (parseTokenTimezone.exec(string) || [])[0],
709
+ parts = (tzchunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
710
+ minutes = +(parts[1] * 60) + ~~parts[2];
711
+
712
+ return parts[0] === '+' ? -minutes : minutes;
713
+ }
714
+
619
715
  // function to convert string input to date
620
716
  function addTimeToArrayFromToken(token, input, config) {
621
717
  var a, b,
@@ -657,7 +753,7 @@
657
753
  // AM / PM
658
754
  case 'a' : // fall through to A
659
755
  case 'A' :
660
- config._isPm = ((input + '').toLowerCase() === 'pm');
756
+ config._isPm = getLangDefinition(config._l).isPM(input);
661
757
  break;
662
758
  // 24 HOUR
663
759
  case 'H' : // fall through to hh
@@ -690,18 +786,7 @@
690
786
  case 'Z' : // fall through to ZZ
691
787
  case 'ZZ' :
692
788
  config._useUTC = true;
693
- a = (input + '').match(parseTimezoneChunker);
694
- if (a && a[1]) {
695
- config._tzh = ~~a[1];
696
- }
697
- if (a && a[2]) {
698
- config._tzm = ~~a[2];
699
- }
700
- // reverse offsets
701
- if (a && a[0] === '+') {
702
- config._tzh = -config._tzh;
703
- config._tzm = -config._tzm;
704
- }
789
+ config._tzm = timezoneMinutesFromString(input);
705
790
  break;
706
791
  }
707
792
 
@@ -727,8 +812,8 @@
727
812
  }
728
813
 
729
814
  // add the offsets to the time to be parsed so that we can have a clean array for checking isValid
730
- input[3] += config._tzh || 0;
731
- input[4] += config._tzm || 0;
815
+ input[3] += ~~((config._tzm || 0) / 60);
816
+ input[4] += ~~((config._tzm || 0) % 60);
732
817
 
733
818
  date = new Date(0);
734
819
 
@@ -753,7 +838,7 @@
753
838
  config._a = [];
754
839
 
755
840
  for (i = 0; i < tokens.length; i++) {
756
- parsedInput = (getParseRegexForToken(tokens[i]).exec(string) || [])[0];
841
+ parsedInput = (getParseRegexForToken(tokens[i], config).exec(string) || [])[0];
757
842
  if (parsedInput) {
758
843
  string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
759
844
  }
@@ -762,6 +847,12 @@
762
847
  addTimeToArrayFromToken(tokens[i], parsedInput, config);
763
848
  }
764
849
  }
850
+
851
+ // add remaining unparsed input to the string
852
+ if (string) {
853
+ config._il = string;
854
+ }
855
+
765
856
  // handle am pm
766
857
  if (config._isPm && config._a[3] < 12) {
767
858
  config._a[3] += 12;
@@ -782,22 +873,22 @@
782
873
 
783
874
  scoreToBeat = 99,
784
875
  i,
785
- currentDate,
786
876
  currentScore;
787
877
 
788
- while (config._f.length) {
878
+ for (i = 0; i < config._f.length; i++) {
789
879
  tempConfig = extend({}, config);
790
- tempConfig._f = config._f.pop();
880
+ tempConfig._f = config._f[i];
791
881
  makeDateFromStringAndFormat(tempConfig);
792
882
  tempMoment = new Moment(tempConfig);
793
883
 
794
- if (tempMoment.isValid()) {
795
- bestMoment = tempMoment;
796
- break;
797
- }
798
-
799
884
  currentScore = compareArrays(tempConfig._a, tempMoment.toArray());
800
885
 
886
+ // if there is any input that was not parsed
887
+ // add a penalty for that format
888
+ if (tempMoment._il) {
889
+ currentScore += tempMoment._il.length;
890
+ }
891
+
801
892
  if (currentScore < scoreToBeat) {
802
893
  scoreToBeat = currentScore;
803
894
  bestMoment = tempMoment;
@@ -810,9 +901,12 @@
810
901
  // date from iso format
811
902
  function makeDateFromString(config) {
812
903
  var i,
813
- string = config._i;
814
- if (isoRegex.exec(string)) {
815
- config._f = 'YYYY-MM-DDT';
904
+ string = config._i,
905
+ match = isoRegex.exec(string);
906
+
907
+ if (match) {
908
+ // match[2] should be "T" or undefined
909
+ config._f = 'YYYY-MM-DD' + (match[2] || " ");
816
910
  for (i = 0; i < 4; i++) {
817
911
  if (isoTimes[i][1].exec(string)) {
818
912
  config._f += isoTimes[i][0];
@@ -894,7 +988,8 @@
894
988
  // (eg. ISO weeks use thursday (4))
895
989
  function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
896
990
  var end = firstDayOfWeekOfYear - firstDayOfWeek,
897
- daysToDayOfWeek = firstDayOfWeekOfYear - mom.day();
991
+ daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
992
+ adjustedMoment;
898
993
 
899
994
 
900
995
  if (daysToDayOfWeek > end) {
@@ -905,7 +1000,11 @@
905
1000
  daysToDayOfWeek += 7;
906
1001
  }
907
1002
 
908
- return Math.ceil(moment(mom).add('d', daysToDayOfWeek).dayOfYear() / 7);
1003
+ adjustedMoment = moment(mom).add('d', daysToDayOfWeek);
1004
+ return {
1005
+ week: Math.ceil(adjustedMoment.dayOfYear() / 7),
1006
+ year: adjustedMoment.year()
1007
+ };
909
1008
  }
910
1009
 
911
1010
 
@@ -971,6 +1070,8 @@
971
1070
  var isDuration = moment.isDuration(input),
972
1071
  isNumber = (typeof input === 'number'),
973
1072
  duration = (isDuration ? input._data : (isNumber ? {} : input)),
1073
+ matched = aspNetTimeSpanJsonRegex.exec(input),
1074
+ sign,
974
1075
  ret;
975
1076
 
976
1077
  if (isNumber) {
@@ -979,6 +1080,16 @@
979
1080
  } else {
980
1081
  duration.milliseconds = input;
981
1082
  }
1083
+ } else if (matched) {
1084
+ sign = (matched[1] === "-") ? -1 : 1;
1085
+ duration = {
1086
+ y: 0,
1087
+ d: ~~matched[2] * sign,
1088
+ h: ~~matched[3] * sign,
1089
+ m: ~~matched[4] * sign,
1090
+ s: ~~matched[5] * sign,
1091
+ ms: ~~matched[6] * sign
1092
+ };
982
1093
  }
983
1094
 
984
1095
  ret = new Duration(duration);
@@ -996,6 +1107,10 @@
996
1107
  // default format
997
1108
  moment.defaultFormat = isoFormat;
998
1109
 
1110
+ // This function will be called whenever a moment is mutated.
1111
+ // It is intended to keep the offset in sync with the timezone.
1112
+ moment.updateOffset = function () {};
1113
+
999
1114
  // This function will load languages and then set the global language. If
1000
1115
  // no arguments are passed in, it will simply return the current global
1001
1116
  // language key.
@@ -1044,11 +1159,11 @@
1044
1159
  },
1045
1160
 
1046
1161
  valueOf : function () {
1047
- return +this._d;
1162
+ return +this._d + ((this._offset || 0) * 60000);
1048
1163
  },
1049
1164
 
1050
1165
  unix : function () {
1051
- return Math.floor(+this._d / 1000);
1166
+ return Math.floor(+this / 1000);
1052
1167
  },
1053
1168
 
1054
1169
  toString : function () {
@@ -1056,11 +1171,11 @@
1056
1171
  },
1057
1172
 
1058
1173
  toDate : function () {
1059
- return this._d;
1174
+ return this._offset ? new Date(+this) : this._d;
1060
1175
  },
1061
1176
 
1062
- toJSON : function () {
1063
- return moment.utc(this).format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
1177
+ toISOString : function () {
1178
+ return formatMoment(moment(this).utc(), 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
1064
1179
  },
1065
1180
 
1066
1181
  toArray : function () {
@@ -1088,11 +1203,11 @@
1088
1203
  },
1089
1204
 
1090
1205
  utc : function () {
1091
- this._isUTC = true;
1092
- return this;
1206
+ return this.zone(0);
1093
1207
  },
1094
1208
 
1095
1209
  local : function () {
1210
+ this.zone(0);
1096
1211
  this._isUTC = false;
1097
1212
  return this;
1098
1213
  },
@@ -1127,14 +1242,11 @@
1127
1242
  },
1128
1243
 
1129
1244
  diff : function (input, units, asFloat) {
1130
- var that = this._isUTC ? moment(input).utc() : moment(input).local(),
1245
+ var that = this._isUTC ? moment(input).zone(this._offset || 0) : moment(input).local(),
1131
1246
  zoneDiff = (this.zone() - that.zone()) * 6e4,
1132
1247
  diff, output;
1133
1248
 
1134
- if (units) {
1135
- // standardize on singular form
1136
- units = units.replace(/s$/, '');
1137
- }
1249
+ units = normalizeUnits(units);
1138
1250
 
1139
1251
  if (units === 'year' || units === 'month') {
1140
1252
  diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2
@@ -1180,18 +1292,44 @@
1180
1292
  },
1181
1293
 
1182
1294
  isDST : function () {
1183
- return (this.zone() < moment([this.year()]).zone() ||
1184
- this.zone() < moment([this.year(), 5]).zone());
1295
+ return (this.zone() < this.clone().month(0).zone() ||
1296
+ this.zone() < this.clone().month(5).zone());
1185
1297
  },
1186
1298
 
1187
1299
  day : function (input) {
1188
1300
  var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
1189
- return input == null ? day :
1190
- this.add({ d : input - day });
1301
+ if (input != null) {
1302
+ if (typeof input === 'string') {
1303
+ input = this.lang().weekdaysParse(input);
1304
+ if (typeof input !== 'number') {
1305
+ return this;
1306
+ }
1307
+ }
1308
+ return this.add({ d : input - day });
1309
+ } else {
1310
+ return day;
1311
+ }
1312
+ },
1313
+
1314
+ month : function (input) {
1315
+ var utc = this._isUTC ? 'UTC' : '';
1316
+ if (input != null) {
1317
+ if (typeof input === 'string') {
1318
+ input = this.lang().monthsParse(input);
1319
+ if (typeof input !== 'number') {
1320
+ return this;
1321
+ }
1322
+ }
1323
+ this._d['set' + utc + 'Month'](input);
1324
+ moment.updateOffset(this);
1325
+ return this;
1326
+ } else {
1327
+ return this._d['get' + utc + 'Month']();
1328
+ }
1191
1329
  },
1192
1330
 
1193
1331
  startOf: function (units) {
1194
- units = units.replace(/s$/, '');
1332
+ units = normalizeUnits(units);
1195
1333
  // the following switch intentionally omits break keywords
1196
1334
  // to utilize falling through the cases.
1197
1335
  switch (units) {
@@ -1218,14 +1356,14 @@
1218
1356
 
1219
1357
  // weeks are a special case
1220
1358
  if (units === 'week') {
1221
- this.day(0);
1359
+ this.weekday(0);
1222
1360
  }
1223
1361
 
1224
1362
  return this;
1225
1363
  },
1226
1364
 
1227
1365
  endOf: function (units) {
1228
- return this.startOf(units).add(units.replace(/s?$/, 's'), 1).subtract('ms', 1);
1366
+ return this.startOf(units).add(units, 1).subtract('ms', 1);
1229
1367
  },
1230
1368
 
1231
1369
  isAfter: function (input, units) {
@@ -1243,8 +1381,42 @@
1243
1381
  return +this.clone().startOf(units) === +moment(input).startOf(units);
1244
1382
  },
1245
1383
 
1246
- zone : function () {
1247
- return this._isUTC ? 0 : this._d.getTimezoneOffset();
1384
+ min: function (other) {
1385
+ other = moment.apply(null, arguments);
1386
+ return other < this ? this : other;
1387
+ },
1388
+
1389
+ max: function (other) {
1390
+ other = moment.apply(null, arguments);
1391
+ return other > this ? this : other;
1392
+ },
1393
+
1394
+ zone : function (input) {
1395
+ var offset = this._offset || 0;
1396
+ if (input != null) {
1397
+ if (typeof input === "string") {
1398
+ input = timezoneMinutesFromString(input);
1399
+ }
1400
+ if (Math.abs(input) < 16) {
1401
+ input = input * 60;
1402
+ }
1403
+ this._offset = input;
1404
+ this._isUTC = true;
1405
+ if (offset !== input) {
1406
+ addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, true);
1407
+ }
1408
+ } else {
1409
+ return this._isUTC ? offset : this._d.getTimezoneOffset();
1410
+ }
1411
+ return this;
1412
+ },
1413
+
1414
+ zoneAbbr : function () {
1415
+ return this._isUTC ? "UTC" : "";
1416
+ },
1417
+
1418
+ zoneName : function () {
1419
+ return this._isUTC ? "Coordinated Universal Time" : "";
1248
1420
  },
1249
1421
 
1250
1422
  daysInMonth : function () {
@@ -1256,9 +1428,14 @@
1256
1428
  return input == null ? dayOfYear : this.add("d", (input - dayOfYear));
1257
1429
  },
1258
1430
 
1259
- isoWeek : function (input) {
1260
- var week = weekOfYear(this, 1, 4);
1261
- return input == null ? week : this.add("d", (input - week) * 7);
1431
+ weekYear : function (input) {
1432
+ var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year;
1433
+ return input == null ? year : this.add("y", (input - year));
1434
+ },
1435
+
1436
+ isoWeekYear : function (input) {
1437
+ var year = weekOfYear(this, 1, 4).year;
1438
+ return input == null ? year : this.add("y", (input - year));
1262
1439
  },
1263
1440
 
1264
1441
  week : function (input) {
@@ -1266,6 +1443,23 @@
1266
1443
  return input == null ? week : this.add("d", (input - week) * 7);
1267
1444
  },
1268
1445
 
1446
+ isoWeek : function (input) {
1447
+ var week = weekOfYear(this, 1, 4).week;
1448
+ return input == null ? week : this.add("d", (input - week) * 7);
1449
+ },
1450
+
1451
+ weekday : function (input) {
1452
+ var weekday = (this._d.getDay() + 7 - this.lang()._week.dow) % 7;
1453
+ return input == null ? weekday : this.add("d", input - weekday);
1454
+ },
1455
+
1456
+ isoWeekday : function (input) {
1457
+ // iso weeks start on monday, which is 1, so we subtract 1 (and add
1458
+ // 7 for negative mod to work).
1459
+ var weekday = (this._d.getDay() + 6) % 7;
1460
+ return input == null ? weekday : this.add("d", input - weekday);
1461
+ },
1462
+
1269
1463
  // If passed a language key, it will set the language for this
1270
1464
  // instance. Otherwise, it will return the language configuration
1271
1465
  // variables for this instance.
@@ -1285,6 +1479,7 @@
1285
1479
  var utc = this._isUTC ? 'UTC' : '';
1286
1480
  if (input != null) {
1287
1481
  this._d['set' + utc + key](input);
1482
+ moment.updateOffset(this);
1288
1483
  return this;
1289
1484
  } else {
1290
1485
  return this._d['get' + utc + key]();
@@ -1302,9 +1497,13 @@
1302
1497
 
1303
1498
  // add plural methods
1304
1499
  moment.fn.days = moment.fn.day;
1500
+ moment.fn.months = moment.fn.month;
1305
1501
  moment.fn.weeks = moment.fn.week;
1306
1502
  moment.fn.isoWeeks = moment.fn.isoWeek;
1307
1503
 
1504
+ // add aliased format methods
1505
+ moment.fn.toJSON = moment.fn.toISOString;
1506
+
1308
1507
  /************************************
1309
1508
  Duration Prototype
1310
1509
  ************************************/
@@ -1318,7 +1517,8 @@
1318
1517
  valueOf : function () {
1319
1518
  return this._milliseconds +
1320
1519
  this._days * 864e5 +
1321
- this._months * 2592e6;
1520
+ (this._months % 12) * 2592e6 +
1521
+ ~~(this._months / 12) * 31536e6;
1322
1522
  },
1323
1523
 
1324
1524
  humanize : function (withSuffix) {
@@ -1332,6 +1532,37 @@
1332
1532
  return this.lang().postformat(output);
1333
1533
  },
1334
1534
 
1535
+ add : function (input, val) {
1536
+ // supports only 2.0-style add(1, 's') or add(moment)
1537
+ var dur = moment.duration(input, val);
1538
+
1539
+ this._milliseconds += dur._milliseconds;
1540
+ this._days += dur._days;
1541
+ this._months += dur._months;
1542
+
1543
+ return this;
1544
+ },
1545
+
1546
+ subtract : function (input, val) {
1547
+ var dur = moment.duration(input, val);
1548
+
1549
+ this._milliseconds -= dur._milliseconds;
1550
+ this._days -= dur._days;
1551
+ this._months -= dur._months;
1552
+
1553
+ return this;
1554
+ },
1555
+
1556
+ get : function (units) {
1557
+ units = normalizeUnits(units);
1558
+ return this[units.toLowerCase() + 's']();
1559
+ },
1560
+
1561
+ as : function (units) {
1562
+ units = normalizeUnits(units);
1563
+ return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's']();
1564
+ },
1565
+
1335
1566
  lang : moment.fn.lang
1336
1567
  };
1337
1568
 
@@ -1355,6 +1586,9 @@
1355
1586
  }
1356
1587
 
1357
1588
  makeDurationAsGetter('Weeks', 6048e5);
1589
+ moment.duration.fn.asMonths = function () {
1590
+ return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12;
1591
+ };
1358
1592
 
1359
1593
 
1360
1594
  /************************************