Search code examples
javascriptgoogle-chrome-extension

Chrome Extensions - How to run eval code on page load


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.


Solution

  • 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]);
        }