monaco-editor-core
Version:
A browser based code editor
103 lines (102 loc) • 4 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* 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;
}
}