/**
 * @license AngularJS v1.4.8
 * (c) 2010-2015 Google, Inc. http://angularjs.org
 * License: MIT
 */
(function(window, angular, undefined) {'use strict';

/**
 * @ngdoc module
 * @name ngAria
 * @description
 *
 * The `ngAria` module provides support for common
 * [<abbr title="Accessible Rich Internet Applications">ARIA</abbr>](http://www.w3.org/TR/wai-aria/)
 * attributes that convey state or semantic information about the application for users
 * of assistive technologies, such as screen readers.
 *
 * <div doc-module-components="ngAria"></div>
 *
 * ## Usage
 *
 * For ngAria to do its magic, simply include the module `ngAria` as a dependency. The following
 * directives are supported:
 * `ngModel`, `ngDisabled`, `ngShow`, `ngHide`, `ngClick`, `ngDblClick`, and `ngMessages`.
 *
 * Below is a more detailed breakdown of the attributes handled by ngAria:
 *
 * | Directive                                   | Supported Attributes                                                                   |
 * |---------------------------------------------|----------------------------------------------------------------------------------------|
 * | {@link ng.directive:ngDisabled ngDisabled}  | aria-disabled                                                                          |
 * | {@link ng.directive:ngShow ngShow}          | aria-hidden                                                                            |
 * | {@link ng.directive:ngHide ngHide}          | aria-hidden                                                                            |
 * | {@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}.
 *
 * ##Example
 * Using ngDisabled with ngAria:
 * ```html
 * <md-checkbox ng-disabled="disabled">
 * ```
 * Becomes:
 * ```html
 * <md-checkbox ng-disabled="disabled" aria-disabled="true">
 * ```
 *
 * ##Disabling Attributes
 * It's possible to disable individual attributes added by ngAria with the
 * {@link ngAria.$ariaProvider#config config} method. For more details, see the
 * {@link guide/accessibility Developer Guide}.
 */
 /* global -ngAriaModule */
var ngAriaModule = angular.module('ngAria', ['ng']).
                        provider('$aria', $AriaProvider);

/**
* Internal Utilities
*/
var nodeBlackList = ['BUTTON', 'A', 'INPUT', 'TEXTAREA', 'SELECT', 'DETAILS', 'SUMMARY'];

var isNodeOneOf = function(elem, nodeTypeArray) {
  if (nodeTypeArray.indexOf(elem[0].nodeName) !== -1) {
    return true;
  }
};
/**
 * @ngdoc provider
 * @name $ariaProvider
 *
 * @description
 *
 * Used for configuring the ARIA attributes injected and managed by ngAria.
 *
 * ```js
 * angular.module('myApp', ['ngAria'], function config($ariaProvider) {
 *   $ariaProvider.config({
 *     ariaValue: true,
 *     tabindex: false
 *   });
 * });
 *```
 *
 * ## Dependencies
 * Requires the {@link ngAria} module to be installed.
 *
 */
function $AriaProvider() {
  var config = {
    ariaHidden: true,
    ariaChecked: true,
    ariaDisabled: true,
    ariaRequired: true,
    ariaInvalid: true,
    ariaMultiline: true,
    ariaValue: true,
    tabindex: true,
    bindKeypress: true,
    bindRoleForClick: true
  };

  /**
   * @ngdoc method
   * @name $ariaProvider#config
   *
   * @param {object} config object to enable/disable specific ARIA attributes
   *
   *  - **ariaHidden** – `{boolean}` – Enables/disables aria-hidden tags
   *  - **ariaChecked** – `{boolean}` – Enables/disables aria-checked tags
   *  - **ariaDisabled** – `{boolean}` – Enables/disables aria-disabled tags
   *  - **ariaRequired** – `{boolean}` – Enables/disables aria-required tags
   *  - **ariaInvalid** – `{boolean}` – Enables/disables aria-invalid tags
   *  - **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 `&lt;div&gt;` and
   *    `&lt;li&gt;` elements with ng-click
   *  - **bindRoleForClick** – `{boolean}` – Adds role=button to non-interactive elements like `div`
   *    using ng-click, making them more accessible to users of assistive technologies
   *
   * @description
   * Enables/disables various ARIA attributes
   */
  this.config = function(newConfig) {
    config = angular.extend(config, newConfig);
  };

  function watchExpr(attrName, ariaAttr, nodeBlackList, negate) {
    return function(scope, elem, attr) {
      var ariaCamelName = attr.$normalize(ariaAttr);
      if (config[ariaCamelName] && !isNodeOneOf(elem, nodeBlackList) && !attr[ariaCamelName]) {
        scope.$watch(attr[attrName], function(boolVal) {
          // ensure boolean value
          boolVal = negate ? !boolVal : !!boolVal;
          elem.attr(ariaAttr, boolVal);
        });
      }
    };
  }
  /**
   * @ngdoc service
   * @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.
   *
   * ngAria injects common accessibility attributes that tell assistive technologies when HTML
   * elements are enabled, selected, hidden, and more. To see how this is performed with ngAria,
   * let's review a code snippet from ngAria itself:
   *
   *```js
   * ngAriaModule.directive('ngDisabled', ['$aria', function($aria) {
   *   return $aria.$$watchExpr('ngDisabled', 'aria-disabled');
   * }])
   *```
   * Shown above, the ngAria module creates a directive with the same signature as the
   * traditional `ng-disabled` directive. But this ngAria version is dedicated to
   * solely managing accessibility attributes. The internal `$aria` service is used to watch the
   * boolean attribute `ngDisabled`. If it has not been explicitly set by the developer,
   * `aria-disabled` is injected as an attribute with its value synchronized to the value in
   * `ngDisabled`.
   *
   * Because ngAria hooks into the `ng-disabled` directive, developers do not have to do
   * anything to enable this feature. The `aria-disabled` attribute is automatically managed
   * simply as a silent side-effect of using `ng-disabled` with the ngAria module.
   *
   * The full list of directives that interface with ngAria:
   * * **ngModel**
   * * **ngShow**
   * * **ngHide**
   * * **ngClick**
   * * **ngDblclick**
   * * **ngMessages**
   * * **ngDisabled**
   *
   * Read the {@link guide/accessibility ngAria Developer Guide} for a thorough explanation of each
   * directive.
   *
   *
   * ## Dependencies
   * Requires the {@link ngAria} module to be installed.
   */
  this.$get = function() {
    return {
      config: function(key) {
        return config[key];
      },
      $$watchExpr: watchExpr
    };
  };
}


ngAriaModule.directive('ngShow', ['$aria', function($aria) {
  return $aria.$$watchExpr('ngShow', 'aria-hidden', [], true);
}])
.directive('ngHide', ['$aria', function($aria) {
  return $aria.$$watchExpr('ngHide', 'aria-hidden', [], false);
}])
.directive('ngModel', ['$aria', function($aria) {

  function shouldAttachAttr(attr, normalizedAttr, elem) {
    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;

    return ((type || role) === 'checkbox' || role === 'menuitemcheckbox') ? 'checkbox' :
           ((type || role) === 'radio'    || role === 'menuitemradio') ? 'radio' :
           (type === 'range'              || role === 'progressbar' || role === 'slider') ? 'range' :
           (type || role) === 'textbox'   || elem[0].nodeName === 'TEXTAREA' ? 'multiline' : '';
  }

  return {
    restrict: 'A',
    require: '?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);

      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)
                                && !isNodeOneOf(elem, nodeBlackList);

          function ngAriaWatchModelValue() {
            return ngModel.$modelValue;
          }

          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));
              };
            }
          }

          function ngAriaCheckboxReaction() {
            elem.attr('aria-checked', !ngModel.$isEmpty(ngModel.$viewValue));
          }

          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);
              }
              if (needsTabIndex) {
                elem.attr('tabindex', 0);
              }
              break;
            case 'range':
              if (shouldAttachRole(shape, elem)) {
                elem.attr('role', 'slider');
              }
              if ($aria.config('ariaValue')) {
                var needsAriaValuemin = !elem.attr('aria-valuemin') &&
                    (attr.hasOwnProperty('min') || attr.hasOwnProperty('ngMin'));
                var needsAriaValuemax = !elem.attr('aria-valuemax') &&
                    (attr.hasOwnProperty('max') || attr.hasOwnProperty('ngMax'));
                var needsAriaValuenow = !elem.attr('aria-valuenow');

                if (needsAriaValuemin) {
                  attr.$observe('min', function ngAriaValueMinReaction(newVal) {
                    elem.attr('aria-valuemin', newVal);
                  });
                }
                if (needsAriaValuemax) {
                  attr.$observe('max', function ngAriaValueMinReaction(newVal) {
                    elem.attr('aria-valuemax', newVal);
                  });
                }
                if (needsAriaValuenow) {
                  scope.$watch(ngAriaWatchModelValue, function ngAriaValueNowReaction(newVal) {
                    elem.attr('aria-valuenow', newVal);
                  });
                }
              }
              if (needsTabIndex) {
                elem.attr('tabindex', 0);
              }
              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 (shouldAttachAttr('aria-invalid', 'ariaInvalid', elem)) {
            scope.$watch(function ngAriaInvalidWatch() {
              return ngModel.$invalid;
            }, function ngAriaInvalidReaction(newVal) {
              elem.attr('aria-invalid', !!newVal);
            });
          }
        }
      };
    }
  };
}])
.directive('ngDisabled', ['$aria', function($aria) {
  return $aria.$$watchExpr('ngDisabled', 'aria-disabled', []);
}])
.directive('ngMessages', function() {
  return {
    restrict: 'A',
    require: '?ngMessages',
    link: function(scope, elem, attr, ngMessages) {
      if (!elem.attr('aria-live')) {
        elem.attr('aria-live', 'assertive');
      }
    }
  };
})
.directive('ngClick',['$aria', '$parse', function($aria, $parse) {
  return {
    restrict: 'A',
    compile: function(elem, attr) {
      var fn = $parse(attr.ngClick, /* interceptorFn */ null, /* expensiveChecks */ true);
      return function(scope, elem, attr) {

        if (!isNodeOneOf(elem, nodeBlackList)) {

          if ($aria.config('bindRoleForClick') && !elem.attr('role')) {
            elem.attr('role', 'button');
          }

          if ($aria.config('tabindex') && !elem.attr('tabindex')) {
            elem.attr('tabindex', 0);
          }

          if ($aria.config('bindKeypress') && !attr.ngKeypress) {
            elem.on('keypress', function(event) {
              var keyCode = event.which || event.keyCode;
              if (keyCode === 32 || keyCode === 13) {
                scope.$apply(callback);
              }

              function callback() {
                fn(scope, { $event: event });
              }
            });
          }
        }
      };
    }
  };
}])
.directive('ngDblclick', ['$aria', function($aria) {
  return function(scope, elem, attr) {
    if ($aria.config('tabindex') && !elem.attr('tabindex') && !isNodeOneOf(elem, nodeBlackList)) {
      elem.attr('tabindex', 0);
    }
  };
}]);


})(window, window.angular);
