@@ -105,22 +105,25 @@ angular
105105 * icon and to change the icon size. These settings only affect the downloaded icons.
106106 *
107107 * @param {string } md-font-icon String name of CSS icon associated with the font-face will be used
108- * to render the icon. Requires the fonts and the named CSS styles to be preloaded.
108+ * to render the icon. Requires the fonts and the named CSS styles to be preloaded.
109109 * @param {string } md-font-set CSS style name associated with the font library; which will be assigned as
110- * the class for the font-icon ligature. This value may also be an alias that is used to lookup the classname;
111- * internally use `$mdIconProvider.fontSet(<alias>)` to determine the style name.
110+ * the class for the font-icon ligature. This value may also be an alias that is used to lookup the classname;
111+ * internally use `$mdIconProvider.fontSet(<alias>)` to determine the style name.
112112 * @param {string } md-svg-src String URL (or expression) used to load, cache, and display an
113- * external SVG.
113+ * external SVG.
114114 * @param {string } md-svg-icon md-svg-icon String name used for lookup of the icon from the internal cache;
115- * interpolated strings or expressions may also be used. Specific set names can be used with
116- * the syntax `<set name>:<icon name>`.<br/><br/>
117- * To use icon sets, developers are required to pre-register the sets using the `$mdIconProvider` service.
118- * @param {string= } aria-label Labels icon for accessibility. If an empty string is provided, icon
119- * will be hidden from accessibility layer with `aria-hidden="true"`. If there's no aria-label on the icon
120- * nor a label on the parent element, a warning will be logged to the console.
121- * @param {string= } alt Labels icon for accessibility. If an empty string is provided, icon
122- * will be hidden from accessibility layer with `aria-hidden="true"`. If there's no alt on the icon
123- * nor a label on the parent element, a warning will be logged to the console.
115+ * interpolated strings or expressions may also be used. Specific set names can be used with
116+ * the syntax `<set name>:<icon name>`.<br/><br/>
117+ * To use icon sets, developers are required to pre-register the sets using the `$mdIconProvider` service.
118+ * @param {string= } aria-label Labels the icon for accessibility. If an empty string is provided,
119+ * the icon will be hidden from the accessibility layer with `aria-hidden="true"`. If there is no
120+ * `aria-label` attribute on the icon, we check the following, in order: the `alt` attribute, the
121+ * `aria-label` from the parent element, the icon's `md-font-icon` or `md-svg-icon` string, and the
122+ * text content inside `<md-icon></md-icon>`. If none of these have any text, the icon is hidden
123+ * from the accessibility layer with `aria-hidden="true"`.
124+ * @param {string= } alt Labels the icon for accessibility. If an empty string is provided and the
125+ * icon has no `aria-label`, then the icon will be hidden from accessibility layer with
126+ * `aria-hidden="true"`.
124127 *
125128 * @usage
126129 * When using SVGs:
@@ -198,7 +201,10 @@ function mdIconDirective($mdIcon, $mdTheming, $mdAria, $sce) {
198201
199202 /**
200203 * Directive postLink
201- * Supports embedded SVGs, font-icons, & external SVGs
204+ * Supports embedded SVGs, font-icons, & external SVGs.
205+ * @param {IScope } scope
206+ * @param {JQLite } element
207+ * @param {IAttributes } attr
202208 */
203209 function postLink ( scope , element , attr ) {
204210 $mdTheming ( element ) ;
@@ -210,40 +216,40 @@ function mdIconDirective($mdIcon, $mdTheming, $mdAria, $sce) {
210216 attr . $observe ( 'mdFontIcon' , fontIconChanged ) ;
211217 attr . $observe ( 'mdFontSet' , fontIconChanged ) ;
212218
213- // Keep track of the content of the svg src so we can compare against it later to see if the
214- // attribute is static (and thus safe).
215- var originalSvgSrc = element [ 0 ] . getAttribute ( attr . $attr . mdSvgSrc ) ;
216-
217- // If using a font-icon, then the textual name of the icon itself
218- // provides the aria-label.
219-
220- var attrName = attr . $normalize ( attr . $attr . mdSvgIcon || attr . $attr . mdSvgSrc || '' ) ;
221-
222219 /* Provide a default accessibility role of img */
223220 if ( ! attr . role ) {
224221 $mdAria . expect ( element , 'role' , 'img' ) ;
225222 /* manually update attr variable */
226223 attr . role = 'img' ;
227224 }
228225
226+ // If the aria-label is explicitly set to the empty string, then hide this element from the
227+ // accessibility layer.
228+ if ( element [ 0 ] . hasAttribute ( 'aria-label' ) && attr . ariaLabel === '' ) {
229+ element . attr ( 'aria-hidden' , true ) ;
230+ }
231+
229232 /* Don't process ARIA if already valid */
230233 if ( attr . role === "img" && ! attr . ariaHidden && ! $mdAria . hasAriaLabel ( element ) ) {
231- var iconName ;
232- if ( attr . alt ) {
233- /* Use alt text by default if available */
234+ // If the developer signals to hide this icon from the accessibility layer, do so.
235+ if ( element [ 0 ] . hasAttribute ( 'alt' ) && attr . alt === '' ) {
236+ element . attr ( 'aria-hidden' , true ) ;
237+ } else if ( attr . alt ) {
238+ /* Use the alt text for the aria-label by default, if available. */
234239 $mdAria . expect ( element , 'aria-label' , attr . alt ) ;
235240 } else if ( $mdAria . parentHasAriaLabel ( element , 2 ) ) {
236- /* Parent has ARIA so we will assume it will describe the image */
241+ /* Parent has ARIA so we will assume it will describe the icon. */
237242 $mdAria . expect ( element , 'aria-hidden' , 'true' ) ;
238- } else if ( iconName = ( attr . mdFontIcon || attr . mdSvgIcon || element . text ( ) ) ) {
239- /* Use icon name as aria-label */
240- $mdAria . expect ( element , 'aria-label' , iconName ) ;
243+ } else if ( attr . mdFontIcon || attr . mdSvgIcon || element . text ( ) ) {
244+ /* Use icon name or node's text content as the aria-label */
245+ $mdAria . expect ( element , 'aria-label' , attr . mdFontIcon || attr . mdSvgIcon || element . text ( ) ) ;
241246 } else {
242- /* No label found */
247+ /* No label found, hide this icon from the accessibility layer */
243248 $mdAria . expect ( element , 'aria-hidden' , 'true' ) ;
244249 }
245250 }
246251
252+ var attrName = attr . $normalize ( attr . $attr . mdSvgIcon || attr . $attr . mdSvgSrc || '' ) ;
247253 if ( attrName ) {
248254 // Use either pre-configured SVG or URL source, respectively.
249255 attr . $observe ( attrName , function ( attrVal ) {
0 commit comments