0

Code based on this answer: https://stackoverflow.com/a/9517879/947111

var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('script.js');
s.onload = function() {
    this.remove();
};
(document.head || document.documentElement).appendChild(s);

After the script has been loaded, the script tag being removed. And indeed if we try to debug target web page, if we will remove this.remove() line, after script was inject there is following line:

enter image description here

In every example where I've found injected script is being removed, but my question is why it's necessary?

What I want to achieve is to check if this script already was injected and if not inject it. If remaining script tag is antipattern, how can I check that script already was injected?

Anatoly
  • 5,056
  • 9
  • 62
  • 136
  • The only practical benefit is that when injecting at document_start you can avoid detection by the site. You can use a [global] variable in the content script that indicates the status. – wOxxOm Apr 08 '21 at 19:10
  • Actually, I can't. I want to check from [extension's content script](https://developer.chrome.com/docs/extensions/mv3/content_scripts/) if the script already been injected but I haven't access to the window object of the site before injection. I'm playing with it right now and it looks that altering `html` tag by adding to it custom attribute works, but I doubt is there better solution. – Anatoly Apr 08 '21 at 19:22
  • 1
    You seem to misunderstand me. Your content script is what adds the page script so the content script definitely can remember that it performed something by using a variable in the content script, which will be checked at a later time. – wOxxOm Apr 08 '21 at 19:32
  • I got you :) Very clean and simple solution, thank you. Can you write it as answer, so I will be able to accept you? – Anatoly Apr 08 '21 at 19:37

1 Answers1

0

Hope this can help you, basically, this code is permanently asking for some class or id in DOM, if that element is found you can inject the script into the page context.

this use a content script to access the page's context variables and functions:

 /**
 * loader.js
 * Injects necessary scripts into page context
 */

// Selector
const BTNPROCESSFILE = 'CB_594922000000710005';        

function injectScript(scriptPath) {
    let s = document.createElement('script');
    s.src = chrome.runtime.getURL(scriptPath);
    s.onload = function() {
        this.remove();
    };
    (document.head || document.documentElement).appendChild(s);
    
}

/**
 * This function checks if any element of the DOM is already rendered or loaded 
 * (You can choose any according to your DOM), 
 * for my case it is an ID called CB_594922000000710005
 */
async function searchElement() {
    do {
        await delayedLog()
        if (BTNPROCESSFILE) {
            //If the element was found then inject the script
            injectScript('src/content-script/injected.js');        
        }
    } while (!BTNPROCESSFILE)
}

function delay () {
    return new Promise(resolve => setTimeout(resolve, 100))
}
  
async function delayedLog () {
    // notice that we can await a function
    // that returns a promise
    await delay()

    btnFileProcess = document.getElementById(BTNPROCESSFILE)
}    
Frank Jose
  • 346
  • 3
  • 3