just-jeb / angular-chrome-extension

81 stars 29 forks source link

How to use an injected content script #1

Closed garethharding closed 4 years ago

garethharding commented 4 years ago

Thanks for your work on this, has been really helpful.

I was wondering if you knew how to add a content script? I've been racking my brains for a while and have tried every combo of ...

  chrome.tabs.executeScript(null, {
    file: "content.js"
  });

The standard way above works fine for vanilla js but in the context of angular it doesn't seem to work. I presume something webpack related maybe.

I've updated the webpack conf as so...

module.exports = {
  entry: {
    background: "src/background.ts",
    content: "src/content.ts"
  }
};

(dev)

entries: {
        background: "background",
        content: "content"
      }

and the content file transpiles to the dist dir fine. It evens reports to have injected properly with no last runtime error, however I am unable to see any logs or alerts in the websites own console.

Do you kow what might be the way to get this working in the angular context you presented?

thanks :)

just-jeb commented 4 years ago

Mind creating a fork for reproduction so that I could take a look?

just-jeb commented 4 years ago

Not sure what your exact use case is but you can try declarative content scripts.

garethharding commented 4 years ago

Hey, thanks so much for your reply. I've figured it out as it happens. Let me see if I can find my answer when I'm back at my desk and post it here for posterity :)

just-jeb commented 4 years ago

That would be much appreciated, thank you.

azimsodikov commented 4 years ago

What was the solution for this problem @garethharding . I'm having the same issue where content script is not running.

garethharding commented 4 years ago

This was the gist of what I did if I remember correctly. Maybe errors etc as can't find original version. Not a solution using webpack which i'd have preferred but works well for my needs.

Background script - install your content script via appropriate hooks

// on first install ------------------
chrome.runtime.onInstalled.addListener(() => {
  // on every navigation event ------------------
  chrome.webNavigation.onCompleted.addListener(async () => {
    chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
        if (tabs[0].url.includes("chrome://")) return;

        // this injects content script
        chrome.tabs.executeScript(null, { file: "js/content-script.js" }, () => {});
    });
  });
}); // end onInstalled listener

Content script - install angular

(async () => {
    installApp();  
})();

function installApp() {
  document.body.insertAdjacentHTML("beforeend", `<app-root></app-root>`);
  // point these to your own files. localhost here so can use live reload via ng serve
  addScript("http://localhost:4200/runtime.js");
  addScript("http://localhost:4200/polyfills.js");
  addScript("http://localhost:4200/styles.js");
  addScript("http://localhost:4200/vendor.js");
  addScript("http://localhost:4200/main.js");
}

function addScript(src) {
  var s = document.createElement("script");
  s.setAttribute("src", src);
  document.body.appendChild(s);
}
chan-dev commented 3 years ago

any updates on this one? Can't you just reference all the compiled angular-related files and reference them under content_scripts in manifest.json

 // some codes omitted for brevity
  "content_scripts": [
    {
       "matches": ["http://*/*", "https://*/*"],
      "js": ["polyfills.js", "runtime.js", "main.js"],
    }
  ]

In theory, we're essentially just injecting everything in angular as part of a content script w/c is loaded on pages specified by matches property.

In this case, we can just create a separate component for any browser_action or page_action functionality.

just-jeb commented 3 years ago

@chan-dev didn't check that but I don't see why it wouldn't work. Out of curiosity, why do you need Angular in content script? Purely for DI? Or something else?

chan-dev commented 3 years ago

@just-jeb we're currently working on a chrome extension and sort of had a similar setup where instead of using a popup, we use angular components to show a sidebar w/c is an Angular component and you toggle the sidebar when you press the chrome extension icon and with the ability to pin the sidebar w/c I believe you can't do using a popup.

just-jeb commented 3 years ago

Yup, sounds about right.