3

I hope you can help me.

I am trying to create an extension in Chrome which would load a source of the active tab into a variable.

So far I have:

manifest.json

{
"name": "My Extension",
"manifest_version": 2,
"version": "0.1",
"description": "Does some simple stuff",
"browser_action": {
    "default_icon": "logo.png"
},

"background": {    
"scripts": ["main.js"]}}

main.js

chrome.browserAction.onClicked.addListener(
  function(tab) {
   var ps1 = document.getElementsByTagName('html')[0].innerHTML;
   window.alert(ps1);
});

but that loads the page source of the blank page. What do I need to do to get the source of the active page.

I have done some reading and I think I need to use content script whit some listening functions, I have been searching but all answers seem to me very complicated. Would any of you be so kind to give me some easy example?

Highly appreciate your feedback!

Regards


UPDATE after AdrianCooney answer:

I changed my manifest to contain

 "permissions": [
  "tabs"
  ]

Then in main.js I did

chrome.browserAction.onClicked.addListener(function(activeTab) {
 chrome.tabs.query({ currentWindow: true, active: true }, 
  function (tabs) {
   var ps1=document.getElementsByTagName('html')[0].innerHTML;
   window.alert(ps1);
 })
});

When I press the Extension button I get something like that

<html></html>
  <body><script src="main.js"></script>
  </body>

...no matter what tab I have active.

Another try with chrome.tabs.getCurrent

chrome.browserAction.onClicked.addListener(function(activeTab) {
 chrome.tabs.getCurrent(
  function (tabs) {
   var ps1=document.getElementsByTagName('html')[0].innerHTML;
   window.alert(ps1);
  })
 });

The above version of main.js give exact same output as the one before, no matter what page I have active.

Matt
  • 327
  • 1
  • 6
  • 20
  • Related answer: [Open a new Google Chrome tab and get the source](http://stackoverflow.com/questions/10161044/open-a-new-google-chrome-tab-and-get-the-source/10162291#10162291). It's very easy to re-use the code to get the source code of the current tab (don't forget to add the [`activeTab` permission](https://developer.chrome.com/extensions/activeTab.html), by the way). – Rob W Sep 02 '13 at 16:03
  • Duplicate: [Getting the source HTML of the current page from chrome extension](http://stackoverflow.com/questions/11684454/getting-the-source-html-of-the-current-page-from-chrome-extension) – Alon Gubkin Sep 02 '13 at 18:47

5 Answers5

2

Background scripts are isolated from the current page because they're designed to be persistant regardless of the content of the page. You need to use the chrome.tabs API, specifically chrome.tabs.getCurrent. Once you have the current tab, you can inject code into the window. That's where your snippet above comes in.

You will need to add "tab" to your permissions in the manifest file.

AdrianCooney
  • 727
  • 5
  • 13
  • I tried your suggestion and also something else I found, at last something works now, but still not as expected. More ideas? – Matt Sep 02 '13 at 15:43
1

As was pointed out, you need to run code in the context of the active tab. One way to do it is using chrome.tabs.executeScript:

chrome.browserAction.onClicked.addListener( function() {
  chrome.tabs.executeScript(
    { 
      code: "document.getElementsByTagName('html')[0].innerHTML;"
    }, 
    function (ps1) {
      window.alert(ps1);
    }
  );
});
rsanchez
  • 14,467
  • 1
  • 35
  • 46
  • Thanks for that code but I have one concern here. How to define ps1 in this code? I tried `code: "var ps1 = document..."` but alert returns `undefined` – Matt Sep 03 '13 at 09:09
  • @Matt the code works as is, you don't have to add any declaration. The callback function will receive as a parameter the last expression evaluated by the executed code. The problem with the answer you posted below is that you won't have the value available in the context of your background script. – rsanchez Sep 03 '13 at 12:46
1

This code under main.js works!!! Thank you guys for your hints they saved me a lot of time!

chrome.browserAction.onClicked.addListener( 
  function(tab) {
   chrome.tabs.executeScript(
     null,{
       code:"var ps1 = document.getElementsByTagName('html')[0].innerHTML;            
       window.alert(ps1);"});
          }
);
Matt
  • 327
  • 1
  • 6
  • 20
0

In Chrome 47 you need to add "activeTab" to permissions, otherwise it doesn't work. With "tabs" it doesn't work.

manifest.json:

{
"name": "Rafi extension",
"manifest_version": 2,
"version": "7",
"description": "Open something",
"browser_action": {
    "default_icon": "logo.png"
},
"permissions": [
  "activeTab"
  ],
"background": {    
"scripts": ["main.js"]}
}
Rarar
  • 419
  • 2
  • 6
  • 19
0

For anyone looking to do this with Manifest V3, things are much simpler. Let's say you have a script parse_page.js in the root of your extension, that contains whatever code you want to execute:

var ps1 = document.getElementsByTagName('html')[0].innerHTML;            
window.alert(ps1);

From the docs, there are two ways to have it execute:

(1) Inject with static declarations: use this method for scripts that that need to run automatically. Simply add the following to your manifest.json:

"content_scripts": [
  {
    "matches": ["<all_urls>"],
    "js": ["parse_page.js"]
  }
],

The script will run whenever you visit a new page. You can adjust the matches above if you only want it to execute on certain URLs.

(2) Inject programmatically: use this method for scripts that need to run in response to events or on specific occasions. Add the following to your manifest.json:

"permissions": ["activeTab", "scripting"],
"background": {
  "service_worker": "background.js"
},
"action": { }

Next, in background.js, add the following:

chrome.action.onClicked.addListener((tab) => {
    chrome.scripting.executeScript({
        target: { tabId: tab.id },
        files: ['parse_page.js']
    });
});

In this example, the script will run whenever you click on your extension's icon.

Nebel22
  • 478
  • 8
  • 17