diff --git a/src/background/actions/setting.js b/src/background/actions/setting.js deleted file mode 100644 index 7eeb5de..0000000 --- a/src/background/actions/setting.js +++ /dev/null @@ -1,20 +0,0 @@ -import actions from '../actions'; -import * as settingsStorage from 'shared/settings/storage'; - -const load = async() => { - let value = await settingsStorage.loadValue(); - return { - type: actions.SETTING_SET_SETTINGS, - value, - }; -}; - -const setProperty = (name, value) => { - return { - type: actions.SETTING_SET_PROPERTY, - name, - value, - }; -}; - -export { load, setProperty }; diff --git a/src/background/components/background.js b/src/background/components/background.js index d933d7b..9ba733d 100644 --- a/src/background/components/background.js +++ b/src/background/components/background.js @@ -1,6 +1,5 @@ import messages from 'shared/messages'; import * as commandActions from 'background/actions/command'; -import * as settingActions from 'background/actions/setting'; import * as findActions from 'background/actions/find'; import * as tabActions from 'background/actions/tab'; @@ -38,11 +37,6 @@ export default class BackgroundComponent { commandActions.exec(sender.tab, message.text, settings.value), ); return this.broadcastSettingsChanged(); - case messages.SETTINGS_QUERY: - return Promise.resolve(this.store.getState().setting.value); - case messages.SETTINGS_RELOAD: - this.store.dispatch(settingActions.load()); - return this.broadcastSettingsChanged(); case messages.FIND_GET_KEYWORD: return Promise.resolve(find.keyword); case messages.FIND_SET_KEYWORD: diff --git a/src/background/controllers/setting.js b/src/background/controllers/setting.js new file mode 100644 index 0000000..9e6019e --- /dev/null +++ b/src/background/controllers/setting.js @@ -0,0 +1,18 @@ +import SettingInteractor from '../usecases/setting'; +import ContentMessageClient from '../infrastructures/content-message-client'; + +export default class SettingController { + constructor() { + this.settingInteractor = new SettingInteractor(); + this.contentMessageClient = new ContentMessageClient(); + } + + getSetting() { + return this.settingInteractor.get(); + } + + async reload() { + await this.settingInteractor.reload(); + this.contentMessageClient.broadcastSettingsChanged(); + } +} diff --git a/src/background/domains/setting.js b/src/background/domains/setting.js new file mode 100644 index 0000000..106ec0f --- /dev/null +++ b/src/background/domains/setting.js @@ -0,0 +1,51 @@ +import DefaultSettings from '../../shared/settings/default'; +import * as settingsValues from '../../shared/settings/values'; + +export default class Setting { + constructor({ source, json, form }) { + this.obj = { + source, json, form + }; + } + + get source() { + return this.obj.source; + } + + get json() { + return this.obj.json; + } + + get form() { + return this.obj.form; + } + + value() { + let value = JSON.parse(DefaultSettings.json); + if (this.obj.source === 'json') { + value = settingsValues.valueFromJson(this.obj.json); + } else if (this.obj.source === 'form') { + value = settingsValues.valueFromForm(this.obj.form); + } + if (!value.properties) { + value.properties = {}; + } + return { ...settingsValues.valueFromJson(DefaultSettings.json), ...value }; + } + + serialize() { + return this.obj; + } + + static deserialize(obj) { + return new Setting({ source: obj.source, json: obj.json, form: obj.form }); + } + + static defaultSettings() { + return new Setting({ + source: DefaultSettings.source, + json: DefaultSettings.json, + form: {}, + }); + } +} diff --git a/src/background/index.js b/src/background/index.js index 619b076..69dbe06 100644 --- a/src/background/index.js +++ b/src/background/index.js @@ -1,4 +1,3 @@ -import * as settingActions from 'background/actions/setting'; import BackgroundComponent from 'background/components/background'; import OperationComponent from 'background/components/operation'; import TabComponent from 'background/components/tab'; @@ -9,6 +8,7 @@ import promise from 'redux-promise'; import * as versions from './shared/versions'; import ContentMessageListener from './infrastructures/content-message-listener'; +import SettingController from './controllers/setting'; const store = createStore( reducers, @@ -31,8 +31,8 @@ const tabComponent = new TabComponent(store); const indicatorComponent = new IndicatorComponent(store); /* eslint-enable no-unused-vars */ -store.dispatch(settingActions.load()); - checkAndNotifyUpdated(); +new SettingController().reload(); + new ContentMessageListener().run(); diff --git a/src/background/infrastructures/content-message-client.js b/src/background/infrastructures/content-message-client.js new file mode 100644 index 0000000..b3b37b4 --- /dev/null +++ b/src/background/infrastructures/content-message-client.js @@ -0,0 +1,12 @@ +import messages from '../../shared/messages'; + +export default class ContentMessageClient { + async broadcastSettingsChanged() { + let tabs = await browser.tabs.query({}); + for (let tab of tabs) { + browser.tabs.sendMessage(tab.id, { + type: messages.SETTINGS_CHANGED, + }); + } + } +} diff --git a/src/background/infrastructures/content-message-listener.js b/src/background/infrastructures/content-message-listener.js index a0ed66c..6236f1c 100644 --- a/src/background/infrastructures/content-message-listener.js +++ b/src/background/infrastructures/content-message-listener.js @@ -1,8 +1,10 @@ import messages from '../../shared/messages'; import CompletionsController from '../controllers/completions'; +import SettingController from '../controllers/setting'; export default class ContentMessageListener { constructor() { + this.settingController = new SettingController(); this.completionsController = new CompletionsController(); } @@ -22,13 +24,24 @@ export default class ContentMessageListener { onMessage(message) { switch (message.type) { case messages.CONSOLE_QUERY_COMPLETIONS: - return this.onConsoleQueryCompletions(message); + return this.onConsoleQueryCompletions(message.text); + case messages.SETTINGS_QUERY: + return this.onSettingsQuery(); + case messages.SETTINGS_RELOAD: + return this.onSettingsReload(); } } - async onConsoleQueryCompletions(message) { - let completions = - await this.completionsController.getCompletions(message.text); + async onConsoleQueryCompletions(line) { + let completions = await this.completionsController.getCompletions(line); return Promise.resolve(completions.serialize()); } + + onSettingsQuery() { + return this.settingController.getSetting(); + } + + onSettingsReload() { + return this.settingController.reload(); + } } diff --git a/src/background/infrastructures/memory-storage.js b/src/background/infrastructures/memory-storage.js new file mode 100644 index 0000000..0a05928 --- /dev/null +++ b/src/background/infrastructures/memory-storage.js @@ -0,0 +1,11 @@ +const db = {}; + +export default class MemoryStorage { + set(name, value) { + db[name] = value; + } + + get(name) { + return db[name]; + } +} diff --git a/src/background/repositories/persistent-setting.js b/src/background/repositories/persistent-setting.js new file mode 100644 index 0000000..247ea6f --- /dev/null +++ b/src/background/repositories/persistent-setting.js @@ -0,0 +1,16 @@ +import Setting from '../domains/setting'; + +export default class SettingRepository { + save(settings) { + return browser.storage.local.set({ settings: settings.serialize() }); + } + + async load() { + let { settings } = await browser.storage.local.get('settings'); + if (!settings) { + return null; + } + return Setting.deserialize(settings); + } +} + diff --git a/src/background/repositories/setting.js b/src/background/repositories/setting.js new file mode 100644 index 0000000..d9c481d --- /dev/null +++ b/src/background/repositories/setting.js @@ -0,0 +1,17 @@ +import MemoryStorage from '../infrastructures/memory-storage'; + +const CACHED_SETTING_KEY = 'setting'; + +export default class SettingRepository { + constructor() { + this.cache = new MemoryStorage(); + } + + get() { + return Promise.resolve(this.cache.get(CACHED_SETTING_KEY)); + } + + update(value) { + return this.cache.set(CACHED_SETTING_KEY, value); + } +} diff --git a/src/background/usecases/setting.js b/src/background/usecases/setting.js new file mode 100644 index 0000000..656fc3f --- /dev/null +++ b/src/background/usecases/setting.js @@ -0,0 +1,31 @@ +import Setting from '../domains/setting'; +import PersistentSettingRepository from '../repositories/persistent-setting'; +import SettingRepository from '../repositories/setting'; + +export default class SettingInteractor { + constructor() { + this.persistentSettingRepository = new PersistentSettingRepository(); + this.settingRepository = new SettingRepository(); + } + + save(settings) { + this.persistentSettingRepository.save(settings); + } + + get() { + return this.settingRepository.get(); + } + + async reload() { + let settings = await this.persistentSettingRepository.load(); + if (!settings) { + settings = Setting.defaultSettings(); + } + + let value = settings.value(); + + this.settingRepository.update(value); + + return value; + } +}