How to determine if there is a Chrome extension in the popup from the content script?

Background

I have a Chrome extension with a browser action to launch index.html

in a new tab.

I would like to first update the extension to open index.html

in a popup and then enable a button that users can click to choose to open the application in a new tab.

I don't want this button to show when it was not a popup (since that doesn't make sense), which means the content script needs to know if it is a popup in order to show the button.

Questions

This is a two-part question:

  • How does a chrome extension popup know its popup?
  • How do I pass this information to the content script before the popup is displayed?

What i tried

I tried to use chrome.extension.getViews

in background.js

to determine if the popup is open. Then I post a message to the content script, which then shows the button. However, I didn't get it to work - views

it is always an empty array and the message never seems to be accepted by the content of the script.

Here are the relevant parts of my file manifest.json

:

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

"browser_action": {
  "default_icon": {   
    "19": "img/icon19.png",
    "38": "img/icon38.png"
  },

  "default_title": "Super Simple Tasks",

  "default_popup": "index.html"
}

      

And here's what I tried in background.js

:

// Get all popups
var views = chrome.extension.getViews({ type: "popup" });

// Send a message if there is a popup
if (views.length > 0){
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
    chrome.tabs.sendMessage(tabs[0].id, {action: "popup_open"}, function(response) {});  
  });
};

      

And then in my content script, I listen to the message and then add the class to the body:

// Listen for the message
chrome.extension.onMessage.addListener(function(msg, sender, sendResponse) {
  if (msg.action === 'popup_open') {
    // My code here to show the button
  }
});

      

+3


source to share


4 answers


After talking with a friend, I came across an elegant solution that doesn't involve messaging or even a background.js

script at all.

I can point ?popup=true

to manifest.json

and check this parameter in my extension script. Here's the code:

manifest.json

now looks like this:

"browser_action": {
  "default_icon": {   
    "19": "img/icon19.png",
    "38": "img/icon38.png"
  },

  "default_title": "Super Simple Tasks",

  "default_popup": "index.html?popup=true"
}

      



The following code in my content script (taken from this answer ) checks for ?popup=true

. It's worth noting that this function can handle multiple URL parameters separated by a character &

.

function getUrlParameter(sParam) {
  var sPageURL = window.location.search.substring(1);
  var sURLVariables = sPageURL.split('&');
  for (var i = 0; i < sURLVariables.length; i++) {
    var sParameterName = sURLVariables[i].split('=');
    if (sParameterName[0] == sParam) {
      return sParameterName[1];
    }
  }
}

var isPopup;
isPopup = getUrlParameter('popup') === 'true';

      

Finally, add a class to the body if it pops up:

$('body').toggleClass('popup', isPopup)

      

+2


source


I needed something like this as I wanted to create some cross-compatible code for all script types.

I found this worked pretty well.



const SCRIPT_TYPE = (() => {
    if (chrome && chrome.extension && chrome.extension.getBackgroundPage && chrome.extension.getBackgroundPage() === window) {
        return 'BACKGROUND';
    } else if (chrome && chrome.extension && chrome.extension.getBackgroundPage && chrome.extension.getBackgroundPage() !== window) {
        return 'POPUP';
    } else if (!chrome || !chrome.runtime || !chrome.runtime.onMessage) {
        return 'WEB';
    } else {
        return 'CONTENT';
    }
})();

      

+1


source


chrome.tabs.getCurrent(function(tab) {
    if(tab == undefined)
        document.getElementById('mButton').style.display = 'inline-block';
});

      

I originally set the button display: none;

if the returned tab undefined

means it is not a tab (so it is a popup) and then I show the button. You can, of course, cancel it.

======

Well, the submit parameter also works, which in this case you won't need to add the query string to the manifest, just add it to the button to listen to the button.

btn.addEventListener('click', function() {
    chrome.tabs.create({url: "index.html?popup=false"});
});

      

And then the same process (reading the query string and comparing, etc.).

======

Alternatively, you can make a copy of the index.html

say index2.html

, remove the button from index.html, use index2.html in the manifest, and index.html for the button clicked. :)

0


source


In your manifest file add a hash to the url:

"browser_action": {
  "default_popup": "index.html#popup"
}

      

In JavaScript:

if(location.hash == 'popup') 
    // do something awesome!

      

0


source







All Articles