Ad

Best Way To Add A Menu To Greasemonkey Script

- 1 answer

I'm creating a Grease Monkey script and currently I'm storing my settings variables within the code. But I'd like to make them easily changeable for users. The best way to do it imo is creating a settings menu but I have no idea how to do it and where to start (it's my first browser extention). Can you please explain me what to do (or at least where to look for the info)? I'd like to understand: 1) How to store variables and access them? 2) How to put the settings menu in the script? 3) Where can I put this settings menu?

Pseudocode:

//settings
let foo = false; // how do
let bar = true;  // I change these guys using the menu?
Ad

Answer

Create a container with inputs, and listen for changes to the inputs. On change, save the variables in localStorage. Also, on page load, check to see if the localStorage property has anything in it - if so, populate the inputs with the saved values:

// Retrieve the saved values, or if there aren't any, set the default values
// let vals = localStorage.vals ? JSON.parse(localStorage.vals) : ['3', 'foo', '8'];
let vals = ['3', 'foo', '8'];
const inputs = [...menu.querySelectorAll('input')];

// Populate the inputs with the values:
inputs.forEach((input, i) => input.value = vals[i]);

// Listen for changes to the inputs. On change, put all values into the "vals" variable
// and save it in localStorage:
const menu = document.querySelector('#menu');
menu.addEventListener('input', () => {
  vals = inputs.map(input => input.value);
  console.log(vals);
  // Save it:
  // localStorage.vals = JSON.stringify(vals);
});
<div id="menu">
  <div>var1: <input value="3"></div>
  <div>var2: <input value="foo"></div>
  <div>var3: <input value="8"></div>
</div>

(localStorage does not work in the sandboxed Stack Snippet iframe, unfortunately, which is why its use is commented out)

To save an object instead of an array, you might give the inputs names:

// Retrieve the saved values, or if there aren't any, set the default values
// let vals = localStorage.vals ? JSON.parse(localStorage.vals) : { var1: 'foo', var2: 'bar' };
let vals = { var1: 'foo', var2: 'bar' };
const menu = document.querySelector('#menu');
const inputs = [...menu.querySelectorAll('input')];

// Populate the inputs with the values:
Object.entries(vals)
  .forEach(([propName, val]) => {
    menu.querySelector(`input[name="${propName}"]`).value = val;
  });
  
// Listen for changes to the inputs. On change, put all values into the "vals" variable
// and save it in localStorage:
menu.addEventListener('input', () => {
  vals = inputs.reduce((a, input) => {
    a[input.name] = input.value;
    return a;
  }, {});
  console.log(vals);
  // Save it:
  // localStorage.vals = JSON.stringify(vals);
});
<div id="menu">
  <div>var1: <input name="var1"></div>
  <div>var2: <input name="var2"></div>
</div>

Ad
source: stackoverflow.com
Ad