GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Code Duplication    Length = 529-529 lines in 2 locations

third-party/angularjs-modules-plugins/UI-Bootstrap/ui-bootstrap-tpls-1.3.2.js 1 location

@@ 5690-6218 (lines=529) @@
5687
  templateUrl: 'uib/template/timepicker/timepicker.html'
5688
})
5689
5690
.controller('UibTimepickerController', ['$scope', '$element', '$attrs', '$parse', '$log', '$locale', 'uibTimepickerConfig', function($scope, $element, $attrs, $parse, $log, $locale, timepickerConfig) {
5691
  var selected = new Date(),
5692
    watchers = [],
5693
    ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl
5694
    meridians = angular.isDefined($attrs.meridians) ? $scope.$parent.$eval($attrs.meridians) : timepickerConfig.meridians || $locale.DATETIME_FORMATS.AMPMS,
5695
    padHours = angular.isDefined($attrs.padHours) ? $scope.$parent.$eval($attrs.padHours) : true;
5696
5697
  $scope.tabindex = angular.isDefined($attrs.tabindex) ? $attrs.tabindex : 0;
5698
  $element.removeAttr('tabindex');
5699
5700
  this.init = function(ngModelCtrl_, inputs) {
5701
    ngModelCtrl = ngModelCtrl_;
5702
    ngModelCtrl.$render = this.render;
5703
5704
    ngModelCtrl.$formatters.unshift(function(modelValue) {
5705
      return modelValue ? new Date(modelValue) : null;
5706
    });
5707
5708
    var hoursInputEl = inputs.eq(0),
5709
        minutesInputEl = inputs.eq(1),
5710
        secondsInputEl = inputs.eq(2);
5711
5712
    var mousewheel = angular.isDefined($attrs.mousewheel) ? $scope.$parent.$eval($attrs.mousewheel) : timepickerConfig.mousewheel;
5713
5714
    if (mousewheel) {
5715
      this.setupMousewheelEvents(hoursInputEl, minutesInputEl, secondsInputEl);
5716
    }
5717
5718
    var arrowkeys = angular.isDefined($attrs.arrowkeys) ? $scope.$parent.$eval($attrs.arrowkeys) : timepickerConfig.arrowkeys;
5719
    if (arrowkeys) {
5720
      this.setupArrowkeyEvents(hoursInputEl, minutesInputEl, secondsInputEl);
5721
    }
5722
5723
    $scope.readonlyInput = angular.isDefined($attrs.readonlyInput) ? $scope.$parent.$eval($attrs.readonlyInput) : timepickerConfig.readonlyInput;
5724
    this.setupInputEvents(hoursInputEl, minutesInputEl, secondsInputEl);
5725
  };
5726
5727
  var hourStep = timepickerConfig.hourStep;
5728
  if ($attrs.hourStep) {
5729
    watchers.push($scope.$parent.$watch($parse($attrs.hourStep), function(value) {
5730
      hourStep = +value;
5731
    }));
5732
  }
5733
5734
  var minuteStep = timepickerConfig.minuteStep;
5735
  if ($attrs.minuteStep) {
5736
    watchers.push($scope.$parent.$watch($parse($attrs.minuteStep), function(value) {
5737
      minuteStep = +value;
5738
    }));
5739
  }
5740
5741
  var min;
5742
  watchers.push($scope.$parent.$watch($parse($attrs.min), function(value) {
5743
    var dt = new Date(value);
5744
    min = isNaN(dt) ? undefined : dt;
5745
  }));
5746
5747
  var max;
5748
  watchers.push($scope.$parent.$watch($parse($attrs.max), function(value) {
5749
    var dt = new Date(value);
5750
    max = isNaN(dt) ? undefined : dt;
5751
  }));
5752
5753
  var disabled = false;
5754
  if ($attrs.ngDisabled) {
5755
    watchers.push($scope.$parent.$watch($parse($attrs.ngDisabled), function(value) {
5756
      disabled = value;
5757
    }));
5758
  }
5759
5760
  $scope.noIncrementHours = function() {
5761
    var incrementedSelected = addMinutes(selected, hourStep * 60);
5762
    return disabled || incrementedSelected > max ||
5763
      incrementedSelected < selected && incrementedSelected < min;
5764
  };
5765
5766
  $scope.noDecrementHours = function() {
5767
    var decrementedSelected = addMinutes(selected, -hourStep * 60);
5768
    return disabled || decrementedSelected < min ||
5769
      decrementedSelected > selected && decrementedSelected > max;
5770
  };
5771
5772
  $scope.noIncrementMinutes = function() {
5773
    var incrementedSelected = addMinutes(selected, minuteStep);
5774
    return disabled || incrementedSelected > max ||
5775
      incrementedSelected < selected && incrementedSelected < min;
5776
  };
5777
5778
  $scope.noDecrementMinutes = function() {
5779
    var decrementedSelected = addMinutes(selected, -minuteStep);
5780
    return disabled || decrementedSelected < min ||
5781
      decrementedSelected > selected && decrementedSelected > max;
5782
  };
5783
5784
  $scope.noIncrementSeconds = function() {
5785
    var incrementedSelected = addSeconds(selected, secondStep);
5786
    return disabled || incrementedSelected > max ||
5787
      incrementedSelected < selected && incrementedSelected < min;
5788
  };
5789
5790
  $scope.noDecrementSeconds = function() {
5791
    var decrementedSelected = addSeconds(selected, -secondStep);
5792
    return disabled || decrementedSelected < min ||
5793
      decrementedSelected > selected && decrementedSelected > max;
5794
  };
5795
5796
  $scope.noToggleMeridian = function() {
5797
    if (selected.getHours() < 12) {
5798
      return disabled || addMinutes(selected, 12 * 60) > max;
5799
    }
5800
5801
    return disabled || addMinutes(selected, -12 * 60) < min;
5802
  };
5803
5804
  var secondStep = timepickerConfig.secondStep;
5805
  if ($attrs.secondStep) {
5806
    watchers.push($scope.$parent.$watch($parse($attrs.secondStep), function(value) {
5807
      secondStep = +value;
5808
    }));
5809
  }
5810
5811
  $scope.showSeconds = timepickerConfig.showSeconds;
5812
  if ($attrs.showSeconds) {
5813
    watchers.push($scope.$parent.$watch($parse($attrs.showSeconds), function(value) {
5814
      $scope.showSeconds = !!value;
5815
    }));
5816
  }
5817
5818
  // 12H / 24H mode
5819
  $scope.showMeridian = timepickerConfig.showMeridian;
5820
  if ($attrs.showMeridian) {
5821
    watchers.push($scope.$parent.$watch($parse($attrs.showMeridian), function(value) {
5822
      $scope.showMeridian = !!value;
5823
5824
      if (ngModelCtrl.$error.time) {
5825
        // Evaluate from template
5826
        var hours = getHoursFromTemplate(), minutes = getMinutesFromTemplate();
5827
        if (angular.isDefined(hours) && angular.isDefined(minutes)) {
5828
          selected.setHours(hours);
5829
          refresh();
5830
        }
5831
      } else {
5832
        updateTemplate();
5833
      }
5834
    }));
5835
  }
5836
5837
  // Get $scope.hours in 24H mode if valid
5838
  function getHoursFromTemplate() {
5839
    var hours = +$scope.hours;
5840
    var valid = $scope.showMeridian ? hours > 0 && hours < 13 :
5841
      hours >= 0 && hours < 24;
5842
    if (!valid || $scope.hours === '') {
5843
      return undefined;
5844
    }
5845
5846
    if ($scope.showMeridian) {
5847
      if (hours === 12) {
5848
        hours = 0;
5849
      }
5850
      if ($scope.meridian === meridians[1]) {
5851
        hours = hours + 12;
5852
      }
5853
    }
5854
    return hours;
5855
  }
5856
5857
  function getMinutesFromTemplate() {
5858
    var minutes = +$scope.minutes;
5859
    var valid = minutes >= 0 && minutes < 60;
5860
    if (!valid || $scope.minutes === '') {
5861
      return undefined;
5862
    }
5863
    return minutes;
5864
  }
5865
5866
  function getSecondsFromTemplate() {
5867
    var seconds = +$scope.seconds;
5868
    return seconds >= 0 && seconds < 60 ? seconds : undefined;
5869
  }
5870
5871
  function pad(value, noPad) {
5872
    if (value === null) {
5873
      return '';
5874
    }
5875
5876
    return angular.isDefined(value) && value.toString().length < 2 && !noPad ?
5877
      '0' + value : value.toString();
5878
  }
5879
5880
  // Respond on mousewheel spin
5881
  this.setupMousewheelEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) {
5882
    var isScrollingUp = function(e) {
5883
      if (e.originalEvent) {
5884
        e = e.originalEvent;
5885
      }
5886
      //pick correct delta variable depending on event
5887
      var delta = e.wheelDelta ? e.wheelDelta : -e.deltaY;
5888
      return e.detail || delta > 0;
5889
    };
5890
5891
    hoursInputEl.bind('mousewheel wheel', function(e) {
5892
      if (!disabled) {
5893
        $scope.$apply(isScrollingUp(e) ? $scope.incrementHours() : $scope.decrementHours());
5894
      }
5895
      e.preventDefault();
5896
    });
5897
5898
    minutesInputEl.bind('mousewheel wheel', function(e) {
5899
      if (!disabled) {
5900
        $scope.$apply(isScrollingUp(e) ? $scope.incrementMinutes() : $scope.decrementMinutes());
5901
      }
5902
      e.preventDefault();
5903
    });
5904
5905
     secondsInputEl.bind('mousewheel wheel', function(e) {
5906
      if (!disabled) {
5907
        $scope.$apply(isScrollingUp(e) ? $scope.incrementSeconds() : $scope.decrementSeconds());
5908
      }
5909
      e.preventDefault();
5910
    });
5911
  };
5912
5913
  // Respond on up/down arrowkeys
5914
  this.setupArrowkeyEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) {
5915
    hoursInputEl.bind('keydown', function(e) {
5916
      if (!disabled) {
5917
        if (e.which === 38) { // up
5918
          e.preventDefault();
5919
          $scope.incrementHours();
5920
          $scope.$apply();
5921
        } else if (e.which === 40) { // down
5922
          e.preventDefault();
5923
          $scope.decrementHours();
5924
          $scope.$apply();
5925
        }
5926
      }
5927
    });
5928
5929
    minutesInputEl.bind('keydown', function(e) {
5930
      if (!disabled) {
5931
        if (e.which === 38) { // up
5932
          e.preventDefault();
5933
          $scope.incrementMinutes();
5934
          $scope.$apply();
5935
        } else if (e.which === 40) { // down
5936
          e.preventDefault();
5937
          $scope.decrementMinutes();
5938
          $scope.$apply();
5939
        }
5940
      }
5941
    });
5942
5943
    secondsInputEl.bind('keydown', function(e) {
5944
      if (!disabled) {
5945
        if (e.which === 38) { // up
5946
          e.preventDefault();
5947
          $scope.incrementSeconds();
5948
          $scope.$apply();
5949
        } else if (e.which === 40) { // down
5950
          e.preventDefault();
5951
          $scope.decrementSeconds();
5952
          $scope.$apply();
5953
        }
5954
      }
5955
    });
5956
  };
5957
5958
  this.setupInputEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) {
5959
    if ($scope.readonlyInput) {
5960
      $scope.updateHours = angular.noop;
5961
      $scope.updateMinutes = angular.noop;
5962
      $scope.updateSeconds = angular.noop;
5963
      return;
5964
    }
5965
5966
    var invalidate = function(invalidHours, invalidMinutes, invalidSeconds) {
5967
      ngModelCtrl.$setViewValue(null);
5968
      ngModelCtrl.$setValidity('time', false);
5969
      if (angular.isDefined(invalidHours)) {
5970
        $scope.invalidHours = invalidHours;
5971
      }
5972
5973
      if (angular.isDefined(invalidMinutes)) {
5974
        $scope.invalidMinutes = invalidMinutes;
5975
      }
5976
5977
      if (angular.isDefined(invalidSeconds)) {
5978
        $scope.invalidSeconds = invalidSeconds;
5979
      }
5980
    };
5981
5982
    $scope.updateHours = function() {
5983
      var hours = getHoursFromTemplate(),
5984
        minutes = getMinutesFromTemplate();
5985
5986
      ngModelCtrl.$setDirty();
5987
5988
      if (angular.isDefined(hours) && angular.isDefined(minutes)) {
5989
        selected.setHours(hours);
5990
        selected.setMinutes(minutes);
5991
        if (selected < min || selected > max) {
5992
          invalidate(true);
5993
        } else {
5994
          refresh('h');
5995
        }
5996
      } else {
5997
        invalidate(true);
5998
      }
5999
    };
6000
6001
    hoursInputEl.bind('blur', function(e) {
6002
      ngModelCtrl.$setTouched();
6003
      if (modelIsEmpty()) {
6004
        makeValid();
6005
      } else if ($scope.hours === null || $scope.hours === '') {
6006
        invalidate(true);
6007
      } else if (!$scope.invalidHours && $scope.hours < 10) {
6008
        $scope.$apply(function() {
6009
          $scope.hours = pad($scope.hours, !padHours);
6010
        });
6011
      }
6012
    });
6013
6014
    $scope.updateMinutes = function() {
6015
      var minutes = getMinutesFromTemplate(),
6016
        hours = getHoursFromTemplate();
6017
6018
      ngModelCtrl.$setDirty();
6019
6020
      if (angular.isDefined(minutes) && angular.isDefined(hours)) {
6021
        selected.setHours(hours);
6022
        selected.setMinutes(minutes);
6023
        if (selected < min || selected > max) {
6024
          invalidate(undefined, true);
6025
        } else {
6026
          refresh('m');
6027
        }
6028
      } else {
6029
        invalidate(undefined, true);
6030
      }
6031
    };
6032
6033
    minutesInputEl.bind('blur', function(e) {
6034
      ngModelCtrl.$setTouched();
6035
      if (modelIsEmpty()) {
6036
        makeValid();
6037
      } else if ($scope.minutes === null) {
6038
        invalidate(undefined, true);
6039
      } else if (!$scope.invalidMinutes && $scope.minutes < 10) {
6040
        $scope.$apply(function() {
6041
          $scope.minutes = pad($scope.minutes);
6042
        });
6043
      }
6044
    });
6045
6046
    $scope.updateSeconds = function() {
6047
      var seconds = getSecondsFromTemplate();
6048
6049
      ngModelCtrl.$setDirty();
6050
6051
      if (angular.isDefined(seconds)) {
6052
        selected.setSeconds(seconds);
6053
        refresh('s');
6054
      } else {
6055
        invalidate(undefined, undefined, true);
6056
      }
6057
    };
6058
6059
    secondsInputEl.bind('blur', function(e) {
6060
      if (modelIsEmpty()) {
6061
        makeValid();
6062
      } else if (!$scope.invalidSeconds && $scope.seconds < 10) {
6063
        $scope.$apply( function() {
6064
          $scope.seconds = pad($scope.seconds);
6065
        });
6066
      }
6067
    });
6068
6069
  };
6070
6071
  this.render = function() {
6072
    var date = ngModelCtrl.$viewValue;
6073
6074
    if (isNaN(date)) {
6075
      ngModelCtrl.$setValidity('time', false);
6076
      $log.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
6077
    } else {
6078
      if (date) {
6079
        selected = date;
6080
      }
6081
6082
      if (selected < min || selected > max) {
6083
        ngModelCtrl.$setValidity('time', false);
6084
        $scope.invalidHours = true;
6085
        $scope.invalidMinutes = true;
6086
      } else {
6087
        makeValid();
6088
      }
6089
      updateTemplate();
6090
    }
6091
  };
6092
6093
  // Call internally when we know that model is valid.
6094
  function refresh(keyboardChange) {
6095
    makeValid();
6096
    ngModelCtrl.$setViewValue(new Date(selected));
6097
    updateTemplate(keyboardChange);
6098
  }
6099
6100
  function makeValid() {
6101
    ngModelCtrl.$setValidity('time', true);
6102
    $scope.invalidHours = false;
6103
    $scope.invalidMinutes = false;
6104
    $scope.invalidSeconds = false;
6105
  }
6106
6107
  function updateTemplate(keyboardChange) {
6108
    if (!ngModelCtrl.$modelValue) {
6109
      $scope.hours = null;
6110
      $scope.minutes = null;
6111
      $scope.seconds = null;
6112
      $scope.meridian = meridians[0];
6113
    } else {
6114
      var hours = selected.getHours(),
6115
        minutes = selected.getMinutes(),
6116
        seconds = selected.getSeconds();
6117
6118
      if ($scope.showMeridian) {
6119
        hours = hours === 0 || hours === 12 ? 12 : hours % 12; // Convert 24 to 12 hour system
6120
      }
6121
6122
      $scope.hours = keyboardChange === 'h' ? hours : pad(hours, !padHours);
6123
      if (keyboardChange !== 'm') {
6124
        $scope.minutes = pad(minutes);
6125
      }
6126
      $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
6127
6128
      if (keyboardChange !== 's') {
6129
        $scope.seconds = pad(seconds);
6130
      }
6131
      $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
6132
    }
6133
  }
6134
6135
  function addSecondsToSelected(seconds) {
6136
    selected = addSeconds(selected, seconds);
6137
    refresh();
6138
  }
6139
6140
  function addMinutes(selected, minutes) {
6141
    return addSeconds(selected, minutes*60);
6142
  }
6143
6144
  function addSeconds(date, seconds) {
6145
    var dt = new Date(date.getTime() + seconds * 1000);
6146
    var newDate = new Date(date);
6147
    newDate.setHours(dt.getHours(), dt.getMinutes(), dt.getSeconds());
6148
    return newDate;
6149
  }
6150
6151
  function modelIsEmpty() {
6152
    return ($scope.hours === null || $scope.hours === '') &&
6153
      ($scope.minutes === null || $scope.minutes === '') &&
6154
      (!$scope.showSeconds || $scope.showSeconds && ($scope.seconds === null || $scope.seconds === ''));
6155
  }
6156
6157
  $scope.showSpinners = angular.isDefined($attrs.showSpinners) ?
6158
    $scope.$parent.$eval($attrs.showSpinners) : timepickerConfig.showSpinners;
6159
6160
  $scope.incrementHours = function() {
6161
    if (!$scope.noIncrementHours()) {
6162
      addSecondsToSelected(hourStep * 60 * 60);
6163
    }
6164
  };
6165
6166
  $scope.decrementHours = function() {
6167
    if (!$scope.noDecrementHours()) {
6168
      addSecondsToSelected(-hourStep * 60 * 60);
6169
    }
6170
  };
6171
6172
  $scope.incrementMinutes = function() {
6173
    if (!$scope.noIncrementMinutes()) {
6174
      addSecondsToSelected(minuteStep * 60);
6175
    }
6176
  };
6177
6178
  $scope.decrementMinutes = function() {
6179
    if (!$scope.noDecrementMinutes()) {
6180
      addSecondsToSelected(-minuteStep * 60);
6181
    }
6182
  };
6183
6184
  $scope.incrementSeconds = function() {
6185
    if (!$scope.noIncrementSeconds()) {
6186
      addSecondsToSelected(secondStep);
6187
    }
6188
  };
6189
6190
  $scope.decrementSeconds = function() {
6191
    if (!$scope.noDecrementSeconds()) {
6192
      addSecondsToSelected(-secondStep);
6193
    }
6194
  };
6195
6196
  $scope.toggleMeridian = function() {
6197
    var minutes = getMinutesFromTemplate(),
6198
        hours = getHoursFromTemplate();
6199
6200
    if (!$scope.noToggleMeridian()) {
6201
      if (angular.isDefined(minutes) && angular.isDefined(hours)) {
6202
        addSecondsToSelected(12 * 60 * (selected.getHours() < 12 ? 60 : -60));
6203
      } else {
6204
        $scope.meridian = $scope.meridian === meridians[0] ? meridians[1] : meridians[0];
6205
      }
6206
    }
6207
  };
6208
6209
  $scope.blur = function() {
6210
    ngModelCtrl.$setTouched();
6211
  };
6212
6213
  $scope.$on('$destroy', function() {
6214
    while (watchers.length) {
6215
      watchers.shift()();
6216
    }
6217
  });
6218
}])
6219
6220
.directive('uibTimepicker', ['uibTimepickerConfig', function(uibTimepickerConfig) {
6221
  return {

third-party/angularjs-modules-plugins/UI-Bootstrap/ui-bootstrap-1.3.2.js 1 location

@@ 5689-6217 (lines=529) @@
5686
  templateUrl: 'uib/template/timepicker/timepicker.html'
5687
})
5688
5689
.controller('UibTimepickerController', ['$scope', '$element', '$attrs', '$parse', '$log', '$locale', 'uibTimepickerConfig', function($scope, $element, $attrs, $parse, $log, $locale, timepickerConfig) {
5690
  var selected = new Date(),
5691
    watchers = [],
5692
    ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl
5693
    meridians = angular.isDefined($attrs.meridians) ? $scope.$parent.$eval($attrs.meridians) : timepickerConfig.meridians || $locale.DATETIME_FORMATS.AMPMS,
5694
    padHours = angular.isDefined($attrs.padHours) ? $scope.$parent.$eval($attrs.padHours) : true;
5695
5696
  $scope.tabindex = angular.isDefined($attrs.tabindex) ? $attrs.tabindex : 0;
5697
  $element.removeAttr('tabindex');
5698
5699
  this.init = function(ngModelCtrl_, inputs) {
5700
    ngModelCtrl = ngModelCtrl_;
5701
    ngModelCtrl.$render = this.render;
5702
5703
    ngModelCtrl.$formatters.unshift(function(modelValue) {
5704
      return modelValue ? new Date(modelValue) : null;
5705
    });
5706
5707
    var hoursInputEl = inputs.eq(0),
5708
        minutesInputEl = inputs.eq(1),
5709
        secondsInputEl = inputs.eq(2);
5710
5711
    var mousewheel = angular.isDefined($attrs.mousewheel) ? $scope.$parent.$eval($attrs.mousewheel) : timepickerConfig.mousewheel;
5712
5713
    if (mousewheel) {
5714
      this.setupMousewheelEvents(hoursInputEl, minutesInputEl, secondsInputEl);
5715
    }
5716
5717
    var arrowkeys = angular.isDefined($attrs.arrowkeys) ? $scope.$parent.$eval($attrs.arrowkeys) : timepickerConfig.arrowkeys;
5718
    if (arrowkeys) {
5719
      this.setupArrowkeyEvents(hoursInputEl, minutesInputEl, secondsInputEl);
5720
    }
5721
5722
    $scope.readonlyInput = angular.isDefined($attrs.readonlyInput) ? $scope.$parent.$eval($attrs.readonlyInput) : timepickerConfig.readonlyInput;
5723
    this.setupInputEvents(hoursInputEl, minutesInputEl, secondsInputEl);
5724
  };
5725
5726
  var hourStep = timepickerConfig.hourStep;
5727
  if ($attrs.hourStep) {
5728
    watchers.push($scope.$parent.$watch($parse($attrs.hourStep), function(value) {
5729
      hourStep = +value;
5730
    }));
5731
  }
5732
5733
  var minuteStep = timepickerConfig.minuteStep;
5734
  if ($attrs.minuteStep) {
5735
    watchers.push($scope.$parent.$watch($parse($attrs.minuteStep), function(value) {
5736
      minuteStep = +value;
5737
    }));
5738
  }
5739
5740
  var min;
5741
  watchers.push($scope.$parent.$watch($parse($attrs.min), function(value) {
5742
    var dt = new Date(value);
5743
    min = isNaN(dt) ? undefined : dt;
5744
  }));
5745
5746
  var max;
5747
  watchers.push($scope.$parent.$watch($parse($attrs.max), function(value) {
5748
    var dt = new Date(value);
5749
    max = isNaN(dt) ? undefined : dt;
5750
  }));
5751
5752
  var disabled = false;
5753
  if ($attrs.ngDisabled) {
5754
    watchers.push($scope.$parent.$watch($parse($attrs.ngDisabled), function(value) {
5755
      disabled = value;
5756
    }));
5757
  }
5758
5759
  $scope.noIncrementHours = function() {
5760
    var incrementedSelected = addMinutes(selected, hourStep * 60);
5761
    return disabled || incrementedSelected > max ||
5762
      incrementedSelected < selected && incrementedSelected < min;
5763
  };
5764
5765
  $scope.noDecrementHours = function() {
5766
    var decrementedSelected = addMinutes(selected, -hourStep * 60);
5767
    return disabled || decrementedSelected < min ||
5768
      decrementedSelected > selected && decrementedSelected > max;
5769
  };
5770
5771
  $scope.noIncrementMinutes = function() {
5772
    var incrementedSelected = addMinutes(selected, minuteStep);
5773
    return disabled || incrementedSelected > max ||
5774
      incrementedSelected < selected && incrementedSelected < min;
5775
  };
5776
5777
  $scope.noDecrementMinutes = function() {
5778
    var decrementedSelected = addMinutes(selected, -minuteStep);
5779
    return disabled || decrementedSelected < min ||
5780
      decrementedSelected > selected && decrementedSelected > max;
5781
  };
5782
5783
  $scope.noIncrementSeconds = function() {
5784
    var incrementedSelected = addSeconds(selected, secondStep);
5785
    return disabled || incrementedSelected > max ||
5786
      incrementedSelected < selected && incrementedSelected < min;
5787
  };
5788
5789
  $scope.noDecrementSeconds = function() {
5790
    var decrementedSelected = addSeconds(selected, -secondStep);
5791
    return disabled || decrementedSelected < min ||
5792
      decrementedSelected > selected && decrementedSelected > max;
5793
  };
5794
5795
  $scope.noToggleMeridian = function() {
5796
    if (selected.getHours() < 12) {
5797
      return disabled || addMinutes(selected, 12 * 60) > max;
5798
    }
5799
5800
    return disabled || addMinutes(selected, -12 * 60) < min;
5801
  };
5802
5803
  var secondStep = timepickerConfig.secondStep;
5804
  if ($attrs.secondStep) {
5805
    watchers.push($scope.$parent.$watch($parse($attrs.secondStep), function(value) {
5806
      secondStep = +value;
5807
    }));
5808
  }
5809
5810
  $scope.showSeconds = timepickerConfig.showSeconds;
5811
  if ($attrs.showSeconds) {
5812
    watchers.push($scope.$parent.$watch($parse($attrs.showSeconds), function(value) {
5813
      $scope.showSeconds = !!value;
5814
    }));
5815
  }
5816
5817
  // 12H / 24H mode
5818
  $scope.showMeridian = timepickerConfig.showMeridian;
5819
  if ($attrs.showMeridian) {
5820
    watchers.push($scope.$parent.$watch($parse($attrs.showMeridian), function(value) {
5821
      $scope.showMeridian = !!value;
5822
5823
      if (ngModelCtrl.$error.time) {
5824
        // Evaluate from template
5825
        var hours = getHoursFromTemplate(), minutes = getMinutesFromTemplate();
5826
        if (angular.isDefined(hours) && angular.isDefined(minutes)) {
5827
          selected.setHours(hours);
5828
          refresh();
5829
        }
5830
      } else {
5831
        updateTemplate();
5832
      }
5833
    }));
5834
  }
5835
5836
  // Get $scope.hours in 24H mode if valid
5837
  function getHoursFromTemplate() {
5838
    var hours = +$scope.hours;
5839
    var valid = $scope.showMeridian ? hours > 0 && hours < 13 :
5840
      hours >= 0 && hours < 24;
5841
    if (!valid || $scope.hours === '') {
5842
      return undefined;
5843
    }
5844
5845
    if ($scope.showMeridian) {
5846
      if (hours === 12) {
5847
        hours = 0;
5848
      }
5849
      if ($scope.meridian === meridians[1]) {
5850
        hours = hours + 12;
5851
      }
5852
    }
5853
    return hours;
5854
  }
5855
5856
  function getMinutesFromTemplate() {
5857
    var minutes = +$scope.minutes;
5858
    var valid = minutes >= 0 && minutes < 60;
5859
    if (!valid || $scope.minutes === '') {
5860
      return undefined;
5861
    }
5862
    return minutes;
5863
  }
5864
5865
  function getSecondsFromTemplate() {
5866
    var seconds = +$scope.seconds;
5867
    return seconds >= 0 && seconds < 60 ? seconds : undefined;
5868
  }
5869
5870
  function pad(value, noPad) {
5871
    if (value === null) {
5872
      return '';
5873
    }
5874
5875
    return angular.isDefined(value) && value.toString().length < 2 && !noPad ?
5876
      '0' + value : value.toString();
5877
  }
5878
5879
  // Respond on mousewheel spin
5880
  this.setupMousewheelEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) {
5881
    var isScrollingUp = function(e) {
5882
      if (e.originalEvent) {
5883
        e = e.originalEvent;
5884
      }
5885
      //pick correct delta variable depending on event
5886
      var delta = e.wheelDelta ? e.wheelDelta : -e.deltaY;
5887
      return e.detail || delta > 0;
5888
    };
5889
5890
    hoursInputEl.bind('mousewheel wheel', function(e) {
5891
      if (!disabled) {
5892
        $scope.$apply(isScrollingUp(e) ? $scope.incrementHours() : $scope.decrementHours());
5893
      }
5894
      e.preventDefault();
5895
    });
5896
5897
    minutesInputEl.bind('mousewheel wheel', function(e) {
5898
      if (!disabled) {
5899
        $scope.$apply(isScrollingUp(e) ? $scope.incrementMinutes() : $scope.decrementMinutes());
5900
      }
5901
      e.preventDefault();
5902
    });
5903
5904
     secondsInputEl.bind('mousewheel wheel', function(e) {
5905
      if (!disabled) {
5906
        $scope.$apply(isScrollingUp(e) ? $scope.incrementSeconds() : $scope.decrementSeconds());
5907
      }
5908
      e.preventDefault();
5909
    });
5910
  };
5911
5912
  // Respond on up/down arrowkeys
5913
  this.setupArrowkeyEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) {
5914
    hoursInputEl.bind('keydown', function(e) {
5915
      if (!disabled) {
5916
        if (e.which === 38) { // up
5917
          e.preventDefault();
5918
          $scope.incrementHours();
5919
          $scope.$apply();
5920
        } else if (e.which === 40) { // down
5921
          e.preventDefault();
5922
          $scope.decrementHours();
5923
          $scope.$apply();
5924
        }
5925
      }
5926
    });
5927
5928
    minutesInputEl.bind('keydown', function(e) {
5929
      if (!disabled) {
5930
        if (e.which === 38) { // up
5931
          e.preventDefault();
5932
          $scope.incrementMinutes();
5933
          $scope.$apply();
5934
        } else if (e.which === 40) { // down
5935
          e.preventDefault();
5936
          $scope.decrementMinutes();
5937
          $scope.$apply();
5938
        }
5939
      }
5940
    });
5941
5942
    secondsInputEl.bind('keydown', function(e) {
5943
      if (!disabled) {
5944
        if (e.which === 38) { // up
5945
          e.preventDefault();
5946
          $scope.incrementSeconds();
5947
          $scope.$apply();
5948
        } else if (e.which === 40) { // down
5949
          e.preventDefault();
5950
          $scope.decrementSeconds();
5951
          $scope.$apply();
5952
        }
5953
      }
5954
    });
5955
  };
5956
5957
  this.setupInputEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) {
5958
    if ($scope.readonlyInput) {
5959
      $scope.updateHours = angular.noop;
5960
      $scope.updateMinutes = angular.noop;
5961
      $scope.updateSeconds = angular.noop;
5962
      return;
5963
    }
5964
5965
    var invalidate = function(invalidHours, invalidMinutes, invalidSeconds) {
5966
      ngModelCtrl.$setViewValue(null);
5967
      ngModelCtrl.$setValidity('time', false);
5968
      if (angular.isDefined(invalidHours)) {
5969
        $scope.invalidHours = invalidHours;
5970
      }
5971
5972
      if (angular.isDefined(invalidMinutes)) {
5973
        $scope.invalidMinutes = invalidMinutes;
5974
      }
5975
5976
      if (angular.isDefined(invalidSeconds)) {
5977
        $scope.invalidSeconds = invalidSeconds;
5978
      }
5979
    };
5980
5981
    $scope.updateHours = function() {
5982
      var hours = getHoursFromTemplate(),
5983
        minutes = getMinutesFromTemplate();
5984
5985
      ngModelCtrl.$setDirty();
5986
5987
      if (angular.isDefined(hours) && angular.isDefined(minutes)) {
5988
        selected.setHours(hours);
5989
        selected.setMinutes(minutes);
5990
        if (selected < min || selected > max) {
5991
          invalidate(true);
5992
        } else {
5993
          refresh('h');
5994
        }
5995
      } else {
5996
        invalidate(true);
5997
      }
5998
    };
5999
6000
    hoursInputEl.bind('blur', function(e) {
6001
      ngModelCtrl.$setTouched();
6002
      if (modelIsEmpty()) {
6003
        makeValid();
6004
      } else if ($scope.hours === null || $scope.hours === '') {
6005
        invalidate(true);
6006
      } else if (!$scope.invalidHours && $scope.hours < 10) {
6007
        $scope.$apply(function() {
6008
          $scope.hours = pad($scope.hours, !padHours);
6009
        });
6010
      }
6011
    });
6012
6013
    $scope.updateMinutes = function() {
6014
      var minutes = getMinutesFromTemplate(),
6015
        hours = getHoursFromTemplate();
6016
6017
      ngModelCtrl.$setDirty();
6018
6019
      if (angular.isDefined(minutes) && angular.isDefined(hours)) {
6020
        selected.setHours(hours);
6021
        selected.setMinutes(minutes);
6022
        if (selected < min || selected > max) {
6023
          invalidate(undefined, true);
6024
        } else {
6025
          refresh('m');
6026
        }
6027
      } else {
6028
        invalidate(undefined, true);
6029
      }
6030
    };
6031
6032
    minutesInputEl.bind('blur', function(e) {
6033
      ngModelCtrl.$setTouched();
6034
      if (modelIsEmpty()) {
6035
        makeValid();
6036
      } else if ($scope.minutes === null) {
6037
        invalidate(undefined, true);
6038
      } else if (!$scope.invalidMinutes && $scope.minutes < 10) {
6039
        $scope.$apply(function() {
6040
          $scope.minutes = pad($scope.minutes);
6041
        });
6042
      }
6043
    });
6044
6045
    $scope.updateSeconds = function() {
6046
      var seconds = getSecondsFromTemplate();
6047
6048
      ngModelCtrl.$setDirty();
6049
6050
      if (angular.isDefined(seconds)) {
6051
        selected.setSeconds(seconds);
6052
        refresh('s');
6053
      } else {
6054
        invalidate(undefined, undefined, true);
6055
      }
6056
    };
6057
6058
    secondsInputEl.bind('blur', function(e) {
6059
      if (modelIsEmpty()) {
6060
        makeValid();
6061
      } else if (!$scope.invalidSeconds && $scope.seconds < 10) {
6062
        $scope.$apply( function() {
6063
          $scope.seconds = pad($scope.seconds);
6064
        });
6065
      }
6066
    });
6067
6068
  };
6069
6070
  this.render = function() {
6071
    var date = ngModelCtrl.$viewValue;
6072
6073
    if (isNaN(date)) {
6074
      ngModelCtrl.$setValidity('time', false);
6075
      $log.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
6076
    } else {
6077
      if (date) {
6078
        selected = date;
6079
      }
6080
6081
      if (selected < min || selected > max) {
6082
        ngModelCtrl.$setValidity('time', false);
6083
        $scope.invalidHours = true;
6084
        $scope.invalidMinutes = true;
6085
      } else {
6086
        makeValid();
6087
      }
6088
      updateTemplate();
6089
    }
6090
  };
6091
6092
  // Call internally when we know that model is valid.
6093
  function refresh(keyboardChange) {
6094
    makeValid();
6095
    ngModelCtrl.$setViewValue(new Date(selected));
6096
    updateTemplate(keyboardChange);
6097
  }
6098
6099
  function makeValid() {
6100
    ngModelCtrl.$setValidity('time', true);
6101
    $scope.invalidHours = false;
6102
    $scope.invalidMinutes = false;
6103
    $scope.invalidSeconds = false;
6104
  }
6105
6106
  function updateTemplate(keyboardChange) {
6107
    if (!ngModelCtrl.$modelValue) {
6108
      $scope.hours = null;
6109
      $scope.minutes = null;
6110
      $scope.seconds = null;
6111
      $scope.meridian = meridians[0];
6112
    } else {
6113
      var hours = selected.getHours(),
6114
        minutes = selected.getMinutes(),
6115
        seconds = selected.getSeconds();
6116
6117
      if ($scope.showMeridian) {
6118
        hours = hours === 0 || hours === 12 ? 12 : hours % 12; // Convert 24 to 12 hour system
6119
      }
6120
6121
      $scope.hours = keyboardChange === 'h' ? hours : pad(hours, !padHours);
6122
      if (keyboardChange !== 'm') {
6123
        $scope.minutes = pad(minutes);
6124
      }
6125
      $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
6126
6127
      if (keyboardChange !== 's') {
6128
        $scope.seconds = pad(seconds);
6129
      }
6130
      $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
6131
    }
6132
  }
6133
6134
  function addSecondsToSelected(seconds) {
6135
    selected = addSeconds(selected, seconds);
6136
    refresh();
6137
  }
6138
6139
  function addMinutes(selected, minutes) {
6140
    return addSeconds(selected, minutes*60);
6141
  }
6142
6143
  function addSeconds(date, seconds) {
6144
    var dt = new Date(date.getTime() + seconds * 1000);
6145
    var newDate = new Date(date);
6146
    newDate.setHours(dt.getHours(), dt.getMinutes(), dt.getSeconds());
6147
    return newDate;
6148
  }
6149
6150
  function modelIsEmpty() {
6151
    return ($scope.hours === null || $scope.hours === '') &&
6152
      ($scope.minutes === null || $scope.minutes === '') &&
6153
      (!$scope.showSeconds || $scope.showSeconds && ($scope.seconds === null || $scope.seconds === ''));
6154
  }
6155
6156
  $scope.showSpinners = angular.isDefined($attrs.showSpinners) ?
6157
    $scope.$parent.$eval($attrs.showSpinners) : timepickerConfig.showSpinners;
6158
6159
  $scope.incrementHours = function() {
6160
    if (!$scope.noIncrementHours()) {
6161
      addSecondsToSelected(hourStep * 60 * 60);
6162
    }
6163
  };
6164
6165
  $scope.decrementHours = function() {
6166
    if (!$scope.noDecrementHours()) {
6167
      addSecondsToSelected(-hourStep * 60 * 60);
6168
    }
6169
  };
6170
6171
  $scope.incrementMinutes = function() {
6172
    if (!$scope.noIncrementMinutes()) {
6173
      addSecondsToSelected(minuteStep * 60);
6174
    }
6175
  };
6176
6177
  $scope.decrementMinutes = function() {
6178
    if (!$scope.noDecrementMinutes()) {
6179
      addSecondsToSelected(-minuteStep * 60);
6180
    }
6181
  };
6182
6183
  $scope.incrementSeconds = function() {
6184
    if (!$scope.noIncrementSeconds()) {
6185
      addSecondsToSelected(secondStep);
6186
    }
6187
  };
6188
6189
  $scope.decrementSeconds = function() {
6190
    if (!$scope.noDecrementSeconds()) {
6191
      addSecondsToSelected(-secondStep);
6192
    }
6193
  };
6194
6195
  $scope.toggleMeridian = function() {
6196
    var minutes = getMinutesFromTemplate(),
6197
        hours = getHoursFromTemplate();
6198
6199
    if (!$scope.noToggleMeridian()) {
6200
      if (angular.isDefined(minutes) && angular.isDefined(hours)) {
6201
        addSecondsToSelected(12 * 60 * (selected.getHours() < 12 ? 60 : -60));
6202
      } else {
6203
        $scope.meridian = $scope.meridian === meridians[0] ? meridians[1] : meridians[0];
6204
      }
6205
    }
6206
  };
6207
6208
  $scope.blur = function() {
6209
    ngModelCtrl.$setTouched();
6210
  };
6211
6212
  $scope.$on('$destroy', function() {
6213
    while (watchers.length) {
6214
      watchers.shift()();
6215
    }
6216
  });
6217
}])
6218
6219
.directive('uibTimepicker', ['uibTimepickerConfig', function(uibTimepickerConfig) {
6220
  return {