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 () {
var bannerKey = this.get("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 (dismissedBannerKey) { dismissedBannerKey = parseInt(dismissedBannerKey, 10); }
@ -19,10 +19,9 @@ export default VisibleComponent.extend({
this.get("user").dismissBanner(this.get("banner.key"));
} else {
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",
initialize: function (container) {
const messageBus = container.lookup('message-bus:main'),
siteSettings = container.lookup('site-settings:main');
const messageBus = container.lookup('message-bus:main');
const siteSettings = container.lookup('site-settings:main');
const keyValueStore = container.lookup('key-value-store:main');
if (!messageBus) { return; }
const callback = () => logout(siteSettings);
const callback = () => logout(siteSettings, keyValueStore);
messageBus.subscribe("/logout", function () {
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.start();
Discourse.KeyValueStore.init("discourse_", messageBus);
messageBus.callbackInterval = siteSettings.anon_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) {
Discourse.KeyValueStore.abandonLocal();
export default function logout(siteSettings, keyValueStore) {
keyValueStore.abandonLocal();
const redirect = siteSettings.logout_redirect;
if (Ember.isEmpty(redirect)) {

View File

@ -281,7 +281,7 @@ const Composer = RestModel.extend({
}.property('reply'),
_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('archetypeId', this.site.get('default_archetype'));
}.on('init'),
@ -336,7 +336,7 @@ const Composer = RestModel.extend({
togglePreview() {
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() {
@ -731,6 +731,7 @@ Composer.reopenClass({
}
},
// TODO: Replace with injection
create(args) {
args = args || {};
args.user = args.user || Discourse.User.current();

View File

@ -78,10 +78,13 @@ RestModel.reopenClass({
create(args) {
args = args || {};
if (!args.store) {
if (!args.store || !args.keyValueStore) {
const container = Discourse.__container__;
// Ember.warn('Use `store.createRecord` to create records instead of `.create()`');
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;

View File

@ -1,4 +1,5 @@
import Session from 'discourse/models/session';
import KeyValueStore from 'discourse/lib/key-value-store';
import AppEvents from 'discourse/lib/app-events';
import Store from 'discourse/models/store';
import DiscourseURL from 'discourse/lib/url';
@ -8,7 +9,7 @@ import SearchService from 'discourse/services/search';
function inject() {
const app = arguments[0],
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));
}
@ -49,5 +50,9 @@ export default {
injectAll(app, 'messageBus');
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: {
logout() {
this.currentUser.destroySession().then(() => logout(this.siteSettings));
this.currentUser.destroySession().then(() => logout(this.siteSettings, this.keyValueStore));
},
_collectTitleTokens(tokens) {

View File

@ -18,6 +18,7 @@
//= require ./discourse/lib/url
//= require ./discourse/lib/debounce
//= require ./discourse/lib/quote
//= require ./discourse/lib/key-value-store
//= require ./discourse/helpers/i18n
//= require ./discourse/helpers/fa-icon
//= 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", {
setup: function() {
store.init("test");
}
});
module("lib:key-value-store");
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" });
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.abandonLocal();
localStorage.a = 1;
equal(store.get("bob1"), void 0);
equal(localStorage.a, "1");
assert.equal(store.get("bob1"), void 0);
assert.equal(localStorage.a, "1");
});

View File

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