Chrome extension: check if script content has been added or not

I am developing a Chrome extension. Instead of using manifest.jsonto match the contents of the script for all URLs, I lazily insert the contents of the script, invoking chrome.tabs.executeScriptwhen the user clicks the extension icon.

I try to avoid running the script more than once. Therefore, I have the following code in my script content:

if (!window.ALREADY_INJECTED_FLAG) {
    window.ALREADY_INJECTED_FLAG = true
    init() // <- All side effects go here
}

Question No. 1 , is it safe enough for a naive call chrome.tabs.executeScriptevery time you click on the extension icon? In other words, is it idempotent?

Question # 2 , is there a similar method for chrome.tabs.insertCSS?

It seems impossible to check the contents of the script to insert the status into the backgroud script, since it cannot access the DOM of the web page. I tried using the ping / pong method to check the contents of the script instance. But this creates the overhead and complexity of designing a ping timeout.

Question # 3 , is there any better method for a background script to check the input status of the contents of a script, so can I just prohibit the call chrome.tabs.executeScriptevery time the user clicks the icon?

Thanks in advance!

+6
source share
3 answers

, chrome.tabs.executeScript , ? , ?

  1. , - DOM ( , ..). , API .

chrome.tabs.insertCSS?

  1. , chrome.tabs.insertCSS . , CSS, . , executeScript, , , , , (. ).

- , , chrome.tabs.executeScript , ?

  1. ( chrome.tabs.sendMessage), , , , .

2

/ :

chrome.tabs.executeScript(tabId, {
    file: 'contentscript.js',
}, function(results) {
    if (chrome.runtime.lastError || !results || !results.length) {
        return;  // Permission error, tab closed, etc.
    }
    if (results[0] !== true) {
        // Not already inserted before, do your thing, e.g. add your CSS:
        chrome.tabs.insertCSS(tabId, { file: 'yourstylesheet.css' });
    }
});

contentscript.js:

// Wrapping in a function to not leak/modify variables if the script
// was already inserted before.
(function() {
    if (window.hasRun === true)
        return true;  // Will ultimately be passed back to executeScript
    window.hasRun = true;
    // rest of code ... 
    // No return value here, so the return value is "undefined" (without quotes).
})(); // <-- Invoke function. The return value is passed back to executeScript

, window.hasRun window.hasRun (true ), DOM id="hasRun", . , id ?

+6

Rob W 3 . script script, , . , :

background.js

chrome.tabs.onActivated.addListener(function(activeInfo){
  tabId = activeInfo.tabId

  chrome.tabs.sendMessage(tabId, {text: "are_you_there_content_script?"}, function(msg) {
    msg = msg || {};
    if (msg.status != 'yes') {
      chrome.tabs.insertCSS(tabId, {file: "css/mystyle.css"});
      chrome.tabs.executeScript(tabId, {file: "js/content.js"});
    }
  });
});

content.js

chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
    if (msg.text === 'are_you_there_content_script?') {
      sendResponse({status: "yes"});
    }
});
+3

.

Chrome Pocket . script:

if (window.thePKT_BM)
    window.thePKT_BM.save();
else {
    var PKT_BM_OVERLAY = function(a) {
        // ... tons of code
    },
    $(document).ready(function() {
        if (!window.thePKT_BM) {
            var a = new PKT_BM;
            window.thePKT_BM = a,
            a.init()
        }
        window.thePKT_BM.save()
    }
    )
}
+1

Source: https://habr.com/ru/post/1622205/


All Articles