@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2018 The xterm.js authors. All rights reserved.
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ITerminal, ISoundManager } from './Types';
|
||||||
|
|
||||||
|
// 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 DEFAULT_BELL_SOUND = 'data:audio/wav;base64,UklGRigBAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQBAADpAFgCwAMlBZoG/wdmCcoKRAypDQ8PbRDBEQQTOxRtFYcWlBePGIUZXhoiG88bcBz7HHIdzh0WHlMeZx51HmkeUx4WHs8dah0AHXwc3hs9G4saxRnyGBIYGBcQFv8U4RPAEoYRQBACD70NWwwHC6gJOwjWBloF7gOBAhABkf8b/qv8R/ve+Xf4Ife79W/0JfPZ8Z/wde9N7ijtE+wU6xvqM+lb6H7nw+YX5mrlxuQz5Mzje+Ma49fioeKD4nXiYeJy4pHitOL04j/jn+MN5IPkFOWs5U3mDefM55/ogOl36m7rdOyE7abuyu8D8Unyj/Pg9D/2qfcb+Yn6/vuK/Qj/lAAlAg==';
|
||||||
|
|
||||||
|
export class SoundManager implements ISoundManager {
|
||||||
|
private _audioContext: AudioContext;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private _terminal: ITerminal
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public playBellSound(): void {
|
||||||
|
const audioContextCtor: typeof AudioContext = (<any>window).AudioContext || (<any>window).webkitAudioContext;
|
||||||
|
if (!this._audioContext && audioContextCtor) {
|
||||||
|
this._audioContext = new audioContextCtor();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._audioContext) {
|
||||||
|
const bellAudioSource = this._audioContext.createBufferSource();
|
||||||
|
const context = this._audioContext;
|
||||||
|
this._audioContext.decodeAudioData(this.base64ToArrayBuffer(this.removeMimeType(this._terminal.options.bellSound)), (buffer) => {
|
||||||
|
bellAudioSource.buffer = buffer;
|
||||||
|
bellAudioSource.connect(context.destination);
|
||||||
|
bellAudioSource.start(0);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.warn('Sorry, but the Web Audio API is not supported by your browser. Please, consider upgrading to the latest version');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private base64ToArrayBuffer(base64: string): ArrayBuffer {
|
||||||
|
const binaryString = window.atob(base64);
|
||||||
|
const len = binaryString.length;
|
||||||
|
const bytes = new Uint8Array(len);
|
||||||
|
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
bytes[i] = binaryString.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private removeMimeType(dataURI: string): string {
|
||||||
|
// Split the input to get the mime-type and the data itself
|
||||||
|
const splitUri = dataURI.split(',');
|
||||||
|
|
||||||
|
// Return only the data
|
||||||
|
return splitUri[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-27
@@ -42,7 +42,7 @@ import * as Browser from './shared/utils/Browser';
|
|||||||
import * as Strings from './Strings';
|
import * as Strings from './Strings';
|
||||||
import { MouseHelper } from './utils/MouseHelper';
|
import { MouseHelper } from './utils/MouseHelper';
|
||||||
import { CHARSETS } from './Charsets';
|
import { CHARSETS } from './Charsets';
|
||||||
import { BELL_SOUND } from './utils/Sounds';
|
import { DEFAULT_BELL_SOUND, SoundManager } from './SoundManager';
|
||||||
import { DEFAULT_ANSI_COLORS } from './renderer/ColorManager';
|
import { DEFAULT_ANSI_COLORS } from './renderer/ColorManager';
|
||||||
import { MouseZoneManager } from './input/MouseZoneManager';
|
import { MouseZoneManager } from './input/MouseZoneManager';
|
||||||
import { AccessibilityManager } from './AccessibilityManager';
|
import { AccessibilityManager } from './AccessibilityManager';
|
||||||
@@ -100,7 +100,7 @@ const DEFAULT_OPTIONS: ITerminalOptions = {
|
|||||||
termName: 'xterm',
|
termName: 'xterm',
|
||||||
cursorBlink: false,
|
cursorBlink: false,
|
||||||
cursorStyle: 'block',
|
cursorStyle: 'block',
|
||||||
bellSound: BELL_SOUND,
|
bellSound: DEFAULT_BELL_SOUND,
|
||||||
bellStyle: 'none',
|
bellStyle: 'none',
|
||||||
enableBold: true,
|
enableBold: true,
|
||||||
fontFamily: 'courier-new, courier, monospace',
|
fontFamily: 'courier-new, courier, monospace',
|
||||||
@@ -142,7 +142,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
|
|||||||
private helperContainer: HTMLElement;
|
private helperContainer: HTMLElement;
|
||||||
private compositionView: HTMLElement;
|
private compositionView: HTMLElement;
|
||||||
private charSizeStyleElement: HTMLStyleElement;
|
private charSizeStyleElement: HTMLStyleElement;
|
||||||
private bellAudioElement: HTMLAudioElement;
|
|
||||||
private visualBellTimer: number;
|
private visualBellTimer: number;
|
||||||
|
|
||||||
public browser: IBrowser = <any>Browser;
|
public browser: IBrowser = <any>Browser;
|
||||||
@@ -224,6 +224,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
|
|||||||
private userScrolling: boolean;
|
private userScrolling: boolean;
|
||||||
|
|
||||||
private inputHandler: InputHandler;
|
private inputHandler: InputHandler;
|
||||||
|
public soundManager: SoundManager;
|
||||||
private parser: Parser;
|
private parser: Parser;
|
||||||
public renderer: IRenderer;
|
public renderer: IRenderer;
|
||||||
public selectionManager: SelectionManager;
|
public selectionManager: SelectionManager;
|
||||||
@@ -328,6 +329,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
|
|||||||
this.selectionManager = this.selectionManager || null;
|
this.selectionManager = this.selectionManager || null;
|
||||||
this.linkifier = this.linkifier || new Linkifier(this);
|
this.linkifier = this.linkifier || new Linkifier(this);
|
||||||
this._mouseZoneManager = this._mouseZoneManager || null;
|
this._mouseZoneManager = this._mouseZoneManager || null;
|
||||||
|
this.soundManager = this.soundManager || new SoundManager(this);
|
||||||
|
|
||||||
// Create the terminal's buffers and set the current buffer
|
// Create the terminal's buffers and set the current buffer
|
||||||
this.buffers = new BufferSet(this);
|
this.buffers = new BufferSet(this);
|
||||||
@@ -493,8 +495,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'tabStopWidth': this.buffers.setupTabStops(); break;
|
case 'tabStopWidth': this.buffers.setupTabStops(); break;
|
||||||
case 'bellSound':
|
|
||||||
case 'bellStyle': this.syncBellSound(); break;
|
|
||||||
}
|
}
|
||||||
// Inform renderer of changes
|
// Inform renderer of changes
|
||||||
if (this.renderer) {
|
if (this.renderer) {
|
||||||
@@ -693,9 +693,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
|
|||||||
this.helperContainer.appendChild(this.charSizeStyleElement);
|
this.helperContainer.appendChild(this.charSizeStyleElement);
|
||||||
this.charMeasure = new CharMeasure(document, this.helperContainer);
|
this.charMeasure = new CharMeasure(document, this.helperContainer);
|
||||||
|
|
||||||
// Preload audio, this relied on helperContainer
|
|
||||||
this.syncBellSound();
|
|
||||||
|
|
||||||
// Performance: Add viewport and helper elements from the fragment
|
// Performance: Add viewport and helper elements from the fragment
|
||||||
this.element.appendChild(fragment);
|
this.element.appendChild(fragment);
|
||||||
|
|
||||||
@@ -1894,7 +1891,9 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
|
|||||||
*/
|
*/
|
||||||
public bell(): void {
|
public bell(): void {
|
||||||
this.emit('bell');
|
this.emit('bell');
|
||||||
if (this.soundBell()) this.bellAudioElement.play();
|
if (this.soundBell()) {
|
||||||
|
this.soundManager.playBellSound();
|
||||||
|
}
|
||||||
|
|
||||||
if (this.visualBell()) {
|
if (this.visualBell()) {
|
||||||
this.element.classList.add('visual-bell-active');
|
this.element.classList.add('visual-bell-active');
|
||||||
@@ -2215,24 +2214,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
|
|||||||
// return this.options.bellStyle === 'sound' ||
|
// return this.options.bellStyle === 'sound' ||
|
||||||
// this.options.bellStyle === 'both';
|
// this.options.bellStyle === 'both';
|
||||||
}
|
}
|
||||||
|
|
||||||
private syncBellSound(): void {
|
|
||||||
// Don't update anything if the terminal has not been opened yet
|
|
||||||
if (!this.element) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.soundBell() && this.bellAudioElement) {
|
|
||||||
this.bellAudioElement.setAttribute('src', this.options.bellSound);
|
|
||||||
} else 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -349,3 +349,7 @@ export interface IBrowser {
|
|||||||
isIphone: boolean;
|
isIphone: boolean;
|
||||||
isMSWindows: boolean;
|
isMSWindows: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ISoundManager {
|
||||||
|
playBellSound(): void;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
|
||||||
* @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 BELL_SOUND = 'data:audio/wav;base64,UklGRigBAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQBAADpAFgCwAMlBZoG/wdmCcoKRAypDQ8PbRDBEQQTOxRtFYcWlBePGIUZXhoiG88bcBz7HHIdzh0WHlMeZx51HmkeUx4WHs8dah0AHXwc3hs9G4saxRnyGBIYGBcQFv8U4RPAEoYRQBACD70NWwwHC6gJOwjWBloF7gOBAhABkf8b/qv8R/ve+Xf4Ife79W/0JfPZ8Z/wde9N7ijtE+wU6xvqM+lb6H7nw+YX5mrlxuQz5Mzje+Ma49fioeKD4nXiYeJy4pHitOL04j/jn+MN5IPkFOWs5U3mDefM55/ogOl36m7rdOyE7abuyu8D8Unyj/Pg9D/2qfcb+Yn6/vuK/Qj/lAAlAg==';
|
|
||||||
Reference in New Issue
Block a user