diff --git a/bower.json b/bower.json
index 6fca4d87c..116c6f7c0 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
{
"name": "angular-patternfly",
- "version": "3.3.1",
+ "version": "3.3.2",
"authors": [
"Red Hat"
],
@@ -39,7 +39,7 @@
"angular-sanitize": "1.3.0 - 1.5.*",
"angular-bootstrap": "0.13.x",
"lodash": "3.x",
- "patternfly": "~3.3.1"
+ "patternfly": "~3.3.2"
},
"devDependencies": {
"angular-mocks": "1.3.0 - 1.5.*"
diff --git a/dist/docs/css/patternfly-additions.css b/dist/docs/css/patternfly-additions.css
index 600527850..5d388d145 100644
--- a/dist/docs/css/patternfly-additions.css
+++ b/dist/docs/css/patternfly-additions.css
@@ -4931,7 +4931,10 @@ table.datatable th:active {
padding: 0;
top: 23px!important;
width: calc(100% - 25px);
- z-index: 0;
+}
+.bootstrap-datetimepicker-widget.dropdown-menu:before,
+.bootstrap-datetimepicker-widget.dropdown-menu:after {
+ content: none;
}
.bootstrap-datetimepicker-widget .timepicker-hour {
width: 100%;
diff --git a/dist/docs/grunt-scripts/angular-animate.js b/dist/docs/grunt-scripts/angular-animate.js
index 1652a9bba..c30fed7b5 100644
--- a/dist/docs/grunt-scripts/angular-animate.js
+++ b/dist/docs/grunt-scripts/angular-animate.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.5.2
+ * @license AngularJS v1.5.3
* (c) 2010-2016 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -2225,6 +2225,11 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
});
rules.cancel.push(function(element, newAnimation, currentAnimation) {
+ // cancel the animation if classes added / removed in both animation cancel each other out,
+ // but only if the current animation isn't structural
+
+ if (currentAnimation.structural) return false;
+
var nA = newAnimation.addClass;
var nR = newAnimation.removeClass;
var cA = currentAnimation.addClass;
diff --git a/dist/docs/grunt-scripts/angular-patternfly.js b/dist/docs/grunt-scripts/angular-patternfly.js
index 9439a0666..de4f49aed 100644
--- a/dist/docs/grunt-scripts/angular-patternfly.js
+++ b/dist/docs/grunt-scripts/angular-patternfly.js
@@ -573,7 +573,8 @@ angular.module('patternfly.card').directive('pfCard', function () {
getDefaultSparklineLegend: patternflyDefaults.getDefaultSparklineLegend,
getDefaultSparklinePoint: patternflyDefaults.getDefaultSparklinePoint,
getDefaultSparklineTooltip: patternflyDefaults.getDefaultSparklineTooltip,
- getDefaultSparklineConfig: patternflyDefaults.getDefaultSparklineConfig
+ getDefaultSparklineConfig: patternflyDefaults.getDefaultSparklineConfig,
+ getDefaultLineConfig: patternflyDefaults.getDefaultLineConfig
});
})();
;/**
@@ -942,14 +943,14 @@ angular.module('patternfly.charts').directive('pfDonutPctChart', ["pfUtils", "$t
}
$scope.getStatusColor = function (used, thresholds) {
- var color = '#0088CE';
+ var color = pfUtils.colorPalette.blue;
if (thresholds) {
- color = '#3f9c35';
+ color = pfUtils.colorPalette.green;
if (used >= thresholds.error) {
- color = '#CC0000';
+ color = pfUtils.colorPalette.red;
} else if (used >= thresholds.warning) {
- color = '#EC7A08';
+ color = pfUtils.colorPalette.orange;
}
}
@@ -962,7 +963,7 @@ angular.module('patternfly.charts').directive('pfDonutPctChart', ["pfUtils", "$t
color = { pattern: [] };
percentUsed = scope.data.used / scope.data.total * 100.0;
color.pattern[0] = $scope.getStatusColor(percentUsed, scope.config.thresholds);
- color.pattern[1] = '#D1D1D1';
+ color.pattern[1] = pfUtils.colorPalette.black300;
return color;
};
@@ -1463,6 +1464,225 @@ angular.module('patternfly.charts').directive('pfHeatmap', ["$compile", function
}
};
}]);
+;/**
+ * @ngdoc directive
+ * @name patternfly.charts.directive:pfLineChart
+ *
+ * @description
+ * Directive for rendering a line chart.
+ *
+ * See http://c3js.org/reference.html for a full list of C3 chart options.
+ *
+ * @param {object} config configuration settings for the line chart:
+ *
+ * - .chartId - the ID of the container that the chart should bind to
+ *
- .units - unit label for values, ex: 'MHz','GB', etc..
+ *
- .tooltipFn - (optional) override the tooltip contents generation functions. Should take a data point and
+ * return HTML markup for the tooltip contents. Setting this overrides the tooltipType value.
+ *
- .area - (optional) overrides the default Area properties of the C3 chart
+ *
- .size - (optional) overrides the default Size properties of the C3 chart
+ *
- .axis - (optional) overrides the default Axis properties of the C3 chart
+ *
- .color - (optional) overrides the default Color properties of the C3 chart
+ *
- .legend - (optional) overrides the default Legend properties of the C3 chart
+ *
- .point - (optional) overrides the default Point properties of the C3 chart
+ *
+ *
+ * @param {object} chartData the data to be shown as an area chart
+ * First and second Array elements, xData and yData, must exist, next data arrays are optional.
+ *
+ * - .xData - Array, X values for the data points, first element must be the name of the data
+ *
- .yData - Array, Y Values for the data points, first element must be the name of the data
+ *
- .yData1 - Array, Y Values for the data points, first element must be the name of the data
+ *
- .[...] - Array, Y Values for the data points, first element must be the name of the data
+ *
+ *
+ * @param {boolean=} showXAxis override config settings for showing the X Axis
+ * @param {boolean=} showYAxis override config settings for showing the Y Axis
+ * @param {boolean=} setAreaChart override config settings for showing area type chart
+
+ * @example
+
+
+
+
+
+
+ angular.module( 'patternfly.charts' ).controller( 'ChartCtrl', function( $scope, pfUtils ) {
+
+ $scope.config = {
+ chartId: 'exampleLine',
+ grid: {y: {show: false}},
+ point: {r: 1},
+ color: {pattern: [pfUtils.colorPalette.blue, pfUtils.colorPalette.green]}
+ };
+
+ var today = new Date();
+ var dates = ['dates'];
+ for (var d = 20 - 1; d >= 0; d--) {
+ dates.push(new Date(today.getTime() - (d * 24 * 60 * 60 * 1000)));
+ }
+
+ $scope.data = {
+ xData: dates,
+ yData0: ['Created', 12, 10,10, 62, 17, 10, 15, 13, 17, 10, 12, 10, 10, 12, 17, 16, 15, 13, 17, 10],
+ yData1: ['Deleted', 10, 17, 76,14, 10, 10, 10, 10, 10, 10, 10, 17, 17, 14, 10, 10, 10, 10, 10, 10]
+ };
+
+ $scope.custShowXAxis = false;
+ $scope.custShowYAxis = false;
+ $scope.custAreaChart = false;
+
+ $scope.addDataPoint = function () {
+ $scope.data.xData.push(new Date($scope.data.xData[$scope.data.xData.length - 1].getTime() + (24 * 60 * 60 * 1000)));
+ $scope.data.yData0.push(Math.round(Math.random() * 100));
+ $scope.data.yData1.push(Math.round(Math.random() * 100));
+ };
+ });
+
+
+ */
+angular.module('patternfly.charts').directive('pfLineChart', ["pfUtils", function (pfUtils) {
+ 'use strict';
+ return {
+ restrict: 'A',
+ scope: {
+ config: '=',
+ chartData: '=',
+ showXAxis: '=?',
+ showYAxis: '=?',
+ setAreaChart: '=?'
+ },
+ replace: true,
+ templateUrl: 'charts/line/line-chart.html',
+ controller: ['$scope',
+ function ($scope) {
+
+ // Create an ID for the chart based on the chartId in the config if given
+ $scope.lineChartId = 'lineChart';
+ if ($scope.config.chartId) {
+ $scope.lineChartId = $scope.config.chartId + $scope.lineChartId;
+ }
+
+ /*
+ * Convert the config data to C3 Data
+ */
+ $scope.getLineData = function (chartData) {
+ var lineData = {
+ type: $scope.setAreaChart ? "area" : "line"
+ };
+
+ if (chartData && chartData.dataAvailable !== false && chartData.xData) {
+ lineData.x = chartData.xData[0];
+ // Convert the chartData dictionary into a C3 columns data arrays
+ lineData.columns = Object.keys (chartData).map (function (key) {
+ return chartData[key];
+ });
+ }
+
+ return lineData;
+ };
+
+ /*
+ * Setup Axis options. Default is to not show either axis. This can be overridden in two ways:
+ * 1) in the config, setting showAxis to true will show both axes
+ * 2) in the attributes showXAxis and showYAxis will override the config if set
+ *
+ * By default only line and the tick marks are shown, no labels. This is a line and should be used
+ * only to show a brief idea of trending. This can be overridden by setting the config.axis options per C3
+ */
+
+ if ($scope.showXAxis === undefined) {
+ $scope.showXAxis = ($scope.config.showAxis !== undefined) && $scope.config.showAxis;
+ }
+
+ if ($scope.showYAxis === undefined) {
+ $scope.showYAxis = ($scope.config.showAxis !== undefined) && $scope.config.showAxis;
+ }
+
+ $scope.defaultConfig = $().c3ChartDefaults().getDefaultLineConfig();
+ $scope.defaultConfig.axis = {
+ x: {
+ show: $scope.showXAxis === true,
+ type: 'timeseries',
+ tick: {
+ format: function () {
+ return '';
+ }
+ }
+ },
+ y: {
+ show: $scope.showYAxis === true,
+ tick: {
+ format: function () {
+ return '';
+ }
+ }
+ }
+ };
+
+ /*
+ * Setup Chart type option. Default is Line Chart.
+ */
+ if ($scope.setAreaChart === undefined) {
+ $scope.setAreaChart = ($scope.config.setAreaChart !== undefined) && $scope.config.setAreaChart;
+ }
+
+ // Convert the given data to C3 chart format
+ $scope.config.data = pfUtils.merge($scope.config.data, $scope.getLineData($scope.chartData));
+
+ // Override defaults with callers specifications
+ $scope.defaultConfig = pfUtils.merge($scope.defaultConfig, $scope.config);
+ }
+ ],
+
+ link: function (scope) {
+ scope.$watch('config', function () {
+ scope.config.data = pfUtils.merge(scope.config.data, scope.getLineData(scope.chartData));
+ scope.chartConfig = pfUtils.merge(scope.config, scope.defaultConfig);
+ }, true);
+ scope.$watch('showXAxis', function () {
+ scope.chartConfig.axis.x.show = scope.showXAxis === true;
+ });
+ scope.$watch('showYAxis', function () {
+ scope.chartConfig.axis.y.show = scope.showYAxis === true;
+ });
+ scope.$watch('setAreaChart', function () {
+ scope.chartConfig.data.type = scope.setAreaChart ? "area" : "line";
+ });
+ scope.$watch('chartData', function () {
+ scope.chartConfig.data = pfUtils.merge(scope.chartConfig.data, scope.getLineData(scope.chartData));
+ }, true);
+ }
+ };
+}]
+);
;/**
* @ngdoc directive
* @name patternfly.charts.directive:pfSparklineChart
@@ -4470,7 +4690,9 @@ angular
},
mergeDeep: function (source1, source2) {
return mergeDeep({}, angular.copy(source1), angular.copy(source2));
- }
+ },
+
+ colorPalette: $.pfPaletteColors
});
})();
@@ -5568,6 +5790,11 @@ angular.module('patternfly.views').directive('pfListView', ["$timeout", "$window
);
+ $templateCache.put('charts/line/line-chart.html',
+ ""
+ );
+
+
$templateCache.put('charts/sparkline/sparkline-chart.html',
""
);
@@ -5647,7 +5874,7 @@ angular.module('patternfly.views').directive('pfListView', ["$timeout", "$window
'use strict';
$templateCache.put('sort/sort.html',
- ""
+ ""
);
}]);
diff --git a/dist/docs/grunt-scripts/angular-sanitize.js b/dist/docs/grunt-scripts/angular-sanitize.js
index 8161e4894..f4e25237b 100644
--- a/dist/docs/grunt-scripts/angular-sanitize.js
+++ b/dist/docs/grunt-scripts/angular-sanitize.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.5.2
+ * @license AngularJS v1.5.3
* (c) 2010-2016 Google, Inc. http://angularjs.org
* License: MIT
*/
diff --git a/dist/docs/grunt-scripts/angular.js b/dist/docs/grunt-scripts/angular.js
index 625177774..5e6fb2c36 100644
--- a/dist/docs/grunt-scripts/angular.js
+++ b/dist/docs/grunt-scripts/angular.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.5.2
+ * @license AngularJS v1.5.3
* (c) 2010-2016 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -57,7 +57,7 @@ function minErr(module, ErrorConstructor) {
return match;
});
- message += '\nhttp://errors.angularjs.org/1.5.2/' +
+ message += '\nhttp://errors.angularjs.org/1.5.3/' +
(module ? module + '/' : '') + code;
for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
@@ -2443,11 +2443,11 @@ function toDebugString(obj) {
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
*/
var version = {
- full: '1.5.2', // all of these placeholder strings will be replaced by grunt's
+ full: '1.5.3', // all of these placeholder strings will be replaced by grunt's
major: 1, // package task
minor: 5,
- dot: 2,
- codeName: 'differential-recovery'
+ dot: 3,
+ codeName: 'diplohaplontic-meiosis'
};
@@ -5862,7 +5862,14 @@ function Browser(window, document, $log, $sniffer) {
var cachedState, lastHistoryState,
lastBrowserUrl = location.href,
baseElement = document.find('base'),
- pendingLocation = null;
+ pendingLocation = null,
+ getCurrentState = !$sniffer.history ? noop : function getCurrentState() {
+ try {
+ return history.state;
+ } catch (e) {
+ // MSIE can reportedly throw when there is no state (UNCONFIRMED).
+ }
+ };
cacheState();
lastHistoryState = cachedState;
@@ -5970,14 +5977,6 @@ function Browser(window, document, $log, $sniffer) {
fireUrlChange();
}
- function getCurrentState() {
- try {
- return history.state;
- } catch (e) {
- // MSIE can reportedly throw when there is no state (UNCONFIRMED).
- }
- }
-
// This variable should be used *only* inside the cacheState function.
var lastCachedState = null;
function cacheState() {
@@ -6829,9 +6828,23 @@ function $TemplateCacheProvider() {
* `true` if the specified slot contains content (i.e. one or more DOM nodes).
*
* The controller can provide the following methods that act as life-cycle hooks:
- * * `$onInit` - Called on each controller after all the controllers on an element have been constructed and
+ * * `$onInit()` - Called on each controller after all the controllers on an element have been constructed and
* had their bindings initialized (and before the pre & post linking functions for the directives on
* this element). This is a good place to put initialization code for your controller.
+ * * `$onChanges(changesObj)` - Called whenever one-way (`<`) or interpolation (`@`) bindings are updated. The
+ * `changesObj` is a hash whose keys are the names of the bound properties that have changed, and the values are an
+ * object of the form `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component
+ * such as cloning the bound value to prevent accidental mutation of the outer value.
+ * * `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
+ * external resources, watches and event handlers. Note that components have their `$onDestroy()` hooks called in
+ * the same order as the `$scope.$broadcast` events are triggered, which is top down. This means that parent
+ * components will have their `$onDestroy()` hook called before child components.
+ * * `$postLink()` - Called after this controller's element and its children have been linked. Similar to the post-link
+ * function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
+ * Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
+ * they are waiting for their template to load asynchronously and their own compilation and linking has been
+ * suspended until that occurs.
+ *
*
* #### `require`
* Require another directive and inject its controller as the fourth argument to the linking function. The
@@ -7464,11 +7477,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
function assertValidDirectiveName(name) {
var letter = name.charAt(0);
if (!letter || letter !== lowercase(letter)) {
- throw $compileMinErr('baddir', "Directive name '{0}' is invalid. The first character must be a lowercase letter", name);
+ throw $compileMinErr('baddir', "Directive/Component name '{0}' is invalid. The first character must be a lowercase letter", name);
}
if (name !== name.trim()) {
throw $compileMinErr('baddir',
- "Directive name '{0}' is invalid. The name should not contain leading or trailing whitespaces",
+ "Directive/Component name '{0}' is invalid. The name should not contain leading or trailing whitespaces",
name);
}
}
@@ -7743,6 +7756,36 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
return debugInfoEnabled;
};
+
+ var TTL = 10;
+ /**
+ * @ngdoc method
+ * @name $compileProvider#onChangesTtl
+ * @description
+ *
+ * Sets the number of times `$onChanges` hooks can trigger new changes before giving up and
+ * assuming that the model is unstable.
+ *
+ * The current default is 10 iterations.
+ *
+ * In complex applications it's possible that dependencies between `$onChanges` hooks and bindings will result
+ * in several iterations of calls to these hooks. However if an application needs more than the default 10
+ * iterations to stabilize then you should investigate what is causing the model to continuously change during
+ * the `$onChanges` hook execution.
+ *
+ * Increasing the TTL could have performance implications, so you should not change it without proper justification.
+ *
+ * @param {number} limit The number of `$onChanges` hook iterations.
+ * @returns {number|object} the current limit (or `this` if called as a setter for chaining)
+ */
+ this.onChangesTtl = function(value) {
+ if (arguments.length) {
+ TTL = value;
+ return this;
+ }
+ return TTL;
+ };
+
this.$get = [
'$injector', '$interpolate', '$exceptionHandler', '$templateRequest', '$parse',
'$controller', '$rootScope', '$sce', '$animate', '$$sanitizeUri',
@@ -7751,6 +7794,36 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
var SIMPLE_ATTR_NAME = /^\w/;
var specialAttrHolder = document.createElement('div');
+
+
+
+ var onChangesTtl = TTL;
+ // The onChanges hooks should all be run together in a single digest
+ // When changes occur, the call to trigger their hooks will be added to this queue
+ var onChangesQueue;
+
+ // This function is called in a $$postDigest to trigger all the onChanges hooks in a single digest
+ function flushOnChangesQueue() {
+ try {
+ if (!(--onChangesTtl)) {
+ // We have hit the TTL limit so reset everything
+ onChangesQueue = undefined;
+ throw $compileMinErr('infchng', '{0} $onChanges() iterations reached. Aborting!\n', TTL);
+ }
+ // We must run this hook in an apply since the $$postDigest runs outside apply
+ $rootScope.$apply(function() {
+ for (var i = 0, ii = onChangesQueue.length; i < ii; ++i) {
+ onChangesQueue[i]();
+ }
+ // Reset the queue to trigger a new schedule next time there is a change
+ onChangesQueue = undefined;
+ });
+ } finally {
+ onChangesTtl++;
+ }
+ }
+
+
function Attributes(element, attributesToCopy) {
if (attributesToCopy) {
var keys = Object.keys(attributesToCopy);
@@ -8616,6 +8689,17 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
compileNode = $compileNode[0];
replaceWith(jqCollection, sliceArgs($template), compileNode);
+ // Support: Chrome < 50
+ // https://github.com/angular/angular.js/issues/14041
+
+ // In the versions of V8 prior to Chrome 50, the document fragment that is created
+ // in the `replaceWith` function is improperly garbage collected despite still
+ // being referenced by the `parentNode` property of all of the child nodes. By adding
+ // a reference to the fragment via a different property, we can avoid that incorrect
+ // behavior.
+ // TODO: remove this line after Chrome 50 has been released
+ $template[0].$$parentNode = $template[0].parentNode;
+
childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, terminalPriority,
replaceDirective && replaceDirective.name, {
// Don't pass in:
@@ -8898,10 +8982,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
});
- // Trigger the `$onInit` method on all controllers that have one
+ // Handle the init and destroy lifecycle hooks on all controllers that have them
forEach(elementControllers, function(controller) {
- if (isFunction(controller.instance.$onInit)) {
- controller.instance.$onInit();
+ var controllerInstance = controller.instance;
+ if (isFunction(controllerInstance.$onInit)) {
+ controllerInstance.$onInit();
+ }
+ if (isFunction(controllerInstance.$onDestroy)) {
+ controllerScope.$on('$destroy', function callOnDestroyHook() {
+ controllerInstance.$onDestroy();
+ });
}
});
@@ -8938,6 +9028,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
);
}
+ // Trigger $postLink lifecycle hooks
+ forEach(elementControllers, function(controller) {
+ var controllerInstance = controller.instance;
+ if (isFunction(controllerInstance.$postLink)) {
+ controllerInstance.$postLink();
+ }
+ });
+
// This is the function that is injected as `$transclude`.
// Note: all arguments are optional!
function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement, slotName) {
@@ -9533,6 +9631,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
// only occurs for isolate scopes and new scopes with controllerAs.
function initializeDirectiveBindings(scope, attrs, destination, bindings, directive) {
var removeWatchCollection = [];
+ var changes;
forEach(bindings, function initializeBinding(definition, scopeName) {
var attrName = definition.attrName,
optional = definition.optional,
@@ -9548,6 +9647,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
attrs.$observe(attrName, function(value) {
if (isString(value)) {
+ var oldValue = destination[scopeName];
+ recordChanges(scopeName, value, oldValue);
destination[scopeName] = value;
}
});
@@ -9619,6 +9720,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
destination[scopeName] = parentGet(scope);
removeWatch = scope.$watch(parentGet, function parentValueWatchAction(newParentValue) {
+ var oldValue = destination[scopeName];
+ recordChanges(scopeName, newParentValue, oldValue);
destination[scopeName] = newParentValue;
}, parentGet.literal);
@@ -9639,6 +9742,33 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
});
+ function recordChanges(key, currentValue, previousValue) {
+ if (isFunction(destination.$onChanges) && currentValue !== previousValue) {
+ // If we have not already scheduled the top level onChangesQueue handler then do so now
+ if (!onChangesQueue) {
+ scope.$$postDigest(flushOnChangesQueue);
+ onChangesQueue = [];
+ }
+ // If we have not already queued a trigger of onChanges for this controller then do so now
+ if (!changes) {
+ changes = {};
+ onChangesQueue.push(triggerOnChangesHook);
+ }
+ // If the has been a change on this property already then we need to reuse the previous value
+ if (changes[key]) {
+ previousValue = changes[key].previousValue;
+ }
+ // Store this change
+ changes[key] = {previousValue: previousValue, currentValue: currentValue};
+ }
+ }
+
+ function triggerOnChangesHook() {
+ destination.$onChanges(changes);
+ // Now clear the changes so that we schedule onChanges when more changes arrive
+ changes = undefined;
+ }
+
return removeWatchCollection.length && function removeWatches() {
for (var i = 0, ii = removeWatchCollection.length; i < ii; ++i) {
removeWatchCollection[i]();
@@ -15325,15 +15455,15 @@ function $ParseProvider() {
* [Kris Kowal's Q](https://github.com/kriskowal/q).
*
* $q can be used in two fashions --- one which is more similar to Kris Kowal's Q or jQuery's Deferred
- * implementations, and the other which resembles ES6 promises to some degree.
+ * implementations, and the other which resembles ES6 (ES2015) promises to some degree.
*
* # $q constructor
*
* The streamlined ES6 style promise is essentially just using $q as a constructor which takes a `resolver`
- * function as the first argument. This is similar to the native Promise implementation from ES6 Harmony,
+ * function as the first argument. This is similar to the native Promise implementation from ES6,
* see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
*
- * While the constructor-style use is supported, not all of the supporting methods from ES6 Harmony promises are
+ * While the constructor-style use is supported, not all of the supporting methods from ES6 promises are
* available yet.
*
* It can be used like so:
@@ -18471,6 +18601,10 @@ function $SceProvider() {
function $SnifferProvider() {
this.$get = ['$window', '$document', function($window, $document) {
var eventSupport = {},
+ // Chrome Packaged Apps are not allowed to access `history.pushState`. They can be detected by
+ // the presence of `chrome.app.runtime` (see https://developer.chrome.com/apps/api_index)
+ isChromePackagedApp = $window.chrome && $window.chrome.app && $window.chrome.app.runtime,
+ hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState,
android =
toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
@@ -18515,7 +18649,7 @@ function $SnifferProvider() {
// so let's not use the history API also
// We are purposefully using `!(android < 4)` to cover the case when `android` is undefined
// jshint -W018
- history: !!($window.history && $window.history.pushState && !(android < 4) && !boxee),
+ history: !!(hasHistoryPushState && !(android < 4) && !boxee),
// jshint +W018
hasEvent: function(event) {
// IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
@@ -19797,7 +19931,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
// format the integer digits with grouping separators
var groups = [];
- if (digits.length > pattern.lgSize) {
+ if (digits.length >= pattern.lgSize) {
groups.unshift(digits.splice(-pattern.lgSize).join(''));
}
while (digits.length > pattern.gSize) {
@@ -22033,7 +22167,7 @@ var inputType = {
}]);