Home > Software design >  Chrome Extension embedding script in active web page, in MV3?
Chrome Extension embedding script in active web page, in MV3?

Time:10-01

beautiful people on the internet. I am new to chrome extension not new to writing code though. I have implemented webpack to use external packages. One major one in my application is npm package by the name "mark.js".

My application works like this i want some specific words to be highlighted in active webpage using this package. I have written code for this to achieve the functionality but the problem is with loading the script in a web page. I have performed different aspect of loading script but that doesnot work. The new MV3 version have some strict rules.

I want to achieve anything similar of loading script in an active webpage. Please help.

btn.addEventListener("click", async () => {
  console.log("BUTTON IS PRESSED!!");
  try {
    await chrome.tabs.query(
      { active: true, currentWindow: true },
      async function (tabs) {
        
        chrome.scripting.executeScript({
          target: { tabId: tabs[0].id },
          func: highlightText,
          args: [arr],
        });
      }
    );
  } catch (e) {
    console.log("ERROR AT CHROME TAB QUERY : ", e);
  }
});


async function highlightText(arr) {
  console.log(typeof Mark);
  
  try {
    var instance2 = new Mark(document.querySelector("body"));
    // instance2.mark("is");

    var success = [];
    // const instance2 = new Mark(document.querySelector("body"));
    await Promise.all(
      arr.map(async function (obj) {
        console.log("OBJECT TEXT : ", obj.text);
        instance2.mark(obj.text, {
          element: "span",
          each: function (ele) {
            console.log("STYLING : ");
            ele.setAttribute("style", `background-color: ${obj.color};`);
            if (obj.title && obj.title != "") {
              ele.setAttribute("title", obj.title);
            }
            ele.innerHTML = obj.text;
            success.push({
              status: "Success",
              text: obj.text,
            });
          },
        });
      })
    );
    console.log("SUCCESS : ", success);
  } catch (error) {
    console.log(error);
  }
}

CodePudding user response:

For V3 I assume you will want to use Content Scripts in your manifest to inject the javascript into every webpage it matches. I recently open-sourced TorpedoRead and had to do both V2 and V3, I recommend checking the repo as it sounds like I did something similar to you (Firefox is V2, Chrome is V3).

The code below need to be added to your manifest.json and this will execute on every page based on the matches property. You can read more about content scripts here: https://developer.chrome.com/docs/extensions/mv3/content_scripts/

"content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["yourscript.js"]
    }
 ],

CodePudding user response:

There's no need to use chrome.runtime.getURL. Since you use executeScript to run your code all you need is to inject mark.js before injecting the function.

Also, don't load popup.js in content_scripts, it's not a content script (these run in web pages), it's a script for your extension page. Actually, you don't need content_scripts at all.

btn.addEventListener('click', async () => {
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
  const target = { tabId: tab.id };
  const exec = v => (await chrome.scripting.executeScript({ target, ...v }))[0].result;
  if (!(await exec({ func: () => !!window.Mark }))[0].result) {
    await exec({files: ['mark.js.min'] });
    await exec({func: highlightText, args: [arr] });
  }
});
  • Related