Just a nice guy
Just a nice guy

Reputation: 548

Inject JS only on specific tab on Chrome Extension

Sorry in advantage for my english.


I am creating my first Chrome extension and I want to inject JS only on a specific tab.

This is my manifest.json:

{
  "name": "My Extension Name",
  "version": "0.0.1",
  "manifest_version": 2,
  "description": "My description",
  "homepage_url": "http://example.com",
  "background": {
    "scripts": [
      "background.js"
    ],
    "persistent": true
  },
  "browser_action": {
    "default_title": "Inject!"
  },
  "permissions": [
    "https://*/*",
    "http://*/*",
    "tabs",
    "storage"
  ]
}

Additionally, I have 2 files background.js and inject.js.

Inject.js can be what ever I want to inject, example:

(function() {
    console.log('Live is good');
})();

I think my issue is with the background.js file. I can manually inject the inject.js file in a specific tab when the user clicks on the extension button by using this code on the background.js:

chrome.browserAction.onClicked.addListener(function (tab) {
    // for the current tab, inject the "inject.js" file & execute it
    chrome.tabs.executeScript(tab.ib, {
        file: 'inject.js'
    });
});

Also, I can automatically inject the code on inject.js when the user update (refresh or change URL) the tab using this code on the background.js file:

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    // for the current tab, inject the "inject.js" file & execute it
    chrome.tabs.executeScript(tab.ib, {
        file: 'inject.js'
    });
});

The issue with the first option is that I need to click every time I want to inject the code, the issue with the second one is that the code is injected on ANY tab that is updated.

What I want is that the fist time, I need to click to inject it and then I want the code to be injected automatically only if the updated tab is the same where active tab when the user clicked.

This is my try (not working):

// listen for our browerAction to be clicked
chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.storage.sync.set({indexTabId: tab.id}, function() {
      console.log("The color is green.");
    });
});

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    // for the current tab, inject the "inject.js" file & execute it
    if ( chrome.storage.sync.get ( 'indexTabId', data ){
        if ( data.indexTabId == tab.id ) {
            chrome.tabs.executeScript(tab.ib, {
                file: 'inject.js'
            });
        }
    });
});

Any idea how to solve it?

Upvotes: 0

Views: 1614

Answers (1)

Xan
Xan

Reputation: 77482

You're not calling chrome.storage.sync.get correctly, to the point of a syntax error.

if ( chrome.storage.sync.get ( 'indexTabId', data ){
    if ( data.indexTabId == tab.id ) {
        chrome.tabs.executeScript(tab.ib, {
            file: 'inject.js'
        });
    }
});

The outer if doesn't make much sense; your actual decision-making happens inside, so let's throw it out:

chrome.storage.sync.get ( 'indexTabId', data ){
    if ( data.indexTabId == tab.id ) {
        chrome.tabs.executeScript(tab.ib, {
            file: 'inject.js'
        });
    }
}

This is still not the correct syntax for calling a function. You mix it up with syntax of defining a function. In general, it should have the following form:

chrome.storage.sync.get ( query, callback );

But you can define the callback right there as an anonymous function, like this:

function ( items ) { /* code */ }

Or even like this, in ES6 fashion:

( items ) => { /* code */ }

So, let's combine those:

chrome.storage.sync.get ( 'indexTabId', function ( data ) {
    if ( data.indexTabId == tab.id ) {
        chrome.tabs.executeScript(tab.ib, {
            file: 'inject.js'
        });
    }
});

That should work now (put inside the chrome.tabs.onUpdated.addListener callback)

Upvotes: 1

Related Questions