diff --git a/app/assets/javascripts/discourse/app/lib/key-value-store.js b/app/assets/javascripts/discourse/app/lib/key-value-store.js index 55a843ebfca..c24ceadc926 100644 --- a/app/assets/javascripts/discourse/app/lib/key-value-store.js +++ b/app/assets/javascripts/discourse/app/lib/key-value-store.js @@ -26,14 +26,27 @@ export default class KeyValueStore { } abandonLocal() { + return this.removeKeys(); + } + + removeKeys(predicate = () => true) { if (!safeLocalStorage) { return; } let i = safeLocalStorage.length - 1; + while (i >= 0) { let k = safeLocalStorage.key(i); - if (k.substring(0, this.context.length) === this.context) { + let v = safeLocalStorage[k]; + try { + v = JSON.parse(v); + } catch (e) {} + + if ( + k.substring(0, this.context.length) === this.context && + predicate(k, v) + ) { safeLocalStorage.removeItem(k); } i--; diff --git a/app/assets/javascripts/discourse/tests/unit/lib/key-value-store-test.js b/app/assets/javascripts/discourse/tests/unit/lib/key-value-store-test.js index 7308120df82..d8417c66f28 100644 --- a/app/assets/javascripts/discourse/tests/unit/lib/key-value-store-test.js +++ b/app/assets/javascripts/discourse/tests/unit/lib/key-value-store-test.js @@ -17,6 +17,21 @@ module("Unit | Utility | key-value-store", function () { assert.strictEqual(store.get("bob"), undefined); }); + test("is able to remove multiple items at once from the store", function (assert) { + const store = new KeyValueStore("example"); + store.set({ key: "bob", value: "uncle" }); + store.set({ key: "jane", value: "sister" }); + store.set({ key: "clark", value: "brother" }); + + store.removeKeys((key, value) => { + return key.includes("bob") || value === "brother"; + }); + + assert.strictEqual(store.get("bob"), undefined); + assert.strictEqual(store.get("jane"), "sister"); + assert.strictEqual(store.get("clark"), undefined); + }); + test("is able to nuke the store", function (assert) { const store = new KeyValueStore("example"); store.set({ key: "bob1", value: "uncle" });