summaryrefslogtreecommitdiff
path: root/www/lib/ionic-pullup/dist/ion-pullup.js
blob: c558cb93ea0f31c37f1576b01804c439fc133e39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
angular.module('ionic-pullup', [])
  .constant('ionPullUpFooterState', {
      COLLAPSED: 'COLLAPSED',
      MINIMIZED: 'MINIMIZED',
      EXPANDED: 'EXPANDED'
  })
  .constant('ionPullUpFooterBehavior', {
      HIDE: 'HIDE',
      EXPAND: 'EXPAND'
  })
  .directive('ionPullUpFooter', ['$timeout', '$rootScope', '$window', function($timeout, $rootScope, $window) {
      return {
          restrict: 'AE',
          scope: {
              onExpand: '&',
              onCollapse: '&',
              onMinimize: '&'
          },
          controller: ['$scope', '$element', '$attrs', 'ionPullUpFooterState', 'ionPullUpFooterBehavior', function($scope, $element, $attrs, FooterState, FooterBehavior) {
              var
                tabs = document.querySelector('.tabs'),
                hasBottomTabs = document.querySelector('.tabs-bottom'),
                header = document.querySelector('.bar-header'),
                tabsHeight = tabs ? tabs.offsetHeight : 0,
                headerHeight = header ? header.offsetHeight : 0,
                handleHeight = 0,
                footer = {
                    height: 0,
                    posY: 0,
                    lastPosY: 0,
                    state: FooterState.COLLAPSED,
                    defaultHeight : $element[0].offsetHeight,
                    maxHeight: parseInt($attrs.maxHeight, 10) || 0,
                    initialState: $attrs.initialState ? $attrs.initialState.toUpperCase() : FooterState.COLLAPSED,
                    defaultBehavior: $attrs.defaultBehavior ? $attrs.defaultBehavior.toUpperCase() : FooterBehavior.EXPAND
                };

              function init() {
                  $element.css({'-webkit-backface-visibility': 'hidden', 'backface-visibility': 'hidden', 'transition': '300ms ease-in-out', 'padding': 0});
                  if (tabs && hasBottomTabs) {
                      $element.css('bottom', tabs.offsetHeight + 'px');
                  }
              }

              function computeHeights() {
                  footer.height = footer.maxHeight > 0 ? footer.maxHeight : $window.innerHeight - headerHeight - handleHeight - tabsHeight;
                  $element.css({'height': footer.height + 'px'});

                  if (footer.initialState == FooterState.MINIMIZED) {
                      minimize();
                  }  else {
                      collapse();
                  }
              }

              function expand() {
                  footer.lastPosY = 0;
                  $element.css({'-webkit-transform': 'translate3d(0, 0, 0)', 'transform': 'translate3d(0, 0, 0)'});
                  $scope.onExpand();
                  footer.state = FooterState.EXPANDED;
              }

              function collapse() {
                  footer.lastPosY = (tabs && hasBottomTabs) ? footer.height - tabsHeight : footer.height - footer.defaultHeight;
                  $element.css({'-webkit-transform': 'translate3d(0, ' + footer.lastPosY  + 'px, 0)', 'transform': 'translate3d(0, ' + footer.lastPosY  + 'px, 0)'});
                  $scope.onCollapse();
                  footer.state = FooterState.COLLAPSED
              }

              function minimize() {
                  footer.lastPosY = footer.height;
                  $element.css({'-webkit-transform': 'translate3d(0, ' + footer.lastPosY  + 'px, 0)', 'transform': 'translate3d(0, ' + footer.lastPosY  + 'px, 0)'});
                  $scope.onMinimize();
                  footer.state = FooterState.MINIMIZED;
              }


              this.setHandleHeight = function(height) {
                  handleHeight = height;
                  computeHeights();
              };

              this.getHeight = function() {
                  return $element[0].offsetHeight;
              };

              this.getBackground = function() {
                return $window.getComputedStyle($element[0]).background;
              };

              this.onTap = function(e) {
                  e.gesture.srcEvent.preventDefault();
                  e.gesture.preventDefault();

                  if (footer.state == FooterState.COLLAPSED) {
                      if (footer.defaultBehavior == FooterBehavior.HIDE) {
                          minimize();
                      } else {
                          expand();
                      }
                  } else {
                      if (footer.state == FooterState.MINIMIZED) {
                          if (footer.defaultBehavior == FooterBehavior.HIDE)
                              collapse();
                          else
                              expand();
                      } else {
                          // footer is expanded
                          footer.initialState == FooterState.MINIMIZED ? minimize() : collapse();
                      }
                  }

                  $rootScope.$broadcast('ionPullUp:tap', footer.state);
              };

              this.onDrag = function(e) {
                  e.gesture.srcEvent.preventDefault();
                  e.gesture.preventDefault();

                  switch (e.type) {
                      case 'dragstart':
                          $element.css('transition', 'none');
                          break;
                      case 'drag':
                          footer.posY = Math.round(e.gesture.deltaY) + footer.lastPosY;
                          if (footer.posY < 0 || footer.posY > footer.height) return;
                          $element.css({'-webkit-transform': 'translate3d(0, ' + footer.posY + 'px, 0)', 'transform': 'translate3d(0, ' + footer.posY + 'px, 0)'});
                          break;
                      case 'dragend':
                          $element.css({'transition': '300ms ease-in-out'});
                          footer.lastPosY = footer.posY;
                          break;
                  }
              };

              $window.addEventListener('orientationchange', function() {
                    $timeout(function() {
                        computeHeights();
                    }, 500);
              });

              init();
          }],
          compile: function(element, attrs) {
              attrs.defaultHeight && element.css('height', parseInt(attrs.defaultHeight, 10) + 'px');
              element.addClass('bar bar-footer');
          }
      }
  }])
  .directive('ionPullUpContent', [function() {
      return {
          restrict: 'AE',
          require: '^ionPullUpFooter',
          link: function (scope, element, attrs, controller) {
              var
                footerHeight = controller.getHeight();
              element.css({'display': 'block', 'margin-top': footerHeight + 'px', width: '100%'});
              // add scrolling if needed
              if (attrs.scroll && attrs.scroll.toUpperCase() == 'TRUE') {
                  element.css({'overflow-y': 'scroll', 'overflow-x': 'hidden'});
              }
          }
      }
  }])
  .directive('ionPullUpBar', [function() {
      return {
          restrict: 'AE',
          require: '^ionPullUpFooter',
          link: function (scope, element, attrs, controller) {
              var
                footerHeight = controller.getHeight();
              element.css({'display': 'flex', 'height': footerHeight + 'px', position: 'absolute', right: '0', left: '0'});

          }
      }
  }])
  .directive('ionPullUpTrigger', ['$ionicGesture', function($ionicGesture) {
      return {
          restrict: 'AE',
          require: '^ionPullUpFooter',
          link: function (scope, element, attrs, controller) {
              // add gesture
              $ionicGesture.on('tap', controller.onTap, element);
              $ionicGesture.on('drag dragstart dragend', controller.onDrag, element);
          }
      }
  }])
  .directive('ionPullUpHandle', ['$ionicGesture', '$timeout', '$window',  function($ionicGesture, $timeout, $window) {
      return {
          restrict: 'AE',
          require: '^ionPullUpFooter',
          link: function (scope, element, attrs, controller) {
              var height = parseInt(attrs.height,10) || 25, width = parseInt(attrs.width, 10) || 100,
                background =  controller.getBackground(),
                toggleClasses = attrs.toggle;

              controller.setHandleHeight(height);

              element.css({
                  display: 'block',
                  background: background,
                  position: 'absolute',
                  top: 1-height + 'px',
                  left: (($window.innerWidth - width) / 2) + 'px',
                  height: height + 'px',
                  width: width + 'px',
                  //margin: '0 auto',
                  'text-align': 'center'
                  });

              // add gesture
              $ionicGesture.on('tap', controller.onTap, element);
              $ionicGesture.on('drag dragstart dragend', controller.onDrag, element);

              scope.$on('ionPullUp:tap', function() {
                  element.find('i').toggleClass(toggleClasses);
              });

              $window.addEventListener('orientationchange', function() {
                  $timeout(function() {
                      element.css('left', (($window.innerWidth - width) / 2) + 'px');
                  }, 500);
              });
          }
      }
  }]);