aboutsummaryrefslogtreecommitdiff
path: root/src/shared/settings/Properties.ts
blob: 63ff991db757eb2c27c4ef217a1c8fa464d19cc5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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<string> = 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,
    };
  }
}