Migrate KeyValueStore to ES6 modules

This commit is contained in:
Robin Ward 2015-09-01 13:29:47 -04:00
parent 11b73e1fb7
commit bf2c18fddb
13 changed files with 89 additions and 92 deletions

View File

@ -5,7 +5,7 @@ export default VisibleComponent.extend({
visible: function () { visible: function () {
var bannerKey = this.get("banner.key"), var bannerKey = this.get("banner.key"),
dismissedBannerKey = this.get("user.dismissed_banner_key") || dismissedBannerKey = this.get("user.dismissed_banner_key") ||
Discourse.KeyValueStore.get("dismissed_banner_key"); this.keyValueStore.get("dismissed_banner_key");
if (bannerKey) { bannerKey = parseInt(bannerKey, 10); } if (bannerKey) { bannerKey = parseInt(bannerKey, 10); }
if (dismissedBannerKey) { dismissedBannerKey = parseInt(dismissedBannerKey, 10); } if (dismissedBannerKey) { dismissedBannerKey = parseInt(dismissedBannerKey, 10); }
@ -19,10 +19,9 @@ export default VisibleComponent.extend({
this.get("user").dismissBanner(this.get("banner.key")); this.get("user").dismissBanner(this.get("banner.key"));
} else { } else {
this.set("visible", false); this.set("visible", false);
Discourse.KeyValueStore.set({ key: "dismissed_banner_key", value: this.get("banner.key") }); this.keyValueStore.set({ key: "dismissed_banner_key", value: this.get("banner.key") });
}
} }
} }
},
}); });

View File

@ -6,11 +6,12 @@ export default {
after: "message-bus", after: "message-bus",
initialize: function (container) { initialize: function (container) {
const messageBus = container.lookup('message-bus:main'), const messageBus = container.lookup('message-bus:main');
siteSettings = container.lookup('site-settings:main'); const siteSettings = container.lookup('site-settings:main');
const keyValueStore = container.lookup('key-value-store:main');
if (!messageBus) { return; } if (!messageBus) { return; }
const callback = () => logout(siteSettings); const callback = () => logout(siteSettings, keyValueStore);
messageBus.subscribe("/logout", function () { messageBus.subscribe("/logout", function () {
bootbox.dialog(I18n.t("logout"), {label: I18n.t("refresh"), callback}, {onEscape: callback, backdrop: 'static'}); bootbox.dialog(I18n.t("logout"), {label: I18n.t("refresh"), callback}, {onEscape: callback, backdrop: 'static'});

View File

@ -21,7 +21,6 @@ export default {
messageBus.alwaysLongPoll = Discourse.Environment === "development"; messageBus.alwaysLongPoll = Discourse.Environment === "development";
messageBus.start(); messageBus.start();
Discourse.KeyValueStore.init("discourse_", messageBus);
messageBus.callbackInterval = siteSettings.anon_polling_interval; messageBus.callbackInterval = siteSettings.anon_polling_interval;
messageBus.backgroundCallbackInterval = siteSettings.background_polling_interval; messageBus.backgroundCallbackInterval = siteSettings.background_polling_interval;

View File

@ -0,0 +1,49 @@
// A simple key value store that uses LocalStorage
let safeLocalStorage;
try {
safeLocalStorage = localStorage;
if (localStorage["disableLocalStorage"] === "true") {
safeLocalStorage = null;
}
} catch(e){
// cookies disabled, we don't care
safeLocalStorage = null;
}
const KeyValueStore = function(ctx) {
this.context = ctx;
}
KeyValueStore.prototype = {
abandonLocal() {
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) {
safeLocalStorage.removeItem(k);
}
i--;
}
return true;
},
remove(key) {
return safeLocalStorage.removeItem(this.context + key);
},
set(opts) {
if (!safeLocalStorage) { return false; }
safeLocalStorage[this.context + opts.key] = opts.value;
},
get(key) {
if (!safeLocalStorage) { return null; }
return safeLocalStorage[this.context + key];
}
};
export default KeyValueStore;

View File

@ -1,63 +0,0 @@
/**
A simple key value store that uses LocalStorage
@class KeyValueStore
@namespace Discourse
@module Discourse
**/
var safeLocalStorage;
try {
safeLocalStorage = localStorage;
if (localStorage["disableLocalStorage"] === "true") {
safeLocalStorage = null;
}
} catch(e){
// cookies disabled, we don't care
safeLocalStorage = null;
}
Discourse.KeyValueStore = {
initialized: false,
context: "",
init: function(ctx) {
this.initialized = true;
this.context = ctx;
},
abandonLocal: function() {
var i, k;
if (!(safeLocalStorage && this.initialized)) {
return;
}
i = safeLocalStorage.length - 1;
while (i >= 0) {
k = safeLocalStorage.key(i);
if (k.substring(0, this.context.length) === this.context) {
safeLocalStorage.removeItem(k);
}
i--;
}
return true;
},
remove: function(key) {
return safeLocalStorage.removeItem(this.context + key);
},
set: function(opts) {
if (!safeLocalStorage && this.initialized) {
return false;
}
safeLocalStorage[this.context + opts.key] = opts.value;
},
get: function(key) {
if (!safeLocalStorage) {
return null;
}
return safeLocalStorage[this.context + key];
}
};

View File

@ -1,5 +1,5 @@
export default function logout(siteSettings) { export default function logout(siteSettings, keyValueStore) {
Discourse.KeyValueStore.abandonLocal(); keyValueStore.abandonLocal();
const redirect = siteSettings.logout_redirect; const redirect = siteSettings.logout_redirect;
if (Ember.isEmpty(redirect)) { if (Ember.isEmpty(redirect)) {

View File

@ -281,7 +281,7 @@ const Composer = RestModel.extend({
}.property('reply'), }.property('reply'),
_setupComposer: function() { _setupComposer: function() {
const val = (Discourse.Mobile.mobileView ? false : (Discourse.KeyValueStore.get('composer.showPreview') || 'true')); const val = (Discourse.Mobile.mobileView ? false : (this.keyValueStore.get('composer.showPreview') || 'true'));
this.set('showPreview', val === 'true'); this.set('showPreview', val === 'true');
this.set('archetypeId', this.site.get('default_archetype')); this.set('archetypeId', this.site.get('default_archetype'));
}.on('init'), }.on('init'),
@ -336,7 +336,7 @@ const Composer = RestModel.extend({
togglePreview() { togglePreview() {
this.toggleProperty('showPreview'); this.toggleProperty('showPreview');
Discourse.KeyValueStore.set({ key: 'composer.showPreview', value: this.get('showPreview') }); this.keyValueStore.set({ key: 'composer.showPreview', value: this.get('showPreview') });
}, },
applyTopicTemplate: function() { applyTopicTemplate: function() {
@ -731,6 +731,7 @@ Composer.reopenClass({
} }
}, },
// TODO: Replace with injection
create(args) { create(args) {
args = args || {}; args = args || {};
args.user = args.user || Discourse.User.current(); args.user = args.user || Discourse.User.current();

View File

@ -78,10 +78,13 @@ RestModel.reopenClass({
create(args) { create(args) {
args = args || {}; args = args || {};
if (!args.store) { if (!args.store || !args.keyValueStore) {
const container = Discourse.__container__; const container = Discourse.__container__;
// Ember.warn('Use `store.createRecord` to create records instead of `.create()`'); // Ember.warn('Use `store.createRecord` to create records instead of `.create()`');
args.store = container.lookup('store:main'); args.store = container.lookup('store:main');
// TODO: Remove this when composer is using the store fully
args.keyValueStore = container.lookup('key-value-store:main');
} }
args.__munge = this.munge; args.__munge = this.munge;

View File

@ -1,4 +1,5 @@
import Session from 'discourse/models/session'; import Session from 'discourse/models/session';
import KeyValueStore from 'discourse/lib/key-value-store';
import AppEvents from 'discourse/lib/app-events'; import AppEvents from 'discourse/lib/app-events';
import Store from 'discourse/models/store'; import Store from 'discourse/models/store';
import DiscourseURL from 'discourse/lib/url'; import DiscourseURL from 'discourse/lib/url';
@ -8,7 +9,7 @@ import SearchService from 'discourse/services/search';
function inject() { function inject() {
const app = arguments[0], const app = arguments[0],
name = arguments[1], name = arguments[1],
singletonName = Ember.String.underscore(name).replace(/_/, '-') + ':main'; singletonName = Ember.String.underscore(name).replace(/_/g, '-') + ':main';
Array.prototype.slice.call(arguments, 2).forEach(dest => app.inject(dest, name, singletonName)); Array.prototype.slice.call(arguments, 2).forEach(dest => app.inject(dest, name, singletonName));
} }
@ -49,5 +50,9 @@ export default {
injectAll(app, 'messageBus'); injectAll(app, 'messageBus');
app.register('location:discourse-location', DiscourseLocation); app.register('location:discourse-location', DiscourseLocation);
const keyValueStore = new KeyValueStore("discourse_");
app.register('key-value-store:main', keyValueStore, { instantiate: false });
injectAll(app, 'keyValueStore');
} }
}; };

View File

@ -19,7 +19,7 @@ const ApplicationRoute = Discourse.Route.extend(OpenComposer, {
actions: { actions: {
logout() { logout() {
this.currentUser.destroySession().then(() => logout(this.siteSettings)); this.currentUser.destroySession().then(() => logout(this.siteSettings, this.keyValueStore));
}, },
_collectTitleTokens(tokens) { _collectTitleTokens(tokens) {

View File

@ -18,6 +18,7 @@
//= require ./discourse/lib/url //= require ./discourse/lib/url
//= require ./discourse/lib/debounce //= require ./discourse/lib/debounce
//= require ./discourse/lib/quote //= require ./discourse/lib/quote
//= require ./discourse/lib/key-value-store
//= require ./discourse/helpers/i18n //= require ./discourse/helpers/i18n
//= require ./discourse/helpers/fa-icon //= require ./discourse/helpers/fa-icon
//= require ./discourse/helpers/register-unbound //= require ./discourse/helpers/register-unbound

View File

@ -1,20 +1,18 @@
var store = Discourse.KeyValueStore; import KeyValueStore from "discourse/lib/key-value-store";
module("Discourse.KeyValueStore", { module("lib:key-value-store");
setup: function() {
store.init("test");
}
});
test("it's able to get the result back from the store", function() { test("it's able to get the result back from the store", (assert) => {
const store = new KeyValueStore("_test");
store.set({ key: "bob", value: "uncle" }); store.set({ key: "bob", value: "uncle" });
equal(store.get("bob"), "uncle"); assert.equal(store.get("bob"), "uncle");
}); });
test("is able to nuke the store", function() { test("is able to nuke the store", (assert) => {
const store = new KeyValueStore("_test");
store.set({ key: "bob1", value: "uncle" }); store.set({ key: "bob1", value: "uncle" });
store.abandonLocal(); store.abandonLocal();
localStorage.a = 1; localStorage.a = 1;
equal(store.get("bob1"), void 0); assert.equal(store.get("bob1"), void 0);
equal(localStorage.a, "1"); assert.equal(localStorage.a, "1");
}); });

View File

@ -1,14 +1,18 @@
import { blank } from 'helpers/qunit-helpers'; import { blank } from 'helpers/qunit-helpers';
import { currentUser } from 'helpers/qunit-helpers'; import { currentUser } from 'helpers/qunit-helpers';
import KeyValueStore from 'discourse/lib/key-value-store';
module("model:composer"); module("model:composer");
const keyValueStore = new KeyValueStore("_test_composer");
function createComposer(opts) { function createComposer(opts) {
opts = opts || {}; opts = opts || {};
opts.user = opts.user || currentUser(); opts.user = opts.user || currentUser();
opts.site = Discourse.Site.current(); opts.site = Discourse.Site.current();
opts.siteSettings = Discourse.SiteSettings; opts.siteSettings = Discourse.SiteSettings;
return Discourse.Composer.create(opts); opts.keyValueStore = keyValueStore;
; return Discourse.Composer.create(opts);
} }
test('replyLength', function() { test('replyLength', function() {
@ -184,9 +188,9 @@ test('showPreview', function() {
Discourse.Mobile.mobileView = true; Discourse.Mobile.mobileView = true;
equal(newComposer().get('showPreview'), false, "Don't show preview in mobile view"); equal(newComposer().get('showPreview'), false, "Don't show preview in mobile view");
Discourse.KeyValueStore.set({ key: 'composer.showPreview', value: 'true' }); keyValueStore.set({ key: 'composer.showPreview', value: 'true' });
equal(newComposer().get('showPreview'), false, "Don't show preview in mobile view even if KeyValueStore wants to"); equal(newComposer().get('showPreview'), false, "Don't show preview in mobile view even if KeyValueStore wants to");
Discourse.KeyValueStore.remove('composer.showPreview'); keyValueStore.remove('composer.showPreview');
Discourse.Mobile.mobileView = false; Discourse.Mobile.mobileView = false;
equal(newComposer().get('showPreview'), true, "Show preview by default in desktop view"); equal(newComposer().get('showPreview'), true, "Show preview by default in desktop view");