6

I'm a beginner trying to create a chrome extension. In this extension, I want to have a popup.html file that has the button "highlight" on it. If the user clicks highlight all the words in the page should be highlighted.

Manifest

"browser_action": {
  "default_icon": "icon.png",
  "default_popup": "popup.html" 
},
"permissions": [
  "tabs", "activeTab"
]

Popup.html

<!DOCTYPE html> 
<html>
  <head>
    <script src="popup.js"></script>
  </head>
  <body>
    <button id="highlight">Highlight</button>
  </body>
</html>

popup.js

window.onload = function(){
  document.getElementById('highlight').onclick = highLight;
  function = highLight(){
   //How can I make all the text  highlighted
 }
};

How can I access the DOM so that each word is highlighted?

Thanks in advance!

idude
  • 4,654
  • 8
  • 35
  • 49
  • 1
    http://stackoverflow.com/questions/9794851/find-text-string-in-jquery-and-make-it-bold/9795091#9795091, http://stackoverflow.com/questions/2214794/wrap-some-specified-words-with-span-in-jquery/2214807#2214807, http://stackoverflow.com/questions/9167855/highlight-text-inside-html-with-jquery, http://stackoverflow.com/questions/119441/highlight-a-word-with-jquery – elclanrs Dec 27 '13 at 05:15
  • Where is the question? –  Dec 27 '13 at 05:16
  • How can I access the DOM so that each word is highlighted? – idude Dec 27 '13 at 05:17
  • Add a class= highlighted and customize this with css. –  Dec 27 '13 at 05:21
  • I don't have access to the DOM to do that. I'm wondering how I can access the DOM using an extension. – idude Dec 27 '13 at 05:27

2 Answers2

8

Highlighting the text on a page (or doing anything on the page) via a Chrome Extension must be done through a Content Script. However your popup has to talk to the Content Script to tell it to highlight the page when the button is click in the popup. This is called Message Passing.

Your popup.js should look something like this:

document.getElementById('highlight').addEventListener('click', sendHighlightMessage, false);

function sendHighlightMessage() {
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    chrome.tabs.sendMessage(tabs[0].id, {highlight: true}, function(response) {
      console.log(response);
    });
  });
}

content_script.js is where the DOM manipulation actually happens. It should listen for the message from your popup and appropriately highlight the page. It should contain the following:

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.highlight === true) {
    highlightText(document.body);
    sendResponse({messageStatus: "received"});
  }
});

Read through the Chrome Extension documentation on content scripts and message passing (linked above) for a more complete explanation of what's going on here.

Actually highlighting text on the page as in selecting it (like clicking and dragging over text to copy and paste) can't be done programmatically outside a textarea or input field. However, you can use styling to change the background color of the text. In order to highlight just the text, you need to wrap each text node in a span, with the highlight style. This is a lot of DOM manipulation and will completely mutilate the original page. You should consider whether this is really necessary and useful for your extension. That said, it will look something like this:

function highlightText(element) {
  var nodes = element.childNodes;
  for (var i = 0, l = nodes.length; i < l; i++) {
    if (nodes[i].nodeType === 3)  // Node Type 3 is a text node
      var text = nodes[i].innerHTML;
      nodes[i].innerHTML = "<span style='background-color:#FFEA0'>" + text + "</span>";
    }
    else if (nodes[i].childNodes.length > 0) {
      highlightText(nodes[i]);  // Not a text node or leaf, so check it's children
    }
  }
}
danasilver
  • 556
  • 3
  • 10
1

You can not have access to DOM from popup but you can access DOM using content script. Look at this question which explains the difference between content script and background script. Popup scripts have same permissions/power which background scripts have.

To add content script, add this to your manifest.json

"content_scripts": [
  {
    "matches": ["http://*/*"], 
    "js": ["temp.js"]
  }
] 

And then as mentioned in comments, use some little piece of jQuery code to highlight words.

Community
  • 1
  • 1
Sachin Jain
  • 21,353
  • 33
  • 103
  • 168