Remove onchanged listener from config

This commit is contained in:
Oliver Blanthorn 2020-02-18 18:24:07 +00:00
parent bca999e852
commit 998c106036
No known key found for this signature in database
GPG key ID: 2BB8C36BB504BFF3
2 changed files with 33 additions and 62 deletions

View file

@ -15,6 +15,7 @@
* *
*/ */
import * as locks from "@src/lib/locks" import * as locks from "@src/lib/locks"
import * as messaging from "@src/lib/messaging"
import * as R from "ramda" import * as R from "ramda"
/* Remove all nulls from objects recursively /* Remove all nulls from objects recursively
@ -1276,6 +1277,30 @@ export async function save(storage: "local" | "sync" = get("storageloc")) {
const ans = storage === "local" const ans = storage === "local"
? browser.storage.local.set(settingsobj) ? browser.storage.local.set(settingsobj)
: browser.storage.sync.set(settingsobj) : browser.storage.sync.set(settingsobj)
// Ignore errors about background pages that aren't listening
const friendly_bg_messenger = async () => {
let p
try {
p = await browser.runtime.sendMessage({type: "config", command: "confUpdate", args: [settingsobj]})
} catch (e) {
if (e.message != "Could not establish connection. Receiving end does not exist.") {
throw e
}
p = true
}
return p
}
await Promise.all([
// dispatch message to all content state.ts's
messaging.messageAllTabs("config", "confUpdate", [settingsobj]),
// Ideally this V would use Farnoy's typed messages but
// I haven't had time to get my head around them
friendly_bg_messenger()
])
locks.release("config") locks.release("config")
return ans return ans
} }
@ -1674,68 +1699,13 @@ const parseConfigHelper = (pconf, parseobj) => {
return parseobj return parseobj
} }
// Listen for changes to the storage and update the USERCONFIG if appropriate. const updateHandler = (message, sender, sendResponse) => {
// TODO: BUG! Sync and local storage are merged at startup, but not by this thing. if (message.type !== "config") return false
browser.storage.onChanged.addListener((changes, areaname) => { if (message.command !== "confUpdate") throw("Unsupported message to config, type " + message.command)
if (CONFIGNAME in changes) { Object.assign(USERCONFIG, message.args[0][CONFIGNAME])
const { newValue, oldValue } = changes[CONFIGNAME] sendResponse(true)
const old = oldValue || {} }
function triggerChangeListeners(key, value = newValue[key]) { browser.runtime.onMessage.addListener(updateHandler) // Messaging.addListener doesn't allow us to send async responses - is this on purpose?
const arr = changeListeners.get(key)
if (arr) {
const v = old[key] === undefined ? DEFAULTS[key] : old[key]
arr.forEach(f => f(v, value))
}
}
if (areaname === "sync" && areaname !== get("storageloc")) {
// storageloc=local means ignoring changes that aren't set by us
} else if (newValue !== undefined) {
if (areaname === "sync") {
// prevent storageloc from being set remotely
delete old.storageloc
delete newValue.storageloc
}
// A key has been :unset if it exists in USERCONFIG and doesn't in changes and if its value in USERCONFIG is different from the one it has in default_config
const unsetKeys = Object.keys(old).filter(
k =>
newValue[k] === undefined &&
JSON.stringify(old[k]) !==
JSON.stringify(DEFAULTS[k]),
)
// A key has changed if it is defined in USERCONFIG and its value in USERCONFIG is different from the one in `changes` or if the value in defaultConf is different from the one in `changes`
const changedKeys = Object.keys(
newValue,
).filter(
k =>
JSON.stringify(
old[k] !== undefined
? old[k]
: DEFAULTS[k],
) !== JSON.stringify(newValue[k]),
)
// TODO: this should be a deep comparison but this is better than nothing
changedKeys.forEach(key => USERCONFIG[key] = newValue[key])
unsetKeys.forEach(key => delete USERCONFIG[key])
// Trigger listeners
unsetKeys.forEach(key => triggerChangeListeners(key, DEFAULTS[key]))
changedKeys.forEach(key => triggerChangeListeners(key))
} else {
// newValue is undefined when calling browser.storage.AREANAME.clear()
// If newValue is undefined and AREANAME is the same value as STORAGELOC, the user wants to clean their config
USERCONFIG = o({})
Object.keys(old)
.filter(key => old[key] !== DEFAULTS[key])
.forEach(key => triggerChangeListeners(key))
}
}
})
init() init()

View file

@ -12,6 +12,7 @@ export type TabMessageType =
| "commandline_cmd" | "commandline_cmd"
| "commandline_frame" | "commandline_frame"
| "state" | "state"
| "config"
| "lock" | "lock"
export type NonTabMessageType = export type NonTabMessageType =