Angular phone number masking

HTML

<script src="//cdn.jsdelivr.net/angular.bootstrap/0.4.0/ui-bootstrap-tpls.min.js"></script>
<div class="body" ng-app="myApp">
    <div class="wrapper" ng-controller="MyCtrl">
        <div class="info">Raw Value: {{phoneVal}}</div>
        <div class="info">Filtered Value: {{phoneVal | tel}}</div>

        <input class="input-phone" type='text' phone-input ng-model="phoneVal"/>
    </div>
</div>

CSS

body, html, .body {
  height: 100%;
  width: 100%;
}
body {
  background:
    radial-gradient(closest-corner, rgba(16, 47, 70, 0) 60%, rgba(16, 47, 70, 0.26)),
    linear-gradient(108deg, #26D0CE, #1A2980 90%);
}

.body {
  display: table;
}

.wrapper {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}

.info{
  margin: 0.5em 0;
  font-size: 1.25em;
  color: #FFF;
  text-shadow: 0 0 0.5em #000;
}

.input-phone {
  display: block;
  margin: 2em auto;
  padding: 0.5em 0.25em;
  border: none;
  border-radius: 0.2em;
  font-size: 1.5em;
  text-align: center;
  box-shadow: 0 0 1em 0.25em rgba(0,0,0,0.2);
}

JavaScript

var myApp = angular.module('myApp', []);
 
myApp.controller('MyCtrl', function($scope) {
  $scope.currencyVal;
});

myApp.directive('phoneInput', function($filter, $browser) {
    return {
        require: 'ngModel',
        link: function($scope, $element, $attrs, ngModelCtrl) {
            var listener = function() {
                var value = $element.val().replace(/[^0-9]/g, '');
                $element.val($filter('tel')(value, false));
            };

            // This runs when we update the text field
            ngModelCtrl.$parsers.push(function(viewValue) {
                return viewValue.replace(/[^0-9]/g, '').slice(0,10);
            });

            // This runs when the model gets updated on the scope directly and keeps our view in sync
            ngModelCtrl.$render = function() {
                $element.val($filter('tel')(ngModelCtrl.$viewValue, false));
            };

            $element.bind('change', listener);
            $element.bind('keydown', function(event) {
                var key = event.keyCode;
                // If the keys include the CTRL, SHIFT, ALT, or META keys, or the arrow keys, do nothing.
                // This lets us support copy and paste too
                if (key == 91 || (15 < key && key < 19) || (37 <= key && key <= 40)){
                    return;
                }
                $browser.defer(listener); // Have to do this or changes don't get picked up properly
            });

            $element.bind('paste cut', function() {
                $browser.defer(listener);
            });
        }

    };
});
myApp.filter('tel', function () {
    return function (tel) {
        console.log(tel);
        if (!tel) { return ''; }

        var value = tel.toString().trim().replace(/^\+/, '');

        if (value.match(/[^0-9]/)) {
            return tel;
        }

        var country, city, number;

        switch (value.length) {
            case 1:
            case 2:
            case 3:
               ...