Type-along Phone Formatting

Formats an input field for phone number as the user types

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div class="form-group has-feedback">
  <label class="control-label" for="PhoneFormatDefault">Default phone formatting<em class="validation-info">*</em></label>
  <input type="tel" name="PhoneFormatDefault" id="PhoneFormatDefault" class="required phoneUS form-control" maxlength="20" placeholder="123-456-7890">
  <small for="PhoneFormatDefault" class="help-block"></small>
  <span class="glyphicon form-control-feedback glyphicon-ok"></span>
  <span class="glyphicon form-control-feedback glyphicon-remove"></span>
</div>

<div class="form-group has-feedback">
  <label class="control-label" for="PhoneFormatDefault2">Default phone formatting on text input<em class="validation-info">*</em></label>
  <input type="text" name="PhoneFormatDefault2" id="PhoneFormatDefault2" class="required phoneUS form-control" maxlength="20" placeholder="123-456-7890">
  <small for="PhoneFormatDefault2" class="help-block"></small>
  <span class="glyphicon form-control-feedback glyphicon-ok"></span>
  <span class="glyphicon form-control-feedback glyphicon-remove"></span>
</div>

<div class="form-group has-feedback">
  <label class="control-label" for="PhoneFormatDot">Phone formatting with "."<em class="validation-info">*</em></label>
  <input type="tel" name="PhoneFormatDot" id="PhoneFormatDot" class="required phoneUS form-control" maxlength="20" placeholder="123.456.7890">
  <small for="PhoneFormatDot" class="help-block"></small>
  <span class="glyphicon form-control-feedback glyphicon-ok"></span>
  <span class="glyphicon form-control-feedback glyphicon-remove"></span>
</div>

<div class="form-group has-feedback">
  <label class="control-label" for="PhoneFormatSpace">Phone formatting with " "<em class="validation-info">*</em></label>
  <input type="tel" name="PhoneFormatSpace" id="PhoneFormatSpace" class="required phoneUS form-control" maxlength="20" placeholder="123 456 7890">
  <small...

CSS

.glyphicon-ok, .glyphicon-remove{
  opacity:0;
}
.has-success .glyphicon-ok,
.has-error .glyphicon-remove
{
  opacity:1;
  transition: opacity 0.35s ease-in-out;
}
.has-feedback input {
  transition: border 0.35s ease-in-out;
}

JavaScript

/**/;
//initialize namespace if necessary
window.SL8 = window.SL8 || {};

//extends an object, used mostly for options passed in constructors
SL8._extend = function (a, b) {
    for (var key in b) {
        if (b.hasOwnProperty(key)) {
            a[key] = b[key];
        }
    }
}

//find an ancestor of a given element by class
SL8._getAncestorByClass = function (e, c) {
     while ((e = e.parentNode) && !e.classList.contains(c));
     return e;
}

/**/;
//initialize namespace if necessary
window.SL8 = window.SL8 || {};

SL8.PhoneFormat = (function () {

    return function (input, options) {
        alert(input.id);
        var settings = {
            separator: "-",
            acceptedSeparators: ["-", " ", "."],
            feedback: {
                "a": "Please enter your full 10-digit phone number, area code first",
                "s": "Please enter your full 10-digit phone number",
                "i": "The phone number entered is invalid"
            }
        };

        settings.validate = function (phonenumber, separator) {
            var segments = phonenumber.split(separator);
            //7 digit phone number (possibly missing area code
            if (typeof segments[2] !== "undefined" && segments[2].length === 1) {
                return [false, "a"];
            }
            //phone number is too short
            if (typeof segments[2] === "undefined" || segments[2].length < 4) {
                return [false, "s"];
            }
            //n11 numbers are invalid in North America to avoid confusion with sepcial services (911, 411, etc)
            if (segments[0].substring(1, 3) === "11") { 
                return [false, "i"];
            }
            //555 from 0100-0199 are reserved fictional numbers
            if (segments[1] === "555" && segments[2].charAt(1) === "1") {
                return [false, "i"];
            }
            //area code cannot begin with 1
            if (phonenumber.charAt(0) === "1" ||...