UNPKG

monaco-editor

Version:
143 lines (142 loc) 7.72 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as dom from '../../../../base/browser/dom.js'; import { createFastDomNode } from '../../../../base/browser/fastDomNode.js'; import { SmoothScrollableElement } from '../../../../base/browser/ui/scrollbar/scrollableElement.js'; import { PartFingerprints, ViewPart } from '../../view/viewPart.js'; import { getThemeTypeSelector } from '../../../../platform/theme/common/themeService.js'; export class EditorScrollbar extends ViewPart { constructor(context, linesContent, viewDomNode, overflowGuardDomNode) { super(context); const options = this._context.configuration.options; const scrollbar = options.get(104 /* EditorOption.scrollbar */); const mouseWheelScrollSensitivity = options.get(75 /* EditorOption.mouseWheelScrollSensitivity */); const fastScrollSensitivity = options.get(40 /* EditorOption.fastScrollSensitivity */); const scrollPredominantAxis = options.get(107 /* EditorOption.scrollPredominantAxis */); const scrollbarOptions = { listenOnDomNode: viewDomNode.domNode, className: 'editor-scrollable' + ' ' + getThemeTypeSelector(context.theme.type), useShadows: false, lazyRender: true, vertical: scrollbar.vertical, horizontal: scrollbar.horizontal, verticalHasArrows: scrollbar.verticalHasArrows, horizontalHasArrows: scrollbar.horizontalHasArrows, verticalScrollbarSize: scrollbar.verticalScrollbarSize, verticalSliderSize: scrollbar.verticalSliderSize, horizontalScrollbarSize: scrollbar.horizontalScrollbarSize, horizontalSliderSize: scrollbar.horizontalSliderSize, handleMouseWheel: scrollbar.handleMouseWheel, alwaysConsumeMouseWheel: scrollbar.alwaysConsumeMouseWheel, arrowSize: scrollbar.arrowSize, mouseWheelScrollSensitivity: mouseWheelScrollSensitivity, fastScrollSensitivity: fastScrollSensitivity, scrollPredominantAxis: scrollPredominantAxis, scrollByPage: scrollbar.scrollByPage, }; this.scrollbar = this._register(new SmoothScrollableElement(linesContent.domNode, scrollbarOptions, this._context.viewLayout.getScrollable())); PartFingerprints.write(this.scrollbar.getDomNode(), 6 /* PartFingerprint.ScrollableElement */); this.scrollbarDomNode = createFastDomNode(this.scrollbar.getDomNode()); this.scrollbarDomNode.setPosition('absolute'); this._setLayout(); // When having a zone widget that calls .focus() on one of its dom elements, // the browser will try desperately to reveal that dom node, unexpectedly // changing the .scrollTop of this.linesContent const onBrowserDesperateReveal = (domNode, lookAtScrollTop, lookAtScrollLeft) => { const newScrollPosition = {}; if (lookAtScrollTop) { const deltaTop = domNode.scrollTop; if (deltaTop) { newScrollPosition.scrollTop = this._context.viewLayout.getCurrentScrollTop() + deltaTop; domNode.scrollTop = 0; } } if (lookAtScrollLeft) { const deltaLeft = domNode.scrollLeft; if (deltaLeft) { newScrollPosition.scrollLeft = this._context.viewLayout.getCurrentScrollLeft() + deltaLeft; domNode.scrollLeft = 0; } } this._context.viewModel.viewLayout.setScrollPosition(newScrollPosition, 1 /* ScrollType.Immediate */); }; // I've seen this happen both on the view dom node & on the lines content dom node. this._register(dom.addDisposableListener(viewDomNode.domNode, 'scroll', (e) => onBrowserDesperateReveal(viewDomNode.domNode, true, true))); this._register(dom.addDisposableListener(linesContent.domNode, 'scroll', (e) => onBrowserDesperateReveal(linesContent.domNode, true, false))); this._register(dom.addDisposableListener(overflowGuardDomNode.domNode, 'scroll', (e) => onBrowserDesperateReveal(overflowGuardDomNode.domNode, true, false))); this._register(dom.addDisposableListener(this.scrollbarDomNode.domNode, 'scroll', (e) => onBrowserDesperateReveal(this.scrollbarDomNode.domNode, true, false))); } dispose() { super.dispose(); } _setLayout() { const options = this._context.configuration.options; const layoutInfo = options.get(146 /* EditorOption.layoutInfo */); this.scrollbarDomNode.setLeft(layoutInfo.contentLeft); const minimap = options.get(73 /* EditorOption.minimap */); const side = minimap.side; if (side === 'right') { this.scrollbarDomNode.setWidth(layoutInfo.contentWidth + layoutInfo.minimap.minimapWidth); } else { this.scrollbarDomNode.setWidth(layoutInfo.contentWidth); } this.scrollbarDomNode.setHeight(layoutInfo.height); } getOverviewRulerLayoutInfo() { return this.scrollbar.getOverviewRulerLayoutInfo(); } getDomNode() { return this.scrollbarDomNode; } delegateVerticalScrollbarPointerDown(browserEvent) { this.scrollbar.delegateVerticalScrollbarPointerDown(browserEvent); } delegateScrollFromMouseWheelEvent(browserEvent) { this.scrollbar.delegateScrollFromMouseWheelEvent(browserEvent); } // --- begin event handlers onConfigurationChanged(e) { if (e.hasChanged(104 /* EditorOption.scrollbar */) || e.hasChanged(75 /* EditorOption.mouseWheelScrollSensitivity */) || e.hasChanged(40 /* EditorOption.fastScrollSensitivity */)) { const options = this._context.configuration.options; const scrollbar = options.get(104 /* EditorOption.scrollbar */); const mouseWheelScrollSensitivity = options.get(75 /* EditorOption.mouseWheelScrollSensitivity */); const fastScrollSensitivity = options.get(40 /* EditorOption.fastScrollSensitivity */); const scrollPredominantAxis = options.get(107 /* EditorOption.scrollPredominantAxis */); const newOpts = { vertical: scrollbar.vertical, horizontal: scrollbar.horizontal, verticalScrollbarSize: scrollbar.verticalScrollbarSize, horizontalScrollbarSize: scrollbar.horizontalScrollbarSize, scrollByPage: scrollbar.scrollByPage, handleMouseWheel: scrollbar.handleMouseWheel, mouseWheelScrollSensitivity: mouseWheelScrollSensitivity, fastScrollSensitivity: fastScrollSensitivity, scrollPredominantAxis: scrollPredominantAxis }; this.scrollbar.updateOptions(newOpts); } if (e.hasChanged(146 /* EditorOption.layoutInfo */)) { this._setLayout(); } return true; } onScrollChanged(e) { return true; } onThemeChanged(e) { this.scrollbar.updateClassName('editor-scrollable' + ' ' + getThemeTypeSelector(this._context.theme.type)); return true; } // --- end event handlers prepareRender(ctx) { // Nothing to do } render(ctx) { this.scrollbar.renderNow(); } }