function positionDropdown () {
    if (!elements) {
      return $mdUtil.nextTick(positionDropdown, false, $scope);
    }

    var dropdownHeight = ($scope.dropdownItems || MAX_ITEMS) * ITEM_HEIGHT;

    var hrect  = elements.wrap.getBoundingClientRect(),
        vrect  = elements.snap.getBoundingClientRect(),
        root   = elements.root.getBoundingClientRect(),
        top    = vrect.bottom - root.top,
        bot    = root.bottom - vrect.top,
        left   = hrect.left - root.left,
        width  = hrect.width,
        offset = getVerticalOffset(),
        position = $scope.dropdownPosition,
        styles;

    // Automatically determine dropdown placement based on available space in viewport.
    if (!position) {
      position = (top > bot && root.height - top - MENU_PADDING < dropdownHeight) ? 'top' : 'bottom';
    }
    // Adjust the width to account for the padding provided by `md-input-container`
    if ($attrs.mdFloatingLabel) {
      left += INPUT_PADDING;
      width -= INPUT_PADDING * 2;
    }
    styles = {
      left:     left + 'px',
      minWidth: width + 'px',
      maxWidth: Math.max(hrect.right - root.left, root.right - hrect.left) - MENU_PADDING + 'px'
    };

    if (position === 'top') {
      styles.top       = 'auto';
      styles.bottom    = bot + 'px';
      styles.maxHeight = Math.min(dropdownHeight, hrect.top - root.top - MENU_PADDING) + 'px';
    } else {
      var bottomSpace = root.bottom - hrect.bottom - MENU_PADDING + $mdUtil.getViewportTop();

      styles.top       = (top - offset) + 'px';
      styles.bottom    = 'auto';
      styles.maxHeight = Math.min(dropdownHeight, bottomSpace) + 'px';
    }

    elements.$.scrollContainer.css(styles);
    $mdUtil.nextTick(correctHorizontalAlignment, false);

    /**
     * Calculates the vertical offset for floating label examples to account for ngMessages
     * @returns {number}
     */
    function getVerticalOffset () {
      var offset = 0;
      var inputContainer = $element.find('md-input-container');
      if (inputContainer.length) {
        var input = inputContainer.find('input');
        offset = inputContainer.prop('offsetHeight');
        offset -= input.prop('offsetTop');
        offset -= input.prop('offsetHeight');
        // add in the height left up top for the floating label text
        offset += inputContainer.prop('offsetTop');
      }
      return offset;
    }

    /**
     * Makes sure that the menu doesn't go off of the screen on either side.
     */
    function correctHorizontalAlignment () {
      var dropdown = elements.scrollContainer.getBoundingClientRect(),
          styles   = {};
      if (dropdown.right > root.right - MENU_PADDING) {
        styles.left = (hrect.right - dropdown.width) + 'px';
      }
      elements.$.scrollContainer.css(styles);
    }
  }
function positionDropdown () {
    if (!elements) {
      return $mdUtil.nextTick(positionDropdown, false, $scope);
    }

    var dropdownHeight = ($scope.dropdownItems || MAX_ITEMS) * ITEM_HEIGHT;

    var hrect  = elements.wrap.getBoundingClientRect(),
        vrect  = elements.snap.getBoundingClientRect(),
        root   = elements.root.getBoundingClientRect(),
        top    = vrect.bottom - root.top,
        bot    = root.bottom - vrect.top,
        left   = hrect.left - root.left,
        width  = hrect.width,
        offset = getVerticalOffset(),
        position = $scope.dropdownPosition,
        styles;

    
    if (!position) {
      position = (top > bot && root.height - top - MENU_PADDING < dropdownHeight) ? 'top' : 'bottom';
    }
    
    if ($attrs.mdFloatingLabel) {
      left += INPUT_PADDING;
      width -= INPUT_PADDING * 2;
    }
    styles = {
      left:     left + 'px',
      minWidth: width + 'px',
      maxWidth: Math.max(hrect.right - root.left, root.right - hrect.left) - MENU_PADDING + 'px'
    };

    if (position === 'top') {
      styles.top       = 'auto';
      styles.bottom    = bot + 'px';
      styles.maxHeight = Math.min(dropdownHeight, hrect.top - root.top - MENU_PADDING) + 'px';
    } else {
      var bottomSpace = root.bottom - hrect.bottom - MENU_PADDING + $mdUtil.getViewportTop();

      styles.top       = (top - offset) + 'px';
      styles.bottom    = 'auto';
      styles.maxHeight = Math.min(dropdownHeight, bottomSpace) + 'px';
    }

    elements.$.scrollContainer.css(styles);
    $mdUtil.nextTick(correctHorizontalAlignment, false);

    
    function getVerticalOffset () {
      var offset = 0;
      var inputContainer = $element.find('md-input-container');
      if (inputContainer.length) {
        var input = inputContainer.find('input');
        offset = inputContainer.prop('offsetHeight');
        offset -= input.prop('offsetTop');
        offset -= input.prop('offsetHeight');
        
        offset += inputContainer.prop('offsetTop');
      }
      return offset;
    }

    
    function correctHorizontalAlignment () {
      var dropdown = elements.scrollContainer.getBoundingClientRect(),
          styles   = {};
      if (dropdown.right > root.right - MENU_PADDING) {
        styles.left = (hrect.right - dropdown.width) + 'px';
      }
      elements.$.scrollContainer.css(styles);
    }
  }
function positionDropdown ( ) { if ( ! elements ) { return $mdUtil . nextTick ( positionDropdown , false , $scope ) ; } var dropdownHeight = ( $scope . dropdownItems || MAX_ITEMS ) * ITEM_HEIGHT ; var hrect = elements . wrap . getBoundingClientRect ( ) , vrect = elements . snap . getBoundingClientRect ( ) , root = elements . root . getBoundingClientRect ( ) , top = vrect . bottom - root . top , bot = root . bottom - vrect . top , left = hrect . left - root . left , width = hrect . width , offset = getVerticalOffset ( ) , position = $scope . dropdownPosition , styles ; // Automatically determine dropdown placement based on available space in viewport. if ( ! position ) { position = ( top > bot && root . height - top - MENU_PADDING < dropdownHeight ) ? 'top' : 'bottom' ; } // Adjust the width to account for the padding provided by `md-input-container` if ( $attrs . mdFloatingLabel ) { left += INPUT_PADDING ; width -= INPUT_PADDING * 2 ; } styles = { left : left + 'px' , minWidth : width + 'px' , maxWidth : Math . max ( hrect . right - root . left , root . right - hrect . left ) - MENU_PADDING + 'px' } ; if ( position === 'top' ) { styles . top = 'auto' ; styles . bottom = bot + 'px' ; styles . maxHeight = Math . min ( dropdownHeight , hrect . top - root . top - MENU_PADDING ) + 'px' ; } else { var bottomSpace = root . bottom - hrect . bottom - MENU_PADDING + $mdUtil . getViewportTop ( ) ; styles . top = ( top - offset ) + 'px' ; styles . bottom = 'auto' ; styles . maxHeight = Math . min ( dropdownHeight , bottomSpace ) + 'px' ; } elements . $ . scrollContainer . css ( styles ) ; $mdUtil . nextTick ( correctHorizontalAlignment , false ) ; /**
     * Calculates the vertical offset for floating label examples to account for ngMessages
     * @returns {number}
     */ function getVerticalOffset ( ) { var offset = 0 ; var inputContainer = $element . find ( 'md-input-container' ) ; if ( inputContainer . length ) { var input = inputContainer . find ( 'input' ) ; offset = inputContainer . prop ( 'offsetHeight' ) ; offset -= input . prop ( 'offsetTop' ) ; offset -= input . prop ( 'offsetHeight' ) ; // add in the height left up top for the floating label text offset += inputContainer . prop ( 'offsetTop' ) ; } return offset ; } /**
     * Makes sure that the menu doesn't go off of the screen on either side.
     */ function correctHorizontalAlignment ( ) { var dropdown = elements . scrollContainer . getBoundingClientRect ( ) , styles = { } ; if ( dropdown . right > root . right - MENU_PADDING ) { styles . left = ( hrect . right - dropdown . width ) + 'px' ; } elements . $ . scrollContainer . css ( styles ) ; } }
Calculates the dropdown's position and applies the new styles to the menu element
@returns {*}
Calculates the dropdown s position and applies the new styles to the menu element