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,14 @@
1
+ <div class="modal" tabindex="-1" role="dialog">
2
+ <div class="modal-dialog">
3
+ <div class="modal-content">
4
+ <div class="modal-header" ng-show="title">
5
+ <button type="button" class="close" ng-click="$hide()">&times;</button>
6
+ <h4 class="modal-title" ng-bind="title"></h4>
7
+ </div>
8
+ <div class="modal-body" ng-bind="content"></div>
9
+ <div class="modal-footer">
10
+ <button type="button" class="btn btn-default" ng-click="$hide()">Close</button>
11
+ </div>
12
+ </div>
13
+ </div>
14
+ </div>
@@ -0,0 +1,19 @@
1
+
2
+ angular.module('mgcrea.ngStrap', [
3
+ 'mgcrea.ngStrap.modal',
4
+ 'mgcrea.ngStrap.aside',
5
+ 'mgcrea.ngStrap.alert',
6
+ 'mgcrea.ngStrap.button',
7
+ 'mgcrea.ngStrap.select',
8
+ 'mgcrea.ngStrap.datepicker',
9
+ 'mgcrea.ngStrap.timepicker',
10
+ 'mgcrea.ngStrap.navbar',
11
+ 'mgcrea.ngStrap.tooltip',
12
+ 'mgcrea.ngStrap.popover',
13
+ 'mgcrea.ngStrap.dropdown',
14
+ 'mgcrea.ngStrap.typeahead',
15
+ 'mgcrea.ngStrap.scrollspy',
16
+ 'mgcrea.ngStrap.affix',
17
+ 'mgcrea.ngStrap.tab',
18
+ 'mgcrea.ngStrap.collapse'
19
+ ]);
@@ -0,0 +1,65 @@
1
+ 'use strict';
2
+
3
+ angular.module('mgcrea.ngStrap.navbar', [])
4
+
5
+ .provider('$navbar', function() {
6
+
7
+ var defaults = this.defaults = {
8
+ activeClass: 'active',
9
+ routeAttr: 'data-match-route',
10
+ strict: false
11
+ };
12
+
13
+ this.$get = function() {
14
+ return {defaults: defaults};
15
+ };
16
+
17
+ })
18
+
19
+ .directive('bsNavbar', function($window, $location, $navbar) {
20
+
21
+ var defaults = $navbar.defaults;
22
+
23
+ return {
24
+ restrict: 'A',
25
+ link: function postLink(scope, element, attr, controller) {
26
+
27
+ // Directive options
28
+ var options = angular.copy(defaults);
29
+ angular.forEach(Object.keys(defaults), function(key) {
30
+ if(angular.isDefined(attr[key])) options[key] = attr[key];
31
+ });
32
+
33
+ // Watch for the $location
34
+ scope.$watch(function() {
35
+
36
+ return $location.path();
37
+
38
+ }, function(newValue, oldValue) {
39
+
40
+ var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');
41
+
42
+ angular.forEach(liElements, function(li) {
43
+
44
+ var liElement = angular.element(li);
45
+ var pattern = liElement.attr(options.routeAttr).replace('/', '\\/');
46
+ if(options.strict) {
47
+ pattern = '^' + pattern + '$';
48
+ }
49
+ var regexp = new RegExp(pattern, ['i']);
50
+
51
+ if(regexp.test(newValue)) {
52
+ liElement.addClass(options.activeClass);
53
+ } else {
54
+ liElement.removeClass(options.activeClass);
55
+ }
56
+
57
+ });
58
+
59
+ });
60
+
61
+ }
62
+
63
+ };
64
+
65
+ });
@@ -0,0 +1,111 @@
1
+ 'use strict';
2
+
3
+ angular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])
4
+
5
+ .provider('$popover', function() {
6
+
7
+ var defaults = this.defaults = {
8
+ animation: 'am-fade',
9
+ customClass: '',
10
+ container: false,
11
+ target: false,
12
+ placement: 'right',
13
+ template: 'popover/popover.tpl.html',
14
+ contentTemplate: false,
15
+ trigger: 'click',
16
+ keyboard: true,
17
+ html: false,
18
+ title: '',
19
+ content: '',
20
+ delay: 0,
21
+ autoClose: false
22
+ };
23
+
24
+ this.$get = function($tooltip) {
25
+
26
+ function PopoverFactory(element, config) {
27
+
28
+ // Common vars
29
+ var options = angular.extend({}, defaults, config);
30
+
31
+ var $popover = $tooltip(element, options);
32
+
33
+ // Support scope as string options [/*title, */content]
34
+ if(options.content) {
35
+ $popover.$scope.content = options.content;
36
+ }
37
+
38
+ return $popover;
39
+
40
+ }
41
+
42
+ return PopoverFactory;
43
+
44
+ };
45
+
46
+ })
47
+
48
+ .directive('bsPopover', function($window, $sce, $popover) {
49
+
50
+ var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;
51
+
52
+ return {
53
+ restrict: 'EAC',
54
+ scope: true,
55
+ link: function postLink(scope, element, attr) {
56
+
57
+ // Directive options
58
+ var options = {scope: scope};
59
+ angular.forEach(['template', 'contentTemplate', 'placement', 'container', 'target', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'customClass', 'autoClose', 'id'], function(key) {
60
+ if(angular.isDefined(attr[key])) options[key] = attr[key];
61
+ });
62
+
63
+ // Support scope as data-attrs
64
+ angular.forEach(['title', 'content'], function(key) {
65
+ attr[key] && attr.$observe(key, function(newValue, oldValue) {
66
+ scope[key] = $sce.trustAsHtml(newValue);
67
+ angular.isDefined(oldValue) && requestAnimationFrame(function() {
68
+ popover && popover.$applyPlacement();
69
+ });
70
+ });
71
+ });
72
+
73
+ // Support scope as an object
74
+ attr.bsPopover && scope.$watch(attr.bsPopover, function(newValue, oldValue) {
75
+ if(angular.isObject(newValue)) {
76
+ angular.extend(scope, newValue);
77
+ } else {
78
+ scope.content = newValue;
79
+ }
80
+ angular.isDefined(oldValue) && requestAnimationFrame(function() {
81
+ popover && popover.$applyPlacement();
82
+ });
83
+ }, true);
84
+
85
+ // Visibility binding support
86
+ attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {
87
+ if(!popover || !angular.isDefined(newValue)) return;
88
+ if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);
89
+ newValue === true ? popover.show() : popover.hide();
90
+ });
91
+
92
+ // Viewport support
93
+ attr.viewport && scope.$watch(attr.viewport, function (newValue) {
94
+ if(!popover || !angular.isDefined(newValue)) return;
95
+ popover.setViewport(newValue);
96
+ });
97
+
98
+ // Initialize popover
99
+ var popover = $popover(element, options);
100
+
101
+ // Garbage collection
102
+ scope.$on('$destroy', function() {
103
+ if (popover) popover.destroy();
104
+ options = null;
105
+ popover = null;
106
+ });
107
+
108
+ }
109
+ };
110
+
111
+ });
@@ -0,0 +1,5 @@
1
+ <div class="popover">
2
+ <div class="arrow"></div>
3
+ <h3 class="popover-title" ng-bind="title" ng-show="title"></h3>
4
+ <div class="popover-content" ng-bind="content"></div>
5
+ </div>
@@ -0,0 +1,254 @@
1
+ 'use strict';
2
+
3
+ angular.module('mgcrea.ngStrap.scrollspy', ['mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions'])
4
+
5
+ .provider('$scrollspy', function() {
6
+
7
+ // Pool of registered spies
8
+ var spies = this.$$spies = {};
9
+
10
+ var defaults = this.defaults = {
11
+ debounce: 150,
12
+ throttle: 100,
13
+ offset: 100
14
+ };
15
+
16
+ this.$get = function($window, $document, $rootScope, dimensions, debounce, throttle) {
17
+
18
+ var windowEl = angular.element($window);
19
+ var docEl = angular.element($document.prop('documentElement'));
20
+ var bodyEl = angular.element($window.document.body);
21
+
22
+ // Helper functions
23
+
24
+ function nodeName(element, name) {
25
+ return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase();
26
+ }
27
+
28
+ function ScrollSpyFactory(config) {
29
+
30
+ // Common vars
31
+ var options = angular.extend({}, defaults, config);
32
+ if(!options.element) options.element = bodyEl;
33
+ var isWindowSpy = nodeName(options.element, 'body');
34
+ var scrollEl = isWindowSpy ? windowEl : options.element;
35
+ var scrollId = isWindowSpy ? 'window' : options.id;
36
+
37
+ // Use existing spy
38
+ if(spies[scrollId]) {
39
+ spies[scrollId].$$count++;
40
+ return spies[scrollId];
41
+ }
42
+
43
+ var $scrollspy = {};
44
+
45
+ // Private vars
46
+ var unbindViewContentLoaded, unbindIncludeContentLoaded;
47
+ var trackedElements = $scrollspy.$trackedElements = [];
48
+ var sortedElements = [];
49
+ var activeTarget;
50
+ var debouncedCheckPosition;
51
+ var throttledCheckPosition;
52
+ var debouncedCheckOffsets;
53
+ var viewportHeight;
54
+ var scrollTop;
55
+
56
+ $scrollspy.init = function() {
57
+
58
+ // Setup internal ref counter
59
+ this.$$count = 1;
60
+
61
+ // Bind events
62
+ debouncedCheckPosition = debounce(this.checkPosition, options.debounce);
63
+ throttledCheckPosition = throttle(this.checkPosition, options.throttle);
64
+ scrollEl.on('click', this.checkPositionWithEventLoop);
65
+ windowEl.on('resize', debouncedCheckPosition);
66
+ scrollEl.on('scroll', throttledCheckPosition);
67
+
68
+ debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce);
69
+ unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets);
70
+ unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets);
71
+ debouncedCheckOffsets();
72
+
73
+ // Register spy for reuse
74
+ if(scrollId) {
75
+ spies[scrollId] = $scrollspy;
76
+ }
77
+
78
+ };
79
+
80
+ $scrollspy.destroy = function() {
81
+
82
+ // Check internal ref counter
83
+ this.$$count--;
84
+ if(this.$$count > 0) {
85
+ return;
86
+ }
87
+
88
+ // Unbind events
89
+ scrollEl.off('click', this.checkPositionWithEventLoop);
90
+ windowEl.off('resize', debouncedCheckPosition);
91
+ scrollEl.off('scroll', throttledCheckPosition);
92
+ unbindViewContentLoaded();
93
+ unbindIncludeContentLoaded();
94
+ if (scrollId) {
95
+ delete spies[scrollId];
96
+ }
97
+ };
98
+
99
+ $scrollspy.checkPosition = function() {
100
+
101
+ // Not ready yet
102
+ if(!sortedElements.length) return;
103
+
104
+ // Calculate the scroll position
105
+ scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0;
106
+
107
+ // Calculate the viewport height for use by the components
108
+ viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight'));
109
+
110
+ // Activate first element if scroll is smaller
111
+ if(scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) {
112
+ return $scrollspy.$activateElement(sortedElements[0]);
113
+ }
114
+
115
+ // Activate proper element
116
+ for (var i = sortedElements.length; i--;) {
117
+ if(angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue;
118
+ if(activeTarget === sortedElements[i].target) continue;
119
+ if(scrollTop < sortedElements[i].offsetTop) continue;
120
+ if(sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue;
121
+ return $scrollspy.$activateElement(sortedElements[i]);
122
+ }
123
+
124
+ };
125
+
126
+ $scrollspy.checkPositionWithEventLoop = function() {
127
+ // IE 9 throws an error if we use 'this' instead of '$scrollspy'
128
+ // in this setTimeout call
129
+ setTimeout($scrollspy.checkPosition, 1);
130
+ };
131
+
132
+ // Protected methods
133
+
134
+ $scrollspy.$activateElement = function(element) {
135
+ if(activeTarget) {
136
+ var activeElement = $scrollspy.$getTrackedElement(activeTarget);
137
+ if(activeElement) {
138
+ activeElement.source.removeClass('active');
139
+ if(nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) {
140
+ activeElement.source.parent().parent().removeClass('active');
141
+ }
142
+ }
143
+ }
144
+ activeTarget = element.target;
145
+ element.source.addClass('active');
146
+ if(nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) {
147
+ element.source.parent().parent().addClass('active');
148
+ }
149
+ };
150
+
151
+ $scrollspy.$getTrackedElement = function(target) {
152
+ return trackedElements.filter(function(obj) {
153
+ return obj.target === target;
154
+ })[0];
155
+ };
156
+
157
+ // Track offsets behavior
158
+
159
+ $scrollspy.checkOffsets = function() {
160
+
161
+ angular.forEach(trackedElements, function(trackedElement) {
162
+ var targetElement = document.querySelector(trackedElement.target);
163
+ trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null;
164
+ if(options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1;
165
+ });
166
+
167
+ sortedElements = trackedElements
168
+ .filter(function(el) {
169
+ return el.offsetTop !== null;
170
+ })
171
+ .sort(function(a, b) {
172
+ return a.offsetTop - b.offsetTop;
173
+ });
174
+
175
+ debouncedCheckPosition();
176
+
177
+ };
178
+
179
+ $scrollspy.trackElement = function(target, source) {
180
+ trackedElements.push({target: target, source: source});
181
+ };
182
+
183
+ $scrollspy.untrackElement = function(target, source) {
184
+ var toDelete;
185
+ for (var i = trackedElements.length; i--;) {
186
+ if(trackedElements[i].target === target && trackedElements[i].source === source) {
187
+ toDelete = i;
188
+ break;
189
+ }
190
+ }
191
+ trackedElements = trackedElements.splice(toDelete, 1);
192
+ };
193
+
194
+ $scrollspy.activate = function(i) {
195
+ trackedElements[i].addClass('active');
196
+ };
197
+
198
+ // Initialize plugin
199
+
200
+ $scrollspy.init();
201
+ return $scrollspy;
202
+
203
+ }
204
+
205
+ return ScrollSpyFactory;
206
+
207
+ };
208
+
209
+ })
210
+
211
+ .directive('bsScrollspy', function($rootScope, debounce, dimensions, $scrollspy) {
212
+
213
+ return {
214
+ restrict: 'EAC',
215
+ link: function postLink(scope, element, attr) {
216
+
217
+ var options = {scope: scope};
218
+ angular.forEach(['offset', 'target'], function(key) {
219
+ if(angular.isDefined(attr[key])) options[key] = attr[key];
220
+ });
221
+
222
+ var scrollspy = $scrollspy(options);
223
+ scrollspy.trackElement(options.target, element);
224
+
225
+ scope.$on('$destroy', function() {
226
+ if (scrollspy) {
227
+ scrollspy.untrackElement(options.target, element);
228
+ scrollspy.destroy();
229
+ }
230
+ options = null;
231
+ scrollspy = null;
232
+ });
233
+
234
+ }
235
+ };
236
+
237
+ })
238
+
239
+
240
+ .directive('bsScrollspyList', function($rootScope, debounce, dimensions, $scrollspy) {
241
+
242
+ return {
243
+ restrict: 'A',
244
+ compile: function postLink(element, attr) {
245
+ var children = element[0].querySelectorAll('li > a[href]');
246
+ angular.forEach(children, function(child) {
247
+ var childEl = angular.element(child);
248
+ childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href'));
249
+ });
250
+ }
251
+
252
+ };
253
+
254
+ });