@21epub/epub-thirdparty
Version:
epub-thirdparty
102 lines (101 loc) • 4.66 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 { Emitter } from '../../../base/common/event.js';
import { Disposable } from '../../../base/common/lifecycle.js';
import { NULL_MODE_ID } from '../modes/nullMode.js';
import { LanguagesRegistry } from './languagesRegistry.js';
import { firstOrDefault } from '../../../base/common/arrays.js';
class LanguageSelection {
constructor(onLanguagesMaybeChanged, selector) {
this._selector = selector;
this.languageId = this._selector();
let listener;
this._onDidChange = new Emitter({
onFirstListenerAdd: () => {
listener = onLanguagesMaybeChanged(() => this._evaluate());
},
onLastListenerRemove: () => {
listener.dispose();
}
});
this.onDidChange = this._onDidChange.event;
}
_evaluate() {
const languageId = this._selector();
if (languageId === this.languageId) {
// no change
return;
}
this.languageId = languageId;
this._onDidChange.fire(this.languageId);
}
}
export class ModeServiceImpl extends Disposable {
constructor(warnOnOverwrite = false) {
super();
this._onDidEncounterLanguage = this._register(new Emitter());
this.onDidEncounterLanguage = this._onDidEncounterLanguage.event;
this._onLanguagesMaybeChanged = this._register(new Emitter({ leakWarningThreshold: 200 /* https://github.com/microsoft/vscode/issues/119968 */ }));
this.onLanguagesMaybeChanged = this._onLanguagesMaybeChanged.event;
ModeServiceImpl.instanceCount++;
this._encounteredLanguages = new Set();
this._registry = this._register(new LanguagesRegistry(true, warnOnOverwrite));
this.languageIdCodec = this._registry.languageIdCodec;
this._register(this._registry.onDidChange(() => this._onLanguagesMaybeChanged.fire()));
}
dispose() {
ModeServiceImpl.instanceCount--;
super.dispose();
}
isRegisteredMode(mimetypeOrModeId) {
return this._registry.isRegisteredMode(mimetypeOrModeId);
}
getModeIdForLanguageName(alias) {
return this._registry.getModeIdForLanguageNameLowercase(alias);
}
getModeIdByFilepathOrFirstLine(resource, firstLine) {
const modeIds = this._registry.getModeIdsFromFilepathOrFirstLine(resource, firstLine);
return firstOrDefault(modeIds, null);
}
getModeId(commaSeparatedMimetypesOrCommaSeparatedIds) {
const modeIds = this._registry.extractModeIds(commaSeparatedMimetypesOrCommaSeparatedIds);
return firstOrDefault(modeIds, null);
}
validateLanguageId(languageId) {
return this._registry.validateLanguageId(languageId);
}
// --- instantiation
create(commaSeparatedMimetypesOrCommaSeparatedIds) {
return new LanguageSelection(this.onLanguagesMaybeChanged, () => {
const languageId = this.getModeId(commaSeparatedMimetypesOrCommaSeparatedIds);
return this._createModeAndGetLanguageIdentifier(languageId);
});
}
createByFilepathOrFirstLine(resource, firstLine) {
return new LanguageSelection(this.onLanguagesMaybeChanged, () => {
const languageId = this.getModeIdByFilepathOrFirstLine(resource, firstLine);
return this._createModeAndGetLanguageIdentifier(languageId);
});
}
_createModeAndGetLanguageIdentifier(languageId) {
// Fall back to plain text if no mode was found
const validLanguageId = this.validateLanguageId(languageId || 'plaintext') || NULL_MODE_ID;
this._getOrCreateMode(validLanguageId);
return validLanguageId;
}
triggerMode(commaSeparatedMimetypesOrCommaSeparatedIds) {
const languageId = this.getModeId(commaSeparatedMimetypesOrCommaSeparatedIds);
// Fall back to plain text if no mode was found
this._getOrCreateMode(languageId || 'plaintext');
}
_getOrCreateMode(languageId) {
if (!this._encounteredLanguages.has(languageId)) {
this._encounteredLanguages.add(languageId);
const validLanguageId = this.validateLanguageId(languageId) || NULL_MODE_ID;
this._onDidEncounterLanguage.fire(validLanguageId);
}
}
}
ModeServiceImpl.instanceCount = 0;