-1

So I'm trying to make an extension that allows you to write custom JS to be injected on any page for a given domain. My popup loads the saved JS code, and when clicking save, the JS is evaluated, and that works just fine. I can't figure out how to get the code to evaluate on page load, though.

Here is what I have so far.

//Content.js

//Globals
var entries = {"test": "test"};     //Entries dictionary "domain": "js code"
var url = window.location.href;     //Full URL of the tab
var parts = url.split("/");         //URL split by '/' character
var domain = parts[2] + '';         //Just the domain (global)

loadChanges();
chrome.runtime.onMessage.addListener(listener);

window.onload=eval(entries[domain]); //doesn't work


function listener (request, sender, sendResponse) {
    console.log("Manipulating data for: " + domain);
    if (request == "LOAD"){
        if(entries.hasOwnProperty(domain)){
            console.log("PE - Loaded Value: " + entries[domain].toString());
            sendResponse(entries[domain]);
        } else {
            console.log("Nothing to load");
            sendResponse('');
        }
    } else {
        entries[domain] = request;
        console.log(entries[domain]);
        saveChanges();
        eval(request); //This one DOES work
    }
}

//Load saved code (on startup)
function loadChanges() {
    chrome.storage.local.get(['PE'], function (data){
        console.log(data.PE);
        if (data.PE == null){
            return;
        }
        entries=data.PE;
    });
    
    if(entries.hasOwnProperty(domain)){
        eval(entries[domain]); //doesn't work
    }
}

//Save changes to code (on button press)
function saveChanges() {
    chrome.storage.local.set({PE: entries}, function(data){
        console.log("Saved Value: " + entries[domain])
    });
}

Note the "doesn't work" comments in there.

manifest.json
{
    "name": "PersistEdit",
    "version": "0.1.1",
    "manifest_version": 2,
    "content_scripts":[
        {
            "matches": ["<all_urls>"],
            "js": ["content.js"],
            "run_at": "document_end",
            "persistent": false
        }
    ],
    "background": {
        "scripts": [
            "background.js"
        ],
        "persistent": false
    },
    "browser_action": {
        "default_popup": "popup.html",
        "default_title": "PersistEdit"
    },
    "permissions": [
        "storage"
    ]
}
document.addEventListener('DOMContentLoaded', onload, false);

function onload(){
    chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
        chrome.tabs.sendMessage(tabs[0].id, "LOAD");
    });
}

Didn't include my popup.html or popup.js because those parts of it work as intended, but I can include them if necessary. I'm not sure what I'm missing here, any guidance would be appreciated.

Scrub Nugget
  • 9
  • 1
  • 4
  • Chrome extensions are sandboxed to prevent people injecting malicious code into websites. Specifically [`eval` is disabled](https://developer.chrome.com/docs/extensions/mv3/sandboxingEval/). – Andy Sep 10 '21 at 05:00
  • @Andy I was able to get eval to work, I just hadn't formatted my window.onload correctly. As it turns out, it needed to be inside of a user defined function. – Scrub Nugget Sep 10 '21 at 05:09

1 Answers1

0

window.onload is supposed to be a function. Here window.onload=eval(entries[domain]); you are just assigning the result of eval to onload(which happens immediately during the assignment). It's possible that entries isn't properly populated at that time.

Try the following code

    window.onload=function () {
      eval(entries[domain]);
    }
Hariom Balhara
  • 832
  • 8
  • 19