16

I would like to create Google Chrome extension. Its job is to replace a word with another on all websites.

I have the following manifest.json file:

{
  "name": "My extension",
  "version": "1.0",
  "background_page": "background.html",
  "permissions": [
    "tabs", "http://*/*"
  ],
  "content_scripts": [
    {
      "matches": ["http://*/*"],
      "js": ["myscript.js"],
      "run_at": "document_end"
    }
  ]
}

and the javascript in myscript.js is:

< script type="text/javascript" >
    document.body.innerHTML = document.body.innerHTML.replace("uno", "dos");
< /script >

However this does not function.. and I cannot find a way to debug the content script, only the background.html

Will Richardson
  • 7,780
  • 7
  • 42
  • 56
  • 2
    According to google's content security policy java-script should be in separate js files. As a result the script tags are irrelevant because you are working in a java-script file and would only be required only if you were writing your script in the html file. In your case you would only use the tags to include the js file to your html using the src attribute. – Andreas Sep 25 '13 at 07:58
  • Why doesn't giving a relative path to the js work? eg `src/inject/myscript.js` – theTuxRacer May 26 '14 at 12:49

5 Answers5

15

I took the example from JavaNut13 and Matt Curtis to create an alias hider extension for Reddit, and updated it for the new manifest 2. It looks for user on Reddit named "user1" and replaces it with "nobody". Modify as you need.

manifest.json

{
  "name": "No Alias",
  "version": "0.1",
  "permissions": [
    "https://www.reddit.com/*"
  ],
  "content_scripts": [
    {
      "matches": ["https://www.reddit.com/*"],
      "js": ["myscript.js"],
      "run_at": "document_end"
    }
  ],
  "manifest_version": 2
}

myscript.js

document.body.innerHTML = document.body.innerHTML.replace(new RegExp("user1", "g"), "nobody");
Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
Volomike
  • 23,743
  • 21
  • 113
  • 209
  • This is working fine but there is big issue is that some button's click event can't be fire. For ex: After enable this extension I can't login gmail. I can enter email id and press submit button then it clear the text box. Anybody can help to solve out this issue. – Pankaj Vavadiya Jun 30 '16 at 16:16
  • How about dynamic word replacement? – Testing123 Oct 31 '17 at 03:53
  • trying to figure out replace numbers and not text will this method work could i find and replace zip code numbers could someone add an example and add placeholder (number_here) (replace_number here) – Fred Mcgiff May 04 '18 at 23:00
11

I have actually written this in jQuery: (Making sure you have the correct include tag)

var replaced = $("body").html().replace(/text/g,'replace');
$("body").html(replaced);
Will Richardson
  • 7,780
  • 7
  • 42
  • 56
  • 3
    Thanks, this works! For others - here's very simple tutorial how to use jQuery in extensions: [http://blog.michael-forster.de/2009/08/using-jquery-to-build-google-chrome.html](http://blog.michael-forster.de/2009/08/using-jquery-to-build-google-chrome.html) – Micer May 12 '12 at 11:54
  • trying to figure out replace numbers and not text will this method work could i find and replace zip code numbers – Fred Mcgiff May 04 '18 at 22:59
5

Replacing/changing text within the DOM on this scale should not be done with blunt HTML-regex replacement, which is very unsafe. You risk mutilating the HTML in the process.

What you need to do is loop over every TextNode (Node) within the document, modifying the text within them.

Your code will end up looking something like this:

var replaceTextInNode = function(parentNode){
    for(var i = parentNode.childNodes.length-1; i >= 0; i--){
        var node = parentNode.childNodes[i];

        //  Make sure this is a text node

        if(node.nodeType == Element.TEXT_NODE){
            node.textContent = /* modify text here */
        } else if(node.nodeType == Element.ELEMENT_NODE){
            //  Check this node's child nodes for text nodes to act on

            replaceTextInNode(node);
        }
    }
};

replaceTextInNode(document.body);
mattsven
  • 22,305
  • 11
  • 68
  • 104
  • Cheers, this code works, but when I view facebook with this enabled it makes all the hidden fields (for development..) appear.. – Will Richardson Apr 27 '11 at 03:10
  • 1
    Yep, that's the tricky thing with reloading the DOM of an entire body tag. You'd do much better to iterate over the elements of the DOM and replace the text inside of them one by one. I can give you an example, if you want. – mattsven Apr 27 '11 at 03:13
  • That would be very helpful if you could. – Will Richardson Apr 27 '11 at 22:28
  • I face the same kind of issue after enable my chrome extension. In some webpage can't be fully loaded. Some button's can't be clicked. Even I can't login stackoverflow by pressing google account button. Is there any way to solve??? Pls... – Pankaj Vavadiya Jun 30 '16 at 16:22
  • @PankajVavadiya Updated code with an example. Please follow the provided link as well. – mattsven Jun 30 '16 at 17:14
  • trying to figure out replace numbers and not text will this method work could i find and replace zip code numbers – Fred Mcgiff May 07 '18 at 22:45
  • @mattsven do you know of any code examples that will work in this situation. working examples – Fred Mcgiff May 15 '18 at 03:39
  • @FredMcgiff Not off the top of my head. You'll have to try and adapt some of the examples in this question's answers. – mattsven May 15 '18 at 15:14
  • failing each time nothing wants to select numbers like text does – Fred Mcgiff Jun 05 '18 at 04:25
1

Use the DOM and modify the data of the appropriate Text nodes. E.g.

document.body.querySelector(".number").firstChild.data = "dos";
Eli Grey
  • 35,104
  • 14
  • 75
  • 93
  • trying to figure out replace numbers and not text will this method work could i find and replace zip code numbers – Fred Mcgiff May 03 '18 at 17:05
-1
var matchText = function(node, regex, callback, excludeElements) { 

    excludeElements || (excludeElements = ['script', 'style', 'iframe', 'canvas', 'a']);
    console.log("Node name " + node.nodeName);
    var child = node.firstChild;

    while (child) 
    {
        switch (child.nodeType) 
        {
        case 1:
            if (excludeElements.indexOf(child.tagName.toLowerCase()) > -1)
                break;
            matchText(child, regex, callback, excludeElements);
            break;
        case 3:
            var bk = 0;
            child.data.replace(regex, function(all) 
            {
                var args = [].slice.call(arguments),
                    offset = args[args.length - 2],
                    newTextNode = child.splitText(offset+bk), tag;
                bk -= child.data.length + all.length;

                newTextNode.data = newTextNode.data.substr(all.length);
                tag = callback.apply(window, [child].concat(args));
                child.parentNode.insertBefore(tag, newTextNode);
                child = newTextNode;
            });
            regex.lastIndex = 0;
            break;
        }
        child = child.nextSibling;
    }

    return node;
};

matchText(document.body, new RegExp("(?:(?:\\+|0{0,2})91(\\s*[\\- ]\\s*)?|[0 ]?)?[789]\\d{9}|(\\d[ -]?){10}\\d", "g"), function(node, match, offset) {
    var newAnchor = document.createElement("a");
    newAnchor.className = "search-term";
    //newAnchor.textContent = match;
    newAnchor.href = "tel:" + match.replace( /(\s|-)/g, "");
    newAnchor.innerHTML = '<img src =' + chrome.extension.getURL("call_icon_10x10.png")+'> ' + match;
    return newAnchor;
});
Pankaj Vavadiya
  • 481
  • 7
  • 15
  • As my previous code erase some textnode content, I modified code correctly. It is working fine. It is referenced from http://stackoverflow.com/questions/16662393/insert-html-into-text-node-with-javascript link – Pankaj Vavadiya Jul 04 '16 at 12:16
  • This method will be lifesaver cause it will run all the time so for each page a person prints it already altered to correct zip and phone number but as you can see this is for text and i still trying to figure out replace numbers – Fred Mcgiff May 03 '18 at 16:28
  • 1
    Could you clarify where the text and replacement is happening adding (put text here) put (replacement text here) – Fred Mcgiff May 03 '18 at 16:30