4

I Need to get source code of current tab when the chrome extension icon is clicked . i have also tried with button click event. Please go through my current code :

manifest.json

    {  "name": "UM Chrome Extension!",  "version": "1.0",
  "description": "To ensure the tracking codes present.",
    "icons": {
"128": "TW-Extension-Icon2.png"
},   "background": {
      "scripts": [ "background.js"]
   }, 
  "content_scripts": [
    {
      "matches": ["http://*/*"],  
      "js": ["popup1.js","jquery-1.10.2.js","jquery-ui.js","bootstrap.min.js"]
    }
    ], 
    "permissions": [
    "activeTab","tabs","contextMenus", "http://*/*"
  ],

  "browser_action": {
    "default_popup": "popup.html"
  },
  "manifest_version": 2
}

popup.html

<!doctype html>
<html class="no-js" lang="">
    <head>
        <script type="text/javascript" src="popup1.js"></script>
    </head>

    <body style="width: 600px; height: 300px;">
<button value="Test" id="check-1"> </button>
</body>
</html>

and popup.js

window.addEventListener('DOMContentLoaded', function() {
var fbshare = document.querySelector('#check-1');
    fbshare.addEventListener('click', function() {
        var htmlCode = document.documentElement.outerHTML;
     window.alert(htmlCode);
      });

});

How to get active tab's source code ? i need to get source code of the page so that i need to search whether the page contains particular tracking code(like GA code).

Thank You

ForTW
  • 176
  • 1
  • 1
  • 8
  • Please define "source code". Do you mean the HTML? the scripts? the CSS? – Makyen Apr 20 '17 at 06:13
  • You are loading *popup1.js* for both your popup and as a content script. This is almost always a Bad Idea™. You should only load it as one or the other. It is very rare for any script files, other than libraries, to be shared between the two. – Makyen Apr 20 '17 at 06:17
  • *Please* don't load jQuery, jQueryUI and BootStrap into **every** page (`content_scripts` with your `matches`) unless you **need** to. jQuery alone is 85kiB of minimized code. This is a significant burden to place on *every single page*. What of those of us with 100's of tabs open? While It's possible you really *need* to load all these libraries, you should load the *absolute minimum* needed to allow the user to begin interacting with your extension (e.g. a static image and event handler w/o libraries), then dynamically load everything once the user actually interacts with your extension. – Makyen Apr 20 '17 at 06:24
  • It's unclear what you are really asking. What code are you wanting? Where are you wanting it? You already have defined a content script, so you can just get it there. For at least some interpretations of what you are asking, you should be able to do a bit of searching and get an answer. – Makyen Apr 20 '17 at 06:27
  • Possible duplicate of [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) – Paul Roub Apr 20 '17 at 12:57

1 Answers1

13

Your manifest has both "content_scripts" (which run in the context of the page on document_idle) and "browser_action" scripts (which run in an isolated context when the extensions menu button is clicked).

In popup.html you reference popup.js, so in popup.js when you call document.documentElement.outerHTML you're getting the content of popup.html, not the active tab.

You reference both popup.js and popup1.js, which is confusing. You're currently running the same code in both the popup and the page context, which is almost guaranteed to break in one or the other. By convention use content.js in "content_scripts" and reference popup.js in the action popup.html.

"content_scripts" run in every page, whether users click on the extension or not. Your current manifest is adding ["popup1.js","jquery-1.10.2.js","jquery-ui.js","bootstrap.min.js"] to every page, which is needlessly slow.

Avoid using jQuery in Chrome extensions. It's fairly large and a browser standardisation library doesn't add much when you know for absolute certain that all your users are on Chrome. If you can't code without it then try to restrict it to just your popup or load it in dynamically.

You set a "scripts": [ "background.js"], which runs constantly in the background and isn't needed at all in your current code. If you need to do things outside of the action button consider using event pages instead.

Use the Chrome API to get from the context of the popup to the page. You need to query chrome.tabs to get the active tab, and then call chrome.tabs.executeScript to execute script in the context of that tab.

Google's API uses callbacks, but in this example I'm going to use chrome-extension-async to allow use of promises (there are other libraries that do this too).

In popup.html (assuming you use bower install chrome-extension-async):

<!doctype html>
<html>
<head>
    <script type="text/javascript" src="bower_components/chrome-extension-async/chrome-extension-async.js"></script>
    <script type="text/javascript" src="popup.js"></script>
</head>

<body style="width: 600px; height: 300px;">
    <button value="Test" id="check-1"> </button>
</body>
</html>

In popup.js (discard popup1.js):

function scrapeThePage() {
    // Keep this function isolated - it can only call methods you set up in content scripts
    var htmlCode = document.documentElement.outerHTML;
    return htmlCode;
}

document.addEventListener('DOMContentLoaded', () => {
    // Hook up #check-1 button in popup.html
    const fbshare = document.querySelector('#check-1');
    fbshare.addEventListener('click', async () => {
        // Get the active tab
        const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
        const tab = tabs[0];

        // We have to convert the function to a string
        const scriptToExec = `(${scrapeThePage})()`;

        // Run the script in the context of the tab
        const scraped = await chrome.tabs.executeScript(tab.id, { code: scriptToExec });

        // Result will be an array of values from the execution
        // For testing this will be the same as the console output if you ran scriptToExec in the console
        alert(scraped[0]);
    });
});

If you do it this way you don't need any "content_scripts" in manifest.json. You don't need jQuery or jQuery UI or Bootstrap either.

Keith
  • 150,284
  • 78
  • 298
  • 434
  • Thanks Keith! Your code was very helpul :) – ForTW Apr 20 '17 at 09:27
  • @ForTW cheers. If this answers your question please click the green tick on the left to select it as the answer. If it doesn't then please let me know what more you still need. – Keith Apr 24 '17 at 11:02
  • This answer got me closer to my solution, than I've ever been. But, this does not get the source . The head of the returned html simply contains the head of the popup.html file. Is there really no way of getting the html source of the entire page? – Lasserh May 16 '20 at 10:31
  • @Lasserh That sounds like you're calling it inline - you need to call [`chrome.tabs.executeScript`](https://developer.chrome.com/extensions/tabs#method-executeScript) to ensure that the script gets the HTML from the tab you want. – Keith May 22 '20 at 07:10