Make Settings class
This commit is contained in:
		
							parent
							
								
									b86b4680b6
								
							
						
					
					
						commit
						0dec6c641f
					
				
					 13 changed files with 120 additions and 99 deletions
				
			
		| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
import { injectable } from 'tsyringe';
 | 
			
		||||
import SettingUseCase from '../usecases/SettingUseCase';
 | 
			
		||||
import ContentMessageClient from '../infrastructures/ContentMessageClient';
 | 
			
		||||
import Settings from '../../shared/Settings';
 | 
			
		||||
import Settings from '../../shared/settings/Settings';
 | 
			
		||||
 | 
			
		||||
@injectable()
 | 
			
		||||
export default class SettingController {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,6 @@ import AddonEnabledController from '../controllers/AddonEnabledController';
 | 
			
		|||
import LinkController from '../controllers/LinkController';
 | 
			
		||||
import OperationController from '../controllers/OperationController';
 | 
			
		||||
import MarkController from '../controllers/MarkController';
 | 
			
		||||
import { toJSON } from '../../shared/Settings';
 | 
			
		||||
 | 
			
		||||
@injectable()
 | 
			
		||||
export default class ContentMessageListener {
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +102,7 @@ export default class ContentMessageListener {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  async onSettingsQuery(): Promise<any> {
 | 
			
		||||
    return toJSON(await this.settingController.getSetting());
 | 
			
		||||
    return (await this.settingController.getSetting()).toJSON();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onFindGetKeyword(): Promise<string> {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
import { injectable } from 'tsyringe';
 | 
			
		||||
import MemoryStorage from '../infrastructures/MemoryStorage';
 | 
			
		||||
import Settings, { valueOf, toJSON } from '../../shared/Settings';
 | 
			
		||||
import Settings from '../../shared/settings/Settings';
 | 
			
		||||
import Properties from '../../shared/settings/Properties';
 | 
			
		||||
 | 
			
		||||
const CACHED_SETTING_KEY = 'setting';
 | 
			
		||||
| 
						 | 
				
			
			@ -15,12 +15,11 @@ export default class SettingRepository {
 | 
			
		|||
 | 
			
		||||
  get(): Promise<Settings> {
 | 
			
		||||
    let data = this.cache.get(CACHED_SETTING_KEY);
 | 
			
		||||
    return Promise.resolve(valueOf(data));
 | 
			
		||||
    return Promise.resolve(Settings.fromJSON(data));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  update(value: Settings): void {
 | 
			
		||||
    let data = toJSON(value);
 | 
			
		||||
    return this.cache.set(CACHED_SETTING_KEY, data);
 | 
			
		||||
    return this.cache.set(CACHED_SETTING_KEY, value.toJSON());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async setProperty(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@ import PersistentSettingRepository
 | 
			
		|||
  from '../repositories/PersistentSettingRepository';
 | 
			
		||||
import SettingRepository from '../repositories/SettingRepository';
 | 
			
		||||
import { DefaultSettingData } from '../../shared/SettingData';
 | 
			
		||||
import Settings from '../../shared/Settings';
 | 
			
		||||
import Settings from '../../shared/settings/Settings';
 | 
			
		||||
import NotifyPresenter from '../presenters/NotifyPresenter';
 | 
			
		||||
 | 
			
		||||
@injectable()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
import Settings, { valueOf } from '../../shared/Settings';
 | 
			
		||||
import Settings from '../../shared/settings/Settings';
 | 
			
		||||
import * as messages from '../../shared/messages';
 | 
			
		||||
 | 
			
		||||
export default interface SettingClient {
 | 
			
		||||
| 
						 | 
				
			
			@ -10,6 +10,6 @@ export class SettingClientImpl {
 | 
			
		|||
    let settings = await browser.runtime.sendMessage({
 | 
			
		||||
      type: messages.SETTINGS_QUERY,
 | 
			
		||||
    });
 | 
			
		||||
    return valueOf(settings);
 | 
			
		||||
    return Settings.fromJSON(settings);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
import Settings, { DefaultSetting } from '../../shared/Settings';
 | 
			
		||||
import Settings, { DefaultSetting } from '../../shared/settings/Settings';
 | 
			
		||||
 | 
			
		||||
let current: Settings = DefaultSetting;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
import { injectable, inject } from 'tsyringe';
 | 
			
		||||
import SettingRepository from '../repositories/SettingRepository';
 | 
			
		||||
import SettingClient from '../client/SettingClient';
 | 
			
		||||
import Settings from '../../shared/Settings';
 | 
			
		||||
import Settings from '../../shared/settings/Settings';
 | 
			
		||||
 | 
			
		||||
@injectable()
 | 
			
		||||
export default class SettingUseCase {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
import * as operations from './operations';
 | 
			
		||||
import Settings, * as settings from './Settings';
 | 
			
		||||
import Settings from './settings/Settings';
 | 
			
		||||
import Keymaps from './settings/Keymaps';
 | 
			
		||||
import Search from './settings/Search';
 | 
			
		||||
import Properties from './settings/Properties';
 | 
			
		||||
| 
						 | 
				
			
			@ -118,7 +118,7 @@ export class JSONTextSettings {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  toSettings(): Settings {
 | 
			
		||||
    return settings.valueOf(JSON.parse(this.json));
 | 
			
		||||
    return Settings.fromJSON(JSON.parse(this.json));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  toJSONText(): string {
 | 
			
		||||
| 
						 | 
				
			
			@ -198,7 +198,7 @@ export class FormSettings {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  toSettings(): Settings {
 | 
			
		||||
    return settings.valueOf({
 | 
			
		||||
    return Settings.fromJSON({
 | 
			
		||||
      keymaps: this.keymaps.toKeymaps().toJSON(),
 | 
			
		||||
      search: this.search.toSearchSettings().toJSON(),
 | 
			
		||||
      properties: this.properties.toJSON(),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,49 +1,76 @@
 | 
			
		|||
import Keymaps from './settings/Keymaps';
 | 
			
		||||
import Search from './settings/Search';
 | 
			
		||||
import Properties from './settings/Properties';
 | 
			
		||||
import Blacklist from './settings/Blacklist';
 | 
			
		||||
import Keymaps, { KeymapsJSON } from './Keymaps';
 | 
			
		||||
import Search, { SearchJSON } from './Search';
 | 
			
		||||
import Properties, { PropertiesJSON } from './Properties';
 | 
			
		||||
import Blacklist, { BlacklistJSON } from './Blacklist';
 | 
			
		||||
 | 
			
		||||
export default interface Settings {
 | 
			
		||||
  keymaps: Keymaps;
 | 
			
		||||
  search: Search;
 | 
			
		||||
  properties: Properties;
 | 
			
		||||
  blacklist: Blacklist;
 | 
			
		||||
export type SettingsJSON = {
 | 
			
		||||
  keymaps: KeymapsJSON,
 | 
			
		||||
  search: SearchJSON,
 | 
			
		||||
  properties: PropertiesJSON,
 | 
			
		||||
  blacklist: BlacklistJSON,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default class Settings {
 | 
			
		||||
  public keymaps: Keymaps;
 | 
			
		||||
 | 
			
		||||
  public search: Search;
 | 
			
		||||
 | 
			
		||||
  public properties: Properties;
 | 
			
		||||
 | 
			
		||||
  public blacklist: Blacklist;
 | 
			
		||||
 | 
			
		||||
  constructor({
 | 
			
		||||
    keymaps,
 | 
			
		||||
    search,
 | 
			
		||||
    properties,
 | 
			
		||||
    blacklist,
 | 
			
		||||
  }: {
 | 
			
		||||
    keymaps: Keymaps;
 | 
			
		||||
    search: Search;
 | 
			
		||||
    properties: Properties;
 | 
			
		||||
    blacklist: Blacklist;
 | 
			
		||||
  }) {
 | 
			
		||||
    this.keymaps = keymaps;
 | 
			
		||||
    this.search = search;
 | 
			
		||||
    this.properties = properties;
 | 
			
		||||
    this.blacklist = blacklist;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static fromJSON(json: any): Settings {
 | 
			
		||||
    let settings = { ...DefaultSetting };
 | 
			
		||||
    for (let key of Object.keys(json)) {
 | 
			
		||||
      switch (key) {
 | 
			
		||||
      case 'keymaps':
 | 
			
		||||
        settings.keymaps = Keymaps.fromJSON(json.keymaps);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'search':
 | 
			
		||||
        settings.search = Search.fromJSON(json.search);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'properties':
 | 
			
		||||
        settings.properties = Properties.fromJSON(json.properties);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'blacklist':
 | 
			
		||||
        settings.blacklist = Blacklist.fromJSON(json.blacklist);
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        throw new TypeError('unknown setting: ' + key);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return new Settings(settings);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  toJSON(): SettingsJSON {
 | 
			
		||||
    return {
 | 
			
		||||
      keymaps: this.keymaps.toJSON(),
 | 
			
		||||
      search: this.search.toJSON(),
 | 
			
		||||
      properties: this.properties.toJSON(),
 | 
			
		||||
      blacklist: this.blacklist.toJSON(),
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const valueOf = (o: any): Settings => {
 | 
			
		||||
  let settings = { ...DefaultSetting };
 | 
			
		||||
  for (let key of Object.keys(o)) {
 | 
			
		||||
    switch (key) {
 | 
			
		||||
    case 'keymaps':
 | 
			
		||||
      settings.keymaps = Keymaps.fromJSON(o.keymaps);
 | 
			
		||||
      break;
 | 
			
		||||
    case 'search':
 | 
			
		||||
      settings.search = Search.fromJSON(o.search);
 | 
			
		||||
      break;
 | 
			
		||||
    case 'properties':
 | 
			
		||||
      settings.properties = Properties.fromJSON(o.properties);
 | 
			
		||||
      break;
 | 
			
		||||
    case 'blacklist':
 | 
			
		||||
      settings.blacklist = Blacklist.fromJSON(o.blacklist);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      throw new TypeError('unknown setting: ' + key);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return settings;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const toJSON = (settings: Settings): any => {
 | 
			
		||||
  return {
 | 
			
		||||
    keymaps: settings.keymaps.toJSON(),
 | 
			
		||||
    search: settings.search.toJSON(),
 | 
			
		||||
    properties: settings.properties.toJSON(),
 | 
			
		||||
    blacklist: settings.blacklist.toJSON(),
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const DefaultSetting: Settings = {
 | 
			
		||||
  keymaps: Keymaps.fromJSON({
 | 
			
		||||
export const DefaultSetting: Settings = Settings.fromJSON({
 | 
			
		||||
  keymaps: {
 | 
			
		||||
    '0': { 'type': 'scroll.home' },
 | 
			
		||||
    ':': { 'type': 'command.show' },
 | 
			
		||||
    'o': { 'type': 'command.show.open', 'alter': false },
 | 
			
		||||
| 
						 | 
				
			
			@ -106,8 +133,8 @@ export const DefaultSetting: Settings = {
 | 
			
		|||
    'N': { 'type': 'find.prev' },
 | 
			
		||||
    '.': { 'type': 'repeat.last' },
 | 
			
		||||
    '<S-Esc>': { 'type': 'addon.toggle.enabled' }
 | 
			
		||||
  }),
 | 
			
		||||
  search: Search.fromJSON({
 | 
			
		||||
  },
 | 
			
		||||
  search: {
 | 
			
		||||
    default: 'google',
 | 
			
		||||
    engines: {
 | 
			
		||||
      'google': 'https://google.com/search?q={}',
 | 
			
		||||
| 
						 | 
				
			
			@ -117,11 +144,11 @@ export const DefaultSetting: Settings = {
 | 
			
		|||
      'twitter': 'https://twitter.com/search?q={}',
 | 
			
		||||
      'wikipedia': 'https://en.wikipedia.org/w/index.php?search={}'
 | 
			
		||||
    }
 | 
			
		||||
  }),
 | 
			
		||||
  properties: Properties.fromJSON({
 | 
			
		||||
  },
 | 
			
		||||
  properties: {
 | 
			
		||||
    hintchars: 'abcdefghijklmnopqrstuvwxyz',
 | 
			
		||||
    smoothscroll: false,
 | 
			
		||||
    complete: 'sbh'
 | 
			
		||||
  }),
 | 
			
		||||
  blacklist: Blacklist.fromJSON([]),
 | 
			
		||||
};
 | 
			
		||||
  },
 | 
			
		||||
  blacklist: [],
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -1,27 +1,26 @@
 | 
			
		|||
import { SettingRepositoryImpl } from '../../../src/content/repositories/SettingRepository';
 | 
			
		||||
import { expect } from 'chai';
 | 
			
		||||
import Keymaps from '../../../src/shared/settings/Keymaps';
 | 
			
		||||
import Search from '../../../src/shared/settings/Search';
 | 
			
		||||
import Settings from '../../../src/shared/settings/Settings';
 | 
			
		||||
 | 
			
		||||
describe('SettingRepositoryImpl', () => {
 | 
			
		||||
  it('updates and gets current value', () => {
 | 
			
		||||
    let sut = new SettingRepositoryImpl();
 | 
			
		||||
 | 
			
		||||
    let settings = {
 | 
			
		||||
      keymaps: Keymaps.fromJSON({}),
 | 
			
		||||
      search: Search.fromJSON({
 | 
			
		||||
    let settings = Settings.fromJSON({
 | 
			
		||||
      keymaps: {},
 | 
			
		||||
      search:{
 | 
			
		||||
        default: 'google',
 | 
			
		||||
        engines: {
 | 
			
		||||
          google: 'https://google.com/?q={}',
 | 
			
		||||
        }
 | 
			
		||||
      }),
 | 
			
		||||
      },
 | 
			
		||||
      properties: {
 | 
			
		||||
        hintchars: 'abcd1234',
 | 
			
		||||
        smoothscroll: false,
 | 
			
		||||
        complete: 'sbh',
 | 
			
		||||
      },
 | 
			
		||||
      blacklist: [],
 | 
			
		||||
    };
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    sut.set(settings);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
import SettingRepository from '../../../src/content/repositories/SettingRepository';
 | 
			
		||||
import SettingClient from '../../../src/content/client/SettingClient';
 | 
			
		||||
import SettingUseCase from '../../../src/content/usecases/SettingUseCase';
 | 
			
		||||
import Settings, { DefaultSetting } from '../../../src/shared/Settings';
 | 
			
		||||
import Settings, { DefaultSetting } from '../../../src/shared/settings/Settings';
 | 
			
		||||
import { expect } from 'chai';
 | 
			
		||||
 | 
			
		||||
class MockSettingRepository implements SettingRepository {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,9 @@
 | 
			
		|||
import SettingData, {
 | 
			
		||||
  FormKeymaps, JSONTextSettings, FormSettings,
 | 
			
		||||
} from '../../src/shared/SettingData';
 | 
			
		||||
import Settings from '../../src/shared/Settings';
 | 
			
		||||
import Settings from '../../src/shared/settings/Settings';
 | 
			
		||||
import { expect } from 'chai';
 | 
			
		||||
import Keymaps from '../../src/shared/settings/Keymaps';
 | 
			
		||||
import Search from '../../src/shared/settings/Search';
 | 
			
		||||
import Properties from '../../src/shared/settings/Properties';
 | 
			
		||||
import Blacklist from '../../src/shared/settings/Blacklist'
 | 
			
		||||
 | 
			
		||||
describe('shared/SettingData', () => {
 | 
			
		||||
  describe('FormKeymaps', () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -72,21 +69,21 @@ describe('shared/SettingData', () => {
 | 
			
		|||
 | 
			
		||||
    describe('#fromSettings to #toJSON', () => {
 | 
			
		||||
      it('create from a Settings and create a JSON string', () => {
 | 
			
		||||
        let o = {
 | 
			
		||||
          keymaps: Keymaps.fromJSON({}),
 | 
			
		||||
          search: Search.fromJSON({
 | 
			
		||||
        let o = Settings.fromJSON({
 | 
			
		||||
          keymaps: {},
 | 
			
		||||
          search: {
 | 
			
		||||
            default: "google",
 | 
			
		||||
            engines: {
 | 
			
		||||
              google: "https://google.com/search?q={}",
 | 
			
		||||
            },
 | 
			
		||||
          }),
 | 
			
		||||
          properties: Properties.fromJSON({
 | 
			
		||||
          },
 | 
			
		||||
          properties: {
 | 
			
		||||
            hintchars: "abcdefghijklmnopqrstuvwxyz",
 | 
			
		||||
            smoothscroll: false,
 | 
			
		||||
            complete: "sbh"
 | 
			
		||||
          }),
 | 
			
		||||
          blacklist: Blacklist.fromJSON([]),
 | 
			
		||||
        };
 | 
			
		||||
          },
 | 
			
		||||
          blacklist: [],
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let json = JSONTextSettings.fromSettings(o).toJSONText();
 | 
			
		||||
        expect(JSON.parse(json)).to.deep.equal({
 | 
			
		||||
| 
						 | 
				
			
			@ -150,24 +147,24 @@ describe('shared/SettingData', () => {
 | 
			
		|||
 | 
			
		||||
    describe('#fromSettings to #toJSON', () => {
 | 
			
		||||
      it('create from a Settings and create a JSON string', () => {
 | 
			
		||||
        let data: Settings = {
 | 
			
		||||
          keymaps: Keymaps.fromJSON({
 | 
			
		||||
        let data: Settings = Settings.fromJSON({
 | 
			
		||||
          keymaps: {
 | 
			
		||||
            'j': { type: 'scroll.vertically', count: 1 },
 | 
			
		||||
            '0': { type: 'scroll.home' },
 | 
			
		||||
          }),
 | 
			
		||||
          search: Search.fromJSON({
 | 
			
		||||
          },
 | 
			
		||||
          search: {
 | 
			
		||||
            default: "google",
 | 
			
		||||
            engines: {
 | 
			
		||||
              "google": "https://google.com/search?q={}"
 | 
			
		||||
            }
 | 
			
		||||
          }),
 | 
			
		||||
          properties: Properties.fromJSON({
 | 
			
		||||
          },
 | 
			
		||||
          properties: {
 | 
			
		||||
            hintchars: "abcdefghijklmnopqrstuvwxyz",
 | 
			
		||||
            smoothscroll: false,
 | 
			
		||||
            complete: "sbh"
 | 
			
		||||
          }),
 | 
			
		||||
          blacklist: Blacklist.fromJSON([]),
 | 
			
		||||
        };
 | 
			
		||||
          },
 | 
			
		||||
          blacklist: [],
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let json = FormSettings.fromSettings(data).toJSON();
 | 
			
		||||
        expect(json).to.deep.equal({
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,10 @@
 | 
			
		|||
import * as settings from '../../src/shared/Settings';
 | 
			
		||||
import {expect} from 'chai';
 | 
			
		||||
import Settings from '../../../src/shared/settings/Settings';
 | 
			
		||||
import { expect } from 'chai';
 | 
			
		||||
 | 
			
		||||
describe('Settings', () => {
 | 
			
		||||
  describe('#valueOf', () => {
 | 
			
		||||
    it('returns settings by valid settings', () => {
 | 
			
		||||
      let x = settings.valueOf({
 | 
			
		||||
      let x = Settings.fromJSON({
 | 
			
		||||
        keymaps: {},
 | 
			
		||||
        "search": {
 | 
			
		||||
          "default": "google",
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ describe('Settings', () => {
 | 
			
		|||
    });
 | 
			
		||||
 | 
			
		||||
    it('sets default settings', () => {
 | 
			
		||||
      let value = settings.valueOf({});
 | 
			
		||||
      let value = Settings.fromJSON({});
 | 
			
		||||
      expect(value.keymaps.toJSON()).to.not.be.empty;
 | 
			
		||||
      expect(value.properties.toJSON()).to.not.be.empty;
 | 
			
		||||
      expect(value.search.defaultEngine).to.be.a('string');
 | 
			
		||||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ describe('Settings', () => {
 | 
			
		|||
    });
 | 
			
		||||
 | 
			
		||||
    it('throws a TypeError with an unknown field', () => {
 | 
			
		||||
      expect(() => settings.valueOf({ name: 'alice' })).to.throw(TypeError)
 | 
			
		||||
      expect(() => Settings.fromJSON({ name: 'alice' })).to.throw(TypeError)
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
		Reference in a new issue