2

I'm making a extension for Google Chrome, the extension deletes all browsing data when the user clicks it, the extension works fine but now im trying to add a options panel where the user can choose which data to delete, my problem is that the options made by the user in the options panel are not being saved (or im not being able to retrieve the data stored in localStorage properly) because when i access the options panel again after saving and closing the checkboxes are blank again.

Manifest [manifest.json]

{
  "name": "TEST TITLE",
  "version": "1.0",
  "manifest_version": 2,
  "description": "TEST DESCRIPTION",
  "options_page": "options.html",
  "icons": { "16": "icon-small.png",
            "48": "icon-medium.png",
            "128": "icon-big.png" },
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "permissions": [
    "storage",
    "browsingData"
  ]
}

HTML [popup.html]

<!DOCTYPE html>
<html>
  <head>
  <script src="script.js"></script>
  </head>
  <body>
  </body>
</html>

HTML [options.html]

<!DOCTYPE html>
<html>
  <head>
  <script src="script-options.js"></script>
  <link href="style.css" rel="stylesheet" type="text/css" />
  </head>
  <body onLoad="loadOptions()">
  <div id="wrapper-options">
  <div id="header-options">OPTIONS</div>
  <div id="content-options">
  <div id="checkbox-options">
  <input name="" id="protectedWeb-checkbox" type="checkbox" value="">Websites that have been installed as hosted applications
  </div>
  <div id="checkbox">
  <input name="" id="unprotectedWeb-checkbox" type="checkbox" value="">Normal websites
  </div>
  <div id="checkbox">
  <input name="" id="extension-checkbox" type="checkbox" value="">Extensions and packaged applications a user has installed
  </div>
  <div id="checkbox">
  <input name="" id="appcache-checkbox" type="checkbox" value="">Websites appcaches
  </div>
  <div id="checkbox">
  <input name="" id="cache-checkbox" type="checkbox" value="">Browser's cache
  </div>
  <div id="checkbox">
  <input name="" id="cookies-checkbox" type="checkbox" value="">Browser's cookies
  </div>
  <div id="checkbox">
  <input name="" id="downloads-checkbox" type="checkbox" value="">Browser's download
  </div>
  <div id="checkbox">
  <input name="" id="fileSystems-checkbox" type="checkbox" value="">Websites file systems
  </div>
  <div id="checkbox">
  <input name="" id="formData-checkbox" type="checkbox" value="">Browser's stored form data
  </div>
  <div id="checkbox">
  <input name="" id="history-checkbox" type="checkbox" value="">Browser's history
  </div>
  <div id="checkbox">
  <input name="" id="indexedDB-checkbox" type="checkbox" value="">Websites IndexedDB data
  </div>
  <div id="checkbox">
  <input name="" id="localStorage-checkbox" type="checkbox" value="">Websites local storage data
  </div>
  <div id="checkbox">
  <input name="" id="pluginData-checkbox" type="checkbox" value="">Plugins data
  </div>
  <div id="checkbox">
  <input name="" id="passwords-checkbox" type="checkbox" value="">Stored passwords
  </div>
  <div id="checkbox">
  <input name="" id="webSQL-checkbox" type="checkbox" value="">Websites WebSQL data
  </div>
  <div id="button-option">
  <input name="" type="button" value="SAVE" onClick="saveOptions()">
  <input name="" type="button" value="CANCEL" onClick="">
  </div>
  </div>
  </div>
  </body>
</html>

JavaScript [script.js]

// JavaScript Document

function browsingdata(){
chrome.browsingData.remove({
  "originTypes": {
    "protectedWeb": true, // Set to true or false as per your requirement / Websites that have been installed as hosted applications
    "unprotectedWeb":true, // Set to true or false as per your requirement / Normal websites
    "extension":true // Set to true or false as per your requirement / Extensions and packaged applications a user has installed
  }
}, {
  "appcache": true, // Set to true or false as per your requirement / Websites appcaches
  "cache": true, // Set to true or false as per your requirement / Browser's cache
  "cookies": true, // Set to true or false as per your requirement / Browser's cookies
  "downloads": true, // Set to true or false as per your requirement / Browser's download
  "fileSystems": true, // Set to true or false as per your requirement / Websites file systems
  "formData": true, // Set to true or false as per your requirement / Browser's stored form data
  "history": true, // Set to true or false as per your requirement / Browser's history
  "indexedDB": true, // Set to true or false as per your requirement / Websites IndexedDB data
  "localStorage": true, // Set to true or false as per your requirement / Websites local storage data
  "pluginData": true, // Set to true or false as per your requirement / Plugins data
  "passwords": true, // Set to true or false as per your requirement / Stored passwords
  "webSQL": true // Set to true or false as per your requirement / Websites WebSQL data
}, function (){
    console.log("All data Deleted");
});
}
window.onload=browsingdata;

JavaScript [script-options.js]

// JavaScript Document

function saveOptions() {
    if (document.getElementById('protectedWeb-checkbox').checked) {
        localStorage.setItem('protectedWeb-checkbox', "true");
    } else {
        localStorage.setItem('protectedWeb-checkbox', "false");
    }
}

function loadOptions() {
    if (localStorage.getItem('protectedWeb-checkbox') == "true") {
        console.log("its checked");
        document.getElementById("protectedWeb-checkbox").checked=true;
    } else {
        console.log("its not checked");
    }
}

In addition to the main question i also would like to know which is the best way in your opinion to add the other 14 options to JavaScript [script-options.js] and how would you recommend i change the value (true/false) on JavaScript [script.js] using also JavaScript, and ANY advice or recommendation about the whole extension code also would be very appreciated.

As always thanks in advance for taking the time to read this, the below list are all the StackOverflow questions and sites i've been reading so far.

https://stackoverflow.com/questions/3033829/google-chrome-extension-local-storage
https://stackoverflow.com/questions/2153070/do-chrome-extensions-have-access-to-local-storage
https://stackoverflow.com/questions/11679967/remember-checkbox-with-localstorage-onclick
http://julip.co/2010/01/how-to-build-a-chrome-extension-part-2-options-and-localstorage/
https://developer.chrome.com/stable/extensions/storage.html
Community
  • 1
  • 1
Minnen
  • 441
  • 8
  • 27

3 Answers3

4

And here's my contibution.
Done the way it is because I HATE doing html/css ;)
Got auto save on the options so no need for the save button.
Commented out the bit that clears things on the popup press, didnt want to clear anything.
manifest.json

{
  "name": "ProtectedWeb",
  "description" : "http://stackoverflow.com/questions/13617257/saving-data-in-localstorage-for-a-googlechrome-extension-options-panel-and-acces/",
  "version": "1.0",
  "permissions": [
    "tabs", "<all_urls>","storage","browsingData"
  ],
  "browser_action": {
      "default_title": "Clear stuff",
      "default_icon": "icon.png",
      "default_popup": "popup.html"
  },
  "options_page": "options.html",
  "manifest_version":2
}

options.html

<html>
  <head>
  <script src="options.js"></script>
  </head>
  <body>
  <div id="wrapper-options">
  <div id="header-options">OPTIONS</div>
  <div id="content-options">
    <br />
    Origin Type
    <div id="originTypes">
    </div>
  <div id="checkbox-options">
    <br />
    Options
    <div id="options">
    </div>
  </div>
  </div>
  </div>
  </body>
</html>

options.js

// This is where we store the default options if there aren't any options saved and it gets replaced with what is saved on load if there is anything in storage
var Options = {
    "originTypes": {
        "protectedWeb": false,
        // Set to false or false as per your requirement / Websites that have been installed as hosted applications
        "unprotectedWeb": true,
        // Set to true or false as per your requirement / Normal websites
        "extension": false
        // Set to true or false as per your requirement / Extensions and packaged applications a user has installed
    },
    options: {
        "appcache": true,
        // Set to false or false as per your requirement / Websites appcaches
        "cache": true,
        // Set to false or false as per your requirement / Browser's cache
        "cookies": true,
        // Set to false or false as per your requirement / Browser's cookies
        "downloads": true,
        // Set to false or false as per your requirement / Browser's download
        "fileSystems": true,
        // Set to false or false as per your requirement / Websites file systems
        "formData": true,
        // Set to false or false as per your requirement / Browser's stored form data
        "history": true,
        // Set to false or false as per your requirement / Browser's history
        "indexedDB": true,
        // Set to false or false as per your requirement / Websites IndexedDB data
        "localStorage": true,
        // Set to false or false as per your requirement / Websites local storage data
        "pluginData": true,
        // Set to false or false as per your requirement / Plugins data
        "passwords": true,
        // Set to false or false as per your requirement / Stored passwords
        "webSQL": true
        // Set to false or false as per your requirement / Websites WebSQL data
    }
}


var optionsTemplate = {
    originTypes: [{
        name: "appcache",
        title: "appcache",
        description: "Websites appcaches"

    }, {
        name: "unprotectedWeb",
        title: "Unprotected Web",
        description: "Normal websites"

    }, {
        name: "extension",
        title: "Extension",
        description: "Extensions and packaged applications a user has installed"

    }],
    options: [{
        name: "appcache",
        title: "appcache",
        description: "Websites appcaches"

    }, {
        name: "cache",
        title: "cache",
        description: "Browser's cache"

    }, {
        name: "cookies",
        title: "cookies",
        description: "Browser's cookies"

    }, {
        name: "downloads",
        title: "downloads",
        description: "Browser's download"

    }, {
        name: "fileSystems",
        title: "fileSystems",
        description: "Websites file systems"

    }, {
        name: "formData",
        title: "formData",
        description: "Browser's stored form data"

    }, {
        name: "history",
        title: "history",
        description: "Browser's history"

    }, {
        name: "indexedDB",
        title: "indexedDB",
        description: "Websites IndexedDB data"

    }, {
        name: "localStorage",
        title: "localStorage",
        description: "Websites local storage data"

    }, {
        name: "pluginData",
        title: "pluginData",
        description: "Plugins data"

    }, {
        name: "passwords",
        title: "passwords",
        description: "Stored passwords"

    }, {
        name: "webSQL",
        title: "webSQL",
        description: "Websites WebSQL data"
    }]
}

var optionsTemplateSelectors = {
    originTypes: '#originTypes',
    options: '#options'
}


renderHTML = function(template, targets) {
    var key, keys, elements = {};
    keys = Object.keys(targets);
    for(var i = 0; i < keys.length; i++) {
        key = keys[i];
        elements[key] = document.querySelector(targets[key]);
        if (elements[key]===null) console.debug('Couldn\'t find "'+key+'"" using the querySelector "'+targets[key]+'"');
    }

    var sections = Object.keys(template),
        section;
    var item;
    var checkbox, div, text;
    for(var z = 0; z < sections.length; z++) {
        section = sections[z];
        for(var i = 0; i < template[section].length; i++) {
            item = template[section][i];
            div = document.createElement('div');
            text = document.createTextNode(item.title);
            checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.id = item.name + '-checkbox';
            checkbox.dataset['section'] = section;
            checkbox.dataset['key'] = item.name;
            checkbox.title = item.description;
            if(Options[section][item.name] === true) checkbox.checked = true;
            checkbox.addEventListener('change', checkboxChanged);
            div.id = item.name;
            div.appendChild(checkbox);
            div.appendChild(text);
            elements[section].appendChild(div);
        }
    }
}


checkboxChanged = function(evt) {
    var src = evt.srcElement;
    var checked = src.checked;
    Options[src.dataset['section']][src.dataset['key']] = checked;
    chrome.storage.local.set({
        'options': Options
    });
}


init = function() {
    chrome.storage.local.get('options', function(options) {
        if(Object.keys(options).length === 0) {
            chrome.storage.local.set({
                'options': Options
            });
        } else {
            Options = options.options;
        }
        renderHTML(optionsTemplate, optionsTemplateSelectors);
    })
}


window.addEventListener('load', init);

popup.html

<!doctype html>
<html>
  <head>
    <script src="popup.js"></script>
  </head>
  <body>
  </body>
</html>

popup.js

chrome.storage.local.get('options', function(data) {
    chrome.browsingData.remove({
  "originTypes":data.options.originTypes
},data.options.options);
});

//window.close();
PAEz
  • 8,366
  • 2
  • 34
  • 27
  • 1
    oh and `optionTitlesDescripions` was meant to be `optionTitlesDescriptions'....buggered if I can be bothered fixing it now ;) And as Ha. said, your settings where getting deleted by you every time the popup came up, because your clearing the browser history/storage including those belonging to extensions which included your own. – PAEz Nov 29 '12 at 18:46
  • Thanks for the answer @PAEz unfortunately your code doesn't work, all it does is print some stuff where the checkboxes for the options used to be. – Minnen Nov 29 '12 at 23:29
  • 1
    @Minnen So sorry, forgot {} doesnt equal nothing so checks its keys length now. Also changed the templatey bit so it keeps its order and a couple of other things while I was at it (plan on using something like this myself soon, so needed to get it right ;) ). Hope it works out for you....should. – PAEz Nov 30 '12 at 10:28
  • 1
    @Minnen Also should point out that each `originTypes` could have its own set of `options`. – PAEz Nov 30 '12 at 17:12
  • hi @PAEz, the code for the checkboxes worked!, the choices made are still there after refreshing the page, taking away the save button was a good move, i ran the extension and it didn't erased any data thou. (took away the comment parameters) – Minnen Dec 01 '12 at 03:00
  • 1
    @Minnen Sorry, again. Forgot to add browsingData to the manifest, should all work now (there I go again, tempting the gods;). I actually tested it this time. By the way, uncomment that window.close in the popup if you dont want a window to popup when they click the browser action. – PAEz Dec 01 '12 at 08:19
1

You delete all localstorage data in popup.html. So every time you open it, your settings are gone. If you don't open it, settings are not really usefull.

Ha.
  • 3,454
  • 21
  • 24
  • I was afraid someone would think that, i don't run the extension in this process, all this post is about is the options panel, what i attempt to do now is simply find the way to store the options and access that data later. – Minnen Nov 29 '12 at 23:33
1

After going through your code, i prepared a structure which you can further expand for all check boxes;

I have tested it in following cases, let me know if you still have difficulties:

Beginning of page:

enter image description here

After Selection Made

enter image description here

After Page Load:

enter image description here

Refresh:

enter image description here

You can use chrome storage API instead of Local Storage

manifest.json

{
  "name": "TEST TITLE",
  "version": "1.0",
  "manifest_version": 2,
  "description": "TEST DESCRIPTION",
  "options_page": "options.html",
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "permissions": [
    "storage",
    "browsingData"
  ]
}

popup.html

<html>
  <head>
  <script src="scripts.js"></script>
  </head>
  <body>
  </body>
</html>

options.html

<html>
  <head>
  <script src="script-options.js"></script>
  </head>
  <body>
  <div id="wrapper-options">
  <div id="header-options">OPTIONS</div>
  <div id="content-options">
  <div id="checkbox-options">
  <input name="" id="protectedWeb" type="checkbox" value="">Websites that have been installed as hosted applications
  </div>
  <div id="button-option">
  <input name="" type="button" value="SAVE" id="save" >
  </div>
  </div>
  </div>
  </body>
</html>

scripts.js

// JavaScript Document

function browsingdata(){

var protectedWeb;
chrome.storage.local.get('protectedWeb',function (obj){
    console.log(obj.protectedWeb);
    protectedWeb = obj.protectedWeb;
});

chrome.browsingData.remove({
  "originTypes": {
        "protectedWeb": protectedWeb, // Set to false or false as per your requirement / Websites that have been installed as hosted applications
        "unprotectedWeb":true, // Set to true or false as per your requirement / Normal websites
        "extension":true // Set to true or false as per your requirement / Extensions and packaged applications a user has installed

    }}, {
  "appcache": false, // Set to false or false as per your requirement / Websites appcaches
  "cache": false, // Set to false or false as per your requirement / Browser's cache
  "cookies": false, // Set to false or false as per your requirement / Browser's cookies
  "downloads": false, // Set to false or false as per your requirement / Browser's download
  "fileSystems": false, // Set to false or false as per your requirement / Websites file systems
  "formData": false, // Set to false or false as per your requirement / Browser's stored form data
  "history": false, // Set to false or false as per your requirement / Browser's history
  "indexedDB": false, // Set to false or false as per your requirement / Websites IndexedDB data
  "localStorage": false, // Set to false or false as per your requirement / Websites local storage data
  "pluginData": false, // Set to false or false as per your requirement / Plugins data
  "passwords": false, // Set to false or false as per your requirement / Stored passwords
  "webSQL": false // Set to false or false as per your requirement / Websites WebSQL data
}, function (){
    console.log("All data Deleted");
});

}
window.onload=browsingdata;

script-options.js

// JavaScript Document var storage = chrome.storage.local;

function saveOptions() {
    console.log("Clicked ... ");
//Use document.querySelectorAll() function when you all multiple check boxes and iterate over them instead of huge if-else chains
    if (document.getElementById('protectedWeb').checked) {
        // Save it using the Chrome extension storage API.
        storage.set({'protectedWeb': 'true'}, function() {
            // Notify that we saved.
            console.log('Settings saved');
        });

    } else {
        // Save it using the Chrome extension storage API.
        storage.set({'protectedWeb': 'false'}, function() {
            // Notify that we saved.
            console.log('Settings saved');
        });
    }
}

function getSelectedData() {
    chrome.storage.local.get('protectedWeb',function (obj){
    if(obj.protectedWeb == "true"){
    document.getElementById('protectedWeb').checked = true;
}else{
    document.getElementById('protectedWeb').checked = false;
}
});
}

window.onload = function (){
    getSelectedData();
    document.getElementById('save').onclick=saveOptions;
}
Sudarshan
  • 18,140
  • 7
  • 53
  • 61
  • Hi @Sudarshan !, i tested your code and it didn't worked, the options still disappear if you refresh the options panel or simply save close and re open it. I still appreciate your concern. – Minnen Nov 29 '12 at 23:26
  • 1
    @Minnen: Sorry i forgot that point to include in code, i have added it; Check it now, let me know if it still fails.. – Sudarshan Nov 30 '12 at 08:18
  • 2
    @Sudarshan In your saveOptions function you should use `document.querySelectorAll('input[type="checkbox"]')` to get a list of all checkboxs. Then iterate over that list and check each elements checked value and use the elements id to know what to set in storage. Otherwise your going to end up with one huge function that will be a pain to change/maintain. Just a suggestion. – PAEz Nov 30 '12 at 11:01
  • 1
    @PAEz: Yes, you are correct, i started off with one check box and ended doing it , yes maintenance wise querySelectorAll() is best approach.. – Sudarshan Nov 30 '12 at 11:09
  • @Sudarshan hi!, i copied the entire code and tested it, it still doesn't work, i checked each line twice in case i was missing something or maybe copied something wrong or "dirty" but its the exact same code, don't know what to say really – Minnen Dec 01 '12 at 02:38
  • @Minnen: Hmm... what exactly is not working :), do you see some errors or? because i have added the code after testing. if you provide me some hints, i can help. – Sudarshan Dec 01 '12 at 10:32