summaryrefslogtreecommitdiff
path: root/xstatic/pkg/angular/data/angular-aria.js
diff options
context:
space:
mode:
Diffstat (limited to 'xstatic/pkg/angular/data/angular-aria.js')
-rw-r--r--xstatic/pkg/angular/data/angular-aria.js207
1 files changed, 126 insertions, 81 deletions
diff --git a/xstatic/pkg/angular/data/angular-aria.js b/xstatic/pkg/angular/data/angular-aria.js
index 197b9c8..19bcbb6 100644
--- a/xstatic/pkg/angular/data/angular-aria.js
+++ b/xstatic/pkg/angular/data/angular-aria.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.3.7
+ * @license AngularJS v1.3.18
* (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -27,13 +27,13 @@
*
* | Directive | Supported Attributes |
* |---------------------------------------------|----------------------------------------------------------------------------------------|
- * | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required |
* | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled |
* | {@link ng.directive:ngShow ngShow} | aria-hidden |
* | {@link ng.directive:ngHide ngHide} | aria-hidden |
- * | {@link ng.directive:ngClick ngClick} | tabindex, keypress event |
* | {@link ng.directive:ngDblclick ngDblclick} | tabindex |
* | {@link module:ngMessages ngMessages} | aria-live |
+ * | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required, input roles |
+ * | {@link ng.directive:ngClick ngClick} | tabindex, keypress event, button role |
*
* Find out more information about each directive by reading the
* {@link guide/accessibility ngAria Developer Guide}.
@@ -105,7 +105,8 @@ function $AriaProvider() {
* - **ariaMultiline** – `{boolean}` – Enables/disables aria-multiline tags
* - **ariaValue** – `{boolean}` – Enables/disables aria-valuemin, aria-valuemax and aria-valuenow tags
* - **tabindex** – `{boolean}` – Enables/disables tabindex tags
- * - **bindKeypress** – `{boolean}` – Enables/disables keypress event binding on ng-click
+ * - **bindKeypress** – `{boolean}` – Enables/disables keypress event binding on `<div>` and
+ * `<li>` elements with ng-click
*
* @description
* Enables/disables various ARIA attributes
@@ -133,6 +134,7 @@ function $AriaProvider() {
* @name $aria
*
* @description
+ * @priority 200
*
* The $aria service contains helper methods for applying common
* [ARIA](http://www.w3.org/TR/wai-aria/) attributes to HTML directives.
@@ -196,6 +198,10 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
return $aria.config(normalizedAttr) && !elem.attr(attr);
}
+ function shouldAttachRole(role, elem) {
+ return !elem.attr('role') && (elem.attr('type') === role) && (elem[0].nodeName !== 'INPUT');
+ }
+
function getShape(attr, elem) {
var type = attr.type,
role = attr.role;
@@ -209,82 +215,102 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
return {
restrict: 'A',
require: '?ngModel',
- link: function(scope, elem, attr, ngModel) {
+ priority: 200, //Make sure watches are fired after any other directives that affect the ngModel value
+ compile: function(elem, attr) {
var shape = getShape(attr, elem);
- var needsTabIndex = shouldAttachAttr('tabindex', 'tabindex', elem);
-
- function ngAriaWatchModelValue() {
- return ngModel.$modelValue;
- }
-
- function getRadioReaction() {
- if (needsTabIndex) {
- needsTabIndex = false;
- return function ngAriaRadioReaction(newVal) {
- var boolVal = newVal === attr.value;
- elem.attr('aria-checked', boolVal);
- elem.attr('tabindex', 0 - !boolVal);
- };
- } else {
- return function ngAriaRadioReaction(newVal) {
- elem.attr('aria-checked', newVal === attr.value);
- };
- }
- }
- function ngAriaCheckboxReaction(newVal) {
- elem.attr('aria-checked', !!newVal);
- }
+ return {
+ pre: function(scope, elem, attr, ngModel) {
+ if (shape === 'checkbox' && attr.type !== 'checkbox') {
+ //Use the input[checkbox] $isEmpty implementation for elements with checkbox roles
+ ngModel.$isEmpty = function(value) {
+ return value === false;
+ };
+ }
+ },
+ post: function(scope, elem, attr, ngModel) {
+ var needsTabIndex = shouldAttachAttr('tabindex', 'tabindex', elem);
- switch (shape) {
- case 'radio':
- case 'checkbox':
- if (shouldAttachAttr('aria-checked', 'ariaChecked', elem)) {
- scope.$watch(ngAriaWatchModelValue, shape === 'radio' ?
- getRadioReaction() : ngAriaCheckboxReaction);
+ function ngAriaWatchModelValue() {
+ return ngModel.$modelValue;
}
- break;
- case 'range':
- if ($aria.config('ariaValue')) {
- if (attr.min && !elem.attr('aria-valuemin')) {
- elem.attr('aria-valuemin', attr.min);
- }
- if (attr.max && !elem.attr('aria-valuemax')) {
- elem.attr('aria-valuemax', attr.max);
- }
- if (!elem.attr('aria-valuenow')) {
- scope.$watch(ngAriaWatchModelValue, function ngAriaValueNowReaction(newVal) {
- elem.attr('aria-valuenow', newVal);
- });
+
+ function getRadioReaction() {
+ if (needsTabIndex) {
+ needsTabIndex = false;
+ return function ngAriaRadioReaction(newVal) {
+ var boolVal = (attr.value == ngModel.$viewValue);
+ elem.attr('aria-checked', boolVal);
+ elem.attr('tabindex', 0 - !boolVal);
+ };
+ } else {
+ return function ngAriaRadioReaction(newVal) {
+ elem.attr('aria-checked', (attr.value == ngModel.$viewValue));
+ };
}
}
- break;
- case 'multiline':
- if (shouldAttachAttr('aria-multiline', 'ariaMultiline', elem)) {
- elem.attr('aria-multiline', true);
+
+ function ngAriaCheckboxReaction() {
+ elem.attr('aria-checked', !ngModel.$isEmpty(ngModel.$viewValue));
}
- break;
- }
- if (needsTabIndex) {
- elem.attr('tabindex', 0);
- }
+ switch (shape) {
+ case 'radio':
+ case 'checkbox':
+ if (shouldAttachRole(shape, elem)) {
+ elem.attr('role', shape);
+ }
+ if (shouldAttachAttr('aria-checked', 'ariaChecked', elem)) {
+ scope.$watch(ngAriaWatchModelValue, shape === 'radio' ?
+ getRadioReaction() : ngAriaCheckboxReaction);
+ }
+ break;
+ case 'range':
+ if (shouldAttachRole(shape, elem)) {
+ elem.attr('role', 'slider');
+ }
+ if ($aria.config('ariaValue')) {
+ if (attr.min && !elem.attr('aria-valuemin')) {
+ elem.attr('aria-valuemin', attr.min);
+ }
+ if (attr.max && !elem.attr('aria-valuemax')) {
+ elem.attr('aria-valuemax', attr.max);
+ }
+ if (!elem.attr('aria-valuenow')) {
+ scope.$watch(ngAriaWatchModelValue, function ngAriaValueNowReaction(newVal) {
+ elem.attr('aria-valuenow', newVal);
+ });
+ }
+ }
+ break;
+ case 'multiline':
+ if (shouldAttachAttr('aria-multiline', 'ariaMultiline', elem)) {
+ elem.attr('aria-multiline', true);
+ }
+ break;
+ }
- if (ngModel.$validators.required && shouldAttachAttr('aria-required', 'ariaRequired', elem)) {
- scope.$watch(function ngAriaRequiredWatch() {
- return ngModel.$error.required;
- }, function ngAriaRequiredReaction(newVal) {
- elem.attr('aria-required', !!newVal);
- });
- }
+ if (needsTabIndex) {
+ elem.attr('tabindex', 0);
+ }
- if (shouldAttachAttr('aria-invalid', 'ariaInvalid', elem)) {
- scope.$watch(function ngAriaInvalidWatch() {
- return ngModel.$invalid;
- }, function ngAriaInvalidReaction(newVal) {
- elem.attr('aria-invalid', !!newVal);
- });
- }
+ if (ngModel.$validators.required && shouldAttachAttr('aria-required', 'ariaRequired', elem)) {
+ scope.$watch(function ngAriaRequiredWatch() {
+ return ngModel.$error.required;
+ }, function ngAriaRequiredReaction(newVal) {
+ elem.attr('aria-required', !!newVal);
+ });
+ }
+
+ if (shouldAttachAttr('aria-invalid', 'ariaInvalid', elem)) {
+ scope.$watch(function ngAriaInvalidWatch() {
+ return ngModel.$invalid;
+ }, function ngAriaInvalidReaction(newVal) {
+ elem.attr('aria-invalid', !!newVal);
+ });
+ }
+ }
+ };
}
};
}])
@@ -302,21 +328,40 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
}
};
})
-.directive('ngClick',['$aria', function($aria) {
+.directive('ngClick',['$aria', '$parse', function($aria, $parse) {
return {
restrict: 'A',
- link: function(scope, elem, attr) {
- if ($aria.config('tabindex') && !elem.attr('tabindex')) {
- elem.attr('tabindex', 0);
- }
+ compile: function(elem, attr) {
+ var fn = $parse(attr.ngClick, /* interceptorFn */ null, /* expensiveChecks */ true);
+ return function(scope, elem, attr) {
+
+ var nodeBlackList = ['BUTTON', 'A', 'INPUT', 'TEXTAREA'];
- if ($aria.config('bindKeypress') && !elem.attr('ng-keypress')) {
- elem.on('keypress', function(event) {
- if (event.keyCode === 32 || event.keyCode === 13) {
- scope.$eval(attr.ngClick);
+ function isNodeOneOf(elem, nodeTypeArray) {
+ if (nodeTypeArray.indexOf(elem[0].nodeName) !== -1) {
+ return true;
}
- });
- }
+ }
+ if (!elem.attr('role') && !isNodeOneOf(elem, nodeBlackList)) {
+ elem.attr('role', 'button');
+ }
+
+ if ($aria.config('tabindex') && !elem.attr('tabindex')) {
+ elem.attr('tabindex', 0);
+ }
+
+ if ($aria.config('bindKeypress') && !attr.ngKeypress && !isNodeOneOf(elem, nodeBlackList)) {
+ elem.on('keypress', function(event) {
+ if (event.keyCode === 32 || event.keyCode === 13) {
+ scope.$apply(callback);
+ }
+
+ function callback() {
+ fn(scope, { $event: event });
+ }
+ });
+ }
+ };
}
};
}])