Chrome extension regarding injected script + localstorage

content-script, google-chrome-extension, javascript

Solution

First of all: You do not need an injected script to access the page's DOM (`<img>` elements). The DOM is already available to the content script.

Content scripts cannot directly access the `localStorage` of the extension's process, you need to implement a communication channel between the background page and the content script in order to achieve this. Fortunately, Chrome offers a simple message passing API for this purpose.

I suggest to use the `chrome.storage` API instead of `localStorage`. The advantage of `chrome.storage` is that it's available to content scripts, which allows you to read/set values without a background page. Currently, your code looks quite manageable, so switching from the synchronous `localStorage` to the asynchronous `chrome.storage` API is doable.

Regardless of your choice, the content script's code has to read/write the preferences asynchronously:

// Example of preference name, used in the following two content script examples
var key = 'adurl';

// Example using message passing:
chrome.extension.sendMessage({type:'getPref',key:key}, function(result) {
    // Do something with result
});
// Example using chrome.storage:
chrome.storage.local.get(key, function(items) {
    var result = items[key];
    // Do something with result
});

As you can see, there's hardly any difference between the two. However, to get the first to work, you also have to add more logic to the background page:

// Background page
chrome.extension.onMessage.addListener(function(message, sender, sendResponse) {
    if (message.type === 'getPref') {
        var result = localStorage.getItem(message.key);
        sendResponse(result);
    }
});

On the other hand, if you want to switch to `chrome.storage`, the logic in your options page has to be slightly rewritten, because the current code (using `localStorage`) is synchronous, while `chrome.storage` is asynchronous:

// Options page
function load_options() {
   chrome.storage.local.get('repl_adurl', function(items) {
       var repl_adurl = items.repl_adurl;
       default_img.src = repl_adurl;
       tf_default_ad.value = repl_adurl;
   });
}
function save_options() {
   var tf_ad = document.getElementById('tf_default_ad');
   chrome.storage.local.set({
       repl_adurl: tf_ad.value
   });
}

Documentation

- `chrome.storage` (method get, method set)

- Message passing (note: this page uses `chrome.runtime` instead `chrome.extension`. For backwards-compatibility with Chrome 25-, use `chrome.extension` (example using both))

- A simple and practical explanation of synchronous vs asynchronous ft. Chrome extensions

Problem

I am puzzling my way through my first 'putting it all together' Chrome extension, I'll describe what I am trying to do and then how I have been going about it with some script excerpts: - I have an options.html page and an options.js script that lets the user set a url in a textfield -- this gets stored using localStorage. ``` function load_options() { var repl_adurl = localStorage["repl_adurl"]; default_img.src = repl_adurl; tf_default_ad.value = repl_adurl; } function save_options() { var tf_ad = document.getElementById("tf_default_ad"); localStorage["repl_adurl"] = tf_ad.value; } document.addEventListener('DOMContentLoaded', function () { document.querySelector('button').addEventListener('click', save_options); }); document.addEventListener('DOMContentLoaded', load_options ); ``` - My contentscript injects a script 'myscript' into the page ( so it can have access to the img elements from the page's html ) ``` var s = document.createElement('script'); s.src = chrome.extension.getURL("myscript.js"); console.log( s.src ); (document.head||document.documentElement).appendChild(s); s.parentNode.removeChild(s); ``` - myscript.js is supposed to somehow grab the local storage data and that determines how the image elements are manipulated. I don't have any trouble grabbing the images from the html source, but I cannot seem to access the localStorage data. I realize it must have to do with the two scripts having different environments but I am unsure of how to overcome this issue -- as far as I know I need to have myscript.js injected from contentscript.js because contentscript.js doesn't have access to the html source. Hopefully somebody here can suggest something I am missing. Thank you, I appreciate any help you can offer! -Andy

Original source

Related problems