1

I'm trying to share data between the browser_action and the content_scripts.

Currently, I'm having an issue where I CAN access the data in the browser_action page (it returns the proper values once set and saves across sessions).

HOWEVER, I can't seem to access the data in the content_script, even after being saved in the browser_action.js. The console.log always return "undefined" for the value.

The expected workflow would be:

content_script:

if syncData === undefined {
    /* Do default stuff */
} else if syncData {
    /* Do stuff if set to true */
} else {
    /* Do stuff if set to false */
}

browser_action.js:

/* Allow user to set syncData so that it saves across page refreshes and is accessible by content_script */

manifest.json

{
    "manifest_version": 2,

    "name": "Name",
    "description": "Description",
    "version": "1.0",
    "content_scripts": [
        {
            "js": ["content_script.js"]
        }
    ],
    "browser_action": {
        "default_icon": "icon128.png",
        "default_popup": "browser_action.html"
    },
    "icons": {
        "16": "icon16.png",
        "48": "icon48.png",
        "128": "icon128.png"
    },
    "permissions": [
        "storage"
    ]
}

content_script.js

chrome.storage.sync.get('descriptionEnabled', function (data) {
    console.log(data.descriptionEnabled)
});

browser_action.js

/*jslint browser: true*/
/*global window, document, alert, chrome */

window.onload = function () {
    "use strict";
    chrome.storage.sync.get('descriptionEnabled', function (data) {
        if (data.descriptionEnabled === true) {
            document.getElementById("settingsId").value = "on";
        } else if (data.descriptionEnabled === false) {
            document.getElementById("settingsId").value = "off";
        }
    });
    document.getElementById("settingsId").onchange = function () {
        if (document.getElementById("settingsId").value === "on") {
            chrome.storage.sync.set({'descriptionEnabled': true});
        } else {
            chrome.storage.sync.set({'descriptionEnabled': false});
        }
    };
};

browser_action.html

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
        <script type="text/javascript" src="browser_action.js"></script>
        <title>Description Background Page</title>
    </head>
    <body>
        <div>Display Saved Notifications?</div>
        <div>
            <select id="settingsId">
                <option value="on">Yes</option>
                <option value="off">No</option>
            </select>
        </div>
    </body>
</html>
Britt
  • 23
  • 4

3 Answers3

0

To store user data for your extension, you can use either storage.sync or storage.local. When using storage.sync, the stored data will automatically be synced to any Chrome browser that the user is logged into, provided the user has sync enabled.

When Chrome is offline, Chrome stores the data locally. The next time the browser is online, Chrome syncs the data. Even if a user disables syncing, storage.sync will still work. In this case, it will behave identically to storage.local.

Check this document for more information and sample codes.

For the error you receive, you can understand more by reading this blog. It explains here what is the meaning and caused of getting undefined in console.log

Also try to check this SO question. It think it will help you a lot about content script and background action.

Community
  • 1
  • 1
KENdi
  • 7,205
  • 2
  • 14
  • 26
0

First of all, don't forget to add matches field in you manifest.json.

Your code works well, but please be aware you set the storage after popup page loads and options changes, so you will then need to refresh the web page to re-load the content scripts to make it executed again, then you will see true or false from the console in the current web page.

Haibara Ai
  • 9,915
  • 2
  • 23
  • 44
0

While messaging is the most usual way to communicate between content and extension scripts, you can use storage, too. In your content script, add a listener for storage's changed event:

chrome.storage.onChanged.addListener(function(changes, areaName){
if(areaName=="sync"){
  if(changes.descriptionEnabled) 
    console.log(changes.descriptionEnabled.newValue);
  }
});

Storage, especially local, is pretty fast, so sometimes, when you need to save the data into storage anyway, listening for storage changes instead of messages makes sense.

An additional difference with messaging is that this event will be fired on changed value only. If your value was true, and the new value is also true, the event won't be fired.

Mike Tyukanov
  • 495
  • 4
  • 9