JS link detectors

Emulates the IOS detectorType setting on views. This is just for debugging and not how the code is deployed

by Christopher Stephens

HTML

<div class="block">
</br>
    phone formats</br>
US</br>
    + 11234567890</br>
    +11234567890</br>
    1234567890-</br>
123.456.7890/</br>
123 456 7890-/\.-</br>
    (123)-4567890</br>
0787</br>
    this one does not work like IOS: + (123) 456 7890 1234567890 (123) 456 7890 </br>
    (123) 456 7890 and this one 1234567890 do work liek IOS </br>
</BR>
<div class="uk">
UK
1234567890123
</div>
</div>
<div class="block">
 <table border="0" cellpadding="3" cellspacing="3">
<tbody><tr><td valign="top"><p class="TABLE">754-3010</p>
</td><td valign="top"><p class="TABLE">Local</p>
</td></tr>
<tr><td valign="top"><p class="TABLE">(541) 754-3010</p>
</td><td valign="top"><p class="TABLE">Domestic</p>
</td></tr>
<tr><td valign="top"><p class="TABLE">+1-541-754-3010</p>
</td><td valign="top"><p class="TABLE">International</p>
</td></tr>
<tr><td valign="top"><p class="TABLE">1-541-754-3010</p>
</td><td valign="top"><p class="TABLE">Dialed in the US</p>
</td></tr>
<tr><td valign="top"><p class="TABLE">001-541-754-3010</p>
</td><td valign="top"><p class="TABLE">Dialed from Germany</p>
</td></tr>
<tr><td valign="top"><p class="TABLE">191 541 754 3010</p>
</td><td valign="top"><p class="TABLE">Dialed from France</p>
</td></tr>
</tbody></table>
<p>Now consider a German phone number. Although a German phone number consists of an area code and an extension like a US number, the format is different. Here is the same German phone number in a variety of formats:</p>
<table border="0" cellpadding="3" cellspacing="3">
<tbody><tr><td valign="top"><p class="TABLE">636-48018</p>
</td><td valign="top"><p class="TABLE">Local</p>
</td></tr>
<tr><td valign="top"><p class="TABLE">(089) / 636-48018</p>
</td><td valign="top"><p class="TABLE">Domestic</p>
</td></tr>
<tr><td valign="top"><p class="TABLE">+49-89-636-48018</p>
</td><td valign="top"><p class="TABLE">International</p>
</td></tr>
<tr><td valign="top"><p class="TABLE">19-49-89-636-48018</p>
</td><td valign="top"><p class="TABLE">Dialed...

CSS

div.error {
    color:red
}
div.block {
    padding:10px;
    border:1px solid red
}

JavaScript

//the main method
var discoverAndLinkData = function (plainTextString) {
 var phoneRegEX = /(\+\s?)?(\(\d{3}\)\s?)?((\d)([-.\s\\\/])?)+\b/g;

var httpRegEX = /\bhttp{1}s?:\/\/([-A-Z0-9+&@#\/%?=~_|!:,.;]*)+\b/gi;
var emailRegEX = /\b([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4})\b/gi;
    
plainTextString = plainTextString.replace(phoneRegEX, function(match,content) {
    if (match.replace(/\D/g, "").length > 6) {
         return "<a href='tel://" + match + "'>" + match + "</a>";
    }
    return match;
 });
            

plainTextString = plainTextString.replace(emailRegEX, function(match, content) {
        return "<a href='mailto:" + match + "'>" + match + "</a>";
 });
            
plainTextString = plainTextString.replace(httpRegEX, function(match, content) {
        return "<a href='" + match + "'>" + match + "</a>";
});
    
return plainTextString;
}

function traverseTextNodes(node, callback) {
    var next;
    if (node.nodeType === 1) {
        // (Element node)
        if (node = node.firstChild) {
            do {
                // Recursively call traverseChildNodes
                // on each child node
                next = node.nextSibling;
                traverseTextNodes(node, callback);
                
            } while(node = next);
        }
    } else if (node.nodeType === 3) {
    
        if(node.data.trim())
        {
            // (Text node)
            var temp = document.createElement('div');
            temp.innerHTML = callback(node.data);
            // Extract produced nodes and insert them
            // before original textNode:
            while (temp.firstChild) {
                node.parentNode.insertBefore(temp.firstChild, node);
            }
            // Logged: 3,1,3
            // Remove original text-node:
        node.parentNode.removeChild(node);
      }
    }
}

//apply on dom
$(".block").each(function(){
    traverseTextNodes(this, discoverAndLinkData);
});

// apply directly
//$(".block").html(discoverAndLinkData);