/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; import * as aria from '../../../base/browser/ui/aria/aria.js'; import { Disposable, toDisposable, DisposableStore } from '../../../base/common/lifecycle.js'; import { ICodeEditorService } from '../../browser/services/codeEditorService.js'; import { CodeEditorWidget } from '../../browser/widget/codeEditorWidget.js'; import { DiffEditorWidget } from '../../browser/widget/diffEditorWidget.js'; import { InternalEditorAction } from '../../common/editorAction.js'; import { IEditorWorkerService } from '../../common/services/editorWorker.js'; import { StandaloneKeybindingService, updateConfigurationService } from './standaloneServices.js'; import { IStandaloneThemeService } from '../common/standaloneTheme.js'; import { MenuId, MenuRegistry } from '../../../platform/actions/common/actions.js'; import { CommandsRegistry, ICommandService } from '../../../platform/commands/common/commands.js'; import { IConfigurationService } from '../../../platform/configuration/common/configuration.js'; import { ContextKeyExpr, IContextKeyService } from '../../../platform/contextkey/common/contextkey.js'; import { IContextMenuService } from '../../../platform/contextview/browser/contextView.js'; import { IInstantiationService } from '../../../platform/instantiation/common/instantiation.js'; import { IKeybindingService } from '../../../platform/keybinding/common/keybinding.js'; import { INotificationService } from '../../../platform/notification/common/notification.js'; import { IThemeService } from '../../../platform/theme/common/themeService.js'; import { IAccessibilityService } from '../../../platform/accessibility/common/accessibility.js'; import { StandaloneCodeEditorNLS } from '../../common/standaloneStrings.js'; import { IClipboardService } from '../../../platform/clipboard/common/clipboardService.js'; import { IEditorProgressService } from '../../../platform/progress/common/progress.js'; import { IModelService } from '../../common/services/model.js'; import { ILanguageService } from '../../common/languages/language.js'; import { StandaloneCodeEditorService } from './standaloneCodeEditorService.js'; import { PLAINTEXT_LANGUAGE_ID } from '../../common/languages/modesRegistry.js'; import { ILanguageConfigurationService } from '../../common/languages/languageConfigurationRegistry.js'; import { ILanguageFeaturesService } from '../../common/services/languageFeatures.js'; let LAST_GENERATED_COMMAND_ID = 0; let ariaDomNodeCreated = false; /** * Create ARIA dom node inside parent, * or only for the first editor instantiation inside document.body. * @param parent container element for ARIA dom node */ function createAriaDomNode(parent) { if (!parent) { if (ariaDomNodeCreated) { return; } ariaDomNodeCreated = true; } aria.setARIAContainer(parent || document.body); } /** * A code editor to be used both by the standalone editor and the standalone diff editor. */ let StandaloneCodeEditor = class StandaloneCodeEditor extends CodeEditorWidget { constructor(domElement, _options, instantiationService, codeEditorService, commandService, contextKeyService, keybindingService, themeService, notificationService, accessibilityService, languageConfigurationService, languageFeaturesService) { const options = Object.assign({}, _options); options.ariaLabel = options.ariaLabel || StandaloneCodeEditorNLS.editorViewAccessibleLabel; options.ariaLabel = options.ariaLabel + ';' + (StandaloneCodeEditorNLS.accessibilityHelpMessage); super(domElement, options, {}, instantiationService, codeEditorService, commandService, contextKeyService, themeService, notificationService, accessibilityService, languageConfigurationService, languageFeaturesService); if (keybindingService instanceof StandaloneKeybindingService) { this._standaloneKeybindingService = keybindingService; } else { this._standaloneKeybindingService = null; } createAriaDomNode(options.ariaContainerElement); } addCommand(keybinding, handler, context) { if (!this._standaloneKeybindingService) { console.warn('Cannot add command because the editor is configured with an unrecognized KeybindingService'); return null; } const commandId = 'DYNAMIC_' + (++LAST_GENERATED_COMMAND_ID); const whenExpression = ContextKeyExpr.deserialize(context); this._standaloneKeybindingService.addDynamicKeybinding(commandId, keybinding, handler, whenExpression); return commandId; } createContextKey(key, defaultValue) { return this._contextKeyService.createKey(key, defaultValue); } addAction(_descriptor) { if ((typeof _descriptor.id !== 'string') || (typeof _descriptor.label !== 'string') || (typeof _descriptor.run !== 'function')) { throw new Error('Invalid action descriptor, `id`, `label` and `run` are required properties!'); } if (!this._standaloneKeybindingService) { console.warn('Cannot add keybinding because the editor is configured with an unrecognized KeybindingService'); return Disposable.None; } // Read descriptor options const id = _descriptor.id; const label = _descriptor.label; const precondition = ContextKeyExpr.and(ContextKeyExpr.equals('editorId', this.getId()), ContextKeyExpr.deserialize(_descriptor.precondition)); const keybindings = _descriptor.keybindings; const keybindingsWhen = ContextKeyExpr.and(precondition, ContextKeyExpr.deserialize(_descriptor.keybindingContext)); const contextMenuGroupId = _descriptor.contextMenuGroupId || null; const contextMenuOrder = _descriptor.contextMenuOrder || 0; const run = (accessor, ...args) => { return Promise.resolve(_descriptor.run(this, ...args)); }; const toDispose = new DisposableStore(); // Generate a unique id to allow the same descriptor.id across multiple editor instances const uniqueId = this.getId() + ':' + id; // Register the command toDispose.add(CommandsRegistry.registerCommand(uniqueId, run)); // Register the context menu item if (contextMenuGroupId) { const menuItem = { command: { id: uniqueId, title: label }, when: precondition, group: contextMenuGroupId, order: contextMenuOrder }; toDispose.add(MenuRegistry.appendMenuItem(MenuId.EditorContext, menuItem)); } // Register the keybindings if (Array.isArray(keybindings)) { for (const kb of keybindings) { toDispose.add(this._standaloneKeybindingService.addDynamicKeybinding(uniqueId, kb, run, keybindingsWhen)); } } // Finally, register an internal editor action const internalAction = new InternalEditorAction(uniqueId, label, label, precondition, run, this._contextKeyService); // Store it under the original id, such that trigger with the original id will work this._actions[id] = internalAction; toDispose.add(toDisposable(() => { delete this._actions[id]; })); return toDispose; } _triggerCommand(handlerId, payload) { if (this._codeEditorService instanceof StandaloneCodeEditorService) { // Help commands find this editor as the active editor try { this._codeEditorService.setActiveCodeEditor(this); super._triggerCommand(handlerId, payload); } finally { this._codeEditorService.setActiveCodeEditor(null); } } else { super._triggerCommand(handlerId, payload); } } }; StandaloneCodeEditor = __decorate([ __param(2, IInstantiationService), __param(3, ICodeEditorService), __param(4, ICommandService), __param(5, IContextKeyService), __param(6, IKeybindingService), __param(7, IThemeService), __param(8, INotificationService), __param(9, IAccessibilityService), __param(10, ILanguageConfigurationService), __param(11, ILanguageFeaturesService) ], StandaloneCodeEditor); export { StandaloneCodeEditor }; let StandaloneEditor = class StandaloneEditor extends StandaloneCodeEditor { constructor(domElement, _options, instantiationService, codeEditorService, commandService, contextKeyService, keybindingService, themeService, notificationService, configurationService, accessibilityService, modelService, languageService, languageConfigurationService, languageFeaturesService) { const options = Object.assign({}, _options); updateConfigurationService(configurationService, options, false); const themeDomRegistration = themeService.registerEditorContainer(domElement); if (typeof options.theme === 'string') { themeService.setTheme(options.theme); } if (typeof options.autoDetectHighContrast !== 'undefined') { themeService.setAutoDetectHighContrast(Boolean(options.autoDetectHighContrast)); } const _model = options.model; delete options.model; super(domElement, options, instantiationService, codeEditorService, commandService, contextKeyService, keybindingService, themeService, notificationService, accessibilityService, languageConfigurationService, languageFeaturesService); this._configurationService = configurationService; this._standaloneThemeService = themeService; this._register(themeDomRegistration); let model; if (typeof _model === 'undefined') { const languageId = languageService.getLanguageIdByMimeType(options.language) || options.language || PLAINTEXT_LANGUAGE_ID; model = createTextModel(modelService, languageService, options.value || '', languageId, undefined); this._ownsModel = true; } else { model = _model; this._ownsModel = false; } this._attachModel(model); if (model) { const e = { oldModelUrl: null, newModelUrl: model.uri }; this._onDidChangeModel.fire(e); } } dispose() { super.dispose(); } updateOptions(newOptions) { updateConfigurationService(this._configurationService, newOptions, false); if (typeof newOptions.theme === 'string') { this._standaloneThemeService.setTheme(newOptions.theme); } if (typeof newOptions.autoDetectHighContrast !== 'undefined') { this._standaloneThemeService.setAutoDetectHighContrast(Boolean(newOptions.autoDetectHighContrast)); } super.updateOptions(newOptions); } _postDetachModelCleanup(detachedModel) { super._postDetachModelCleanup(detachedModel); if (detachedModel && this._ownsModel) { detachedModel.dispose(); this._ownsModel = false; } } }; StandaloneEditor = __decorate([ __param(2, IInstantiationService), __param(3, ICodeEditorService), __param(4, ICommandService), __param(5, IContextKeyService), __param(6, IKeybindingService), __param(7, IStandaloneThemeService), __param(8, INotificationService), __param(9, IConfigurationService), __param(10, IAccessibilityService), __param(11, IModelService), __param(12, ILanguageService), __param(13, ILanguageConfigurationService), __param(14, ILanguageFeaturesService) ], StandaloneEditor); export { StandaloneEditor }; let StandaloneDiffEditor = class StandaloneDiffEditor extends DiffEditorWidget { constructor(domElement, _options, instantiationService, contextKeyService, editorWorkerService, codeEditorService, themeService, notificationService, configurationService, contextMenuService, editorProgressService, clipboardService) { const options = Object.assign({}, _options); updateConfigurationService(configurationService, options, true); const themeDomRegistration = themeService.registerEditorContainer(domElement); if (typeof options.theme === 'string') { themeService.setTheme(options.theme); } if (typeof options.autoDetectHighContrast !== 'undefined') { themeService.setAutoDetectHighContrast(Boolean(options.autoDetectHighContrast)); } super(domElement, options, {}, clipboardService, editorWorkerService, contextKeyService, instantiationService, codeEditorService, themeService, notificationService, contextMenuService, editorProgressService); this._configurationService = configurationService; this._standaloneThemeService = themeService; this._register(themeDomRegistration); } dispose() { super.dispose(); } updateOptions(newOptions) { updateConfigurationService(this._configurationService, newOptions, true); if (typeof newOptions.theme === 'string') { this._standaloneThemeService.setTheme(newOptions.theme); } if (typeof newOptions.autoDetectHighContrast !== 'undefined') { this._standaloneThemeService.setAutoDetectHighContrast(Boolean(newOptions.autoDetectHighContrast)); } super.updateOptions(newOptions); } _createInnerEditor(instantiationService, container, options) { return instantiationService.createInstance(StandaloneCodeEditor, container, options); } getOriginalEditor() { return super.getOriginalEditor(); } getModifiedEditor() { return super.getModifiedEditor(); } addCommand(keybinding, handler, context) { return this.getModifiedEditor().addCommand(keybinding, handler, context); } createContextKey(key, defaultValue) { return this.getModifiedEditor().createContextKey(key, defaultValue); } addAction(descriptor) { return this.getModifiedEditor().addAction(descriptor); } }; StandaloneDiffEditor = __decorate([ __param(2, IInstantiationService), __param(3, IContextKeyService), __param(4, IEditorWorkerService), __param(5, ICodeEditorService), __param(6, IStandaloneThemeService), __param(7, INotificationService), __param(8, IConfigurationService), __param(9, IContextMenuService), __param(10, IEditorProgressService), __param(11, IClipboardService) ], StandaloneDiffEditor); export { StandaloneDiffEditor }; /** * @internal */ export function createTextModel(modelService, languageService, value, languageId, uri) { value = value || ''; if (!languageId) { const firstLF = value.indexOf('\n'); let firstLine = value; if (firstLF !== -1) { firstLine = value.substring(0, firstLF); } return doCreateModel(modelService, value, languageService.createByFilepathOrFirstLine(uri || null, firstLine), uri); } return doCreateModel(modelService, value, languageService.createById(languageId), uri); } /** * @internal */ function doCreateModel(modelService, value, languageSelection, uri) { return modelService.createModel(value, languageSelection, uri); }