angular-ui-bootstrap-rails 0.11.0 → 0.11.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 85f812e3f7f178e10580078d59e6a10ec3a972d8
4
- data.tar.gz: 13e0843c45c3a3f4e49caebe5810d734f24a69c6
3
+ metadata.gz: 27e4bece79303fd2da07e638a82cbfd6804c577c
4
+ data.tar.gz: 00475d11b2f375ce5e66e2325c67df12ea54038d
5
5
  SHA512:
6
- metadata.gz: 4259ed0ada0ea8c87aade0067cbfc7c85440eab8e13b84a81c950798ef8002148807114d96a2cf7215bc6ac5a2a94f9f339ac3e36ab77420935cf41aa2344640
7
- data.tar.gz: 87a81f50fb592b85e7be03e413abdfd32bc875751e505ade49c5dbdcdf999990740c52a2ac5a399c0f9247fbd03c05ff4abd2ddd4646e3c3f57f8ceca20e4244
6
+ metadata.gz: 1b6dabb638ff4e3e744d9973cbd19841ee1b059cc4e45c173e26e9b61fb328591272005d6ca0aa6d1e26fd5b6535a2989b535684dbb5ed5bd3dcda916b5169a5
7
+ data.tar.gz: 73def3d19c170800d216f6a22d0738f87f885a5ef047b5031e800d942cb3d07f23d88796ead7a157b1bfac6d88083fb308722edd53a36d1769e8ada9aec2915b
@@ -1,7 +1,7 @@
1
1
  module AngularUI
2
2
  module Bootstrap
3
3
  module Rails
4
- VERSION = "0.11.0"
4
+ VERSION = "0.11.1"
5
5
  end
6
6
  end
7
7
  end
@@ -2,7 +2,7 @@
2
2
  * angular-ui-bootstrap
3
3
  * http://angular-ui.github.io/bootstrap/
4
4
 
5
- * Version: 0.11.0 - 2014-05-01
5
+ * Version: 0.11.1 - 2014-09-26
6
6
  * License: MIT
7
7
  */
8
8
  angular.module("ui.bootstrap", ["ui.bootstrap.tpls", "ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.dateparser","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdown","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]);
@@ -747,7 +747,7 @@ angular.module('ui.bootstrap.dateparser', [])
747
747
  }
748
748
  };
749
749
 
750
- this.createParser = function(format) {
750
+ function createParser(format) {
751
751
  var map = [], regex = format.split('');
752
752
 
753
753
  angular.forEach(formatCodeToRegex, function(data, code) {
@@ -772,17 +772,17 @@ angular.module('ui.bootstrap.dateparser', [])
772
772
  regex: new RegExp('^' + regex.join('') + '$'),
773
773
  map: orderByFilter(map, 'index')
774
774
  };
775
- };
775
+ }
776
776
 
777
777
  this.parse = function(input, format) {
778
- if ( !angular.isString(input) ) {
778
+ if ( !angular.isString(input) || !format ) {
779
779
  return input;
780
780
  }
781
781
 
782
782
  format = $locale.DATETIME_FORMATS[format] || format;
783
783
 
784
784
  if ( !this.parsers[format] ) {
785
- this.parsers[format] = this.createParser(format);
785
+ this.parsers[format] = createParser(format);
786
786
  }
787
787
 
788
788
  var parser = this.parsers[format],
@@ -1008,7 +1008,7 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
1008
1008
  self[key] = angular.isDefined($attrs[key]) ? (index < 8 ? $interpolate($attrs[key])($scope.$parent) : $scope.$parent.$eval($attrs[key])) : datepickerConfig[key];
1009
1009
  });
1010
1010
 
1011
- // Watchable attributes
1011
+ // Watchable date attributes
1012
1012
  angular.forEach(['minDate', 'maxDate'], function( key ) {
1013
1013
  if ( $attrs[key] ) {
1014
1014
  $scope.$parent.$watch($parse($attrs[key]), function(value) {
@@ -1455,12 +1455,24 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
1455
1455
  });
1456
1456
  }
1457
1457
 
1458
- angular.forEach(['minDate', 'maxDate'], function( key ) {
1458
+ scope.watchData = {};
1459
+ angular.forEach(['minDate', 'maxDate', 'datepickerMode'], function( key ) {
1459
1460
  if ( attrs[key] ) {
1460
- scope.$parent.$watch($parse(attrs[key]), function(value){
1461
- scope[key] = value;
1461
+ var getAttribute = $parse(attrs[key]);
1462
+ scope.$parent.$watch(getAttribute, function(value){
1463
+ scope.watchData[key] = value;
1462
1464
  });
1463
- datepickerEl.attr(cameltoDash(key), key);
1465
+ datepickerEl.attr(cameltoDash(key), 'watchData.' + key);
1466
+
1467
+ // Propagate changes from datepicker to outside
1468
+ if ( key === 'datepickerMode' ) {
1469
+ var setAttribute = getAttribute.assign;
1470
+ scope.$watch('watchData.' + key, function(value, oldvalue) {
1471
+ if ( value !== oldvalue ) {
1472
+ setAttribute(scope.$parent, value);
1473
+ }
1474
+ });
1475
+ }
1464
1476
  }
1465
1477
  });
1466
1478
  if (attrs.dateDisabled) {
@@ -1571,6 +1583,9 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
1571
1583
  };
1572
1584
 
1573
1585
  var $popup = $compile(popupEl)(scope);
1586
+ // Prevent jQuery cache memory leak (template is now redundant after linking)
1587
+ popupEl.remove();
1588
+
1574
1589
  if ( appendToBody ) {
1575
1590
  $document.find('body').append($popup);
1576
1591
  } else {
@@ -1632,7 +1647,8 @@ angular.module('ui.bootstrap.dropdown', [])
1632
1647
  };
1633
1648
 
1634
1649
  var closeDropdown = function( evt ) {
1635
- if (evt && evt.isDefaultPrevented()) {
1650
+ var toggleElement = openScope.getToggleElement();
1651
+ if ( evt && toggleElement && toggleElement[0].contains(evt.target) ) {
1636
1652
  return;
1637
1653
  }
1638
1654
 
@@ -1679,6 +1695,10 @@ angular.module('ui.bootstrap.dropdown', [])
1679
1695
  return scope.isOpen;
1680
1696
  };
1681
1697
 
1698
+ scope.getToggleElement = function() {
1699
+ return self.toggleElement;
1700
+ };
1701
+
1682
1702
  scope.focusToggleElement = function() {
1683
1703
  if ( self.toggleElement ) {
1684
1704
  self.toggleElement[0].focus();
@@ -1712,7 +1732,6 @@ angular.module('ui.bootstrap.dropdown', [])
1712
1732
 
1713
1733
  .directive('dropdown', function() {
1714
1734
  return {
1715
- restrict: 'CA',
1716
1735
  controller: 'DropdownController',
1717
1736
  link: function(scope, element, attrs, dropdownCtrl) {
1718
1737
  dropdownCtrl.init( element );
@@ -1722,7 +1741,6 @@ angular.module('ui.bootstrap.dropdown', [])
1722
1741
 
1723
1742
  .directive('dropdownToggle', function() {
1724
1743
  return {
1725
- restrict: 'CA',
1726
1744
  require: '?^dropdown',
1727
1745
  link: function(scope, element, attrs, dropdownCtrl) {
1728
1746
  if ( !dropdownCtrl ) {
@@ -1820,7 +1838,8 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1820
1838
  restrict: 'EA',
1821
1839
  replace: true,
1822
1840
  templateUrl: 'template/modal/backdrop.html',
1823
- link: function (scope) {
1841
+ link: function (scope, element, attrs) {
1842
+ scope.backdropClass = attrs.backdropClass || '';
1824
1843
 
1825
1844
  scope.animate = false;
1826
1845
 
@@ -1851,8 +1870,18 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1851
1870
  $timeout(function () {
1852
1871
  // trigger CSS transitions
1853
1872
  scope.animate = true;
1854
- // focus a freshly-opened modal
1855
- element[0].focus();
1873
+
1874
+ /**
1875
+ * Auto-focusing of a freshly-opened modal element causes any child elements
1876
+ * with the autofocus attribute to loose focus. This is an issue on touch
1877
+ * based devices which will show and then hide the onscreen keyboard.
1878
+ * Attempts to refocus the autofocus element via JavaScript will not reopen
1879
+ * the onscreen keyboard. Fixed by updated the focusing logic to only autofocus
1880
+ * the modal element if the modal does not contain an autofocus element.
1881
+ */
1882
+ if (!element[0].querySelectorAll('[autofocus]').length) {
1883
+ element[0].focus();
1884
+ }
1856
1885
  });
1857
1886
 
1858
1887
  scope.close = function (evt) {
@@ -1867,6 +1896,17 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1867
1896
  };
1868
1897
  }])
1869
1898
 
1899
+ .directive('modalTransclude', function () {
1900
+ return {
1901
+ link: function($scope, $element, $attrs, controller, $transclude) {
1902
+ $transclude($scope.$parent, function(clone) {
1903
+ $element.empty();
1904
+ $element.append(clone);
1905
+ });
1906
+ }
1907
+ };
1908
+ })
1909
+
1870
1910
  .factory('$modalStack', ['$transition', '$timeout', '$document', '$compile', '$rootScope', '$$stackedMap',
1871
1911
  function ($transition, $timeout, $document, $compile, $rootScope, $$stackedMap) {
1872
1912
 
@@ -1938,7 +1978,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1938
1978
  });
1939
1979
  } else {
1940
1980
  // Ensure this call is async
1941
- $timeout(afterAnimating, 0);
1981
+ $timeout(afterAnimating);
1942
1982
  }
1943
1983
 
1944
1984
  function afterAnimating() {
@@ -1983,7 +2023,9 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1983
2023
  if (currBackdropIndex >= 0 && !backdropDomEl) {
1984
2024
  backdropScope = $rootScope.$new(true);
1985
2025
  backdropScope.index = currBackdropIndex;
1986
- backdropDomEl = $compile('<div modal-backdrop></div>')(backdropScope);
2026
+ var angularBackgroundDomEl = angular.element('<div modal-backdrop></div>');
2027
+ angularBackgroundDomEl.attr('backdrop-class', modal.backdropClass);
2028
+ backdropDomEl = $compile(angularBackgroundDomEl)(backdropScope);
1987
2029
  body.append(backdropDomEl);
1988
2030
  }
1989
2031
 
@@ -2003,17 +2045,17 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
2003
2045
  };
2004
2046
 
2005
2047
  $modalStack.close = function (modalInstance, result) {
2006
- var modalWindow = openedWindows.get(modalInstance).value;
2048
+ var modalWindow = openedWindows.get(modalInstance);
2007
2049
  if (modalWindow) {
2008
- modalWindow.deferred.resolve(result);
2050
+ modalWindow.value.deferred.resolve(result);
2009
2051
  removeModalWindow(modalInstance);
2010
2052
  }
2011
2053
  };
2012
2054
 
2013
2055
  $modalStack.dismiss = function (modalInstance, reason) {
2014
- var modalWindow = openedWindows.get(modalInstance).value;
2056
+ var modalWindow = openedWindows.get(modalInstance);
2015
2057
  if (modalWindow) {
2016
- modalWindow.deferred.reject(reason);
2058
+ modalWindow.value.deferred.reject(reason);
2017
2059
  removeModalWindow(modalInstance);
2018
2060
  }
2019
2061
  };
@@ -2047,14 +2089,15 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
2047
2089
 
2048
2090
  function getTemplatePromise(options) {
2049
2091
  return options.template ? $q.when(options.template) :
2050
- $http.get(options.templateUrl, {cache: $templateCache}).then(function (result) {
2051
- return result.data;
2092
+ $http.get(angular.isFunction(options.templateUrl) ? (options.templateUrl)() : options.templateUrl,
2093
+ {cache: $templateCache}).then(function (result) {
2094
+ return result.data;
2052
2095
  });
2053
2096
  }
2054
2097
 
2055
2098
  function getResolvePromises(resolves) {
2056
2099
  var promisesArr = [];
2057
- angular.forEach(resolves, function (value, key) {
2100
+ angular.forEach(resolves, function (value) {
2058
2101
  if (angular.isFunction(value) || angular.isArray(value)) {
2059
2102
  promisesArr.push($q.when($injector.invoke(value)));
2060
2103
  }
@@ -2110,6 +2153,9 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
2110
2153
  });
2111
2154
 
2112
2155
  ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
2156
+ if (modalOptions.controllerAs) {
2157
+ modalScope[modalOptions.controllerAs] = ctrlInstance;
2158
+ }
2113
2159
  }
2114
2160
 
2115
2161
  $modalStack.open(modalInstance, {
@@ -2118,6 +2164,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
2118
2164
  content: tplAndVars[0],
2119
2165
  backdrop: modalOptions.backdrop,
2120
2166
  keyboard: modalOptions.keyboard,
2167
+ backdropClass: modalOptions.backdropClass,
2121
2168
  windowClass: modalOptions.windowClass,
2122
2169
  windowTemplateUrl: modalOptions.windowTemplateUrl,
2123
2170
  size: modalOptions.size
@@ -3428,7 +3475,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3428
3475
  .factory('typeaheadParser', ['$parse', function ($parse) {
3429
3476
 
3430
3477
  // 00000111000000000000022200000000000000003333333333333330000000000044000
3431
- var TYPEAHEAD_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+(.*)$/;
3478
+ var TYPEAHEAD_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+([\s\S]+?)$/;
3432
3479
 
3433
3480
  return {
3434
3481
  parse:function (input) {
@@ -3594,6 +3641,18 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3594
3641
  //Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later
3595
3642
  var timeoutPromise;
3596
3643
 
3644
+ var scheduleSearchWithTimeout = function(inputValue) {
3645
+ timeoutPromise = $timeout(function () {
3646
+ getMatchesAsync(inputValue);
3647
+ }, waitTime);
3648
+ };
3649
+
3650
+ var cancelPreviousTimeout = function() {
3651
+ if (timeoutPromise) {
3652
+ $timeout.cancel(timeoutPromise);
3653
+ }
3654
+ };
3655
+
3597
3656
  //plug into $parsers pipeline to open a typeahead on view changes initiated from DOM
3598
3657
  //$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue
3599
3658
  modelCtrl.$parsers.unshift(function (inputValue) {
@@ -3602,17 +3661,14 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3602
3661
 
3603
3662
  if (inputValue && inputValue.length >= minSearch) {
3604
3663
  if (waitTime > 0) {
3605
- if (timeoutPromise) {
3606
- $timeout.cancel(timeoutPromise);//cancel previous timeout
3607
- }
3608
- timeoutPromise = $timeout(function () {
3609
- getMatchesAsync(inputValue);
3610
- }, waitTime);
3664
+ cancelPreviousTimeout();
3665
+ scheduleSearchWithTimeout(inputValue);
3611
3666
  } else {
3612
3667
  getMatchesAsync(inputValue);
3613
3668
  }
3614
3669
  } else {
3615
3670
  isLoadingSetter(originalScope, false);
3671
+ cancelPreviousTimeout();
3616
3672
  resetMatches();
3617
3673
  }
3618
3674
 
@@ -3820,7 +3876,7 @@ angular.module("template/accordion/accordion.html", []).run(["$templateCache", f
3820
3876
 
3821
3877
  angular.module("template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
3822
3878
  $templateCache.put("template/alert/alert.html",
3823
- "<div class=\"alert\" ng-class=\"{'alert-{{type || 'warning'}}': true, 'alert-dismissable': closeable}\" role=\"alert\">\n" +
3879
+ "<div class=\"alert\" ng-class=\"['alert-' + (type || 'warning'), closeable ? 'alert-dismissable' : null]\" role=\"alert\">\n" +
3824
3880
  " <button ng-show=\"closeable\" type=\"button\" class=\"close\" ng-click=\"close()\">\n" +
3825
3881
  " <span aria-hidden=\"true\">&times;</span>\n" +
3826
3882
  " <span class=\"sr-only\">Close</span>\n" +
@@ -3949,7 +4005,7 @@ angular.module("template/datepicker/year.html", []).run(["$templateCache", funct
3949
4005
 
3950
4006
  angular.module("template/modal/backdrop.html", []).run(["$templateCache", function($templateCache) {
3951
4007
  $templateCache.put("template/modal/backdrop.html",
3952
- "<div class=\"modal-backdrop fade\"\n" +
4008
+ "<div class=\"modal-backdrop fade {{ backdropClass }}\"\n" +
3953
4009
  " ng-class=\"{in: animate}\"\n" +
3954
4010
  " ng-style=\"{'z-index': 1040 + (index && 1 || 0) + index*10}\"\n" +
3955
4011
  "></div>\n" +
@@ -3959,7 +4015,7 @@ angular.module("template/modal/backdrop.html", []).run(["$templateCache", functi
3959
4015
  angular.module("template/modal/window.html", []).run(["$templateCache", function($templateCache) {
3960
4016
  $templateCache.put("template/modal/window.html",
3961
4017
  "<div tabindex=\"-1\" role=\"dialog\" class=\"modal fade\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1050 + index*10, display: 'block'}\" ng-click=\"close($event)\">\n" +
3962
- " <div class=\"modal-dialog\" ng-class=\"{'modal-sm': size == 'sm', 'modal-lg': size == 'lg'}\"><div class=\"modal-content\" ng-transclude></div></div>\n" +
4018
+ " <div class=\"modal-dialog\" ng-class=\"{'modal-sm': size == 'sm', 'modal-lg': size == 'lg'}\"><div class=\"modal-content\" modal-transclude></div></div>\n" +
3963
4019
  "</div>");
3964
4020
  }]);
3965
4021
 
@@ -4047,16 +4103,8 @@ angular.module("template/tabs/tab.html", []).run(["$templateCache", function($te
4047
4103
  "");
4048
4104
  }]);
4049
4105
 
4050
- angular.module("template/tabs/tabset-titles.html", []).run(["$templateCache", function($templateCache) {
4051
- $templateCache.put("template/tabs/tabset-titles.html",
4052
- "<ul class=\"nav {{type && 'nav-' + type}}\" ng-class=\"{'nav-stacked': vertical}\">\n" +
4053
- "</ul>\n" +
4054
- "");
4055
- }]);
4056
-
4057
4106
  angular.module("template/tabs/tabset.html", []).run(["$templateCache", function($templateCache) {
4058
4107
  $templateCache.put("template/tabs/tabset.html",
4059
- "\n" +
4060
4108
  "<div>\n" +
4061
4109
  " <ul class=\"nav nav-{{type || 'tabs'}}\" ng-class=\"{'nav-stacked': vertical, 'nav-justified': justified}\" ng-transclude></ul>\n" +
4062
4110
  " <div class=\"tab-content\">\n" +
@@ -4108,9 +4156,10 @@ angular.module("template/typeahead/typeahead-match.html", []).run(["$templateCac
4108
4156
 
4109
4157
  angular.module("template/typeahead/typeahead-popup.html", []).run(["$templateCache", function($templateCache) {
4110
4158
  $templateCache.put("template/typeahead/typeahead-popup.html",
4111
- "<ul class=\"dropdown-menu\" ng-if=\"isOpen()\" ng-style=\"{top: position.top+'px', left: position.left+'px'}\" style=\"display: block;\" role=\"listbox\" aria-hidden=\"{{!isOpen()}}\">\n" +
4159
+ "<ul class=\"dropdown-menu\" ng-show=\"isOpen()\" ng-style=\"{top: position.top+'px', left: position.left+'px'}\" style=\"display: block;\" role=\"listbox\" aria-hidden=\"{{!isOpen()}}\">\n" +
4112
4160
  " <li ng-repeat=\"match in matches track by $index\" ng-class=\"{active: isActive($index) }\" ng-mouseenter=\"selectActive($index)\" ng-click=\"selectMatch($index)\" role=\"option\" id=\"{{match.id}}\">\n" +
4113
4161
  " <div typeahead-match index=\"$index\" match=\"match\" query=\"query\" template-url=\"templateUrl\"></div>\n" +
4114
4162
  " </li>\n" +
4115
- "</ul>");
4163
+ "</ul>\n" +
4164
+ "");
4116
4165
  }]);
@@ -2,7 +2,7 @@
2
2
  * angular-ui-bootstrap
3
3
  * http://angular-ui.github.io/bootstrap/
4
4
 
5
- * Version: 0.11.0 - 2014-05-01
5
+ * Version: 0.11.1 - 2014-09-26
6
6
  * License: MIT
7
7
  */
8
8
  angular.module("ui.bootstrap", ["ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.dateparser","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdown","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]);
@@ -746,7 +746,7 @@ angular.module('ui.bootstrap.dateparser', [])
746
746
  }
747
747
  };
748
748
 
749
- this.createParser = function(format) {
749
+ function createParser(format) {
750
750
  var map = [], regex = format.split('');
751
751
 
752
752
  angular.forEach(formatCodeToRegex, function(data, code) {
@@ -771,17 +771,17 @@ angular.module('ui.bootstrap.dateparser', [])
771
771
  regex: new RegExp('^' + regex.join('') + '$'),
772
772
  map: orderByFilter(map, 'index')
773
773
  };
774
- };
774
+ }
775
775
 
776
776
  this.parse = function(input, format) {
777
- if ( !angular.isString(input) ) {
777
+ if ( !angular.isString(input) || !format ) {
778
778
  return input;
779
779
  }
780
780
 
781
781
  format = $locale.DATETIME_FORMATS[format] || format;
782
782
 
783
783
  if ( !this.parsers[format] ) {
784
- this.parsers[format] = this.createParser(format);
784
+ this.parsers[format] = createParser(format);
785
785
  }
786
786
 
787
787
  var parser = this.parsers[format],
@@ -1007,7 +1007,7 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
1007
1007
  self[key] = angular.isDefined($attrs[key]) ? (index < 8 ? $interpolate($attrs[key])($scope.$parent) : $scope.$parent.$eval($attrs[key])) : datepickerConfig[key];
1008
1008
  });
1009
1009
 
1010
- // Watchable attributes
1010
+ // Watchable date attributes
1011
1011
  angular.forEach(['minDate', 'maxDate'], function( key ) {
1012
1012
  if ( $attrs[key] ) {
1013
1013
  $scope.$parent.$watch($parse($attrs[key]), function(value) {
@@ -1454,12 +1454,24 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
1454
1454
  });
1455
1455
  }
1456
1456
 
1457
- angular.forEach(['minDate', 'maxDate'], function( key ) {
1457
+ scope.watchData = {};
1458
+ angular.forEach(['minDate', 'maxDate', 'datepickerMode'], function( key ) {
1458
1459
  if ( attrs[key] ) {
1459
- scope.$parent.$watch($parse(attrs[key]), function(value){
1460
- scope[key] = value;
1460
+ var getAttribute = $parse(attrs[key]);
1461
+ scope.$parent.$watch(getAttribute, function(value){
1462
+ scope.watchData[key] = value;
1461
1463
  });
1462
- datepickerEl.attr(cameltoDash(key), key);
1464
+ datepickerEl.attr(cameltoDash(key), 'watchData.' + key);
1465
+
1466
+ // Propagate changes from datepicker to outside
1467
+ if ( key === 'datepickerMode' ) {
1468
+ var setAttribute = getAttribute.assign;
1469
+ scope.$watch('watchData.' + key, function(value, oldvalue) {
1470
+ if ( value !== oldvalue ) {
1471
+ setAttribute(scope.$parent, value);
1472
+ }
1473
+ });
1474
+ }
1463
1475
  }
1464
1476
  });
1465
1477
  if (attrs.dateDisabled) {
@@ -1570,6 +1582,9 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
1570
1582
  };
1571
1583
 
1572
1584
  var $popup = $compile(popupEl)(scope);
1585
+ // Prevent jQuery cache memory leak (template is now redundant after linking)
1586
+ popupEl.remove();
1587
+
1573
1588
  if ( appendToBody ) {
1574
1589
  $document.find('body').append($popup);
1575
1590
  } else {
@@ -1631,7 +1646,8 @@ angular.module('ui.bootstrap.dropdown', [])
1631
1646
  };
1632
1647
 
1633
1648
  var closeDropdown = function( evt ) {
1634
- if (evt && evt.isDefaultPrevented()) {
1649
+ var toggleElement = openScope.getToggleElement();
1650
+ if ( evt && toggleElement && toggleElement[0].contains(evt.target) ) {
1635
1651
  return;
1636
1652
  }
1637
1653
 
@@ -1678,6 +1694,10 @@ angular.module('ui.bootstrap.dropdown', [])
1678
1694
  return scope.isOpen;
1679
1695
  };
1680
1696
 
1697
+ scope.getToggleElement = function() {
1698
+ return self.toggleElement;
1699
+ };
1700
+
1681
1701
  scope.focusToggleElement = function() {
1682
1702
  if ( self.toggleElement ) {
1683
1703
  self.toggleElement[0].focus();
@@ -1711,7 +1731,6 @@ angular.module('ui.bootstrap.dropdown', [])
1711
1731
 
1712
1732
  .directive('dropdown', function() {
1713
1733
  return {
1714
- restrict: 'CA',
1715
1734
  controller: 'DropdownController',
1716
1735
  link: function(scope, element, attrs, dropdownCtrl) {
1717
1736
  dropdownCtrl.init( element );
@@ -1721,7 +1740,6 @@ angular.module('ui.bootstrap.dropdown', [])
1721
1740
 
1722
1741
  .directive('dropdownToggle', function() {
1723
1742
  return {
1724
- restrict: 'CA',
1725
1743
  require: '?^dropdown',
1726
1744
  link: function(scope, element, attrs, dropdownCtrl) {
1727
1745
  if ( !dropdownCtrl ) {
@@ -1819,7 +1837,8 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1819
1837
  restrict: 'EA',
1820
1838
  replace: true,
1821
1839
  templateUrl: 'template/modal/backdrop.html',
1822
- link: function (scope) {
1840
+ link: function (scope, element, attrs) {
1841
+ scope.backdropClass = attrs.backdropClass || '';
1823
1842
 
1824
1843
  scope.animate = false;
1825
1844
 
@@ -1850,8 +1869,18 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1850
1869
  $timeout(function () {
1851
1870
  // trigger CSS transitions
1852
1871
  scope.animate = true;
1853
- // focus a freshly-opened modal
1854
- element[0].focus();
1872
+
1873
+ /**
1874
+ * Auto-focusing of a freshly-opened modal element causes any child elements
1875
+ * with the autofocus attribute to loose focus. This is an issue on touch
1876
+ * based devices which will show and then hide the onscreen keyboard.
1877
+ * Attempts to refocus the autofocus element via JavaScript will not reopen
1878
+ * the onscreen keyboard. Fixed by updated the focusing logic to only autofocus
1879
+ * the modal element if the modal does not contain an autofocus element.
1880
+ */
1881
+ if (!element[0].querySelectorAll('[autofocus]').length) {
1882
+ element[0].focus();
1883
+ }
1855
1884
  });
1856
1885
 
1857
1886
  scope.close = function (evt) {
@@ -1866,6 +1895,17 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1866
1895
  };
1867
1896
  }])
1868
1897
 
1898
+ .directive('modalTransclude', function () {
1899
+ return {
1900
+ link: function($scope, $element, $attrs, controller, $transclude) {
1901
+ $transclude($scope.$parent, function(clone) {
1902
+ $element.empty();
1903
+ $element.append(clone);
1904
+ });
1905
+ }
1906
+ };
1907
+ })
1908
+
1869
1909
  .factory('$modalStack', ['$transition', '$timeout', '$document', '$compile', '$rootScope', '$$stackedMap',
1870
1910
  function ($transition, $timeout, $document, $compile, $rootScope, $$stackedMap) {
1871
1911
 
@@ -1937,7 +1977,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1937
1977
  });
1938
1978
  } else {
1939
1979
  // Ensure this call is async
1940
- $timeout(afterAnimating, 0);
1980
+ $timeout(afterAnimating);
1941
1981
  }
1942
1982
 
1943
1983
  function afterAnimating() {
@@ -1982,7 +2022,9 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1982
2022
  if (currBackdropIndex >= 0 && !backdropDomEl) {
1983
2023
  backdropScope = $rootScope.$new(true);
1984
2024
  backdropScope.index = currBackdropIndex;
1985
- backdropDomEl = $compile('<div modal-backdrop></div>')(backdropScope);
2025
+ var angularBackgroundDomEl = angular.element('<div modal-backdrop></div>');
2026
+ angularBackgroundDomEl.attr('backdrop-class', modal.backdropClass);
2027
+ backdropDomEl = $compile(angularBackgroundDomEl)(backdropScope);
1986
2028
  body.append(backdropDomEl);
1987
2029
  }
1988
2030
 
@@ -2002,17 +2044,17 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
2002
2044
  };
2003
2045
 
2004
2046
  $modalStack.close = function (modalInstance, result) {
2005
- var modalWindow = openedWindows.get(modalInstance).value;
2047
+ var modalWindow = openedWindows.get(modalInstance);
2006
2048
  if (modalWindow) {
2007
- modalWindow.deferred.resolve(result);
2049
+ modalWindow.value.deferred.resolve(result);
2008
2050
  removeModalWindow(modalInstance);
2009
2051
  }
2010
2052
  };
2011
2053
 
2012
2054
  $modalStack.dismiss = function (modalInstance, reason) {
2013
- var modalWindow = openedWindows.get(modalInstance).value;
2055
+ var modalWindow = openedWindows.get(modalInstance);
2014
2056
  if (modalWindow) {
2015
- modalWindow.deferred.reject(reason);
2057
+ modalWindow.value.deferred.reject(reason);
2016
2058
  removeModalWindow(modalInstance);
2017
2059
  }
2018
2060
  };
@@ -2046,14 +2088,15 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
2046
2088
 
2047
2089
  function getTemplatePromise(options) {
2048
2090
  return options.template ? $q.when(options.template) :
2049
- $http.get(options.templateUrl, {cache: $templateCache}).then(function (result) {
2050
- return result.data;
2091
+ $http.get(angular.isFunction(options.templateUrl) ? (options.templateUrl)() : options.templateUrl,
2092
+ {cache: $templateCache}).then(function (result) {
2093
+ return result.data;
2051
2094
  });
2052
2095
  }
2053
2096
 
2054
2097
  function getResolvePromises(resolves) {
2055
2098
  var promisesArr = [];
2056
- angular.forEach(resolves, function (value, key) {
2099
+ angular.forEach(resolves, function (value) {
2057
2100
  if (angular.isFunction(value) || angular.isArray(value)) {
2058
2101
  promisesArr.push($q.when($injector.invoke(value)));
2059
2102
  }
@@ -2109,6 +2152,9 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
2109
2152
  });
2110
2153
 
2111
2154
  ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
2155
+ if (modalOptions.controllerAs) {
2156
+ modalScope[modalOptions.controllerAs] = ctrlInstance;
2157
+ }
2112
2158
  }
2113
2159
 
2114
2160
  $modalStack.open(modalInstance, {
@@ -2117,6 +2163,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
2117
2163
  content: tplAndVars[0],
2118
2164
  backdrop: modalOptions.backdrop,
2119
2165
  keyboard: modalOptions.keyboard,
2166
+ backdropClass: modalOptions.backdropClass,
2120
2167
  windowClass: modalOptions.windowClass,
2121
2168
  windowTemplateUrl: modalOptions.windowTemplateUrl,
2122
2169
  size: modalOptions.size
@@ -3427,7 +3474,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3427
3474
  .factory('typeaheadParser', ['$parse', function ($parse) {
3428
3475
 
3429
3476
  // 00000111000000000000022200000000000000003333333333333330000000000044000
3430
- var TYPEAHEAD_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+(.*)$/;
3477
+ var TYPEAHEAD_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+([\s\S]+?)$/;
3431
3478
 
3432
3479
  return {
3433
3480
  parse:function (input) {
@@ -3593,6 +3640,18 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3593
3640
  //Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later
3594
3641
  var timeoutPromise;
3595
3642
 
3643
+ var scheduleSearchWithTimeout = function(inputValue) {
3644
+ timeoutPromise = $timeout(function () {
3645
+ getMatchesAsync(inputValue);
3646
+ }, waitTime);
3647
+ };
3648
+
3649
+ var cancelPreviousTimeout = function() {
3650
+ if (timeoutPromise) {
3651
+ $timeout.cancel(timeoutPromise);
3652
+ }
3653
+ };
3654
+
3596
3655
  //plug into $parsers pipeline to open a typeahead on view changes initiated from DOM
3597
3656
  //$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue
3598
3657
  modelCtrl.$parsers.unshift(function (inputValue) {
@@ -3601,17 +3660,14 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3601
3660
 
3602
3661
  if (inputValue && inputValue.length >= minSearch) {
3603
3662
  if (waitTime > 0) {
3604
- if (timeoutPromise) {
3605
- $timeout.cancel(timeoutPromise);//cancel previous timeout
3606
- }
3607
- timeoutPromise = $timeout(function () {
3608
- getMatchesAsync(inputValue);
3609
- }, waitTime);
3663
+ cancelPreviousTimeout();
3664
+ scheduleSearchWithTimeout(inputValue);
3610
3665
  } else {
3611
3666
  getMatchesAsync(inputValue);
3612
3667
  }
3613
3668
  } else {
3614
3669
  isLoadingSetter(originalScope, false);
3670
+ cancelPreviousTimeout();
3615
3671
  resetMatches();
3616
3672
  }
3617
3673
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: angular-ui-bootstrap-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Constantin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-09 00:00:00.000000000 Z
11
+ date: 2014-09-26 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Injects Angular.js UI Bootstrap directives into your asset pipeline.
14
14
  email: chris@chrisconstantin.net
@@ -16,12 +16,12 @@ executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
- - lib/angular-ui-bootstrap-rails/version.rb
19
+ - MIT-LICENSE
20
+ - README.md
20
21
  - lib/angular-ui-bootstrap-rails.rb
22
+ - lib/angular-ui-bootstrap-rails/version.rb
21
23
  - vendor/assets/javascripts/angular-ui-bootstrap-tpls.js
22
24
  - vendor/assets/javascripts/angular-ui-bootstrap.js
23
- - MIT-LICENSE
24
- - README.md
25
25
  homepage: https://github.com/cconstantin/angular-ui-bootstrap-rails/
26
26
  licenses:
27
27
  - MIT
@@ -32,17 +32,17 @@ require_paths:
32
32
  - lib
33
33
  required_ruby_version: !ruby/object:Gem::Requirement
34
34
  requirements:
35
- - - '>='
35
+ - - ">="
36
36
  - !ruby/object:Gem::Version
37
37
  version: '0'
38
38
  required_rubygems_version: !ruby/object:Gem::Requirement
39
39
  requirements:
40
- - - '>='
40
+ - - ">="
41
41
  - !ruby/object:Gem::Version
42
42
  version: '0'
43
43
  requirements: []
44
44
  rubyforge_project:
45
- rubygems_version: 2.0.14
45
+ rubygems_version: 2.2.2
46
46
  signing_key:
47
47
  specification_version: 4
48
48
  summary: Angular.js UI Bootstrap on Rails