0

I am trying to receive some info from the content page to the popup page in chrome extension.

Here is my manifest.json:

{
  "name": " Downloader",
  "description": "history ",
  "version": "1.0",
  "permissions": [
    "activeTab",
    "notifications"
  ],
  "background": {
    "persistent": false,
    "scripts": ["background.js"]
  },
  "content_scripts": [
    {
    "all_frames": false,
    "matches": ["<all_urls>"],
    "exclude_matches": [],
      "js": [
        "/src/jquery.js",
        "/src/sheet-min.js",
        "/src/file-saver-min.js"
      ]

      // "css": [
      //   "js/content/page.css"
      // ]
    }
  ],
  "content_scripts": [{
    "matches": ["*://*.ebay.com/*"],
    "js": ["content.js"],
    "run_at": "document_idle",
    "all_frames": false
  }],
  "browser_action": {
      "default_title": "Download History.",
      "default_icon": "icon.png",
      "default_popup": "popup.html"
  },
  "manifest_version": 2
}

background.js

  chrome.runtime.onMessage.addListener((msg, sender) => {
    // First, validate the message's structure.
    if ((msg.from === 'content') && (msg.subject === 'showPageAction')) {
      // Enable the page-action for the requesting tab.
      chrome.browserAction.show(sender.tab.id);
    }
  });

content.js

// Inform the background page that 
// this tab should have a page-action.
function ping() {
  chrome.runtime.sendMessage('ping', response => {
    if(chrome.runtime.lastError) {
      setTimeout(ping, 1000);
    } else {
      chrome.runtime.sendMessage({
        from: 'content',
        subject: 'showPageAction',
      });
    }
  });
}

ping();


  // Listen for messages from the popup.
  chrome.runtime.onMessage.addListener((msg, sender, response) => {
    // First, validate the message's structure.
    if ((msg.from === 'popup') && (msg.subject === 'DOMInfo')) {
      // Collect the necessary data. 
      // (For your specific requirements `document.querySelectorAll(...)`
      //  should be equivalent to jquery's `$(...)`.)
      var domInfo = {
        total: document.querySelectorAll('*').length,
        inputs: document.querySelectorAll('input').length,
        buttons: document.querySelectorAll('button').length,
      };

      // Directly respond to the sender (popup), 
      // through the specified callback.
      response(domInfo);
    }
  });

popup.js

const setDOMInfo = info => {
    console.log(info)
};


window.addEventListener('DOMContentLoaded', () => {
    // ...query for the active tab...
    chrome.tabs.query({
      active: true,
      currentWindow: true
    }, tabs => {
      // ...and send a request for the DOM info...
      chrome.tabs.sendMessage(
          tabs[0].id,
          {from: 'popup', subject: 'DOMInfo'},
          // ...also specifying a callback to be called 
          //    from the receiving end (content script).
          setDOMInfo);
    });
  });

I know that this error occurs when the content script sends message to the background script but the background script is not ready to receive the message. After looking for a solution on stackoverflow I decided to use the ping function but as you can see above but it still gives me the same error message.

namko
  • 537
  • 5
  • 19

1 Answers1

0

There's no chrome.browserAction.show as you can see in the documentation so the listener in background.js throws and aborts the execution. The messaging cycle never completes so to the sender it looks just like an absence of any receiver.

Each part of an extension has its own devtools.
Open devtools for the background script and you'll see the error.

There's no need for the background script here.
No need for showPageAction message either because browser_action is enabled by default.

P.S. the entire code can be simplified by switching to programmatic injection (example) so you can remove content_scripts, background script, and messaging.

wOxxOm
  • 43,497
  • 7
  • 75
  • 96
  • I am using programmatic injection to inject code to the content.js based on what happens to popup.js. But now I want to do the opposite. I am trying to track an input value in the content page and make necessary changes in the popup page – namko Apr 19 '20 at 16:56
  • This answer is based on your question, which doesn't track anything. Still, programmatic injection can be used if you want to start tracking only after the user clicked something in the popup or simply opened the popup. – wOxxOm Apr 19 '20 at 17:00