From 574692551a27ea56660bf2061daeaa0d34beaff4 Mon Sep 17 00:00:00 2001 From: Shin'ya UEOKA Date: Sat, 5 Oct 2019 02:06:02 +0000 Subject: Make Properties class --- src/background/repositories/SettingRepository.ts | 4 +- src/background/usecases/CompletionsUseCase.ts | 4 +- src/background/usecases/parsers.ts | 4 +- src/settings/components/form/PropertiesForm.tsx | 6 +- src/settings/components/index.tsx | 13 +-- src/shared/SettingData.ts | 15 ++-- src/shared/Settings.ts | 37 ++------ src/shared/properties.ts | 50 ----------- src/shared/property-defs.ts | 56 ------------ src/shared/settings/Properties.ts | 110 +++++++++++++++++++++++ 10 files changed, 136 insertions(+), 163 deletions(-) delete mode 100644 src/shared/properties.ts delete mode 100644 src/shared/property-defs.ts create mode 100644 src/shared/settings/Properties.ts (limited to 'src') diff --git a/src/background/repositories/SettingRepository.ts b/src/background/repositories/SettingRepository.ts index c7a0e84..a11b65f 100644 --- a/src/background/repositories/SettingRepository.ts +++ b/src/background/repositories/SettingRepository.ts @@ -1,7 +1,7 @@ import { injectable } from 'tsyringe'; import MemoryStorage from '../infrastructures/MemoryStorage'; import Settings, { valueOf, toJSON } from '../../shared/Settings'; -import * as PropertyDefs from '../../shared/property-defs'; +import Properties from '../../shared/settings/Properties'; const CACHED_SETTING_KEY = 'setting'; @@ -26,7 +26,7 @@ export default class SettingRepository { async setProperty( name: string, value: string | number | boolean, ): Promise { - let def = PropertyDefs.defs.find(d => name === d.name); + let def = Properties.def(name); if (!def) { throw new Error('unknown property: ' + name); } diff --git a/src/background/usecases/CompletionsUseCase.ts b/src/background/usecases/CompletionsUseCase.ts index 8cd4f32..bfff1e6 100644 --- a/src/background/usecases/CompletionsUseCase.ts +++ b/src/background/usecases/CompletionsUseCase.ts @@ -5,7 +5,7 @@ import CompletionsRepository from '../repositories/CompletionsRepository'; import * as filters from './filters'; import SettingRepository from '../repositories/SettingRepository'; import TabPresenter from '../presenters/TabPresenter'; -import * as PropertyDefs from '../../shared/property-defs'; +import Properties from '../../shared/settings/Properties'; const COMPLETION_ITEM_LIMIT = 10; @@ -129,7 +129,7 @@ export default class CompletionsUseCase { } querySet(name: string, keywords: string): Promise { - let items = PropertyDefs.defs.map((def) => { + let items = Properties.defs().map((def) => { if (def.type === 'boolean') { return [ { diff --git a/src/background/usecases/parsers.ts b/src/background/usecases/parsers.ts index 6135fd8..e8a1149 100644 --- a/src/background/usecases/parsers.ts +++ b/src/background/usecases/parsers.ts @@ -1,4 +1,4 @@ -import * as PropertyDefs from '../../shared//property-defs'; +import Properties from '../../shared/settings/Properties'; const mustNumber = (v: any): number => { let num = Number(v); @@ -16,7 +16,7 @@ const parseSetOption = ( value = !key.startsWith('no'); key = value ? key : key.slice(2); } - let def = PropertyDefs.defs.find(d => d.name === key); + let def = Properties.def(key); if (!def) { throw new Error('Unknown property: ' + key); } diff --git a/src/settings/components/form/PropertiesForm.tsx b/src/settings/components/form/PropertiesForm.tsx index ee98b7e..db8c8e5 100644 --- a/src/settings/components/form/PropertiesForm.tsx +++ b/src/settings/components/form/PropertiesForm.tsx @@ -18,7 +18,7 @@ class PropertiesForm extends React.Component { render() { let types = this.props.types; - let value = this.props.value; + let values = this.props.value; return
{ @@ -46,10 +46,10 @@ class PropertiesForm extends React.Component { {name}
; diff --git a/src/settings/components/index.tsx b/src/settings/components/index.tsx index ada6efb..e86d765 100644 --- a/src/settings/components/index.tsx +++ b/src/settings/components/index.tsx @@ -8,11 +8,11 @@ import BlacklistForm from './form/BlacklistForm'; import PropertiesForm from './form/PropertiesForm'; import * as settingActions from '../../settings/actions/setting'; import SettingData, { - JSONTextSettings, FormKeymaps, FormSearch, FormSettings, + FormKeymaps, FormSearch, FormSettings, JSONTextSettings, } from '../../shared/SettingData'; import { State as AppState } from '../reducers/setting'; import * as settings from '../../shared/Settings'; -import * as PropertyDefs from '../../shared/property-defs'; +import Properties from '../../shared/settings/Properties'; const DO_YOU_WANT_TO_CONTINUE = 'Some settings in JSON can be lost when migrating. ' + @@ -33,11 +33,6 @@ class SettingsComponent extends React.Component { } renderFormFields(form: any) { - let types = PropertyDefs.defs.reduce( - (o: {[key: string]: string}, def) => { - o[def.name] = def.type; - return o; - }, {}); return
Keybindings @@ -66,7 +61,7 @@ class SettingsComponent extends React.Component {
Properties { let data = new SettingData({ source: this.props.source, form: (this.props.form as FormSettings).buildWithProperties( - settings.propertiesValueOf(value)), + Properties.fromJSON(value)) }); this.props.dispatch(settingActions.set(data)); } diff --git a/src/shared/SettingData.ts b/src/shared/SettingData.ts index 6605c80..aa4e382 100644 --- a/src/shared/SettingData.ts +++ b/src/shared/SettingData.ts @@ -2,6 +2,7 @@ import * as operations from './operations'; import Settings, * as settings from './Settings'; import Keymaps from './settings/Keymaps'; import Search from './settings/Search'; +import Properties from './settings/Properties'; export class FormKeymaps { private data: {[op: string]: string}; @@ -143,14 +144,14 @@ export class FormSettings { private search: FormSearch; - private properties: settings.Properties; + private properties: Properties; private blacklist: string[]; constructor( keymaps: FormKeymaps, search: FormSearch, - properties: settings.Properties, + properties: Properties, blacklist: string[], ) { this.keymaps = keymaps; @@ -177,7 +178,7 @@ export class FormSettings { ); } - buildWithProperties(props: settings.Properties): FormSettings { + buildWithProperties(props: Properties): FormSettings { return new FormSettings( this.keymaps, this.search, @@ -199,7 +200,7 @@ export class FormSettings { return settings.valueOf({ keymaps: this.keymaps.toKeymaps().toJSON(), search: this.search.toSearchSettings().toJSON(), - properties: this.properties, + properties: this.properties.toJSON(), blacklist: this.blacklist, }); } @@ -207,13 +208,13 @@ export class FormSettings { toJSON(): { keymaps: ReturnType; search: ReturnType; - properties: settings.Properties; + properties: ReturnType; blacklist: string[]; } { return { keymaps: this.keymaps.toJSON(), search: this.search.toJSON(), - properties: this.properties, + properties: this.properties.toJSON(), blacklist: this.blacklist, }; } @@ -227,7 +228,7 @@ export class FormSettings { return new FormSettings( FormKeymaps.valueOf(o.keymaps), FormSearch.valueOf(o.search), - settings.propertiesValueOf(o.properties), + Properties.fromJSON(o.properties), settings.blacklistValueOf(o.blacklist), ); } diff --git a/src/shared/Settings.ts b/src/shared/Settings.ts index e2bb3f4..6250aae 100644 --- a/src/shared/Settings.ts +++ b/src/shared/Settings.ts @@ -1,12 +1,6 @@ -import * as PropertyDefs from './property-defs'; import Keymaps from './settings/Keymaps'; import Search from './settings/Search'; - -export interface Properties { - hintchars: string; - smoothscroll: boolean; - complete: string; -} +import Properties from './settings/Properties'; export default interface Settings { keymaps: Keymaps; @@ -15,27 +9,6 @@ export default interface Settings { blacklist: string[]; } -export const propertiesValueOf = (o: any): Properties => { - let defNames = new Set(PropertyDefs.defs.map(def => def.name)); - let unknownName = Object.keys(o).find(name => !defNames.has(name)); - if (unknownName) { - throw new TypeError(`Unknown property name: "${unknownName}"`); - } - - for (let def of PropertyDefs.defs) { - if (!Object.prototype.hasOwnProperty.call(o, def.name)) { - continue; - } - if (typeof o[def.name] !== def.type) { - throw new TypeError(`property "${def.name}" is not ${def.type}`); - } - } - return { - ...PropertyDefs.defaultValues, - ...o, - }; -}; - export const blacklistValueOf = (o: any): string[] => { if (!Array.isArray(o)) { throw new TypeError(`"blacklist" is not an array of string`); @@ -59,7 +32,7 @@ export const valueOf = (o: any): Settings => { settings.search = Search.fromJSON(o.search); break; case 'properties': - settings.properties = propertiesValueOf(o.properties); + settings.properties = Properties.fromJSON(o.properties); break; case 'blacklist': settings.blacklist = blacklistValueOf(o.blacklist); @@ -75,7 +48,7 @@ export const toJSON = (settings: Settings): any => { return { keymaps: settings.keymaps.toJSON(), search: settings.search.toJSON(), - properties: settings.properties, + properties: settings.properties.toJSON(), blacklist: settings.blacklist, }; }; @@ -156,10 +129,10 @@ export const DefaultSetting: Settings = { 'wikipedia': 'https://en.wikipedia.org/w/index.php?search={}' } }), - properties: { + properties: Properties.fromJSON({ hintchars: 'abcdefghijklmnopqrstuvwxyz', smoothscroll: false, complete: 'sbh' - }, + }), blacklist: [] }; diff --git a/src/shared/properties.ts b/src/shared/properties.ts deleted file mode 100644 index 6315030..0000000 --- a/src/shared/properties.ts +++ /dev/null @@ -1,50 +0,0 @@ -export type Type = string | number | boolean; - -export class Def { - private name0: string; - - private description0: string; - - private defaultValue0: Type; - - constructor( - name: string, - description: string, - defaultValue: Type, - ) { - this.name0 = name; - this.description0 = description; - this.defaultValue0 = defaultValue; - } - - public get name(): string { - return this.name0; - } - - public get defaultValue(): Type { - return this.defaultValue0; - } - - public get description(): Type { - return this.description0; - } - - public get type(): string { - return typeof this.defaultValue; - } -} - -export const defs: Def[] = [ - new Def( - 'hintchars', - 'hint characters on follow mode', - 'abcdefghijklmnopqrstuvwxyz'), - new Def( - 'smoothscroll', - 'smooth scroll', - false), - new Def( - 'complete', - 'which are completed at the open page', - 'sbh'), -]; diff --git a/src/shared/property-defs.ts b/src/shared/property-defs.ts deleted file mode 100644 index fec9f80..0000000 --- a/src/shared/property-defs.ts +++ /dev/null @@ -1,56 +0,0 @@ -export type Type = string | number | boolean; - -export class Def { - private name0: string; - - private description0: string; - - private defaultValue0: Type; - - constructor( - name: string, - description: string, - defaultValue: Type, - ) { - this.name0 = name; - this.description0 = description; - this.defaultValue0 = defaultValue; - } - - public get name(): string { - return this.name0; - } - - public get defaultValue(): Type { - return this.defaultValue0; - } - - public get description(): Type { - return this.description0; - } - - public get type(): string { - return typeof this.defaultValue; - } -} - -export const defs: Def[] = [ - new Def( - 'hintchars', - 'hint characters on follow mode', - 'abcdefghijklmnopqrstuvwxyz'), - new Def( - 'smoothscroll', - 'smooth scroll', - false), - new Def( - 'complete', - 'which are completed at the open page', - 'sbh'), -]; - -export const defaultValues = { - hintchars: 'abcdefghijklmnopqrstuvwxyz', - smoothscroll: false, - complete: 'sbh', -}; diff --git a/src/shared/settings/Properties.ts b/src/shared/settings/Properties.ts new file mode 100644 index 0000000..1bc4c7f --- /dev/null +++ b/src/shared/settings/Properties.ts @@ -0,0 +1,110 @@ +export type PropertiesJSON = { + hintchars?: string; + smoothscroll?: boolean; + complete?: string; +}; + +export type PropertyTypes = { + hintchars: string; + smoothscroll: string; + complete: string; +}; + +type PropertyName = 'hintchars' | 'smoothscroll' | 'complete'; + +type PropertyDef = { + name: PropertyName; + description: string; + defaultValue: string | number | boolean; + type: 'string' | 'number' | 'boolean'; +}; + +const defs: PropertyDef[] = [ + { + name: 'hintchars', + description: 'hint characters on follow mode', + defaultValue: 'abcdefghijklmnopqrstuvwxyz', + type: 'string', + }, { + name: 'smoothscroll', + description: 'smooth scroll', + defaultValue: false, + type: 'boolean', + }, { + name: 'complete', + description: 'which are completed at the open page', + defaultValue: 'sbh', + type: 'string', + } +]; + +const defaultValues = { + hintchars: 'abcdefghijklmnopqrstuvwxyz', + smoothscroll: false, + complete: 'sbh', +}; + +export default class Properties { + public hintchars: string; + + public smoothscroll: boolean; + + public complete: string; + + constructor({ + hintchars, + smoothscroll, + complete, + }: { + hintchars?: string; + smoothscroll?: boolean; + complete?: string; + }) { + this.hintchars = hintchars || defaultValues.hintchars; + this.smoothscroll = smoothscroll || defaultValues.smoothscroll; + this.complete = complete || defaultValues.complete; + } + + static fromJSON(json: any): Properties { + let defNames: Set = new Set(defs.map(def => def.name)); + let unknownName = Object.keys(json).find(name => !defNames.has(name)); + if (unknownName) { + throw new TypeError(`Unknown property name: "${unknownName}"`); + } + + for (let def of defs) { + if (!Object.prototype.hasOwnProperty.call(json, def.name)) { + continue; + } + if (typeof json[def.name] !== def.type) { + throw new TypeError( + `property "${def.name}" is not ${def.type}`); + } + } + return new Properties(json); + } + + static types(): PropertyTypes { + return { + hintchars: 'string', + smoothscroll: 'boolean', + complete: 'string', + }; + } + + static def(name: string): PropertyDef | undefined { + return defs.find(p => p.name === name); + } + + static defs(): PropertyDef[] { + return defs; + } + + toJSON(): PropertiesJSON { + return { + hintchars: this.hintchars, + smoothscroll: this.smoothscroll, + complete: this.complete, + }; + } +} -- cgit v1.2.3