2 * Copyright (c) 2019 The xterm.js authors. All rights reserved.
6 import { IOptionsService, ITerminalOptions, IPartialTerminalOptions } from 'common/services/Services';
7 import { EventEmitter, IEvent } from 'common/EventEmitter';
8 import { isMac } from 'common/Platform';
9 import { clone } from 'common/Clone';
11 // Source: https://freesound.org/people/altemark/sounds/45759/
12 // This sound is released under the Creative Commons Attribution 3.0 Unported
13 // (CC BY 3.0) license. It was created by 'altemark'. No modifications have been
14 // made, apart from the conversion to base64.
15 export const DEFAULT_BELL_SOUND = 'data:audio/mp3;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4LjMyLjEwNAAAAAAAAAAAAAAA//tQxAADB8AhSmxhIIEVCSiJrDCQBTcu3UrAIwUdkRgQbFAZC1CQEwTJ9mjRvBA4UOLD8nKVOWfh+UlK3z/177OXrfOdKl7pyn3Xf//WreyTRUoAWgBgkOAGbZHBgG1OF6zM82DWbZaUmMBptgQhGjsyYqc9ae9XFz280948NMBWInljyzsNRFLPWdnZGWrddDsjK1unuSrVN9jJsK8KuQtQCtMBjCEtImISdNKJOopIpBFpNSMbIHCSRpRR5iakjTiyzLhchUUBwCgyKiweBv/7UsQbg8isVNoMPMjAAAA0gAAABEVFGmgqK////9bP/6XCykxBTUUzLjEwMKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq';
18 export const DEFAULT_OPTIONS: ITerminalOptions = Object.freeze({
23 bellSound: DEFAULT_BELL_SOUND,
25 drawBoldTextInBrightColors: true,
26 fastScrollModifier: 'alt',
27 fastScrollSensitivity: 5,
28 fontFamily: 'courier-new, courier, monospace',
31 fontWeightBold: 'bold',
37 screenReaderMode: false,
38 macOptionIsMeta: false,
39 macOptionClickForcesSelection: false,
41 allowTransparency: false,
44 rightClickSelectsWord: isMac,
45 rendererType: 'canvas',
52 useFlowControl: false,
53 wordSeparator: ' ()[]{}\',:;"'
57 * The set of options that only have an effect when set in the Terminal constructor.
59 const CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows'];
61 export class OptionsService implements IOptionsService {
64 public options: ITerminalOptions;
66 private _onOptionChange = new EventEmitter<string>();
67 public get onOptionChange(): IEvent<string> { return this._onOptionChange.event; }
69 constructor(options: IPartialTerminalOptions) {
70 this.options = clone(DEFAULT_OPTIONS);
71 Object.keys(options).forEach(k => {
72 if (k in this.options) {
73 const newValue = options[k as keyof IPartialTerminalOptions] as any;
74 this.options[k] = newValue;
79 public setOption(key: string, value: any): void {
80 if (!(key in DEFAULT_OPTIONS)) {
81 throw new Error('No option with key "' + key + '"');
83 if (CONSTRUCTOR_ONLY_OPTIONS.indexOf(key) !== -1) {
84 throw new Error(`Option "${key}" can only be set in the constructor`);
86 if (this.options[key] === value) {
90 value = this._sanitizeAndValidateOption(key, value);
92 // Don't fire an option change event if they didn't change
93 if (this.options[key] === value) {
97 this.options[key] = value;
98 this._onOptionChange.fire(key);
101 private _sanitizeAndValidateOption(key: string, value: any): any {
106 case 'fontWeightBold':
108 case 'wordSeparator':
110 value = DEFAULT_OPTIONS[key];
116 throw new Error(`${key} cannot be less than 1, value: ${value}`);
120 value = Math.min(value, 4294967295);
122 throw new Error(`${key} cannot be less than 0, value: ${value}`);
125 case 'fastScrollSensitivity':
126 case 'scrollSensitivity':
128 throw new Error(`${key} cannot be less than or equal to 0, value: ${value}`);
135 public getOption(key: string): any {
136 if (!(key in DEFAULT_OPTIONS)) {
137 throw new Error(`No option with key "${key}"`);
139 return this.options[key];