@21epub/epub-thirdparty
Version:
epub-thirdparty
1,018 lines • 101 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* 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); }
};
var _a;
import './media/diffEditor.css';
import * as nls from '../../../nls.js';
import * as dom from '../../../base/browser/dom.js';
import { createFastDomNode } from '../../../base/browser/fastDomNode.js';
import { Sash } from '../../../base/browser/ui/sash/sash.js';
import { RunOnceScheduler } from '../../../base/common/async.js';
import { Emitter } from '../../../base/common/event.js';
import { Disposable } from '../../../base/common/lifecycle.js';
import { Configuration } from '../config/configuration.js';
import { StableEditorScrollState } from '../core/editorState.js';
import { ICodeEditorService } from '../services/codeEditorService.js';
import { CodeEditorWidget } from './codeEditorWidget.js';
import { DiffReview } from './diffReview.js';
import { EditorOptions, EditorFontLigatures, stringSet as validateStringSetOption, boolean as validateBooleanOption, clampedInt } from '../../common/config/editorOptions.js';
import { Range } from '../../common/core/range.js';
import { createStringBuilder } from '../../common/core/stringBuilder.js';
import * as editorCommon from '../../common/editorCommon.js';
import { ModelDecorationOptions } from '../../common/model/textModel.js';
import { IEditorWorkerService } from '../../common/services/editorWorkerService.js';
import { OverviewRulerZone } from '../../common/view/overviewZoneManager.js';
import { LineDecoration } from '../../common/viewLayout/lineDecorations.js';
import { RenderLineInput, renderViewLine } from '../../common/viewLayout/viewLineRenderer.js';
import { InlineDecoration, ViewLineRenderingData } from '../../common/viewModel/viewModel.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 { defaultInsertColor, defaultRemoveColor, diffBorder, diffInserted, diffInsertedOutline, diffRemoved, diffRemovedOutline, scrollbarShadow, scrollbarSliderBackground, scrollbarSliderHoverBackground, scrollbarSliderActiveBackground, diffDiagonalFill } from '../../../platform/theme/common/colorRegistry.js';
import { IThemeService, getThemeTypeSelector, registerThemingParticipant, ThemeIcon } from '../../../platform/theme/common/themeService.js';
import { IContextMenuService } from '../../../platform/contextview/browser/contextView.js';
import { InlineDiffMargin } from './inlineDiffMargin.js';
import { IClipboardService } from '../../../platform/clipboard/common/clipboardService.js';
import { EditorExtensionsRegistry } from '../editorExtensions.js';
import { onUnexpectedError } from '../../../base/common/errors.js';
import { IEditorProgressService } from '../../../platform/progress/common/progress.js';
import { ElementSizeObserver } from '../config/elementSizeObserver.js';
import { Codicon } from '../../../base/common/codicons.js';
import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from '../../../base/browser/ui/mouseCursor/mouseCursor.js';
import { registerIcon } from '../../../platform/theme/common/iconRegistry.js';
class VisualEditorState {
constructor(_contextMenuService, _clipboardService) {
this._contextMenuService = _contextMenuService;
this._clipboardService = _clipboardService;
this._zones = [];
this._inlineDiffMargins = [];
this._zonesMap = {};
this._decorations = [];
}
getForeignViewZones(allViewZones) {
return allViewZones.filter((z) => !this._zonesMap[String(z.id)]);
}
clean(editor) {
// (1) View zones
if (this._zones.length > 0) {
editor.changeViewZones((viewChangeAccessor) => {
for (const zoneId of this._zones) {
viewChangeAccessor.removeZone(zoneId);
}
});
}
this._zones = [];
this._zonesMap = {};
// (2) Model decorations
this._decorations = editor.deltaDecorations(this._decorations, []);
}
apply(editor, overviewRuler, newDecorations, restoreScrollState) {
const scrollState = restoreScrollState ? StableEditorScrollState.capture(editor) : null;
// view zones
editor.changeViewZones((viewChangeAccessor) => {
var _a;
for (const zoneId of this._zones) {
viewChangeAccessor.removeZone(zoneId);
}
for (const inlineDiffMargin of this._inlineDiffMargins) {
inlineDiffMargin.dispose();
}
this._zones = [];
this._zonesMap = {};
this._inlineDiffMargins = [];
for (let i = 0, length = newDecorations.zones.length; i < length; i++) {
const viewZone = newDecorations.zones[i];
viewZone.suppressMouseDown = true;
const zoneId = viewChangeAccessor.addZone(viewZone);
this._zones.push(zoneId);
this._zonesMap[String(zoneId)] = true;
if (newDecorations.zones[i].diff && viewZone.marginDomNode) {
viewZone.suppressMouseDown = false;
if (((_a = newDecorations.zones[i].diff) === null || _a === void 0 ? void 0 : _a.originalModel.getValueLength()) !== 0) {
// do not contribute diff margin actions for newly created files
this._inlineDiffMargins.push(new InlineDiffMargin(zoneId, viewZone.marginDomNode, editor, newDecorations.zones[i].diff, this._contextMenuService, this._clipboardService));
}
}
}
});
if (scrollState) {
scrollState.restore(editor);
}
// decorations
this._decorations = editor.deltaDecorations(this._decorations, newDecorations.decorations);
// overview ruler
if (overviewRuler) {
overviewRuler.setZones(newDecorations.overviewZones);
}
}
}
let DIFF_EDITOR_ID = 0;
const diffInsertIcon = registerIcon('diff-insert', Codicon.add, nls.localize('diffInsertIcon', 'Line decoration for inserts in the diff editor.'));
const diffRemoveIcon = registerIcon('diff-remove', Codicon.remove, nls.localize('diffRemoveIcon', 'Line decoration for removals in the diff editor.'));
const ttPolicy = (_a = window.trustedTypes) === null || _a === void 0 ? void 0 : _a.createPolicy('diffEditorWidget', { createHTML: value => value });
let DiffEditorWidget = class DiffEditorWidget extends Disposable {
constructor(domElement, options, codeEditorWidgetOptions, clipboardService, editorWorkerService, contextKeyService, instantiationService, codeEditorService, themeService, notificationService, contextMenuService, _editorProgressService) {
super();
this._editorProgressService = _editorProgressService;
this._onDidDispose = this._register(new Emitter());
this.onDidDispose = this._onDidDispose.event;
this._onDidUpdateDiff = this._register(new Emitter());
this.onDidUpdateDiff = this._onDidUpdateDiff.event;
this._onDidContentSizeChange = this._register(new Emitter());
this._lastOriginalWarning = null;
this._lastModifiedWarning = null;
this._editorWorkerService = editorWorkerService;
this._codeEditorService = codeEditorService;
this._contextKeyService = this._register(contextKeyService.createScoped(domElement));
this._instantiationService = instantiationService.createChild(new ServiceCollection([IContextKeyService, this._contextKeyService]));
this._contextKeyService.createKey('isInDiffEditor', true);
this._themeService = themeService;
this._notificationService = notificationService;
this._id = (++DIFF_EDITOR_ID);
this._state = 0 /* Idle */;
this._updatingDiffProgress = null;
this._domElement = domElement;
options = options || {};
this._options = validateDiffEditorOptions(options, {
enableSplitViewResizing: true,
renderSideBySide: true,
maxComputationTime: 5000,
maxFileSize: 50,
ignoreTrimWhitespace: true,
renderIndicators: true,
originalEditable: false,
diffCodeLens: false,
renderOverviewRuler: true,
diffWordWrap: 'inherit'
});
if (typeof options.isInEmbeddedEditor !== 'undefined') {
this._contextKeyService.createKey('isInEmbeddedDiffEditor', options.isInEmbeddedEditor);
}
else {
this._contextKeyService.createKey('isInEmbeddedDiffEditor', false);
}
this._updateDecorationsRunner = this._register(new RunOnceScheduler(() => this._updateDecorations(), 0));
this._containerDomElement = document.createElement('div');
this._containerDomElement.className = DiffEditorWidget._getClassName(this._themeService.getColorTheme(), this._options.renderSideBySide);
this._containerDomElement.style.position = 'relative';
this._containerDomElement.style.height = '100%';
this._domElement.appendChild(this._containerDomElement);
this._overviewViewportDomElement = createFastDomNode(document.createElement('div'));
this._overviewViewportDomElement.setClassName('diffViewport');
this._overviewViewportDomElement.setPosition('absolute');
this._overviewDomElement = document.createElement('div');
this._overviewDomElement.className = 'diffOverview';
this._overviewDomElement.style.position = 'absolute';
this._overviewDomElement.appendChild(this._overviewViewportDomElement.domNode);
this._register(dom.addStandardDisposableListener(this._overviewDomElement, 'mousedown', (e) => {
this._modifiedEditor.delegateVerticalScrollbarMouseDown(e);
}));
if (this._options.renderOverviewRuler) {
this._containerDomElement.appendChild(this._overviewDomElement);
}
// Create left side
this._originalDomNode = document.createElement('div');
this._originalDomNode.className = 'editor original';
this._originalDomNode.style.position = 'absolute';
this._originalDomNode.style.height = '100%';
this._containerDomElement.appendChild(this._originalDomNode);
// Create right side
this._modifiedDomNode = document.createElement('div');
this._modifiedDomNode.className = 'editor modified';
this._modifiedDomNode.style.position = 'absolute';
this._modifiedDomNode.style.height = '100%';
this._containerDomElement.appendChild(this._modifiedDomNode);
this._beginUpdateDecorationsTimeout = -1;
this._currentlyChangingViewZones = false;
this._diffComputationToken = 0;
this._originalEditorState = new VisualEditorState(contextMenuService, clipboardService);
this._modifiedEditorState = new VisualEditorState(contextMenuService, clipboardService);
this._isVisible = true;
this._isHandlingScrollEvent = false;
this._elementSizeObserver = this._register(new ElementSizeObserver(this._containerDomElement, options.dimension, () => this._onDidContainerSizeChanged()));
if (options.automaticLayout) {
this._elementSizeObserver.startObserving();
}
this._diffComputationResult = null;
this._originalEditor = this._createLeftHandSideEditor(options, codeEditorWidgetOptions.originalEditor || {});
this._modifiedEditor = this._createRightHandSideEditor(options, codeEditorWidgetOptions.modifiedEditor || {});
this._originalOverviewRuler = null;
this._modifiedOverviewRuler = null;
this._reviewPane = instantiationService.createInstance(DiffReview, this);
this._containerDomElement.appendChild(this._reviewPane.domNode.domNode);
this._containerDomElement.appendChild(this._reviewPane.shadow.domNode);
this._containerDomElement.appendChild(this._reviewPane.actionBarContainer.domNode);
if (this._options.renderSideBySide) {
this._setStrategy(new DiffEditorWidgetSideBySide(this._createDataSource(), this._options.enableSplitViewResizing));
}
else {
this._setStrategy(new DiffEditorWidgetInline(this._createDataSource(), this._options.enableSplitViewResizing));
}
this._register(themeService.onDidColorThemeChange(t => {
if (this._strategy && this._strategy.applyColors(t)) {
this._updateDecorationsRunner.schedule();
}
this._containerDomElement.className = DiffEditorWidget._getClassName(this._themeService.getColorTheme(), this._options.renderSideBySide);
}));
const contributions = EditorExtensionsRegistry.getDiffEditorContributions();
for (const desc of contributions) {
try {
this._register(instantiationService.createInstance(desc.ctor, this));
}
catch (err) {
onUnexpectedError(err);
}
}
this._codeEditorService.addDiffEditor(this);
}
_setState(newState) {
if (this._state === newState) {
return;
}
this._state = newState;
if (this._updatingDiffProgress) {
this._updatingDiffProgress.done();
this._updatingDiffProgress = null;
}
if (this._state === 1 /* ComputingDiff */) {
this._updatingDiffProgress = this._editorProgressService.show(true, 1000);
}
}
diffReviewNext() {
this._reviewPane.next();
}
diffReviewPrev() {
this._reviewPane.prev();
}
static _getClassName(theme, renderSideBySide) {
let result = 'monaco-diff-editor monaco-editor-background ';
if (renderSideBySide) {
result += 'side-by-side ';
}
result += getThemeTypeSelector(theme.type);
return result;
}
_recreateOverviewRulers() {
if (!this._options.renderOverviewRuler) {
return;
}
if (this._originalOverviewRuler) {
this._overviewDomElement.removeChild(this._originalOverviewRuler.getDomNode());
this._originalOverviewRuler.dispose();
}
if (this._originalEditor.hasModel()) {
this._originalOverviewRuler = this._originalEditor.createOverviewRuler('original diffOverviewRuler');
this._overviewDomElement.appendChild(this._originalOverviewRuler.getDomNode());
}
if (this._modifiedOverviewRuler) {
this._overviewDomElement.removeChild(this._modifiedOverviewRuler.getDomNode());
this._modifiedOverviewRuler.dispose();
}
if (this._modifiedEditor.hasModel()) {
this._modifiedOverviewRuler = this._modifiedEditor.createOverviewRuler('modified diffOverviewRuler');
this._overviewDomElement.appendChild(this._modifiedOverviewRuler.getDomNode());
}
this._layoutOverviewRulers();
}
_createLeftHandSideEditor(options, codeEditorWidgetOptions) {
const editor = this._createInnerEditor(this._instantiationService, this._originalDomNode, this._adjustOptionsForLeftHandSide(options), codeEditorWidgetOptions);
this._register(editor.onDidScrollChange((e) => {
if (this._isHandlingScrollEvent) {
return;
}
if (!e.scrollTopChanged && !e.scrollLeftChanged && !e.scrollHeightChanged) {
return;
}
this._isHandlingScrollEvent = true;
this._modifiedEditor.setScrollPosition({
scrollLeft: e.scrollLeft,
scrollTop: e.scrollTop
});
this._isHandlingScrollEvent = false;
this._layoutOverviewViewport();
}));
this._register(editor.onDidChangeViewZones(() => {
this._onViewZonesChanged();
}));
this._register(editor.onDidChangeConfiguration((e) => {
if (!editor.getModel()) {
return;
}
if (e.hasChanged(43 /* fontInfo */)) {
this._updateDecorationsRunner.schedule();
}
if (e.hasChanged(130 /* wrappingInfo */)) {
this._updateDecorationsRunner.cancel();
this._updateDecorations();
}
}));
this._register(editor.onDidChangeHiddenAreas(() => {
this._updateDecorationsRunner.cancel();
this._updateDecorations();
}));
this._register(editor.onDidChangeModelContent(() => {
if (this._isVisible) {
this._beginUpdateDecorationsSoon();
}
}));
const isInDiffLeftEditorKey = this._contextKeyService.createKey('isInDiffLeftEditor', editor.hasWidgetFocus());
this._register(editor.onDidFocusEditorWidget(() => isInDiffLeftEditorKey.set(true)));
this._register(editor.onDidBlurEditorWidget(() => isInDiffLeftEditorKey.set(false)));
this._register(editor.onDidContentSizeChange(e => {
const width = this._originalEditor.getContentWidth() + this._modifiedEditor.getContentWidth() + DiffEditorWidget.ONE_OVERVIEW_WIDTH;
const height = Math.max(this._modifiedEditor.getContentHeight(), this._originalEditor.getContentHeight());
this._onDidContentSizeChange.fire({
contentHeight: height,
contentWidth: width,
contentHeightChanged: e.contentHeightChanged,
contentWidthChanged: e.contentWidthChanged
});
}));
return editor;
}
_createRightHandSideEditor(options, codeEditorWidgetOptions) {
const editor = this._createInnerEditor(this._instantiationService, this._modifiedDomNode, this._adjustOptionsForRightHandSide(options), codeEditorWidgetOptions);
this._register(editor.onDidScrollChange((e) => {
if (this._isHandlingScrollEvent) {
return;
}
if (!e.scrollTopChanged && !e.scrollLeftChanged && !e.scrollHeightChanged) {
return;
}
this._isHandlingScrollEvent = true;
this._originalEditor.setScrollPosition({
scrollLeft: e.scrollLeft,
scrollTop: e.scrollTop
});
this._isHandlingScrollEvent = false;
this._layoutOverviewViewport();
}));
this._register(editor.onDidChangeViewZones(() => {
this._onViewZonesChanged();
}));
this._register(editor.onDidChangeConfiguration((e) => {
if (!editor.getModel()) {
return;
}
if (e.hasChanged(43 /* fontInfo */)) {
this._updateDecorationsRunner.schedule();
}
if (e.hasChanged(130 /* wrappingInfo */)) {
this._updateDecorationsRunner.cancel();
this._updateDecorations();
}
}));
this._register(editor.onDidChangeHiddenAreas(() => {
this._updateDecorationsRunner.cancel();
this._updateDecorations();
}));
this._register(editor.onDidChangeModelContent(() => {
if (this._isVisible) {
this._beginUpdateDecorationsSoon();
}
}));
this._register(editor.onDidChangeModelOptions((e) => {
if (e.tabSize) {
this._updateDecorationsRunner.schedule();
}
}));
const isInDiffRightEditorKey = this._contextKeyService.createKey('isInDiffRightEditor', editor.hasWidgetFocus());
this._register(editor.onDidFocusEditorWidget(() => isInDiffRightEditorKey.set(true)));
this._register(editor.onDidBlurEditorWidget(() => isInDiffRightEditorKey.set(false)));
this._register(editor.onDidContentSizeChange(e => {
const width = this._originalEditor.getContentWidth() + this._modifiedEditor.getContentWidth() + DiffEditorWidget.ONE_OVERVIEW_WIDTH;
const height = Math.max(this._modifiedEditor.getContentHeight(), this._originalEditor.getContentHeight());
this._onDidContentSizeChange.fire({
contentHeight: height,
contentWidth: width,
contentHeightChanged: e.contentHeightChanged,
contentWidthChanged: e.contentWidthChanged
});
}));
return editor;
}
_createInnerEditor(instantiationService, container, options, editorWidgetOptions) {
return instantiationService.createInstance(CodeEditorWidget, container, options, editorWidgetOptions);
}
dispose() {
this._codeEditorService.removeDiffEditor(this);
if (this._beginUpdateDecorationsTimeout !== -1) {
window.clearTimeout(this._beginUpdateDecorationsTimeout);
this._beginUpdateDecorationsTimeout = -1;
}
this._cleanViewZonesAndDecorations();
if (this._originalOverviewRuler) {
this._overviewDomElement.removeChild(this._originalOverviewRuler.getDomNode());
this._originalOverviewRuler.dispose();
}
if (this._modifiedOverviewRuler) {
this._overviewDomElement.removeChild(this._modifiedOverviewRuler.getDomNode());
this._modifiedOverviewRuler.dispose();
}
this._overviewDomElement.removeChild(this._overviewViewportDomElement.domNode);
if (this._options.renderOverviewRuler) {
this._containerDomElement.removeChild(this._overviewDomElement);
}
this._containerDomElement.removeChild(this._originalDomNode);
this._originalEditor.dispose();
this._containerDomElement.removeChild(this._modifiedDomNode);
this._modifiedEditor.dispose();
this._strategy.dispose();
this._containerDomElement.removeChild(this._reviewPane.domNode.domNode);
this._containerDomElement.removeChild(this._reviewPane.shadow.domNode);
this._containerDomElement.removeChild(this._reviewPane.actionBarContainer.domNode);
this._reviewPane.dispose();
this._domElement.removeChild(this._containerDomElement);
this._onDidDispose.fire();
super.dispose();
}
//------------ begin IDiffEditor methods
getId() {
return this.getEditorType() + ':' + this._id;
}
getEditorType() {
return editorCommon.EditorType.IDiffEditor;
}
getLineChanges() {
if (!this._diffComputationResult) {
return null;
}
return this._diffComputationResult.changes;
}
getOriginalEditor() {
return this._originalEditor;
}
getModifiedEditor() {
return this._modifiedEditor;
}
updateOptions(_newOptions) {
const newOptions = validateDiffEditorOptions(_newOptions, this._options);
const changed = changedDiffEditorOptions(this._options, newOptions);
this._options = newOptions;
const beginUpdateDecorations = (changed.ignoreTrimWhitespace || changed.renderIndicators);
const beginUpdateDecorationsSoon = (this._isVisible && (changed.maxComputationTime || changed.maxFileSize));
if (beginUpdateDecorations) {
this._beginUpdateDecorations();
}
else if (beginUpdateDecorationsSoon) {
this._beginUpdateDecorationsSoon();
}
this._modifiedEditor.updateOptions(this._adjustOptionsForRightHandSide(_newOptions));
this._originalEditor.updateOptions(this._adjustOptionsForLeftHandSide(_newOptions));
// enableSplitViewResizing
this._strategy.setEnableSplitViewResizing(this._options.enableSplitViewResizing);
// renderSideBySide
if (changed.renderSideBySide) {
if (this._options.renderSideBySide) {
this._setStrategy(new DiffEditorWidgetSideBySide(this._createDataSource(), this._options.enableSplitViewResizing));
}
else {
this._setStrategy(new DiffEditorWidgetInline(this._createDataSource(), this._options.enableSplitViewResizing));
}
// Update class name
this._containerDomElement.className = DiffEditorWidget._getClassName(this._themeService.getColorTheme(), this._options.renderSideBySide);
}
// renderOverviewRuler
if (changed.renderOverviewRuler) {
if (this._options.renderOverviewRuler) {
this._containerDomElement.appendChild(this._overviewDomElement);
}
else {
this._containerDomElement.removeChild(this._overviewDomElement);
}
}
}
getModel() {
return {
original: this._originalEditor.getModel(),
modified: this._modifiedEditor.getModel()
};
}
setModel(model) {
// Guard us against partial null model
if (model && (!model.original || !model.modified)) {
throw new Error(!model.original ? 'DiffEditorWidget.setModel: Original model is null' : 'DiffEditorWidget.setModel: Modified model is null');
}
// Remove all view zones & decorations
this._cleanViewZonesAndDecorations();
// Update code editor models
this._originalEditor.setModel(model ? model.original : null);
this._modifiedEditor.setModel(model ? model.modified : null);
this._updateDecorationsRunner.cancel();
// this.originalEditor.onDidChangeModelOptions
if (model) {
this._originalEditor.setScrollTop(0);
this._modifiedEditor.setScrollTop(0);
}
// Disable any diff computations that will come in
this._diffComputationResult = null;
this._diffComputationToken++;
this._setState(0 /* Idle */);
if (model) {
this._recreateOverviewRulers();
// Begin comparing
this._beginUpdateDecorations();
}
this._layoutOverviewViewport();
}
getDomNode() {
return this._domElement;
}
getVisibleColumnFromPosition(position) {
return this._modifiedEditor.getVisibleColumnFromPosition(position);
}
getPosition() {
return this._modifiedEditor.getPosition();
}
setPosition(position) {
this._modifiedEditor.setPosition(position);
}
revealLine(lineNumber, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealLine(lineNumber, scrollType);
}
revealLineInCenter(lineNumber, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealLineInCenter(lineNumber, scrollType);
}
revealLineInCenterIfOutsideViewport(lineNumber, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealLineInCenterIfOutsideViewport(lineNumber, scrollType);
}
revealLineNearTop(lineNumber, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealLineNearTop(lineNumber, scrollType);
}
revealPosition(position, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealPosition(position, scrollType);
}
revealPositionInCenter(position, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealPositionInCenter(position, scrollType);
}
revealPositionInCenterIfOutsideViewport(position, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealPositionInCenterIfOutsideViewport(position, scrollType);
}
revealPositionNearTop(position, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealPositionNearTop(position, scrollType);
}
getSelection() {
return this._modifiedEditor.getSelection();
}
getSelections() {
return this._modifiedEditor.getSelections();
}
setSelection(something) {
this._modifiedEditor.setSelection(something);
}
setSelections(ranges) {
this._modifiedEditor.setSelections(ranges);
}
revealLines(startLineNumber, endLineNumber, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealLines(startLineNumber, endLineNumber, scrollType);
}
revealLinesInCenter(startLineNumber, endLineNumber, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealLinesInCenter(startLineNumber, endLineNumber, scrollType);
}
revealLinesInCenterIfOutsideViewport(startLineNumber, endLineNumber, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealLinesInCenterIfOutsideViewport(startLineNumber, endLineNumber, scrollType);
}
revealLinesNearTop(startLineNumber, endLineNumber, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealLinesNearTop(startLineNumber, endLineNumber, scrollType);
}
revealRange(range, scrollType = 0 /* Smooth */, revealVerticalInCenter = false, revealHorizontal = true) {
this._modifiedEditor.revealRange(range, scrollType, revealVerticalInCenter, revealHorizontal);
}
revealRangeInCenter(range, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealRangeInCenter(range, scrollType);
}
revealRangeInCenterIfOutsideViewport(range, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealRangeInCenterIfOutsideViewport(range, scrollType);
}
revealRangeNearTop(range, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealRangeNearTop(range, scrollType);
}
revealRangeNearTopIfOutsideViewport(range, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealRangeNearTopIfOutsideViewport(range, scrollType);
}
revealRangeAtTop(range, scrollType = 0 /* Smooth */) {
this._modifiedEditor.revealRangeAtTop(range, scrollType);
}
getSupportedActions() {
return this._modifiedEditor.getSupportedActions();
}
saveViewState() {
const originalViewState = this._originalEditor.saveViewState();
const modifiedViewState = this._modifiedEditor.saveViewState();
return {
original: originalViewState,
modified: modifiedViewState
};
}
restoreViewState(s) {
if (s && s.original && s.modified) {
const diffEditorState = s;
this._originalEditor.restoreViewState(diffEditorState.original);
this._modifiedEditor.restoreViewState(diffEditorState.modified);
}
}
layout(dimension) {
this._elementSizeObserver.observe(dimension);
}
focus() {
this._modifiedEditor.focus();
}
hasTextFocus() {
return this._originalEditor.hasTextFocus() || this._modifiedEditor.hasTextFocus();
}
trigger(source, handlerId, payload) {
this._modifiedEditor.trigger(source, handlerId, payload);
}
changeDecorations(callback) {
return this._modifiedEditor.changeDecorations(callback);
}
//------------ end IDiffEditor methods
//------------ begin layouting methods
_onDidContainerSizeChanged() {
this._doLayout();
}
_getReviewHeight() {
return this._reviewPane.isVisible() ? this._elementSizeObserver.getHeight() : 0;
}
_layoutOverviewRulers() {
if (!this._options.renderOverviewRuler) {
return;
}
if (!this._originalOverviewRuler || !this._modifiedOverviewRuler) {
return;
}
const height = this._elementSizeObserver.getHeight();
const reviewHeight = this._getReviewHeight();
const freeSpace = DiffEditorWidget.ENTIRE_DIFF_OVERVIEW_WIDTH - 2 * DiffEditorWidget.ONE_OVERVIEW_WIDTH;
const layoutInfo = this._modifiedEditor.getLayoutInfo();
if (layoutInfo) {
this._originalOverviewRuler.setLayout({
top: 0,
width: DiffEditorWidget.ONE_OVERVIEW_WIDTH,
right: freeSpace + DiffEditorWidget.ONE_OVERVIEW_WIDTH,
height: (height - reviewHeight)
});
this._modifiedOverviewRuler.setLayout({
top: 0,
right: 0,
width: DiffEditorWidget.ONE_OVERVIEW_WIDTH,
height: (height - reviewHeight)
});
}
}
//------------ end layouting methods
_onViewZonesChanged() {
if (this._currentlyChangingViewZones) {
return;
}
this._updateDecorationsRunner.schedule();
}
_beginUpdateDecorationsSoon() {
// Clear previous timeout if necessary
if (this._beginUpdateDecorationsTimeout !== -1) {
window.clearTimeout(this._beginUpdateDecorationsTimeout);
this._beginUpdateDecorationsTimeout = -1;
}
this._beginUpdateDecorationsTimeout = window.setTimeout(() => this._beginUpdateDecorations(), DiffEditorWidget.UPDATE_DIFF_DECORATIONS_DELAY);
}
static _equals(a, b) {
if (!a && !b) {
return true;
}
if (!a || !b) {
return false;
}
return (a.toString() === b.toString());
}
_beginUpdateDecorations() {
this._beginUpdateDecorationsTimeout = -1;
const currentOriginalModel = this._originalEditor.getModel();
const currentModifiedModel = this._modifiedEditor.getModel();
if (!currentOriginalModel || !currentModifiedModel) {
return;
}
// Prevent old diff requests to come if a new request has been initiated
// The best method would be to call cancel on the Promise, but this is not
// yet supported, so using tokens for now.
this._diffComputationToken++;
const currentToken = this._diffComputationToken;
const diffLimit = this._options.maxFileSize * 1024 * 1024; // MB
const canSyncModelForDiff = (model) => {
const bufferTextLength = model.getValueLength();
return (diffLimit === 0 || bufferTextLength <= diffLimit);
};
if (!canSyncModelForDiff(currentOriginalModel) || !canSyncModelForDiff(currentModifiedModel)) {
if (!DiffEditorWidget._equals(currentOriginalModel.uri, this._lastOriginalWarning)
|| !DiffEditorWidget._equals(currentModifiedModel.uri, this._lastModifiedWarning)) {
this._lastOriginalWarning = currentOriginalModel.uri;
this._lastModifiedWarning = currentModifiedModel.uri;
this._notificationService.warn(nls.localize("diff.tooLarge", "Cannot compare files because one file is too large."));
}
return;
}
this._setState(1 /* ComputingDiff */);
this._editorWorkerService.computeDiff(currentOriginalModel.uri, currentModifiedModel.uri, this._options.ignoreTrimWhitespace, this._options.maxComputationTime).then((result) => {
if (currentToken === this._diffComputationToken
&& currentOriginalModel === this._originalEditor.getModel()
&& currentModifiedModel === this._modifiedEditor.getModel()) {
this._setState(2 /* DiffComputed */);
this._diffComputationResult = result;
this._updateDecorationsRunner.schedule();
this._onDidUpdateDiff.fire();
}
}, (error) => {
if (currentToken === this._diffComputationToken
&& currentOriginalModel === this._originalEditor.getModel()
&& currentModifiedModel === this._modifiedEditor.getModel()) {
this._setState(2 /* DiffComputed */);
this._diffComputationResult = null;
this._updateDecorationsRunner.schedule();
}
});
}
_cleanViewZonesAndDecorations() {
this._originalEditorState.clean(this._originalEditor);
this._modifiedEditorState.clean(this._modifiedEditor);
}
_updateDecorations() {
if (!this._originalEditor.getModel() || !this._modifiedEditor.getModel()) {
return;
}
const lineChanges = (this._diffComputationResult ? this._diffComputationResult.changes : []);
const foreignOriginal = this._originalEditorState.getForeignViewZones(this._originalEditor.getWhitespaces());
const foreignModified = this._modifiedEditorState.getForeignViewZones(this._modifiedEditor.getWhitespaces());
const diffDecorations = this._strategy.getEditorsDiffDecorations(lineChanges, this._options.ignoreTrimWhitespace, this._options.renderIndicators, foreignOriginal, foreignModified);
try {
this._currentlyChangingViewZones = true;
this._originalEditorState.apply(this._originalEditor, this._originalOverviewRuler, diffDecorations.original, false);
this._modifiedEditorState.apply(this._modifiedEditor, this._modifiedOverviewRuler, diffDecorations.modified, true);
}
finally {
this._currentlyChangingViewZones = false;
}
}
_adjustOptionsForSubEditor(options) {
const clonedOptions = Object.assign({}, options);
clonedOptions.inDiffEditor = true;
clonedOptions.automaticLayout = false;
// Clone scrollbar options before changing them
clonedOptions.scrollbar = Object.assign({}, (clonedOptions.scrollbar || {}));
clonedOptions.scrollbar.vertical = 'visible';
clonedOptions.folding = false;
clonedOptions.codeLens = this._options.diffCodeLens;
clonedOptions.fixedOverflowWidgets = true;
// clonedOptions.lineDecorationsWidth = '2ch';
// Clone minimap options before changing them
clonedOptions.minimap = Object.assign({}, (clonedOptions.minimap || {}));
clonedOptions.minimap.enabled = false;
return clonedOptions;
}
_adjustOptionsForLeftHandSide(options) {
const result = this._adjustOptionsForSubEditor(options);
if (!this._options.renderSideBySide) {
// never wrap hidden editor
result.wordWrapOverride1 = 'off';
}
else {
result.wordWrapOverride1 = this._options.diffWordWrap;
}
if (options.originalAriaLabel) {
result.ariaLabel = options.originalAriaLabel;
}
result.readOnly = !this._options.originalEditable;
result.extraEditorClassName = 'original-in-monaco-diff-editor';
return Object.assign(Object.assign({}, result), { dimension: {
height: 0,
width: 0
} });
}
_adjustOptionsForRightHandSide(options) {
const result = this._adjustOptionsForSubEditor(options);
if (options.modifiedAriaLabel) {
result.ariaLabel = options.modifiedAriaLabel;
}
result.wordWrapOverride1 = this._options.diffWordWrap;
result.revealHorizontalRightPadding = EditorOptions.revealHorizontalRightPadding.defaultValue + DiffEditorWidget.ENTIRE_DIFF_OVERVIEW_WIDTH;
result.scrollbar.verticalHasArrows = false;
result.extraEditorClassName = 'modified-in-monaco-diff-editor';
return Object.assign(Object.assign({}, result), { dimension: {
height: 0,
width: 0
} });
}
doLayout() {
this._elementSizeObserver.observe();
this._doLayout();
}
_doLayout() {
const width = this._elementSizeObserver.getWidth();
const height = this._elementSizeObserver.getHeight();
const reviewHeight = this._getReviewHeight();
const splitPoint = this._strategy.layout();
this._originalDomNode.style.width = splitPoint + 'px';
this._originalDomNode.style.left = '0px';
this._modifiedDomNode.style.width = (width - splitPoint) + 'px';
this._modifiedDomNode.style.left = splitPoint + 'px';
this._overviewDomElement.style.top = '0px';
this._overviewDomElement.style.height = (height - reviewHeight) + 'px';
this._overviewDomElement.style.width = DiffEditorWidget.ENTIRE_DIFF_OVERVIEW_WIDTH + 'px';
this._overviewDomElement.style.left = (width - DiffEditorWidget.ENTIRE_DIFF_OVERVIEW_WIDTH) + 'px';
this._overviewViewportDomElement.setWidth(DiffEditorWidget.ENTIRE_DIFF_OVERVIEW_WIDTH);
this._overviewViewportDomElement.setHeight(30);
this._originalEditor.layout({ width: splitPoint, height: (height - reviewHeight) });
this._modifiedEditor.layout({ width: width - splitPoint - (this._options.renderOverviewRuler ? DiffEditorWidget.ENTIRE_DIFF_OVERVIEW_WIDTH : 0), height: (height - reviewHeight) });
if (this._originalOverviewRuler || this._modifiedOverviewRuler) {
this._layoutOverviewRulers();
}
this._reviewPane.layout(height - reviewHeight, width, reviewHeight);
this._layoutOverviewViewport();
}
_layoutOverviewViewport() {
const layout = this._computeOverviewViewport();
if (!layout) {
this._overviewViewportDomElement.setTop(0);
this._overviewViewportDomElement.setHeight(0);
}
else {
this._overviewViewportDomElement.setTop(layout.top);
this._overviewViewportDomElement.setHeight(layout.height);
}
}
_computeOverviewViewport() {
const layoutInfo = this._modifiedEditor.getLayoutInfo();
if (!layoutInfo) {
return null;
}
const scrollTop = this._modifiedEditor.getScrollTop();
const scrollHeight = this._modifiedEditor.getScrollHeight();
const computedAvailableSize = Math.max(0, layoutInfo.height);
const computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * 0);
const computedRatio = scrollHeight > 0 ? (computedRepresentableSize / scrollHeight) : 0;
const computedSliderSize = Math.max(0, Math.floor(layoutInfo.height * computedRatio));
const computedSliderPosition = Math.floor(scrollTop * computedRatio);
return {
height: computedSliderSize,
top: computedSliderPosition
};
}
_createDataSource() {
return {
getWidth: () => {
return this._elementSizeObserver.getWidth();
},
getHeight: () => {
return (this._elementSizeObserver.getHeight() - this._getReviewHeight());
},
getOptions: () => {
return {
renderOverviewRuler: this._options.renderOverviewRuler
};
},
getContainerDomNode: () => {
return this._containerDomElement;
},
relayoutEditors: () => {
this._doLayout();
},
getOriginalEditor: () => {
return this._originalEditor;
},
getModifiedEditor: () => {
return this._modifiedEditor;
}
};
}
_setStrategy(newStrategy) {
if (this._strategy) {
this._strategy.dispose();
}
this._strategy = newStrategy;
newStrategy.applyColors(this._themeService.getColorTheme());
if (this._diffComputationResult) {
this._updateDecorations();
}
// Just do a layout, the strategy might need it
this._doLayout();
}
_getLineChangeAtOrBeforeLineNumber(lineNumber, startLineNumberExtractor) {
const lineChanges = (this._diffComputationResult ? this._diffComputationResult.changes : []);
if (lineChanges.length === 0 || lineNumber < startLineNumberExtractor(lineChanges[0])) {
// There are no changes or `lineNumber` is before the first change
return null;
}
let min = 0;
let max = lineChanges.length - 1;
while (min < max) {
const mid = Math.floor((min + max) / 2);
const midStart = startLineNumberExtractor(lineChanges[mid]);
const midEnd = (mid + 1 <= max ? startLineNumberExtractor(lineChanges[mid + 1]) : 1073741824 /* MAX_SAFE_SMALL_INTEGER */);
if (lineNumber < midStart) {
max = mid - 1;
}
else if (lineNumber >= midEnd) {
min = mid + 1;
}
else {
// HIT!
min = mid;
max = mid;
}
}
return lineChanges[min];
}
_getEquivalentLineForOriginalLineNumber(lineNumber) {
const lineChange = this._getLineChangeAtOrBeforeLineNumber(lineNumber, (lineChange) => lineChange.originalStartLineNumber);
if (!lineChange) {
return lineNumber;
}
const originalEquivalentLineNumber = lineChange.originalStartLineNumber + (lineChange.originalEndLineNumber > 0 ? -1 : 0);
const modifiedEquivalentLineNumber = lineChange.modifiedStartLineNumber + (lineChange.modifiedEndLineNumber > 0 ? -1 : 0);
const lineChangeOriginalLength = (lineChange.originalEndLineNumber > 0 ? (lineChange.originalEndLineNumber - lineChange.originalStartLineNumber + 1) : 0);
const lineChangeModifiedLength = (lineChange.modifiedEndLineNumber > 0 ? (lineChange.modifiedEndLineNumber - lineChange.modifiedStartLineNumber + 1) : 0);
const delta = lineNumber - originalEquivalentLineNumber;
if (delta <= lineChangeOriginalLength) {
return modifiedEquivalentLineNumber + Math.min(delta, lineChangeModifiedLength);
}
return modifiedEquivalentLineNumber + lineChangeModifiedLength - lineChangeOriginalLength + delta;
}
_getEquivalentLineForModifiedLineNumber(lineNumber) {
const lineChange = this._getLineChangeAtOrBeforeLineNumber(lineNumber, (lineChange) => lineChange.modifiedStartLineNumber);
if (!lineChange) {
return lineNumber;
}
const originalEquivalentLineNumber = lineChange.originalStartLineNumber + (lineChange.originalEndLineNumber > 0 ? -1 : 0);
const modifiedEquivalentLineNumber = lineChange.modifiedStartLineNumber + (lineChange.modifiedEndLineNumber > 0 ? -1 : 0);
const lineChangeOriginalLength = (lineChange.originalEndLineNumber > 0 ? (lineChange.originalEndLineNumber - lineChange.originalStartLineNumber + 1) : 0);
const lineChangeModifiedLength = (lineChange.modifiedEndLineNumber > 0 ? (lineChange.modifiedEndLineNumber - lineChange.modifiedStartLineNumber + 1) : 0);
const delta = lineNumber - modifiedEquivalentLineNumber;
if (delta <= lineChangeModifiedLength) {
return originalEquivalentLineNumber + Math.min(delta, lineChangeOriginalLength);
}
return originalEquivalentLineNumber + lineChangeOriginalLength - lineChangeModifiedLength + delta;
}
getDiffLineInformationForOriginal(lineNumber) {
if (!this._diffComputationResult) {
// Cannot answer that which I don't know
return null;
}
return {
equivalentLineNumber: this._getEquivalentLineForOriginalLineNumber(lineNumber)
};
}
getDiffLineInformationForModified(lineNumber) {
if (!this._diffComputationResult) {
// Cannot answer that which I don't know
return null;
}
return {
equivalentLineNumber: this._getEquivalentLineForModifiedLineNumber(lineNumber)
};
}
};
DiffEditorWidget.ONE_OVERVIEW_WIDTH = 15;
DiffEditorWidget.ENTIRE_DIFF_OVERVIEW_WIDTH = 30;
DiffEditorWidget.UPDATE_DIFF_DECORATIONS_DELAY = 200; // ms
DiffEditorWidget = __decorate([
__param(3, IClipboardService),
__param(4, IEditorWorkerService),
__param(5, IContextKeyService),
__param(6, IInstantiationService),
__param(7, ICodeEditorService),
__param(8, IThemeService),
__param(9, INotificationService),
__param(10, IContextMenuService),
__param(11, IEditorProgressService)
], DiffEditorWidget);
export { DiffEditorWidget };
class DiffEditorWidgetStyle extends Disposable {
constructor(dataSource) {
super();
this._dataSource = dataSource;
this._insertColor = null;
this._removeColor = null;
}
applyColors(theme) {
const newInsertColor = (theme.getColor(diffInserted) || defaultInsertColor).transparent(2);
const newRemoveColor = (theme.getColor(diffRemoved) || defaultRemoveColor).transparent(2);
const hasChanges = !newInsertColor.equals(this._insertColor) || !newRemoveColor.equals(this._removeColor);
this._insertColor = newInsertColor;
this._removeColor = newRemoveColor;
return hasChanges;
}
getEditorsDiffDecorations(lineChanges, ignoreTrimWhitespace, renderIndicators, originalWhitespaces, modifiedWhitespaces) {
// Get view zones
modifiedWhitespaces = modifiedWhitespaces.sort((a, b) => {
return a.afterLineNumber - b.afterLineNumber;
});
originalW