0

I used these pre-written chrome extension codes which I found here (thanks to @gkalpak) in stakoverflow to build (and most importantly getting familiar and getting engaged with JavaScript programming language on daily basis, because I thought based on my field of work which is working mainly with office applications and improving in programming Visual Basic programming, and occasionally with our company internal web service, making a chrome extension to automate my repetitive works in our web service is the best way for improving my JavaScript skills) my chrome extension. I know basics of javascript (Passed some online courses) but never practiced it on a practical-daily routine problem. I also read many of google's official documentation for developing an extension.

Here are my (used and not much edited) codes for each individual parts:

Manifest:

{
  "manifest_version": 2,
  "name": "Content to Popup",
  "version": "0.0",
  "offline_enabled": true,

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

  "content_scripts": [{
    "matches":["<all_urls>"],
    "js": ["content.js"],
    "all_frames": false
  }],

  "page_action": {
    "default_title": "Test Extension",
    "default_icon": {
      "19":"icon.png"
    },
  "default_popup": "popup.html"
  }
}

background.js:

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

content.js:

// (Original Code author's comment) Inform the background page that this tab should have a page-action.
chrome.runtime.sendMessage({
  from: 'content',
  subject: 'showPageAction',
});

// (Original Code author's comment) Listen for messages from the popup.
chrome.runtime.onMessage.addListener((msg, sender, response) => {
  // (Original Code author's comment) First, validate the message's structure.
  if ((msg.from === 'popup') && (msg.subject === 'DOMInfo')) {
    // (Original Code author's comment) Collect the necessary data. 
    var domInfo = {
      total: document.querySelectorAll('*').length,
      inputs: document.querySelectorAll('input').length,
      buttons: document.querySelectorAll('button').length,
      // Here I tried to select an element in a specific website which I know it exists
      // (Through 'inspect' tool of chrome)
      specificElement: document.querySelector("span[class='masthead-nav-item- 
    text']")
    };

    // (Original Code author's comment) Directly respond to the sender (popup) through the specified callback.
    response(domInfo);
  }
});

Popup.js

// (Original Code author's comment) Update the relevant fields with the new data.
const setDOMInfo = info => {
  document.getElementById('total').textContent = info.total;
  document.getElementById('inputs').textContent = info.inputs;
  document.getElementById('buttons').textContent = info.buttons;
  // Here I tried to fill a cell in "Popup.html" which I added it in popoup.html file
  document.getElementById('elementValue').textContent = 
 info.specificElement.childNodes[0].nodeValue
 };

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

Popop.html:

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="popup.js"></script>
  </head>
  <body>
    <h3 style="font-weight:bold; text-align:center;">DOM Info</h3>
    <table border="1" cellpadding="3" style="border-collapse:collapse;">
      <tr>
         <td nowrap>Total number of elements:</td>
        <td align="right"><span id="total">N/A</span></td>
      </tr>
      <tr>
        <td nowrap>Number of input elements:</td>
        <td align="right"><span id="inputs">N/A</span></td>
      </tr>
      <tr>
        <td nowrap>Number of button elements:</td>
        <td align="right"><span id="buttons">N/A</span></td>
      </tr>
      //----This is the row which I added and expected to show my value----
      <tr>
        <td>Element Value:</td>
        <td nowrap><span id="elementValue">N/A</span></td>
      </tr>
    </table>
  </body>
</html>

My Problem is that the 4th row in my popoup page is always empty or N/A:

My added row always shows "N/A" or it's empty

I used many methods like .childNode[] , .firstCild and... to refer to an already know existed element on any page. I should mention that 3 First rows (which are in original code) are always get populated on every site. What am I missing?

Milad
  • 77
  • 11
  • On an unrelated note: Your extension uses Manifest V2, which is being phased out, see [Manifest V2 support timeline](https://developer.chrome.com/docs/extensions/mv3/mv2-sunset/) - It's recommended that you switch to Manifest V3, see [Migrating to Manifest V3](https://developer.chrome.com/docs/extensions/mv3/mv3-migration/) – Thomas Mueller Mar 11 '23 at 10:47
  • @ThomasMueller Thanks Thomas. I know but it seems that I started to learn Javascript in bad time (In transactions time). Unfortunately this is the only example that I found which comprehensively match to my goal which is: sending a message from content script to popup – Milad Mar 11 '23 at 10:53
  • 1
    DOM element cannot be transferred between a content script and the popup. You should transfer individual properties of the element. You can see what is transferred by debugging the popup in devtools with breakpoints in the source code. Note that the popup is a separate window so it has its own separate devtools: right-click inside the popup and select "inspect" in the menu. – wOxxOm Mar 11 '23 at 12:35
  • @wOxxOm Thank you wOxxOm. Based on what you have said I added `.textContent` to `specificElement: document.querySelector("span[class='masthead-nav-item- text']")` in my **content.js** and deleted that method in my **popup.js** but the result was a string which was shown as [object Object] in designated cell – Milad Mar 11 '23 at 12:42
  • @wOxxOm You pointed out the root of my problem. Later I used `JSON.stringify()' in my Content.js to only pass a string to popup and it worked. Thanks again. – Milad Mar 11 '23 at 13:03

0 Answers0