UNPKG

jodit

Version:

Jodit is an awesome and useful wysiwyg editor with filebrowser

70 lines (69 loc) 2.18 kB
/*! * Jodit Editor (https://xdsoft.net/jodit/) * Released under MIT see LICENSE.txt in the project root for license information. * Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net */ /** * @module plugins/speech-recognize */ import { globalWindow } from "../../../core/constants.js"; import { PII } from "../constants.js"; /** * One AudioContext per owner (e.g. a RecognizeManager). Previously a new context * was created on every beep and never closed, so during continuous recognition * they piled up — leaking until the browser's per-page limit was hit and the * overlapping audio turned into a "roar". We now reuse a single context per * owner and release it via {@link closeSound} when the owner is destroyed. * @internal */ const contexts = new WeakMap(); function getContext(owner) { if (!globalWindow) { return null; } const existing = contexts.get(owner); if (existing && existing.state !== 'closed') { return existing; } const Ctor = globalWindow.AudioContext || globalWindow.webkitAudioContext; if (!Ctor) { return null; } const context = new Ctor(); contexts.set(owner, context); return context; } /** * Play a short beep on the owner's (lazily created, reused) AudioContext. * @internal */ export function sound(owner, { sec = 0.1, frequency = PII, gain = 0.1, type = 'sine' } = {}) { const context = getContext(owner); if (!context) { return; } const vol = context.createGain(); const osc = context.createOscillator(); osc.type = type; osc.frequency.value = frequency; // Hz vol.gain.value = gain; osc.connect(vol); vol.connect(context.destination); osc.start(); // start the oscillator osc.stop(context.currentTime + sec); } /** * Close and forget the owner's AudioContext. Call this when the owner is * destroyed so the context does not leak. * @internal */ export function closeSound(owner) { const context = contexts.get(owner); if (context) { contexts.delete(owner); if (context.state !== 'closed') { void context.close(); } } }