Friday, December 11, 2009

Google Chrome extensions: example of how to use Options page


If you want to let the user customize the behavior of your extension, you can provide an Options page. In my Boss Key and Button extension (version 1.1), I use an Options page to allow the user control what features they want to enable. Here are the steps to do that.

Add the Options page to file manifest.json
{
  ...
  "options_page": "options.html",
  ...
}

Then in the extensions page (chrome://extensions/), the user can see an Options button beside your extension.

Write an Options page
It is an regular HTML file with the name that you have specified in the manifest.json file. In my example, I use some checkboxes to let the user enable or disable the features (s)he wants.
<html>
<head>
<title>Boss Key & Button Extension Options</title>

<script type="text/javascript">

function saveOptions() {
  localStorage["bossKnB12PrefEnableKey"] =
             document.getElementById("enableKey").checked;
...
}

function restoreOptions() {
  var value = localStorage["bossKnB12PrefEnableKey"];
  if (null != value)
     document.getElementById("enableKey").checked = toBool(value);
...
}
...
</script>
</head> 
 
<body onload="restoreOptions()">

<form>
<input type="checkbox" id="enableKey" checked="checked" /> Enable F12<br />
...
</form>

<button id="saveButton" onclick="saveOptions()">Save</button>
...

</body>
</html> 

When the Options page is loaded, function restoreOptions() is called. It would try to read the old preferences data from the localStorage, and pre-check/uncheck the checkbox on the page accordingly.

After the user has made his own choices, he presses the Save button. Function saveOptions() is then called and it would save the new preferences data to the localStorage.

Please note that in function restoreOptions(), I use a toBool() function to convert the value read from localStorage. That is because localStorage saves boolean value as a string.

Read preferences in Background pages
The localStorage is accessible in the Background pages, so it is very easy to read the preferences.
<script>
...
var value = localStorage["bossKnB12PrefEnableKey"];
if (null != value)
  prefEnableKey = toBool(value);
...
</script>

Read preferences in Content Scripts
The localStorage is not accessible in Content Scripts. To get the preferences in Content Scripts, I use chrome.extension.sendRequest() to send a request to the Background page and get the preferences data in the response.
chrome.extension.sendRequest({name: "getPreferences"},
     function(response)
     {
        myPrefEnableKey = response.prefEnableKey;
        ...
     });

The Background page waits for the request and sends back a response with the preferences data when it receives a request.
chrome.extension.onRequest.addListener(
     function(request, sender, sendResponse)
     {
        switch (request.name)
        {
           ...
           case "getPreferences":
              // request from the content script to get the preferences.
              sendResponse(
                    {
                       prefEnableKey : localStorage["bossKnB12PrefEnableKey"],
                       ...
                    });
              break;
           ...
        }
     }
);

Note: Source code here are simplified to made it more readable.

8 comments:

Anonymous said...

You've just saved me a lot of with that - cheers my good man!

I've read some suggestions that local storage may be opened up to content scripts in the future, but I like that this method encourages good practice by having a single access point to stored data.

Fafu said...

Very nice! Thanks a lot!

John Tarn said...

I keep getting undefined for the variable I'm trying to save the response to. but console.log shows the right data. any clues what could cause this?

Rob said...

Thanks for this, saved me a lot of time!

G Veera Sekhar said...

This worked perfect to me.
Thanks a lot for sharing the knoweldge !

G Veera Sekhar said...

@John Tarn,

By this time, you might solved the issue. Just to give info to anyone searching for that.

Instead of showing it in console, just assign to a method level variable and use it. Here's is the example.

function getLocalStorageValues(name) {

var value = "";
chrome.extension.sendMessage({ method : "getLocalStorageData", key: name },
function(response)
{
value = response.value;
}
);

return value;
}

Anonymous said...

@G Veera Sekhar

function getLocalStorageValues(name) {
var value = "";
chrome.extension.sendMessage({ method : "getLocalStorageData", key: name },
function(response)
{
value = response.value;
}
);
return value;
}

Do you even try to run that code? It won't work. It's wrong. You can't set value inside chrome.extension.sendMessage and the to use it outside

不使用名稱 said...

Oh my GOD!!
Thanks for your sharing,the knowledge helps me a lot!

 
Get This <