1
1
/**
2
- * @license AngularJS v1.5.7
3
- * (c) 2010-2016 Google, Inc. http://angularjs.org
2
+ * @license AngularJS v1.7.8
3
+ * (c) 2010-2018 Google, Inc. http://angularjs.org
4
4
* License: MIT
5
5
*/
6
6
( function ( window , angular ) { 'use strict' ;
15
15
* attributes that convey state or semantic information about the application for users
16
16
* of assistive technologies, such as screen readers.
17
17
*
18
- * <div doc-module-components="ngAria"></div>
19
- *
20
18
* ## Usage
21
19
*
22
20
* For ngAria to do its magic, simply include the module `ngAria` as a dependency. The following
23
21
* directives are supported:
24
- * `ngModel`, `ngChecked`, `ngReadonly`, `ngRequired`, `ngValue`, `ngDisabled`, `ngShow`, `ngHide`, `ngClick`,
25
- * `ngDblClick`, and `ngMessages`.
22
+ * `ngModel`, `ngChecked`, `ngReadonly`, `ngRequired`, `ngValue`, `ngDisabled`, `ngShow`, `ngHide`,
23
+ * `ngClick`, ` ngDblClick`, and `ngMessages`.
26
24
*
27
25
* Below is a more detailed breakdown of the attributes handled by ngAria:
28
26
*
29
- * | Directive | Supported Attributes |
30
- * |---------------------------------------------|----------------------------------------------------------------------------------------|
27
+ * | Directive | Supported Attributes |
28
+ * |---------------------------------------------|----------------------------------------------------------------------------------------------------- |
31
29
* | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required, input roles |
32
- * | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled |
33
- * | {@link ng.directive:ngRequired ngRequired} | aria-required
34
- * | {@link ng.directive:ngChecked ngChecked} | aria-checked
35
- * | {@link ng.directive:ngReadonly ngReadonly} | aria-readonly |
36
- * | {@link ng.directive:ngValue ngValue} | aria-checked |
37
- * | {@link ng.directive:ngShow ngShow} | aria-hidden |
38
- * | {@link ng.directive:ngHide ngHide} | aria-hidden |
39
- * | {@link ng.directive:ngDblclick ngDblclick} | tabindex |
40
- * | {@link module:ngMessages ngMessages} | aria-live |
41
- * | {@link ng.directive:ngClick ngClick} | tabindex, keypress event, button role |
30
+ * | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled |
31
+ * | {@link ng.directive:ngRequired ngRequired} | aria-required |
32
+ * | {@link ng.directive:ngChecked ngChecked} | aria-checked |
33
+ * | {@link ng.directive:ngReadonly ngReadonly} | aria-readonly |
34
+ * | {@link ng.directive:ngValue ngValue} | aria-checked |
35
+ * | {@link ng.directive:ngShow ngShow} | aria-hidden |
36
+ * | {@link ng.directive:ngHide ngHide} | aria-hidden |
37
+ * | {@link ng.directive:ngDblclick ngDblclick} | tabindex |
38
+ * | {@link module:ngMessages ngMessages} | aria-live |
39
+ * | {@link ng.directive:ngClick ngClick} | tabindex, keydown event, button role |
42
40
*
43
41
* Find out more information about each directive by reading the
44
42
* {@link guide/accessibility ngAria Developer Guide}.
53
51
* <md-checkbox ng-disabled="disabled" aria-disabled="true">
54
52
* ```
55
53
*
56
- * ## Disabling Attributes
57
- * It's possible to disable individual attributes added by ngAria with the
54
+ * ## Disabling Specific Attributes
55
+ * It is possible to disable individual attributes added by ngAria with the
58
56
* {@link ngAria.$ariaProvider#config config} method. For more details, see the
59
57
* {@link guide/accessibility Developer Guide}.
58
+ *
59
+ * ## Disabling `ngAria` on Specific Elements
60
+ * It is possible to make `ngAria` ignore a specific element, by adding the `ng-aria-disable`
61
+ * attribute on it. Note that only the element itself (and not its child elements) will be ignored.
60
62
*/
61
- /* global -ngAriaModule */
63
+ var ARIA_DISABLE_ATTR = 'ngAriaDisable' ;
64
+
62
65
var ngAriaModule = angular . module ( 'ngAria' , [ 'ng' ] ) .
66
+ info ( { angularVersion : '1.7.8' } ) .
63
67
provider ( '$aria' , $AriaProvider ) ;
64
68
65
69
/**
@@ -75,6 +79,7 @@ var isNodeOneOf = function(elem, nodeTypeArray) {
75
79
/**
76
80
* @ngdoc provider
77
81
* @name $ariaProvider
82
+ * @this
78
83
*
79
84
* @description
80
85
*
@@ -103,7 +108,7 @@ function $AriaProvider() {
103
108
ariaInvalid : true ,
104
109
ariaValue : true ,
105
110
tabindex : true ,
106
- bindKeypress : true ,
111
+ bindKeydown : true ,
107
112
bindRoleForClick : true
108
113
} ;
109
114
@@ -119,12 +124,15 @@ function $AriaProvider() {
119
124
* - **ariaDisabled** – `{boolean}` – Enables/disables aria-disabled tags
120
125
* - **ariaRequired** – `{boolean}` – Enables/disables aria-required tags
121
126
* - **ariaInvalid** – `{boolean}` – Enables/disables aria-invalid tags
122
- * - **ariaValue** – `{boolean}` – Enables/disables aria-valuemin, aria-valuemax and aria-valuenow tags
127
+ * - **ariaValue** – `{boolean}` – Enables/disables aria-valuemin, aria-valuemax and
128
+ * aria-valuenow tags
123
129
* - **tabindex** – `{boolean}` – Enables/disables tabindex tags
124
- * - **bindKeypress** – `{boolean}` – Enables/disables keypress event binding on `div` and
125
- * `li` elements with ng-click
126
- * - **bindRoleForClick** – `{boolean}` – Adds role=button to non-interactive elements like `div`
127
- * using ng-click, making them more accessible to users of assistive technologies
130
+ * - **bindKeydown** – `{boolean}` – Enables/disables keyboard event binding on non-interactive
131
+ * elements (such as `div` or `li`) using ng-click, making them more accessible to users of
132
+ * assistive technologies
133
+ * - **bindRoleForClick** – `{boolean}` – Adds role=button to non-interactive elements (such as
134
+ * `div` or `li`) using ng-click, making them more accessible to users of assistive
135
+ * technologies
128
136
*
129
137
* @description
130
138
* Enables/disables various ARIA attributes
@@ -135,6 +143,8 @@ function $AriaProvider() {
135
143
136
144
function watchExpr ( attrName , ariaAttr , nodeBlackList , negate ) {
137
145
return function ( scope , elem , attr ) {
146
+ if ( attr . hasOwnProperty ( ARIA_DISABLE_ATTR ) ) return ;
147
+
138
148
var ariaCamelName = attr . $normalize ( ariaAttr ) ;
139
149
if ( config [ ariaCamelName ] && ! isNodeOneOf ( elem , nodeBlackList ) && ! attr [ ariaCamelName ] ) {
140
150
scope . $watch ( attr [ attrName ] , function ( boolVal ) {
@@ -227,14 +237,17 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
227
237
. directive ( 'ngModel' , [ '$aria' , function ( $aria ) {
228
238
229
239
function shouldAttachAttr ( attr , normalizedAttr , elem , allowBlacklistEls ) {
230
- return $aria . config ( normalizedAttr ) && ! elem . attr ( attr ) && ( allowBlacklistEls || ! isNodeOneOf ( elem , nodeBlackList ) ) ;
240
+ return $aria . config ( normalizedAttr ) &&
241
+ ! elem . attr ( attr ) &&
242
+ ( allowBlacklistEls || ! isNodeOneOf ( elem , nodeBlackList ) ) &&
243
+ ( elem . attr ( 'type' ) !== 'hidden' || elem [ 0 ] . nodeName !== 'INPUT' ) ;
231
244
}
232
245
233
246
function shouldAttachRole ( role , elem ) {
234
247
// if element does not have role attribute
235
248
// AND element type is equal to role (if custom element has a type equaling shape) <-- remove?
236
- // AND element is not INPUT
237
- return ! elem . attr ( 'role' ) && ( elem . attr ( 'type' ) === role ) && ( elem [ 0 ] . nodeName !== 'INPUT' ) ;
249
+ // AND element is not in nodeBlackList
250
+ return ! elem . attr ( 'role' ) && ( elem . attr ( 'type' ) === role ) && ! isNodeOneOf ( elem , nodeBlackList ) ;
238
251
}
239
252
240
253
function getShape ( attr , elem ) {
@@ -251,17 +264,11 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
251
264
require : 'ngModel' ,
252
265
priority : 200 , //Make sure watches are fired after any other directives that affect the ngModel value
253
266
compile : function ( elem , attr ) {
267
+ if ( attr . hasOwnProperty ( ARIA_DISABLE_ATTR ) ) return ;
268
+
254
269
var shape = getShape ( attr , elem ) ;
255
270
256
271
return {
257
- pre : function ( scope , elem , attr , ngModel ) {
258
- if ( shape === 'checkbox' ) {
259
- //Use the input[checkbox] $isEmpty implementation for elements with checkbox roles
260
- ngModel . $isEmpty = function ( value ) {
261
- return value === false ;
262
- } ;
263
- }
264
- } ,
265
272
post : function ( scope , elem , attr , ngModel ) {
266
273
var needsTabIndex = shouldAttachAttr ( 'tabindex' , 'tabindex' , elem , false ) ;
267
274
@@ -270,6 +277,8 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
270
277
}
271
278
272
279
function getRadioReaction ( newVal ) {
280
+ // Strict comparison would cause a BC
281
+ // eslint-disable-next-line eqeqeq
273
282
var boolVal = ( attr . value == ngModel . $viewValue ) ;
274
283
elem . attr ( 'aria-checked' , boolVal ) ;
275
284
}
@@ -353,6 +362,8 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
353
362
restrict : 'A' ,
354
363
require : '?ngMessages' ,
355
364
link : function ( scope , elem , attr , ngMessages ) {
365
+ if ( attr . hasOwnProperty ( ARIA_DISABLE_ATTR ) ) return ;
366
+
356
367
if ( ! elem . attr ( 'aria-live' ) ) {
357
368
elem . attr ( 'aria-live' , 'assertive' ) ;
358
369
}
@@ -363,7 +374,9 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
363
374
return {
364
375
restrict : 'A' ,
365
376
compile : function ( elem , attr ) {
366
- var fn = $parse ( attr . ngClick , /* interceptorFn */ null , /* expensiveChecks */ true ) ;
377
+ if ( attr . hasOwnProperty ( ARIA_DISABLE_ATTR ) ) return ;
378
+
379
+ var fn = $parse ( attr . ngClick ) ;
367
380
return function ( scope , elem , attr ) {
368
381
369
382
if ( ! isNodeOneOf ( elem , nodeBlackList ) ) {
@@ -376,10 +389,17 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
376
389
elem . attr ( 'tabindex' , 0 ) ;
377
390
}
378
391
379
- if ( $aria . config ( 'bindKeypress ' ) && ! attr . ngKeypress ) {
380
- elem . on ( 'keypress ' , function ( event ) {
392
+ if ( $aria . config ( 'bindKeydown ' ) && ! attr . ngKeydown && ! attr . ngKeypress && ! attr . ngKeyup ) {
393
+ elem . on ( 'keydown ' , function ( event ) {
381
394
var keyCode = event . which || event . keyCode ;
382
- if ( keyCode === 32 || keyCode === 13 ) {
395
+
396
+ if ( keyCode === 13 || keyCode === 32 ) {
397
+ // If the event is triggered on a non-interactive element ...
398
+ if ( nodeBlackList . indexOf ( event . target . nodeName ) === - 1 && ! event . target . isContentEditable ) {
399
+ // ... prevent the default browser behavior (e.g. scrolling when pressing spacebar)
400
+ // See https://github.com/angular/angular.js/issues/16664
401
+ event . preventDefault ( ) ;
402
+ }
383
403
scope . $apply ( callback ) ;
384
404
}
385
405
@@ -395,6 +415,8 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
395
415
} ] )
396
416
. directive ( 'ngDblclick' , [ '$aria' , function ( $aria ) {
397
417
return function ( scope , elem , attr ) {
418
+ if ( attr . hasOwnProperty ( ARIA_DISABLE_ATTR ) ) return ;
419
+
398
420
if ( $aria . config ( 'tabindex' ) && ! elem . attr ( 'tabindex' ) && ! isNodeOneOf ( elem , nodeBlackList ) ) {
399
421
elem . attr ( 'tabindex' , 0 ) ;
400
422
}
0 commit comments