Merge pull request #878 from npezza93/add-bell-sound

If bell() gets called emit bell event and add default bell sound
This commit is contained in:
Daniel Imms
2017-08-19 13:05:01 -07:00
committed by GitHub
9 changed files with 85 additions and 22 deletions
+11
View File
@@ -38,6 +38,17 @@
</select>
</label>
</p>
<p>
<label>
bellStyle
<select id="option-bell-style">
<option value="">none</option>
<option value="sound">sound</option>
<option value="visual">visual</option>
<option value="both">both</option>
</select>
</label>
</p>
<p>
<label>scrollback <input type="number" id="option-scrollback" value="1000" /></label>
</p>
+5 -1
View File
@@ -15,7 +15,8 @@ var terminalContainer = document.getElementById('terminal-container'),
cursorBlink: document.querySelector('#option-cursor-blink'),
cursorStyle: document.querySelector('#option-cursor-style'),
scrollback: document.querySelector('#option-scrollback'),
tabstopwidth: document.querySelector('#option-tabstopwidth')
tabstopwidth: document.querySelector('#option-tabstopwidth'),
bellStyle: document.querySelector('#option-bell-style')
},
colsElement = document.getElementById('cols'),
rowsElement = document.getElementById('rows');
@@ -53,6 +54,9 @@ optionElements.cursorBlink.addEventListener('change', function () {
optionElements.cursorStyle.addEventListener('change', function () {
term.setOption('cursorStyle', optionElements.cursorStyle.value);
});
optionElements.bellStyle.addEventListener('change', function () {
term.setOption('bellStyle', optionElements.bellStyle.value);
});
optionElements.scrollback.addEventListener('change', function () {
term.setOption('scrollback', parseInt(optionElements.scrollback.value, 10));
});
+1 -8
View File
@@ -106,14 +106,7 @@ export class InputHandler implements IInputHandler {
* Bell (Ctrl-G).
*/
public bell(): void {
if (!this._terminal.options.visualBell) {
return;
}
this._terminal.element.style.borderColor = 'white';
setTimeout(() => this._terminal.element.style.borderColor = '', 10);
if (this._terminal.options.popOnBell) {
this._terminal.focus();
}
this._terminal.bell();
}
/**
+3 -2
View File
@@ -87,6 +87,7 @@ export interface IInputHandlingTerminal extends IEventEmitter {
viewport: IViewport;
selectionManager: ISelectionManager;
bell(): void;
focus(): void;
convertEol: boolean;
updateRange(y: number): void;
@@ -113,6 +114,8 @@ export interface IInputHandlingTerminal extends IEventEmitter {
}
export interface ITerminalOptions {
bellSound?: string;
bellStyle?: string;
cancelEvents?: boolean;
colors?: string[];
cols?: number;
@@ -123,14 +126,12 @@ export interface ITerminalOptions {
disableStdin?: boolean;
geometry?: [number, number];
handler?: (data: string) => void;
popOnBell?: boolean;
rows?: number;
screenKeys?: boolean;
scrollback?: number;
tabStopWidth?: number;
termName?: string;
useFlowControl?: boolean;
visualBell?: boolean;
}
export interface IBuffer {
+40 -8
View File
@@ -39,6 +39,7 @@ import { CHARSETS } from './Charsets';
import { getRawByteCoords } from './utils/Mouse';
import { CustomKeyEventHandler, Charset, LinkMatcherHandler, LinkMatcherValidationCallback, CharData, LineData, Option, StringOption, BooleanOption, StringArrayOption, NumberOption, GeometryOption, HandlerOption } from './Types';
import { ITerminal, IBrowser, ITerminalOptions, IInputHandlingTerminal, ILinkMatcherOptions, IViewport, ICompositionHelper } from './Interfaces';
import { BellSound } from './utils/Sounds';
// Declare for RequireJS in loadAddon
declare var define: any;
@@ -147,8 +148,8 @@ const DEFAULT_OPTIONS: ITerminalOptions = {
geometry: [80, 24],
cursorBlink: false,
cursorStyle: 'block',
visualBell: false,
popOnBell: false,
bellSound: BellSound,
bellStyle: null,
scrollback: 1000,
screenKeys: false,
debug: false,
@@ -178,6 +179,8 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
private helperContainer: HTMLElement;
private compositionView: HTMLElement;
private charSizeStyleElement: HTMLStyleElement;
private bellAudioElement: HTMLAudioElement;
private visualBellTimer: number;
public browser: IBrowser = <any>Browser;
@@ -482,6 +485,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
this.viewport.syncScrollArea();
break;
case 'tabStopWidth': this.setupStops(); break;
case 'bellStyle': this.preloadBellSound(); break;
}
}
@@ -689,6 +693,9 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
this.viewportScrollArea.classList.add('xterm-scroll-area');
this.viewportElement.appendChild(this.viewportScrollArea);
// preload audio
this.preloadBellSound();
// Create the selection container.
this.selectionContainer = document.createElement('div');
this.selectionContainer.classList.add('xterm-selection');
@@ -1874,12 +1881,16 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
* Note: We could do sweet things with webaudio here
*/
public bell(): void {
if (!this.options.visualBell) return;
this.element.style.borderColor = 'white';
setTimeout(() => {
this.element.style.borderColor = '';
}, 10);
if (this.options.popOnBell) this.focus();
this.emit('bell');
if (this.soundBell()) this.bellAudioElement.play();
if (this.visualBell()) {
this.element.classList.add('visual-bell-active');
clearTimeout(this.visualBellTimer);
this.visualBellTimer = window.setTimeout(() => {
this.element.classList.remove('visual-bell-active');
}, 200);
}
}
/**
@@ -2271,6 +2282,27 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
return matchColorCache[hash] = li;
}
private visualBell(): boolean {
return this.options.bellStyle === 'visual' ||
this.options.bellStyle === 'both';
}
private soundBell(): boolean {
return this.options.bellStyle === 'sound' ||
this.options.bellStyle === 'both';
}
private preloadBellSound(): void {
if (this.soundBell()) {
this.bellAudioElement = document.createElement('audio');
this.bellAudioElement.setAttribute('preload', 'auto');
this.bellAudioElement.setAttribute('src', this.options.bellSound);
this.helperContainer.appendChild(this.bellAudioElement);
} else if (this.bellAudioElement) {
this.helperContainer.removeChild(this.bellAudioElement);
}
}
}
/**
+2 -3
View File
@@ -26,12 +26,11 @@ export type BooleanOption =
'cursorBlink' |
'debug' |
'disableStdin' |
'popOnBell' |
'screenKeys' |
'useFlowControl' |
'visualBell';
'useFlowControl';
export type StringOption =
'cursorStyle' |
'bellStyle' |
'termName';
export type StringArrayOption = 'colors';
export type NumberOption =
+9
View File
@@ -0,0 +1,9 @@
/**
* @license MIT
*/
// Source: https://freesound.org/people/altemark/sounds/45759/
// This sound is released under the Creative Commons Attribution 3.0 Unported
// (CC BY 3.0) license. It was created by 'altemark'. No modifications have been
// made, apart from the conversion to base64.
export const BellSound = 'data:audio/wav;base64,UklGRigBAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQBAADpAFgCwAMlBZoG/wdmCcoKRAypDQ8PbRDBEQQTOxRtFYcWlBePGIUZXhoiG88bcBz7HHIdzh0WHlMeZx51HmkeUx4WHs8dah0AHXwc3hs9G4saxRnyGBIYGBcQFv8U4RPAEoYRQBACD70NWwwHC6gJOwjWBloF7gOBAhABkf8b/qv8R/ve+Xf4Ife79W/0JfPZ8Z/wde9N7ijtE+wU6xvqM+lb6H7nw+YX5mrlxuQz5Mzje+Ma49fioeKD4nXiYeJy4pHitOL04j/jn+MN5IPkFOWs5U3mDefM55/ogOl36m7rdOyE7abuyu8D8Unyj/Pg9D/2qfcb+Yn6/vuK/Qj/lAAlAg==';
+4
View File
@@ -97,6 +97,10 @@ export class MockInputHandlingTerminal implements IInputHandlingTerminal {
throw new Error('Method not implemented.');
}
convertEol: boolean;
bell(): void {
throw new Error('Method not implemented.');
}
updateRange(y: number): void {
throw new Error('Method not implemented.');
}
+10
View File
@@ -91,6 +91,7 @@
.terminal .terminal-cursor {
position: relative;
transition: opacity 150ms ease;
}
.terminal:not(.focus) .terminal-cursor {
@@ -108,6 +109,7 @@
content: '';
position: absolute;
background-color: #fff;
transition: opacity 150ms ease;
}
.terminal.focus.xterm-cursor-style-bar:not(.xterm-cursor-blink-on) .terminal-cursor::before {
@@ -124,6 +126,14 @@
height: 1px;
}
.terminal.focus.xterm-cursor-style-block.visual-bell-active .terminal-cursor {
opacity: 0.5;
}
.terminal.focus.xterm-cursor-style-bar.visual-bell-active .terminal-cursor::before,
.terminal.focus.xterm-cursor-style-underline.visual-bell-active .terminal-cursor::before {
opacity: 0;
}
.terminal .composition-view {
background: #000;
color: #FFF;