diff options
Diffstat (limited to 'src/shared/settings')
| -rw-r--r-- | src/shared/settings/default.js | 2 | ||||
| -rw-r--r-- | src/shared/settings/properties.js | 15 | ||||
| -rw-r--r-- | src/shared/settings/storage.js | 31 | ||||
| -rw-r--r-- | src/shared/settings/validator.js | 76 | ||||
| -rw-r--r-- | src/shared/settings/values.js | 20 | 
5 files changed, 139 insertions, 5 deletions
| diff --git a/src/shared/settings/default.js b/src/shared/settings/default.js index d187565..6425354 100644 --- a/src/shared/settings/default.js +++ b/src/shared/settings/default.js @@ -58,6 +58,8 @@ export default {        "duckduckgo": "https://duckduckgo.com/?q={}",        "twitter": "https://twitter.com/search?q={}",        "wikipedia": "https://en.wikipedia.org/w/index.php?search={}" +    }, +    "properties": {      }    }  }`, diff --git a/src/shared/settings/properties.js b/src/shared/settings/properties.js new file mode 100644 index 0000000..ff8039b --- /dev/null +++ b/src/shared/settings/properties.js @@ -0,0 +1,15 @@ +const types = { +  // TODO describe property types here +  // mystr: 'string', +  // mynum: 'number', +  // mybool: 'boolean', +}; + +const defaults = { +  // TODO describe property defaults values +  // mystr: 'hello', +  // mynum: 123, +  // mybool: true, +}; + +export { types, defaults }; diff --git a/src/shared/settings/storage.js b/src/shared/settings/storage.js new file mode 100644 index 0000000..1edb441 --- /dev/null +++ b/src/shared/settings/storage.js @@ -0,0 +1,31 @@ +import DefaultSettings from './default'; +import * as settingsValues from './values'; + +const loadRaw = () => { +  return browser.storage.local.get('settings').then(({ settings }) => { +    if (!settings) { +      return DefaultSettings; +    } +    return Object.assign({}, DefaultSettings, settings); +  }); +}; + +const loadValue = () => { +  return loadRaw().then((settings) => { +    let value = JSON.parse(DefaultSettings.json); +    if (settings.source === 'json') { +      value = settingsValues.valueFromJson(settings.json); +    } else if (settings.source === 'form') { +      value = settingsValues.valueFromForm(settings.form); +    } +    return value; +  }); +}; + +const save = (settings) => { +  return browser.storage.local.set({ +    settings, +  }); +}; + +export { loadRaw, loadValue, save }; diff --git a/src/shared/settings/validator.js b/src/shared/settings/validator.js new file mode 100644 index 0000000..1589420 --- /dev/null +++ b/src/shared/settings/validator.js @@ -0,0 +1,76 @@ +import operations from 'shared/operations'; +import * as properties from './properties'; + +const VALID_TOP_KEYS = ['keymaps', 'search', 'blacklist', 'properties']; +const VALID_OPERATION_VALUES = Object.keys(operations).map((key) => { +  return operations[key]; +}); + +const validateInvalidTopKeys = (settings) => { +  let invalidKey = Object.keys(settings).find((key) => { +    return !VALID_TOP_KEYS.includes(key); +  }); +  if (invalidKey) { +    throw Error(`Unknown key: "${invalidKey}"`); +  } +}; + +const validateKeymaps = (keymaps) => { +  for (let key of Object.keys(keymaps)) { +    let value = keymaps[key]; +    if (!VALID_OPERATION_VALUES.includes(value.type)) { +      throw Error(`Unknown operation: "${value.type}"`); +    } +  } +}; + +const validateSearch = (search) => { +  let engines = search.engines; +  for (let key of Object.keys(engines)) { +    if (/\s/.test(key)) { +      throw new Error( +        `While space in search engine name is not allowed: "${key}"` +      ); +    } +    let url = engines[key]; +    if (!url.match(/{}/)) { +      throw new Error(`No {}-placeholders in URL of "${key}"`); +    } +    if (url.match(/{}/g).length > 1) { +      throw new Error(`Multiple {}-placeholders in URL of "${key}"`); +    } +  } + +  if (!search.default) { +    throw new Error(`Default engine is not set`); +  } +  if (!Object.keys(engines).includes(search.default)) { +    throw new Error(`Default engine "${search.default}" not found`); +  } +}; + +const validateProperties = (props) => { +  for (let name of Object.keys(props)) { +    if (!properties.types[name]) { +      throw new Error(`Unknown property name: "${name}"`); +    } +    if (typeof props[name] !== properties.types[name]) { +      throw new Error(`Invalid type for property: "${name}"`); +    } +  } +}; + +const validate = (settings) => { +  validateInvalidTopKeys(settings); +  if (settings.keymaps) { +    validateKeymaps(settings.keymaps); +  } +  if (settings.search) { +    validateSearch(settings.search); +  } +  if (settings.properties) { +    validateProperties(settings.properties); +  } +}; + +export { validate }; diff --git a/src/shared/settings/values.js b/src/shared/settings/values.js index 4e55fa0..bd03be2 100644 --- a/src/shared/settings/values.js +++ b/src/shared/settings/values.js @@ -1,3 +1,5 @@ +import * as properties from './properties'; +  const operationFromFormName = (name) => {    let [type, argStr] = name.split('?');    let args = {}; @@ -44,9 +46,12 @@ const valueFromForm = (form) => {      }    } -  let blacklist = form.blacklist; - -  return { keymaps, search, blacklist }; +  return { +    keymaps, +    search, +    blacklist: form.blacklist, +    properties: form.properties +  };  };  const jsonFromValue = (value) => { @@ -78,9 +83,14 @@ const formFromValue = (value, allowedOps) => {      }    } -  let blacklist = value.blacklist; +  let formProperties = Object.assign({}, properties.defaults, value.properties); -  return { keymaps, search, blacklist }; +  return { +    keymaps, +    search, +    blacklist: value.blacklist, +    properties: formProperties, +  };  };  const jsonFromForm = (form) => { | 
