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/shared/settings/Properties.ts | 110 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 src/shared/settings/Properties.ts (limited to 'src/shared/settings/Properties.ts') 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 From 8428671a0acf47a4a90b6b1f39cf94401f1e5520 Mon Sep 17 00:00:00 2001 From: Shin'ya UEOKA Date: Sat, 5 Oct 2019 13:56:21 +0000 Subject: Fix form options --- src/settings/components/form/BlacklistForm.tsx | 38 +++++++++++++++----------- src/settings/components/index.tsx | 11 ++++---- src/settings/reducers/setting.ts | 2 ++ src/shared/SettingData.ts | 10 +++---- src/shared/settings/Properties.ts | 2 +- 5 files changed, 35 insertions(+), 28 deletions(-) (limited to 'src/shared/settings/Properties.ts') diff --git a/src/settings/components/form/BlacklistForm.tsx b/src/settings/components/form/BlacklistForm.tsx index 637bc1e..f352e41 100644 --- a/src/settings/components/form/BlacklistForm.tsx +++ b/src/settings/components/form/BlacklistForm.tsx @@ -2,10 +2,11 @@ import './BlacklistForm.scss'; import AddButton from '../ui/AddButton'; import DeleteButton from '../ui/DeleteButton'; import React from 'react'; +import { BlacklistJSON } from '../../../shared/settings/Blacklist'; interface Props { - value: string[]; - onChange: (value: string[]) => void; + value: BlacklistJSON; + onChange: (value: BlacklistJSON) => void; onBlur: () => void; } @@ -19,19 +20,24 @@ class BlacklistForm extends React.Component { render() { return
{ - this.props.value.map((url, index) => { - return
- - -
; - }) + this.props.value + .map((item, index) => { + if (typeof item !== 'string') { + // TODO support partial blacklist; + return null; + } + return
+ + +
; + }) } @@ -41,7 +47,7 @@ class BlacklistForm extends React.Component { bindValue(e: any) { let name = e.target.name; let index = e.target.getAttribute('data-index'); - let next = this.props.value ? this.props.value.slice() : []; + let next = this.props.value.slice(); if (name === 'url') { next[index] = e.target.value; diff --git a/src/settings/components/index.tsx b/src/settings/components/index.tsx index bd99d52..586f0f0 100644 --- a/src/settings/components/index.tsx +++ b/src/settings/components/index.tsx @@ -32,7 +32,7 @@ class SettingsComponent extends React.Component { this.props.dispatch(settingActions.load()); } - renderFormFields(form: any) { + renderFormFields(form: FormSettings) { return
Keybindings @@ -53,7 +53,7 @@ class SettingsComponent extends React.Component {
Blacklist @@ -62,7 +62,7 @@ class SettingsComponent extends React.Component { Properties @@ -89,10 +89,9 @@ class SettingsComponent extends React.Component { let fields = null; let disabled = this.props.error.length > 0; if (this.props.source === 'form') { - fields = this.renderFormFields(this.props.form); + fields = this.renderFormFields(this.props.form!!); } else if (this.props.source === 'json') { - fields = this.renderJsonFields( - this.props.json as JSONTextSettings, this.props.error); + fields = this.renderJsonFields(this.props.json!!, this.props.error); } return (
diff --git a/src/settings/reducers/setting.ts b/src/settings/reducers/setting.ts index 89bf1cb..804853f 100644 --- a/src/settings/reducers/setting.ts +++ b/src/settings/reducers/setting.ts @@ -2,6 +2,7 @@ import * as actions from '../actions'; import { JSONTextSettings, FormSettings, SettingSource, } from '../../shared/SettingData'; +import { DefaultSetting } from '../../shared/settings/Settings'; export interface State { source: SettingSource; @@ -13,6 +14,7 @@ export interface State { const defaultState: State = { source: SettingSource.JSON, json: JSONTextSettings.fromText(''), + form: FormSettings.fromSettings(DefaultSetting), error: '', }; diff --git a/src/shared/SettingData.ts b/src/shared/SettingData.ts index 2dedfef..c28a5dd 100644 --- a/src/shared/SettingData.ts +++ b/src/shared/SettingData.ts @@ -141,13 +141,13 @@ export class JSONTextSettings { } export class FormSettings { - private keymaps: FormKeymaps; + public readonly keymaps: FormKeymaps; - private search: FormSearch; + public readonly search: FormSearch; - private properties: Properties; + public readonly properties: Properties; - private blacklist: Blacklist; + public readonly blacklist: Blacklist; constructor( keymaps: FormKeymaps, @@ -210,7 +210,7 @@ export class FormSettings { keymaps: ReturnType; search: ReturnType; properties: ReturnType; - blacklist: string[]; + blacklist: ReturnType; } { return { keymaps: this.keymaps.toJSON(), diff --git a/src/shared/settings/Properties.ts b/src/shared/settings/Properties.ts index 1bc4c7f..63ff991 100644 --- a/src/shared/settings/Properties.ts +++ b/src/shared/settings/Properties.ts @@ -59,7 +59,7 @@ export default class Properties { hintchars?: string; smoothscroll?: boolean; complete?: string; - }) { + } = {}) { this.hintchars = hintchars || defaultValues.hintchars; this.smoothscroll = smoothscroll || defaultValues.smoothscroll; this.complete = complete || defaultValues.complete; -- cgit v1.2.3