how to make a chrome extension that turns specific words into hyperlinks?

Viewed 343

I am trying to make a chrome extension that finds certain words on pages and turns them into hyperlinks. So for example, if I visit a website that has the word "search" written somewhere, then that word will turn into a link that I can click on (it will still appear as the word but maybe in a different colour or something) and be redirected to "www.google.com".

I have a code that finds words and changes them to other words but I don't know how to change them to hyperlinks. Here is the JavaScript I have:

walk(document.body);    
function walk(node)  
{       
    var child, next;    
    switch ( node.nodeType )  
    {
        case 1: 
        case 9:  
        case 11: 
            child = node.firstChild;
            while ( child ) 
            {
                next = child.nextSibling; 
                walk(child);
                child = next;
            }
            break;    
        case 3: 
            handleText(node);
            break;
    }
}

function handleText(textNode) 
{
    var v = textNode.nodeValue;    
    v = v.replace(/\bsearch\b/g, (str.link("https://www.google.com")));
    v = v.replace(/\bsearch\b/g, <a href="http://www.google.com">asdf</a>);

    textNode.nodeValue = v;
}

Can somebody helpful help me out please?

2 Answers

HTML is parsed into the DOM, which is what you are traversing. You are not really replacing the DOM, but instead replacing the text node with unparsed HTML, which won't work. Instead, you need to replace the text node with a <a> node that has the URL and text you want.

You have to replace the text node with the parsed HTML elements.

Change

    textNode.nodeValue = v;

to something like

    var htmlParser = document.createElement('div');
    htmlParser.innerHTML = v;
    // replace text node with parsed nodes
    var newNodes = htmlParser.childNodes;
    while (newNodes.length) {
      textNode.parentNode.insertBefore(newNodes[0], textNode);
    }
    textNode.parentNode.removeChild(textNode);

Also, make sure to ignore anchors (node.tagName === 'A') while traversing the DOM, or you could end up replacing the text inside existing anchors.

Related