rails-angularstrap 2.2.0

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 (148) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +89 -0
  3. data/Rakefile +2 -0
  4. data/lib/rails/angularstrap.rb +8 -0
  5. data/lib/rails/angularstrap/version.rb +5 -0
  6. data/vendor/assets/javascripts/angular-strap/LICENSE.md +21 -0
  7. data/vendor/assets/javascripts/angular-strap/README.md +112 -0
  8. data/vendor/assets/javascripts/angular-strap/angular-strap.nuspec +23 -0
  9. data/vendor/assets/javascripts/angular-strap/bower.json +53 -0
  10. data/vendor/assets/javascripts/angular-strap/dist/angular-strap.js +5014 -0
  11. data/vendor/assets/javascripts/angular-strap/dist/angular-strap.min.js +11 -0
  12. data/vendor/assets/javascripts/angular-strap/dist/angular-strap.min.js.map +1 -0
  13. data/vendor/assets/javascripts/angular-strap/dist/angular-strap.tpl.js +89 -0
  14. data/vendor/assets/javascripts/angular-strap/dist/angular-strap.tpl.min.js +8 -0
  15. data/vendor/assets/javascripts/angular-strap/dist/modules/affix.js +249 -0
  16. data/vendor/assets/javascripts/angular-strap/dist/modules/affix.min.js +9 -0
  17. data/vendor/assets/javascripts/angular-strap/dist/modules/affix.min.js.map +1 -0
  18. data/vendor/assets/javascripts/angular-strap/dist/modules/alert.js +120 -0
  19. data/vendor/assets/javascripts/angular-strap/dist/modules/alert.min.js +9 -0
  20. data/vendor/assets/javascripts/angular-strap/dist/modules/alert.min.js.map +1 -0
  21. data/vendor/assets/javascripts/angular-strap/dist/modules/alert.tpl.js +14 -0
  22. data/vendor/assets/javascripts/angular-strap/dist/modules/alert.tpl.min.js +8 -0
  23. data/vendor/assets/javascripts/angular-strap/dist/modules/aside.js +96 -0
  24. data/vendor/assets/javascripts/angular-strap/dist/modules/aside.min.js +9 -0
  25. data/vendor/assets/javascripts/angular-strap/dist/modules/aside.min.js.map +1 -0
  26. data/vendor/assets/javascripts/angular-strap/dist/modules/aside.tpl.js +14 -0
  27. data/vendor/assets/javascripts/angular-strap/dist/modules/aside.tpl.min.js +8 -0
  28. data/vendor/assets/javascripts/angular-strap/dist/modules/button.js +177 -0
  29. data/vendor/assets/javascripts/angular-strap/dist/modules/button.min.js +9 -0
  30. data/vendor/assets/javascripts/angular-strap/dist/modules/button.min.js.map +1 -0
  31. data/vendor/assets/javascripts/angular-strap/dist/modules/collapse.js +273 -0
  32. data/vendor/assets/javascripts/angular-strap/dist/modules/collapse.min.js +9 -0
  33. data/vendor/assets/javascripts/angular-strap/dist/modules/collapse.min.js.map +1 -0
  34. data/vendor/assets/javascripts/angular-strap/dist/modules/date-formatter.js +61 -0
  35. data/vendor/assets/javascripts/angular-strap/dist/modules/date-formatter.min.js +9 -0
  36. data/vendor/assets/javascripts/angular-strap/dist/modules/date-formatter.min.js.map +1 -0
  37. data/vendor/assets/javascripts/angular-strap/dist/modules/date-parser.js +273 -0
  38. data/vendor/assets/javascripts/angular-strap/dist/modules/date-parser.min.js +9 -0
  39. data/vendor/assets/javascripts/angular-strap/dist/modules/date-parser.min.js.map +1 -0
  40. data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.js +640 -0
  41. data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.min.js +9 -0
  42. data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.min.js.map +1 -0
  43. data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.tpl.js +14 -0
  44. data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.tpl.min.js +8 -0
  45. data/vendor/assets/javascripts/angular-strap/dist/modules/debounce.js +62 -0
  46. data/vendor/assets/javascripts/angular-strap/dist/modules/debounce.min.js +9 -0
  47. data/vendor/assets/javascripts/angular-strap/dist/modules/debounce.min.js.map +1 -0
  48. data/vendor/assets/javascripts/angular-strap/dist/modules/dimensions.js +156 -0
  49. data/vendor/assets/javascripts/angular-strap/dist/modules/dimensions.min.js +9 -0
  50. data/vendor/assets/javascripts/angular-strap/dist/modules/dimensions.min.js.map +1 -0
  51. data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.js +149 -0
  52. data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.min.js +9 -0
  53. data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.min.js.map +1 -0
  54. data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.tpl.js +14 -0
  55. data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.tpl.min.js +8 -0
  56. data/vendor/assets/javascripts/angular-strap/dist/modules/modal.js +349 -0
  57. data/vendor/assets/javascripts/angular-strap/dist/modules/modal.min.js +9 -0
  58. data/vendor/assets/javascripts/angular-strap/dist/modules/modal.min.js.map +1 -0
  59. data/vendor/assets/javascripts/angular-strap/dist/modules/modal.tpl.js +14 -0
  60. data/vendor/assets/javascripts/angular-strap/dist/modules/modal.tpl.min.js +8 -0
  61. data/vendor/assets/javascripts/angular-strap/dist/modules/navbar.js +72 -0
  62. data/vendor/assets/javascripts/angular-strap/dist/modules/navbar.min.js +9 -0
  63. data/vendor/assets/javascripts/angular-strap/dist/modules/navbar.min.js.map +1 -0
  64. data/vendor/assets/javascripts/angular-strap/dist/modules/parse-options.js +76 -0
  65. data/vendor/assets/javascripts/angular-strap/dist/modules/parse-options.min.js +9 -0
  66. data/vendor/assets/javascripts/angular-strap/dist/modules/parse-options.min.js.map +1 -0
  67. data/vendor/assets/javascripts/angular-strap/dist/modules/popover.js +112 -0
  68. data/vendor/assets/javascripts/angular-strap/dist/modules/popover.min.js +9 -0
  69. data/vendor/assets/javascripts/angular-strap/dist/modules/popover.min.js.map +1 -0
  70. data/vendor/assets/javascripts/angular-strap/dist/modules/popover.tpl.js +14 -0
  71. data/vendor/assets/javascripts/angular-strap/dist/modules/popover.tpl.min.js +8 -0
  72. data/vendor/assets/javascripts/angular-strap/dist/modules/raf.js +61 -0
  73. data/vendor/assets/javascripts/angular-strap/dist/modules/raf.min.js +9 -0
  74. data/vendor/assets/javascripts/angular-strap/dist/modules/raf.min.js.map +1 -0
  75. data/vendor/assets/javascripts/angular-strap/dist/modules/scrollspy.js +261 -0
  76. data/vendor/assets/javascripts/angular-strap/dist/modules/scrollspy.min.js +9 -0
  77. data/vendor/assets/javascripts/angular-strap/dist/modules/scrollspy.min.js.map +1 -0
  78. data/vendor/assets/javascripts/angular-strap/dist/modules/select.js +325 -0
  79. data/vendor/assets/javascripts/angular-strap/dist/modules/select.min.js +9 -0
  80. data/vendor/assets/javascripts/angular-strap/dist/modules/select.min.js.map +1 -0
  81. data/vendor/assets/javascripts/angular-strap/dist/modules/select.tpl.js +14 -0
  82. data/vendor/assets/javascripts/angular-strap/dist/modules/select.tpl.min.js +8 -0
  83. data/vendor/assets/javascripts/angular-strap/dist/modules/tab.js +186 -0
  84. data/vendor/assets/javascripts/angular-strap/dist/modules/tab.min.js +9 -0
  85. data/vendor/assets/javascripts/angular-strap/dist/modules/tab.min.js.map +1 -0
  86. data/vendor/assets/javascripts/angular-strap/dist/modules/tab.tpl.js +14 -0
  87. data/vendor/assets/javascripts/angular-strap/dist/modules/tab.tpl.min.js +8 -0
  88. data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.js +485 -0
  89. data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.min.js +9 -0
  90. data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.min.js.map +1 -0
  91. data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.tpl.js +14 -0
  92. data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.tpl.min.js +8 -0
  93. data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.js +690 -0
  94. data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.min.js +9 -0
  95. data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.min.js.map +1 -0
  96. data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.tpl.js +14 -0
  97. data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.tpl.min.js +8 -0
  98. data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.js +266 -0
  99. data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.min.js +9 -0
  100. data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.min.js.map +1 -0
  101. data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.tpl.js +14 -0
  102. data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.tpl.min.js +8 -0
  103. data/vendor/assets/javascripts/angular-strap/gulpfile.js +489 -0
  104. data/vendor/assets/javascripts/angular-strap/package.json +73 -0
  105. data/vendor/assets/javascripts/angular-strap/src/affix/affix.js +258 -0
  106. data/vendor/assets/javascripts/angular-strap/src/alert/alert.js +113 -0
  107. data/vendor/assets/javascripts/angular-strap/src/alert/alert.tpl.html +4 -0
  108. data/vendor/assets/javascripts/angular-strap/src/aside/aside.js +89 -0
  109. data/vendor/assets/javascripts/angular-strap/src/aside/aside.tpl.html +14 -0
  110. data/vendor/assets/javascripts/angular-strap/src/button/button.js +174 -0
  111. data/vendor/assets/javascripts/angular-strap/src/collapse/collapse.js +266 -0
  112. data/vendor/assets/javascripts/angular-strap/src/datepicker/datepicker.js +633 -0
  113. data/vendor/assets/javascripts/angular-strap/src/datepicker/datepicker.tpl.html +33 -0
  114. data/vendor/assets/javascripts/angular-strap/src/dropdown/dropdown.js +143 -0
  115. data/vendor/assets/javascripts/angular-strap/src/dropdown/dropdown.tpl.html +6 -0
  116. data/vendor/assets/javascripts/angular-strap/src/helpers/date-formatter.js +54 -0
  117. data/vendor/assets/javascripts/angular-strap/src/helpers/date-parser.js +266 -0
  118. data/vendor/assets/javascripts/angular-strap/src/helpers/debounce.js +55 -0
  119. data/vendor/assets/javascripts/angular-strap/src/helpers/dimensions.js +212 -0
  120. data/vendor/assets/javascripts/angular-strap/src/helpers/parse-options.js +69 -0
  121. data/vendor/assets/javascripts/angular-strap/src/helpers/raf.js +54 -0
  122. data/vendor/assets/javascripts/angular-strap/src/modal/modal.js +348 -0
  123. data/vendor/assets/javascripts/angular-strap/src/modal/modal.tpl.html +14 -0
  124. data/vendor/assets/javascripts/angular-strap/src/module.js +19 -0
  125. data/vendor/assets/javascripts/angular-strap/src/navbar/navbar.js +65 -0
  126. data/vendor/assets/javascripts/angular-strap/src/popover/popover.js +111 -0
  127. data/vendor/assets/javascripts/angular-strap/src/popover/popover.tpl.html +5 -0
  128. data/vendor/assets/javascripts/angular-strap/src/scrollspy/scrollspy.js +254 -0
  129. data/vendor/assets/javascripts/angular-strap/src/select/select.js +321 -0
  130. data/vendor/assets/javascripts/angular-strap/src/select/select.tpl.html +14 -0
  131. data/vendor/assets/javascripts/angular-strap/src/tab/tab.js +183 -0
  132. data/vendor/assets/javascripts/angular-strap/src/tab/tab.tpl.html +7 -0
  133. data/vendor/assets/javascripts/angular-strap/src/timepicker/timepicker.js +493 -0
  134. data/vendor/assets/javascripts/angular-strap/src/timepicker/timepicker.tpl.html +62 -0
  135. data/vendor/assets/javascripts/angular-strap/src/tooltip/tooltip.js +806 -0
  136. data/vendor/assets/javascripts/angular-strap/src/tooltip/tooltip.tpl.html +4 -0
  137. data/vendor/assets/javascripts/angular-strap/src/typeahead/typeahead.js +262 -0
  138. data/vendor/assets/javascripts/angular-strap/src/typeahead/typeahead.tpl.html +5 -0
  139. data/vendor/assets/javascripts/angular/README.md +64 -0
  140. data/vendor/assets/javascripts/angular/angular-csp.css +13 -0
  141. data/vendor/assets/javascripts/angular/angular.js +26181 -0
  142. data/vendor/assets/javascripts/angular/angular.min.js +250 -0
  143. data/vendor/assets/javascripts/angular/angular.min.js.gzip +0 -0
  144. data/vendor/assets/javascripts/angular/angular.min.js.map +8 -0
  145. data/vendor/assets/javascripts/angular/bower.json +8 -0
  146. data/vendor/assets/javascripts/angular/index.js +2 -0
  147. data/vendor/assets/javascripts/angular/package.json +25 -0
  148. metadata +237 -0
@@ -0,0 +1,33 @@
1
+ <div class="dropdown-menu datepicker" ng-class="'datepicker-mode-' + $mode" style="max-width: 320px;">
2
+ <table style="table-layout: fixed; height: 100%; width: 100%;">
3
+ <thead>
4
+ <tr class="text-center">
5
+ <th>
6
+ <button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$selectPane(-1)">
7
+ <i class="{{$iconLeft}}"></i>
8
+ </button>
9
+ </th>
10
+ <th colspan="{{ rows[0].length - 2 }}">
11
+ <button tabindex="-1" type="button" class="btn btn-default btn-block text-strong" ng-click="$toggleMode()">
12
+ <strong style="text-transform: capitalize;" ng-bind="title"></strong>
13
+ </button>
14
+ </th>
15
+ <th>
16
+ <button tabindex="-1" type="button" class="btn btn-default pull-right" ng-click="$selectPane(+1)">
17
+ <i class="{{$iconRight}}"></i>
18
+ </button>
19
+ </th>
20
+ </tr>
21
+ <tr ng-show="showLabels" ng-bind-html="labels"></tr>
22
+ </thead>
23
+ <tbody>
24
+ <tr ng-repeat="(i, row) in rows" height="{{ 100 / rows.length }}%">
25
+ <td class="text-center" ng-repeat="(j, el) in row">
26
+ <button tabindex="-1" type="button" class="btn btn-default" style="width: 100%" ng-class="{'btn-primary': el.selected, 'btn-info btn-today': el.isToday && !el.selected}" ng-click="$select(el.date)" ng-disabled="el.disabled">
27
+ <span ng-class="{'text-muted': el.muted}" ng-bind="el.label"></span>
28
+ </button>
29
+ </td>
30
+ </tr>
31
+ </tbody>
32
+ </table>
33
+ </div>
@@ -0,0 +1,143 @@
1
+ 'use strict';
2
+
3
+ angular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])
4
+
5
+ .provider('$dropdown', function() {
6
+
7
+ var defaults = this.defaults = {
8
+ animation: 'am-fade',
9
+ prefixClass: 'dropdown',
10
+ prefixEvent: 'dropdown',
11
+ placement: 'bottom-left',
12
+ template: 'dropdown/dropdown.tpl.html',
13
+ trigger: 'click',
14
+ container: false,
15
+ keyboard: true,
16
+ html: false,
17
+ delay: 0
18
+ };
19
+
20
+ this.$get = function($window, $rootScope, $tooltip, $timeout) {
21
+
22
+ var bodyEl = angular.element($window.document.body);
23
+ var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;
24
+
25
+ function DropdownFactory(element, config) {
26
+
27
+ var $dropdown = {};
28
+
29
+ // Common vars
30
+ var options = angular.extend({}, defaults, config);
31
+ var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();
32
+
33
+ $dropdown = $tooltip(element, options);
34
+ var parentEl = element.parent();
35
+
36
+ // Protected methods
37
+
38
+ $dropdown.$onKeyDown = function(evt) {
39
+ if (!/(38|40)/.test(evt.keyCode)) return;
40
+ evt.preventDefault();
41
+ evt.stopPropagation();
42
+
43
+ // Retrieve focused index
44
+ var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));
45
+ if(!items.length) return;
46
+ var index;
47
+ angular.forEach(items, function(el, i) {
48
+ if(matchesSelector && matchesSelector.call(el, ':focus')) index = i;
49
+ });
50
+
51
+ // Navigate with keyboard
52
+ if(evt.keyCode === 38 && index > 0) index--;
53
+ else if(evt.keyCode === 40 && index < items.length - 1) index++;
54
+ else if(angular.isUndefined(index)) index = 0;
55
+ items.eq(index)[0].focus();
56
+
57
+ };
58
+
59
+ // Overrides
60
+
61
+ var show = $dropdown.show;
62
+ $dropdown.show = function() {
63
+ show();
64
+ // use timeout to hookup the events to prevent
65
+ // event bubbling from being processed imediately.
66
+ $timeout(function() {
67
+ options.keyboard && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);
68
+ bodyEl.on('click', onBodyClick);
69
+ }, 0, false);
70
+ parentEl.hasClass('dropdown') && parentEl.addClass('open');
71
+ };
72
+
73
+ var hide = $dropdown.hide;
74
+ $dropdown.hide = function() {
75
+ if(!$dropdown.$isShown) return;
76
+ options.keyboard && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);
77
+ bodyEl.off('click', onBodyClick);
78
+ parentEl.hasClass('dropdown') && parentEl.removeClass('open');
79
+ hide();
80
+ };
81
+
82
+ var destroy = $dropdown.destroy;
83
+ $dropdown.destroy = function() {
84
+ bodyEl.off('click', onBodyClick);
85
+ destroy();
86
+ };
87
+
88
+ // Private functions
89
+
90
+ function onBodyClick(evt) {
91
+ if(evt.target === element[0]) return;
92
+ return evt.target !== element[0] && $dropdown.hide();
93
+ }
94
+
95
+ return $dropdown;
96
+
97
+ }
98
+
99
+ return DropdownFactory;
100
+
101
+ };
102
+
103
+ })
104
+
105
+ .directive('bsDropdown', function($window, $sce, $dropdown) {
106
+
107
+ return {
108
+ restrict: 'EAC',
109
+ scope: true,
110
+ link: function postLink(scope, element, attr, transclusion) {
111
+
112
+ // Directive options
113
+ var options = {scope: scope};
114
+ angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', 'id'], function(key) {
115
+ if(angular.isDefined(attr[key])) options[key] = attr[key];
116
+ });
117
+
118
+ // Support scope as an object
119
+ attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {
120
+ scope.content = newValue;
121
+ }, true);
122
+
123
+ // Visibility binding support
124
+ attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {
125
+ if(!dropdown || !angular.isDefined(newValue)) return;
126
+ if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);
127
+ newValue === true ? dropdown.show() : dropdown.hide();
128
+ });
129
+
130
+ // Initialize dropdown
131
+ var dropdown = $dropdown(element, options);
132
+
133
+ // Garbage collection
134
+ scope.$on('$destroy', function() {
135
+ if (dropdown) dropdown.destroy();
136
+ options = null;
137
+ dropdown = null;
138
+ });
139
+
140
+ }
141
+ };
142
+
143
+ });
@@ -0,0 +1,6 @@
1
+ <ul tabindex="-1" class="dropdown-menu" role="menu">
2
+ <li role="presentation" ng-class="{divider: item.divider}" ng-repeat="item in content" >
3
+ <a role="menuitem" tabindex="-1" ng-href="{{item.href}}" ng-if="!item.divider && item.href" target="{{item.target || ''}}" ng-bind="item.text"></a>
4
+ <a role="menuitem" tabindex="-1" href="javascript:void(0)" ng-if="!item.divider && item.click" ng-click="$eval(item.click);$hide()" ng-bind="item.text"></a>
5
+ </li>
6
+ </ul>
@@ -0,0 +1,54 @@
1
+ 'use strict';
2
+
3
+ angular.module('mgcrea.ngStrap.helpers.dateFormatter', [])
4
+
5
+ .service('$dateFormatter', function($locale, dateFilter) {
6
+
7
+ // The unused `lang` arguments are on purpose. The default implementation does not
8
+ // use them and it always uses the locale loaded into the `$locale` service.
9
+ // Custom implementations might use it, thus allowing different directives to
10
+ // have different languages.
11
+
12
+ this.getDefaultLocale = function() {
13
+ return $locale.id;
14
+ };
15
+
16
+ // Format is either a data format name, e.g. "shortTime" or "fullDate", or a date format
17
+ // Return either the corresponding date format or the given date format.
18
+ this.getDatetimeFormat = function(format, lang) {
19
+ return $locale.DATETIME_FORMATS[format] || format;
20
+ };
21
+
22
+ this.weekdaysShort = function(lang) {
23
+ return $locale.DATETIME_FORMATS.SHORTDAY;
24
+ };
25
+
26
+ function splitTimeFormat(format) {
27
+ return /(h+)([:\.])?(m+)[ ]?(a?)/i.exec(format).slice(1);
28
+ }
29
+
30
+ // h:mm a => h
31
+ this.hoursFormat = function(timeFormat) {
32
+ return splitTimeFormat(timeFormat)[0];
33
+ };
34
+
35
+ // h:mm a => mm
36
+ this.minutesFormat = function(timeFormat) {
37
+ return splitTimeFormat(timeFormat)[2];
38
+ };
39
+
40
+ // h:mm a => :
41
+ this.timeSeparator = function(timeFormat) {
42
+ return splitTimeFormat(timeFormat)[1];
43
+ };
44
+
45
+ // h:mm a => true, H.mm => false
46
+ this.showAM = function(timeFormat) {
47
+ return !!splitTimeFormat(timeFormat)[3];
48
+ };
49
+
50
+ this.formatDate = function(date, format, lang){
51
+ return dateFilter(date, format);
52
+ };
53
+
54
+ });
@@ -0,0 +1,266 @@
1
+ 'use strict';
2
+
3
+ angular.module('mgcrea.ngStrap.helpers.dateParser', [])
4
+
5
+ .provider('$dateParser', function($localeProvider) {
6
+
7
+ // define a custom ParseDate object to use instead of native Date
8
+ // to avoid date values wrapping when setting date component values
9
+ function ParseDate() {
10
+ this.year = 1970;
11
+ this.month = 0;
12
+ this.day = 1;
13
+ this.hours = 0;
14
+ this.minutes = 0;
15
+ this.seconds = 0;
16
+ this.milliseconds = 0;
17
+ }
18
+
19
+ ParseDate.prototype.setMilliseconds = function(value) { this.milliseconds = value; };
20
+ ParseDate.prototype.setSeconds = function(value) { this.seconds = value; };
21
+ ParseDate.prototype.setMinutes = function(value) { this.minutes = value; };
22
+ ParseDate.prototype.setHours = function(value) { this.hours = value; };
23
+ ParseDate.prototype.getHours = function() { return this.hours; };
24
+ ParseDate.prototype.setDate = function(value) { this.day = value; };
25
+ ParseDate.prototype.setMonth = function(value) { this.month = value; };
26
+ ParseDate.prototype.setFullYear = function(value) { this.year = value; };
27
+ ParseDate.prototype.fromDate = function(value) {
28
+ this.year = value.getFullYear();
29
+ this.month = value.getMonth();
30
+ this.day = value.getDate();
31
+ this.hours = value.getHours();
32
+ this.minutes = value.getMinutes();
33
+ this.seconds = value.getSeconds();
34
+ this.milliseconds = value.getMilliseconds();
35
+ return this;
36
+ };
37
+
38
+ ParseDate.prototype.toDate = function() {
39
+ return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);
40
+ };
41
+
42
+ var proto = ParseDate.prototype;
43
+
44
+ function noop() {
45
+ }
46
+
47
+ function isNumeric(n) {
48
+ return !isNaN(parseFloat(n)) && isFinite(n);
49
+ }
50
+
51
+ function indexOfCaseInsensitive(array, value) {
52
+ var len = array.length, str=value.toString().toLowerCase();
53
+ for (var i=0; i<len; i++) {
54
+ if (array[i].toLowerCase() === str) { return i; }
55
+ }
56
+ return -1; // Return -1 per the "Array.indexOf()" method.
57
+ }
58
+
59
+ var defaults = this.defaults = {
60
+ format: 'shortDate',
61
+ strict: false
62
+ };
63
+
64
+ this.$get = function($locale, dateFilter) {
65
+
66
+ var DateParserFactory = function(config) {
67
+
68
+ var options = angular.extend({}, defaults, config);
69
+
70
+ var $dateParser = {};
71
+
72
+ var regExpMap = {
73
+ 'sss' : '[0-9]{3}',
74
+ 'ss' : '[0-5][0-9]',
75
+ 's' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',
76
+ 'mm' : '[0-5][0-9]',
77
+ 'm' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',
78
+ 'HH' : '[01][0-9]|2[0-3]',
79
+ 'H' : options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]',
80
+ 'hh' : '[0][1-9]|[1][012]',
81
+ 'h' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',
82
+ 'a' : 'AM|PM',
83
+ 'EEEE' : $locale.DATETIME_FORMATS.DAY.join('|'),
84
+ 'EEE' : $locale.DATETIME_FORMATS.SHORTDAY.join('|'),
85
+ 'dd' : '0[1-9]|[12][0-9]|3[01]',
86
+ 'd' : options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]',
87
+ 'MMMM' : $locale.DATETIME_FORMATS.MONTH.join('|'),
88
+ 'MMM' : $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),
89
+ 'MM' : '0[1-9]|1[012]',
90
+ 'M' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',
91
+ 'yyyy' : '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',
92
+ 'yy' : '[0-9]{2}',
93
+ 'y' : options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}',
94
+ };
95
+
96
+ var setFnMap = {
97
+ 'sss' : proto.setMilliseconds,
98
+ 'ss' : proto.setSeconds,
99
+ 's' : proto.setSeconds,
100
+ 'mm' : proto.setMinutes,
101
+ 'm' : proto.setMinutes,
102
+ 'HH' : proto.setHours,
103
+ 'H' : proto.setHours,
104
+ 'hh' : proto.setHours,
105
+ 'h' : proto.setHours,
106
+ 'EEEE' : noop,
107
+ 'EEE' : noop,
108
+ 'dd' : proto.setDate,
109
+ 'd' : proto.setDate,
110
+ 'a' : function(value) { var hours = this.getHours() % 12; return this.setHours(value.match(/pm/i) ? hours + 12 : hours); },
111
+ 'MMMM' : function(value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); },
112
+ 'MMM' : function(value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); },
113
+ 'MM' : function(value) { return this.setMonth(1 * value - 1); },
114
+ 'M' : function(value) { return this.setMonth(1 * value - 1); },
115
+ 'yyyy' : proto.setFullYear,
116
+ 'yy' : function(value) { return this.setFullYear(2000 + 1 * value); },
117
+ 'y' : proto.setFullYear
118
+ };
119
+
120
+ var regex, setMap;
121
+
122
+ $dateParser.init = function() {
123
+ $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format;
124
+ regex = regExpForFormat($dateParser.$format);
125
+ setMap = setMapForFormat($dateParser.$format);
126
+ };
127
+
128
+ $dateParser.isValid = function(date) {
129
+ if(angular.isDate(date)) return !isNaN(date.getTime());
130
+ return regex.test(date);
131
+ };
132
+
133
+ $dateParser.parse = function(value, baseDate, format) {
134
+ // check for date format special names
135
+ if(format) format = $locale.DATETIME_FORMATS[format] || format;
136
+ if(angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format);
137
+ var formatRegex = format ? regExpForFormat(format) : regex;
138
+ var formatSetMap = format ? setMapForFormat(format) : setMap;
139
+ var matches = formatRegex.exec(value);
140
+ if(!matches) return false;
141
+ // use custom ParseDate object to set parsed values
142
+ var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0));
143
+ for(var i = 0; i < matches.length - 1; i++) {
144
+ formatSetMap[i] && formatSetMap[i].call(date, matches[i+1]);
145
+ }
146
+ // convert back to native Date object
147
+ var newDate = date.toDate();
148
+
149
+ // check new native Date object for day values overflow
150
+ if (parseInt(date.day, 10) !== newDate.getDate()) {
151
+ return false;
152
+ }
153
+
154
+ return newDate;
155
+ };
156
+
157
+ $dateParser.getDateForAttribute = function(key, value) {
158
+ var date;
159
+
160
+ if(value === 'today') {
161
+ var today = new Date();
162
+ date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, (key === 'minDate' ? 0 : -1));
163
+ } else if(angular.isString(value) && value.match(/^".+"$/)) { // Support {{ dateObj }}
164
+ date = new Date(value.substr(1, value.length - 2));
165
+ } else if(isNumeric(value)) {
166
+ date = new Date(parseInt(value, 10));
167
+ } else if (angular.isString(value) && 0 === value.length) { // Reset date
168
+ date = key === 'minDate' ? -Infinity : +Infinity;
169
+ } else {
170
+ date = new Date(value);
171
+ }
172
+
173
+ return date;
174
+ };
175
+
176
+ $dateParser.getTimeForAttribute = function(key, value) {
177
+ var time;
178
+
179
+ if(value === 'now') {
180
+ time = new Date().setFullYear(1970, 0, 1);
181
+ } else if(angular.isString(value) && value.match(/^".+"$/)) {
182
+ time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1);
183
+ } else if(isNumeric(value)) {
184
+ time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1);
185
+ } else if (angular.isString(value) && 0 === value.length) { // Reset time
186
+ time = key === 'minTime' ? -Infinity : +Infinity;
187
+ } else {
188
+ time = $dateParser.parse(value, new Date(1970, 0, 1, 0));
189
+ }
190
+
191
+ return time;
192
+ };
193
+
194
+ /* Handle switch to/from daylight saving.
195
+ * Hours may be non-zero on daylight saving cut-over:
196
+ * > 12 when midnight changeover, but then cannot generate
197
+ * midnight datetime, so jump to 1AM, otherwise reset.
198
+ * @param date (Date) the date to check
199
+ * @return (Date) the corrected date
200
+ *
201
+ * __ copied from jquery ui datepicker __
202
+ */
203
+ $dateParser.daylightSavingAdjust = function(date) {
204
+ if (!date) {
205
+ return null;
206
+ }
207
+ date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
208
+ return date;
209
+ };
210
+
211
+ // Private functions
212
+
213
+ function setMapForFormat(format) {
214
+ var keys = Object.keys(setFnMap), i;
215
+ var map = [], sortedMap = [];
216
+ // Map to setFn
217
+ var clonedFormat = format;
218
+ for(i = 0; i < keys.length; i++) {
219
+ if(format.split(keys[i]).length > 1) {
220
+ var index = clonedFormat.search(keys[i]);
221
+ format = format.split(keys[i]).join('');
222
+ if(setFnMap[keys[i]]) {
223
+ map[index] = setFnMap[keys[i]];
224
+ }
225
+ }
226
+ }
227
+ // Sort result map
228
+ angular.forEach(map, function(v) {
229
+ // conditional required since angular.forEach broke around v1.2.21
230
+ // related pr: https://github.com/angular/angular.js/pull/8525
231
+ if(v) sortedMap.push(v);
232
+ });
233
+ return sortedMap;
234
+ }
235
+
236
+ function escapeReservedSymbols(text) {
237
+ return text.replace(/\//g, '[\\/]').replace('/-/g', '[-]').replace(/\./g, '[.]').replace(/\\s/g, '[\\s]');
238
+ }
239
+
240
+ function regExpForFormat(format) {
241
+ var keys = Object.keys(regExpMap), i;
242
+
243
+ var re = format;
244
+ // Abstract replaces to avoid collisions
245
+ for(i = 0; i < keys.length; i++) {
246
+ re = re.split(keys[i]).join('${' + i + '}');
247
+ }
248
+ // Replace abstracted values
249
+ for(i = 0; i < keys.length; i++) {
250
+ re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');
251
+ }
252
+ format = escapeReservedSymbols(format);
253
+
254
+ return new RegExp('^' + re + '$', ['i']);
255
+ }
256
+
257
+ $dateParser.init();
258
+ return $dateParser;
259
+
260
+ };
261
+
262
+ return DateParserFactory;
263
+
264
+ };
265
+
266
+ });