1

For a simple Chrome extension I've made that finds and replaces a text string I'm trying to add an option to add an asterisk after the replaced text. I have a bloolean variable showAsterisk that gets set in options.js from the options.html dialogue. I can see from the console that the value is being set properly, however it is not being retrieved with chrome.storage.sync.get. Not sure what I'm doing wrong. Here is the relevant code:

manifest.json

"permissions": ["storage"],
"options_ui": {
    "page": "options.html",
    "chrome_style": true
    },

options.html

<h1>Options</h1>
<p><input type="checkbox" id="showAsterisk"> Add an asterisk after each instance of replaced text.</p>
<button id="save">Save</button>
<script src="options.js"></script>

options.js

function save_options() {
  var showAsterisk = document.getElementById('showAsterisk').checked;
  chrome.storage.sync.set({ showAsterisk: showAsterisk }, function() {
    window.close();
  });
}

function restore_options() {
  chrome.storage.sync.get({ showAsterisk: false }, function(items) {
    document.getElementById('showAsterisk').checked = items.showAsterisk;
  });
}

document.addEventListener('DOMContentLoaded', restore_options);
document.getElementById('save').addEventListener('click', save_options);

content.js

var elements = document.getElementsByTagName("*");

var showAsterisk = false;

chrome.storage.sync.get("showAsterisk", function(items) {
    if(typeof items.showAsterisk !== "undefined") showAsterisk = items.showAsterisk;
})

for (var i = 0; i < elements.length; i++) {
    var element = elements[i];

    for (var j = 0; j < element.childNodes.length; j++) {
        var node = element.childNodes[j];

        if (node.nodeType === 3) {
            var text = node.nodeValue;

            if (showAsterisk === true) {
              var replacedText = text.replace(/Moda Center/gi, "Rose Garden*");
            }

            if (showAsterisk === false) {
              var replacedText = text.replace(/Moda Center/gi, "Rose Garden");
            }

            if (replacedText !== text) {
                element.replaceChild(document.createTextNode(replacedText), node);
            }
        }
    }
}
zach4618
  • 57
  • 7
  • Where is it not being retrieved? Your options.js script is loaded at the end when the document is ready so you don't need DOMContentLoaded listener, just call `restore_options()` directly. – wOxxOm Jul 29 '16 at 21:13
  • In content.js below the code I've shown there is an if statement in the find/replace script that either adds the asterisk or not. It's not being retrieved in content.js because the extension just uses whatever I set the default value as at the top of content.js. – zach4618 Jul 30 '16 at 00:14
  • 1
    The posted code seems to be correct. [Debug it](https://developer.chrome.com/extensions/tut_debugging): set a breakpoint inside chrome.storage.sync.get and see what happens. Make sure you use the asynchronous callback [properly](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call): outside it the value isn't yet retrieved. – wOxxOm Jul 30 '16 at 00:20
  • Thanks @wOxxOm for the suggestion. The debug tutorial seems to be outdated however. When I open developer tools there is no "scripts" tab. Am I missing something? – zach4618 Jul 30 '16 at 20:23
  • Just click through all panels and explore the abundance of features: the devtools inspector and debugger are the most important and handy means of diagnosing problems quickly and precisely. Also, I'm not The Source of All Knowledge so you're free to find other/better tutorials and references. – wOxxOm Jul 30 '16 at 20:28

1 Answers1

2

I am having no problem with the extension working properly.

In the developer tools you want to make sure you're opening the frame that the options page runs in, otherwise you'll be asking the extensions webpage, rather than the options page when debugging and testing things.

Running the following gives me false when I hit "Save" with the box uncheck in the options:

chrome.storage.sync.get({'showAsterisk' : '0'}, function(items){console.log(items.showAsterisk)});

And when I run this again but instead with it checked I get true.

It seems to be getting the data as intended, just when you're testing with the developer tools you may be in the wrong frame. Even running this on a random page like a google search result I can get the data. However I will get an error if I don't switch the frame the console is showing. See the image below for what I am talking about:

You want this:

picture of what you want

Not this default frame:

picture of what you don't want

Edit:

Referencing why you are not seeing the asterisks. I believe it is because your extension was not actually injecting onto any pages. I could not see it in the list when on a web page. However, I altered the permissions line in your manifest to the following:

"permissions": ["storage","http://*/*","https://*/*"],

Now it loads on webpages:

Chrome extension loaded on hackernews

ComputerLocus
  • 3,448
  • 10
  • 47
  • 96
  • thanks for the response. I'm able to duplicate your results. I can see now that the showAsterisk variable is being set and retrieved properly, but now I'm wondering why it doesn't work. That is, the asterisk never actually shows regardless of the value of showAsterisk. I've posted the rest of the code from content.js to show how I'm using that variable. – zach4618 Aug 01 '16 at 06:57
  • @zach4618 See my edit, it looks like it was a permissions issue and the code simply wasn't being injected. – ComputerLocus Aug 01 '16 at 15:48
  • Changed the permissions setting but it's still not working. Were you able to get the extension to actually replace the text with/without the asterisk depending on the setting? Here's a page where you can check: https://en.wikipedia.org/wiki/Moda_Center – zach4618 Aug 01 '16 at 22:47