text: export var KeyCodes;
  (function (KeyCodes) {
      KeyCodes[KeyCodes["Enter"] = 13] = "Enter";
      KeyCodes[KeyCodes["Escape"] = 27] = "Escape";
      KeyCodes[KeyCodes["Tab"] = 9] = "Tab";
      KeyCodes[KeyCodes["F10"] = 121] = "F10";
      KeyCodes[KeyCodes["P"] = 80] = "P";
  })(KeyCodes || (KeyCodes = {}));
  export function isEscape(e) {
      return isKey(KeyCodes.Escape, e);
  }
  export function isEnter(e) {
      return isKey(KeyCodes.Enter, e);
  }
  export function isShiftTab(e) {
      return isKey(KeyCodes.Tab, e, false, false, true);
  }
  export function isTab(e) {
      return isKey(KeyCodes.Tab, e);
  }
  export function isKey(
  /* tslint:disable-next-line:no-any */
  keyCode, e, allowAlt, allowCtrl, allowShift) {
      if (allowAlt === void 0) { allowAlt = false; }
      if (allowCtrl === void 0) { allowCtrl = false; }
      if (allowShift === void 0) { allowShift = false; }
      return e.keyCode === keyCode &&
          ((allowAlt && e.altKey) || (!allowAlt && !e.altKey)) &&
          ((allowCtrl && e.ctrlKey) || (!allowCtrl && !e.ctrlKey)) &&
          ((allowShift && e.shiftKey) || (!allowShift && !e.shiftKey));
  }
  export function getFocusableChildren(elem, ignoreTabIndex) {
      if (ignoreTabIndex === void 0) { ignoreTabIndex = false; }
      var children = [];
      for (var _i = 0, _a = getFocusableDescendants(elem, ignoreTabIndex); _i < _a.length; _i++) {
          var descendant = _a[_i];
          if (isElementFocusableChildOf(descendant, elem)) {
              children.push(descendant);
          }
      }
      return children;
  }
  export function isElementFocusable(elem, ignoreTabIndex) {
      if (ignoreTabIndex === void 0) { ignoreTabIndex = false; }
      var tagName = elem.tagName.toLowerCase();
      if (elem && !elem.hidden && elem.offsetParent && window.getComputedStyle(elem).display !== 'none') {
          var hasTabIndex = elem.hasAttribute('tabindex');
          // If TabIndex exists, then we can assume elem.getAttribute is not null
          var tabindex = hasTabIndex ? parseInt(elem.getAttribute('tabindex'), 10) : NaN;
          if (!ignoreTabIndex && hasTabIndex && tabindex < 0) {
              return false;
          }
          if (tagName === 'a' && !!elem.href ||
              elem.isContentEditable) {
              return true;
          }
          if ((tagName === 'button' ||
              tagName === 'input' ||
              tagName === 'select' ||
              tagName === 'textarea') && !elem.disabled) {
              return true;
          }
          /**
           * There are few cases like office-ui-fabric-react's dropdown control, which do not
           * use the conventional HTML elements to create dropdown. Instead they are using a
           * data attribute 'is-focusable' and making it focusable. Hence to respect those elements
           * added this check. Check this only when the 'ignoreTabIndex' is true, this is because when
           * user doesn't want to ignore tabindexes then tabindex will get preference over this attribute.
           */
          if (ignoreTabIndex && elem.getAttribute('data-is-focusable') === 'true') {
              return true;
          }
          if (!ignoreTabIndex && hasTabIndex && tabindex > -1) {
              return true;
          }
      }
      return false;
  }
  export function getFocusableParent(elem, topElement) {
      if (topElement === void 0) { topElement = document.body; }
      var parent = elem;
      do {
          // Impossible for parent to become null.
          parent = parent.parentElement;
      } while (parent &&
          !isElementFocusable(parent) &&
          !parent.isEqualNode(topElement) &&
          !parent.isEqualNode(document.body));
      return parent;
  }
  function queryFocusableSelector(elem) {
      var selector = 'button,input,textarea,select,a[href]:not([href=\'\']),\
        [tabindex],[contenteditable=\'true\'], [data-is-focusable=\'true\']';
      var nodes = elem.querySelectorAll(selector);
      return Array.prototype.slice.call(nodes);
  }
  export function getFirstFocusableChild(elem, ignoreTabIndex) {
      if (ignoreTabIndex === void 0) { ignoreTabIndex = false; }
      var elements = queryFocusableSelector(elem);
      var focusableElements = elements.filter(function (element) { return isElementFocusable(element, ignoreTabIndex); });
      // If the first focusable node is a radio input, we focus on the first checked one.
      // If there is no checked radio input, the first radio input will be focused.
      var firstFocusableElement = focusableElements[0];
      if (firstFocusableElement instanceof HTMLInputElement && firstFocusableElement.type === 'radio') {
          var results = focusableElements.filter(function (element) {
              return element instanceof HTMLInputElement &&
                  element.name === firstFocusableElement.name &&
                  element.checked;
          });
          return results[0] || firstFocusableElement;
      }
      return firstFocusableElement;
  }
  export function getFocusableDescendants(elem, ignoreTabIndex) {
      if (ignoreTabIndex === void 0) { ignoreTabIndex = false; }
      var descendants = [];
      var nodes = queryFocusableSelector(elem);
      for (var i = 0; i < nodes.length; i++) {
          var node = nodes[i];
          if (isElementFocusable(node, ignoreTabIndex)) {
              descendants.push(node);
          }
      }
      return descendants;
  }
  export function getFocusableSiblings(elem, topElement) {
      if (topElement === void 0) { topElement = document.body; }
      var children = getFocusableChildren(getFocusableParent(elem, topElement));
      // Remove input element and start the list from its next sibling
      var siblings = [];
      var insertPointer = 0;
      for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
          var child = children_1[_i];
          if (!child.isEqualNode(elem)) {
              siblings.splice(insertPointer++, 0, child);
          }
          else {
              insertPointer = 0;
          }
      }
      return siblings;
  }
  export function getNextFocusableElement(elem, topElement) {
      if (topElement === void 0) { topElement = document.body; }
      var siblings = getFocusableSiblings(elem, topElement);
      return siblings[0];
  }
  export function getPrevFocusableElement(elem, topElement) {
      if (topElement === void 0) { topElement = document.body; }
      var siblings = getFocusableSiblings(elem, topElement);
      return siblings[siblings.length - 1];
  }
  export function isElementFocusableChildOf(elem, ancestor) {
      var parent = elem.parentElement;
      while (parent && parent.tagName !== 'BODY') {
          if (parent.isEqualNode(ancestor)) {
              return true;
          }
          if (isElementFocusable(parent)) {
              break;
          }
          parent = parent.parentElement;
      }
      return false;
  }
  export function navigateInside(elem) {
      var children = getFocusableChildren(elem);
      if (children.length) {
          children[0].focus();
          return true;
      }
      else {
          return false;
      }
  }
  export function navigateTo(elem) {
      if (elem && isElementFocusable(elem)) {
          elem.focus();
          return true;
      }
      else {
          return navigateInside(elem);
      }
  }
  export function navigateOutOf(elem, topElement) {
      if (topElement === void 0) { topElement = document.body; }
      topElement = topElement || document.body;
      getFocusableParent(elem, topElement).focus();
  }
  var CanvasA11yManager = /** @class */ (function () {
      function CanvasA11yManager(canvasElement, shouldHandleKeyDown) {
          if (shouldHandleKeyDown === void 0) { shouldHandleKeyDown = true; }
          this._canvasElement = canvasElement;
          this._handleKeyDown = this._handleKeyDown.bind(this);
          this._randId = Math.floor(Math.random() * 1000000);
          if (shouldHandleKeyDown) {
              this._canvasElement.addEventListener('keydown', this._handleKeyDown);
          }
      }
      CanvasA11yManager.prototype.ariaAlert = function (message) {
          var divId = 'aria_alert_' + this._randId;
          var oldAlert = document.querySelector('#' + divId);
          if (oldAlert) {
              document.body.removeChild(oldAlert);
          }
          var alertNode = document.createElement('p');
          alertNode.classList.add('Canvas-screenReaderOnly');
          alertNode.setAttribute('role', 'alert');
          alertNode.setAttribute('id', divId);
          var alertText = document.createTextNode(message);
          alertNode.appendChild(alertText);
          document.body.appendChild(alertNode);
      };
      CanvasA11yManager.prototype.navigateInside = function (elem) {
          return navigateInside(elem);
      };
      CanvasA11yManager.prototype.navigateTo = function (elem) {
          return navigateTo(elem);
      };
      CanvasA11yManager.prototype.navigateOutOf = function (elem) {
          navigateOutOf(elem);
      };
      CanvasA11yManager.prototype.clearState = function () {
          this._savedFocusedElement = undefined;
      };
      CanvasA11yManager.prototype.restoreState = function () {
          return this._savedFocusedElement ? this.navigateTo(this._savedFocusedElement) : false;
      };
      CanvasA11yManager.prototype.saveState = function (elem) {
          elem = elem || document.activeElement;
          this._savedFocusedElement = elem;
      };
      CanvasA11yManager.prototype.skipEvent = function (e) {
          e[CanvasA11yManager._SKIP_FLAG] = true;
      };
      CanvasA11yManager.prototype._shouldSkipEvent = function (e) {
          return e[CanvasA11yManager._SKIP_FLAG];
      };
      CanvasA11yManager.prototype._handleKeyDown = function (e) {
          if (this._shouldSkipEvent(e)) {
              return;
          }
          var currentElement = isElementFocusable(e.target) ?
              e.target : getFocusableParent(e.target, this._canvasElement);
          var elementToGo;
          if (currentElement) {
              if (isTab(e)) {
                  var children = getFocusableChildren(this._canvasElement);
                  if (children.length && !currentElement.isEqualNode(children[children.length - 1])) {
                      elementToGo = getNextFocusableElement(currentElement, this._canvasElement);
                  }
              }
              else if (isShiftTab(e)) {
                  var children = getFocusableChildren(this._canvasElement);
                  if (children.length && !currentElement.isEqualNode(children[0])) {
                      elementToGo = getPrevFocusableElement(currentElement, this._canvasElement);
                  }
              }
              else if (isEnter(e)) {
                  var children = getFocusableChildren(currentElement);
                  elementToGo = children.length ? children[0] : undefined;
              }
              else if (isEscape(e)) {
                  elementToGo = getFocusableParent(currentElement, this._canvasElement);
              }
          }
          if (elementToGo) {
              elementToGo.focus();
              e.preventDefault();
              e.stopPropagation();
          }
      };
      CanvasA11yManager._SKIP_FLAG = 'a11y-skip';
      return CanvasA11yManager;
  }());
  export { CanvasA11yManager };
  //# sourceMappingURL=CanvasA11y.js.map