UNPKG

@21epub/epub-thirdparty

Version:
1,153 lines (1,152 loc) 70.9 kB
/*--------------------------------------------------------------------------------------------- * 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 '../services/markerDecorations.js'; import './media/editor.css'; import * as nls from '../../../nls.js'; import * as dom from '../../../base/browser/dom.js'; import { onUnexpectedError } from '../../../base/common/errors.js'; import { Emitter } from '../../../base/common/event.js'; import { Disposable, dispose } from '../../../base/common/lifecycle.js'; import { Schemas } from '../../../base/common/network.js'; import { Configuration } from '../config/configuration.js'; import { EditorExtensionsRegistry } from '../editorExtensions.js'; import { ICodeEditorService } from '../services/codeEditorService.js'; import { View } from '../view/viewImpl.js'; import { ViewUserInputEvents } from '../view/viewUserInputEvents.js'; import { filterValidationDecorations } from '../../common/config/editorOptions.js'; import { CursorsController } from '../../common/controller/cursor.js'; import { CursorColumns } from '../../common/controller/cursorCommon.js'; import { Position } from '../../common/core/position.js'; import { Range } from '../../common/core/range.js'; import { Selection } from '../../common/core/selection.js'; import { InternalEditorAction } from '../../common/editorAction.js'; import * as editorCommon from '../../common/editorCommon.js'; import { EditorContextKeys } from '../../common/editorContextKeys.js'; import * as modes from '../../common/modes.js'; import { editorUnnecessaryCodeBorder, editorUnnecessaryCodeOpacity } from '../../common/view/editorColorRegistry.js'; import { editorErrorBorder, editorErrorForeground, editorHintBorder, editorHintForeground, editorInfoBorder, editorInfoForeground, editorWarningBorder, editorWarningForeground, editorForeground, editorErrorBackground, editorInfoBackground, editorWarningBackground } from '../../../platform/theme/common/colorRegistry.js'; import { ViewModel } from '../../common/viewModel/viewModelImpl.js'; import { ICommandService } from '../../../platform/commands/common/commands.js'; import { IContextKeyService } from '../../../platform/contextkey/common/contextkey.js'; import { IInstantiationService } from '../../../platform/instantiation/common/instantiation.js'; import { ServiceCollection } from '../../../platform/instantiation/common/serviceCollection.js'; import { INotificationService } from '../../../platform/notification/common/notification.js'; import { IThemeService, registerThemingParticipant } from '../../../platform/theme/common/themeService.js'; import { IAccessibilityService } from '../../../platform/accessibility/common/accessibility.js'; import { withNullAsUndefined } from '../../../base/common/types.js'; import { MonospaceLineBreaksComputerFactory } from '../../common/viewModel/monospaceLineBreaksComputer.js'; import { DOMLineBreaksComputerFactory } from '../view/domLineBreaksComputer.js'; import { WordOperations } from '../../common/controller/cursorWordOperations.js'; let EDITOR_ID = 0; class ModelData { constructor(model, viewModel, view, hasRealView, listenersToRemove) { this.model = model; this.viewModel = viewModel; this.view = view; this.hasRealView = hasRealView; this.listenersToRemove = listenersToRemove; } dispose() { dispose(this.listenersToRemove); this.model.onBeforeDetached(); if (this.hasRealView) { this.view.dispose(); } this.viewModel.dispose(); } } let CodeEditorWidget = class CodeEditorWidget extends Disposable { constructor(domElement, _options, codeEditorWidgetOptions, instantiationService, codeEditorService, commandService, contextKeyService, themeService, notificationService, accessibilityService) { super(); //#region Eventing this._onDidDispose = this._register(new Emitter()); this.onDidDispose = this._onDidDispose.event; this._onDidChangeModelContent = this._register(new Emitter()); this.onDidChangeModelContent = this._onDidChangeModelContent.event; this._onDidChangeModelLanguage = this._register(new Emitter()); this.onDidChangeModelLanguage = this._onDidChangeModelLanguage.event; this._onDidChangeModelLanguageConfiguration = this._register(new Emitter()); this.onDidChangeModelLanguageConfiguration = this._onDidChangeModelLanguageConfiguration.event; this._onDidChangeModelOptions = this._register(new Emitter()); this.onDidChangeModelOptions = this._onDidChangeModelOptions.event; this._onDidChangeModelDecorations = this._register(new Emitter()); this.onDidChangeModelDecorations = this._onDidChangeModelDecorations.event; this._onDidChangeConfiguration = this._register(new Emitter()); this.onDidChangeConfiguration = this._onDidChangeConfiguration.event; this._onDidChangeModel = this._register(new Emitter()); this.onDidChangeModel = this._onDidChangeModel.event; this._onDidChangeCursorPosition = this._register(new Emitter()); this.onDidChangeCursorPosition = this._onDidChangeCursorPosition.event; this._onDidChangeCursorSelection = this._register(new Emitter()); this.onDidChangeCursorSelection = this._onDidChangeCursorSelection.event; this._onDidAttemptReadOnlyEdit = this._register(new Emitter()); this.onDidAttemptReadOnlyEdit = this._onDidAttemptReadOnlyEdit.event; this._onDidLayoutChange = this._register(new Emitter()); this.onDidLayoutChange = this._onDidLayoutChange.event; this._editorTextFocus = this._register(new BooleanEventEmitter()); this.onDidFocusEditorText = this._editorTextFocus.onDidChangeToTrue; this.onDidBlurEditorText = this._editorTextFocus.onDidChangeToFalse; this._editorWidgetFocus = this._register(new BooleanEventEmitter()); this.onDidFocusEditorWidget = this._editorWidgetFocus.onDidChangeToTrue; this.onDidBlurEditorWidget = this._editorWidgetFocus.onDidChangeToFalse; this._onWillType = this._register(new Emitter()); this.onWillType = this._onWillType.event; this._onDidType = this._register(new Emitter()); this.onDidType = this._onDidType.event; this._onDidCompositionStart = this._register(new Emitter()); this.onDidCompositionStart = this._onDidCompositionStart.event; this._onDidCompositionEnd = this._register(new Emitter()); this.onDidCompositionEnd = this._onDidCompositionEnd.event; this._onDidPaste = this._register(new Emitter()); this.onDidPaste = this._onDidPaste.event; this._onMouseUp = this._register(new Emitter()); this.onMouseUp = this._onMouseUp.event; this._onMouseDown = this._register(new Emitter()); this.onMouseDown = this._onMouseDown.event; this._onMouseDrag = this._register(new Emitter()); this.onMouseDrag = this._onMouseDrag.event; this._onMouseDrop = this._register(new Emitter()); this.onMouseDrop = this._onMouseDrop.event; this._onMouseDropCanceled = this._register(new Emitter()); this.onMouseDropCanceled = this._onMouseDropCanceled.event; this._onContextMenu = this._register(new Emitter()); this.onContextMenu = this._onContextMenu.event; this._onMouseMove = this._register(new Emitter()); this.onMouseMove = this._onMouseMove.event; this._onMouseLeave = this._register(new Emitter()); this.onMouseLeave = this._onMouseLeave.event; this._onMouseWheel = this._register(new Emitter()); this.onMouseWheel = this._onMouseWheel.event; this._onKeyUp = this._register(new Emitter()); this.onKeyUp = this._onKeyUp.event; this._onKeyDown = this._register(new Emitter()); this.onKeyDown = this._onKeyDown.event; this._onDidContentSizeChange = this._register(new Emitter()); this.onDidContentSizeChange = this._onDidContentSizeChange.event; this._onDidScrollChange = this._register(new Emitter()); this.onDidScrollChange = this._onDidScrollChange.event; this._onDidChangeViewZones = this._register(new Emitter()); this.onDidChangeViewZones = this._onDidChangeViewZones.event; this._onDidChangeHiddenAreas = this._register(new Emitter()); this.onDidChangeHiddenAreas = this._onDidChangeHiddenAreas.event; const options = Object.assign({}, _options); this._domElement = domElement; this._overflowWidgetsDomNode = options.overflowWidgetsDomNode; delete options.overflowWidgetsDomNode; this._id = (++EDITOR_ID); this._decorationTypeKeysToIds = {}; this._decorationTypeSubtypes = {}; this.isSimpleWidget = codeEditorWidgetOptions.isSimpleWidget || false; this._telemetryData = codeEditorWidgetOptions.telemetryData; this._configuration = this._register(this._createConfiguration(options, accessibilityService)); this._register(this._configuration.onDidChange((e) => { this._onDidChangeConfiguration.fire(e); const options = this._configuration.options; if (e.hasChanged(129 /* layoutInfo */)) { const layoutInfo = options.get(129 /* layoutInfo */); this._onDidLayoutChange.fire(layoutInfo); } })); this._contextKeyService = this._register(contextKeyService.createScoped(this._domElement)); this._notificationService = notificationService; this._codeEditorService = codeEditorService; this._commandService = commandService; this._themeService = themeService; this._register(new EditorContextKeysManager(this, this._contextKeyService)); this._register(new EditorModeContext(this, this._contextKeyService)); this._instantiationService = instantiationService.createChild(new ServiceCollection([IContextKeyService, this._contextKeyService])); this._modelData = null; this._contributions = {}; this._actions = {}; this._focusTracker = new CodeEditorWidgetFocusTracker(domElement); this._register(this._focusTracker.onChange(() => { this._editorWidgetFocus.setValue(this._focusTracker.hasFocus()); })); this._contentWidgets = {}; this._overlayWidgets = {}; let contributions; if (Array.isArray(codeEditorWidgetOptions.contributions)) { contributions = codeEditorWidgetOptions.contributions; } else { contributions = EditorExtensionsRegistry.getEditorContributions(); } for (const desc of contributions) { if (this._contributions[desc.id]) { onUnexpectedError(new Error(`Cannot have two contributions with the same id ${desc.id}`)); continue; } try { const contribution = this._instantiationService.createInstance(desc.ctor, this); this._contributions[desc.id] = contribution; } catch (err) { onUnexpectedError(err); } } EditorExtensionsRegistry.getEditorActions().forEach((action) => { if (this._actions[action.id]) { onUnexpectedError(new Error(`Cannot have two actions with the same id ${action.id}`)); return; } const internalAction = new InternalEditorAction(action.id, action.label, action.alias, withNullAsUndefined(action.precondition), () => { return this._instantiationService.invokeFunction((accessor) => { return Promise.resolve(action.runEditorCommand(accessor, this, null)); }); }, this._contextKeyService); this._actions[internalAction.id] = internalAction; }); this._codeEditorService.addCodeEditor(this); } _createConfiguration(options, accessibilityService) { return new Configuration(this.isSimpleWidget, options, this._domElement, accessibilityService); } getId() { return this.getEditorType() + ':' + this._id; } getEditorType() { return editorCommon.EditorType.ICodeEditor; } dispose() { this._codeEditorService.removeCodeEditor(this); this._focusTracker.dispose(); const keys = Object.keys(this._contributions); for (let i = 0, len = keys.length; i < len; i++) { const contributionId = keys[i]; this._contributions[contributionId].dispose(); } this._contributions = {}; this._actions = {}; this._contentWidgets = {}; this._overlayWidgets = {}; this._removeDecorationTypes(); this._postDetachModelCleanup(this._detachModel()); this._onDidDispose.fire(); super.dispose(); } invokeWithinContext(fn) { return this._instantiationService.invokeFunction(fn); } updateOptions(newOptions) { this._configuration.updateOptions(newOptions); } getOptions() { return this._configuration.options; } getOption(id) { return this._configuration.options.get(id); } getRawOptions() { return this._configuration.getRawOptions(); } getOverflowWidgetsDomNode() { return this._overflowWidgetsDomNode; } getConfiguredWordAtPosition(position) { if (!this._modelData) { return null; } return WordOperations.getWordAtPosition(this._modelData.model, this._configuration.options.get(115 /* wordSeparators */), position); } getValue(options = null) { if (!this._modelData) { return ''; } const preserveBOM = (options && options.preserveBOM) ? true : false; let eolPreference = 0 /* TextDefined */; if (options && options.lineEnding && options.lineEnding === '\n') { eolPreference = 1 /* LF */; } else if (options && options.lineEnding && options.lineEnding === '\r\n') { eolPreference = 2 /* CRLF */; } return this._modelData.model.getValue(eolPreference, preserveBOM); } setValue(newValue) { if (!this._modelData) { return; } this._modelData.model.setValue(newValue); } getModel() { if (!this._modelData) { return null; } return this._modelData.model; } setModel(_model = null) { const model = _model; if (this._modelData === null && model === null) { // Current model is the new model return; } if (this._modelData && this._modelData.model === model) { // Current model is the new model return; } const hasTextFocus = this.hasTextFocus(); const detachedModel = this._detachModel(); this._attachModel(model); if (hasTextFocus && this.hasModel()) { this.focus(); } const e = { oldModelUrl: detachedModel ? detachedModel.uri : null, newModelUrl: model ? model.uri : null }; this._removeDecorationTypes(); this._onDidChangeModel.fire(e); this._postDetachModelCleanup(detachedModel); } _removeDecorationTypes() { this._decorationTypeKeysToIds = {}; if (this._decorationTypeSubtypes) { for (let decorationType in this._decorationTypeSubtypes) { const subTypes = this._decorationTypeSubtypes[decorationType]; for (let subType in subTypes) { this._removeDecorationType(decorationType + '-' + subType); } } this._decorationTypeSubtypes = {}; } } getVisibleRanges() { if (!this._modelData) { return []; } return this._modelData.viewModel.getVisibleRanges(); } getVisibleRangesPlusViewportAboveBelow() { if (!this._modelData) { return []; } return this._modelData.viewModel.getVisibleRangesPlusViewportAboveBelow(); } getWhitespaces() { if (!this._modelData) { return []; } return this._modelData.viewModel.viewLayout.getWhitespaces(); } static _getVerticalOffsetForPosition(modelData, modelLineNumber, modelColumn) { const modelPosition = modelData.model.validatePosition({ lineNumber: modelLineNumber, column: modelColumn }); const viewPosition = modelData.viewModel.coordinatesConverter.convertModelPositionToViewPosition(modelPosition); return modelData.viewModel.viewLayout.getVerticalOffsetForLineNumber(viewPosition.lineNumber); } getTopForLineNumber(lineNumber) { if (!this._modelData) { return -1; } return CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, lineNumber, 1); } getTopForPosition(lineNumber, column) { if (!this._modelData) { return -1; } return CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, lineNumber, column); } setHiddenAreas(ranges) { if (this._modelData) { this._modelData.viewModel.setHiddenAreas(ranges.map(r => Range.lift(r))); } } getVisibleColumnFromPosition(rawPosition) { if (!this._modelData) { return rawPosition.column; } const position = this._modelData.model.validatePosition(rawPosition); const tabSize = this._modelData.model.getOptions().tabSize; return CursorColumns.visibleColumnFromColumn(this._modelData.model.getLineContent(position.lineNumber), position.column, tabSize) + 1; } getPosition() { if (!this._modelData) { return null; } return this._modelData.viewModel.getPosition(); } setPosition(position) { if (!this._modelData) { return; } if (!Position.isIPosition(position)) { throw new Error('Invalid arguments'); } this._modelData.viewModel.setSelections('api', [{ selectionStartLineNumber: position.lineNumber, selectionStartColumn: position.column, positionLineNumber: position.lineNumber, positionColumn: position.column }]); } _sendRevealRange(modelRange, verticalType, revealHorizontal, scrollType) { if (!this._modelData) { return; } if (!Range.isIRange(modelRange)) { throw new Error('Invalid arguments'); } const validatedModelRange = this._modelData.model.validateRange(modelRange); const viewRange = this._modelData.viewModel.coordinatesConverter.convertModelRangeToViewRange(validatedModelRange); this._modelData.viewModel.revealRange('api', revealHorizontal, viewRange, verticalType, scrollType); } revealLine(lineNumber, scrollType = 0 /* Smooth */) { this._revealLine(lineNumber, 0 /* Simple */, scrollType); } revealLineInCenter(lineNumber, scrollType = 0 /* Smooth */) { this._revealLine(lineNumber, 1 /* Center */, scrollType); } revealLineInCenterIfOutsideViewport(lineNumber, scrollType = 0 /* Smooth */) { this._revealLine(lineNumber, 2 /* CenterIfOutsideViewport */, scrollType); } revealLineNearTop(lineNumber, scrollType = 0 /* Smooth */) { this._revealLine(lineNumber, 5 /* NearTop */, scrollType); } _revealLine(lineNumber, revealType, scrollType) { if (typeof lineNumber !== 'number') { throw new Error('Invalid arguments'); } this._sendRevealRange(new Range(lineNumber, 1, lineNumber, 1), revealType, false, scrollType); } revealPosition(position, scrollType = 0 /* Smooth */) { this._revealPosition(position, 0 /* Simple */, true, scrollType); } revealPositionInCenter(position, scrollType = 0 /* Smooth */) { this._revealPosition(position, 1 /* Center */, true, scrollType); } revealPositionInCenterIfOutsideViewport(position, scrollType = 0 /* Smooth */) { this._revealPosition(position, 2 /* CenterIfOutsideViewport */, true, scrollType); } revealPositionNearTop(position, scrollType = 0 /* Smooth */) { this._revealPosition(position, 5 /* NearTop */, true, scrollType); } _revealPosition(position, verticalType, revealHorizontal, scrollType) { if (!Position.isIPosition(position)) { throw new Error('Invalid arguments'); } this._sendRevealRange(new Range(position.lineNumber, position.column, position.lineNumber, position.column), verticalType, revealHorizontal, scrollType); } getSelection() { if (!this._modelData) { return null; } return this._modelData.viewModel.getSelection(); } getSelections() { if (!this._modelData) { return null; } return this._modelData.viewModel.getSelections(); } setSelection(something) { const isSelection = Selection.isISelection(something); const isRange = Range.isIRange(something); if (!isSelection && !isRange) { throw new Error('Invalid arguments'); } if (isSelection) { this._setSelectionImpl(something); } else if (isRange) { // act as if it was an IRange const selection = { selectionStartLineNumber: something.startLineNumber, selectionStartColumn: something.startColumn, positionLineNumber: something.endLineNumber, positionColumn: something.endColumn }; this._setSelectionImpl(selection); } } _setSelectionImpl(sel) { if (!this._modelData) { return; } const selection = new Selection(sel.selectionStartLineNumber, sel.selectionStartColumn, sel.positionLineNumber, sel.positionColumn); this._modelData.viewModel.setSelections('api', [selection]); } revealLines(startLineNumber, endLineNumber, scrollType = 0 /* Smooth */) { this._revealLines(startLineNumber, endLineNumber, 0 /* Simple */, scrollType); } revealLinesInCenter(startLineNumber, endLineNumber, scrollType = 0 /* Smooth */) { this._revealLines(startLineNumber, endLineNumber, 1 /* Center */, scrollType); } revealLinesInCenterIfOutsideViewport(startLineNumber, endLineNumber, scrollType = 0 /* Smooth */) { this._revealLines(startLineNumber, endLineNumber, 2 /* CenterIfOutsideViewport */, scrollType); } revealLinesNearTop(startLineNumber, endLineNumber, scrollType = 0 /* Smooth */) { this._revealLines(startLineNumber, endLineNumber, 5 /* NearTop */, scrollType); } _revealLines(startLineNumber, endLineNumber, verticalType, scrollType) { if (typeof startLineNumber !== 'number' || typeof endLineNumber !== 'number') { throw new Error('Invalid arguments'); } this._sendRevealRange(new Range(startLineNumber, 1, endLineNumber, 1), verticalType, false, scrollType); } revealRange(range, scrollType = 0 /* Smooth */, revealVerticalInCenter = false, revealHorizontal = true) { this._revealRange(range, revealVerticalInCenter ? 1 /* Center */ : 0 /* Simple */, revealHorizontal, scrollType); } revealRangeInCenter(range, scrollType = 0 /* Smooth */) { this._revealRange(range, 1 /* Center */, true, scrollType); } revealRangeInCenterIfOutsideViewport(range, scrollType = 0 /* Smooth */) { this._revealRange(range, 2 /* CenterIfOutsideViewport */, true, scrollType); } revealRangeNearTop(range, scrollType = 0 /* Smooth */) { this._revealRange(range, 5 /* NearTop */, true, scrollType); } revealRangeNearTopIfOutsideViewport(range, scrollType = 0 /* Smooth */) { this._revealRange(range, 6 /* NearTopIfOutsideViewport */, true, scrollType); } revealRangeAtTop(range, scrollType = 0 /* Smooth */) { this._revealRange(range, 3 /* Top */, true, scrollType); } _revealRange(range, verticalType, revealHorizontal, scrollType) { if (!Range.isIRange(range)) { throw new Error('Invalid arguments'); } this._sendRevealRange(Range.lift(range), verticalType, revealHorizontal, scrollType); } setSelections(ranges, source = 'api', reason = 0 /* NotSet */) { if (!this._modelData) { return; } if (!ranges || ranges.length === 0) { throw new Error('Invalid arguments'); } for (let i = 0, len = ranges.length; i < len; i++) { if (!Selection.isISelection(ranges[i])) { throw new Error('Invalid arguments'); } } this._modelData.viewModel.setSelections(source, ranges, reason); } getContentWidth() { if (!this._modelData) { return -1; } return this._modelData.viewModel.viewLayout.getContentWidth(); } getScrollWidth() { if (!this._modelData) { return -1; } return this._modelData.viewModel.viewLayout.getScrollWidth(); } getScrollLeft() { if (!this._modelData) { return -1; } return this._modelData.viewModel.viewLayout.getCurrentScrollLeft(); } getContentHeight() { if (!this._modelData) { return -1; } return this._modelData.viewModel.viewLayout.getContentHeight(); } getScrollHeight() { if (!this._modelData) { return -1; } return this._modelData.viewModel.viewLayout.getScrollHeight(); } getScrollTop() { if (!this._modelData) { return -1; } return this._modelData.viewModel.viewLayout.getCurrentScrollTop(); } setScrollLeft(newScrollLeft, scrollType = 1 /* Immediate */) { if (!this._modelData) { return; } if (typeof newScrollLeft !== 'number') { throw new Error('Invalid arguments'); } this._modelData.viewModel.setScrollPosition({ scrollLeft: newScrollLeft }, scrollType); } setScrollTop(newScrollTop, scrollType = 1 /* Immediate */) { if (!this._modelData) { return; } if (typeof newScrollTop !== 'number') { throw new Error('Invalid arguments'); } this._modelData.viewModel.setScrollPosition({ scrollTop: newScrollTop }, scrollType); } setScrollPosition(position, scrollType = 1 /* Immediate */) { if (!this._modelData) { return; } this._modelData.viewModel.setScrollPosition(position, scrollType); } saveViewState() { if (!this._modelData) { return null; } const contributionsState = {}; const keys = Object.keys(this._contributions); for (const id of keys) { const contribution = this._contributions[id]; if (typeof contribution.saveViewState === 'function') { contributionsState[id] = contribution.saveViewState(); } } const cursorState = this._modelData.viewModel.saveCursorState(); const viewState = this._modelData.viewModel.saveState(); return { cursorState: cursorState, viewState: viewState, contributionsState: contributionsState }; } restoreViewState(s) { if (!this._modelData || !this._modelData.hasRealView) { return; } const codeEditorState = s; if (codeEditorState && codeEditorState.cursorState && codeEditorState.viewState) { const cursorState = codeEditorState.cursorState; if (Array.isArray(cursorState)) { this._modelData.viewModel.restoreCursorState(cursorState); } else { // Backwards compatibility this._modelData.viewModel.restoreCursorState([cursorState]); } const contributionsState = codeEditorState.contributionsState || {}; const keys = Object.keys(this._contributions); for (let i = 0, len = keys.length; i < len; i++) { const id = keys[i]; const contribution = this._contributions[id]; if (typeof contribution.restoreViewState === 'function') { contribution.restoreViewState(contributionsState[id]); } } const reducedState = this._modelData.viewModel.reduceRestoreState(codeEditorState.viewState); this._modelData.view.restoreState(reducedState); } } getContribution(id) { return (this._contributions[id] || null); } getActions() { const result = []; const keys = Object.keys(this._actions); for (let i = 0, len = keys.length; i < len; i++) { const id = keys[i]; result.push(this._actions[id]); } return result; } getSupportedActions() { let result = this.getActions(); result = result.filter(action => action.isSupported()); return result; } getAction(id) { return this._actions[id] || null; } trigger(source, handlerId, payload) { payload = payload || {}; switch (handlerId) { case "compositionStart" /* CompositionStart */: this._startComposition(); return; case "compositionEnd" /* CompositionEnd */: this._endComposition(source); return; case "type" /* Type */: { const args = payload; this._type(source, args.text || ''); return; } case "replacePreviousChar" /* ReplacePreviousChar */: { const args = payload; this._compositionType(source, args.text || '', args.replaceCharCnt || 0, 0, 0); return; } case "compositionType" /* CompositionType */: { const args = payload; this._compositionType(source, args.text || '', args.replacePrevCharCnt || 0, args.replaceNextCharCnt || 0, args.positionDelta || 0); return; } case "paste" /* Paste */: { const args = payload; this._paste(source, args.text || '', args.pasteOnNewLine || false, args.multicursorText || null, args.mode || null); return; } case "cut" /* Cut */: this._cut(source); return; } const action = this.getAction(handlerId); if (action) { Promise.resolve(action.run()).then(undefined, onUnexpectedError); return; } if (!this._modelData) { return; } if (this._triggerEditorCommand(source, handlerId, payload)) { return; } this._triggerCommand(handlerId, payload); } _triggerCommand(handlerId, payload) { this._commandService.executeCommand(handlerId, payload); } _startComposition() { if (!this._modelData) { return; } this._modelData.viewModel.startComposition(); this._onDidCompositionStart.fire(); } _endComposition(source) { if (!this._modelData) { return; } this._modelData.viewModel.endComposition(source); this._onDidCompositionEnd.fire(); } _type(source, text) { if (!this._modelData || text.length === 0) { return; } if (source === 'keyboard') { this._onWillType.fire(text); } this._modelData.viewModel.type(text, source); if (source === 'keyboard') { this._onDidType.fire(text); } } _compositionType(source, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta) { if (!this._modelData) { return; } this._modelData.viewModel.compositionType(text, replacePrevCharCnt, replaceNextCharCnt, positionDelta, source); } _paste(source, text, pasteOnNewLine, multicursorText, mode) { if (!this._modelData || text.length === 0) { return; } const startPosition = this._modelData.viewModel.getSelection().getStartPosition(); this._modelData.viewModel.paste(text, pasteOnNewLine, multicursorText, source); const endPosition = this._modelData.viewModel.getSelection().getStartPosition(); if (source === 'keyboard') { this._onDidPaste.fire({ range: new Range(startPosition.lineNumber, startPosition.column, endPosition.lineNumber, endPosition.column), languageId: mode }); } } _cut(source) { if (!this._modelData) { return; } this._modelData.viewModel.cut(source); } _triggerEditorCommand(source, handlerId, payload) { const command = EditorExtensionsRegistry.getEditorCommand(handlerId); if (command) { payload = payload || {}; payload.source = source; this._instantiationService.invokeFunction((accessor) => { Promise.resolve(command.runEditorCommand(accessor, this, payload)).then(undefined, onUnexpectedError); }); return true; } return false; } _getViewModel() { if (!this._modelData) { return null; } return this._modelData.viewModel; } pushUndoStop() { if (!this._modelData) { return false; } if (this._configuration.options.get(80 /* readOnly */)) { // read only editor => sorry! return false; } this._modelData.model.pushStackElement(); return true; } popUndoStop() { if (!this._modelData) { return false; } if (this._configuration.options.get(80 /* readOnly */)) { // read only editor => sorry! return false; } this._modelData.model.popStackElement(); return true; } executeEdits(source, edits, endCursorState) { if (!this._modelData) { return false; } if (this._configuration.options.get(80 /* readOnly */)) { // read only editor => sorry! return false; } let cursorStateComputer; if (!endCursorState) { cursorStateComputer = () => null; } else if (Array.isArray(endCursorState)) { cursorStateComputer = () => endCursorState; } else { cursorStateComputer = endCursorState; } this._modelData.viewModel.executeEdits(source, edits, cursorStateComputer); return true; } executeCommand(source, command) { if (!this._modelData) { return; } this._modelData.viewModel.executeCommand(command, source); } executeCommands(source, commands) { if (!this._modelData) { return; } this._modelData.viewModel.executeCommands(commands, source); } changeDecorations(callback) { if (!this._modelData) { // callback will not be called return null; } return this._modelData.model.changeDecorations(callback, this._id); } getLineDecorations(lineNumber) { if (!this._modelData) { return null; } return this._modelData.model.getLineDecorations(lineNumber, this._id, filterValidationDecorations(this._configuration.options)); } deltaDecorations(oldDecorations, newDecorations) { if (!this._modelData) { return []; } if (oldDecorations.length === 0 && newDecorations.length === 0) { return oldDecorations; } return this._modelData.model.deltaDecorations(oldDecorations, newDecorations, this._id); } removeDecorations(decorationTypeKey) { // remove decorations for type and sub type const oldDecorationsIds = this._decorationTypeKeysToIds[decorationTypeKey]; if (oldDecorationsIds) { this.deltaDecorations(oldDecorationsIds, []); } if (this._decorationTypeKeysToIds.hasOwnProperty(decorationTypeKey)) { delete this._decorationTypeKeysToIds[decorationTypeKey]; } if (this._decorationTypeSubtypes.hasOwnProperty(decorationTypeKey)) { delete this._decorationTypeSubtypes[decorationTypeKey]; } } getLayoutInfo() { const options = this._configuration.options; const layoutInfo = options.get(129 /* layoutInfo */); return layoutInfo; } createOverviewRuler(cssClassName) { if (!this._modelData || !this._modelData.hasRealView) { return null; } return this._modelData.view.createOverviewRuler(cssClassName); } getContainerDomNode() { return this._domElement; } getDomNode() { if (!this._modelData || !this._modelData.hasRealView) { return null; } return this._modelData.view.domNode.domNode; } delegateVerticalScrollbarMouseDown(browserEvent) { if (!this._modelData || !this._modelData.hasRealView) { return; } this._modelData.view.delegateVerticalScrollbarMouseDown(browserEvent); } layout(dimension) { this._configuration.observeReferenceElement(dimension); this.render(); } focus() { if (!this._modelData || !this._modelData.hasRealView) { return; } this._modelData.view.focus(); } hasTextFocus() { if (!this._modelData || !this._modelData.hasRealView) { return false; } return this._modelData.view.isFocused(); } hasWidgetFocus() { return this._focusTracker && this._focusTracker.hasFocus(); } addContentWidget(widget) { const widgetData = { widget: widget, position: widget.getPosition() }; if (this._contentWidgets.hasOwnProperty(widget.getId())) { console.warn('Overwriting a content widget with the same id.'); } this._contentWidgets[widget.getId()] = widgetData; if (this._modelData && this._modelData.hasRealView) { this._modelData.view.addContentWidget(widgetData); } } layoutContentWidget(widget) { const widgetId = widget.getId(); if (this._contentWidgets.hasOwnProperty(widgetId)) { const widgetData = this._contentWidgets[widgetId]; widgetData.position = widget.getPosition(); if (this._modelData && this._modelData.hasRealView) { this._modelData.view.layoutContentWidget(widgetData); } } } removeContentWidget(widget) { const widgetId = widget.getId(); if (this._contentWidgets.hasOwnProperty(widgetId)) { const widgetData = this._contentWidgets[widgetId]; delete this._contentWidgets[widgetId]; if (this._modelData && this._modelData.hasRealView) { this._modelData.view.removeContentWidget(widgetData); } } } addOverlayWidget(widget) { const widgetData = { widget: widget, position: widget.getPosition() }; if (this._overlayWidgets.hasOwnProperty(widget.getId())) { console.warn('Overwriting an overlay widget with the same id.'); } this._overlayWidgets[widget.getId()] = widgetData; if (this._modelData && this._modelData.hasRealView) { this._modelData.view.addOverlayWidget(widgetData); } } layoutOverlayWidget(widget) { const widgetId = widget.getId(); if (this._overlayWidgets.hasOwnProperty(widgetId)) { const widgetData = this._overlayWidgets[widgetId]; widgetData.position = widget.getPosition(); if (this._modelData && this._modelData.hasRealView) { this._modelData.view.layoutOverlayWidget(widgetData); } } } removeOverlayWidget(widget) { const widgetId = widget.getId(); if (this._overlayWidgets.hasOwnProperty(widgetId)) { const widgetData = this._overlayWidgets[widgetId]; delete this._overlayWidgets[widgetId]; if (this._modelData && this._modelData.hasRealView) { this._modelData.view.removeOverlayWidget(widgetData); } } } changeViewZones(callback) { if (!this._modelData || !this._modelData.hasRealView) { return; } this._modelData.view.change(callback); } getTargetAtClientPoint(clientX, clientY) { if (!this._modelData || !this._modelData.hasRealView) { return null; } return this._modelData.view.getTargetAtClientPoint(clientX, clientY); } getScrolledVisiblePosition(rawPosition) { if (!this._modelData || !this._modelData.hasRealView) { return null; } const position = this._modelData.model.validatePosition(rawPosition); const options = this._configuration.options; const layoutInfo = options.get(129 /* layoutInfo */); const top = CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, position.lineNumber, position.column) - this.getScrollTop(); const left = this._modelData.view.getOffsetForColumn(position.lineNumber, position.column) + layoutInfo.glyphMarginWidth + layoutInfo.lineNumbersWidth + layoutInfo.decorationsWidth - this.getScrollLeft(); return { top: top, left: left, height: options.get(58 /* lineHeight */) }; } getOffsetForColumn(lineNumber, column) { if (!this._modelData || !this._modelData.hasRealView) { return -1; } return this._modelData.view.getOffsetForColumn(lineNumber, column); } render(forceRedraw = false) { if (!this._modelData || !this._modelData.hasRealView) { return; } this._modelData.view.render(true, forceRedraw); } setAriaOptions(options) { if (!this._modelData || !this._modelData.hasRealView) { return; } this._modelData.view.setAriaOptions(options); } applyFontInfo(target) { Configuration.applyFontInfoSlow(target, this._configuration.options.get(43 /* fontInfo */)); } _attachModel(model) { if (!model) { this._modelData = null; return; } const listenersToRemove = []; this._domElement.setAttribute('data-mode-id', model.getLanguageId()); this._configuration.setIsDominatedByLongLines(model.isDominatedByLongLines()); this._configuration.setMaxLineNumber(model.getLineCount()); model.onBeforeAttached(); const viewModel = new ViewModel(this._id, this._configuration, model, DOMLineBreaksComputerFactory.create(), MonospaceLineBreaksComputerFactory.create(this._configuration.options), (callback) => dom.scheduleAtNextAnimationFrame(callback)); listenersToRemove.push(model.onDidChangeDecorations((e) => this._onDidChangeModelDecorations.fire(e))); listenersToRemove.push(model.onDidChangeLanguage((e) => { this._domElement.setAttribute('data-mode-id', model.getLanguageId()); this._onDidChangeModelLanguage.fire(e); })); listenersToRemove.push(model.onDidChangeLanguageConfiguration((e) => this._onDidChangeModelLanguageConfiguration.fire(e))); listenersToRemove.push(model.onDidChangeContent((e) => this._onDidChangeModelContent.fire(e))); listenersToRemove.push(model.onDidChangeOptions((e) => this._onDidChangeModelOptions.fire(e))); // Someone might destroy the model from under the editor, so prevent any exceptions by setting a null model listenersToRemove.push(model.onWillDispose(() => this.setModel(null))); listenersToRemove.push(viewModel.onEvent((e) => { switch (e.kind) { case 0 /* ContentSizeChanged */: this._onDidContentSizeChange.fire(e); break; case 1 /* FocusChanged */: this._editorTextFocus.setValue(e.hasFocus); break; case 2 /* ScrollChanged */: this._onDidScrollChange.fire(e); break; case 3 /* ViewZonesChanged */: this._onDidChangeViewZones.fire(); break; case 4 /* HiddenAreasChanged */: this._onDidChangeHiddenAreas.fire(); break; case 5 /* ReadOnlyEditAttempt */: this._onDidAttemptReadOnlyEdit.fire(); break; case 6 /* CursorStateChanged */: { if (e.reachedMaxCursorCount) { this._notificationService.warn(nls.localize('cursors.maximum', "The number of cursors has been limited to {0}.", CursorsController.MAX_CURSOR_COUNT)); } const positions = []; for (let i = 0, len = e.selections.length; i < len; i++) { positions[i] = e.selections[i].getPosition(); } const e1 = { position: positions[0], secondaryPositions: positions.slice(1), reason: e.reason, source: e.source }; this._onDidChangeCursorPosition.fire(e1); const e2 = { selection: e.selections[0], secondarySelections: e.selections.slice(1), modelVersionId: e.modelVersionId, oldSelections: e.oldSelections, oldModelVersionId: e.oldModelVersionId, source: e.source, reason: e.reason }; this._onDidChangeCursorSelection.fire(e2); break; } } })); const [view, hasRealView] = this._createView(viewModel); if (hasRealView) { this._domElement.appendChild(view.domNode.domNode); let keys = Object.keys(this._contentWidgets); for (let i = 0, len = keys.length; i < len; i++) { const widgetId = keys[i]; view.addContentWidget(this._contentWidgets[widgetId]); } keys = Object.keys(this._overlayWidgets); for (let i = 0, len = keys.length; i < len; i++) { const widgetId = keys[i]; view.addOverlayWidget(this._overlayWidgets[widgetId]); } view.render(false, true); view.domNode.domNode.setAttribute('data-uri', model.uri.toString()); } this._modelData = new ModelData(model, viewModel, view, hasRealView, listenersToRemove); } _createView(viewModel) { let commandDelegate; if (this.isSimpleWidget) { commandDelegate = { paste: (text, pasteOnNewLine, multicursorText, mode) => { this._paste('keyboard', text, pasteOnNewLine, multicursorText, mode); }, type: (text) => { this._type('keyboard', text); }, compositionType: (text, replacePrevCharCnt, replaceNextCharCnt, positionDelta) => { this._compositionType('keyboard', text, replacePrevCharCnt, replaceNextCharCnt, positionDelta); }, startComposition: () => { this._startComposition(); }, endComposition: () => { this._endComposition('keyboard'); }, cut: () => { this._cut('keyboard'); } }; } else { commandDelegate = { paste: (text, pasteOnNewLine, multicursorText, mode) => { const payload = { text, pasteOnNewLine, multicursorText, mode }; this._commandService.executeCommand("paste" /* Paste */, payload);