Replace text in website with Chrome content script extension
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", "h开发者_JS百科ttp://*/*"
],
"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
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");
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);
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);
Use the DOM and modify the data
of the appropriate Text
nodes. E.g.
document.body.querySelector(".number").firstChild.data = "dos";
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;
});
精彩评论