UNPKG

monaco-editor-core

Version:

A browser based code editor

103 lines (102 loc) 4 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { show } from '../../dom.js'; import { RunOnceScheduler } from '../../../common/async.js'; import { Disposable, MutableDisposable } from '../../../common/lifecycle.js'; import './progressbar.css'; const CSS_DONE = 'done'; const CSS_ACTIVE = 'active'; const CSS_INFINITE = 'infinite'; const CSS_INFINITE_LONG_RUNNING = 'infinite-long-running'; const CSS_DISCRETE = 'discrete'; /** * A progress bar with support for infinite or discrete progress. */ export class ProgressBar extends Disposable { /** * After a certain time of showing the progress bar, switch * to long-running mode and throttle animations to reduce * the pressure on the GPU process. * * https://github.com/microsoft/vscode/issues/97900 * https://github.com/microsoft/vscode/issues/138396 */ static { this.LONG_RUNNING_INFINITE_THRESHOLD = 10000; } constructor(container, options) { super(); this.progressSignal = this._register(new MutableDisposable()); this.workedVal = 0; this.showDelayedScheduler = this._register(new RunOnceScheduler(() => show(this.element), 0)); this.longRunningScheduler = this._register(new RunOnceScheduler(() => this.infiniteLongRunning(), ProgressBar.LONG_RUNNING_INFINITE_THRESHOLD)); this.create(container, options); } create(container, options) { this.element = document.createElement('div'); this.element.classList.add('monaco-progress-container'); this.element.setAttribute('role', 'progressbar'); this.element.setAttribute('aria-valuemin', '0'); container.appendChild(this.element); this.bit = document.createElement('div'); this.bit.classList.add('progress-bit'); this.bit.style.backgroundColor = options?.progressBarBackground || '#0E70C0'; this.element.appendChild(this.bit); } off() { this.bit.style.width = 'inherit'; this.bit.style.opacity = '1'; this.element.classList.remove(CSS_ACTIVE, CSS_INFINITE, CSS_INFINITE_LONG_RUNNING, CSS_DISCRETE); this.workedVal = 0; this.totalWork = undefined; this.longRunningScheduler.cancel(); this.progressSignal.clear(); } /** * Stops the progressbar from showing any progress instantly without fading out. */ stop() { return this.doDone(false); } doDone(delayed) { this.element.classList.add(CSS_DONE); // discrete: let it grow to 100% width and hide afterwards if (!this.element.classList.contains(CSS_INFINITE)) { this.bit.style.width = 'inherit'; if (delayed) { setTimeout(() => this.off(), 200); } else { this.off(); } } // infinite: let it fade out and hide afterwards else { this.bit.style.opacity = '0'; if (delayed) { setTimeout(() => this.off(), 200); } else { this.off(); } } return this; } /** * Use this mode to indicate progress that has no total number of work units. */ infinite() { this.bit.style.width = '2%'; this.bit.style.opacity = '1'; this.element.classList.remove(CSS_DISCRETE, CSS_DONE, CSS_INFINITE_LONG_RUNNING); this.element.classList.add(CSS_ACTIVE, CSS_INFINITE); this.longRunningScheduler.schedule(); return this; } infiniteLongRunning() { this.element.classList.add(CSS_INFINITE_LONG_RUNNING); } getContainer() { return this.element; } }